git.iko.soy/typeable/pandoc
on master help sign in
Use parsec parsers to split locator.

This is easier to read and maintain. Also, formatting is now stripped from the locator prefix, so you can write e.g. '*p.* 33'.

commit283f1e60ccd2cdfe48a056687565aedade5ceb6d authorJohn MacFarlane <jgm@berkeley.edu> dateSat 27 Nov 2010, 07:08 (16 years ago) parent044a9a6
1 file changed+34−27
src/Text/Pandoc/Biblio.hs+34−27
src/Text/Pandoc/Biblio.hs+34−27
@@ -36,6 +36,9 @@ import qualified Data.Map as M
3636import Text.CSL hiding ( Cite(..), Citation(..) )
3737import qualified Text.CSL as CSL ( Cite(..) )
3838import Text.Pandoc.Definition
39+import Text.Pandoc.Shared (stringify)
40+import Text.ParserCombinators.Parsec
41+import Control.Monad
3942
4043-- | Process a 'Pandoc' document by adding citations formatted
4144-- according to a CSL style, using 'citeproc' from citeproc-hs.
@@ -152,7 +155,7 @@ setCitationNoteNum i = map $ \c -> c { citationNoteNum = i}
152155toCslCite :: Citation -> CSL.Cite
153156toCslCite c
154157 = let (l, s) = locatorWords $ citationSuffix c
155− (la,lo) = parseLocator $ unwords l
158+ (la,lo) = parseLocator l
156159 citMode = case citationMode c of
157160 AuthorInText -> (True, False)
158161 SuppressAuthor -> (False,True )
@@ -168,30 +171,34 @@ toCslCite c
168171 , CSL.citeHash = citationHash c
169172 }
170173
171−locatorWords :: [Inline] -> ([String], [Inline])
172−locatorWords (Space : t) = locatorWords t
173−locatorWords (Str "" : t) = locatorWords t
174−locatorWords a@(Str (',' : s) : t)
175− = if ws /= [] then (ws, t') else ([], a)
176− where
177− (ws, t') = locatorWords (Str s:t)
178−locatorWords i
179− = if any isDigit w then (w':ws, s'') else ([], i)
180− where
181− (w, s') = locatorWord i
182− (ws, s'') = locatorWords s'
183− w' = if ws == [] then w else w ++ ","
184−
185−locatorWord :: [Inline] -> (String, [Inline])
186−locatorWord (Space : r) = (" " ++ ts, r')
187− where
188− (ts, r') = locatorWord r
189−locatorWord (Str t : r)
190− | t' /= "" = (w , Str t' : r)
191− | otherwise = (t ++ ts, r' )
192− where
193− w = takeWhile (/= ',') t
194− t' = dropWhile (/= ',') t
195− (ts, r') = locatorWord r
196−locatorWord i = ("", i)
174+locatorWords :: [Inline] -> (String, [Inline])
175+locatorWords inp =
176+ case parse (liftM2 (,) pLocator getInput) "suffix" inp of
177+ Right r -> r
178+ Left _ -> ("",inp)
179+
180+pMatch :: (Inline -> Bool) -> GenParser Inline st Inline
181+pMatch condition = try $ do
182+ t <- anyToken
183+ guard $ condition t
184+ return t
185+
186+pSpace :: GenParser Inline st Inline
187+pSpace = pMatch (== Space)
188+
189+pLocator :: GenParser Inline st String
190+pLocator = try $ do
191+ optional $ pMatch (== Str ",")
192+ optional pSpace
193+ f <- many1 (notFollowedBy pSpace >> anyToken)
194+ gs <- many1 pWordWithDigits
195+ return $ stringify f ++ (' ' : unwords gs)
196+
197+pWordWithDigits :: GenParser Inline st String
198+pWordWithDigits = try $ do
199+ pSpace
200+ r <- many1 (notFollowedBy pSpace >> anyToken)
201+ let s = stringify r
202+ guard $ any isDigit s
203+ return s
197204