#! /usr/bin/env python
# -*- coding: utf-8; -*-
#
# bin/bibgen — Bibliography generator for XML documents
#
# Copyright © 2014–2015 Émilien Tlapale
# Licensed under the Simplified BSD License

from __future__ import print_function

import argparse
import codecs
import os.path
import sys
import xml.dom.minidom

import bibgen

description = 'Bibliography generator for XML documents'

if __name__ == '__main__':
    # Command line arguments
    ap = argparse.ArgumentParser(description=description)
    ap.add_argument('document', metavar='DOC', nargs=1,
                    help='input DocBook document')
    ap.add_argument('biblio', metavar='BIBLIO', nargs='?', default=None,
                    help='bibliography database')
    ap.add_argument('-d', '--docbook', dest='doc_type',
                    action='store_const', const='docbook', default=None,
                    help='DocBook document')
    ap.add_argument('-e', '--encoding', dest='db_encoding',
                    default='utf-8',
                    help='encoding of the bibliography database')
    ap.add_argument('-j', '--json', dest='db_type', action='store_const',
                    const='json', default='bibtex',
                    help='JSON bibliography database')
    ap.add_argument('-m', '--mendeley', dest='db_type', action='store_const',
                    const='mendeley', default='bibtex',
                    help='Mendeley bibliography database')
    ap.add_argument('-n', '--no-sort', dest='sort_order', action='store_const',
                    const='nosort', default='alpha',
                    help='do not sort the entries')
    ap.add_argument('-o', '--output', default=None,
                    help='generated DocBook bibliography')
    ap.add_argument('-p', '--link-prefix', dest='link_prefix', default='bib-',
                    help='prefix for bibliography links')
    ap.add_argument('-r', '--restructuredtext', dest='doc_type',
                    action='store_const', const='rst', default=None,
                    help='reStructuredText document')
    ap.add_argument('-s', '--style', metavar='STYLE.CSL', default='harvard1',
                    help='path or name of citation style')
    ap.add_argument('-t', '--citation-separator', dest='cit_sep', default=';',
                    help='citation separator for multi-citing')
    args = ap.parse_args()

    # Search for the database
    doc_path = args.document[0]
    if args.biblio is None:
        args.biblio = bibgen.default_database(args.db_type, doc_path)

    # Try to infer document type
    if not os.path.exists(doc_path):
        exit('error: cannot find input document')
    doc_base,doc_ext = os.path.splitext(doc_path)
    dom = None
    if args.doc_type is None:
        suff = doc_ext
        if suff == '.rst':
            args.doc_type = 'rst'
        elif suff == '.dbk':
            args.doc_type = 'docbook'
        elif suff == '.xml':
            import bibgen.xml
            dom = xml.dom.minidom.parse(doc_path)
            if dom.documentElement.namespaceURI == bibgen.xml.docbook_ns:
                args.doc_type = 'docbook'
            else:
                exit('error: unknown XML document type')
        else:
            exit('error: cannot infer document type')

    # Check if a biblio db is required
    if args.biblio is None and args.doc_type != 'rst':
        exit('error: could not find a bibliography database')

    # Open the database
    biblio = None
    if args.biblio:
        biblio = bibgen.open_bibliography(args.db_type, args.biblio,
                                          args.db_encoding, args.style,
                                          formatter_name=args.doc_type)
    
    # Open the output stream
    if args.output is None:
        out = sys.stdout
    else:
        out = codecs.open(args.output, 'w', 'utf-8')

    # Process a reStructuredText document
    if args.doc_type == 'rst':
        import bibgen.rst
        bibgen.rst.register()
        txt = bibgen.rst.process_file(open(doc_path).read(), biblio,
                                      source_path=doc_path,
                                      writer_name='html')
        out.write(txt.decode('utf-8'))
    # Process a DocBook document
    elif args.doc_type == 'docbook':
        import bibgen.xml
        if dom is None:
            dom = xml.dom.minidom.parse(args.document[0])
        # Render citations and fill the bibliography
        bibgen.xml.process_dom(dom, biblio,
                               args.cit_sep, args.sort_order,
                               link_format=lambda key: args.link_prefix+key.lower())

        # Write the result
        dom.writexml(out)

# Local Variables:
# mode: python
# End:
