From e814a3f6d23f640b1aed5b7cb949459d514a3e33 Mon Sep 17 00:00:00 2001 From: fiddlosopher Date: Wed, 8 Aug 2007 02:43:15 +0000 Subject: Major change in the way ordered lists are handled: + The changes are documented in README, under Lists. + The OrderedList block element now stores information about list number style, list number delimiter, and starting number. + The readers parse this information, when possible. + The writers use this information to style ordered lists. + Test suites have been changed accordingly. Motivation: It's often useful to start lists with numbers other than 1, and to have control over the style of the list. Added to Text.Pandoc.Shared: + camelCaseToHyphenated + toRomanNumeral + anyOrderedListMarker + orderedListMarker + orderedListMarkers Added to Text.Pandoc.ParserCombinators: + charsInBalanced' + withHorizDisplacement + romanNumeral RST writer: + Force blank line before lists, so that sublists will be handled correctly. LaTeX reader: + Fixed bug in parsing of footnotes containing multiple paragraphs, introduced by use of charsInBalanced. Fix: use charsInBalanced' instead. LaTeX header: + use mathletters option in ucs package, so that basic unicode Greek letters will work properly. git-svn-id: https://pandoc.googlecode.com/svn/trunk@834 788f1e2b-df1e-0410-8736-df70ead52e1b --- src/Text/Pandoc/Readers/HTML.hs | 19 +++++++++++-- src/Text/Pandoc/Readers/LaTeX.hs | 30 ++++++++++++++------ src/Text/Pandoc/Readers/Markdown.hs | 41 ++++++++++++++++----------- src/Text/Pandoc/Readers/RST.hs | 55 ++++++++----------------------------- 4 files changed, 75 insertions(+), 70 deletions(-) (limited to 'src/Text/Pandoc/Readers') diff --git a/src/Text/Pandoc/Readers/HTML.hs b/src/Text/Pandoc/Readers/HTML.hs index 270c7ba21..1742667b8 100644 --- a/src/Text/Pandoc/Readers/HTML.hs +++ b/src/Text/Pandoc/Readers/HTML.hs @@ -354,11 +354,26 @@ blockQuote = try (do list = choice [ bulletList, orderedList, definitionList ] "list" orderedList = try $ do - htmlTag "ol" + (_, attribs) <- htmlTag "ol" + (start, style) <- option (1, DefaultStyle) $ + do failIfStrict + let sta = fromMaybe "1" $ + lookup "start" attribs + let sty = fromMaybe (fromMaybe "" $ + lookup "style" attribs) $ + lookup "class" attribs + let sty' = case sty of + "lower-roman" -> LowerRoman + "upper-roman" -> UpperRoman + "lower-alpha" -> LowerAlpha + "upper-alpha" -> UpperAlpha + "decimal" -> Decimal + _ -> DefaultStyle + return (read sta, sty') spaces items <- sepEndBy1 (blocksIn "li") spaces htmlEndTag "ol" - return (OrderedList items) + return (OrderedList (start, style, DefaultDelim) items) bulletList = try $ do htmlTag "ul" diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs index 77ed4607a..73a3e4a8f 100644 --- a/src/Text/Pandoc/Readers/LaTeX.hs +++ b/src/Text/Pandoc/Readers/LaTeX.hs @@ -59,12 +59,8 @@ specialChars = "\\$%&^&_~#{}\n \t|<>'\"-" -- | Returns text between brackets and its matching pair. bracketedText openB closeB = try (do - char openB - result <- many (choice [ oneOfStrings [ ['\\', openB], ['\\', closeB] ], - count 1 (noneOf [openB, closeB]), - bracketedText openB closeB ]) - char closeB - return ([openB] ++ (concat result) ++ [closeB])) + result <- charsInBalanced' openB closeB + return ([openB] ++ result ++ [closeB])) -- | Returns an option or argument of a LaTeX command. optOrArg = choice [ (bracketedText '{' '}'), (bracketedText '[' ']') ] @@ -255,12 +251,30 @@ listItem = try $ do return (opt, blocks) orderedList = try $ do - begin "enumerate" + string "\\begin{enumerate}" + (_, style, delim) <- option (1, DefaultStyle, DefaultDelim) $ + try $ do failIfStrict + char '[' + res <- anyOrderedListMarker + char ']' + return res spaces + option "" $ try $ do string "\\setlength{\\itemindent}" + char '{' + manyTill anyChar (char '}') + spaces + start <- option 1 $ try $ do failIfStrict + string "\\setcounter{enum" + many1 (char 'i') + string "}{" + num <- many1 digit + char '}' + spaces + return $ (read num) + 1 items <- many listItem end "enumerate" spaces - return (OrderedList $ map snd items) + return $ OrderedList (start, style, delim) $ map snd items bulletList = try $ do begin "itemize" diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs index 0ecb09178..3ccb74ba7 100644 --- a/src/Text/Pandoc/Readers/Markdown.hs +++ b/src/Text/Pandoc/Readers/Markdown.hs @@ -243,6 +243,8 @@ header = choice [ setextHeader, atxHeader ] "header" atxHeader = try (do lead <- many1 (char '#') + notFollowedBy (char '.') -- this would be a list + notFollowedBy (char ')') skipSpaces txt <- manyTill inline atxClosing return (Header (length lead) (normalizeSpaces txt))) @@ -354,27 +356,33 @@ blockQuote = do list = choice [ bulletList, orderedList, definitionList ] "list" -bulletListStart = try (do +bulletListStart = try $ do option ' ' newline -- if preceded by a Plain block in a list context nonindentSpaces notFollowedBy' hrule -- because hrules start out just like lists oneOf bulletListMarkers spaceChar - skipSpaces) - -standardOrderedListStart = try (do - many1 digit - char '.') + skipSpaces -extendedOrderedListStart = try (do - failIfStrict - oneOf ['a'..'n'] - oneOf ".)") +anyOrderedListStart = try $ do + option ' ' newline -- if preceded by a Plain block in a list context + nonindentSpaces + state <- getState + if stateStrict state + then do many1 digit + char '.' + return (1, DefaultStyle, DefaultDelim) + else anyOrderedListMarker -orderedListStart = try $ do +orderedListStart style delim = try $ do option ' ' newline -- if preceded by a Plain block in a list context nonindentSpaces - standardOrderedListStart <|> extendedOrderedListStart + state <- getState + if stateStrict state + then do many1 digit + char '.' + return 1 + else orderedListMarker style delim oneOf spaceChars skipSpaces @@ -385,7 +393,7 @@ listLine start = try (do notFollowedBy' (do indentSpaces many (spaceChar) - choice [bulletListStart, orderedListStart]) + choice [bulletListStart, anyOrderedListStart >> return ()]) line <- manyTill anyChar newline return (line ++ "\n")) @@ -431,9 +439,10 @@ listItem start = try (do return contents) orderedList = try (do - items <- many1 (listItem orderedListStart) + (start, style, delim) <- lookAhead anyOrderedListStart + items <- many1 (listItem (orderedListStart style delim)) let items' = compactify items - return (OrderedList items')) + return (OrderedList (start, style, delim) items')) bulletList = try (do items <- many1 (listItem bulletListStart) @@ -906,7 +915,7 @@ endline = try (do else return () -- parse potential list-starts differently if in a list: if (stateParserContext st) == ListItemState - then notFollowedBy' (orderedListStart <|> bulletListStart) + then notFollowedBy' $ choice [bulletListStart, anyOrderedListStart >> return ()] else return () return Space) diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs index 83c5383bd..a36c33d92 100644 --- a/src/Text/Pandoc/Readers/RST.hs +++ b/src/Text/Pandoc/Readers/RST.hs @@ -379,46 +379,11 @@ bulletListStart = try (do let len = length (marker:white) return len) -withPeriodSuffix parser = try (do - a <- parser - b <- char '.' - return (a ++ [b])) - -withParentheses parser = try (do - a <- char '(' - b <- parser - c <- char ')' - return ([a] ++ b ++ [c])) - -withRightParen parser = try (do - a <- parser - b <- char ')' - return (a ++ [b])) - -upcaseWord = map toUpper - -romanNumeral = do - let lowerNumerals = ["i", "ii", "iii", "iiii", "iv", "v", "vi", - "vii", "viii", "ix", "x", "xi", "xii", "xiii", - "xiv", "xv", "xvi", "xvii", "xviii", "xix", "xx", - "xxi", "xxii", "xxiii", "xxiv" ] - let upperNumerals = map upcaseWord lowerNumerals - result <- choice $ map string (lowerNumerals ++ upperNumerals) - return result - -orderedListEnumerator = choice [ many1 digit, - count 1 (char '#'), - count 1 letter, - romanNumeral ] - -- parses ordered list start and returns its length (inc following whitespace) -orderedListStart = try (do - marker <- choice [ withPeriodSuffix orderedListEnumerator, - withParentheses orderedListEnumerator, - withRightParen orderedListEnumerator ] +orderedListStart style delim = try $ do + (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim) white <- many1 spaceChar - let len = length (marker ++ white) - return len) + return $ markerLen + length white -- parse a line of a list item listLine markerLength = try (do @@ -437,11 +402,11 @@ indentWith num = do (try (do {char '\t'; count (num - tabStop) (char ' ')})) ] -- parse raw text for one list item, excluding start marker and continuations -rawListItem start = try (do +rawListItem start = try $ do markerLength <- start firstLine <- manyTill anyChar newline restLines <- many (listLine markerLength) - return (markerLength, (firstLine ++ "\n" ++ (concat restLines)))) + return (markerLength, (firstLine ++ "\n" ++ (concat restLines))) -- continuation of a list item - indented and separated by blankline or -- (in compact lists) endline. @@ -473,10 +438,11 @@ listItem start = try (do updateState (\st -> st {stateParserContext = oldContext}) return parsed) -orderedList = try (do - items <- many1 (listItem orderedListStart) +orderedList = try $ do + (start, style, delim) <- lookAhead anyOrderedListMarker + items <- many1 (listItem (orderedListStart style delim)) let items' = compactify items - return (OrderedList items')) + return (OrderedList (start, style, delim) items') bulletList = try (do items <- many1 (listItem bulletListStart) @@ -611,7 +577,8 @@ endline = try (do -- parse potential list-starts at beginning of line differently in a list: st <- getState if ((stateParserContext st) == ListItemState) - then notFollowedBy' (choice [orderedListStart, bulletListStart]) + then do notFollowedBy' anyOrderedListMarker + notFollowedBy' bulletListStart else option () pzero return Space) -- cgit v1.2.3