citeproc-hs 0.1 → 0.2
raw patch · 17 files changed
+1070/−338 lines, 17 filesdep +filepathdep +hs-bibutilsdep +sybdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: filepath, hs-bibutils, syb
Dependency ranges changed: base
API changes (from Hackage documentation)
- Text.CSL: evalLayout :: Layout -> Bool -> [TermMap] -> [MacroMap] -> [Option] -> String -> Reference -> [Output]
- Text.CSL.Proc: allTheSame :: (Eq a) => [a] -> Bool
- Text.CSL.Proc: disambiguate :: (Eq a) => [[a]] -> [[a]]
- Text.CSL.Proc: getCiteData :: Output -> [CiteData]
- Text.CSL.Proc: getDisOptions :: Style -> [String]
- Text.CSL.Proc: getDuplicates :: [CitationGroup] -> [NamesYear]
- Text.CSL.Proc: getNamesYear :: Output -> [(String, NamesYear)]
- Text.CSL.Proc: getRefs :: [Reference] -> [[(String, String)]] -> [[(String, Reference)]]
- Text.CSL.Proc: getYears :: Output -> [String]
- Text.CSL.Proc: hasDuplicates :: (Eq a) => [a] -> Bool
- Text.CSL.Proc: hasIfDis :: IfThen -> [Bool]
- Text.CSL.Proc: hasSame :: (Eq a) => ([Bool] -> Bool) -> [a] -> Bool
- Text.CSL.Proc: procGroup :: Style -> [(String, Reference)] -> CitationGroup
- Text.CSL.Proc: reEvaluate :: Style -> [CiteData] -> [(String, Reference)] -> CitationGroup -> CitationGroup
- Text.CSL.Proc: same :: (Eq a) => [a] -> [Bool]
- Text.CSL.Proc: type NamesYear = ([Output], String)
- Text.CSL.Proc: updateOutput :: [CiteData] -> Output -> Output
- Text.CSL.Style: FC :: String -> [Output] -> [[Output]] -> Output
- Text.CSL.Style: FN :: String -> [String] -> Formatting -> Output
- Text.CSL.Style: FS :: String -> Formatting -> Output
- Text.CSL.Style: FY :: String -> String -> Formatting -> Output
- Text.CSL.Style: O :: [Output] -> Formatting -> Output
- Text.CSL.Style: S :: String -> Output
- Text.CSL.Style: disData :: CiteData -> [[Output]]
+ Text.CSL: readBiblioFile :: FilePath -> String -> IO [Reference]
+ Text.CSL.Eval: head' :: [a] -> [a]
+ Text.CSL.Input.Bibutils: readBiblioFile :: FilePath -> String -> IO [Reference]
+ Text.CSL.Proc.Collapse: collapseCitGroups :: Style -> [CitationGroup] -> [CitationGroup]
+ Text.CSL.Proc.Collapse: collapseNumber :: CitationGroup -> CitationGroup
+ Text.CSL.Proc.Collapse: collapseYear :: CitationGroup -> CitationGroup
+ Text.CSL.Proc.Collapse: collapseYearSuf :: CitationGroup -> CitationGroup
+ Text.CSL.Proc.Collapse: getCollapseOptions :: Style -> [String]
+ Text.CSL.Proc.Collapse: groupConsec :: [Int] -> [[Int]]
+ Text.CSL.Proc.Collapse: rmFirstDelim :: Output -> Output
+ Text.CSL.Proc.Disamb: allTheSame :: (Eq a) => [a] -> Bool
+ Text.CSL.Proc.Disamb: disambCitations :: Style -> [Reference] -> [[(String, String)]] -> [CitationGroup]
+ Text.CSL.Proc.Disamb: disambWithNames :: Bool -> Bool -> [CiteData] -> [CiteData]
+ Text.CSL.Proc.Disamb: disambiguate :: (Eq a) => [[a]] -> [[a]]
+ Text.CSL.Proc.Disamb: getCitDisambOptions :: Style -> [String]
+ Text.CSL.Proc.Disamb: getCiteData :: Output -> [CiteData]
+ Text.CSL.Proc.Disamb: getDuplCiteData :: [CitationGroup] -> [[CiteData]]
+ Text.CSL.Proc.Disamb: getDuplNamesYear :: [CitationGroup] -> [NamesYear]
+ Text.CSL.Proc.Disamb: getNamesYear :: Output -> [(String, NamesYear)]
+ Text.CSL.Proc.Disamb: getRefs :: [Reference] -> [[(String, String)]] -> [[(String, Reference)]]
+ Text.CSL.Proc.Disamb: getYears :: Output -> [String]
+ Text.CSL.Proc.Disamb: hasDuplicates :: (Eq a) => [a] -> Bool
+ Text.CSL.Proc.Disamb: hasIfDis :: IfThen -> [Bool]
+ Text.CSL.Proc.Disamb: procGroup :: Style -> [(String, Reference)] -> CitationGroup
+ Text.CSL.Proc.Disamb: reEvaluate :: Style -> [CiteData] -> [(String, Reference)] -> CitationGroup -> CitationGroup
+ Text.CSL.Proc.Disamb: same :: (Eq a) => [a] -> [Bool]
+ Text.CSL.Proc.Disamb: type NamesYear = ([Output], String)
+ Text.CSL.Proc.Disamb: updateOutput :: [CiteData] -> Output -> Output
+ Text.CSL.Reference: Broadcast :: RefType
+ Text.CSL.Reference: CNum :: Int -> CNum
+ Text.CSL.Reference: PageFstLoc :: String -> Locator
+ Text.CSL.Reference: ParaLoc :: String -> Locator
+ Text.CSL.Reference: PartLoc :: String -> Locator
+ Text.CSL.Reference: SecLoc :: String -> Locator
+ Text.CSL.Reference: SubVerbLoc :: String -> Locator
+ Text.CSL.Reference: VerseLoc :: String -> Locator
+ Text.CSL.Reference: VolLoc :: String -> Locator
+ Text.CSL.Reference: instance Data CNum
+ Text.CSL.Reference: instance Eq CNum
+ Text.CSL.Reference: instance Num CNum
+ Text.CSL.Reference: instance Read CNum
+ Text.CSL.Reference: instance Show CNum
+ Text.CSL.Reference: instance Typeable CNum
+ Text.CSL.Reference: newtype CNum
+ Text.CSL.Reference: unCNum :: CNum -> Int
+ Text.CSL.Style: OCitNum :: Int -> Formatting -> Output
+ Text.CSL.Style: OContrib :: String -> [Output] -> [[Output]] -> Output
+ Text.CSL.Style: ODel :: String -> Output
+ Text.CSL.Style: OName :: String -> [String] -> Formatting -> Output
+ Text.CSL.Style: OStr :: String -> Formatting -> Output
+ Text.CSL.Style: OYear :: String -> String -> Formatting -> Output
+ Text.CSL.Style: Output :: [Output] -> Formatting -> Output
+ Text.CSL.Style: disambData :: CiteData -> [[Output]]
+ Text.CSL.Style: mapGroupOutput :: (Output -> [a]) -> CitationGroup -> [a]
+ Text.CSL.Style: rmContribs :: Output -> Output
- Text.CSL: Reference :: String -> RefType -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> String -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> Locator -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Int -> String -> String -> Reference
+ Text.CSL: Reference :: String -> RefType -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> String -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> Locator -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> CNum -> String -> String -> Reference
- Text.CSL: citationNumber :: Reference -> Int
+ Text.CSL: citationNumber :: Reference -> CNum
- Text.CSL: readCSLFile :: String -> IO Style
+ Text.CSL: readCSLFile :: FilePath -> IO Style
- Text.CSL: readModsColletionFile :: String -> IO [Reference]
+ Text.CSL: readModsColletionFile :: FilePath -> IO [Reference]
- Text.CSL: readModsFile :: String -> IO Reference
+ Text.CSL: readModsFile :: FilePath -> IO Reference
- Text.CSL.Input.MODS: readModsColletionFile :: String -> IO [Reference]
+ Text.CSL.Input.MODS: readModsColletionFile :: FilePath -> IO [Reference]
- Text.CSL.Input.MODS: readModsFile :: String -> IO Reference
+ Text.CSL.Input.MODS: readModsFile :: FilePath -> IO Reference
- Text.CSL.Parser: readCSLFile :: String -> IO Style
+ Text.CSL.Parser: readCSLFile :: FilePath -> IO Style
- Text.CSL.Reference: Reference :: String -> RefType -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> String -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> Locator -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Int -> String -> String -> Reference
+ Text.CSL.Reference: Reference :: String -> RefType -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [Agent] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> [RefDate] -> String -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> Locator -> String -> String -> Int -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> CNum -> String -> String -> Reference
- Text.CSL.Reference: citationNumber :: Reference -> Int
+ Text.CSL.Reference: citationNumber :: Reference -> CNum
Files
- README +60/−32
- citeproc-hs.cabal +40/−26
- locales/locales-sr-RS.xml +35/−27
- locales/locales-uk-UA.xml +207/−0
- src/Text/CSL.hs +100/−7
- src/Text/CSL/Eval.hs +25/−18
- src/Text/CSL/Input/Bibutils.hs +90/−0
- src/Text/CSL/Input/MODS.hs +5/−3
- src/Text/CSL/Output/Pandoc.hs +7/−1
- src/Text/CSL/Output/Plain.hs +4/−1
- src/Text/CSL/Parser.hs +4/−2
- src/Text/CSL/Proc.hs +34/−181
- src/Text/CSL/Proc/Collapse.hs +103/−0
- src/Text/CSL/Proc/Disamb.hs +249/−0
- src/Text/CSL/Reference.hs +48/−15
- src/Text/CSL/Style.hs +58/−24
- test/test.hs +1/−1
README view
@@ -5,9 +5,9 @@ ----- [citeproc-hs] is a Haskell implementation of the Citation Style-Language [CSL].+Language ([CSL]). -[citeproc-hs] adds to [Pandoc], the famous [Haskell] text processing+[citeproc-hs] adds to [pandoc], the famous [Haskell] text processing tool, a Bibtex like citation and bibliographic formatting and generation facility. @@ -25,27 +25,30 @@ releases of [OpenOffice](http://bibliographic.openoffice.org/). [citeproc-hs] can process and format citations according to a [CSL]-style, given a [MODS] collection of references.+style, given a collection of references. -The Metadata Object Description Schema ([MODS]) is an XML format which-is used by [Bibutils] to interconvert many different bibliographic-database formats, like Bibtex, Endnote, and others.+Natively [citeproc-hs] can only read [MODS] XML formattted+bibliographic databases. The Metadata Object Description Schema+([MODS]) is an XML format which is used by [bibutils] to interconvert+many different bibliographic database formats, like Bibtex, Endnote,+and others. -[Bibutils] can be used to convert Bibtex and other bibliographic+[bibutils] can be used to convert Bibtex and other bibliographic databases to [MODS] collections, which can be thus read by [citeproc-hs]. -[Bibutils] also exports a library and a future plan is to use that-library for providing native support for the most widely used-bibliographic databases in [citeproc-hs].+[bibutils] also exports a library and this library can be used by+[citeproc-hs] for reading the most widely used bibliographic+databases. This requires the installation of [hs-bibutils], the+Haskell bindings to [bibutils]. [citeproc-hs] is a library that exports functions to parse [CSL] styles and [MODS] collections, to process lists of citation groups and to format the processed output. The output is a Haskell data type that can be further processed for conversion to any kind of formats (at the-present time plain ASCII and the [Pandoc] native format)+present time plain ASCII and the pandoc] native format) -[Pandoc] is a [Haskell] library for converting from one markup format to+[pandoc] is a [Haskell] library for converting from one markup format to another, and a command-line tool that uses this library. It can read [markdown] and (subsets of) [reStructuredText], [HTML], and [LaTeX]; and it can write [markdown], [reStructuredText], [HTML], [LaTeX], [ConTeXt],@@ -67,6 +70,8 @@ Installation ------------ +### Installing without bibutils support+ [citeproc-hs] depends on [hxt], the Haskell XML Tool Box. In order to install [citeproc-hs] you need to install [hxt] and its@@ -74,7 +79,7 @@ <http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hxt> -Every package downloaded form [Hackage] can be installed with those+Every package downloaded form [Hackage] can be installed with these simple commands: runhaskell Setup.lhs configure@@ -90,16 +95,34 @@ runhaskell Setup.lhs build runhaskell Setup.lhs install --user +### Installing with bibutils support++Since [bibutils] doesn't build a shared object and doesn't install the+library, which is a static object used to compile the single+[bibutils] utilities, by default [citeproc-hs] is not built with+[bibutils] support.++If you succeeded in installing [bibutils] and [hs-bibutils], you can+enable [bibutils] by configuring with the `-fbibutils` flag:++ runhaskell Setup.lhs configure -fbibutils++and then build and install with:++ runhaskell Setup.lhs build+ runhaskell Setup.lhs install++ Using citeproc-hs with Pandoc ----------------------------- -If you want to use [citeproc-hs] with [Pandoc] you need to install-[citeproc-hs] first, get the [Pandoc] source code and compile it with+If you want to use [citeproc-hs] with [pandoc] you need to install+[citeproc-hs] first, get the [pandoc] source code and compile it with the `-f citeproc` flag: - runhaskell Setup.lhs configure -f citeproc- runhaskell Setup.lhs build- runhaskell Setup.lhs install+ runhaskell Setup.hs configure -f citeproc+ runhaskell Setup.hs build+ runhaskell Setup.hs install Citations are inserted like simple reference links: @@ -119,29 +142,33 @@ [Rossato2006@ p. 10; Pascuzzi2002@ cap. 12] To automatically format citations and generate the bibliography, run-[Pandoc] with the `--csl` and `--mods` flags:+[pandoc] with the `--csl` and `--biblio` flags: - pandoc --csl cslStyle.csl --mods modsCollection.xml text.markdown > text.html+ pandoc --csl cslStyle.csl --biblio modsCollection.mods text.markdown > text.html Obviously you can export the text into any of the formats supported by-[Pandoc].+[pandoc]. Some examples can be found in the `test` directory of the source tree. You can try them with: - pandoc --csl apa.csl --mods modsCollection.xml test.markdown- pandoc --csl apa.csl --mods modsCollection.xml test_note.markdown+ pandoc --csl apa.csl --biblio modsCollection.xml --biblio-format mods test.markdown+ pandoc --csl apa.csl --biblio modsCollection.xml --biblio-format mods test_note.markdown Documentation ------------- -No further documentation is so far available and even haddock-generated documentation is at a very early stage.+[Haddock] documentation for the exported API is available at the+following address: -Some usage examples can be found in the `test` directory of the-source tree.+<http://code.haskell.org/citeproc-hs/docs/> +Generating the [Haddock] documentation is troublesome with Cabal <+1.6.0.2 (GHC-6.10.1 comes with Cabal-1.6.0.1), because of this:++<http://hackage.haskell.org/trac/hackage/ticket/396>+ Known Issues ------------ @@ -150,7 +177,6 @@ Specifically the following options are not implemented: - - "collapse" (citation collapsing) - "hanging-indent" - "second-field-align" - "line-spacing"@@ -174,7 +200,7 @@ me with ideas, comments and suggestions that made it possible to come to something usable. -[John MacFarlane], the author of [Pandoc], has been very supportive of+[John MacFarlane], the author of [pandoc], has been very supportive of the project and provided a lot of useful feed back, comments and suggestions. @@ -213,16 +239,18 @@ Copyright © 2008 Andrea Rossato -[citeproc-hs]: http://code.haskell.org/cioteproc-hs+[citeproc-hs]: http://code.haskell.org/citeproc-hs [CSL]: http://xbiblio.sourceforge.net/csl/-[Pandoc]: http://johnmacfarlane.net/pandoc/+[pandoc]: http://johnmacfarlane.net/pandoc/ [Zotero]: http://www.zotero.org [MODS]: http://www.loc.gov/mods/-[Bibutils]: http://www.scripps.edu/~cdputnam/software/bibutils/+[bibutils]: http://www.scripps.edu/~cdputnam/software/bibutils/+[hs-bibutils]: http://code.haskell.org/hs-bibutils/ [Hackage]: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/citeproc-hs [hxt]: http://www.fh-wedel.de/~si/HXmlToolbox/ [Bruce D'Arcus]: http://community.muohio.edu/blogs/darcusb/ [John MacFarlane]: http://johnmacfarlane.net/+[Haddock]: http://www.haskell.org/haddock/ [markdown]: http://daringfireball.net/projects/markdown/ [reStructuredText]: http://docutils.sourceforge.net/docs/ref/rst/introduction.html
citeproc-hs.cabal view
@@ -1,22 +1,23 @@ name: citeproc-hs-version: 0.1+version: 0.2 homepage: http://code.haskell.org/citeproc-hs synopsis: A Citation Style Language implementation in Haskell -description: citeproc-hs is a Hakell port of Citeproc, a- processor for converting citations into a variety- of formats using a macro language called Citation- Style Language (CSL).- .- For more details on Citeproc and CSL, please check:- <http://xbiblio.sourceforge.net/>.+description: citeproc-hs is a library for automatically+ formatting bibliographic reference citations into+ a variety of styles using a macro language called+ Citation Style Language (CSL). More details on+ CSL can be found here:+ <http://xbiblio.sourceforge.net/>.+ .+ For the API documentation please see "Text.CSL". category: Text license: BSD3 license-file: LICENSE author: Andrea Rossato maintainer: andrea.rossato@ing.unitn.it-cabal-version: >= 1.2+cabal-version: >= 1.6 build-type: Simple data-files: locales/locales-af-AZ.xml locales/locales-af-ZA.xml@@ -53,6 +54,7 @@ locales/locales-sv-SE.xml locales/locales-th-TH.xml locales/locales-tr-TR.xml+ locales/locales-uk-UA.xml locales/locales-vi-VN.xml locales/locales-zh-CN.xml locales/locales-zh-TW.xml@@ -63,25 +65,37 @@ flag test description: Run the textsuite. +flag bibutils+ description: Use Chris Putnam's Bibutils.+ default: False+ library- exposed-modules: Text.CSL- Text.CSL.Eval- Text.CSL.Parser- Text.CSL.Proc- Text.CSL.Reference- Text.CSL.Style- Text.CSL.Input.MODS- Text.CSL.Output.Pandoc- Text.CSL.Output.Plain- other-modules: Paths_citeproc_hs- ghc-options: -funbox-strict-fields -Wall- ghc-prof-options: -prof -auto-all- hs-source-dirs: src dist/build/autogen+ exposed-modules: Text.CSL+ Text.CSL.Eval+ Text.CSL.Parser+ Text.CSL.Proc+ Text.CSL.Proc.Collapse+ Text.CSL.Proc.Disamb+ Text.CSL.Reference+ Text.CSL.Style+ Text.CSL.Input.MODS+ Text.CSL.Input.Bibutils+ Text.CSL.Output.Pandoc+ Text.CSL.Output.Plain+ other-modules: Paths_citeproc_hs+ ghc-options: -funbox-strict-fields -Wall+ ghc-prof-options: -prof -auto-all+ hs-source-dirs: src+ build-depends: containers, directory, mtl, hxt >= 8.1 - if flag(small_base)- build-depends: base >= 3, containers, directory+ if flag(bibutils)+ build-depends: hs-bibutils, filepath, directory+ extra-libraries: bibutils+ extensions: CPP+ cpp-options: -DUSE_BIBUTILS + if impl(ghc >= 6.10)+ build-depends: base >= 4, syb else- build-depends: base < 3+ build-depends: base >= 3 && < 4 - build-depends: mtl, hxt >= 8.1
locales/locales-sr-RS.xml view
@@ -15,7 +15,7 @@ <term name="interview">интервју</term> <term name="letter">писмо</term> <term name="anonymous">анонимна</term>- <term name="anonymous" form="short">анон</term>+ <term name="anonymous" form="short">анон.</term> <term name="and others">и остали</term> <term name="in press">у штампи</term> <term name="online">на Интернету</term>@@ -109,30 +109,38 @@ <single>строфа</single> <multiple>строфе</multiple> </term>+ <term name="sub verbo">+ <single>sub verbo</single>+ <multiple>s.vv</multiple>+ </term> <term name="book" form="short">књига</term>- <term name="chapter" form="short">Пог</term>- <term name="column" form="short">кол</term>- <term name="figure" form="short">црт</term>+ <term name="chapter" form="short">Пог.</term>+ <term name="column" form="short">кол.</term>+ <term name="figure" form="short">црт.</term> <term name="folio" form="short">фолио</term>- <term name="issue" form="short">изд</term>- <term name="opus" form="short">оп</term>+ <term name="issue" form="short">изд.</term>+ <term name="opus" form="short">оп.</term> <term name="page" form="short">- <single>стр</single>- <multiple>стр</multiple>+ <single>стр.</single>+ <multiple>стр.</multiple> </term>- <term name="paragraph" form="short">пар</term>+ <term name="paragraph" form="short">пар.</term> <term name="part" form="short">део</term>- <term name="section" form="short">од</term>+ <term name="section" form="short">од.</term>+ <term name="sub verbo" form="short">+ <single>s.v</single>+ <multiple>s.vv</multiple>+ </term> <term name="verse" form="short">- <single>стр</single>- <multiple>стр</multiple>+ <single>стр.</single>+ <multiple>стр.</multiple> </term> <term name="volume" form="short"> <single>том</single> <multiple>томови</multiple> </term> <term name="edition">edition</term>- <term name="edition" form="short">изд</term>+ <term name="edition" form="short">изд.</term> <term name="paragraph" form="symbol"> <single>¶</single> <multiple>¶¶</multiple>@@ -158,19 +166,19 @@ <multiple/> </term> <term name="editor" form="short">- <single>ур</single>- <multiple>ур</multiple>+ <single>ур.</single>+ <multiple>ур.</multiple> </term> <term name="translator" form="short">- <single>прев</single>- <multiple>прев</multiple>+ <single>прев.</single>+ <multiple>прев.</multiple> </term> <term name="editor" form="verb">уредио</term> <term name="translator" form="verb">превео</term> <term name="recipient" form="verb">прима</term> <term name="interviewer" form="verb">интервјуисао</term>- <term name="editor" form="verb-short">ур</term>- <term name="translator" form="verb-short">прев</term>+ <term name="editor" form="verb-short">ур.</term>+ <term name="translator" form="verb-short">прев.</term> <term name="month-01">Јануар</term> <term name="month-02">Фебруар</term> <term name="month-03">Март</term>@@ -183,17 +191,17 @@ <term name="month-10">Октобар</term> <term name="month-11">Новембар</term> <term name="month-12">Децембар</term>- <term name="month-01" form="short">Јан</term>- <term name="month-02" form="short">Феб</term>+ <term name="month-01" form="short">Јан.</term>+ <term name="month-02" form="short">Феб.</term> <term name="month-03" form="short">Март</term>- <term name="month-04" form="short">Апр</term>+ <term name="month-04" form="short">Апр.</term> <term name="month-05" form="short">Мај</term> <term name="month-06" form="short">Јуни</term> <term name="month-07" form="short">Јули</term>- <term name="month-08" form="short">Авг</term>- <term name="month-09" form="short">Сеп</term>- <term name="month-10" form="short">Окт</term>- <term name="month-11" form="short">Нов</term>- <term name="month-12" form="short">Дец</term>+ <term name="month-08" form="short">Авг.</term>+ <term name="month-09" form="short">Сеп.</term>+ <term name="month-10" form="short">Окт.</term>+ <term name="month-11" form="short">Нов.</term>+ <term name="month-12" form="short">Дец.</term> </locale> </terms>
+ locales/locales-uk-UA.xml view
@@ -0,0 +1,207 @@+<?xml version="1.0" encoding="UTF-8"?>+<terms xmlns="http://purl.org/net/xbiblio/csl">+ <locale xml:lang="uk">+ <term name="at">на</term>+ <term name="in">в</term>+ <term name="ibid">ibid</term>+ <term name="accessed">accessed</term>+ <term name="retrieved">retrieved</term>+ <term name="from">із</term>+ <term name="forthcoming">forthcoming</term>+ <term name="references">посилання</term>+ <term name="no date">n.d.</term>+ <term name="and">і</term>+ <term name="et-al">et al.</term>+ <term name="interview">інтервю</term>+ <term name="letter">лист</term>+ <term name="anonymous">анонімний</term>+ <term name="anonymous" form="short">анон.</term>+ <term name="and others">та інші</term>+ <term name="in press">у пресі</term>+ <term name="online">online</term>+ <term name="cited">cited</term>+ <term name="internet">інтернет</term>+ <term name="presented at">presented at the</term>+ <term name="anthropology">антропологія</term>+ <term name="astronomy">астрономія</term>+ <term name="biology">біологія</term>+ <term name="botany">ботаніка</term>+ <term name="chemistry">хімія</term>+ <term name="engineering">інженерія</term>+ <term name="generic-base">generic base</term>+ <term name="geography">географія</term>+ <term name="geology">геологія</term>+ <term name="history">історія</term>+ <term name="humanities">гуманітарні</term>+ <term name="literature">література</term>+ <term name="math">математика</term>+ <term name="medicine">медицина</term>+ <term name="philosophy">філософія</term>+ <term name="physics">фізика</term>+ <term name="psychology">психологія</term>+ <term name="sociology">соціологія</term>+ <term name="science">наука</term>+ <term name="political_science">політичні науки</term>+ <term name="social_science">соціальні науки</term>+ <term name="theology">теологія</term>+ <term name="zoology">зоологія</term>+ <term name="book">+ <single>book</single>+ <multiple>books</multiple>+ </term>+ <term name="chapter">+ <single>chapter</single>+ <multiple>chapters</multiple>+ </term>+ <term name="column">+ <single>column</single>+ <multiple>columns</multiple>+ </term>+ <term name="figure">+ <single>figure</single>+ <multiple>figures</multiple>+ </term>+ <term name="folio">+ <single>folio</single>+ <multiple>folios</multiple>+ </term>+ <term name="issue">+ <single>number</single>+ <multiple>numbers</multiple>+ </term>+ <term name="line">+ <single>line</single>+ <multiple>lines</multiple>+ </term>+ <term name="note">+ <single>note</single>+ <multiple>notes</multiple>+ </term>+ <term name="opus">+ <single>opus</single>+ <multiple>opera</multiple>+ </term>+ <term name="page">+ <single>page</single>+ <multiple>pages</multiple>+ </term>+ <term name="paragraph">+ <single>paragraph</single>+ <multiple>paragraph</multiple>+ </term>+ <term name="part">+ <single>part</single>+ <multiple>parts</multiple>+ </term>+ <term name="section">+ <single>section</single>+ <multiple>sections</multiple>+ </term>+ <term name="volume">+ <single>volume</single>+ <multiple>volumes</multiple>+ </term>+ <term name="edition">+ <single>edition</single>+ <multiple>editions</multiple>+ </term>+ <term name="verse">+ <single>verse</single>+ <multiple>verses</multiple>+ </term>+ <term name="sub verbo">+ <single>sub verbo</single>+ <multiple>s.vv</multiple>+ </term>+ <term name="book" form="short">bk</term>+ <term name="chapter" form="short">chap</term>+ <term name="column" form="short">col</term>+ <term name="figure" form="short">fig</term>+ <term name="folio" form="short">f</term>+ <term name="issue" form="short">no</term>+ <term name="opus" form="short">op</term>+ <term name="page" form="short">+ <single>p</single>+ <multiple>pp</multiple>+ </term>+ <term name="paragraph" form="short">para</term>+ <term name="part" form="short">pt</term>+ <term name="section" form="short">sec</term>+ <term name="sub verbo" form="short">+ <single>s.v</single>+ <multiple>s.vv</multiple>+ </term>+ <term name="verse" form="short">+ <single>v</single>+ <multiple>vv</multiple>+ </term>+ <term name="volume" form="short">+ <single>vol</single>+ <multiple>vols</multiple>+ </term>+ <term name="edition">edition</term>+ <term name="edition" form="short">ed</term>+ <term name="paragraph" form="symbol">+ <single>¶</single>+ <multiple>¶¶</multiple>+ </term>+ <term name="section" form="symbol">+ <single>§</single>+ <multiple>§§</multiple>+ </term>+ <term name="author">+ <single/>+ <multiple/>+ </term>+ <term name="editor">+ <single>editor</single>+ <multiple>editors</multiple>+ </term>+ <term name="translator">+ <single>translator</single>+ <multiple>translators</multiple>+ </term>+ <term name="author" form="short">+ <single/>+ <multiple/>+ </term>+ <term name="editor" form="short">+ <single>ed</single>+ <multiple>eds</multiple>+ </term>+ <term name="translator" form="short">+ <single>tran</single>+ <multiple>trans</multiple>+ </term>+ <term name="editor" form="verb">edited by</term>+ <term name="translator" form="verb">translated by</term>+ <term name="recipient" form="verb">to</term>+ <term name="interviewer" form="verb">interview by</term>+ <term name="editor" form="verb-short">ed</term>+ <term name="translator" form="verb-short">trans</term>+ <term name="month-01">Січень</term>+ <term name="month-02">Лютий</term>+ <term name="month-03">Березень</term>+ <term name="month-04">Квітень</term>+ <term name="month-05">Травень</term>+ <term name="month-06">Червень</term>+ <term name="month-07">Липень</term>+ <term name="month-08">Серпень</term>+ <term name="month-09">Вересень</term>+ <term name="month-10">Жовтень</term>+ <term name="month-11">Листопад</term>+ <term name="month-12">Грудень</term>+ <term name="month-01" form="short">Січ</term>+ <term name="month-02" form="short">Лют</term>+ <term name="month-03" form="short">Бер</term>+ <term name="month-04" form="short">Квіт</term>+ <term name="month-05" form="short">Трав</term>+ <term name="month-06" form="short">Чер</term>+ <term name="month-07" form="short">Лип</term>+ <term name="month-08" form="short">Сер</term>+ <term name="month-09" form="short">Вер</term>+ <term name="month-10" form="short">Жов</term>+ <term name="month-11" form="short">Лис</term>+ <term name="month-12" form="short">Груд</term>+ </locale>+</terms>
src/Text/CSL.hs view
@@ -4,29 +4,51 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable ----- The CSL implementation+-- /citeproc-hs/ is a library for automatically formatting+-- bibliographic reference citations into a variety of styles using a+-- macro language called Citation Style Language (CSL). More details+-- on CSL can be found here: <http://xbiblio.sourceforge.net/>. --+-- This module documents and exports the library API.+-- ----------------------------------------------------------------------------- module Text.CSL- ( readCSLFile+ ( -- * Introduction+ -- $intro++ -- * Overview: A Simple Example+ -- $overview++ -- * Reading Bibliographic Databases+ readBiblioFile , readModsFile , readModsColletionFile++ -- ** Reference Representation , Reference (..) , getReference++ -- * CSL Parser, Representation, and Processing+ , readCSLFile++ -- ** The Style Types , Style (..) , Citation (..) , Bibliography (..)- , FormattedOutput (..)- , evalLayout- , BiblioData (..)++ -- ** High Level Processing , citeproc , processCitations , processBibliography+ , BiblioData (..)++ -- * The output and the rendering functions+ , FormattedOutput (..) , renderPlain , renderPlainStrict , renderPandoc@@ -34,12 +56,83 @@ , renderPandocStrict ) where -import Text.CSL.Eval import Text.CSL.Parser import Text.CSL.Proc import Text.CSL.Reference import Text.CSL.Style+import Text.CSL.Input.Bibutils import Text.CSL.Input.MODS import Text.CSL.Output.Pandoc import Text.CSL.Output.Plain ++-- $intro+--+-- /citeproc-hs/ provides functions for reading bibliographic+-- databases, for reading and parsing CSL files and for generating+-- citations in an internal format, 'FormattedOutput', that can be+-- easily rendered into different final formats. At the present time+-- only 'Pandoc' and plain text rendering functions are provided by+-- the library.+--+-- The library also provides a wrapper around hs-bibutils, the Haskell+-- bindings to Chris Putnam's bibutils, a library that interconverts+-- between various bibliography formats using a common MODS-format XML+-- intermediate.+--+-- For more information about hs-bibutils see here:+-- <http://code.haskell.org/hs-bibutils/>.+--+-- /citeproc-hs/ can natively read MODS formatted bibliographic+-- databases.++-- $overview+--+-- The following example assumes you have properly installed+-- hs-bibutils. If not you can use bibutils to convert the following+-- bibtex bibliographic database into a MODS collection.+--+-- Suppose you have a small bibliographic database, like this one:+--+-- > @Book{Rossato2005,+-- > author="Andrea Rossato",+-- > title="My First Book",+-- > year="2005"+-- > }+-- >+-- > @Book{Rossato2006,+-- > author="Andrea Rossato",+-- > title="My Second Book",+-- > year="2006"+-- > }+-- >+-- > @Book{Caso2007,+-- > author="Roberto Caso",+-- > title="Roberto's Book",+-- > year="2007"+-- > }+--+-- Save it as @mybibdb.bib@.+--+-- Then you can grab one of the CSL style developed by the Zotero+-- community. Suppose this one:+--+-- <http://www.zotero.org/styles/apa>+--+-- saved locally as @apa.csl@.+--+-- This would be a simple program that formats a list of citations+-- according to that style:+--+-- > import Text.CSL+-- >+-- > main :: IO ()+-- > main = do+-- > m <- readBiblioFile "mybibdb.bib" "bibtex"+-- > s <- readCSLFile "apa.csl"+-- > let result = citeproc s m $ [[("Caso2007","p. 10"),("Rossato2005","p. 10"),("Rossato2006","p. 15")]]+-- > putStrLn . unlines . map (renderPlainStrict) . citations $ result+--+-- The result would be:+--+-- > (Caso, 2007, p. 10; Rossato, 2005, p. 10, 2006, p. 15)
src/Text/CSL/Eval.hs view
@@ -5,7 +5,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -172,12 +172,12 @@ getOptionVal "subsequent-author-substitute" ops else do res <- agents ea s as if res /= []- then return . return . FC k res =<<+ then return . return . OContrib k res =<< mapM (rest ags ea s) [1 + l .. length ags] else return [] r' <- evalNames xs nl d return $ if r /= [] && r' /= []- then r ++ [S d] ++ r'+ then r ++ [ODel d] ++ r' else cleanOutput (r ++ r') | otherwise = return [] where@@ -247,6 +247,7 @@ | Just v <- fromValue val :: Maybe String = output fm v | Just v <- fromValue val :: Maybe Locator = output fm (locString v) | Just v <- fromValue val :: Maybe Int = output fm (if v == 0 then [] else show v)+ | Just v <- fromValue val :: Maybe CNum = if v == 0 then [] else [OCitNum (unCNum v) fm] | Just v <- fromValue val :: Maybe [RefDate] = formatDate s [] defaultDate v | Just v <- fromValue val :: Maybe [Agent] = concatMap (formatName True f fm defaultNameFormatting) v | otherwise = []@@ -284,9 +285,9 @@ | True <- et , length x > 1 = addDelim d x | "always" <- delimiterPrecedesLast nf- , length x == 2 = addDelim d (init x) ++ S (d <> andStr nf) : [last x]- | length x == 2 = addDelim d (init x) ++ S ( andStr nf) : [last x]- | length x > 2 = addDelim d (init x) ++ S (d <> andStr nf) : [last x]+ , length x == 2 = addDelim d (init x) ++ ODel (d <> andStr nf) : [last x]+ | length x == 2 = addDelim d (init x) ++ ODel ( andStr nf) : [last x]+ | length x > 2 = addDelim d (init x) ++ ODel (d <> andStr nf) : [last x] | otherwise = addDelim d x andStr nf | "text" <- andConnector nf = " and "@@ -294,17 +295,20 @@ | otherwise = [] isPlural p = (&&) p . (<) 1 +-- | Generate the 'Agent's names applying et-al options, with all+-- possible permutations to disambiguate colliding citations. formatName :: Bool -> Form -> Formatting -> NameFormatting -> Agent -> [Output] formatName b f fm nf n | Person {} <- n- , Short <- f = return $ FN short rest fm- | Person {} <- n = return $ FN (long given') [long given] fm+ , Short <- f = return $ OName short rest fm+ | Person {} <- n = return $ OName (long given') [long given] fm | Entity s <- n = output fm s | otherwise = [] where- rest = [ family $ concatMap (flip (:) ". " . head) (givenName n)+ rest = [ family $ concatMap addPnt (givenName n) , long given] addSpace = flip (++) (if b then [] else " ")+ addPnt x = if x /= [] then head x : ". " else [] format x = procList x initia initia x = if initializeWith nf /= [] then head x : initializeWith nf@@ -337,10 +341,10 @@ where addZero n = if length n == 1 then '0' : n else n formatDatePart (RefDate y m d o) (DatePart n f fm)- | "year" <- n, y /= 0 = return $ FY (formatYear f $ show y) s fm- | "month" <- n, m /= 0 = output fm (formatMonth f $ show m)- | "day" <- n, d /= 0 = output fm (formatDay f $ show d)- | "other" <- n, o /= [] = output fm o+ | "year" <- n, y /= 0 = return $ OYear (formatYear f $ show y) s fm+ | "month" <- n, m /= 0 = output fm (formatMonth f $ show m)+ | "day" <- n, d /= 0 = output fm (formatDay f $ show d)+ | "other" <- n, o /= [] = output fm o | otherwise = [] formatYear f y | "short" <- f = drop 2 y@@ -364,10 +368,10 @@ _ -> "th" output :: Formatting -> String -> [Output]-output fm s = if s /= "" then [FS s fm] else []+output fm s = if s /= "" then [OStr s fm] else [] appendOutput :: Formatting -> [Output] -> [Output]-appendOutput fm xs = if xs /= [] then [O xs fm] else []+appendOutput fm xs = if xs /= [] then [Output xs fm] else [] outputList :: Formatting -> Delimiter -> [Output] -> [Output] outputList fm d = appendOutput fm . addDelim d . cleanOutput@@ -375,11 +379,11 @@ cleanOutput :: [Output] -> [Output] cleanOutput = filter isNotEmpty where- isNotEmpty (FS "" _) = False- isNotEmpty _ = True+ isNotEmpty (OStr "" _) = False+ isNotEmpty _ = True addDelim :: String -> [Output] -> [Output]-addDelim d = foldr (\x xs -> if length xs < 1 then x : xs else x : S d : xs) []+addDelim d = foldr (\x xs -> if length xs < 1 then x : xs else x : ODel d : xs) [] consumeVariable :: String -> State EvalState () consumeVariable s@@ -406,6 +410,9 @@ formatVariable :: String -> String formatVariable = foldr f [] where f x xs = if x == '_' then '-' : xs else toLower x : xs++head' :: [a] -> [a]+head' = foldr (\x _ -> [x]) [] trace :: String -> State EvalState () trace d = modify $ \s -> s { debug = d : debug s }
+ src/Text/CSL/Input/Bibutils.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE CPP, ForeignFunctionInterface, PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module : Text.CSL.Input.Bibutils+-- Copyright : (C) 2008 Andrea Rossato+-- License : BSD3+--+-- Maintainer : andrea.rossato@unitn.it+-- Stability : unstable+-- Portability : unportable+--+-----------------------------------------------------------------------------++module Text.CSL.Input.Bibutils+ ( readBiblioFile+ ) where++import Text.CSL.Reference+import Text.CSL.Input.MODS++#ifdef USE_BIBUTILS+import Data.Char+import System.Directory ( getTemporaryDirectory, removeFile )+import System.FilePath ( takeExtension, (</>) )+import System.IO+import Text.Bibutils+#endif++-- | Read a file with a bibliographic database of the format specified+-- by the 'String'. If the 'String' is empty the file extension will+-- be used to identify the format.+--+-- Supported formats are: @\"mods\"@, @\"bibtex\"@, @\"biblatex\"@,+-- @\"ris\"@, @\"endnote\"@, @\"endnotexml\"@, @\"isi\"@,+-- @\"medline\"@, and @\"copac\"@.+readBiblioFile :: FilePath -> String -> IO [Reference]+#ifdef USE_BIBUTILS+readBiblioFile f m+ | [] <- m = let mode = case takeExtension (map toLower f) of+ ".mods" -> mods_in+ ".bib" -> bibtex_in+ ".bbx" -> biblatex_in+ ".ris" -> ris_in+ ".enl" -> endnote_in+ ".xml" -> endnotexml_in+ ".wos" -> isi_in+ ".medline" -> medline_in+ ".copac" -> copac_in+ _ -> error "Bibliography format not supported."+ in readBiblioFile' f mode+ | otherwise = let mode = case m of+ "mods" -> mods_in+ "bibtex" -> bibtex_in+ "biblatex" -> biblatex_in+ "ris" -> ris_in+ "endnote" -> endnote_in+ "endnotexml" -> endnotexml_in+ "isi" -> isi_in+ "medline" -> medline_in+ "copac" -> copac_in+ _ -> error "Bibliography format not supported."+ in readBiblioFile' f mode++#else+readBiblioFile f m+ | "mods" <- m = readModsColletionFile f+ | otherwise = error $ "Bibliography format not supported.\n" +++ "citeproc-hs was not compiled with bibutils support"+#endif++#ifdef USE_BIBUTILS+readBiblioFile' :: FilePath -> BiblioIn -> IO [Reference]+readBiblioFile' fin bin+ | bin == mods_in = readModsColletionFile fin+ | otherwise = do+ tdir <- getTemporaryDirectory+ (f,h) <- openTempFile tdir "citeproc.txt"+ hClose h+ let tfile = tdir </> f+ param <- bibl_initparams bin mods_out "citeproc-hs"+ bibl <- bibl_init+ unsetBOM param+ bibl_read param bibl fin+ bibl_write param bibl tfile+ bibl_free bibl+ bibl_freeparams param+ refs <- readModsColletionFile tfile+ removeFile tfile+ return refs+#endif
src/Text/CSL/Input/MODS.hs view
@@ -6,7 +6,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -24,10 +24,12 @@ import Data.Char ( isDigit ) -readModsFile :: String -> IO Reference+-- | Read a file with a single MODS record.+readModsFile :: FilePath -> IO Reference readModsFile f = readXmlFile xpMods f -readModsColletionFile :: String -> IO [Reference]+-- | Read a file with a collection of MODS records.+readModsColletionFile :: FilePath -> IO [Reference] readModsColletionFile f = readXmlFile xpModsCollection f xpModsCollection :: PU [Reference]
src/Text/CSL/Output/Pandoc.hs view
@@ -5,7 +5,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -26,14 +26,20 @@ import Text.CSL.Style import Text.CSL.Output.Plain +-- | With a 'Style' and the formatted output generate a 'String' in+-- the native 'Pandoc' formats (i.e. immediately readable by pandoc). renderPandoc :: Style -> [FormattedOutput] -> String renderPandoc _ = show . clean . concatMap (render False) +-- | Same as 'renderPandoc', but the output is wrapped in a pandoc+-- paragraph block. renderPandoc' :: Style -> [FormattedOutput] -> String renderPandoc' _ = show . Para . clean . concatMap (render False) +-- | Same as 'renderPandoc', but will not clean up the produced+-- output. renderPandocStrict :: [FormattedOutput] -> String renderPandocStrict = show . cleanStrict . concatMap (render True)
src/Text/CSL/Output/Plain.hs view
@@ -5,7 +5,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -26,9 +26,12 @@ import Text.CSL.Style +-- | Render the 'FormattedOutput' into a plain text string. renderPlain :: [FormattedOutput] -> String renderPlain = concatMap $ render False +-- | Same as 'renderPlain' , but will not clean up the produced+-- output. renderPlainStrict :: [FormattedOutput] -> String renderPlainStrict = concatMap $ render True
src/Text/CSL/Parser.hs view
@@ -6,7 +6,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -413,7 +413,9 @@ [x] -> return x _ -> error $ "error while reading file " ++ f -readCSLFile :: String -> IO Style+-- | Read and parse a CSL style file into the internal style+-- representation, the 'Style'.+readCSLFile :: FilePath -> IO Style readCSLFile f = do s <- readXmlFile xpStyle f l <- getDataFileName ("locales/locales-" ++ styleLocale s ++ ".xml")
src/Text/CSL/Proc.hs view
@@ -5,93 +5,62 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable ----- Output processing.+-- This module provides functions for processing the evaluated+-- 'Output' for disambiguation and citation collapsing. -- ----------------------------------------------------------------------------- module Text.CSL.Proc where -import Control.Arrow ( (&&&), (>>>), (***) )+import Control.Arrow ( (&&&), (***) ) import Data.Char ( chr )-import Data.List ( (\\), elemIndex, findIndices- , sortBy, mapAccumL, nub, groupBy- , isPrefixOf )+import Data.List ( elemIndex, findIndices+ , sortBy, mapAccumL, nub ) import Data.Maybe import Data.Ord ( comparing ) import Text.CSL.Eval+import Text.CSL.Proc.Collapse+import Text.CSL.Proc.Disamb import Text.CSL.Reference import Text.CSL.Style +-- | With a 'Style', a list of 'Reference's and the list of citation+-- groups (the list of citations with their locator), produce the+-- 'FormattedOutput' for each citation group. processCitations :: Style -> [Reference] -> [[(String, String)]] -> [[FormattedOutput]] processCitations s rs = citations . citeproc s rs +-- | With a 'Style' and the list of 'Reference's produce the+-- 'FormattedOutput' for the bibliography. processBibliography :: Style -> [Reference] -> [[FormattedOutput]] processBibliography s rs = bibliography $ citeproc s rs [zip (map citeKey rs) (repeat "")] +-- | With a 'Style', a list of 'Reference's and the list of citation+-- groups (the list of citations with their locator), produce the+-- 'FormattedOutput' for each citation group and the bibliography. citeproc :: Style -> [Reference] -> [[(String, String)]] -> BiblioData citeproc s rs cs- = BD (outputGroups citOutput) biblioOutput+ = BD citsOutput biblioOutput where- bibs = refsYSuffix . procRefs s . map (getReference rs) .- nub . map (id *** const []) . concat $ cs- refs = getRefs bibs cs- groups = map (procGroup s) refs-- -- | group citation data (with possible alternative names) for every- -- list of contributors which has a duplicate.- contribs = nub $ concatMap (\(CG _ _ os) -> concatMap getCiteData os) groups- collid = map rmGivenNames . collision- duplics = groupBy (\a b -> collid a == collid b) .- sortBy (comparing collid) $- filter (collid &&& citYear >>> flip elem (getDuplicates groups)) contribs-- needYSuff = map (allTheSame . map disData) duplics- needName = concatMap fst . filter (not . snd) $ zip duplics needYSuff-- disSolved = zip needName (disambiguate $ map disData needName)- addLNames = map (\(c,n) -> c { disambed = head n }) disSolved- addGNames = map (\ c -> c { disambed = addGivenNames (disambed c) })-- chkdup = same . proc rmGivenNames . map disambed- need a = map fst . filter (not . snd) . zip a- done a = (,) (need a $ chkdup a) (a \\ (need a $ chkdup a))-- disOpts = getDisOptions s- hasNames = "disambiguate-add-names" `elem` disOpts- hasGName = "disambiguate-add-givenname" `elem` disOpts- hasYSuff = "disambiguate-add-year-suffix" `elem` disOpts- nameDis = case () of- _ | hasNames- , hasGName -> let (n ,ns ) = done addLNames- (n',ns') = done $ addGNames ns- in n ++ n' ++ addGNames ns'- | hasNames -> fst . done $ addLNames- | hasGName -> fst . done $ addGNames needName- | otherwise -> []-- reEval = let chk = if hasYSuff then filter ((==) [] . citYear) else id- in chk . concatMap fst . filter snd $ zip duplics needYSuff- reEvaluated = if or (query hasIfDis s) && reEval /= []- then map (uncurry $ reEvaluate s reEval) $ zip refs groups- else groups-+ -- the list of bib entries, as a list of Reference, with+ -- position, locator and year suffix set.+ biblioRefs = refsYSuffix . procRefs s . map (getReference rs) .+ nub . map (id *** const []) . concat $ cs+ biblioOutput = if "disambiguate-add-year-suffix" `elem` getCitDisambOptions s+ then map (map formatOutput) $ proc addYearSuffix $ procBiblio s biblioRefs+ else map (map formatOutput) $ procBiblio s biblioRefs outputGroups = map $ \(CG fm d os) -> map formatOutput $ outputList fm d os- citOutput = if disOpts /= []- then if hasYSuff- then proc addYearSuffix $ proc (updateOutput nameDis) reEvaluated- else proc (updateOutput nameDis) reEvaluated- else groups- biblioOutput = if hasYSuff- then map (map formatOutput) $ proc addYearSuffix $ procBiblio s bibs- else map (map formatOutput) $ procBiblio s bibs+ citsOutput = outputGroups $ collapseCitGroups s $ disambCitations s biblioRefs cs +-- | With a 'Style' and a sorted list of 'Reference's produce the+-- evaluated output for the bibliography. procBiblio :: Style -> [Reference] -> [[Output]] procBiblio (Style {biblio = mb, csMacros = ms , csTerms = ts}) rs = maybe [] process mb@@ -104,14 +73,20 @@ then ("subsequent",x) : chkAut a xs else ("first" ,x) : chkAut (author x : a) xs +-- | Given the CSL 'Style' and the list of 'Reference's sort the list+-- according to the 'Style' and assign the citation number to each+-- 'Reference'. procRefs :: Style -> [Reference] -> [Reference] procRefs (Style {biblio = mb, csMacros = ms , csTerms = ts}) rs = maybe rs process mb where- citNum x = x { citationNumber = maybe 0 ((+) 1) . elemIndex x $ rs }+ citNum x = x { citationNumber = maybe 0 ((+) 1 . fromIntegral) . elemIndex x $ rs } sort b = evalSorting ts ms (bibOptions b) (bibSort b) process b = map fst . sortBy (comparing snd) . map (citNum &&& sort b) $ rs +-- | Given the list of 'Reference's, compare year and contributors'+-- names and, when they collide, generate a suffix to append to the+-- year for disambiguation. refsYSuffix :: [Reference] -> [Reference] refsYSuffix rs = update indices@@ -131,130 +106,8 @@ , length i > 1 -> i | otherwise -> [] -procGroup :: Style -> [(String,Reference)] -> CitationGroup-procGroup (Style {citation = c, csMacros = ms , csTerms = ts})- = CG (layFormat $ citLayout c) (layDelim $ citLayout c) . concat . process- where- format (p,r) = evalLayout (citLayout c) False ts ms (citOptions c) p r- sort = evalSorting ts ms (citOptions c) (citSort c) . snd- process = map fst . sortBy (comparing snd) . map (format &&& sort)--reEvaluate :: Style -> [CiteData] -> [(String,Reference)] -> CitationGroup -> CitationGroup-reEvaluate (Style {citation = c, csMacros = ms , csTerms = ts}) l pr (CG f d os)- = CG f d . flip concatMap (zip pr os) $- \((p,r),out) -> if citeKey r `elem` map key l- then evalLayout (citLayout c) True ts ms (citOptions c) p r- else [out]- suffixes :: [String] suffixes = l ++ [x ++ y | x <- l, y <- l ] where l = map (return . chr) [97..122]--updateOutput :: [CiteData] -> Output -> Output-updateOutput m o- | FC k x _ <- o = case elemIndex (CD k x [] [] []) m of- Just i -> FC k (disambed $ m !! i) []- _ -> o- | otherwise = o--getDisOptions :: Style -> [String]-getDisOptions- = map fst . filter ((==) "true" . snd) .- filter (isPrefixOf "disambiguate" . fst) . citOptions . citation--getRefs :: [Reference] -> [[(String, String)]] -> [[(String, Reference)]]-getRefs r = map (map $ getReference' r) . generatePosition---- | The contributors diambiguation data, the list of names and--- give-names, and the citation year ('FY').-type NamesYear = ([Output],String)---- | Get the contributors list ('FC') and the year occurring in more--- then one citation.-getDuplicates :: [CitationGroup] -> [NamesYear]-getDuplicates- = nub . catMaybes . snd . mapAccumL dupl [] . getData- where- getData l = concat . map nub . flip map l $ \(CG _ _ os) -> concatMap getNamesYear os- dupl a c = if snd c `elem` map snd a- then if fst c `elem` map fst a then (a,Nothing) else (c:a,Just $ snd c)- else if fst c `elem` map fst a then (a,Nothing) else (c:a,Nothing )--getNamesYear :: Output -> [(String,NamesYear)]-getNamesYear- = proc rmGivenNames >>>- query contribs &&& years >>>- zipData- where- yearsQ = query getYears- years o = if yearsQ o /= [] then yearsQ o else [""]- zipData = uncurry . zipWith $ \(k,c) y -> (,) k (c,y)- contribs o- | FC k x _ <- o = [(k,x)]- | otherwise = []--getYears :: Output -> [String]-getYears o- | FY x _ _ <- o = [x]- | otherwise = []--hasIfDis :: IfThen -> [Bool]-hasIfDis o- | IfThen (Condition {disambiguation = d}) _ _ <- o = [d /= []]- | otherwise = [False ]---- | Get the list of possible non ambiguous names for every citation--- whose contributor list and year is occuring in more then one--- citation.-getCiteData :: Output -> [CiteData]-getCiteData- = query contribs &&& years >>>- zipData- where- yearsQ = query getYears- years o = if yearsQ o /= [] then yearsQ o else [""]- zipData = uncurry . zipWith $ \c y -> c {citYear = y}- contribs o- | FC k x xs <- o = [CD k x xs [] []]- | otherwise = []---- List Utilities--disambiguate :: (Eq a) => [[a]] -> [[a]]-disambiguate [] = []-disambiguate ls- = if hasDuplicates takeHead- then diff ++ disambiguate (map tail' dupl)- else takeHead- where- zipped = zip ls takeHead- diff = map fst . filter (not . snd) $ zip takeHead (same takeHead)- dupl = map (fst . fst) . filter snd $ zip zipped (same takeHead)-- takeHead = map head' ls- head' = foldr (\x _ -> [x]) []- tail' [x] = [x]- tail' x = tail x--same :: Eq a => [a] -> [Bool]-same [] = []-same l- = snd $ mapAccumL check (catMaybes dupl) l- where- dupl = snd $ mapAccumL (\a x -> if x `elem` a then (a,Just x) else (x:a,Nothing)) [] l- check a e = if e `elem` a then (a,True) else (e:a,False)--hasDuplicates :: Eq a => [a] -> Bool-hasDuplicates = hasSame or--allTheSame :: Eq a => [a] -> Bool-allTheSame = hasSame and--hasSame :: Eq a => ([Bool] -> Bool) -> [a] -> Bool-hasSame _ [] = False-hasSame f l- = f . snd $ mapAccumL check [head l] (tail l)- where- check a e = if e `elem` a then (a,True) else (e:a,False)
+ src/Text/CSL/Proc/Collapse.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module : Text.CSL.Proc.Collapse+-- Copyright : (c) Andrea Rossato+-- License : BSD-style (see LICENSE)+--+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it>+-- Stability : unstable+-- Portability : unportable+--+-- This module provides functions for processing the evaluated+-- 'Output' for citation collapsing.+--+-----------------------------------------------------------------------------++module Text.CSL.Proc.Collapse where++import Control.Arrow ( (&&&), (>>>) )+import Data.List ( groupBy )++import Text.CSL.Eval+import Text.CSL.Proc.Disamb+import Text.CSL.Style++-- | Collapse citations according to the style options.+collapseCitGroups :: Style -> [CitationGroup] -> [CitationGroup]+collapseCitGroups s+ = map doCollapse+ where+ doCollapse = case getCollapseOptions s of+ "year" : _ -> collapseYear+ "year-suffix" : _ -> collapseYearSuf+ "citation-number" : _ -> collapseNumber+ _ -> id++-- | Get the collapse option set in the 'Style' for citations.+getCollapseOptions :: Style -> [String]+getCollapseOptions+ = map snd . filter ((==) "collapse" . fst) . citOptions . citation++collapseNumber :: CitationGroup -> CitationGroup+collapseNumber (CG fm d os) = CG fm d (process os)+ where+ citNum o+ | OCitNum i f <- o = [(i,f)]+ | otherwise = []+ numOf = foldr (\x _ -> x) (0,emptyFormatting) . query citNum+ newNum = map numOf >>> (map fst >>> groupConsec) &&& map snd >>> uncurry zip+ process xs = flip concatMap (newNum xs) $+ \(x,f) -> if length x > 2+ then return $ Output [ OCitNum (head x) f+ , ODel "-"+ , OCitNum (last x) f+ ] emptyFormatting+ else map (flip OCitNum f) x++collapseYear :: CitationGroup -> CitationGroup+collapseYear (CG f d os) = CG f d (process os)+ where+ rmNames [] = []+ rmNames (x:xs) = x : remove xs+ remove = proc rmFirstDelim . proc rmContribs+ namesOf = map (fst . snd) . getNamesYear+ process = map (\x -> Output (addDelim ", " $ rmNames x) emptyFormatting) .+ groupBy (\a b -> namesOf a == namesOf b)++collapseYearSuf :: CitationGroup -> CitationGroup+collapseYearSuf (CG f d os) = CG f d (process os)+ where+ rmNames [] = []+ rmNames (x:xs) = x : remove xs+ remove = proc rmFirstDelim . proc rmYear . proc rmContribs+ namesOf = map (fst . snd) . getNamesYear+ yearOf = concatMap (take 4 . snd . snd) . getNamesYear+ process = map (\x -> Output (addDelim ", " $ rmNames x) emptyFormatting) .+ groupBy (\a b -> namesOf a == namesOf b && yearOf a == yearOf b)++ rmYear o+ | OYear _ sf fm <- o = OYear sf sf fm+ | otherwise = o++rmFirstDelim :: Output -> Output+rmFirstDelim o+ | Output os f <- o = Output (rm os) f+ | otherwise = o+ where+ rm [] = []+ rm (x:xs)+ | ODel _ <- x = xs+ | otherwise = x : rm xs++-- | Group consecutive integers:+--+-- > groupConsec [1,2,3,5,6,8,9] == [[1,2,3],[5,6],[8,9]]+groupConsec :: [Int] -> [[Int]]+groupConsec = groupConsec' []+ where+ groupConsec' x [] = x+ groupConsec' [] (y:ys) = groupConsec' [[y]] ys+ groupConsec' xs (y:ys) = if y - head (last xs) == length (last xs)+ then groupConsec' (init xs ++ [last xs ++ [y]]) ys+ else groupConsec' ( xs ++ [ [y]]) ys
+ src/Text/CSL/Proc/Disamb.hs view
@@ -0,0 +1,249 @@+{-# LANGUAGE PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module : Text.CSL.Proc.Disamb+-- Copyright : (c) Andrea Rossato+-- License : BSD-style (see LICENSE)+--+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it>+-- Stability : unstable+-- Portability : unportable+--+-- This module provides functions for processing the evaluated+-- 'Output' for citation disambiguation.+--+-- Describe the disambiguation process.+--+-----------------------------------------------------------------------------++module Text.CSL.Proc.Disamb where++import Control.Arrow ( (&&&), (>>>) )+import Data.List ( (\\), elemIndex, sortBy, mapAccumL+ , nub, groupBy, isPrefixOf )+import Data.Maybe+import Data.Ord ( comparing )++import Text.CSL.Eval+import Text.CSL.Reference+import Text.CSL.Style++-- | Given the 'Style', the list of references and the citation+-- groups, disambiguate citations according to the style options.+disambCitations :: Style -> [Reference] -> [[(String, String)]] -> [CitationGroup]+disambCitations s bibs cs+ = citOutput+ where+ -- the list of the position and the reference of each citation+ -- for each citation group.+ refs = getRefs bibs cs+ -- citation groups+ groups = map (procGroup s) refs+ -- citation data of duplicates+ duplics = getDuplCiteData groups++ -- check the options set in the style+ disOpts = getCitDisambOptions s+ hasNames = "disambiguate-add-names" `elem` disOpts+ hasGName = "disambiguate-add-givenname" `elem` disOpts+ hasYSuff = "disambiguate-add-year-suffix" `elem` disOpts++ -- citations for which adding a name is not enough.+ needYSuff = map (allTheSame . map disambData) duplics+ needName = concatMap fst . filter (not . snd) $ zip duplics needYSuff++ -- apply name disambiguation options+ addNames = disambWithNames hasNames hasGName needName++ -- the list of citations that need re-evaluation with the+ -- \"disambiguate\" condition set to 'True'+ reEval = let chk = if hasYSuff then filter ((==) [] . citYear) else id+ in chk . concatMap fst . filter snd $ zip duplics needYSuff+ reEvaluated = if or (query hasIfDis s) && reEval /= []+ then map (uncurry $ reEvaluate s reEval) $ zip refs groups+ else groups++ -- generate the final FormattedOutput.+ citOutput = if disOpts /= []+ then if hasYSuff+ then proc addYearSuffix $ proc (updateOutput addNames) reEvaluated+ else proc (updateOutput addNames) reEvaluated+ else groups++-- | Disambiguate a list of 'CiteData' by adding names to the list of+-- contributors, thus overriding @et-al@ options, if the first 'Bool'+-- is 'True', and/or by adding given-names if the second 'Bool' is+-- 'True'.+disambWithNames :: Bool -> Bool -> [CiteData] -> [CiteData]+disambWithNames bn bg needName+ | bn && bg = let (n ,ns ) = done addLNames+ (n',ns') = done $ addGNames ns+ in n ++ n' ++ addGNames ns'+ | bn = fst . done $ addLNames+ | bg = fst . done $ addGNames needName+ | otherwise = []+ where+ -- do name disambiguation+ disSolved = zip needName (disambiguate $ map disambData needName)+ addLNames = map (\(c,n) -> c { disambed = head n }) disSolved+ addGNames = map (\ c -> c { disambed = addGivenNames (disambed c) })++ chkdup = same . proc rmGivenNames . map disambed+ need a = map fst . filter (not . snd) . zip a+ done a = (,) (need a $ chkdup a) (a \\ (need a $ chkdup a))++-- | Given the list of 'CiteData' with the disambiguated field set+-- update the evaluated citations by setting the contributor list+-- accordingly.+updateOutput :: [CiteData] -> Output -> Output+updateOutput m o+ | OContrib k x _ <- o = case elemIndex (CD k x [] [] []) m of+ Just i -> OContrib k (disambed $ m !! i) []+ _ -> o+ | otherwise = o++-- | Given the CSL 'Style' and the list of 'Reference's coupled with+-- their position, generate a 'CitationGroup'. The citations are+-- sorted according to the 'Style'.+procGroup :: Style -> [(String,Reference)] -> CitationGroup+procGroup (Style {citation = c, csMacros = ms , csTerms = ts})+ = CG (layFormat $ citLayout c) (layDelim $ citLayout c) . concat . process+ where+ format (p,r) = evalLayout (citLayout c) False ts ms (citOptions c) p r+ sort = evalSorting ts ms (citOptions c) (citSort c) . snd+ process = map fst . sortBy (comparing snd) . map (format &&& sort)+++-- | Evaluate again a citation group with the 'EvalState' 'disamb'+-- field set to 'True' (for matching the @\"disambiguate\"@+-- condition).+reEvaluate :: Style -> [CiteData] -> [(String,Reference)] -> CitationGroup -> CitationGroup+reEvaluate (Style {citation = c, csMacros = ms , csTerms = ts}) l pr (CG f d os)+ = CG f d . flip concatMap (zip pr os) $+ \((p,r),out) -> if citeKey r `elem` map key l+ then evalLayout (citLayout c) True ts ms (citOptions c) p r+ else [out]++-- | Check if the 'Style' has any conditional for disambiguation. In+-- this case the conditional will be try after all other+-- disambiguation strategies have failed. To be used with the generic+-- 'query' function.+hasIfDis :: IfThen -> [Bool]+hasIfDis o+ | IfThen (Condition {disambiguation = d}) _ _ <- o = [d /= []]+ | otherwise = [False ]++-- | Get the list of disambiguation options set in the 'Style' for+-- citations.+getCitDisambOptions :: Style -> [String]+getCitDisambOptions+ = map fst . filter ((==) "true" . snd) .+ filter (isPrefixOf "disambiguate" . fst) . citOptions . citation++-- | Set the locator, the 'citationNumber' and the position for each+-- citation, with the list of 'Reference's and the list of citation+-- groups (citation keys with locators).+getRefs :: [Reference] -> [[(String, String)]] -> [[(String, Reference)]]+getRefs r = map (map $ getReference' r) . generatePosition++-- | Group citation data (with possible alternative names) of+-- citations which have a duplicate (same 'collision' and same+-- 'citYear').+getDuplCiteData :: [CitationGroup] -> [[CiteData]]+getDuplCiteData g+ = groupBy (\a b -> collide a == collide b) . sortBy (comparing collide) $ duplicates+ where+ collide = proc rmGivenNames . collision+ citeData = nub $ concatMap (mapGroupOutput getCiteData) g+ duplicates = filter (collide &&& citYear >>> flip elem (getDuplNamesYear g)) citeData++-- | For an evaluated citation get its 'CiteData'. The disambiguated+-- citation and the year fields are empty.+getCiteData :: Output -> [CiteData]+getCiteData+ = query contribs &&& years >>>+ zipData+ where+ yearsQ = query getYears+ years o = if yearsQ o /= [] then yearsQ o else [""]+ zipData = uncurry . zipWith $ \c y -> c {citYear = y}+ contribs o+ | OContrib k x xs <- o = [CD k x xs [] []]+ | otherwise = []++-- | The contributors diambiguation data, the list of names and+-- give-names, and the citation year ('OYear').+type NamesYear = ([Output],String)++-- | Get the contributors list ('OContrib') and the year occurring in+-- more then one citation.+getDuplNamesYear :: [CitationGroup] -> [NamesYear]+getDuplNamesYear+ = nub . catMaybes . snd . mapAccumL dupl [] . getData+ where+ getData = concat . map nub . map (mapGroupOutput getNamesYear)+ dupl a c = if snd c `elem` map snd a+ then if fst c `elem` map fst a then (a,Nothing) else (c:a,Just $ snd c)+ else if fst c `elem` map fst a then (a,Nothing) else (c:a,Nothing )++-- | Get the list of citation keys coupled with their 'NamesYear' in+-- the evaluated 'Output'.+getNamesYear :: Output -> [(String,NamesYear)]+getNamesYear+ = proc rmGivenNames >>>+ query contribs &&& years >>>+ zipData+ where+ yearsQ = query getYears+ years o = if yearsQ o /= [] then yearsQ o else [""]+ zipData = uncurry . zipWith $ \(k,c) y -> (,) k (c,y)+ contribs o+ | OContrib k x _ <- o = [(k,x)]+ | otherwise = []++getYears :: Output -> [String]+getYears o+ | OYear x _ _ <- o = [x]+ | otherwise = []+++-- List Utilities++-- | Try to disambiguate a list of lists by returning the first non+-- colliding element, if any, of each list:+--+-- > disambiguate [[1,2],[1,3],[2]] = [[2],[3],[2]]+disambiguate :: (Eq a) => [[a]] -> [[a]]+disambiguate [] = []+disambiguate l+ = if hasMult l && not (allTheSame l) && hasDuplicates heads+ then disambiguate (rest l)+ else heads+ where+ heads = map head' l+ rest = map (\(b,x) -> if b then tail' x else head' x) . zip (same heads)++ hasMult [] = False+ hasMult (x:xs) = length x > 1 || hasMult xs++ tail' [x] = [x]+ tail' x = if null x then x else tail x++-- | For each element a list of 'Bool': 'True' if the element has a+-- duplicate in the list:+--+-- > same [1,2,1] = [True,False,True]+same :: Eq a => [a] -> [Bool]+same [] = []+same l+ = map (flip elem dupl) l+ where+ dupl = catMaybes . snd . macc [] $ l+ macc = mapAccumL $ \a x -> if x `elem` a then (a,Just x) else (x:a,Nothing)++hasDuplicates :: Eq a => [a] -> Bool+hasDuplicates = or . same++allTheSame :: Eq a => [a] -> Bool+allTheSame = and . same+
src/Text/CSL/Reference.hs view
@@ -5,7 +5,7 @@ -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -49,6 +49,7 @@ | Just v <- fromValue val :: Maybe [Agent] = v /= [] | Just v <- fromValue val :: Maybe [RefDate] = v /= [] | Just v <- fromValue val :: Maybe Int = v /= 0+ | Just v <- fromValue val :: Maybe CNum = v /= 0 | Just v <- fromValue val :: Maybe Locator = v /= NoneLoc | otherwise = False @@ -79,6 +80,7 @@ | ArticleJournal | Bill | Book+ | Broadcast | Chapter | Entry | EntryDictionary@@ -111,6 +113,9 @@ instance Show RefType where show = map toLower . formatField . showConstr . toConstr +newtype CNum = CNum { unCNum :: Int } deriving ( Show, Read, Eq, Num, Typeable, Data )++-- | The 'Reference' record. data Reference = Reference { citeKey :: String@@ -167,7 +172,7 @@ , doi :: String , isbn :: String - , citationNumber :: Int+ , citationNumber :: CNum , yearSuffix :: String , citationLabel :: String } deriving ( Eq, Show, Read, Typeable, Data )@@ -229,24 +234,29 @@ , doi = [] , isbn = [] - , citationNumber = 0+ , citationNumber = CNum 0 , yearSuffix = [] , citationLabel = [] } +-- | With the list of 'Reference's and the tuple (citation key,+-- locator), return the needed reference with the correct locator set. getReference :: [Reference] -> (String,String) -> Reference getReference r = snd . getReference' r . flip (,) ("",0) +-- | With the 'Reference' list and the generated position for each+-- tuple of citation key and locator, produce a list of 'Reference's+-- with their positions (which come first. getReference' :: [Reference] -> ((String,String),(String,Int)) -> (String, Reference) getReference' r ((c,l),(p,n)) = case c `elemIndex` map citeKey r of Just i -> (,) p $ (r !! i) { locator = parseLocator l- , citationNumber = n }+ , citationNumber = CNum n } Nothing -> (,) p $ emptyReference { title = c ++ " not found!"- , citationNumber = n }+ , citationNumber = CNum n } data Locator = NoneLoc@@ -260,6 +270,13 @@ | NoteLoc String | OpusLoc String | PageLoc String+ | PageFstLoc String+ | ParaLoc String+ | PartLoc String+ | SecLoc String+ | SubVerbLoc String+ | VolLoc String+ | VerseLoc String deriving ( Read, Eq, Typeable, Data ) instance Show Locator where@@ -277,24 +294,40 @@ | NoteLoc s <- l = s | OpusLoc s <- l = s | PageLoc s <- l = s+ | PageFstLoc s <- l = s+ | ParaLoc s <- l = s+ | PartLoc s <- l = s+ | SecLoc s <- l = s+ | SubVerbLoc s <- l = s+ | VolLoc s <- l = s+ | VerseLoc s <- l = s | otherwise = [] parseLocator :: String -> Locator parseLocator s- | "b" `isPrefixOf` formatField s = mk BookLoc- | "ch" `isPrefixOf` formatField s = mk ChapterLoc- | "co" `isPrefixOf` formatField s = mk ColumnLoc- | "fi" `isPrefixOf` formatField s = mk FigureLoc- | "fo" `isPrefixOf` formatField s = mk FolioLoc- | "i" `isPrefixOf` formatField s = mk IssueLoc- | "l" `isPrefixOf` formatField s = mk LineLoc- | "n" `isPrefixOf` formatField s = mk NoteLoc- | "o" `isPrefixOf` formatField s = mk OpusLoc- | "p" `isPrefixOf` formatField s = mk PageLoc+ | "b" `isPrefixOf` formatField s = mk BookLoc+ | "ch" `isPrefixOf` formatField s = mk ChapterLoc+ | "co" `isPrefixOf` formatField s = mk ColumnLoc+ | "fi" `isPrefixOf` formatField s = mk FigureLoc+ | "fo" `isPrefixOf` formatField s = mk FolioLoc+ | "i" `isPrefixOf` formatField s = mk IssueLoc+ | "l" `isPrefixOf` formatField s = mk LineLoc+ | "n" `isPrefixOf` formatField s = mk NoteLoc+ | "o" `isPrefixOf` formatField s = mk OpusLoc+ | "para" `isPrefixOf` formatField s = mk ParaLoc+ | "part" `isPrefixOf` formatField s = mk PartLoc+ | "p" `isPrefixOf` formatField s = mk PageLoc+ | "sec" `isPrefixOf` formatField s = mk SecLoc+ | "sub" `isPrefixOf` formatField s = mk SubVerbLoc+ | "ve" `isPrefixOf` formatField s = mk VerseLoc+ | "v" `isPrefixOf` formatField s = mk VolLoc+-- | "p" `isPrefixOf` formatField s = mk PageFstLoc | otherwise = NoneLoc where mk c = if null s then NoneLoc else c . concat . tail . words $ s +-- | For each citation group generate the position and the citation+-- number of each citation. generatePosition :: [[(String,String)]] -> [[((String,String),(String,Int))]] generatePosition = getPos ([],[])
src/Text/CSL/Style.hs view
@@ -1,13 +1,12 @@ {-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable {-# LANGUAGE PatternGuards #-}--- {-# LANGUAGE #-} ----------------------------------------------------------------------------- -- | -- Module : Text.CSL.Style -- Copyright : (c) Andrea Rossato -- License : BSD-style (see LICENSE) ----- Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>+-- Maintainer : Andrea Rossato <andrea.rossato@unitn.it> -- Stability : unstable -- Portability : unportable --@@ -19,6 +18,7 @@ import Data.Generics +-- | The representation of a parsed CSL style. data Style = Style { styleClass :: String@@ -207,20 +207,29 @@ data CSAuthor = CSAuthor String String String deriving ( Show, Read, Eq, Typeable, Data ) data CSCategory = CSCategory String String String deriving ( Show, Read, Eq, Typeable, Data ) +-- | The formatted output, produced after post-processing the+-- evaluated citations. data FormattedOutput = FO String Formatting [FormattedOutput] | Delimiter String deriving ( Eq, Show ) +-- | The 'Output' generated by the evaluation of a style. Must be+-- further processed for disambiguation and collapsing. data Output- = FS String Formatting- | FN String [String] Formatting -- ^ A name and its given name if needed- | FY String String Formatting -- ^ The year and a suffix if needed- | O [Output] Formatting- | FC String [Output] [[Output]] -- ^ The contributor(s) with additional names- | S String+ = OStr String Formatting -- ^ A simple 'String'+ | OName String [String] Formatting -- ^ A (family) name with the list of given names.+ | OYear String String Formatting -- ^ The year and a suffix if needed+ | OCitNum Int Formatting -- ^ The citation number+ | Output [Output] Formatting -- ^ Some nested 'Output'+ | OContrib String [Output] [[Output]] -- ^ The citation key with the contributor(s), and everything+ -- used for disambiguation.+ | ODel String -- ^ A delimiter string. deriving ( Eq, Ord, Show, Typeable, Data ) +-- | A citation group: a list of evaluated citations, the 'Formatting'+-- to be applied to them, and the 'Delimiter' between individual+-- citations. data CitationGroup = CG Formatting String [Output] deriving ( Show, Eq, Typeable, Data ) data BiblioData@@ -229,54 +238,79 @@ , bibliography :: [[FormattedOutput]] } deriving ( Show ) +-- | A record with all the data to produce the 'FormattedOutput' of a+-- citation: the citation key, the part of the citation that may be+-- colliding with other citations (the list of contributors for the+-- same year), the data to disambiguate it (all possible contributors+-- and all possible given names), and the disambiguated citation and+-- its year. data CiteData = CD- { key :: String- , collision :: [Output]- , disData :: [[Output]]- , disambed :: [Output]- , citYear :: String+ { key :: String+ , collision :: [Output]+ , disambData :: [[Output]]+ , disambed :: [Output]+ , citYear :: String } deriving ( Show, Typeable, Data ) instance Eq CiteData where (==) (CD ka ca _ _ _) (CD kb cb _ _ _) = ka == kb && ca == cb +-- | Convert evaluated 'Output' into 'FormattedOutput', ready for the+-- output filters. formatOutput :: Output -> FormattedOutput formatOutput o- | S s <- o = Delimiter s- | FS s f <- o = FO s f []- | FN s _ f <- o = FO s f []- | FY s _ f <- o = FO s f []- | O os f <- o = FO "" f (format os)- | FC _ s _ <- o = FO "" emptyFormatting (format s)+ | ODel s <- o = Delimiter s+ | OStr s f <- o = FO s f []+ | OName s _ f <- o = FO s f []+ | OYear s _ f <- o = FO s f []+ | Output os f <- o = FO "" f (format os)+ | OContrib _ s _ <- o = FO "" emptyFormatting (format s)+ | OCitNum i f <- o = FO (show i) f [] | otherwise = FO "" emptyFormatting [] where format = map formatOutput +-- | Map the evaluated output of a citation group.+mapGroupOutput :: (Output -> [a]) -> CitationGroup -> [a]+mapGroupOutput f (CG _ _ os) = concatMap f os++-- | A generic processing function. proc :: (Typeable a, Data b) => (a -> a) -> b -> b proc f = everywhere (mkT f) +-- | A generic query function. query :: (Typeable a, Data b) => (a -> [c]) -> b -> [c] query f = everything (++) ([] `mkQ` f) +-- | Removes all given names form a 'OName' element with 'proc'. rmGivenNames :: Output -> Output rmGivenNames o- | FN s _ f <- o = FN s [] f+ | OName s _ f <- o = OName s [] f | otherwise = o +-- | Removes all contributors' names.+rmContribs :: Output -> Output+rmContribs o+ | OContrib s _ _ <- o = OContrib s [] []+ | otherwise = o++-- | Add, with 'proc', a give name to the family name. Needed for+-- disambiguation. addGivenNames :: [Output] -> [Output] addGivenNames = reverse . addGN True . reverse where addGN _ [] = [] addGN b (o:os)- | FN _ xs f <- o- , xs /= [] = if b then FN (head xs) (tail xs) f : addGN False os else o:os+ | OName _ xs f <- o+ , xs /= [] = if b then OName (head xs) (tail xs) f : addGN False os else o:os | otherwise = o : addGN b os +-- | Add the year suffix to the year. Needed for disambiguation. addYearSuffix :: Output -> Output addYearSuffix o- | FY y s f <- o = FY (y ++ s) s f- | otherwise = o+ | OYear y s f <- o = OYear (y ++ s) s f+ | otherwise = o
test/test.hs view
@@ -38,7 +38,7 @@ putStrLn . concatMap renderPlainStrict $ bibliography result when (modsCo config /= []) $ do- ref <- readModsColletionFile (modsCo config)+ ref <- readBiblioFile (modsCo config) "bibtex" let result = citeproc s ref [map (citeKey &&& const "") ref] case output config of "pandoc" -> do let concatPan = foldr (\x xs -> if xs /= [] then x ++ "," ++ xs else x ++ xs) []