git.iko.soy/typeable/pandoc
on master help sign in
Org reader: allow changing emphasis syntax

The characters allowed before and after emphasis can be configured via `#+pandoc-emphasis-pre` and `#+pandoc-emphasis-post`, respectively. This allows to change which strings are recognized as emphasized text on a per-document or even per-paragraph basis. The allowed characters must be given as (Haskell) string. #+pandoc-emphasis-pre: "-\t ('\"{" #+pandoc-emphasis-post: "-\t\n .,:!?;'\")}[" If the argument cannot be read as a string, the default value is restored. Closes: #4378

commit00d20ccd09a8542fda631ab16c7f569098f2918d authorAlbert Krewinkel <albert@zeitkraut.de> dateWed 21 Feb 2018, 08:53 (9 years ago) parent84db7e4
4 files changed+58−12
src/Text/Pandoc/Readers/Org/Inlines.hs+6−10 src/Text/Pandoc/Readers/Org/Meta.hs+22 src/Text/Pandoc/Readers/Org/ParserState.hs+11−1 test/Tests/Readers/Org/Meta.hs+19−1
src/Text/Pandoc/Readers/Org/Inlines.hs+6−10
@@ -603,6 +603,8 @@ updatePositions :: PandocMonad m
603603 => Char
604604 -> OrgParser m Char
605605updatePositions c = do
606+ st <- getState
607+ let emphasisPreChars = orgStateEmphasisPreChars st
606608 when (c `elem` emphasisPreChars) updateLastPreCharPos
607609 when (c `elem` emphasisForbiddenBorderChars) updateLastForbiddenCharPos
608610 return c
@@ -681,8 +683,10 @@ emphasisEnd c = try $ do
681683 updateLastStrPos
682684 popInlineCharStack
683685 return c
684− where acceptablePostChars =
685− surroundingEmphasisChar >>= \x -> oneOf (x ++ emphasisPostChars)
686+ where
687+ acceptablePostChars = do
688+ emphasisPostChars <- orgStateEmphasisPostChars <$> getState
689+ surroundingEmphasisChar >>= \x -> oneOf (x ++ emphasisPostChars)
686690
687691mathStart :: PandocMonad m => Char -> OrgParser m Char
688692mathStart c = try $
@@ -734,14 +738,6 @@ many1TillNOrLessNewlines n p end = try $
734738-- here (see, e.g., the Emacs Lisp variable `org-emphasis-regexp-components`
735739-- for details).
736740
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−
745741-- | Chars not allowed at the (inner) border of emphasis
746742emphasisForbiddenBorderChars :: [Char]
747743emphasisForbiddenBorderChars = "\t\n\r "
src/Text/Pandoc/Readers/Org/Meta.hs+22
@@ -43,6 +43,7 @@ import Text.Pandoc.Builder (Blocks, Inlines)
4343import qualified Text.Pandoc.Builder as B
4444import Text.Pandoc.Class (PandocMonad)
4545import Text.Pandoc.Definition
46+import Text.Pandoc.Shared (safeRead)
4647
4748import Control.Monad (mzero, void, when)
4849import Data.Char (toLower)
@@ -154,6 +155,8 @@ optionLine = try $ do
154155 "seq_todo" -> todoSequence >>= updateState . registerTodoSequence
155156 "typ_todo" -> todoSequence >>= updateState . registerTodoSequence
156157 "macro" -> macroDefinition >>= updateState . registerMacro
158+ "pandoc-emphasis-pre" -> emphChars >>= updateState . setEmphasisPreChar
159+ "pandoc-emphasis-post" -> emphChars >>= updateState . setEmphasisPostChar
157160 _ -> mzero
158161
159162addLinkFormat :: Monad m => String
@@ -184,6 +187,25 @@ parseFormat = try $ replacePlain <|> replaceUrl <|> justAppend
184187 rest = manyTill anyChar (eof <|> () <$ oneOf "\n\r")
185188 tillSpecifier c = manyTill (noneOf "\n\r") (try $ string ('%':c:""))
186189
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+
187209inlinesTillNewline :: PandocMonad m => OrgParser m (F Inlines)
188210inlinesTillNewline = do
189211 updateLastPreCharPos
src/Text/Pandoc/Readers/Org/ParserState.hs+11−1
@@ -29,6 +29,7 @@ Define the Org-mode parser state.
2929-}
3030module Text.Pandoc.Readers.Org.ParserState
3131 ( OrgParserState (..)
32+ , defaultOrgParserState
3233 , OrgParserLocal (..)
3334 , OrgNoteRecord
3435 , HasReaderOptions (..)
@@ -104,6 +105,11 @@ type TodoSequence = [TodoMarker]
104105data OrgParserState = OrgParserState
105106 { orgStateAnchorIds :: [String]
106107 , 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
107113 , orgStateEmphasisNewlines :: Maybe Int
108114 , orgStateExportSettings :: ExportSettings
109115 , orgStateHeaderMap :: M.Map Inlines String
@@ -124,7 +130,9 @@ data OrgParserState = OrgParserState
124130 , orgMacros :: M.Map Text Macro
125131 }
126132
127−data OrgParserLocal = OrgParserLocal { orgLocalQuoteContext :: QuoteContext }
133+data OrgParserLocal = OrgParserLocal
134+ { orgLocalQuoteContext :: QuoteContext
135+ }
128136
129137instance Default OrgParserLocal where
130138 def = OrgParserLocal NoQuote
@@ -168,6 +176,8 @@ instance Default OrgParserState where
168176defaultOrgParserState :: OrgParserState
169177defaultOrgParserState = OrgParserState
170178 { orgStateAnchorIds = []
179+ , orgStateEmphasisPreChars = "-\t ('\"{"
180+ , orgStateEmphasisPostChars = "-\t\n .,:!?;'\")}["
171181 , orgStateEmphasisCharStack = []
172182 , orgStateEmphasisNewlines = Nothing
173183 , orgStateExportSettings = def
test/Tests/Readers/Org/Meta.hs+19−1
@@ -1,7 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Tests.Readers.Org.Meta (tests) where
33
4−import Test.Tasty (TestTree)
4+import Test.Tasty (TestTree, testGroup)
55import Tests.Helpers ((=?>))
66import Tests.Readers.Org.Shared ((=:), spcSep)
77import Text.Pandoc
@@ -170,4 +170,22 @@ tests =
170170 , "[[expl:foo][bar]]"
171171 ] =?>
172172 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+ ]
173191 ]