git.iko.soy/typeable/pandoc
on master help sign in
Reverted changes in r1086 (implicit section header references).

This caused too much of a performance hit. git-svn-id: https://pandoc.googlecode.com/svn/trunk@1093 788f1e2b-df1e-0410-8736-df70ead52e1b

commit7deee9c874f6ee3606460052a5dc22b342166a19 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateFri 23 Nov 2007, 03:51 (19 years ago) parent66efec1
4 files changed+126−169
README+3−23 src/Text/Pandoc/Readers/Markdown.hs+74−93 src/Text/Pandoc/Shared.hs+3−53 src/Text/Pandoc/Writers/HTML.hs+46
README+3−23
@@ -299,7 +299,7 @@ For further documentation, see the `pandoc(1)` man page.
299299: includes *string* as a prefix at the beginning of the title that
300300 appears in the HTML header (but not in the title as it appears at
301301 the beginning of the HTML body). (See below on
302− [Title Blocks].)
302+ [Title Blocks](#title-blocks).)
303303
304304`-S` or `--smart`
305305: causes `pandoc` to produce typographically correct output, along the
@@ -797,28 +797,8 @@ another. A link to this section, for example, might look like this:
797797
798798 See the section on [header identifiers](#header-identifiers-in-html).
799799
800−Note that this method of providing links to sections works only in
801−HTML.
802−
803−Shortcut links to section headers
804−---------------------------------
805−
806−You may use the following shortcut to link to a section header:
807−
808− See the section on [Header identifiers in HTML].
809−
810−Pandoc will behave as if the document contains
811−
812− [Header identifiers in HTML]: #header-identifiers-in-html
813−
814−If there are multiple headers labeled "Header identifiers in HTML",
815−this will link to the first one. Note that implicit references are always
816−overridden by explicit ones, so the link in the following text
817−will be to `/url`, not `#header-identifiers-in-html`:
818−
819− See the section on [Header identifiers in HTML].
820−
821− [Header identifiers in HTML]: /url
800+Note, however, that this method of providing links to sections works
801+only in HTML.
822802
823803Box-style blockquotes
824804---------------------
src/Text/Pandoc/Readers/Markdown.hs+74−93
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1919{- |
2020 Module : Text.Pandoc.Readers.Markdown
2121 Copyright : Copyright (C) 2006-7 John MacFarlane
22− License : GNU GPL, version 2 or above
22+ License : GNU GPL, version 2 or above
2323
2424 Maintainer : John MacFarlane <jgm@berkeley.edu>
2525 Stability : alpha
@@ -27,8 +27,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2727
2828Conversion of markdown-formatted plain text to 'Pandoc' document.
2929-}
30−module Text.Pandoc.Readers.Markdown (
31− readMarkdown
30+module Text.Pandoc.Readers.Markdown (
31+ readMarkdown
3232 ) where
3333
3434import Data.List ( transpose, isPrefixOf, isSuffixOf, lookup, sortBy, findIndex )
@@ -37,9 +37,9 @@ import Data.Char ( isAlphaNum )
3737import Data.Maybe ( fromMaybe )
3838import Network.URI ( isURI )
3939import Text.Pandoc.Definition
40−import Text.Pandoc.Shared
40+import Text.Pandoc.Shared
4141import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment )
42−import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
42+import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
4343 anyHtmlInlineTag, anyHtmlTag,
4444 anyHtmlEndTag, htmlEndTag, extractTagType,
4545 htmlBlockElement )
@@ -69,14 +69,14 @@ specialChars = "\\[]*_~`<>$!^-.&'\"\8216\8217\8220\8221"
6969indentSpaces = try $ do
7070 state <- getState
7171 let tabStop = stateTabStop state
72− try (count tabStop (char ' ')) <|>
72+ try (count tabStop (char ' ')) <|>
7373 (many (char ' ') >> string "\t") <?> "indentation"
7474
7575nonindentSpaces = do
7676 state <- getState
7777 let tabStop = stateTabStop state
7878 sps <- many (char ' ')
79− if length sps < tabStop
79+ if length sps < tabStop
8080 then return sps
8181 else unexpected "indented line"
8282
@@ -91,8 +91,8 @@ failUnlessSmart = do
9191 if stateSmart state then return () else fail "Smart typography feature"
9292
9393-- | Parse an inline Str element with a given content.
94−inlineString str = try $ do
95− (Str res) <- inline
94+inlineString str = try $ do
95+ (Str res) <- inline
9696 if res == str then return res else fail $ "unexpected Str content"
9797
9898-- | Parse a sequence of inline elements between a string
@@ -103,9 +103,9 @@ inlinesInBalanced opener closer = try $ do
103103 string opener
104104 result <- manyTill ( (do lookAhead (inlineString opener)
105105 -- because it might be a link...
106− bal <- inlinesInBalanced opener closer
106+ bal <- inlinesInBalanced opener closer
107107 return $ [Str opener] ++ bal ++ [Str closer])
108− <|> (count 1 inline))
108+ <|> (count 1 inline))
109109 (try (string closer))
110110 return $ concat result
111111
@@ -115,7 +115,7 @@ inlinesInBalanced opener closer = try $ do
115115
116116titleLine = try $ char '%' >> skipSpaces >> manyTill inline newline
117117
118−authorsLine = try $ do
118+authorsLine = try $ do
119119 char '%'
120120 skipSpaces
121121 authors <- sepEndBy (many1 (noneOf ",;\n")) (oneOf ",;")
@@ -143,24 +143,15 @@ parseMarkdown = do
143143 startPos <- getPosition
144144 -- go through once just to get list of reference keys
145145 -- docMinusKeys is the raw document with blanks where the keys were...
146− docMinusKeys <- manyTill (referenceKey <|> headerReference <|>
147− lineClump) eof >>= return . concat
146+ docMinusKeys <- manyTill (referenceKey <|> lineClump) eof >>=
147+ return . concat
148148 setInput docMinusKeys
149149 setPosition startPos
150150 st <- getState
151− -- get headers and construct implicit references unless strict
152− if stateStrict st
153− then return ()
154− else do let oldkeys = stateKeys st
155− let headers = reverse $ stateHeaders st
156− let idents = uniqueIdentifiers headers
157− let implicitRefs = zipWith (\hd ident -> (hd, ("#" ++ ident, "")))
158− headers idents
159− updateState $ \st -> st { stateKeys = oldkeys ++ implicitRefs }
160151 -- go through again for notes unless strict...
161152 if stateStrict st
162153 then return ()
163− else do docMinusNotes <- manyTill (noteBlock <|> lineClump) eof >>=
154+ else do docMinusNotes <- manyTill (noteBlock <|> lineClump) eof >>=
164155 return . concat
165156 st <- getState
166157 let reversedNotes = stateNotes st
@@ -169,10 +160,10 @@ parseMarkdown = do
169160 setPosition startPos
170161 -- now parse it for real...
171162 (title, author, date) <- option ([],[],"") titleBlock
172− blocks <- parseBlocks
163+ blocks <- parseBlocks
173164 return $ Pandoc (Meta title author date) $ filter (/= Null) blocks
174165
175−--
166+--
176167-- initial pass for references and notes
177168--
178169
@@ -195,17 +186,7 @@ referenceKey = try $ do
195186 -- return blanks so line count isn't affected
196187 return $ replicate (sourceLine endPos - sourceLine startPos) '\n'
197188
198−headerReference = try $ do
199− failIfStrict
200− startPos <- getPosition
201− (Header level text) <- lookAhead $ atxHeader <|> setextHeader
202− st <- getState
203− let headers = stateHeaders st
204− updateState $ \st -> st { stateHeaders = text:headers }
205− endPos <- getPosition
206− lineClump -- return the raw header, because we need to parse it later
207−
208−referenceTitle = try $ do
189+referenceTitle = try $ do
209190 (many1 spaceChar >> option '\n' newline) <|> newline
210191 skipSpaces
211192 tit <- (charsInBalanced '(' ')' >>= return . unwords . words)
@@ -220,7 +201,7 @@ rawLine = do
220201 notFollowedBy blankline
221202 notFollowedBy' noteMarker
222203 contents <- many1 nonEndline
223− end <- option "" (newline >> optional indentSpaces >> return "\n")
204+ end <- option "" (newline >> optional indentSpaces >> return "\n")
224205 return $ contents ++ end
225206
226207rawLines = many1 rawLine >>= return . concat
@@ -249,7 +230,7 @@ noteBlock = try $ do
249230
250231parseBlocks = manyTill block eof
251232
252−block = choice [ header
233+block = choice [ header
253234 , table
254235 , codeBlock
255236 , hrule
@@ -304,7 +285,7 @@ hrule = try $ do
304285indentedLine = indentSpaces >> manyTill anyChar newline >>= return . (++ "\n")
305286
306287codeBlock = do
307− contents <- many1 (indentedLine <|>
288+ contents <- many1 (indentedLine <|>
308289 try (do b <- blanklines
309290 l <- indentedLine
310291 return $ b ++ l))
@@ -319,7 +300,7 @@ emacsBoxQuote = try $ do
319300 failIfStrict
320301 string ",----"
321302 manyTill anyChar newline
322− raw <- manyTill
303+ raw <- manyTill
323304 (try (char '|' >> optional (char ' ') >> manyTill anyChar newline))
324305 (try (string "`----"))
325306 blanklines
@@ -329,7 +310,7 @@ emailBlockQuoteStart = try $ nonindentSpaces >> char '>' >>~ optional (char ' ')
329310
330311emailBlockQuote = try $ do
331312 emailBlockQuoteStart
332− raw <- sepBy (many (nonEndline <|>
313+ raw <- sepBy (many (nonEndline <|>
333314 (try (endline >> notFollowedBy emailBlockQuoteStart >>
334315 return '\n'))))
335316 (try (newline >> emailBlockQuoteStart))
@@ -337,12 +318,12 @@ emailBlockQuote = try $ do
337318 optional blanklines
338319 return raw
339320
340−blockQuote = do
321+blockQuote = do
341322 raw <- emailBlockQuote <|> emacsBoxQuote
342323 -- parse the extracted block, which may contain various block elements:
343324 contents <- parseFromString parseBlocks $ (joinWithSep "\n" raw) ++ "\n\n"
344325 return $ BlockQuote contents
345−
326+
346327--
347328-- list blocks
348329--
@@ -377,7 +358,7 @@ orderedListStart style delim = try $ do
377358 then do many1 digit
378359 char '.'
379360 return 1
380− else orderedListMarker style delim
361+ else orderedListMarker style delim
381362 if delim == Period && (style == UpperAlpha || (style == UpperRoman &&
382363 num `elem` [1, 5, 10, 50, 100, 500, 1000]))
383364 then char '\t' <|> (spaceChar >> spaceChar)
@@ -401,7 +382,7 @@ rawListItem start = try $ do
401382 blanks <- many blankline
402383 return $ concat result ++ blanks
403384
404−-- continuation of a list item - indented and separated by blankline
385+-- continuation of a list item - indented and separated by blankline
405386-- or (in compact lists) endline.
406387-- note: nested lists are parsed as continuations
407388listContinuation start = try $ do
@@ -417,7 +398,7 @@ listContinuationLine start = try $ do
417398 result <- manyTill anyChar newline
418399 return $ result ++ "\n"
419400
420−listItem start = try $ do
401+listItem start = try $ do
421402 first <- rawListItem start
422403 continuations <- many (listContinuation start)
423404 -- parsing with ListItemState forces markers at beginning of lines to
@@ -437,7 +418,7 @@ orderedList = try $ do
437418 items <- many1 (listItem (orderedListStart style delim))
438419 return $ OrderedList (start, style, delim) $ compactify items
439420
440−bulletList = many1 (listItem bulletListStart) >>=
421+bulletList = many1 (listItem bulletListStart) >>=
441422 return . BulletList . compactify
442423
443424-- definition lists
@@ -478,7 +459,7 @@ definitionList = do
478459-- paragraph block
479460--
480461
481−para = try $ do
462+para = try $ do
482463 result <- many1 inline
483464 newline
484465 blanklines <|> do st <- getState
@@ -487,9 +468,9 @@ para = try $ do
487468 else lookAhead emacsBoxQuote >> return ""
488469 return $ Para $ normalizeSpaces result
489470
490−plain = many1 inline >>= return . Plain . normalizeSpaces
471+plain = many1 inline >>= return . Plain . normalizeSpaces
491472
492−--
473+--
493474-- raw html
494475--
495476
@@ -506,25 +487,25 @@ htmlBlock = do
506487 else rawHtmlBlocks
507488
508489-- True if tag is self-closing
509−isSelfClosing tag =
490+isSelfClosing tag =
510491 isSuffixOf "/>" $ filter (not . (`elem` " \n\t")) tag
511492
512493strictHtmlBlock = try $ do
513− tag <- anyHtmlBlockTag
494+ tag <- anyHtmlBlockTag
514495 let tag' = extractTagType tag
515− if isSelfClosing tag || tag' == "hr"
496+ if isSelfClosing tag || tag' == "hr"
516497 then return tag
517− else do contents <- many (notFollowedBy' (htmlEndTag tag') >>
498+ else do contents <- many (notFollowedBy' (htmlEndTag tag') >>
518499 (htmlElement <|> (count 1 anyChar)))
519500 end <- htmlEndTag tag'
520501 return $ tag ++ concat contents ++ end
521502
522503rawHtmlBlocks = do
523− htmlBlocks <- many1 rawHtmlBlock
504+ htmlBlocks <- many1 rawHtmlBlock
524505 let combined = concatMap (\(RawHtml str) -> str) htmlBlocks
525506 let combined' = if not (null combined) && last combined == '\n'
526− then init combined -- strip extra newline
527− else combined
507+ then init combined -- strip extra newline
508+ else combined
528509 return $ RawHtml combined'
529510
530511--
@@ -535,7 +516,7 @@ rawLaTeXEnvironment' = failIfStrict >> rawLaTeXEnvironment
535516
536517--
537518-- Tables
538−--
519+--
539520
540521-- Parse a dashed line with optional trailing spaces; return its length
541522-- and the length including trailing space.
@@ -544,7 +525,7 @@ dashedLine ch = do
544525 sp <- many spaceChar
545526 return $ (length dashes, length $ dashes ++ sp)
546527
547−-- Parse a table header with dashed lines of '-' preceded by
528+-- Parse a table header with dashed lines of '-' preceded by
548529-- one line of text.
549530simpleTableHeader = try $ do
550531 rawContent <- anyLine
@@ -567,7 +548,7 @@ tableSep = try $ nonindentSpaces >> many1 (dashedLine '-') >> string "\n"
567548rawTableLine indices = do
568549 notFollowedBy' (blanklines <|> tableFooter)
569550 line <- many1Till anyChar newline
570− return $ map removeLeadingTrailingSpace $ tail $
551+ return $ map removeLeadingTrailingSpace $ tail $
571552 splitByIndices (init indices) line
572553
573554-- Parse a table line and return a list of lists of blocks (columns).
@@ -584,8 +565,8 @@ multilineRow indices = do
584565widthsFromIndices :: Int -- Number of columns on terminal
585566 -> [Int] -- Indices
586567 -> [Float] -- Fractional relative sizes of columns
587−widthsFromIndices _ [] = []
588−widthsFromIndices numColumns indices =
568+widthsFromIndices _ [] = []
569+widthsFromIndices numColumns indices =
589570 let lengths = zipWith (-) indices (0:indices)
590571 totLength = sum lengths
591572 quotient = if totLength > numColumns
@@ -624,14 +605,14 @@ simpleTable = tableWith simpleTableHeader tableLine blanklines
624605multilineTable = tableWith multilineTableHeader multilineRow tableFooter
625606
626607multilineTableHeader = try $ do
627− tableSep
608+ tableSep
628609 rawContent <- many1 (notFollowedBy' tableSep >> many1Till anyChar newline)
629610 initSp <- nonindentSpaces
630611 dashes <- many1 (dashedLine '-')
631612 newline
632613 let (lengths, lines) = unzip dashes
633614 let indices = scanl (+) (length initSp) lines
634− let rawHeadsList = transpose $ map
615+ let rawHeadsList = transpose $ map
635616 (\ln -> tail $ splitByIndices (init indices) ln)
636617 rawContent
637618 let rawHeads = map (joinWithSep " ") rawHeadsList
@@ -644,7 +625,7 @@ multilineTableHeader = try $ do
644625alignType :: [String] -> Int -> Alignment
645626alignType [] len = AlignDefault
646627alignType strLst len =
647− let str = head $ sortBy (comparing length) $
628+ let str = head $ sortBy (comparing length) $
648629 map removeTrailingSpace strLst
649630 leftSpace = if null str then False else (str !! 0) `elem` " \t"
650631 rightSpace = length str < len || (str !! (len - 1)) `elem` " \t"
@@ -656,7 +637,7 @@ alignType strLst len =
656637
657638table = failIfStrict >> (simpleTable <|> multilineTable) <?> "table"
658639
659−--
640+--
660641-- inline
661642--
662643
@@ -686,7 +667,7 @@ inline = choice [ str
686667escapedChar = do
687668 char '\\'
688669 state <- getState
689− result <- option '\\' $ if stateStrict state
670+ result <- option '\\' $ if stateStrict state
690671 then oneOf "\\`*_{}[]()>#+-.!~"
691672 else satisfy (not . isAlphaNum)
692673 return $ Str [result]
@@ -700,17 +681,17 @@ ltSign = do
700681
701682specialCharsMinusLt = filter (/= '<') specialChars
702683
703−symbol = do
684+symbol = do
704685 result <- oneOf specialCharsMinusLt
705686 return $ Str [result]
706687
707688-- parses inline code, between n `s and n `s
708−code = try $ do
689+code = try $ do
709690 starts <- many1 (char '`')
710691 skipSpaces
711692 result <- many1Till (many1 (noneOf "`\n") <|> many1 (char '`') <|>
712− (char '\n' >> return " "))
713− (try (skipSpaces >> count (length starts) (char '`') >>
693+ (char '\n' >> return " "))
694+ (try (skipSpaces >> count (length starts) (char '`') >>
714695 notFollowedBy (char '`')))
715696 return $ Code $ removeLeadingTrailingSpace $ concat result
716697
@@ -726,30 +707,30 @@ math = try $ do
726707 return $ TeX ("$" ++ (joinWithSep " " words) ++ "$")
727708
728709emph = ((enclosed (char '*') (char '*') inline) <|>
729− (enclosed (char '_') (char '_' >> notFollowedBy alphaNum) inline)) >>=
710+ (enclosed (char '_') (char '_' >> notFollowedBy alphaNum) inline)) >>=
730711 return . Emph . normalizeSpaces
731712
732−strong = ((enclosed (string "**") (try $ string "**") inline) <|>
713+strong = ((enclosed (string "**") (try $ string "**") inline) <|>
733714 (enclosed (string "__") (try $ string "__") inline)) >>=
734715 return . Strong . normalizeSpaces
735716
736717strikeout = failIfStrict >> enclosed (string "~~") (try $ string "~~") inline >>=
737718 return . Strikeout . normalizeSpaces
738719
739−superscript = failIfStrict >> enclosed (char '^') (char '^')
720+superscript = failIfStrict >> enclosed (char '^') (char '^')
740721 (notFollowedBy' whitespace >> inline) >>= -- may not contain Space
741722 return . Superscript
742723
743724subscript = failIfStrict >> enclosed (char '~') (char '~')
744725 (notFollowedBy' whitespace >> inline) >>= -- may not contain Space
745− return . Subscript
726+ return . Subscript
746727
747−smartPunctuation = failUnlessSmart >>
728+smartPunctuation = failUnlessSmart >>
748729 choice [ quoted, apostrophe, dash, ellipses ]
749730
750731apostrophe = (char '\'' <|> char '\8217') >> return Apostrophe
751732
752−quoted = doubleQuoted <|> singleQuoted
733+quoted = doubleQuoted <|> singleQuoted
753734
754735withQuoteContext context parser = do
755736 oldState <- getState
@@ -765,7 +746,7 @@ singleQuoted = try $ do
765746 withQuoteContext InSingleQuote $ many1Till inline singleQuoteEnd >>=
766747 return . Quoted SingleQuote . normalizeSpaces
767748
768−doubleQuoted = try $ do
749+doubleQuoted = try $ do
769750 doubleQuoteStart
770751 withQuoteContext InDoubleQuote $ many1Till inline doubleQuoteEnd >>=
771752 return . Quoted DoubleQuote . normalizeSpaces
@@ -776,13 +757,13 @@ failIfInQuoteContext context = do
776757 then fail "already inside quotes"
777758 else return ()
778759
779−singleQuoteStart = do
760+singleQuoteStart = do
780761 failIfInQuoteContext InSingleQuote
781− char '\8216' <|>
782− (try $ do char '\''
762+ char '\8216' <|>
763+ (try $ do char '\''
783764 notFollowedBy (oneOf ")!],.;:-? \t\n")
784765 notFollowedBy (try (oneOfStrings ["s","t","m","ve","ll","re"] >>
785− satisfy (not . isAlphaNum)))
766+ satisfy (not . isAlphaNum)))
786767 -- possess/contraction
787768 return '\'')
788769
@@ -826,13 +807,13 @@ endline = try $ do
826807 newline
827808 notFollowedBy blankline
828809 st <- getState
829− if stateStrict st
810+ if stateStrict st
830811 then do notFollowedBy emailBlockQuoteStart
831812 notFollowedBy (char '#') -- atx header
832− else return ()
813+ else return ()
833814 -- parse potential list-starts differently if in a list:
834815 if stateParserContext st == ListItemState
835− then notFollowedBy' (bulletListStart <|>
816+ then notFollowedBy' (bulletListStart <|>
836817 (anyOrderedListStart >> return ()))
837818 else return ()
838819 return Space
@@ -846,7 +827,7 @@ reference = notFollowedBy' (string "[^") >> -- footnote reference
846827 inlinesInBalanced "[" "]" >>= (return . normalizeSpaces)
847828
848829-- source for a link, with optional title
849−source = try $ do
830+source = try $ do
850831 char '('
851832 optional (char '<')
852833 src <- many (noneOf ")> \t\n")
@@ -856,7 +837,7 @@ source = try $ do
856837 char ')'
857838 return (removeTrailingSpace src, tit)
858839
859−linkTitle = try $ do
840+linkTitle = try $ do
860841 (many1 spaceChar >> option '\n' newline) <|> newline
861842 skipSpaces
862843 delim <- char '\'' <|> char '"'
@@ -871,13 +852,13 @@ link = try $ do
871852
872853-- a link like [this][ref] or [this][] or [this]
873854referenceLink label = do
874− ref <- option [] (try (optional (char ' ') >>
855+ ref <- option [] (try (optional (char ' ') >>
875856 optional (newline >> skipSpaces) >> reference))
876857 let ref' = if null ref then label else ref
877858 state <- getState
878859 case lookupKeySrc (stateKeys state) ref' of
879− Nothing -> fail "no corresponding key"
880− Just target -> return target
860+ Nothing -> fail "no corresponding key"
861+ Just target -> return target
881862
882863emailAddress = try $ do
883864 name <- many1 (alphaNum <|> char '+')
@@ -898,7 +879,7 @@ autoLink = try $ do
898879 char '>'
899880 let src' = if "mailto:" `isPrefixOf` src
900881 then drop 7 src
901− else src
882+ else src
902883 st <- getState
903884 return $ if stateStrict st
904885 then Link [Str src'] (src, "")
@@ -929,7 +910,7 @@ rawLaTeXInline' = failIfStrict >> rawLaTeXInline
929910rawHtmlInline' = do
930911 st <- getState
931912 result <- choice $ if stateStrict st
932− then [htmlBlockElement, anyHtmlTag, anyHtmlEndTag]
913+ then [htmlBlockElement, anyHtmlTag, anyHtmlEndTag]
933914 else [htmlBlockElement, anyHtmlInlineTag]
934915 return $ HtmlInline result
935916
src/Text/Pandoc/Shared.hs+3−53
@@ -34,7 +34,6 @@ module Text.Pandoc.Shared (
3434 substitute,
3535 joinWithSep,
3636 -- * Text processing
37− isPunctuation,
3837 backslashEscapes,
3938 escapeStringUsing,
4039 stripTrailingNewlines,
@@ -92,7 +91,6 @@ module Text.Pandoc.Shared (
9291 Element (..),
9392 hierarchicalize,
9493 isHeaderBlock,
95− uniqueIdentifiers,
9694 -- * Writer options
9795 WriterOptions (..),
9896 defaultWriterOptions
@@ -104,7 +102,7 @@ import Text.PrettyPrint.HughesPJ ( Doc, fsep, ($$), (<>), empty )
104102import qualified Text.PrettyPrint.HughesPJ as PP
105103import Text.Pandoc.CharacterReferences ( characterReference )
106104import Data.Char ( toLower, toUpper, ord, isLower, isUpper )
107−import Data.List ( find, isPrefixOf, intersperse )
105+import Data.List ( find, isPrefixOf )
108106import Control.Monad ( join )
109107
110108--
@@ -146,15 +144,6 @@ joinWithSep sep lst = foldr1 (\a b -> a ++ sep ++ b) lst
146144-- Text processing
147145--
148146
149−-- | True if character is a punctuation character (unicode).
150−isPunctuation :: Char -> Bool
151−isPunctuation c =
152− let c' = ord c
153− in if c `elem` "!\"'()*,-./:;<>?[\\]`{|}~" || c' >= 0x2000 && c' <= 0x206F ||
154− c' >= 0xE000 && c' <= 0xE0FF
155− then True
156− else False
157−
158147-- | Returns an association list of backslash escapes for the
159148-- designated characters.
160149backslashEscapes :: [Char] -- ^ list of special characters to escape
@@ -580,8 +569,7 @@ data ParserState = ParserState
580569 stateStrict :: Bool, -- ^ Use strict markdown syntax?
581570 stateSmart :: Bool, -- ^ Use smart typography?
582571 stateColumns :: Int, -- ^ Number of columns in terminal
583− stateHeaderTable :: [HeaderType], -- ^ Ordered list of header types used
584− stateHeaders :: [[Inline]] -- ^ List of header texts used
572+ stateHeaderTable :: [HeaderType] -- ^ Ordered list of header types used
585573 }
586574 deriving Show
587575
@@ -600,8 +588,7 @@ defaultParserState =
600588 stateStrict = False,
601589 stateSmart = False,
602590 stateColumns = 80,
603− stateHeaderTable = [],
604− stateHeaders = [] }
591+ stateHeaderTable = [] }
605592
606593data HeaderType
607594 = SingleHeader Char -- ^ Single line of characters underneath
@@ -803,43 +790,6 @@ isHeaderBlock :: Block -> Bool
803790isHeaderBlock (Header _ _) = True
804791isHeaderBlock _ = False
805792
806−-- | Convert Pandoc inline list to plain text identifier.
807−inlineListToIdentifier :: [Inline] -> String
808−inlineListToIdentifier [] = ""
809−inlineListToIdentifier (x:xs) =
810− xAsText ++ inlineListToIdentifier xs
811− where xAsText = case x of
812− Str s -> filter (\c -> c == '-' || not (isPunctuation c)) $
813− concat $ intersperse "-" $ words $ map toLower s
814− Emph lst -> inlineListToIdentifier lst
815− Strikeout lst -> inlineListToIdentifier lst
816− Superscript lst -> inlineListToIdentifier lst
817− Subscript lst -> inlineListToIdentifier lst
818− Strong lst -> inlineListToIdentifier lst
819− Quoted _ lst -> inlineListToIdentifier lst
820− Code s -> s
821− Space -> "-"
822− EmDash -> "-"
823− EnDash -> "-"
824− Apostrophe -> ""
825− Ellipses -> ""
826− LineBreak -> "-"
827− TeX _ -> ""
828− HtmlInline _ -> ""
829− Link lst _ -> inlineListToIdentifier lst
830− Image lst _ -> inlineListToIdentifier lst
831− Note _ -> ""
832−
833−-- | Return unique identifiers for list of inline lists.
834−uniqueIdentifiers :: [[Inline]] -> [String]
835−uniqueIdentifiers ls =
836− let addIdentifier (nonuniqueIds, uniqueIds) l =
837− let new = inlineListToIdentifier l
838− matches = length $ filter (== new) nonuniqueIds
839− new' = new ++ if matches > 0 then ("-" ++ show matches) else ""
840− in (new:nonuniqueIds, new':uniqueIds)
841− in reverse $ snd $ foldl addIdentifier ([],[]) ls
842−
843793--
844794-- Writer options
845795--
src/Text/Pandoc/Writers/HTML.hs+46
@@ -193,6 +193,15 @@ obfuscateChar char =
193193obfuscateString :: String -> String
194194obfuscateString = concatMap obfuscateChar . decodeCharacterReferences
195195
196+-- | True if character is a punctuation character (unicode).
197+isPunctuation :: Char -> Bool
198+isPunctuation c =
199+ let c' = ord c
200+ in if c `elem` "!\"'()*,-./:;<>?[\\]`{|}~" || c' >= 0x2000 && c' <= 0x206F ||
201+ c' >= 0xE000 && c' <= 0xE0FF
202+ then True
203+ else False
204+
196205-- | Add CSS for document header.
197206addToCSS :: String -> State WriterState ()
198207addToCSS item = do
@@ -200,6 +209,43 @@ addToCSS item = do
200209 let current = stCSS st
201210 put $ st {stCSS = S.insert item current}
202211
212+-- | Convert Pandoc inline list to plain text identifier.
213+inlineListToIdentifier :: [Inline] -> String
214+inlineListToIdentifier [] = ""
215+inlineListToIdentifier (x:xs) =
216+ xAsText ++ inlineListToIdentifier xs
217+ where xAsText = case x of
218+ Str s -> filter (\c -> c == '-' || not (isPunctuation c)) $
219+ concat $ intersperse "-" $ words $ map toLower s
220+ Emph lst -> inlineListToIdentifier lst
221+ Strikeout lst -> inlineListToIdentifier lst
222+ Superscript lst -> inlineListToIdentifier lst
223+ Subscript lst -> inlineListToIdentifier lst
224+ Strong lst -> inlineListToIdentifier lst
225+ Quoted _ lst -> inlineListToIdentifier lst
226+ Code s -> s
227+ Space -> "-"
228+ EmDash -> "-"
229+ EnDash -> "-"
230+ Apostrophe -> ""
231+ Ellipses -> ""
232+ LineBreak -> "-"
233+ TeX _ -> ""
234+ HtmlInline _ -> ""
235+ Link lst _ -> inlineListToIdentifier lst
236+ Image lst _ -> inlineListToIdentifier lst
237+ Note _ -> ""
238+
239+-- | Return unique identifiers for list of inline lists.
240+uniqueIdentifiers :: [[Inline]] -> [String]
241+uniqueIdentifiers ls =
242+ let addIdentifier (nonuniqueIds, uniqueIds) l =
243+ let new = inlineListToIdentifier l
244+ matches = length $ filter (== new) nonuniqueIds
245+ new' = new ++ if matches > 0 then ("-" ++ show matches) else ""
246+ in (new:nonuniqueIds, new':uniqueIds)
247+ in reverse $ snd $ foldl addIdentifier ([],[]) ls
248+
203249-- | Convert Pandoc block element to HTML.
204250blockToHtml :: WriterOptions -> Block -> State WriterState Html
205251blockToHtml opts Null = return $ noHtml