You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							117 lines
						
					
					
						
							3.7 KiB
						
					
					
				
			
		
		
	
	
							117 lines
						
					
					
						
							3.7 KiB
						
					
					
				#!/usr/bin/env python
 | 
						|
 | 
						|
# Copyright (c) 2006-2021  Andrey Golovizin
 | 
						|
#
 | 
						|
# Permission is hereby granted, free of charge, to any person obtaining
 | 
						|
# a copy of this software and associated documentation files (the
 | 
						|
# "Software"), to deal in the Software without restriction, including
 | 
						|
# without limitation the rights to use, copy, modify, merge, publish,
 | 
						|
# distribute, sublicense, and/or sell copies of the Software, and to
 | 
						|
# permit persons to whom the Software is furnished to do so, subject to
 | 
						|
# the following conditions:
 | 
						|
#
 | 
						|
# The above copyright notice and this permission notice shall be
 | 
						|
# included in all copies or substantial portions of the Software.
 | 
						|
#
 | 
						|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
						|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
						|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
						|
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
						|
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
						|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
						|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
from __future__ import print_function, unicode_literals, with_statement
 | 
						|
 | 
						|
import re
 | 
						|
import sys
 | 
						|
from os import path
 | 
						|
from shutil import rmtree
 | 
						|
from subprocess import PIPE, Popen
 | 
						|
from tempfile import mkdtemp
 | 
						|
 | 
						|
from pybtex.database import BibliographyData, Entry, Person
 | 
						|
from pybtex.database.output import bibtex
 | 
						|
from pybtex.errors import report_error
 | 
						|
from pybtex.exceptions import PybtexError
 | 
						|
 | 
						|
writer = bibtex.Writer(encoding='ascii')
 | 
						|
 | 
						|
 | 
						|
def write_aux(filename, citations):
 | 
						|
    with open(filename, 'w') as aux_file:
 | 
						|
        for citation in citations:
 | 
						|
            aux_file.write('\\citation{%s}\n' % citation)
 | 
						|
        aux_file.write('\\bibdata{test}\n')
 | 
						|
        aux_file.write('\\bibstyle{test}\n')
 | 
						|
 | 
						|
 | 
						|
def write_bib(filename, database):
 | 
						|
    writer.write_file(database, filename)
 | 
						|
 | 
						|
 | 
						|
def write_bst(filename, style):
 | 
						|
    with open(filename, 'w') as bst_file:
 | 
						|
        bst_file.write(style)
 | 
						|
        bst_file.write('\n')
 | 
						|
 | 
						|
 | 
						|
def run_bibtex(style, database, citations=None):
 | 
						|
    if citations is None:
 | 
						|
        citations = list(database.entries.keys())
 | 
						|
    tmpdir = mkdtemp(prefix='pybtex_test_')
 | 
						|
    try:
 | 
						|
        write_bib(path.join(tmpdir, 'test.bib'), database)
 | 
						|
        write_aux(path.join(tmpdir, 'test.aux'), citations)
 | 
						|
        write_bst(path.join(tmpdir, 'test.bst'), style)
 | 
						|
        bibtex = Popen(('bibtex', 'test'), cwd=tmpdir, stdout=PIPE, stderr=PIPE)
 | 
						|
        stdout, stderr = bibtex.communicate()
 | 
						|
        if bibtex.returncode:
 | 
						|
            report_error(PybtexError(stdout))
 | 
						|
        with open(path.join(tmpdir, 'test.bbl')) as bbl_file:
 | 
						|
            result = bbl_file.read()
 | 
						|
        return result
 | 
						|
    finally:
 | 
						|
        pass
 | 
						|
        rmtree(tmpdir)
 | 
						|
 | 
						|
 | 
						|
def execute(code, database=None):
 | 
						|
    if database is None:
 | 
						|
        database = BibliographyData(entries={'test_entry': Entry('article')})
 | 
						|
    bst = """
 | 
						|
        ENTRY {name format} {} {}
 | 
						|
        FUNCTION {article}
 | 
						|
        {
 | 
						|
            %s write$ newline$
 | 
						|
        }
 | 
						|
        READ
 | 
						|
        ITERATE {call.type$}
 | 
						|
    """.strip() % code
 | 
						|
    result = ' '.join(run_bibtex(bst, database).splitlines())
 | 
						|
    return result
 | 
						|
 | 
						|
 | 
						|
def format_name(name, format):
 | 
						|
    return execute('"%s" #1 "%s" format.name$' % (name, format))
 | 
						|
 | 
						|
 | 
						|
def parse_name(name):
 | 
						|
    space = re.compile(r'[\s~]+')
 | 
						|
    formatted_name = format_name(name, '{ff}|{vv}|{ll}|{jj}')
 | 
						|
    parts = [space.sub(' ', part.strip()) for part in formatted_name.split('|')]
 | 
						|
    first, von, last, junior = parts
 | 
						|
    return Person(first=first, prelast=von, last=last, lineage=junior)
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    args = sys.argv[1:2]
 | 
						|
    if len(args) != 1:
 | 
						|
        print("usage: run_bibtex 'some bibtex code'")
 | 
						|
        sys.exit(1)
 | 
						|
    code = args[0]
 | 
						|
    print(execute(code))
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 | 
						|
 |