[GRASS-SVN] r73081 - sandbox/wenzeslaus/g.citation

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 12 19:41:03 PDT 2018


Author: wenzeslaus
Date: 2018-08-12 19:41:03 -0700 (Sun, 12 Aug 2018)
New Revision: 73081

Modified:
   sandbox/wenzeslaus/g.citation/g.citation.html
   sandbox/wenzeslaus/g.citation/g.citation.py
Log:
g.citation: basic support for CSL

Modified: sandbox/wenzeslaus/g.citation/g.citation.html
===================================================================
--- sandbox/wenzeslaus/g.citation/g.citation.html	2018-08-12 03:07:23 UTC (rev 73080)
+++ sandbox/wenzeslaus/g.citation/g.citation.html	2018-08-13 02:41:03 UTC (rev 73081)
@@ -45,6 +45,10 @@
 g.citation f=pretty-json -a -s | grep '"name": ' | sort | uniq
 </pre></div>
 
+<div class="code"><pre>
+g.citation -s format=citeproc vsep="<p>" -a > all.html
+</pre></div>
+
 <h2>KNOWN ISSUES</h2>
 
 <ul>

Modified: sandbox/wenzeslaus/g.citation/g.citation.py
===================================================================
--- sandbox/wenzeslaus/g.citation/g.citation.py	2018-08-12 03:07:23 UTC (rev 73080)
+++ sandbox/wenzeslaus/g.citation/g.citation.py	2018-08-13 02:41:03 UTC (rev 73081)
@@ -36,12 +36,26 @@
 #% key: format
 #% type: string
 #% description: Citation format or style
-#% options: bibtex,cff,json,pretty-json,chicago-footnote,dict,plain
-#% descriptions: bibtex;BibTeX;cff;Citation File Format;json;JSON;pretty-json;Pretty printed JSON;chicago-footnote;Chicago style for footnotes;dict;Pretty printed Python dictionary;plain;Plain text
+#% options: bibtex,cff,json,pretty-json,csl-json,citeproc,chicago-footnote,dict,plain
+#% descriptions: bibtex;BibTeX;cff;Citation File Format;json;JSON;pretty-json;Pretty printed JSON;csl-json;Citation Style Language JSON (citeproc JSON) format;citeproc;Use the citeproc-py library to create the citation (CSL);chicago-footnote;Chicago style for footnotes;dict;Pretty printed Python dictionary;plain;Plain text
 #% answer: bibtex
 #% required: yes
 #%end
 
+#%option
+#% key: style
+#% type: string
+#% description: Citation style for the citeproc formatter (CSL)
+#% answer: harvard1
+#%end
+
+#%option
+#% key: vertical_separator
+#% type: string
+#% label: Separator of individual citation records
+#% description: Inserted before each item
+#%end
+
 #%option G_OPT_F_INPUT
 #% key: output
 #% type: string
@@ -291,6 +305,61 @@
         raise RuntimeError("The text does not contain source code URLs")
 
 
+def internal_to_csl_json(citation):
+    """Returns the JSON structure as objects (not as one string)"""
+    authors = []
+    for author in citation['authors']:
+        name = author_name_to_cff(author['name'])
+        authors.append({
+            'family': name['family'],
+            'given': name['given']
+            })
+    return {
+        'id': citation['module'],
+        'issued': {
+            'date-parts': [[citation['year'], "1", "1"]]
+        },
+        'title': "GRASS GIS: " + citation['module'] + " module",
+        'type': "software",
+        'author': authors,
+    }
+
+try:
+    # can't be inside the function
+    # (import * is not allowed in function)
+    # but needed to make citeproc give results
+    from citeproc.py2compat import *
+except ImportError:
+    pass
+
+
+def print_using_citeproc(csl_json, keys, style):
+    
+    from citeproc import CitationStylesStyle, CitationStylesBibliography
+    from citeproc import Citation, CitationItem
+    from citeproc import formatter
+    from citeproc.source.json import CiteProcJSON
+
+    def warn(citation_item):
+        raise RuntimeError("Reference with key '{}' not found"
+            .format(citation_item.key))
+
+    bib_source = CiteProcJSON([csl_json])
+    bib_style = CitationStylesStyle(style, validate=False)
+    bibliography = CitationStylesBibliography(bib_style, bib_source, formatter.html)
+    citations = []
+    # the following lines just do whatever example in citeproc repo does
+    for key in keys:
+        citation = Citation([CitationItem(key)])
+        bibliography.register(citation)
+        citations.append(citation)
+    for citation in citations:
+        #unused = bibliography.cite(citation, warn_missing_key)
+        unused = bibliography.cite(citation, warn)
+    for item in bibliography.bibliography():
+        print(str(item))
+
+
 # TODO: Jr. separated by comma
 def author_name_to_cff(text):
     """
@@ -489,6 +558,17 @@
                      sort_keys=True))
 
 
+def print_csl_json(citation):
+    """Create pretty-printed CSL JSON from the citation dictionary"""
+    csl = internal_to_csl_json(citation)
+    # the default separator for list items would leave space at the end
+    # of each line, so providing a custom one
+    # only small indent needed, so using 2
+    # sorting keys because only that can provide consistent output
+    print(json.dumps(csl, separators=(',', ': '), indent=2,
+                     sort_keys=True))
+
+
 def print_chicago_footnote(citation):
     num_authors = len(citation['authors'])
     authors_text = ""
@@ -535,6 +615,7 @@
     'cff': print_cff,
     'json': print_json,
     'pretty-json': print_pretty_json,
+    'csl-json': print_csl_json,
     'chicago-footnote': print_chicago_footnote,
     'plain': print_plain,
     'dict': lambda d: pprint(dict(d)),  # only plain dict pretty prints
@@ -544,6 +625,14 @@
 def print_citation(citation, format):
     """Create citation from dictionary in a given format"""
     # only catch the specific dict access, don't call the function
+
+    # funs with special handling of parameters first
+    # (alternatively all funs can have the most rich unified interface)
+    if format == 'citeproc':
+        print_using_citeproc(
+            internal_to_csl_json(citation),
+            [citation['module']], style='harvard1')
+        return
     try:
         function = _FORMAT_FUNCTION[format]
     except KeyError:
@@ -631,10 +720,18 @@
     if flags['a']:
         names = get_core_modules()
     output_format = options['format']
+    if output_format == 'citeproc':
+        if not options['style']:
+            gs.fatal(_("Option format=citeproc requires also"
+                       " the option style to be set"))
+    vertical_separator = options['vertical_separator']
 
     for name in names:
         try:
             citation = citation_for_module(name, add_grass=flags['d'])
+            if vertical_separator:
+                # TODO: decide if we want the newline here or not
+                print(vertical_separator)
             print_citation(citation, output_format)
         except RuntimeError as error:
             message = _("Module {name}: {error}".format(**locals()))



More information about the grass-commit mailing list