git.iko.soy/typeable/pandoc
on master help sign in
Implemented @ for sequentially numbered examples.
6972c0bJohn MacFarlane
README+27−1
@@ -667,12 +667,38 @@ So, the following yields a list numbered sequentially starting from 2:
667 1. Four
667 1. Four
668 * Five
668 * Five
669
669
670−If default list markers are desired, use '`#.`':
670+If default list markers are desired, use `#.`:
671
671
672 #. one
672 #. one
673 #. two
673 #. two
674 #. three
674 #. three
675
675
676+Numbered examples
677+-----------------
678+
679+The special list marker `@` can be used for sequentially numbered
680+examples. The first list item with a `@` marker will be numbered '1',
681+the next '2', and so on, throughout the document. The numbered examples
682+need not occur in a single list; each new list using `@` will take up
683+where the last stopped. So, for example:
684+
685+ (@) My first example will be numbered (1).
686+ (@) My second example will be numbered (2).
687+
688+ Explanation of examples.
689+
690+ (@) My third example will be numbered (3).
691+
692+Numbered examples can be labeled and referred to later in the
693+document:
694+
695+ (@good) This is a good example.
696+
697+ As (@good) illustrates, ...
698+
699+The label can be any string of alphanumeric characters, underscores,
700+or hyphens. The example must occur before the reference.
701+
676Definition lists
702Definition lists
677----------------
703----------------
678
704
src/Text/Pandoc/Definition.hs+1
@@ -52,6 +52,7 @@ type ListAttributes = (Int, ListNumberStyle, ListNumberDelim)
52
52
53-- | Style of list numbers.
53-- | Style of list numbers.
54data ListNumberStyle = DefaultStyle
54data ListNumberStyle = DefaultStyle
55+ | Example
55 | Decimal
56 | Decimal
56 | LowerRoman
57 | LowerRoman
57 | UpperRoman
58 | UpperRoman
src/Text/Pandoc/Readers/Markdown.hs+12−1
@@ -35,6 +35,7 @@ import Data.List ( transpose, isSuffixOf, sortBy, findIndex, intercalate )
35import Data.Ord ( comparing )
35import Data.Ord ( comparing )
36import Data.Char ( isAlphaNum )
36import Data.Char ( isAlphaNum )
37import Data.Maybe
37import Data.Maybe
38+import qualified Data.Map as M
38import Text.Pandoc.Definition
39import Text.Pandoc.Definition
39import Text.Pandoc.Shared
40import Text.Pandoc.Shared
40import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment' )
41import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment' )
@@ -67,7 +68,7 @@ setextHChars = "=-"
67
68
68-- treat these as potentially non-text when parsing inline:
69-- treat these as potentially non-text when parsing inline:
69specialChars :: [Char]
70specialChars :: [Char]
70−specialChars = "\\[]*_~`<>$!^-.&'\"\8216\8217\8220\8221;"
71+specialChars = "\\[]*_~`<>$!^-.&@'\"\8216\8217\8220\8221;"
71
72
72--
73--
73-- auxiliary functions
74-- auxiliary functions
@@ -915,6 +916,7 @@ inlineParsers = [ str
915 , rawHtmlInline'
916 , rawHtmlInline'
916 , rawLaTeXInline'
917 , rawLaTeXInline'
917 , escapedChar
918 , escapedChar
919+ , exampleRef
918 , symbol
920 , symbol
919 , ltSign ]
921 , ltSign ]
920
922
@@ -950,6 +952,15 @@ ltSign = do
950specialCharsMinusLt :: [Char]
952specialCharsMinusLt :: [Char]
951specialCharsMinusLt = filter (/= '<') specialChars
953specialCharsMinusLt = filter (/= '<') specialChars
952
954
955+exampleRef :: GenParser Char ParserState Inline
956+exampleRef = try $ do
957+ char '@'
958+ lab <- many1 (alphaNum <|> oneOf "-_")
959+ examples <- liftM stateExamples getState
960+ case M.lookup lab examples of
961+ Just num -> return (Str $ show num)
962+ Nothing -> pzero
963+
953symbol :: GenParser Char ParserState Inline
964symbol :: GenParser Char ParserState Inline
954symbol = do
965symbol = do
955 result <- oneOf specialCharsMinusLt
966 result <- oneOf specialCharsMinusLt
src/Text/Pandoc/Readers/RST.hs+1−1
@@ -425,7 +425,7 @@ bulletListStart = try $ do
425-- parses ordered list start and returns its length (inc following whitespace)
425-- parses ordered list start and returns its length (inc following whitespace)
426orderedListStart :: ListNumberStyle
426orderedListStart :: ListNumberStyle
427 -> ListNumberDelim
427 -> ListNumberDelim
428− -> GenParser Char st Int
428+ -> GenParser Char ParserState Int
429orderedListStart style delim = try $ do
429orderedListStart style delim = try $ do
430 (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim)
430 (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim)
431 white <- many1 spaceChar
431 white <- many1 spaceChar
src/Text/Pandoc/Shared.hs+28−5
@@ -576,6 +576,23 @@ decimal = do
576 num <- many1 digit
576 num <- many1 digit
577 return (Decimal, read num)
577 return (Decimal, read num)
578
578
579+-- | Parses a '@' and optional label and
580+-- returns (DefaultStyle, [next example number]). The next
581+-- example number is incremented in parser state, and the label
582+-- (if present) is added to the label table.
583+exampleNum :: GenParser Char ParserState (ListNumberStyle, Int)
584+exampleNum = do
585+ char '@'
586+ lab <- many (alphaNum <|> oneOf "_-")
587+ st <- getState
588+ let num = stateNextExample st
589+ let newlabels = if null lab
590+ then stateExamples st
591+ else M.insert lab num $ stateExamples st
592+ updateState $ \s -> s{ stateNextExample = num + 1
593+ , stateExamples = newlabels }
594+ return (Example, num)
595+
579-- | Parses a '#' returns (DefaultStyle, 1).
596-- | Parses a '#' returns (DefaultStyle, 1).
580defaultNum :: GenParser Char st (ListNumberStyle, Int)
597defaultNum :: GenParser Char st (ListNumberStyle, Int)
581defaultNum = do
598defaultNum = do
@@ -600,10 +617,10 @@ romanOne = (char 'i' >> return (LowerRoman, 1)) <|>
600 (char 'I' >> return (UpperRoman, 1))
617 (char 'I' >> return (UpperRoman, 1))
601
618
602-- | Parses an ordered list marker and returns list attributes.
619-- | Parses an ordered list marker and returns list attributes.
603−anyOrderedListMarker :: GenParser Char st ListAttributes
620+anyOrderedListMarker :: GenParser Char ParserState ListAttributes
604anyOrderedListMarker = choice $
621anyOrderedListMarker = choice $
605 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
622 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
606− numParser <- [decimal, defaultNum, romanOne,
623+ numParser <- [decimal, exampleNum, defaultNum, romanOne,
607 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
624 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
608
625
609-- | Parses a list number (num) followed by a period, returns list attributes.
626-- | Parses a list number (num) followed by a period, returns list attributes.
@@ -638,11 +655,12 @@ inTwoParens num = try $ do
638-- returns number.
655-- returns number.
639orderedListMarker :: ListNumberStyle
656orderedListMarker :: ListNumberStyle
640 -> ListNumberDelim
657 -> ListNumberDelim
641− -> GenParser Char st Int
658+ -> GenParser Char ParserState Int
642orderedListMarker style delim = do
659orderedListMarker style delim = do
643 let num = defaultNum <|> -- # can continue any kind of list
660 let num = defaultNum <|> -- # can continue any kind of list
644 case style of
661 case style of
645 DefaultStyle -> decimal
662 DefaultStyle -> decimal
663+ Example -> exampleNum
646 Decimal -> decimal
664 Decimal -> decimal
647 UpperRoman -> upperRoman
665 UpperRoman -> upperRoman
648 LowerRoman -> lowerRoman
666 LowerRoman -> lowerRoman
@@ -700,7 +718,9 @@ data ParserState = ParserState
700 stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
718 stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
701 stateColumns :: Int, -- ^ Number of columns in terminal
719 stateColumns :: Int, -- ^ Number of columns in terminal
702 stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
720 stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
703− stateIndentedCodeClasses :: [String] -- ^ Classes to use for indented code blocks
721+ stateIndentedCodeClasses :: [String], -- ^ Classes to use for indented code blocks
722+ stateNextExample :: Int, -- ^ Number of next example
723+ stateExamples :: M.Map String Int -- ^ Map from example labels to numbers
704 }
724 }
705 deriving Show
725 deriving Show
706
726
@@ -725,7 +745,9 @@ defaultParserState =
725 stateLiterateHaskell = False,
745 stateLiterateHaskell = False,
726 stateColumns = 80,
746 stateColumns = 80,
727 stateHeaderTable = [],
747 stateHeaderTable = [],
728− stateIndentedCodeClasses = [] }
748+ stateIndentedCodeClasses = [],
749+ stateNextExample = 1,
750+ stateExamples = M.empty }
729
751
730data HeaderType
752data HeaderType
731 = SingleHeader Char -- ^ Single line of characters underneath
753 = SingleHeader Char -- ^ Single line of characters underneath
@@ -855,6 +877,7 @@ orderedListMarkers (start, numstyle, numdelim) =
855 let singleton c = [c]
877 let singleton c = [c]
856 nums = case numstyle of
878 nums = case numstyle of
857 DefaultStyle -> map show [start..]
879 DefaultStyle -> map show [start..]
880+ Example -> map show [start..]
858 Decimal -> map show [start..]
881 Decimal -> map show [start..]
859 UpperAlpha -> drop (start - 1) $ cycle $
882 UpperAlpha -> drop (start - 1) $ cycle $
860 map singleton ['A'..'Z']
883 map singleton ['A'..'Z']
src/Text/Pandoc/Writers/ConTeXt.hs+1
@@ -153,6 +153,7 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
153 let style'' = case style' of
153 let style'' = case style' of
154 DefaultStyle -> orderedListStyles !! level
154 DefaultStyle -> orderedListStyles !! level
155 Decimal -> "[n]"
155 Decimal -> "[n]"
156+ Example -> "[n]"
156 LowerRoman -> "[r]"
157 LowerRoman -> "[r]"
157 UpperRoman -> "[R]"
158 UpperRoman -> "[R]"
158 LowerAlpha -> "[a]"
159 LowerAlpha -> "[a]"
src/Text/Pandoc/Writers/Docbook.hs+1
@@ -154,6 +154,7 @@ blockToDocbook opts (OrderedList (start, numstyle, _) (first:rest)) =
154 let attribs = case numstyle of
154 let attribs = case numstyle of
155 DefaultStyle -> []
155 DefaultStyle -> []
156 Decimal -> [("numeration", "arabic")]
156 Decimal -> [("numeration", "arabic")]
157+ Example -> [("numeration", "arabic")]
157 UpperAlpha -> [("numeration", "upperalpha")]
158 UpperAlpha -> [("numeration", "upperalpha")]
158 LowerAlpha -> [("numeration", "loweralpha")]
159 LowerAlpha -> [("numeration", "loweralpha")]
159 UpperRoman -> [("numeration", "upperroman")]
160 UpperRoman -> [("numeration", "upperroman")]
src/Text/Pandoc/Writers/Markdown.hs+3−3
@@ -34,7 +34,7 @@ import Text.Pandoc.Definition
34import Text.Pandoc.Templates (renderTemplate)
34import Text.Pandoc.Templates (renderTemplate)
35import Text.Pandoc.Shared
35import Text.Pandoc.Shared
36import Text.Pandoc.Blocks
36import Text.Pandoc.Blocks
37−import Text.ParserCombinators.Parsec ( parse, GenParser )
37+import Text.ParserCombinators.Parsec ( runParser, GenParser )
38import Data.List ( group, isPrefixOf, find, intersperse, transpose )
38import Data.List ( group, isPrefixOf, find, intersperse, transpose )
39import Text.PrettyPrint.HughesPJ hiding ( Str )
39import Text.PrettyPrint.HughesPJ hiding ( Str )
40import Control.Monad.State
40import Control.Monad.State
@@ -158,7 +158,7 @@ elementToListItem (Sec _ _ _ headerText subsecs) = [Plain headerText] ++
158 else [BulletList $ map elementToListItem subsecs]
158 else [BulletList $ map elementToListItem subsecs]
159
159
160-- | Ordered list start parser for use in Para below.
160-- | Ordered list start parser for use in Para below.
161−olMarker :: GenParser Char st Char
161+olMarker :: GenParser Char ParserState Char
162olMarker = do (start, style', delim) <- anyOrderedListMarker
162olMarker = do (start, style', delim) <- anyOrderedListMarker
163 if delim == Period &&
163 if delim == Period &&
164 (style' == UpperAlpha || (style' == UpperRoman &&
164 (style' == UpperAlpha || (style' == UpperRoman &&
@@ -169,7 +169,7 @@ olMarker = do (start, style', delim) <- anyOrderedListMarker
169-- | True if string begins with an ordered list marker
169-- | True if string begins with an ordered list marker
170beginsWithOrderedListMarker :: String -> Bool
170beginsWithOrderedListMarker :: String -> Bool
171beginsWithOrderedListMarker str =
171beginsWithOrderedListMarker str =
172− case parse olMarker "para start" str of
172+ case runParser olMarker defaultParserState "para start" str of
173 Left _ -> False
173 Left _ -> False
174 Right _ -> True
174 Right _ -> True
175
175
src/Text/Pandoc/Writers/Texinfo.hs+1
@@ -144,6 +144,7 @@ blockToTexinfo (OrderedList (start, numstyle, _) lst) = do
144 exemplar = case numstyle of
144 exemplar = case numstyle of
145 DefaultStyle -> decimal
145 DefaultStyle -> decimal
146 Decimal -> decimal
146 Decimal -> decimal
147+ Example -> decimal
147 UpperRoman -> decimal -- Roman numerals not supported
148 UpperRoman -> decimal -- Roman numerals not supported
148 LowerRoman -> decimal
149 LowerRoman -> decimal
149 UpperAlpha -> upperAlpha
150 UpperAlpha -> upperAlpha