git.iko.soy/typeable/pandoc
on master help sign in
Org reader: put header tags into empty spans

Org mode allows headers to be tagged: ``` org-mode * Headline :TAG1:TAG2: ``` Instead of being interpreted as part of the headline, the tags are now put into the attributes of empty spans. Spans without textual content won't be visible by default, but they are detectable by filters. They can also be styled using CSS when written as HTML. This fixes #2160.

commitd8e4a8bc10bfd97d81ec0166fd786742fe3a2370 authorAlbert Krewinkel <albert@zeitkraut.de> dateWed 20 May 2015, 18:01 (11 years ago) parentd5f367d
2 files changed+38−6
src/Text/Pandoc/Readers/Org.hs+19−2 tests/Tests/Readers/Org.hs+19−4
src/Text/Pandoc/Readers/Org.hs+19−2
@@ -652,8 +652,25 @@ parseFormat = try $ do
652652header :: OrgParser (F Blocks)
653653header = try $ do
654654 level <- headerStart
655− title <- inlinesTillNewline
656− return $ B.header level <$> title
655+ title <- manyTill inline (lookAhead headerEnd)
656+ tags <- headerEnd
657+ let inlns = trimInlinesF . mconcat $ title <> map tagToInlineF tags
658+ return $ B.header level <$> inlns
659+ where
660+ tagToInlineF :: String -> F Inlines
661+ tagToInlineF t = return $ B.spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
662+
663+headerEnd :: OrgParser [String]
664+headerEnd = option [] headerTags <* newline
665+
666+headerTags :: OrgParser [String]
667+headerTags = try $
668+ skipSpaces
669+ *> char ':'
670+ *> many1 tag
671+ <* skipSpaces
672+ where tag = many1 (alphaNum <|> oneOf "@%#_")
673+ <* char ':'
657674
658675headerStart :: OrgParser Int
659676headerStart = try $
tests/Tests/Readers/Org.hs+19−4
@@ -497,6 +497,21 @@ tests =
497497 , header 2 ("walk" <> space <> "dog")
498498 ]
499499
500+ , "Tagged headers" =:
501+ unlines [ "* Personal :PERSONAL:"
502+ , "** Call Mom :@PHONE:"
503+ , "** Call John :@PHONE:JOHN: "
504+ ] =?>
505+ let tagSpan t = spanWith ("", ["tag"], [("data-tag-name", t)]) mempty
506+ in mconcat [ header 1 ("Personal" <> tagSpan "PERSONAL")
507+ , header 2 ("Call Mom" <> tagSpan "@PHONE")
508+ , header 2 ("Call John" <> tagSpan "@PHONE" <> tagSpan "JOHN")
509+ ]
510+
511+ , "Untagged header containing colons" =:
512+ "* This: is not: tagged" =?>
513+ header 1 "This: is not: tagged"
514+
500515 , "Comment Trees" =:
501516 unlines [ "* COMMENT A comment tree"
502517 , " Not much going on here"
@@ -1164,19 +1179,19 @@ tests =
11641179 [ test orgSmart "quote before ellipses"
11651180 ("'...hi'"
11661181 =?> para (singleQuoted "…hi"))
1167−
1182+
11681183 , test orgSmart "apostrophe before emph"
11691184 ("D'oh! A l'/aide/!"
11701185 =?> para ("D’oh! A l’" <> emph "aide" <> "!"))
1171−
1186+
11721187 , test orgSmart "apostrophe in French"
11731188 ("À l'arrivée de la guerre, le thème de l'«impossibilité du socialisme»"
11741189 =?> para "À l’arrivée de la guerre, le thème de l’«impossibilité du socialisme»")
1175−
1190+
11761191 , test orgSmart "Quotes cannot occur at the end of emphasized text"
11771192 ("/say \"yes\"/" =?>
11781193 para ("/say" <> space <> doubleQuoted "yes" <> "/"))
1179−
1194+
11801195 , test orgSmart "Dashes are allowed at the borders of emphasis'"
11811196 ("/foo---/" =?>
11821197 para (emph "foo—"))