git.iko.soy/typeable/pandoc
on master help sign in
+ Simplified entity handling by removing stringToSGML from Entities.hs.

It is no longer needed now that all entities are processed in the markdown and HTML readers. All calls to stringToSGML have been replaced by calls to encodeEntities. + Since inTag's attribute handling already encodes entities, calls to encodeEntities are no longer needed for attribute values, so they've been removed. + The HTML and Markdown readers now call decodeEntities on all raw strings (e.g. authors, dates, link titles), to ensure that no unprocessed entities are included in the native representation of the document. (In the HTML reader, most of this work is done by a change in extractAttributeName.) + The result is a small speed improvement (around 5% on my benchmark) and cleaner code. git-svn-id: https://pandoc.googlecode.com/svn/trunk@519 788f1e2b-df1e-0410-8736-df70ead52e1b

commitdc6925542c6aa60078c370e7e356b42ea216b1b7 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateSun 28 Jan 2007, 00:04 (20 years ago) parent2148471
6 files changed+25−43
src/Text/Pandoc/Entities.hs−18 src/Text/Pandoc/Readers/HTML.hs+3−1 src/Text/Pandoc/Readers/Markdown.hs+4−4 src/Text/Pandoc/Shared.hs+3−3 src/Text/Pandoc/Writers/Docbook.hs+7−7 src/Text/Pandoc/Writers/HTML.hs+8−10
src/Text/Pandoc/Entities.hs−18
@@ -34,7 +34,6 @@ module Text.Pandoc.Entities (
3434 encodeEntities,
3535 decodeEntities,
3636 escapeSGMLChar,
37− stringToSGML,
3837 characterEntity
3938 ) where
4039import Data.Char ( chr, ord )
@@ -115,23 +114,6 @@ decodeEntities str =
115114 Left err -> error $ "\nError: " ++ show err
116115 Right result -> result
117116
118−-- | Escape string for SGML, preserving entity references.
119−stringToSGML :: String -> String
120−stringToSGML str =
121− let regular = do
122− str <- many1 (satisfy (not . needsEscaping))
123− return str
124− special = do
125− notFollowedBy characterEntity
126− c <- anyChar
127− return $ escapeSGMLChar c
128− entity = do
129− ent <- manyTill anyChar (char ';')
130− return (ent ++ ";") in
131− case parse (many (regular <|> special <|> entity)) str str of
132− Left err -> error $ "\nError: " ++ show err
133− Right result -> concat result
134−
135117entityTable :: [(String, Char)]
136118entityTable = [
137119 ("&quot;", chr 34),
src/Text/Pandoc/Readers/HTML.hs+3−1
@@ -445,7 +445,9 @@ extractAttribute name [] = Nothing
445445extractAttribute name ((attrName, contents):rest) =
446446 let name' = map toLower name
447447 attrName' = map toLower attrName in
448− if (attrName' == name') then Just contents else extractAttribute name rest
448+ if (attrName' == name')
449+ then Just (decodeEntities contents)
450+ else extractAttribute name rest
449451
450452link = try (do
451453 (tag, attributes) <- htmlTag "a"
src/Text/Pandoc/Readers/Markdown.hs+4−4
@@ -42,7 +42,7 @@ import Text.Pandoc.Readers.HTML ( rawHtmlBlock,
4242 anyHtmlTag, anyHtmlEndTag,
4343 htmlEndTag, extractTagType,
4444 htmlBlockElement )
45−import Text.Pandoc.Entities ( characterEntity )
45+import Text.Pandoc.Entities ( characterEntity, decodeEntities )
4646import Text.ParserCombinators.Parsec
4747
4848-- | Read markdown from an input string and return a Pandoc document.
@@ -144,14 +144,14 @@ authorsLine = try (do
144144 skipSpaces
145145 authors <- sepEndBy (many1 (noneOf ",;\n")) (oneOf ",;")
146146 newline
147− return (map removeLeadingTrailingSpace authors))
147+ return (map (decodeEntities . removeLeadingTrailingSpace) authors))
148148
149149dateLine = try (do
150150 char '%'
151151 skipSpaces
152152 date <- many (noneOf "\n")
153153 newline
154− return (removeTrailingSpace date))
154+ return (decodeEntities $ removeTrailingSpace date))
155155
156156titleBlock = try (do
157157 failIfStrict
@@ -894,7 +894,7 @@ titleWith startChar endChar = try (do
894894 char endChar
895895 skipSpaces
896896 notFollowedBy (noneOf ")\n")))
897− return tit)
897+ return $ decodeEntities tit)
898898
899899title = choice [ titleWith '(' ')',
900900 titleWith '"' '"',
src/Text/Pandoc/Shared.hs+3−3
@@ -72,7 +72,7 @@ module Text.Pandoc.Shared (
7272 ) where
7373import Text.Pandoc.Definition
7474import Text.ParserCombinators.Parsec as Parsec
75−import Text.Pandoc.Entities ( decodeEntities, encodeEntities, stringToSGML )
75+import Text.Pandoc.Entities ( decodeEntities, encodeEntities )
7676import Text.PrettyPrint.HughesPJ as PP ( text, char, (<>),
7777 ($$), nest, Doc, isEmpty )
7878import Data.Char ( toLower, ord )
@@ -524,8 +524,8 @@ replaceRefLinksInline keytable other = other
524524-- | Return a text object with a string of formatted SGML attributes.
525525attributeList :: [(String, String)] -> Doc
526526attributeList = text . concatMap
527− (\(a, b) -> " " ++ stringToSGML a ++ "=\"" ++
528− stringToSGML b ++ "\"")
527+ (\(a, b) -> " " ++ encodeEntities a ++ "=\"" ++
528+ encodeEntities b ++ "\"")
529529
530530-- | Put the supplied contents between start and end tags of tagType,
531531-- with specified attributes and (if specified) indentation.
src/Text/Pandoc/Writers/Docbook.hs+7−7
@@ -32,7 +32,7 @@ module Text.Pandoc.Writers.Docbook (
3232 ) where
3333import Text.Pandoc.Definition
3434import Text.Pandoc.Shared
35−import Text.Pandoc.Entities ( encodeEntities, stringToSGML )
35+import Text.Pandoc.Entities ( encodeEntities )
3636import Data.Char ( toLower, ord )
3737import Data.List ( isPrefixOf, partition, drop )
3838import Text.PrettyPrint.HughesPJ hiding ( Str )
@@ -64,8 +64,8 @@ authorToDocbook name = inTagsIndented "author" $
6464 then -- last name first
6565 let (lastname, rest) = break (==',') name
6666 firstname = removeLeadingSpace rest in
67− inTagsSimple "firstname" (text $ stringToSGML firstname) <>
68− inTagsSimple "surname" (text $ stringToSGML lastname)
67+ inTagsSimple "firstname" (text $ encodeEntities firstname) <>
68+ inTagsSimple "surname" (text $ encodeEntities lastname)
6969 else -- last name last
7070 let namewords = words name
7171 lengthname = length namewords
@@ -73,8 +73,8 @@ authorToDocbook name = inTagsIndented "author" $
7373 0 -> ("","")
7474 1 -> ("", name)
7575 n -> (joinWithSep " " (take (n-1) namewords), last namewords) in
76− inTagsSimple "firstname" (text $ stringToSGML firstname) $$
77− inTagsSimple "surname" (text $ stringToSGML lastname)
76+ inTagsSimple "firstname" (text $ encodeEntities firstname) $$
77+ inTagsSimple "surname" (text $ encodeEntities lastname)
7878
7979-- | Convert Pandoc document to string in Docbook format.
8080writeDocbook :: WriterOptions -> Pandoc -> String
@@ -86,7 +86,7 @@ writeDocbook opts (Pandoc (Meta title authors date) blocks) =
8686 then inTagsIndented "articleinfo" $
8787 (inTagsSimple "title" (wrap opts title)) $$
8888 (vcat (map authorToDocbook authors)) $$
89− (inTagsSimple "date" (text $ stringToSGML date))
89+ (inTagsSimple "date" (text $ encodeEntities date))
9090 else empty
9191 blocks' = replaceReferenceLinks blocks
9292 (noteBlocks, blocks'') = partition isNoteBlock blocks'
@@ -227,7 +227,7 @@ inlineToDocbook opts (Image alt (Src src tit)) =
227227 then empty
228228 else inTagsIndented "objectinfo" $
229229 inTagsIndented "title"
230− (text $ stringToSGML tit) in
230+ (text $ encodeEntities tit) in
231231 inTagsIndented "inlinemediaobject" $
232232 inTagsIndented "imageobject" $
233233 titleDoc $$ selfClosingTag "imagedata" [("fileref", src)]
src/Text/Pandoc/Writers/HTML.hs+8−10
@@ -32,7 +32,7 @@ module Text.Pandoc.Writers.HTML (
3232 ) where
3333import Text.Pandoc.Definition
3434import Text.Pandoc.Shared
35−import Text.Pandoc.Entities ( encodeEntities, stringToSGML )
35+import Text.Pandoc.Entities ( encodeEntities )
3636import Text.Regex ( mkRegex, matchRegex )
3737import Numeric ( showHex )
3838import Data.Char ( ord, toLower )
@@ -127,11 +127,11 @@ htmlHeader opts (Meta title authors date) =
127127 then empty
128128 else selfClosingTag "meta" [("name", "author"),
129129 ("content",
130− joinWithSep ", " (map stringToSGML authors))]
130+ joinWithSep ", " (map encodeEntities authors))]
131131 datetext = if (date == "")
132132 then empty
133133 else selfClosingTag "meta" [("name", "date"),
134− ("content", stringToSGML date)] in
134+ ("content", encodeEntities date)] in
135135 text (writerHeader opts) $$ authortext $$ datetext $$ titletext $$
136136 text "</head>\n<body>"
137137
@@ -248,20 +248,18 @@ inlineToHtml opts (TeX str) = text $ encodeEntities str
248248inlineToHtml opts (HtmlInline str) = text str
249249inlineToHtml opts (LineBreak) = selfClosingTag "br" []
250250inlineToHtml opts Space = space
251−inlineToHtml opts (Link txt (Src src tit)) =
252− let title = stringToSGML tit in
251+inlineToHtml opts (Link txt (Src src title)) =
253252 if (isPrefixOf "mailto:" src)
254253 then obfuscateLink opts txt src
255− else inTags False "a" ([("href", encodeEntities src)] ++
256− if null tit then [] else [("title", title)])
254+ else inTags False "a" ([("href", src)] ++
255+ if null title then [] else [("title", title)])
257256 (inlineListToHtml opts txt)
258257inlineToHtml opts (Link txt (Ref ref)) =
259258 char '[' <> (inlineListToHtml opts txt) <> text "][" <>
260259 (inlineListToHtml opts ref) <> char ']'
261260 -- this is what markdown does, for better or worse
262−inlineToHtml opts (Image alt (Src source tit)) =
263− let title = stringToSGML tit
264− alternate = render $ inlineListToHtml opts alt in
261+inlineToHtml opts (Image alt (Src source title)) =
262+ let alternate = render $ inlineListToHtml opts alt in
265263 selfClosingTag "img" $ [("src", source)] ++
266264 (if null alternate then [] else [("alt", alternate)]) ++
267265 [("title", title)] -- note: null title is included, as in Markdown.pl