git.iko.soy/typeable/pandoc
on master help sign in
Org reader: allow changing emphasis syntax
00d20ccAlbert Krewinkel
src/Text/Pandoc/Readers/Org/Inlines.hs+6−10
@@ -603,6 +603,8 @@ updatePositions :: PandocMonad m
603 => Char
603 => Char
604 -> OrgParser m Char
604 -> OrgParser m Char
605updatePositions c = do
605updatePositions c = do
606+ st <- getState
607+ let emphasisPreChars = orgStateEmphasisPreChars st
606 when (c `elem` emphasisPreChars) updateLastPreCharPos
608 when (c `elem` emphasisPreChars) updateLastPreCharPos
607 when (c `elem` emphasisForbiddenBorderChars) updateLastForbiddenCharPos
609 when (c `elem` emphasisForbiddenBorderChars) updateLastForbiddenCharPos
608 return c
610 return c
@@ -681,8 +683,10 @@ emphasisEnd c = try $ do
681 updateLastStrPos
683 updateLastStrPos
682 popInlineCharStack
684 popInlineCharStack
683 return c
685 return c
686+ where
684− where acceptablePostChars =
687+ acceptablePostChars = do
688+ emphasisPostChars <- orgStateEmphasisPostChars <$> getState
685− surroundingEmphasisChar >>= \x -> oneOf (x ++ emphasisPostChars)
689+ surroundingEmphasisChar >>= \x -> oneOf (x ++ emphasisPostChars)
686
690
687mathStart :: PandocMonad m => Char -> OrgParser m Char
691mathStart :: PandocMonad m => Char -> OrgParser m Char
688mathStart c = try $
692mathStart c = try $
@@ -734,14 +738,6 @@ many1TillNOrLessNewlines n p end = try $
734-- here (see, e.g., the Emacs Lisp variable `org-emphasis-regexp-components`
738-- here (see, e.g., the Emacs Lisp variable `org-emphasis-regexp-components`
735-- for details).
739-- for details).
736
740
737−-- | Chars allowed to occur before emphasis (spaces and newlines are ok, too)
738−emphasisPreChars :: [Char]
739−emphasisPreChars = "-\t ('\"{"
740−
741−-- | Chars allowed at after emphasis
742−emphasisPostChars :: [Char]
743−emphasisPostChars = "-\t\n .,:!?;'\")}["
744−
745-- | Chars not allowed at the (inner) border of emphasis
741-- | Chars not allowed at the (inner) border of emphasis
746emphasisForbiddenBorderChars :: [Char]
742emphasisForbiddenBorderChars :: [Char]
747emphasisForbiddenBorderChars = "\t\n\r "
743emphasisForbiddenBorderChars = "\t\n\r "
src/Text/Pandoc/Readers/Org/Meta.hs+22
@@ -43,6 +43,7 @@ import Text.Pandoc.Builder (Blocks, Inlines)
43import qualified Text.Pandoc.Builder as B
43import qualified Text.Pandoc.Builder as B
44import Text.Pandoc.Class (PandocMonad)
44import Text.Pandoc.Class (PandocMonad)
45import Text.Pandoc.Definition
45import Text.Pandoc.Definition
46+import Text.Pandoc.Shared (safeRead)
46
47
47import Control.Monad (mzero, void, when)
48import Control.Monad (mzero, void, when)
48import Data.Char (toLower)
49import Data.Char (toLower)
@@ -154,6 +155,8 @@ optionLine = try $ do
154 "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
155 "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
155 "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
156 "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
156 "macro" -> macroDefinition >>= updateState . registerMacro
157 "macro" -> macroDefinition >>= updateState . registerMacro
158+ "pandoc-emphasis-pre" -> emphChars >>= updateState . setEmphasisPreChar
159+ "pandoc-emphasis-post" -> emphChars >>= updateState . setEmphasisPostChar
157 _ -> mzero
160 _ -> mzero
158
161
159addLinkFormat :: Monad m => String
162addLinkFormat :: Monad m => String
@@ -184,6 +187,25 @@ parseFormat = try $ replacePlain <|> replaceUrl <|> justAppend
184 rest = manyTill anyChar (eof <|> () <$ oneOf "\n\r")
187 rest = manyTill anyChar (eof <|> () <$ oneOf "\n\r")
185 tillSpecifier c = manyTill (noneOf "\n\r") (try $ string ('%':c:""))
188 tillSpecifier c = manyTill (noneOf "\n\r") (try $ string ('%':c:""))
186
189
190+setEmphasisPreChar :: Maybe [Char] -> OrgParserState -> OrgParserState
191+setEmphasisPreChar csMb st =
192+ let preChars = case csMb of
193+ Nothing -> orgStateEmphasisPreChars defaultOrgParserState
194+ Just cs -> cs
195+ in st { orgStateEmphasisPreChars = preChars }
196+
197+setEmphasisPostChar :: Maybe [Char] -> OrgParserState -> OrgParserState
198+setEmphasisPostChar csMb st =
199+ let postChars = case csMb of
200+ Nothing -> orgStateEmphasisPostChars defaultOrgParserState
201+ Just cs -> cs
202+ in st { orgStateEmphasisPostChars = postChars }
203+
204+emphChars :: Monad m => OrgParser m (Maybe [Char])
205+emphChars = do
206+ skipSpaces
207+ safeRead <$> anyLine
208+
187inlinesTillNewline :: PandocMonad m => OrgParser m (F Inlines)
209inlinesTillNewline :: PandocMonad m => OrgParser m (F Inlines)
188inlinesTillNewline = do
210inlinesTillNewline = do
189 updateLastPreCharPos
211 updateLastPreCharPos
src/Text/Pandoc/Readers/Org/ParserState.hs+11−1
@@ -29,6 +29,7 @@ Define the Org-mode parser state.
29-}
29-}
30module Text.Pandoc.Readers.Org.ParserState
30module Text.Pandoc.Readers.Org.ParserState
31 ( OrgParserState (..)
31 ( OrgParserState (..)
32+ , defaultOrgParserState
32 , OrgParserLocal (..)
33 , OrgParserLocal (..)
33 , OrgNoteRecord
34 , OrgNoteRecord
34 , HasReaderOptions (..)
35 , HasReaderOptions (..)
@@ -104,6 +105,11 @@ type TodoSequence = [TodoMarker]
104data OrgParserState = OrgParserState
105data OrgParserState = OrgParserState
105 { orgStateAnchorIds :: [String]
106 { orgStateAnchorIds :: [String]
106 , orgStateEmphasisCharStack :: [Char]
107 , orgStateEmphasisCharStack :: [Char]
108+ , orgStateEmphasisPreChars :: [Char] -- ^ Chars allowed to occur before
109+ -- emphasis; spaces and newlines are
110+ -- always ok in addition to what is
111+ -- specified here.
112+ , orgStateEmphasisPostChars :: [Char] -- ^ Chars allowed at after emphasis
107 , orgStateEmphasisNewlines :: Maybe Int
113 , orgStateEmphasisNewlines :: Maybe Int
108 , orgStateExportSettings :: ExportSettings
114 , orgStateExportSettings :: ExportSettings
109 , orgStateHeaderMap :: M.Map Inlines String
115 , orgStateHeaderMap :: M.Map Inlines String
@@ -124,7 +130,9 @@ data OrgParserState = OrgParserState
124 , orgMacros :: M.Map Text Macro
130 , orgMacros :: M.Map Text Macro
125 }
131 }
126
132
127−data OrgParserLocal = OrgParserLocal { orgLocalQuoteContext :: QuoteContext }
133+data OrgParserLocal = OrgParserLocal
134+ { orgLocalQuoteContext :: QuoteContext
135+ }
128
136
129instance Default OrgParserLocal where
137instance Default OrgParserLocal where
130 def = OrgParserLocal NoQuote
138 def = OrgParserLocal NoQuote
@@ -168,6 +176,8 @@ instance Default OrgParserState where
168defaultOrgParserState :: OrgParserState
176defaultOrgParserState :: OrgParserState
169defaultOrgParserState = OrgParserState
177defaultOrgParserState = OrgParserState
170 { orgStateAnchorIds = []
178 { orgStateAnchorIds = []
179+ , orgStateEmphasisPreChars = "-\t ('\"{"
180+ , orgStateEmphasisPostChars = "-\t\n .,:!?;'\")}["
171 , orgStateEmphasisCharStack = []
181 , orgStateEmphasisCharStack = []
172 , orgStateEmphasisNewlines = Nothing
182 , orgStateEmphasisNewlines = Nothing
173 , orgStateExportSettings = def
183 , orgStateExportSettings = def
test/Tests/Readers/Org/Meta.hs+19−1
@@ -1,7 +1,7 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2module Tests.Readers.Org.Meta (tests) where
2module Tests.Readers.Org.Meta (tests) where
3
3
4−import Test.Tasty (TestTree)
4+import Test.Tasty (TestTree, testGroup)
5import Tests.Helpers ((=?>))
5import Tests.Helpers ((=?>))
6import Tests.Readers.Org.Shared ((=:), spcSep)
6import Tests.Readers.Org.Shared ((=:), spcSep)
7import Text.Pandoc
7import Text.Pandoc
@@ -170,4 +170,22 @@ tests =
170 , "[[expl:foo][bar]]"
170 , "[[expl:foo][bar]]"
171 ] =?>
171 ] =?>
172 para (link "http://example.com/foo" "" "bar")
172 para (link "http://example.com/foo" "" "bar")
173+
174+ , testGroup "emphasis config"
175+ [ "Changing pre and post chars for emphasis" =:
176+ T.unlines [ "#+pandoc-emphasis-pre: \"[)\""
177+ , "#+pandoc-emphasis-post: \"]\\n\""
178+ , "([/emph/])*foo*"
179+ ] =?>
180+ para ("([" <> emph "emph" <> "])" <> strong "foo")
181+
182+ , "setting an invalid value restores the default" =:
183+ T.unlines [ "#+pandoc-emphasis-pre: \"[\""
184+ , "#+pandoc-emphasis-post: \"]\""
185+ , "#+pandoc-emphasis-pre:"
186+ , "#+pandoc-emphasis-post:"
187+ , "[/noemph/]"
188+ ] =?>
189+ para ("[/noemph/]")
190+ ]
173 ]
191 ]