pax_global_header00006660000000000000000000000064125574721470014530gustar00rootroot0000000000000052 comment=ea55e59e484a43caa3d47ff10233d6181479f53a python-bibtexparser-0.6.1/000077500000000000000000000000001255747214700155455ustar00rootroot00000000000000python-bibtexparser-0.6.1/.coveragerc000066400000000000000000000001001255747214700176550ustar00rootroot00000000000000[run] source = bibtexparser [report] omit = bibtexparser/test* python-bibtexparser-0.6.1/.gitignore000066400000000000000000000005001255747214700175300ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info dist build eggs parts bin var sdist develop-eggs .installed.cfg lib lib64 # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # Pycharm .idea python-bibtexparser-0.6.1/.travis.yml000066400000000000000000000012321255747214700176540ustar00rootroot00000000000000language: python matrix: include: - python: "2.7" env: TEST_SUITE=suite_2_7 - python: "3.2" env: TEST_SUITE=suite_3_2 - python: "3.3" env: TEST_SUITE=suite_3_3 - python: "3.4" env: TEST_SUITE=suite_3_4 - python: "pypy" env: TEST_SUITE=suite_pypy install: - if [[ $TEST_SUITE == suite_3_4 ]]; then pip install sphinx; fi; - pip install coverage - python setup.py install script: - nosetests --with-coverage --cover-erase --cover-package=bibtexparser - if [[ $TEST_SUITE == suite_3_4 ]]; then cd docs; make html; fi; after_success: - pip install coveralls - coveralls python-bibtexparser-0.6.1/CHANGELOG000066400000000000000000000037651255747214700167720ustar00rootroot00000000000000vXXXX ===== * API: Previous type and id keywords which are automatically added to the dictionnary are now ENTRYTYPE and ID, respectively (#42). * ENH: comma first syntax support (#49) by Michal Grochmal. v0.6.0 ====== * DOC: clarify version number * ENH: support for bibtex with leading spaces (#34) * FIX: if title contained multiples words in braces * ENH: code refactoring (#33) * ENH: support for comment blocks (#32) * ENH: Removed comma after last key-value pair by faph (#28) * ENH: optional keys sanitising by faph (#29) * FIX: missing coma at the end of a record (#24) * DOC: clarify the usecase of to_bibtex * FIX: raise exception for TypeError in to_bibtex (#22) v0.5.5 ====== * ENH: json output * ENH: Add (optional) support for non-standard entry types by Georg C. Brückmann * FIX: protect uppercase only on unprotected characters. #18 * ENH: string replacement by Uwe Schmidt (#13 #20) v0.5.4 ====== * ENH: json output * API: enhance the naming choice for bwriter v0.5.3 ====== * ENH: add writer (#16), thanks to Lucas Verney * MAINT: Remove non-standard --BREAK-- command detection * FIX: missing strip() (#14) by Sebastien Diemer * API breakage: the parser takes data instead of a filehandler v0.5.2 ====== * ENH: fix tests latex encoding * ENH: support @comment @preambule (escaped) * ENH: check that bibtype belongs to a known type v0.5.1 ====== * ENH: split keywords with various separators * ENH: get_entry_dict make the dict once * ENH: add messages with logging * FIX: fix unittest related to braces detection v0.5 ==== * Permission from original authors and OKFN to use LGPLv3 * ENH: Python 2.7 support * FIX: issue related to accents v0.4 ==== * ENH: Transformations on characters are now considered as a customization * ENH: New customization: clean latex style * FIX: issue related to name processing v0.3 ==== * DOC: moved to readsthedoc * DOC: several improvements * MAINT: separate customizations v0.2 ==== * TEST: initialized * DOC: initialized v0.1 ==== * First preliminary release python-bibtexparser-0.6.1/CONTRIBUTORS.txt000066400000000000000000000010701255747214700202410ustar00rootroot00000000000000- François Boulogne Project coordinator - bibserver's contributors for the parser's core and the permission to release this project under LGPLv3 and BSD - Shuen-Huei (Drake) Guan Python 2.7 porting - Sebastien Diemer Bugfix - Georg C. Brückmann Support for non-standard entry types - Uwe Schmidt String replacement - faph coma fixes, optional keys sanitising, refactoring and other improvements - Steven M. Bellovin Fix braces detection - Sven Goossens Support for bibtex with leading spaces - Michal Grochmal Comma first syntax support python-bibtexparser-0.6.1/COPYING000066400000000000000000000220151255747214700166000ustar00rootroot00000000000000The code is distributed under a dual license (at your choice). ##################################################################### Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3)The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##################################################################### GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. python-bibtexparser-0.6.1/MANIFEST.in000066400000000000000000000000151255747214700172770ustar00rootroot00000000000000include *.md python-bibtexparser-0.6.1/README.md000066400000000000000000000023771255747214700170350ustar00rootroot00000000000000[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=fboulogne&url=https://github.com/sciunto/python-bibtexparser&title=python-bibtexparser&language=&tags=github&category=software) [![Build Status](https://secure.travis-ci.org/sciunto-org/python-bibtexparser.png)](http://travis-ci.org/sciunto-org/python-bibtexparser) [![Coverage Status](https://coveralls.io/repos/sciunto-org/python-bibtexparser/badge.png)](https://coveralls.io/r/sciunto-org/python-bibtexparser) python-bibtexparser =================== Bibtex parser in Python 2.7 and 3. The original source code was part of bibserver from okfn http://github.com/okfn/bibserver This project is released under the AGPLv3. Okfn and the original authors kindly provided the permission to use a subpart of their project (ie the bibtex parser) under LGPLv3. Many thanks to them! The aim of this project is to provide a standalone library in python. Documentation ============= Documentation including installation procedure and archives. https://bibtexparser.readthedocs.org/ Upgrading ========= Please, read the changelog before upgrading for API modifications. License ======= Dual license (at your choice): * LGPLv3. * BSD See COPYING for details. python-bibtexparser-0.6.1/README.rst000066400000000000000000000022331255747214700172340ustar00rootroot00000000000000.. image:: http://api.flattr.com/button/flattr-badge-large.png :target: https://flattr.com/submit/auto?user_id=fboulogne&url=https://github.com/sciunto/python-bibtexparser&title=python-bibtexparser&language=&tags=github&category=software :alt: Flattr this git repo .. image:: https://secure.travis-ci.org/sciunto/python-bibtexparser.png :target: http://travis-ci.org/sciunto/python-bibtexparser :alt: Build Status python-bibtexparser =================== Bibtex parser in Python 2.7 and 3. The original source code was part of bibserver from okfn http://github.com/okfn/bibserver This project is released under the AGPLv3. Okfn and the original authors kindly provided the permission to use a subpart of their project (ie the bibtex parser) under LGPLv3. Many thanks to them! The aim of this project is to provide a standalone library in python. Documentation ============= Documentation including installation procedure and archives. https://bibtexparser.readthedocs.org/ Upgrading ========= Please, read the changelog before upgrading for API modifications. License ======= Dual license (at your choice): * LGPLv3. * BSD See COPYING for details. python-bibtexparser-0.6.1/RELEASE000066400000000000000000000006021255747214700165460ustar00rootroot00000000000000How to release ============== * Update CHANGELOG * Update version in __init__.py * git tag -a 'vX' * merge in branch latest * Create a tarball and upload it on the server git archive master --prefix 'bibtexparser/' | bzip2 > bibtexparser-x.y.tar.bz2 * Send the package on pypi python setup.py sdist upload * tick the doc version on readthedocs * Update version in __init__.py python-bibtexparser-0.6.1/TODO000066400000000000000000000004251255747214700162360ustar00rootroot00000000000000JSON ==== * add unittests * Satisfy bibjson: http://www.bibjson.org/ Parser ====== * String replacement, some cases are implemented, but there is still todos. See #20. unittest ======== * getnames: missing cases DOC === * docstrings * doctests * add examples in docs/ python-bibtexparser-0.6.1/bibtexparser/000077500000000000000000000000001255747214700202375ustar00rootroot00000000000000python-bibtexparser-0.6.1/bibtexparser/__init__.py000066400000000000000000000053541255747214700223570ustar00rootroot00000000000000""" BibTeX is a bibliographic data file format. The :mod:`bibtexparser` module provides parsing and writing of BibTeX files functionality. The API is similar to the :mod:`json` module. The parsed data is returned as a simple :class:`BibDatabase` object with the main attribute being :attr:`entries` representing bibliographic sources such as books and journal articles. Parsing is a simple as:: >>>> import bibtexparser >>>> with open('bibtex.bib') as bibtex_file: >>>> bibtex_database = bibtexparser.load(bibtex_file) And writing:: >>>> import bibtexparser >>>> with open('bibtex.bib', 'w') as bibtex_file: >>>> bibtexparser.dump(bibtex_database, bibtex_file) """ __all__ = [ 'loads', 'load', 'dumps', 'dump', 'bibdatabase', 'bparser', 'bwriter', 'latexenc', 'customization', ] __version__ = '0.6.1' from . import bibdatabase, bparser, bwriter, latexenc, customization def loads(bibtex_str, parser=None): """ Load :class:`BibDatabase` object from a string :param bibtex_str: input BibTeX string to be parsed :type bibtex_str: str or unicode :param parser: custom parser to use (optional) :type parser: BibTexParser :return: bibliographic database object :rtype: BibDatabase """ if parser is None: parser = bparser.BibTexParser() return parser.parse(bibtex_str) def load(bibtex_file, parser=None): """ Load :class:`BibDatabase` object from a file :param bibtex_file: input file to be parsed :type bibtex_file: file :param parser: custom parser to use (optional) :type parser: BibTexParser :return: bibliographic database object :rtype: BibDatabase """ if parser is None: parser = bparser.BibTexParser() return parser.parse_file(bibtex_file) def dumps(bib_database, writer=None): """ Dump :class:`BibDatabase` object to a BibTeX string :param bib_database: bibliographic database object :type bib_database: BibDatabase :param writer: custom writer to use (optional) (not yet implemented) :type writer: BibTexWriter :return: BibTeX string :rtype: unicode """ if writer is None: writer = bwriter.BibTexWriter() return writer.write(bib_database) def dump(bib_database, bibtex_file, writer=None): """ Save :class:`BibDatabase` object as a BibTeX text file :param bib_database: bibliographic database object :type bib_database: BibDatabase :param bibtex_file: file to write to :type bibtex_file: file :param writer: custom writer to use (optional) (not yet implemented) :type writer: BibTexWriter """ if writer is None: writer = bwriter.BibTexWriter() bibtex_file.write(writer.write(bib_database)) python-bibtexparser-0.6.1/bibtexparser/bibdatabase.py000066400000000000000000000037341255747214700230410ustar00rootroot00000000000000from collections import OrderedDict import sys if sys.version_info.major == 2: TEXT_TYPE = unicode else: TEXT_TYPE = str class BibDatabase(object): """ A bibliographic database object following the data structure of a BibTeX file. """ def __init__(self): #: List of BibTeX entries, for example `@book{...}`, `@article{...}`, etc. Each entry is a simple dict with #: BibTeX field-value pairs, for example `'author': 'Bird, R.B. and Armstrong, R.C. and Hassager, O.'` Each #: entry will always have the following dict keys (in addition to other BibTeX fields): #: - `ID` (BibTeX key) #: - `ENTRYTYPE` (entry type in lowercase, e.g. `book`, `article` etc.) self.entries = [] self._entries_dict = {} #: List of BibTeX comment (`@comment{...}`) blocks. self.comments = [] #: OrderedDict of BibTeX string definitions (`@string{...}`). In order of definition. self.strings = OrderedDict() # Not sure if order is import, keep order just in case #: List of BibTeX preamble (`@preamble{...}`) blocks. self.preambles = [] def get_entry_list(self): """Get a list of bibtex entries. :returns: BibTeX entries :rtype: list .. deprecated:: 0.5.6 Use :attr:`entries` instead. """ return self.entries @staticmethod def entry_sort_key(entry, fields): result = [] for field in fields: result.append(TEXT_TYPE(entry.get(field, '')).lower()) # Sorting always as string return tuple(result) def get_entry_dict(self): """Return a dictionary of BibTeX entries. The dict key is the BibTeX entry key """ # If the hash has never been made, make it if not self._entries_dict: for entry in self.entries: self._entries_dict[entry['ID']] = entry return self._entries_dict entries_dict = property(get_entry_dict) python-bibtexparser-0.6.1/bibtexparser/bparser.py000066400000000000000000000374501255747214700222600ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # Original source: github.com/okfn/bibserver # Authors: # markmacgillivray # Etienne Posthumus (epoz) # Francois Boulogne import sys import logging import io import re from .bibdatabase import BibDatabase logger = logging.getLogger(__name__) __all__ = ['BibTexParser'] if sys.version_info >= (3, 0): from io import StringIO ustr = str else: from StringIO import StringIO ustr = unicode class BibTexParser(object): """ A parser for reading BibTeX bibliographic data files. Example:: from bibtexparser.bparser import BibTexParser bibtex_str = ... parser = BibTexParser() parser.ignore_nonstandard_types = False parser.homogenise_fields = False bib_database = bibtexparser.loads(bibtex_str, parser) """ def __new__(cls, data=None, customization=None, ignore_nonstandard_types=True, homogenise_fields=True): """ To catch the old API structure in which creating the parser would immediately parse and return data. """ if data is None: return super(BibTexParser, cls).__new__(cls) else: # For backwards compatibility: if data is given, parse and return the `BibDatabase` object instead of the # parser. parser = BibTexParser() parser.customization = customization parser.ignore_nonstandard_types = ignore_nonstandard_types parser.homogenise_fields = homogenise_fields return parser.parse(data) def __init__(self): """ Creates a parser for rading BibTeX files :return: parser :rtype: `BibTexParser` """ self.bib_database = BibDatabase() #: Callback function to process BibTeX entries after parsing, for example to create a list from a string with #: multiple values. By default all BibTeX values are treated as simple strings. Default: `None`. self.customization = None #: Ignore non-standard BibTeX types (`book`, `article`, etc). Default: `True`. self.ignore_nonstandard_types = True #: Sanitise BibTeX field names, for example change `url` to `link` etc. Field names are always converted to #: lowercase names. Default: `True`. self.homogenise_fields = True # On some sample data files, the character encoding detection simply # hangs We are going to default to utf8, and mandate it. self.encoding = 'utf8' # pre-defined set of key changes self.alt_dict = { 'keyw': 'keyword', 'keywords': 'keyword', 'authors': 'author', 'editors': 'editor', 'url': 'link', 'urls': 'link', 'links': 'link', 'subjects': 'subject' } self.replace_all_re = re.compile(r'((?P
"?)\s*(#|^)\s*(?P[^\d\W]\w*)\s*(#|$)\s*(?P"?))', re.UNICODE)

    def _bibtex_file_obj(self, bibtex_str):
        # Some files have Byte-order marks inserted at the start
        byte = '\xef\xbb\xbf'
        if not isinstance(byte, ustr):
            byte = ustr('\xef\xbb\xbf', self.encoding, 'ignore')
        if bibtex_str[:3] == byte:
            bibtex_str = bibtex_str[3:]
        return StringIO(bibtex_str)

    def parse(self, bibtex_str):
        """Parse a BibTeX string into an object

        :param bibtex_str: BibTeX string
        :type: str or unicode
        :return: bibliographic database
        :rtype: BibDatabase
        """
        self.bibtex_file_obj = self._bibtex_file_obj(bibtex_str)
        self._parse_records(customization=self.customization)
        return self.bib_database

    def parse_file(self, file):
        """Parse a BibTeX file into an object

        :param file: BibTeX file or file-like object
        :type: file
        :return: bibliographic database
        :rtype: BibDatabase
        """
        return self.parse(file.read())

    def _parse_records(self, customization=None):
        """Parse the bibtex into a list of records.

        :param customization: a function
        """
        def _add_parsed_record(record, records):
            """
            Atomic function to parse a record
            and append the result in records
            """
            if record != "":
                logger.debug('The record is not empty. Let\'s parse it.')
                parsed = self._parse_record(record, customization=customization)
                if parsed:
                    logger.debug('Store the result of the parsed record')
                    records.append(parsed)
                else:
                    logger.debug('Nothing returned from the parsed record!')
            else:
                logger.debug('The record is empty')

        records = []
        record = ""
        # read each line, bundle them up until they form an object, then send for parsing
        for linenumber, line in enumerate(self.bibtex_file_obj):
            logger.debug('Inspect line %s', linenumber)
            if line.strip().startswith('@'):
                # Remove leading whitespaces
                line = line.lstrip()
                logger.debug('Line starts with @')
                # Parse previous record
                _add_parsed_record(record, records)
                # Start new record
                logger.debug('The record is set to empty')
                record = ""
            # Keep adding lines to the record
            record += line

        # catch any remaining record and send it for parsing
        _add_parsed_record(record, records)
        logger.debug('Set the list of entries')
        self.bib_database.entries = records

    def _parse_record(self, record, customization=None):
        """Parse a record.

        * tidy whitespace and other rubbish
        * parse out the bibtype and citekey
        * find all the key-value pairs it contains

        :param record: a record
        :param customization: a function

        :returns: dict --
        """
        d = {}

        if not record.startswith('@'):
            logger.debug('The record does not start with @. Return empty dict.')
            return {}

        # if a comment record, add to bib_database.comments
        if record.lower().startswith('@comment'):
            logger.debug('The record startswith @comment')
            logger.debug('Store comment in list of comments')

            self.bib_database.comments.append(re.search('\{(.*)\}', record, re.DOTALL).group(1))

            logger.debug('Return an empty dict')
            return {}

        # if a preamble record, add to bib_database.preambles
        if record.lower().startswith('@preamble'):
            logger.debug('The record startswith @preamble')
            logger.debug('Store preamble in list of preambles')

            self.bib_database.preambles.append(re.search('\{(.*)\}', record, re.DOTALL).group(1))

            logger.debug('Return an empty dict')
            return {}

        # prepare record
        record = '\n'.join([i.strip() for i in record.split('\n')])
        if '}\n' in record:
            logger.debug('}\\n detected in the record. Clean up.')
            record = record.replace('\r\n', '\n').replace('\r', '\n').rstrip('\n')
            # treat the case for which the last line of the record
            # does not have a coma
            if record.endswith('}\n}') or record.endswith('}}'):
                logger.debug('Missing coma in the last line of the record. Fix it.')
                record = re.sub('}(\n|)}$', '},\n}', record)

        # if a string record, put it in the replace_dict
        if record.lower().startswith('@string'):
            logger.debug('The record startswith @string')
            key, val = [i.strip().strip('{').strip('}').replace('\n', ' ') for i in record.split('{', 1)[1].strip('\n').strip(',').strip('}').split('=')]
            key = key.lower()  # key is case insensitive
            val = self._string_subst_partial(val)
            if val.startswith('"') or val.lower() not in self.bib_database.strings:
                self.bib_database.strings[key] = val.strip('"')
            else:
                self.bib_database.strings[key] = self.bib_database.strings[val.lower()]
            logger.debug('Return a dict')
            return d

        # for each line in record
        logger.debug('Split the record of its lines and treat them')
        kvs = [i.strip() for i in re.split(',\s*\n|\n\s*,', record)]
        inkey = ""
        inval = ""
        for kv in kvs:
            logger.debug('Inspect: %s', kv)
            # TODO: We may check that the keyword belongs to a known type
            if kv.startswith('@') and not inkey:
                # it is the start of the record - set the bibtype and citekey (id)
                logger.debug('Line starts with @ and the key is not stored yet.')
                bibtype, id = kv.split('{', 1)
                bibtype = self._add_key(bibtype)
                id = id.lstrip().strip('}').strip(',')
                logger.debug('bibtype = %s', bibtype)
                logger.debug('id = %s', id)
                if self.ignore_nonstandard_types and bibtype not in ('article',
                                                                     'book',
                                                                     'booklet',
                                                                     'conference',
                                                                     'inbook',
                                                                     'incollection',
                                                                     'inproceedings',
                                                                     'manual',
                                                                     'mastersthesis',
                                                                     'misc',
                                                                     'phdthesis',
                                                                     'proceedings',
                                                                     'techreport',
                                                                     'unpublished'):
                    logger.warning('Entry type %s not standard. Not considered.', bibtype)
                    break
            elif '=' in kv and not inkey:
                # it is a line with a key value pair on it
                logger.debug('Line contains a key-pair value and the key is not stored yet.')
                key, val = [i.strip() for i in kv.split('=', 1)]
                key = self._add_key(key)
                val = self._string_subst_partial(val)
                # if it looks like the value spans lines, store details for next loop
                if (val.count('{') != val.count('}')) or (val.startswith('"') and not val.replace('}', '').endswith('"')):
                    logger.debug('The line is not ending the record.')
                    inkey = key
                    inval = val
                else:
                    logger.debug('The line is the end of the record.')
                    d[key] = self._add_val(val)
            elif inkey:
                logger.debug('Continues the previous line to complete the key pair value...')
                # if this line continues the value from a previous line, append
                inval += ', ' + kv
                # if it looks like this line finishes the value, store it and clear for next loop
                if (inval.startswith('{') and inval.endswith('}')) or (inval.startswith('"') and inval.endswith('"')):
                    logger.debug('This line represents the end of the current key-pair value')
                    d[inkey] = self._add_val(inval)
                    inkey = ""
                    inval = ""
                else:
                    logger.debug('This line does NOT represent the end of the current key-pair value')

        logger.debug('All lines have been treated')
        if not d:
            logger.debug('The dict is empty, return it.')
            return d

        d['ENTRYTYPE'] = bibtype
        d['ID'] = id

        if customization is None:
            logger.debug('No customization to apply, return dict')
            return d
        else:
            # apply any customizations to the record object then return it
            logger.debug('Apply customizations and return dict')
            return customization(d)

    def _strip_quotes(self, val):
        """Strip double quotes enclosing string

        :param val: a value
        :type val: string
        :returns: string -- value
        """
        logger.debug('Strip quotes')
        val = val.strip()
        if val.startswith('"') and val.endswith('"'):
            return val[1:-1]
        return val

    def _strip_braces(self, val):
        """Strip braces enclosing string

        :param val: a value
        :type val: string
        :returns: string -- value
        """
        logger.debug('Strip braces')
        val = val.strip()
        if val.startswith('{') and val.endswith('}') and self._full_span(val):
            return val[1:-1]
        return val

    def _full_span(self, val):
        cnt = 0
        for i in range(0, len(val)):
                if val[i] == '{':
                        cnt += 1
                elif val[i] == '}':
                        cnt -= 1
                if cnt == 0:
                        break
        if i == len(val) - 1:
                return True
        else:
                return False

    def _string_subst(self, val):
        """ Substitute string definitions

        :param val: a value
        :type val: string
        :returns: string -- value
        """
        logger.debug('Substitute string definitions')
        if not val:
            return ''
        for k in list(self.bib_database.strings.keys()):
            if val.lower() == k:
                val = self.bib_database.strings[k]
        if not isinstance(val, ustr):
            val = ustr(val, self.encoding, 'ignore')

        return val

    def _string_subst_partial(self, val):
        """ Substitute string definitions inside larger expressions

        :param val: a value
        :type val: string
        :returns: string -- value
        """
        def repl(m):
            k = m.group('id')
            replacement = self.bib_database.strings[k.lower()] if k.lower() in self.bib_database.strings else k
            pre = '"' if m.group('pre') != '"' else ''
            post = '"' if m.group('post') != '"' else ''
            return pre + replacement + post

        logger.debug('Substitute string definitions inside larger expressions')
        if '#' not in val:
            return val

        # TODO?: Does not match two subsequent variables or strings, such as  "start" # foo # bar # "end"  or  "start" # "end".
        # TODO:  Does not support braces instead of quotes, e.g.: {start} # foo # {bar}
        # TODO:  Does not support strings like: "te#s#t"
        return self.replace_all_re.sub(repl, val)

    def _add_val(self, val):
        """ Clean instring before adding to dictionary

        :param val: a value
        :type val: string
        :returns: string -- value
        """
        if not val or val == "{}":
            return ''
        val = self._strip_braces(val)
        val = self._strip_quotes(val)
        val = self._strip_braces(val)
        val = self._string_subst(val)
        return val

    def _add_key(self, key):
        """ Add a key and homogeneize alternative forms.

        :param key: a key
        :type key: string
        :returns: string -- value
        """
        key = key.strip().strip('@').lower()
        if self.homogenise_fields:
            if key in list(self.alt_dict.keys()):
                key = self.alt_dict[key]
        if not isinstance(key, ustr):
            return ustr(key, 'utf-8')
        else:
            return key
python-bibtexparser-0.6.1/bibtexparser/bwriter.py000066400000000000000000000103001255747214700222610ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Francois Boulogne
# License:

import logging
from .bibdatabase import BibDatabase

logger = logging.getLogger(__name__)

__all__ = ['BibTexWriter']


def to_bibtex(parsed):
    """
    Convenience function for backwards compatibility.
    """
    return BibTexWriter().write(parsed)


class BibTexWriter(object):
    """
    Writer to convert a :class:`BibDatabase` object to a string or file formatted as a BibTeX file.

    Example::

        from bibtexparser.bwriter import BibTexWriter

        bib_database = ...

        writer = BibTexWriter()
        writer.contents = ['comments', 'entries']
        writer.indent = '  '
        writer.order_entries_by = ('ENTRYTYPE', 'author', 'year')
        bibtex_str = bibtexparser.dumps(bib_database, writer)

    """

    _valid_contents = ['entries', 'comments', 'preambles', 'strings']

    def __init__(self):
        #: List of BibTeX elements to write, valid values are `entries`, `comments`, `preambles`, `strings`.
        self.contents = ['comments', 'preambles', 'strings', 'entries']
        #: Character(s) for indenting BibTeX field-value pairs. Default: single space.
        self.indent = ' '
        #: Characters(s) for separating BibTeX entries. Default: new line.
        self.entry_separator = '\n'
        #: Tuple of fields for ordering entries. Set to `None` to disable sorting. Default: BibTeX key `('ID', )`.
        self.order_entries_by = ('ID', )
        #: BibTeX syntax allows comma first syntax
        #: (common in functional languages), use this to enable
        #: comma first syntax as the bwritter output
        self.comma_first = False

    def write(self, bib_database):
        """
        Converts a bibliographic database to a BibTeX-formatted string.

        :param bib_database: bibliographic database to be converted to a BibTeX string
        :type bib_database: BibDatabase
        :return: BibTeX-formatted string
        :rtype: str or unicode
        """
        bibtex = ''
        for content in self.contents:
            try:
                # Add each element set (entries, comments)
                bibtex += getattr(self, '_' + content + '_to_bibtex')(bib_database)
            except AttributeError:
                logger.warning("BibTeX item '{}' does not exist and will not be written. Valid items are {}."
                               .format(content, self._valid_contents))
        return bibtex

    def _entries_to_bibtex(self, bib_database):
        bibtex = ''
        if self.order_entries_by:
            # TODO: allow sort field does not exist for entry
            entries = sorted(bib_database.entries, key=lambda x: BibDatabase.entry_sort_key(x, self.order_entries_by))
        else:
            entries = bib_database.entries

        for entry in entries:
            bibtex += self._entry_to_bibtex(entry)
        return bibtex

    def _entry_to_bibtex(self, entry):
        bibtex = ''
        # Write BibTeX key
        bibtex += '@' + entry['ENTRYTYPE'] + '{' + entry['ID']

        # Write field = value lines
        for field in [i for i in sorted(entry) if i not in ['ENTRYTYPE', 'ID']]:
            try:
                if self.comma_first:
                    bibtex += "\n," + self.indent + field + " = {" + entry[field] + "}"
                else:
                    bibtex += ",\n" + self.indent + field + " = {" + entry[field] + "}"
            except TypeError:
                raise TypeError("The field %s in entry %s must be a string"
                                % (field, entry['ID']))
        bibtex += "\n}\n" + self.entry_separator
        return bibtex

    def _comments_to_bibtex(self, bib_database):
        return ''.join(['@comment{{{0}}}\n{1}'.format(comment, self.entry_separator)
                        for comment in bib_database.comments])

    def _preambles_to_bibtex(self, bib_database):
        return ''.join(['@preamble{{{0}}}\n{1}'.format(preamble, self.entry_separator)
                        for preamble in bib_database.preambles])

    def _strings_to_bibtex(self, bib_database):
        return ''.join(['@string{{{0} = "{1}"}}\n{2}'.format(name, value, self.entry_separator)
                        for name, value in bib_database.strings.items()])
python-bibtexparser-0.6.1/bibtexparser/customization.py000066400000000000000000000163611255747214700235300ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
A set of functions useful for customizing bibtex fields.
You can find inspiration from these functions to design yours.
Each of them takes a record and return the modified record.
"""

import itertools
import re
import logging

from .latexenc import unicode_to_latex, unicode_to_crappy_latex1, unicode_to_crappy_latex2, string_to_latex, protect_uppercase

logger = logging.getLogger(__name__)

__all__ = ['getnames', 'author', 'editor', 'journal', 'keyword', 'link',
           'page_double_hyphen', 'doi', 'type', 'convert_to_unicode',
           'homogeneize_latex_encoding']


def getnames(names):
    """Make people names as surname, firstnames
    or surname, initials. Should eventually combine up the two.

    :param names: a list of names
    :type names: list
    :returns: list -- Correctly formated names
    """
    tidynames = []
    for namestring in names:
        namestring = namestring.strip()
        if len(namestring) < 1:
            continue
        if ',' in namestring:
            namesplit = namestring.split(',', 1)
            last = namesplit[0].strip()
            firsts = [i.strip() for i in namesplit[1].split()]
        else:
            namesplit = namestring.split()
            last = namesplit.pop()
            firsts = [i.replace('.', '. ').strip() for i in namesplit]
        if last in ['jnr', 'jr', 'junior']:
            last = firsts.pop()
        for item in firsts:
            if item in ['ben', 'van', 'der', 'de', 'la', 'le']:
                last = firsts.pop() + ' ' + last
        tidynames.append(last + ", " + ' '.join(firsts))
    return tidynames


def author(record):
    """
    Split author field into a list of "Name, Surname".

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "author" in record:
        if record["author"]:
            record["author"] = getnames([i.strip() for i in record["author"].replace('\n', ' ').split(" and ")])
        else:
            del record["author"]
    return record


def editor(record):
    """
    Turn the editor field into a dict composed of the original editor name
    and a editor id (without coma or blank).

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "editor" in record:
        if record["editor"]:
            record["editor"] = getnames([i.strip() for i in record["editor"].replace('\n', ' ').split(" and ")])
            # convert editor to object
            record["editor"] = [{"name": i, "ID": i.replace(',', '').replace(' ', '').replace('.', '')} for i in record["editor"]]
        else:
            del record["editor"]
    return record


def page_double_hyphen(record):
    """
    Separate pages by a double hyphen (--).

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "pages" in record:
        if "-" in record["pages"]:
            p = [i.strip().strip('-') for i in record["pages"].split("-")]
            record["pages"] = p[0] + '--' + p[-1]
    return record


def type(record):
    """
    Put the type into lower case.

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "type" in record:
        record["type"] = record["type"].lower()
    return record


def journal(record):
    """
    Turn the journal field into a dict composed of the original journal name
    and a journal id (without coma or blank).

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "journal" in record:
        # switch journal to object
        if record["journal"]:
            record["journal"] = {"name": record["journal"], "ID": record["journal"].replace(',', '').replace(' ', '').replace('.', '')}

    return record


def keyword(record, sep=',|;'):
    """
    Split keyword field into a list.

    :param record: the record.
    :type record: dict
    :param sep: pattern used for the splitting regexp.
    :type record: string, optional
    :returns: dict -- the modified record.

    """
    if "keyword" in record:
        record["keyword"] = [i.strip() for i in re.split(sep, record["keyword"].replace('\n', ''))]

    return record


def link(record):
    """

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if "link" in record:
        links = [i.strip().replace("  ", " ") for i in record["link"].split('\n')]
        record['link'] = []
        for link in links:
            parts = link.split(" ")
            linkobj = {"url": parts[0]}
            if len(parts) > 1:
                linkobj["anchor"] = parts[1]
            if len(parts) > 2:
                linkobj["format"] = parts[2]
            if len(linkobj["url"]) > 0:
                record["link"].append(linkobj)

    return record


def doi(record):
    """

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.

    """
    if 'doi' in record:
        if 'link' not in record:
            record['link'] = []
        nodoi = True
        for item in record['link']:
            if 'doi' in item:
                nodoi = False
        if nodoi:
            link = record['doi']
            if link.startswith('10'):
                link = 'http://dx.doi.org/' + link
            record['link'].append({"url": link, "anchor": "doi"})
    return record


def convert_to_unicode(record):
    """
    Convert accent from latex to unicode style.

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.
    """
    for val in record:
        if '\\' in record[val] or '{' in record[val]:
            for k, v in itertools.chain(unicode_to_crappy_latex1, unicode_to_latex):
                if v in record[val]:
                    record[val] = record[val].replace(v, k)

        # If there is still very crappy items
        if '\\' in record[val]:
            for k, v in unicode_to_crappy_latex2:
                if v in record[val]:
                    parts = record[val].split(str(v))
                    for key, record[val] in enumerate(parts):
                        if key+1 < len(parts) and len(parts[key+1]) > 0:
                            # Change order to display accents
                            parts[key] = parts[key] + parts[key+1][0]
                            parts[key+1] = parts[key+1][1:]
                    record[val] = k.join(parts)
    return record


def homogeneize_latex_encoding(record):
    """
    Homogeneize the latex enconding style for bibtex

    This function is experimental.

    :param record: the record.
    :type record: dict
    :returns: dict -- the modified record.
    """
    # First, we convert everything to unicode
    record = convert_to_unicode(record)
    # And then, we fall back
    for val in record:
        if val not in ('ID',):
            logger.debug('Apply string_to_latex to: %s', val)
            record[val] = string_to_latex(record[val])
            if val == 'title':
                logger.debug('Protect uppercase in title')
                logger.debug('Before: %s', record[val])
                record[val] = protect_uppercase(record[val])
                logger.debug('After: %s', record[val])
    return record
python-bibtexparser-0.6.1/bibtexparser/latexenc.py000066400000000000000000002736721255747214700224350ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Original source: github.com/okfn/bibserver
# Authors:
# markmacgillivray
# Etienne Posthumus (epoz)
# Francois Boulogne 

import re
import sys

__all__ = ['string_to_latex', 'protect_uppercase', 'unicode_to_latex',
           'unicode_to_crappy_latex1', 'unicode_to_crappy_latex2']


def string_to_latex(string):
    """
    Convert a string to its latex equivalent
    """
    escape = [' ', '{', '}']

    new = []
    for char in string:
        if char in escape:
            new.append(char)
        else:
            new.append(unicode_to_latex_map.get(char, char))
    return ''.join(new)


def protect_uppercase(string):
    """
    Protect uppercase letters for bibtex

    :param string: string to convert
    :returns: string
    """
    string = re.sub('([^{]|^)([A-Z])([^}]|$)', '\g<1>{\g<2>}\g<3>', string)
    return string


# list of latex conversions from
# https://gist.github.com/798549
# this list contrains crappy accents
# like \`{e} which is not advised for bibtex
# http://tex.stackexchange.com/questions/57743/how-to-write-a-and-other-umlauts-and-accented-letters-in-bibliography/57745#57745
# Correct accent are in unicode_to_latex
unicode_to_latex = []
unicode_to_latex_map = {}
unicode_to_crappy_latex1 = []
unicode_to_crappy_latex2 = []

def prepare_unicode_to_latex():
    global unicode_to_latex
    global unicode_to_latex_map
    global unicode_to_crappy_latex1
    global unicode_to_crappy_latex2

    to_crappy1 = (
        ("\u00C0", "\\`{A}"),
        ("\u00C1", "\\'{A}"),
        ("\u00C2", "\\^{A}"),
        ("\u00C3", "\\~{A}"),
        ("\u00C4", "\\\"{A}"),
        ("\u00C5", "\\AA "),
        ("\u00C6", "\\AE "),
        ("\u00C7", "\\c{C}"),
        ("\u00C8", "\\`{E}"),
        ("\u00C9", "\\'{E}"),
        ("\u00CA", "\\^{E}"),
        ("\u00CB", "\\\"{E}"),
        ("\u00CC", "\\`{I}"),
        ("\u00CD", "\\'{I}"),
        ("\u00CE", "\\^{I}"),
        ("\u00CF", "\\\"{I}"),
        ("\u00D0", "\\DH "),
        ("\u00D1", "\\~{N}"),
        ("\u00D2", "\\`{O}"),
        ("\u00D3", "\\'{O}"),
        ("\u00D4", "\\^{O}"),
        ("\u00D5", "\\~{O}"),
        ("\u00D6", "\\\"{O}"),
        ("\u00D7", "\\texttimes "),
        ("\u00D8", "\\O "),
        ("\u00D9", "\\`{U}"),
        ("\u00DA", "\\'{U}"),
        ("\u00DB", "\\^{U}"),
        ("\u00DC", "\\\"{U}"),
        ("\u00DD", "\\'{Y}"),
        ("\u00DE", "\\TH "),
        ("\u00DF", "\\ss "),
        ("\u00E0", "\\`{a}"),
        ("\u00E1", "\\'{a}"),
        ("\u00E2", "\\^{a}"),
        ("\u00E3", "\\~{a}"),
        ("\u00E4", "\\\"{a}"),
        ("\u00E5", "\\aa "),
        ("\u00E6", "\\ae "),
        ("\u00E7", "\\c{c}"),
        ("\u00E8", "\\`{e}"),
        ("\u00E9", "\\'{e}"),
        ("\u00EA", "\\^{e}"),
        ("\u00EB", "\\\"{e}"),
        ("\u00EC", "\\`{\\i}"),
        ("\u00ED", "\\'{\\i}"),
        ("\u00EE", "\\^{\\i}"),
        ("\u00EF", "\\\"{\\i}"),
        ("\u00F0", "\\dh "),
        ("\u00F1", "\\~{n}"),
        ("\u00F2", "\\`{o}"),
        ("\u00F3", "\\'{o}"),
        ("\u00F4", "\\^{o}"),
        ("\u00F5", "\\~{o}"),
        ("\u00F6", "\\\"{o}"),
        ("\u00F7", "\\div "),
        ("\u00F8", "\\o "),
        ("\u00F9", "\\`{u}"),
        ("\u00FA", "\\'{u}"),
        ("\u00FB", "\\^{u}"),
        ("\u00FC", "\\\"{u}"),
        ("\u00FD", "\\'{y}"),
        ("\u00FE", "\\th "),
        ("\u00FF", "\\\"{y}"),
        ("\u0100", "\\={A}"),
        ("\u0101", "\\={a}"),
        ("\u0102", "\\u{A}"),
        ("\u0103", "\\u{a}"),
        ("\u0104", "\\k{A}"),
        ("\u0105", "\\k{a}"),
        ("\u0106", "\\'{C}"),
        ("\u0107", "\\'{c}"),
        ("\u0108", "\\^{C}"),
        ("\u0109", "\\^{c}"),
        ("\u010A", "\\.{C}"),
        ("\u010B", "\\.{c}"),
        ("\u010C", "\\v{C}"),
        ("\u010D", "\\v{c}"),
        ("\u010E", "\\v{D}"),
        ("\u010F", "\\v{d}"),
        ("\u0110", "\\DJ "),
        ("\u0111", "\\dj "),
        ("\u0112", "\\={E}"),
        ("\u0113", "\\={e}"),
        ("\u0114", "\\u{E}"),
        ("\u0115", "\\u{e}"),
        ("\u0116", "\\.{E}"),
        ("\u0117", "\\.{e}"),
        ("\u0118", "\\k{E}"),
        ("\u0119", "\\k{e}"),
        ("\u011A", "\\v{E}"),
        ("\u011B", "\\v{e}"),
        ("\u011C", "\\^{G}"),
        ("\u011D", "\\^{g}"),
        ("\u011E", "\\u{G}"),
        ("\u011F", "\\u{g}"),
        ("\u0120", "\\.{G}"),
        ("\u0121", "\\.{g}"),
        ("\u0122", "\\c{G}"),
        ("\u0123", "\\c{g}"),
        ("\u0124", "\\^{H}"),
        ("\u0125", "\\^{h}"),
        ("\u0126", "{\\fontencoding{LELA}\\selectfont\\char40}"),
        ("\u0127", "\\Elzxh "),
        ("\u0128", "\\~{I}"),
        ("\u0129", "\\~{\\i}"),
        ("\u012A", "\\={I}"),
        ("\u012B", "\\={\\i}"),
        ("\u012C", "\\u{I}"),
        ("\u012D", "\\u{\\i}"),
        ("\u012E", "\\k{I}"),
        ("\u012F", "\\k{i}"),
        ("\u0130", "\\.{I}"),
        ("\u0131", "\\i "),
#        (u"\u0132", "IJ"),
#        (u"\u0133", "ij"),
        ("\u0134", "\\^{J}"),
        ("\u0135", "\\^{\\j}"),
        ("\u0136", "\\c{K}"),
        ("\u0137", "\\c{k}"),
        ("\u0138", "{\\fontencoding{LELA}\\selectfont\\char91}"),
        ("\u0139", "\\'{L}"),
        ("\u013A", "\\'{l}"),
        ("\u013B", "\\c{L}"),
        ("\u013C", "\\c{l}"),
        ("\u013D", "\\v{L}"),
        ("\u013E", "\\v{l}"),
        ("\u013F", "{\\fontencoding{LELA}\\selectfont\\char201}"),
        ("\u0140", "{\\fontencoding{LELA}\\selectfont\\char202}"),
        ("\u0141", "\\L "),
        ("\u0142", "\\l "),
        ("\u0143", "\\'{N}"),
        ("\u0144", "\\'{n}"),
        ("\u0145", "\\c{N}"),
        ("\u0146", "\\c{n}"),
        ("\u0147", "\\v{N}"),
        ("\u0148", "\\v{n}"),
        ("\u0149", "'n"),
        ("\u014A", "\\NG "),
        ("\u014B", "\\ng "),
        ("\u014C", "\\={O}"),
        ("\u014D", "\\={o}"),
        ("\u014E", "\\u{O}"),
        ("\u014F", "\\u{o}"),
        ("\u0150", "\\H{O}"),
        ("\u0151", "\\H{o}"),
        ("\u0152", "\\OE "),
        ("\u0153", "\\oe "),
        ("\u0154", "\\'{R}"),
        ("\u0155", "\\'{r}"),
        ("\u0156", "\\c{R}"),
        ("\u0157", "\\c{r}"),
        ("\u0158", "\\v{R}"),
        ("\u0159", "\\v{r}"),
        ("\u015A", "\\'{S}"),
        ("\u015B", "\\'{s}"),
        ("\u015C", "\\^{S}"),
        ("\u015D", "\\^{s}"),
        ("\u015E", "\\c{S}"),
        ("\u015F", "\\c{s}"),
        ("\u0160", "\\v{S}"),
        ("\u0161", "\\v{s}"),
        ("\u0162", "\\c{T}"),
        ("\u0163", "\\c{t}"),
        ("\u0164", "\\v{T}"),
        ("\u0165", "\\v{t}"),
        ("\u0166", "{\\fontencoding{LELA}\\selectfont\\char47}"),
        ("\u0167", "{\\fontencoding{LELA}\\selectfont\\char63}"),
        ("\u0168", "\\~{U}"),
        ("\u0169", "\\~{u}"),
        ("\u016A", "\\={U}"),
        ("\u016B", "\\={u}"),
        ("\u016C", "\\u{U}"),
        ("\u016D", "\\u{u}"),
        ("\u016E", "\\r{U}"),
        ("\u016F", "\\r{u}"),
        ("\u0170", "\\H{U}"),
        ("\u0171", "\\H{u}"),
        ("\u0172", "\\k{U}"),
        ("\u0173", "\\k{u}"),
        ("\u0174", "\\^{W}"),
        ("\u0175", "\\^{w}"),
        ("\u0176", "\\^{Y}"),
        ("\u0177", "\\^{y}"),
        ("\u0178", "\\\"{Y}"),
        ("\u0179", "\\'{Z}"),
        ("\u017A", "\\'{z}"),
        ("\u017B", "\\.{Z}"),
        ("\u017C", "\\.{z}"),
        ("\u017D", "\\v{Z}"),
        ("\u017E", "\\v{z}"),
        ("\u0195", "\\texthvlig "),
        ("\u019E", "\\textnrleg "),
        ("\u01AA", "\\eth "),
        ("\u01BA", "{\\fontencoding{LELA}\\selectfont\\char195}"),
        ("\u01C2", "\\textdoublepipe "),
        ("\u01F5", "\\'{g}"),
        ("\u0386", "\\'{A}"),
        ("\u0388", "\\'{E}"),
        ("\u0389", "\\'{H}"),
        ("\u03CC", "\\'{o}"),
    )

    # These are dangerous
    # should not be used on
    # {\'E} for instance!
    to_crappy2 = (
        ("\u0300", "\\`"),
        ("\u0301", "\\'"),
        ("\u0302", "\\^"),
        ("\u0327", "\\c"),
    )

    # list of latex conversions from
    # https://gist.github.com/798549
    # Corrected \`{e} -> {\`e}
    to_latex = (
        ("\u0020", "\\space "),
        ("\u0023", "\\#"),
        ("\u0024", "\\textdollar "),
        ("\u0025", "\\%"),
        ("\u0026", "\\&"),
        ("\u0027", "\\textquotesingle "),
        ("\u002A", "\\ast "),
        ("\u005C", "\\textbackslash "),
        ("\u005E", "\\^{}"),
        ("\u005F", "\\_"),
        ("\u0060", "\\textasciigrave "),
        ("\u007B", "\\lbrace "),
        ("\u007C", "\\vert "),
        ("\u007D", "\\rbrace "),
        ("\u007E", "\\textasciitilde "),
        ("\u00A1", "\\textexclamdown "),
        ("\u00A2", "\\textcent "),
        ("\u00A3", "\\textsterling "),
        ("\u00A4", "\\textcurrency "),
        ("\u00A5", "\\textyen "),
        ("\u00A6", "\\textbrokenbar "),
        ("\u00A7", "\\textsection "),
        ("\u00A8", "\\textasciidieresis "),
        ("\u00A9", "\\textcopyright "),
        ("\u00AA", "\\textordfeminine "),
        ("\u00AB", "\\guillemotleft "),
        ("\u00AC", "\\lnot "),
        ("\u00AD", "\\-"),
        ("\u00AE", "\\textregistered "),
        ("\u00AF", "\\textasciimacron "),
        ("\u00B0", "\\textdegree "),
        ("\u00B1", "\\pm "),
        ("\u00B2", "{^2}"),
        ("\u00B3", "{^3}"),
        ("\u00B4", "\\textasciiacute "),
        ("\u00B5", "\\mathrm{\\mu}"),
        ("\u00B6", "\\textparagraph "),
        ("\u00B7", "\\cdot "),
        ("\u00B8", "\\c{}"),
        ("\u00B9", "{^1}"),
        ("\u00BA", "\\textordmasculine "),
        ("\u00BB", "\\guillemotright "),
        ("\u00BC", "\\textonequarter "),
        ("\u00BD", "\\textonehalf "),
        ("\u00BE", "\\textthreequarters "),
        ("\u00BF", "\\textquestiondown "),
        ("\u00C0", "{\\`A}"),
        ("\u00C1", "{\\'A}"),
        ("\u00C2", "{\\^A}"),
        ("\u00C3", "{\\~A}"),
        ("\u00C4", "{\\\"A}"),
        ("\u00C5", "{\\AA}"),
        ("\u00C6", "{\\AE}"),
        ("\u00C7", "{\\c C}"),
        ("\u00C8", "{\\`E}"),
        ("\u00C9", "{\\'E}"),
        ("\u00CA", "{\\^E}"),
        ("\u00CB", "{\\\"E}"),
        ("\u00CC", "{\\`I}"),
        ("\u00CD", "{\\'I}"),
        ("\u00CE", "{\\^I}"),
        ("\u00CF", "{\\\"I}"),
        ("\u00D0", "{\\DH}"),
        ("\u00D1", "{\\~N}"),
        ("\u00D2", "{\\`O}"),
        ("\u00D3", "{\\'O}"),
        ("\u00D4", "{\\^O}"),
        ("\u00D5", "{\\~O}"),
        ("\u00D6", "{\\\"O}"),
        ("\u00D7", "\\texttimes "),
        ("\u00D8", "{\\O}"),
        ("\u00D9", "{\\`U}"),
        ("\u00DA", "{\\'U}"),
        ("\u00DB", "{\\^U}"),
        ("\u00DC", "{\\\"U}"),
        ("\u00DD", "{\\'Y}"),
        ("\u00DE", "{\\TH}"),
        ("\u00DF", "{\\ss}"),
        ("\u00E0", "{\\`a}"),
        ("\u00E1", "{\\'a}"),
        ("\u00E2", "{\\^a}"),
        ("\u00E3", "{\\~a}"),
        ("\u00E4", "{\\\"a}"),
        ("\u00E5", "{\\aa}"),
        ("\u00E6", "{\\ae}"),
        ("\u00E7", "{\\c c}"),
        ("\u00E8", "{\\`e}"),
        ("\u00E9", "{\\'e}"),
        ("\u00EA", "{\\^e}"),
        ("\u00EB", "{\\\"e}"),
        ("\u00EC", "{\\`\\i}"),
        ("\u00ED", "{\\'\\i}"),
        ("\u00EE", "{\\^\\i}"),
        ("\u00EF", "{\\\"\\i}"),
        ("\u00F0", "{\\dh }"),
        ("\u00F1", "{\\~n}"),
        ("\u00F2", "{\\`o}"),
        ("\u00F3", "{\\'o}"),
        ("\u00F4", "{\\^o}"),
        ("\u00F5", "{\\~o}"),
        ("\u00F6", "{\\\"o}"),
        ("\u00F7", "{\\div}"),
        ("\u00F8", "{\\o}"),
        ("\u00F9", "{\\`u}"),
        ("\u00FA", "{\\'u}"),
        ("\u00FB", "{\\^u}"),
        ("\u00FC", "{\\\"u}"),
        ("\u00FD", "{\\'y}"),
        ("\u00FE", "{\\th}"),
        ("\u00FF", "{\\\"y}"),
        ("\u0100", "{\\= A}"),
        ("\u0101", "{\\= a}"),
        ("\u0102", "{\\u A}"),
        ("\u0103", "{\\u a}"),
        ("\u0104", "{\\k A}"),
        ("\u0105", "{\\k a}"),
        ("\u0106", "{\\' C}"),
        ("\u0107", "{\\' c}"),
        ("\u0108", "{\\^ C}"),
        ("\u0109", "{\\^ c}"),
        ("\u010A", "{\\. C}"),
        ("\u010B", "{\\. c}"),
        ("\u010C", "{\\v C}"),
        ("\u010D", "{\\v c}"),
        ("\u010E", "{\\v D}"),
        ("\u010F", "{\\v d}"),
        ("\u0110", "{\\DJ}"),
        ("\u0111", "{\\dj}"),
        ("\u0112", "{\\= E}"),
        ("\u0113", "{\\= e}"),
        ("\u0114", "{\\u E}"),
        ("\u0115", "{\\u e}"),
        ("\u0116", "{\\.E}"),
        ("\u0117", "{\\.e}"),
        ("\u0118", "{\\k E}"),
        ("\u0119", "{\\k e}"),
        ("\u011A", "{\\v E}"),
        ("\u011B", "{\\v e}"),
        ("\u011C", "{\\^ G}"),
        ("\u011D", "{\\^ g}"),
        ("\u011E", "{\\u G}"),
        ("\u011F", "{\\u g}"),
        ("\u0120", "{\\. G}"),
        ("\u0121", "{\\. g}"),
        ("\u0122", "{\\c G}"),
        ("\u0123", "{\\c g}"),
        ("\u0124", "{\\^ H}"),
        ("\u0125", "{\\^ h}"),
        ("\u0126", "{\\fontencoding{LELA}\\selectfont\\char40}"),
        ("\u0127", "\\Elzxh "),
        ("\u0128", "{\\~ I}"),
        ("\u0129", "{\\~ \\i}"),
        ("\u012A", "{\\= I}"),
        ("\u012B", "{\\= \\i}"),
        ("\u012C", "{\\u I}"),
        ("\u012D", "{\\u \\i}"),
        ("\u012E", "{\\k I}"),
        ("\u012F", "{\\k i}"),
        ("\u0130", "{\\. I}"),
        ("\u0131", "{\\i}"),
#        (u"\u0132", "IJ"),
#        (u"\u0133", "ij"),
        ("\u0134", "{\\^J}"),
        ("\u0135", "{\\^\\j}"),
        ("\u0136", "{\\c K}"),
        ("\u0137", "{\\c k}"),
        ("\u0138", "{\\fontencoding{LELA}\\selectfont\\char91}"),
        ("\u0139", "{\\'L}"),
        ("\u013A", "{\\'l}"),
        ("\u013B", "{\\c L}"),
        ("\u013C", "{\\c l}"),
        ("\u013D", "{\\v L}"),
        ("\u013E", "{\\v l}"),
        ("\u013F", "{\\fontencoding{LELA}\\selectfont\\char201}"),
        ("\u0140", "{\\fontencoding{LELA}\\selectfont\\char202}"),
        ("\u0141", "{\\L}"),
        ("\u0142", "{\\l}"),
        ("\u0143", "{\\'N}"),
        ("\u0144", "{\\'n}"),
        ("\u0145", "{\\c N}"),
        ("\u0146", "{\\c n}"),
        ("\u0147", "{\\v N}"),
        ("\u0148", "{\\v n}"),
        ("\u0149", "'n"),
        ("\u014A", "{\\NG}"),
        ("\u014B", "{\\ng}"),
        ("\u014C", "{\\= O}"),
        ("\u014D", "{\\= o}"),
        ("\u014E", "{\\u O}"),
        ("\u014F", "{\\u o}"),
        ("\u0150", "{\\H O}"),
        ("\u0151", "{\\H o}"),
        ("\u0152", "{\\OE}"),
        ("\u0153", "{\\oe}"),
        ("\u0154", "{\\'R}"),
        ("\u0155", "{\\'r}"),
        ("\u0156", "{\\c R}"),
        ("\u0157", "{\\c r}"),
        ("\u0158", "{\\v R}"),
        ("\u0159", "{\\v r}"),
        ("\u015A", "{\\' S}"),
        ("\u015B", "{\\' s}"),
        ("\u015C", "{\\^ S}"),
        ("\u015D", "{\\^ s}"),
        ("\u015E", "{\\c S}"),
        ("\u015F", "{\\c s}"),
        ("\u0160", "{\\v S}"),
        ("\u0161", "{\\v s}"),
        ("\u0162", "{\\c T}"),
        ("\u0163", "{\\c t}"),
        ("\u0164", "{\\v T}"),
        ("\u0165", "{\\v t}"),
        ("\u0166", "{\\fontencoding{LELA}\\selectfont\\char47}"),
        ("\u0167", "{\\fontencoding{LELA}\\selectfont\\char63}"),
        ("\u0168", "{\\~ U}"),
        ("\u0169", "{\\~ u}"),
        ("\u016A", "{\\= U}"),
        ("\u016B", "{\\= u}"),
        ("\u016C", "{\\u U}"),
        ("\u016D", "{\\u u}"),
        ("\u016E", "{\\r U}"),
        ("\u016F", "{\\r u}"),
        ("\u0170", "{\\H U}"),
        ("\u0171", "{\\H u}"),
        ("\u0172", "{\\k U}"),
        ("\u0173", "{\\k u}"),
        ("\u0174", "{\\^ W}"),
        ("\u0175", "{\\^ w}"),
        ("\u0176", "{\\^ Y}"),
        ("\u0177", "{\\^ y}"),
        ("\u0178", "{\\\" Y}"),
        ("\u0179", "{\\' Z}"),
        ("\u017A", "{\\' z}"),
        ("\u017B", "{\\. Z}"),
        ("\u017C", "{\\. z}"),
        ("\u017D", "{\\v Z}"),
        ("\u017E", "{\\v z}"),
        ("\u0195", "{\\texthvlig}"),
        ("\u019E", "{\\textnrleg}"),
        ("\u01AA", "{\\eth}"),
        ("\u01BA", "{\\fontencoding{LELA}\\selectfont\\char195}"),
        ("\u01C2", "\\textdoublepipe "),
        ("\u01F5", "{\\' g}"),
        ("\u0250", "\\Elztrna "),
        ("\u0252", "\\Elztrnsa "),
        ("\u0254", "\\Elzopeno "),
        ("\u0256", "\\Elzrtld "),
        ("\u0258", "{\\fontencoding{LEIP}\\selectfont\\char61}"),
        ("\u0259", "\\Elzschwa "),
        ("\u025B", "\\varepsilon "),
        ("\u0263", "\\Elzpgamma "),
        ("\u0264", "\\Elzpbgam "),
        ("\u0265", "\\Elztrnh "),
        ("\u026C", "\\Elzbtdl "),
        ("\u026D", "\\Elzrtll "),
        ("\u026F", "\\Elztrnm "),
        ("\u0270", "\\Elztrnmlr "),
        ("\u0271", "\\Elzltlmr "),
        ("\u0272", "\\Elzltln "),
        ("\u0273", "\\Elzrtln "),
        ("\u0277", "\\Elzclomeg "),
        ("\u0278", "\\textphi "),
        ("\u0279", "\\Elztrnr "),
        ("\u027A", "\\Elztrnrl "),
        ("\u027B", "\\Elzrttrnr "),
        ("\u027C", "\\Elzrl "),
        ("\u027D", "\\Elzrtlr "),
        ("\u027E", "\\Elzfhr "),
        ("\u027F", "{\\fontencoding{LEIP}\\selectfont\\char202}"),
        ("\u0282", "\\Elzrtls "),
        ("\u0283", "\\Elzesh "),
        ("\u0287", "\\Elztrnt "),
        ("\u0288", "\\Elzrtlt "),
        ("\u028A", "\\Elzpupsil "),
        ("\u028B", "\\Elzpscrv "),
        ("\u028C", "\\Elzinvv "),
        ("\u028D", "\\Elzinvw "),
        ("\u028E", "\\Elztrny "),
        ("\u0290", "\\Elzrtlz "),
        ("\u0292", "\\Elzyogh "),
        ("\u0294", "\\Elzglst "),
        ("\u0295", "\\Elzreglst "),
        ("\u0296", "\\Elzinglst "),
        ("\u029E", "\\textturnk "),
        ("\u02A4", "\\Elzdyogh "),
        ("\u02A7", "\\Elztesh "),
        ("\u02C7", "\\textasciicaron "),
        ("\u02C8", "\\Elzverts "),
        ("\u02CC", "\\Elzverti "),
        ("\u02D0", "\\Elzlmrk "),
        ("\u02D1", "\\Elzhlmrk "),
        ("\u02D2", "\\Elzsbrhr "),
        ("\u02D3", "\\Elzsblhr "),
        ("\u02D4", "\\Elzrais "),
        ("\u02D5", "\\Elzlow "),
        ("\u02D8", "\\textasciibreve "),
        ("\u02D9", "\\textperiodcentered "),
        ("\u02DA", "\\r{}"),
        ("\u02DB", "\\k{}"),
        ("\u02DC", "\\texttildelow "),
        ("\u02DD", "\\H{}"),
        ("\u02E5", "\\tone{55}"),
        ("\u02E6", "\\tone{44}"),
        ("\u02E7", "\\tone{33}"),
        ("\u02E8", "\\tone{22}"),
        ("\u02E9", "\\tone{11}"),
        ("\u0303", "\\~"),
        ("\u0304", "\\="),
        ("\u0306", "\\u"),
        ("\u0307", "\\."),
        ("\u0308", "\\\""),
        ("\u030A", "\\r"),
        ("\u030B", "\\H"),
        ("\u030C", "\\v"),
        ("\u030F", "\\cyrchar\\C"),
        ("\u0311", "{\\fontencoding{LECO}\\selectfont\\char177}"),
        ("\u0318", "{\\fontencoding{LECO}\\selectfont\\char184}"),
        ("\u0319", "{\\fontencoding{LECO}\\selectfont\\char185}"),
        ("\u0321", "\\Elzpalh "),
        ("\u0322", "\\Elzrh "),
        ("\u0328", "\\k"),
        ("\u032A", "\\Elzsbbrg "),
        ("\u032B", "{\\fontencoding{LECO}\\selectfont\\char203}"),
        ("\u032F", "{\\fontencoding{LECO}\\selectfont\\char207}"),
        ("\u0335", "\\Elzxl "),
        ("\u0336", "\\Elzbar "),
        ("\u0337", "{\\fontencoding{LECO}\\selectfont\\char215}"),
        ("\u0338", "{\\fontencoding{LECO}\\selectfont\\char216}"),
        ("\u033A", "{\\fontencoding{LECO}\\selectfont\\char218}"),
        ("\u033B", "{\\fontencoding{LECO}\\selectfont\\char219}"),
        ("\u033C", "{\\fontencoding{LECO}\\selectfont\\char220}"),
        ("\u033D", "{\\fontencoding{LECO}\\selectfont\\char221}"),
        ("\u0361", "{\\fontencoding{LECO}\\selectfont\\char225}"),
        ("\u0386", "{\\' A}"),
        ("\u0388", "{\\' E}"),
        ("\u0389", "{\\' H}"),
        ("\u038A", "\\'{}{I}"),
        ("\u038C", "\\'{}O"),
        ("\u038E", "\\mathrm{'Y}"),
        ("\u038F", "\\mathrm{'\\Omega}"),
        ("\u0390", "\\acute{\\ddot{\\iota}}"),
        ("\u0391", "\\Alpha "),
        ("\u0392", "\\Beta "),
        ("\u0393", "\\Gamma "),
        ("\u0394", "\\Delta "),
        ("\u0395", "\\Epsilon "),
        ("\u0396", "\\Zeta "),
        ("\u0397", "\\Eta "),
        ("\u0398", "\\Theta "),
        ("\u0399", "\\Iota "),
        ("\u039A", "\\Kappa "),
        ("\u039B", "\\Lambda "),
        ("\u039E", "\\Xi "),
        ("\u03A0", "\\Pi "),
        ("\u03A1", "\\Rho "),
        ("\u03A3", "\\Sigma "),
        ("\u03A4", "\\Tau "),
        ("\u03A5", "\\Upsilon "),
        ("\u03A6", "\\Phi "),
        ("\u03A7", "\\Chi "),
        ("\u03A8", "\\Psi "),
        ("\u03A9", "\\Omega "),
        ("\u03AA", "\\mathrm{\\ddot{I}}"),
        ("\u03AB", "\\mathrm{\\ddot{Y}}"),
        ("\u03AC", "\\'{$\\alpha$}"),
        ("\u03AD", "\\acute{\\epsilon}"),
        ("\u03AE", "\\acute{\\eta}"),
        ("\u03AF", "\\acute{\\iota}"),
        ("\u03B0", "\\acute{\\ddot{\\upsilon}}"),
        ("\u03B1", "\\alpha "),
        ("\u03B2", "\\beta "),
        ("\u03B3", "\\gamma "),
        ("\u03B4", "\\delta "),
        ("\u03B5", "\\epsilon "),
        ("\u03B6", "\\zeta "),
        ("\u03B7", "\\eta "),
        ("\u03B8", "\\texttheta "),
        ("\u03B9", "\\iota "),
        ("\u03BA", "\\kappa "),
        ("\u03BB", "\\lambda "),
        ("\u03BC", "\\mu "),
        ("\u03BD", "\\nu "),
        ("\u03BE", "\\xi "),
        ("\u03C0", "\\pi "),
        ("\u03C1", "\\rho "),
        ("\u03C2", "\\varsigma "),
        ("\u03C3", "\\sigma "),
        ("\u03C4", "\\tau "),
        ("\u03C5", "\\upsilon "),
        ("\u03C6", "\\varphi "),
        ("\u03C7", "\\chi "),
        ("\u03C8", "\\psi "),
        ("\u03C9", "\\omega "),
        ("\u03CA", "\\ddot{\\iota}"),
        ("\u03CB", "\\ddot{\\upsilon}"),
        ("\u03CC", "{\\' o}"),
        ("\u03CD", "\\acute{\\upsilon}"),
        ("\u03CE", "\\acute{\\omega}"),
        ("\u03D0", "\\Pisymbol{ppi022}{87}"),
        ("\u03D1", "\\textvartheta "),
        ("\u03D2", "\\Upsilon "),
        ("\u03D5", "\\phi "),
        ("\u03D6", "\\varpi "),
        ("\u03DA", "\\Stigma "),
        ("\u03DC", "\\Digamma "),
        ("\u03DD", "\\digamma "),
        ("\u03DE", "\\Koppa "),
        ("\u03E0", "\\Sampi "),
        ("\u03F0", "\\varkappa "),
        ("\u03F1", "\\varrho "),
        ("\u03F4", "\\textTheta "),
        ("\u03F6", "\\backepsilon "),
        ("\u0401", "\\cyrchar\\CYRYO "),
        ("\u0402", "\\cyrchar\\CYRDJE "),
        ("\u0403", "\\cyrchar{\\'\\CYRG}"),
        ("\u0404", "\\cyrchar\\CYRIE "),
        ("\u0405", "\\cyrchar\\CYRDZE "),
        ("\u0406", "\\cyrchar\\CYRII "),
        ("\u0407", "\\cyrchar\\CYRYI "),
        ("\u0408", "\\cyrchar\\CYRJE "),
        ("\u0409", "\\cyrchar\\CYRLJE "),
        ("\u040A", "\\cyrchar\\CYRNJE "),
        ("\u040B", "\\cyrchar\\CYRTSHE "),
        ("\u040C", "\\cyrchar{\\'\\CYRK}"),
        ("\u040E", "\\cyrchar\\CYRUSHRT "),
        ("\u040F", "\\cyrchar\\CYRDZHE "),
        ("\u0410", "\\cyrchar\\CYRA "),
        ("\u0411", "\\cyrchar\\CYRB "),
        ("\u0412", "\\cyrchar\\CYRV "),
        ("\u0413", "\\cyrchar\\CYRG "),
        ("\u0414", "\\cyrchar\\CYRD "),
        ("\u0415", "\\cyrchar\\CYRE "),
        ("\u0416", "\\cyrchar\\CYRZH "),
        ("\u0417", "\\cyrchar\\CYRZ "),
        ("\u0418", "\\cyrchar\\CYRI "),
        ("\u0419", "\\cyrchar\\CYRISHRT "),
        ("\u041A", "\\cyrchar\\CYRK "),
        ("\u041B", "\\cyrchar\\CYRL "),
        ("\u041C", "\\cyrchar\\CYRM "),
        ("\u041D", "\\cyrchar\\CYRN "),
        ("\u041E", "\\cyrchar\\CYRO "),
        ("\u041F", "\\cyrchar\\CYRP "),
        ("\u0420", "\\cyrchar\\CYRR "),
        ("\u0421", "\\cyrchar\\CYRS "),
        ("\u0422", "\\cyrchar\\CYRT "),
        ("\u0423", "\\cyrchar\\CYRU "),
        ("\u0424", "\\cyrchar\\CYRF "),
        ("\u0425", "\\cyrchar\\CYRH "),
        ("\u0426", "\\cyrchar\\CYRC "),
        ("\u0427", "\\cyrchar\\CYRCH "),
        ("\u0428", "\\cyrchar\\CYRSH "),
        ("\u0429", "\\cyrchar\\CYRSHCH "),
        ("\u042A", "\\cyrchar\\CYRHRDSN "),
        ("\u042B", "\\cyrchar\\CYRERY "),
        ("\u042C", "\\cyrchar\\CYRSFTSN "),
        ("\u042D", "\\cyrchar\\CYREREV "),
        ("\u042E", "\\cyrchar\\CYRYU "),
        ("\u042F", "\\cyrchar\\CYRYA "),
        ("\u0430", "\\cyrchar\\cyra "),
        ("\u0431", "\\cyrchar\\cyrb "),
        ("\u0432", "\\cyrchar\\cyrv "),
        ("\u0433", "\\cyrchar\\cyrg "),
        ("\u0434", "\\cyrchar\\cyrd "),
        ("\u0435", "\\cyrchar\\cyre "),
        ("\u0436", "\\cyrchar\\cyrzh "),
        ("\u0437", "\\cyrchar\\cyrz "),
        ("\u0438", "\\cyrchar\\cyri "),
        ("\u0439", "\\cyrchar\\cyrishrt "),
        ("\u043A", "\\cyrchar\\cyrk "),
        ("\u043B", "\\cyrchar\\cyrl "),
        ("\u043C", "\\cyrchar\\cyrm "),
        ("\u043D", "\\cyrchar\\cyrn "),
        ("\u043E", "\\cyrchar\\cyro "),
        ("\u043F", "\\cyrchar\\cyrp "),
        ("\u0440", "\\cyrchar\\cyrr "),
        ("\u0441", "\\cyrchar\\cyrs "),
        ("\u0442", "\\cyrchar\\cyrt "),
        ("\u0443", "\\cyrchar\\cyru "),
        ("\u0444", "\\cyrchar\\cyrf "),
        ("\u0445", "\\cyrchar\\cyrh "),
        ("\u0446", "\\cyrchar\\cyrc "),
        ("\u0447", "\\cyrchar\\cyrch "),
        ("\u0448", "\\cyrchar\\cyrsh "),
        ("\u0449", "\\cyrchar\\cyrshch "),
        ("\u044A", "\\cyrchar\\cyrhrdsn "),
        ("\u044B", "\\cyrchar\\cyrery "),
        ("\u044C", "\\cyrchar\\cyrsftsn "),
        ("\u044D", "\\cyrchar\\cyrerev "),
        ("\u044E", "\\cyrchar\\cyryu "),
        ("\u044F", "\\cyrchar\\cyrya "),
        ("\u0451", "\\cyrchar\\cyryo "),
        ("\u0452", "\\cyrchar\\cyrdje "),
        ("\u0453", "\\cyrchar{\\'\\cyrg}"),
        ("\u0454", "\\cyrchar\\cyrie "),
        ("\u0455", "\\cyrchar\\cyrdze "),
        ("\u0456", "\\cyrchar\\cyrii "),
        ("\u0457", "\\cyrchar\\cyryi "),
        ("\u0458", "\\cyrchar\\cyrje "),
        ("\u0459", "\\cyrchar\\cyrlje "),
        ("\u045A", "\\cyrchar\\cyrnje "),
        ("\u045B", "\\cyrchar\\cyrtshe "),
        ("\u045C", "\\cyrchar{\\'\\cyrk}"),
        ("\u045E", "\\cyrchar\\cyrushrt "),
        ("\u045F", "\\cyrchar\\cyrdzhe "),
        ("\u0460", "\\cyrchar\\CYROMEGA "),
        ("\u0461", "\\cyrchar\\cyromega "),
        ("\u0462", "\\cyrchar\\CYRYAT "),
        ("\u0464", "\\cyrchar\\CYRIOTE "),
        ("\u0465", "\\cyrchar\\cyriote "),
        ("\u0466", "\\cyrchar\\CYRLYUS "),
        ("\u0467", "\\cyrchar\\cyrlyus "),
        ("\u0468", "\\cyrchar\\CYRIOTLYUS "),
        ("\u0469", "\\cyrchar\\cyriotlyus "),
        ("\u046A", "\\cyrchar\\CYRBYUS "),
        ("\u046C", "\\cyrchar\\CYRIOTBYUS "),
        ("\u046D", "\\cyrchar\\cyriotbyus "),
        ("\u046E", "\\cyrchar\\CYRKSI "),
        ("\u046F", "\\cyrchar\\cyrksi "),
        ("\u0470", "\\cyrchar\\CYRPSI "),
        ("\u0471", "\\cyrchar\\cyrpsi "),
        ("\u0472", "\\cyrchar\\CYRFITA "),
        ("\u0474", "\\cyrchar\\CYRIZH "),
        ("\u0478", "\\cyrchar\\CYRUK "),
        ("\u0479", "\\cyrchar\\cyruk "),
        ("\u047A", "\\cyrchar\\CYROMEGARND "),
        ("\u047B", "\\cyrchar\\cyromegarnd "),
        ("\u047C", "\\cyrchar\\CYROMEGATITLO "),
        ("\u047D", "\\cyrchar\\cyromegatitlo "),
        ("\u047E", "\\cyrchar\\CYROT "),
        ("\u047F", "\\cyrchar\\cyrot "),
        ("\u0480", "\\cyrchar\\CYRKOPPA "),
        ("\u0481", "\\cyrchar\\cyrkoppa "),
        ("\u0482", "\\cyrchar\\cyrthousands "),
        ("\u0488", "\\cyrchar\\cyrhundredthousands "),
        ("\u0489", "\\cyrchar\\cyrmillions "),
        ("\u048C", "\\cyrchar\\CYRSEMISFTSN "),
        ("\u048D", "\\cyrchar\\cyrsemisftsn "),
        ("\u048E", "\\cyrchar\\CYRRTICK "),
        ("\u048F", "\\cyrchar\\cyrrtick "),
        ("\u0490", "\\cyrchar\\CYRGUP "),
        ("\u0491", "\\cyrchar\\cyrgup "),
        ("\u0492", "\\cyrchar\\CYRGHCRS "),
        ("\u0493", "\\cyrchar\\cyrghcrs "),
        ("\u0494", "\\cyrchar\\CYRGHK "),
        ("\u0495", "\\cyrchar\\cyrghk "),
        ("\u0496", "\\cyrchar\\CYRZHDSC "),
        ("\u0497", "\\cyrchar\\cyrzhdsc "),
        ("\u0498", "\\cyrchar\\CYRZDSC "),
        ("\u0499", "\\cyrchar\\cyrzdsc "),
        ("\u049A", "\\cyrchar\\CYRKDSC "),
        ("\u049B", "\\cyrchar\\cyrkdsc "),
        ("\u049C", "\\cyrchar\\CYRKVCRS "),
        ("\u049D", "\\cyrchar\\cyrkvcrs "),
        ("\u049E", "\\cyrchar\\CYRKHCRS "),
        ("\u049F", "\\cyrchar\\cyrkhcrs "),
        ("\u04A0", "\\cyrchar\\CYRKBEAK "),
        ("\u04A1", "\\cyrchar\\cyrkbeak "),
        ("\u04A2", "\\cyrchar\\CYRNDSC "),
        ("\u04A3", "\\cyrchar\\cyrndsc "),
        ("\u04A4", "\\cyrchar\\CYRNG "),
        ("\u04A5", "\\cyrchar\\cyrng "),
        ("\u04A6", "\\cyrchar\\CYRPHK "),
        ("\u04A7", "\\cyrchar\\cyrphk "),
        ("\u04A8", "\\cyrchar\\CYRABHHA "),
        ("\u04A9", "\\cyrchar\\cyrabhha "),
        ("\u04AA", "\\cyrchar\\CYRSDSC "),
        ("\u04AB", "\\cyrchar\\cyrsdsc "),
        ("\u04AC", "\\cyrchar\\CYRTDSC "),
        ("\u04AD", "\\cyrchar\\cyrtdsc "),
        ("\u04AE", "\\cyrchar\\CYRY "),
        ("\u04AF", "\\cyrchar\\cyry "),
        ("\u04B0", "\\cyrchar\\CYRYHCRS "),
        ("\u04B1", "\\cyrchar\\cyryhcrs "),
        ("\u04B2", "\\cyrchar\\CYRHDSC "),
        ("\u04B3", "\\cyrchar\\cyrhdsc "),
        ("\u04B4", "\\cyrchar\\CYRTETSE "),
        ("\u04B5", "\\cyrchar\\cyrtetse "),
        ("\u04B6", "\\cyrchar\\CYRCHRDSC "),
        ("\u04B7", "\\cyrchar\\cyrchrdsc "),
        ("\u04B8", "\\cyrchar\\CYRCHVCRS "),
        ("\u04B9", "\\cyrchar\\cyrchvcrs "),
        ("\u04BA", "\\cyrchar\\CYRSHHA "),
        ("\u04BB", "\\cyrchar\\cyrshha "),
        ("\u04BC", "\\cyrchar\\CYRABHCH "),
        ("\u04BD", "\\cyrchar\\cyrabhch "),
        ("\u04BE", "\\cyrchar\\CYRABHCHDSC "),
        ("\u04BF", "\\cyrchar\\cyrabhchdsc "),
        ("\u04C0", "\\cyrchar\\CYRpalochka "),
        ("\u04C3", "\\cyrchar\\CYRKHK "),
        ("\u04C4", "\\cyrchar\\cyrkhk "),
        ("\u04C7", "\\cyrchar\\CYRNHK "),
        ("\u04C8", "\\cyrchar\\cyrnhk "),
        ("\u04CB", "\\cyrchar\\CYRCHLDSC "),
        ("\u04CC", "\\cyrchar\\cyrchldsc "),
        ("\u04D4", "\\cyrchar\\CYRAE "),
        ("\u04D5", "\\cyrchar\\cyrae "),
        ("\u04D8", "\\cyrchar\\CYRSCHWA "),
        ("\u04D9", "\\cyrchar\\cyrschwa "),
        ("\u04E0", "\\cyrchar\\CYRABHDZE "),
        ("\u04E1", "\\cyrchar\\cyrabhdze "),
        ("\u04E8", "\\cyrchar\\CYROTLD "),
        ("\u04E9", "\\cyrchar\\cyrotld "),
        ("\u2002", "\\hspace{0.6em}"),
        ("\u2003", "\\hspace{1em}"),
        ("\u2004", "\\hspace{0.33em}"),
        ("\u2005", "\\hspace{0.25em}"),
        ("\u2006", "\\hspace{0.166em}"),
        ("\u2007", "\\hphantom{0}"),
        ("\u2008", "\\hphantom{,}"),
        ("\u2009", "\\hspace{0.167em}"),
        ("\u2009-0200A-0200A", "\\;"),
        ("\u200A", "\\mkern1mu "),
        ("\u2013", "\\textendash "),
        ("\u2014", "\\textemdash "),
        ("\u2015", "\\rule{1em}{1pt}"),
        ("\u2016", "\\Vert "),
        ("\u201B", "\\Elzreapos "),
        ("\u201C", "\\textquotedblleft "),
        ("\u201D", "\\textquotedblright "),
        ("\u201E", ",,"),
        ("\u2020", "\\textdagger "),
        ("\u2021", "\\textdaggerdbl "),
        ("\u2022", "\\textbullet "),
#        (u"\u2025", ".."),
        ("\u2026", "\\ldots "),
        ("\u2030", "\\textperthousand "),
        ("\u2031", "\\textpertenthousand "),
        ("\u2032", "{'}"),
        ("\u2033", "{''}"),
        ("\u2034", "{'''}"),
        ("\u2035", "\\backprime "),
        ("\u2039", "\\guilsinglleft "),
        ("\u203A", "\\guilsinglright "),
        ("\u2057", "''''"),
        ("\u205F", "\\mkern4mu "),
        ("\u2060", "\\nolinebreak "),
        ("\u20A7", "\\ensuremath{\\Elzpes}"),
        ("\u20AC", "\\mbox{\\texteuro} "),
        ("\u20DB", "\\dddot "),
        ("\u20DC", "\\ddddot "),
        ("\u2102", "\\mathbb{C}"),
        ("\u210A", "\\mathscr{g}"),
        ("\u210B", "\\mathscr{H}"),
        ("\u210C", "\\mathfrak{H}"),
        ("\u210D", "\\mathbb{H}"),
        ("\u210F", "\\hslash "),
        ("\u2110", "\\mathscr{I}"),
        ("\u2111", "\\mathfrak{I}"),
        ("\u2112", "\\mathscr{L}"),
        ("\u2113", "\\mathscr{l}"),
        ("\u2115", "\\mathbb{N}"),
        ("\u2116", "\\cyrchar\\textnumero "),
        ("\u2118", "\\wp "),
        ("\u2119", "\\mathbb{P}"),
        ("\u211A", "\\mathbb{Q}"),
        ("\u211B", "\\mathscr{R}"),
        ("\u211C", "\\mathfrak{R}"),
        ("\u211D", "\\mathbb{R}"),
        ("\u211E", "\\Elzxrat "),
        ("\u2122", "\\texttrademark "),
        ("\u2124", "\\mathbb{Z}"),
        ("\u2126", "\\Omega "),
        ("\u2127", "\\mho "),
        ("\u2128", "\\mathfrak{Z}"),
        ("\u2129", "\\ElsevierGlyph{2129}"),
        ("\u212B", "\\AA "),
        ("\u212C", "\\mathscr{B}"),
        ("\u212D", "\\mathfrak{C}"),
        ("\u212F", "\\mathscr{e}"),
        ("\u2130", "\\mathscr{E}"),
        ("\u2131", "\\mathscr{F}"),
        ("\u2133", "\\mathscr{M}"),
        ("\u2134", "\\mathscr{o}"),
        ("\u2135", "\\aleph "),
        ("\u2136", "\\beth "),
        ("\u2137", "\\gimel "),
        ("\u2138", "\\daleth "),
        ("\u2153", "\\textfrac{1}{3}"),
        ("\u2154", "\\textfrac{2}{3}"),
        ("\u2155", "\\textfrac{1}{5}"),
        ("\u2156", "\\textfrac{2}{5}"),
        ("\u2157", "\\textfrac{3}{5}"),
        ("\u2158", "\\textfrac{4}{5}"),
        ("\u2159", "\\textfrac{1}{6}"),
        ("\u215A", "\\textfrac{5}{6}"),
        ("\u215B", "\\textfrac{1}{8}"),
        ("\u215C", "\\textfrac{3}{8}"),
        ("\u215D", "\\textfrac{5}{8}"),
        ("\u215E", "\\textfrac{7}{8}"),
        ("\u2190", "\\leftarrow "),
        ("\u2191", "\\uparrow "),
        ("\u2192", "\\rightarrow "),
        ("\u2193", "\\downarrow "),
        ("\u2194", "\\leftrightarrow "),
        ("\u2195", "\\updownarrow "),
        ("\u2196", "\\nwarrow "),
        ("\u2197", "\\nearrow "),
        ("\u2198", "\\searrow "),
        ("\u2199", "\\swarrow "),
        ("\u219A", "\\nleftarrow "),
        ("\u219B", "\\nrightarrow "),
        ("\u219C", "\\arrowwaveright "),
        ("\u219D", "\\arrowwaveright "),
        ("\u219E", "\\twoheadleftarrow "),
        ("\u21A0", "\\twoheadrightarrow "),
        ("\u21A2", "\\leftarrowtail "),
        ("\u21A3", "\\rightarrowtail "),
        ("\u21A6", "\\mapsto "),
        ("\u21A9", "\\hookleftarrow "),
        ("\u21AA", "\\hookrightarrow "),
        ("\u21AB", "\\looparrowleft "),
        ("\u21AC", "\\looparrowright "),
        ("\u21AD", "\\leftrightsquigarrow "),
        ("\u21AE", "\\nleftrightarrow "),
        ("\u21B0", "\\Lsh "),
        ("\u21B1", "\\Rsh "),
        ("\u21B3", "\\ElsevierGlyph{21B3}"),
        ("\u21B6", "\\curvearrowleft "),
        ("\u21B7", "\\curvearrowright "),
        ("\u21BA", "\\circlearrowleft "),
        ("\u21BB", "\\circlearrowright "),
        ("\u21BC", "\\leftharpoonup "),
        ("\u21BD", "\\leftharpoondown "),
        ("\u21BE", "\\upharpoonright "),
        ("\u21BF", "\\upharpoonleft "),
        ("\u21C0", "\\rightharpoonup "),
        ("\u21C1", "\\rightharpoondown "),
        ("\u21C2", "\\downharpoonright "),
        ("\u21C3", "\\downharpoonleft "),
        ("\u21C4", "\\rightleftarrows "),
        ("\u21C5", "\\dblarrowupdown "),
        ("\u21C6", "\\leftrightarrows "),
        ("\u21C7", "\\leftleftarrows "),
        ("\u21C8", "\\upuparrows "),
        ("\u21C9", "\\rightrightarrows "),
        ("\u21CA", "\\downdownarrows "),
        ("\u21CB", "\\leftrightharpoons "),
        ("\u21CC", "\\rightleftharpoons "),
        ("\u21CD", "\\nLeftarrow "),
        ("\u21CE", "\\nLeftrightarrow "),
        ("\u21CF", "\\nRightarrow "),
        ("\u21D0", "\\Leftarrow "),
        ("\u21D1", "\\Uparrow "),
        ("\u21D2", "\\Rightarrow "),
        ("\u21D3", "\\Downarrow "),
        ("\u21D4", "\\Leftrightarrow "),
        ("\u21D5", "\\Updownarrow "),
        ("\u21DA", "\\Lleftarrow "),
        ("\u21DB", "\\Rrightarrow "),
        ("\u21DD", "\\rightsquigarrow "),
        ("\u21F5", "\\DownArrowUpArrow "),
        ("\u2200", "\\forall "),
        ("\u2201", "\\complement "),
        ("\u2202", "\\partial "),
        ("\u2203", "\\exists "),
        ("\u2204", "\\nexists "),
        ("\u2205", "\\varnothing "),
        ("\u2207", "\\nabla "),
        ("\u2208", "\\in "),
        ("\u2209", "\\not\\in "),
        ("\u220B", "\\ni "),
        ("\u220C", "\\not\\ni "),
        ("\u220F", "\\prod "),
        ("\u2210", "\\coprod "),
        ("\u2211", "\\sum "),
        ("\u2213", "\\mp "),
        ("\u2214", "\\dotplus "),
        ("\u2216", "\\setminus "),
        ("\u2217", "{_\\ast}"),
        ("\u2218", "\\circ "),
        ("\u2219", "\\bullet "),
        ("\u221A", "\\surd "),
        ("\u221D", "\\propto "),
        ("\u221E", "\\infty "),
        ("\u221F", "\\rightangle "),
        ("\u2220", "\\angle "),
        ("\u2221", "\\measuredangle "),
        ("\u2222", "\\sphericalangle "),
        ("\u2223", "\\mid "),
        ("\u2224", "\\nmid "),
        ("\u2225", "\\parallel "),
        ("\u2226", "\\nparallel "),
        ("\u2227", "\\wedge "),
        ("\u2228", "\\vee "),
        ("\u2229", "\\cap "),
        ("\u222A", "\\cup "),
        ("\u222B", "\\int "),
        ("\u222C", "\\int\\!\\int "),
        ("\u222D", "\\int\\!\\int\\!\\int "),
        ("\u222E", "\\oint "),
        ("\u222F", "\\surfintegral "),
        ("\u2230", "\\volintegral "),
        ("\u2231", "\\clwintegral "),
        ("\u2232", "\\ElsevierGlyph{2232}"),
        ("\u2233", "\\ElsevierGlyph{2233}"),
        ("\u2234", "\\therefore "),
        ("\u2235", "\\because "),
        ("\u2237", "\\Colon "),
        ("\u2238", "\\ElsevierGlyph{2238}"),
        ("\u223A", "\\mathbin{{:}\\!\\!{-}\\!\\!{:}}"),
        ("\u223B", "\\homothetic "),
        ("\u223C", "\\sim "),
        ("\u223D", "\\backsim "),
        ("\u223E", "\\lazysinv "),
        ("\u2240", "\\wr "),
        ("\u2241", "\\not\\sim "),
        ("\u2242", "\\ElsevierGlyph{2242}"),
        ("\u2242-00338", "\\NotEqualTilde "),
        ("\u2243", "\\simeq "),
        ("\u2244", "\\not\\simeq "),
        ("\u2245", "\\cong "),
        ("\u2246", "\\approxnotequal "),
        ("\u2247", "\\not\\cong "),
        ("\u2248", "\\approx "),
        ("\u2249", "\\not\\approx "),
        ("\u224A", "\\approxeq "),
        ("\u224B", "\\tildetrpl "),
        ("\u224B-00338", "\\not\\apid "),
        ("\u224C", "\\allequal "),
        ("\u224D", "\\asymp "),
        ("\u224E", "\\Bumpeq "),
        ("\u224E-00338", "\\NotHumpDownHump "),
        ("\u224F", "\\bumpeq "),
        ("\u224F-00338", "\\NotHumpEqual "),
        ("\u2250", "\\doteq "),
        ("\u2250-00338", "\\not\\doteq"),
        ("\u2251", "\\doteqdot "),
        ("\u2252", "\\fallingdotseq "),
        ("\u2253", "\\risingdotseq "),
        ("\u2254", ":="),
        ("\u2255", "=:"),
        ("\u2256", "\\eqcirc "),
        ("\u2257", "\\circeq "),
        ("\u2259", "\\estimates "),
        ("\u225A", "\\ElsevierGlyph{225A}"),
        ("\u225B", "\\starequal "),
        ("\u225C", "\\triangleq "),
        ("\u225F", "\\ElsevierGlyph{225F}"),
        ("\u2260", "\\not ="),
        ("\u2261", "\\equiv "),
        ("\u2262", "\\not\\equiv "),
        ("\u2264", "\\leq "),
        ("\u2265", "\\geq "),
        ("\u2266", "\\leqq "),
        ("\u2267", "\\geqq "),
        ("\u2268", "\\lneqq "),
        ("\u2268-0FE00", "\\lvertneqq "),
        ("\u2269", "\\gneqq "),
        ("\u2269-0FE00", "\\gvertneqq "),
        ("\u226A", "\\ll "),
        ("\u226A-00338", "\\NotLessLess "),
        ("\u226B", "\\gg "),
        ("\u226B-00338", "\\NotGreaterGreater "),
        ("\u226C", "\\between "),
        ("\u226D", "\\not\\kern-0.3em\\times "),
        ("\u226E", "\\not<"),
        ("\u226F", "\\not>"),
        ("\u2270", "\\not\\leq "),
        ("\u2271", "\\not\\geq "),
        ("\u2272", "\\lessequivlnt "),
        ("\u2273", "\\greaterequivlnt "),
        ("\u2274", "\\ElsevierGlyph{2274}"),
        ("\u2275", "\\ElsevierGlyph{2275}"),
        ("\u2276", "\\lessgtr "),
        ("\u2277", "\\gtrless "),
        ("\u2278", "\\notlessgreater "),
        ("\u2279", "\\notgreaterless "),
        ("\u227A", "\\prec "),
        ("\u227B", "\\succ "),
        ("\u227C", "\\preccurlyeq "),
        ("\u227D", "\\succcurlyeq "),
        ("\u227E", "\\precapprox "),
        ("\u227E-00338", "\\NotPrecedesTilde "),
        ("\u227F", "\\succapprox "),
        ("\u227F-00338", "\\NotSucceedsTilde "),
        ("\u2280", "\\not\\prec "),
        ("\u2281", "\\not\\succ "),
        ("\u2282", "\\subset "),
        ("\u2283", "\\supset "),
        ("\u2284", "\\not\\subset "),
        ("\u2285", "\\not\\supset "),
        ("\u2286", "\\subseteq "),
        ("\u2287", "\\supseteq "),
        ("\u2288", "\\not\\subseteq "),
        ("\u2289", "\\not\\supseteq "),
        ("\u228A", "\\subsetneq "),
        ("\u228A-0FE00", "\\varsubsetneqq "),
        ("\u228B", "\\supsetneq "),
        ("\u228B-0FE00", "\\varsupsetneq "),
        ("\u228E", "\\uplus "),
        ("\u228F", "\\sqsubset "),
        ("\u228F-00338", "\\NotSquareSubset "),
        ("\u2290", "\\sqsupset "),
        ("\u2290-00338", "\\NotSquareSuperset "),
        ("\u2291", "\\sqsubseteq "),
        ("\u2292", "\\sqsupseteq "),
        ("\u2293", "\\sqcap "),
        ("\u2294", "\\sqcup "),
        ("\u2295", "\\oplus "),
        ("\u2296", "\\ominus "),
        ("\u2297", "\\otimes "),
        ("\u2298", "\\oslash "),
        ("\u2299", "\\odot "),
        ("\u229A", "\\circledcirc "),
        ("\u229B", "\\circledast "),
        ("\u229D", "\\circleddash "),
        ("\u229E", "\\boxplus "),
        ("\u229F", "\\boxminus "),
        ("\u22A0", "\\boxtimes "),
        ("\u22A1", "\\boxdot "),
        ("\u22A2", "\\vdash "),
        ("\u22A3", "\\dashv "),
        ("\u22A4", "\\top "),
        ("\u22A5", "\\perp "),
        ("\u22A7", "\\truestate "),
        ("\u22A8", "\\forcesextra "),
        ("\u22A9", "\\Vdash "),
        ("\u22AA", "\\Vvdash "),
        ("\u22AB", "\\VDash "),
        ("\u22AC", "\\nvdash "),
        ("\u22AD", "\\nvDash "),
        ("\u22AE", "\\nVdash "),
        ("\u22AF", "\\nVDash "),
        ("\u22B2", "\\vartriangleleft "),
        ("\u22B3", "\\vartriangleright "),
        ("\u22B4", "\\trianglelefteq "),
        ("\u22B5", "\\trianglerighteq "),
        ("\u22B6", "\\original "),
        ("\u22B7", "\\image "),
        ("\u22B8", "\\multimap "),
        ("\u22B9", "\\hermitconjmatrix "),
        ("\u22BA", "\\intercal "),
        ("\u22BB", "\\veebar "),
        ("\u22BE", "\\rightanglearc "),
        ("\u22C0", "\\ElsevierGlyph{22C0}"),
        ("\u22C1", "\\ElsevierGlyph{22C1}"),
        ("\u22C2", "\\bigcap "),
        ("\u22C3", "\\bigcup "),
        ("\u22C4", "\\diamond "),
        ("\u22C5", "\\cdot "),
        ("\u22C6", "\\star "),
        ("\u22C7", "\\divideontimes "),
        ("\u22C8", "\\bowtie "),
        ("\u22C9", "\\ltimes "),
        ("\u22CA", "\\rtimes "),
        ("\u22CB", "\\leftthreetimes "),
        ("\u22CC", "\\rightthreetimes "),
        ("\u22CD", "\\backsimeq "),
        ("\u22CE", "\\curlyvee "),
        ("\u22CF", "\\curlywedge "),
        ("\u22D0", "\\Subset "),
        ("\u22D1", "\\Supset "),
        ("\u22D2", "\\Cap "),
        ("\u22D3", "\\Cup "),
        ("\u22D4", "\\pitchfork "),
        ("\u22D6", "\\lessdot "),
        ("\u22D7", "\\gtrdot "),
        ("\u22D8", "\\verymuchless "),
        ("\u22D9", "\\verymuchgreater "),
        ("\u22DA", "\\lesseqgtr "),
        ("\u22DB", "\\gtreqless "),
        ("\u22DE", "\\curlyeqprec "),
        ("\u22DF", "\\curlyeqsucc "),
        ("\u22E2", "\\not\\sqsubseteq "),
        ("\u22E3", "\\not\\sqsupseteq "),
        ("\u22E5", "\\Elzsqspne "),
        ("\u22E6", "\\lnsim "),
        ("\u22E7", "\\gnsim "),
        ("\u22E8", "\\precedesnotsimilar "),
        ("\u22E9", "\\succnsim "),
        ("\u22EA", "\\ntriangleleft "),
        ("\u22EB", "\\ntriangleright "),
        ("\u22EC", "\\ntrianglelefteq "),
        ("\u22ED", "\\ntrianglerighteq "),
        ("\u22EE", "\\vdots "),
        ("\u22EF", "\\cdots "),
        ("\u22F0", "\\upslopeellipsis "),
        ("\u22F1", "\\downslopeellipsis "),
        ("\u2305", "\\barwedge "),
        ("\u2306", "\\perspcorrespond "),
        ("\u2308", "\\lceil "),
        ("\u2309", "\\rceil "),
        ("\u230A", "\\lfloor "),
        ("\u230B", "\\rfloor "),
        ("\u2315", "\\recorder "),
        ("\u2316", "\\mathchar\"2208"),
        ("\u231C", "\\ulcorner "),
        ("\u231D", "\\urcorner "),
        ("\u231E", "\\llcorner "),
        ("\u231F", "\\lrcorner "),
        ("\u2322", "\\frown "),
        ("\u2323", "\\smile "),
        ("\u2329", "\\langle "),
        ("\u232A", "\\rangle "),
        ("\u233D", "\\ElsevierGlyph{E838}"),
        ("\u23A3", "\\Elzdlcorn "),
        ("\u23B0", "\\lmoustache "),
        ("\u23B1", "\\rmoustache "),
        ("\u2423", "\\textvisiblespace "),
        ("\u2460", "\\ding{172}"),
        ("\u2461", "\\ding{173}"),
        ("\u2462", "\\ding{174}"),
        ("\u2463", "\\ding{175}"),
        ("\u2464", "\\ding{176}"),
        ("\u2465", "\\ding{177}"),
        ("\u2466", "\\ding{178}"),
        ("\u2467", "\\ding{179}"),
        ("\u2468", "\\ding{180}"),
        ("\u2469", "\\ding{181}"),
        ("\u24C8", "\\circledS "),
        ("\u2506", "\\Elzdshfnc "),
        ("\u2519", "\\Elzsqfnw "),
        ("\u2571", "\\diagup "),
        ("\u25A0", "\\ding{110}"),
        ("\u25A1", "\\square "),
        ("\u25AA", "\\blacksquare "),
        ("\u25AD", "\\fbox{~~}"),
        ("\u25AF", "\\Elzvrecto "),
        ("\u25B1", "\\ElsevierGlyph{E381}"),
        ("\u25B2", "\\ding{115}"),
        ("\u25B3", "\\bigtriangleup "),
        ("\u25B4", "\\blacktriangle "),
        ("\u25B5", "\\vartriangle "),
        ("\u25B8", "\\blacktriangleright "),
        ("\u25B9", "\\triangleright "),
        ("\u25BC", "\\ding{116}"),
        ("\u25BD", "\\bigtriangledown "),
        ("\u25BE", "\\blacktriangledown "),
        ("\u25BF", "\\triangledown "),
        ("\u25C2", "\\blacktriangleleft "),
        ("\u25C3", "\\triangleleft "),
        ("\u25C6", "\\ding{117}"),
        ("\u25CA", "\\lozenge "),
        ("\u25CB", "\\bigcirc "),
        ("\u25CF", "\\ding{108}"),
        ("\u25D0", "\\Elzcirfl "),
        ("\u25D1", "\\Elzcirfr "),
        ("\u25D2", "\\Elzcirfb "),
        ("\u25D7", "\\ding{119}"),
        ("\u25D8", "\\Elzrvbull "),
        ("\u25E7", "\\Elzsqfl "),
        ("\u25E8", "\\Elzsqfr "),
        ("\u25EA", "\\Elzsqfse "),
        ("\u25EF", "\\bigcirc "),
        ("\u2605", "\\ding{72}"),
        ("\u2606", "\\ding{73}"),
        ("\u260E", "\\ding{37}"),
        ("\u261B", "\\ding{42}"),
        ("\u261E", "\\ding{43}"),
        ("\u263E", "\\rightmoon "),
        ("\u263F", "\\mercury "),
        ("\u2640", "\\venus "),
        ("\u2642", "\\male "),
        ("\u2643", "\\jupiter "),
        ("\u2644", "\\saturn "),
        ("\u2645", "\\uranus "),
        ("\u2646", "\\neptune "),
        ("\u2647", "\\pluto "),
        ("\u2648", "\\aries "),
        ("\u2649", "\\taurus "),
        ("\u264A", "\\gemini "),
        ("\u264B", "\\cancer "),
        ("\u264C", "\\leo "),
        ("\u264D", "\\virgo "),
        ("\u264E", "\\libra "),
        ("\u264F", "\\scorpio "),
        ("\u2650", "\\sagittarius "),
        ("\u2651", "\\capricornus "),
        ("\u2652", "\\aquarius "),
        ("\u2653", "\\pisces "),
        ("\u2660", "\\ding{171}"),
        ("\u2662", "\\diamond "),
        ("\u2663", "\\ding{168}"),
        ("\u2665", "\\ding{170}"),
        ("\u2666", "\\ding{169}"),
        ("\u2669", "\\quarternote "),
        ("\u266A", "\\eighthnote "),
        ("\u266D", "\\flat "),
        ("\u266E", "\\natural "),
        ("\u266F", "\\sharp "),
        ("\u2701", "\\ding{33}"),
        ("\u2702", "\\ding{34}"),
        ("\u2703", "\\ding{35}"),
        ("\u2704", "\\ding{36}"),
        ("\u2706", "\\ding{38}"),
        ("\u2707", "\\ding{39}"),
        ("\u2708", "\\ding{40}"),
        ("\u2709", "\\ding{41}"),
        ("\u270C", "\\ding{44}"),
        ("\u270D", "\\ding{45}"),
        ("\u270E", "\\ding{46}"),
        ("\u270F", "\\ding{47}"),
        ("\u2710", "\\ding{48}"),
        ("\u2711", "\\ding{49}"),
        ("\u2712", "\\ding{50}"),
        ("\u2713", "\\ding{51}"),
        ("\u2714", "\\ding{52}"),
        ("\u2715", "\\ding{53}"),
        ("\u2716", "\\ding{54}"),
        ("\u2717", "\\ding{55}"),
        ("\u2718", "\\ding{56}"),
        ("\u2719", "\\ding{57}"),
        ("\u271A", "\\ding{58}"),
        ("\u271B", "\\ding{59}"),
        ("\u271C", "\\ding{60}"),
        ("\u271D", "\\ding{61}"),
        ("\u271E", "\\ding{62}"),
        ("\u271F", "\\ding{63}"),
        ("\u2720", "\\ding{64}"),
        ("\u2721", "\\ding{65}"),
        ("\u2722", "\\ding{66}"),
        ("\u2723", "\\ding{67}"),
        ("\u2724", "\\ding{68}"),
        ("\u2725", "\\ding{69}"),
        ("\u2726", "\\ding{70}"),
        ("\u2727", "\\ding{71}"),
        ("\u2729", "\\ding{73}"),
        ("\u272A", "\\ding{74}"),
        ("\u272B", "\\ding{75}"),
        ("\u272C", "\\ding{76}"),
        ("\u272D", "\\ding{77}"),
        ("\u272E", "\\ding{78}"),
        ("\u272F", "\\ding{79}"),
        ("\u2730", "\\ding{80}"),
        ("\u2731", "\\ding{81}"),
        ("\u2732", "\\ding{82}"),
        ("\u2733", "\\ding{83}"),
        ("\u2734", "\\ding{84}"),
        ("\u2735", "\\ding{85}"),
        ("\u2736", "\\ding{86}"),
        ("\u2737", "\\ding{87}"),
        ("\u2738", "\\ding{88}"),
        ("\u2739", "\\ding{89}"),
        ("\u273A", "\\ding{90}"),
        ("\u273B", "\\ding{91}"),
        ("\u273C", "\\ding{92}"),
        ("\u273D", "\\ding{93}"),
        ("\u273E", "\\ding{94}"),
        ("\u273F", "\\ding{95}"),
        ("\u2740", "\\ding{96}"),
        ("\u2741", "\\ding{97}"),
        ("\u2742", "\\ding{98}"),
        ("\u2743", "\\ding{99}"),
        ("\u2744", "\\ding{100}"),
        ("\u2745", "\\ding{101}"),
        ("\u2746", "\\ding{102}"),
        ("\u2747", "\\ding{103}"),
        ("\u2748", "\\ding{104}"),
        ("\u2749", "\\ding{105}"),
        ("\u274A", "\\ding{106}"),
        ("\u274B", "\\ding{107}"),
        ("\u274D", "\\ding{109}"),
        ("\u274F", "\\ding{111}"),
        ("\u2750", "\\ding{112}"),
        ("\u2751", "\\ding{113}"),
        ("\u2752", "\\ding{114}"),
        ("\u2756", "\\ding{118}"),
        ("\u2758", "\\ding{120}"),
        ("\u2759", "\\ding{121}"),
        ("\u275A", "\\ding{122}"),
        ("\u275B", "\\ding{123}"),
        ("\u275C", "\\ding{124}"),
        ("\u275D", "\\ding{125}"),
        ("\u275E", "\\ding{126}"),
        ("\u2761", "\\ding{161}"),
        ("\u2762", "\\ding{162}"),
        ("\u2763", "\\ding{163}"),
        ("\u2764", "\\ding{164}"),
        ("\u2765", "\\ding{165}"),
        ("\u2766", "\\ding{166}"),
        ("\u2767", "\\ding{167}"),
        ("\u2776", "\\ding{182}"),
        ("\u2777", "\\ding{183}"),
        ("\u2778", "\\ding{184}"),
        ("\u2779", "\\ding{185}"),
        ("\u277A", "\\ding{186}"),
        ("\u277B", "\\ding{187}"),
        ("\u277C", "\\ding{188}"),
        ("\u277D", "\\ding{189}"),
        ("\u277E", "\\ding{190}"),
        ("\u277F", "\\ding{191}"),
        ("\u2780", "\\ding{192}"),
        ("\u2781", "\\ding{193}"),
        ("\u2782", "\\ding{194}"),
        ("\u2783", "\\ding{195}"),
        ("\u2784", "\\ding{196}"),
        ("\u2785", "\\ding{197}"),
        ("\u2786", "\\ding{198}"),
        ("\u2787", "\\ding{199}"),
        ("\u2788", "\\ding{200}"),
        ("\u2789", "\\ding{201}"),
        ("\u278A", "\\ding{202}"),
        ("\u278B", "\\ding{203}"),
        ("\u278C", "\\ding{204}"),
        ("\u278D", "\\ding{205}"),
        ("\u278E", "\\ding{206}"),
        ("\u278F", "\\ding{207}"),
        ("\u2790", "\\ding{208}"),
        ("\u2791", "\\ding{209}"),
        ("\u2792", "\\ding{210}"),
        ("\u2793", "\\ding{211}"),
        ("\u2794", "\\ding{212}"),
        ("\u2798", "\\ding{216}"),
        ("\u2799", "\\ding{217}"),
        ("\u279A", "\\ding{218}"),
        ("\u279B", "\\ding{219}"),
        ("\u279C", "\\ding{220}"),
        ("\u279D", "\\ding{221}"),
        ("\u279E", "\\ding{222}"),
        ("\u279F", "\\ding{223}"),
        ("\u27A0", "\\ding{224}"),
        ("\u27A1", "\\ding{225}"),
        ("\u27A2", "\\ding{226}"),
        ("\u27A3", "\\ding{227}"),
        ("\u27A4", "\\ding{228}"),
        ("\u27A5", "\\ding{229}"),
        ("\u27A6", "\\ding{230}"),
        ("\u27A7", "\\ding{231}"),
        ("\u27A8", "\\ding{232}"),
        ("\u27A9", "\\ding{233}"),
        ("\u27AA", "\\ding{234}"),
        ("\u27AB", "\\ding{235}"),
        ("\u27AC", "\\ding{236}"),
        ("\u27AD", "\\ding{237}"),
        ("\u27AE", "\\ding{238}"),
        ("\u27AF", "\\ding{239}"),
        ("\u27B1", "\\ding{241}"),
        ("\u27B2", "\\ding{242}"),
        ("\u27B3", "\\ding{243}"),
        ("\u27B4", "\\ding{244}"),
        ("\u27B5", "\\ding{245}"),
        ("\u27B6", "\\ding{246}"),
        ("\u27B7", "\\ding{247}"),
        ("\u27B8", "\\ding{248}"),
        ("\u27B9", "\\ding{249}"),
        ("\u27BA", "\\ding{250}"),
        ("\u27BB", "\\ding{251}"),
        ("\u27BC", "\\ding{252}"),
        ("\u27BD", "\\ding{253}"),
        ("\u27BE", "\\ding{254}"),
        ("\u27F5", "\\longleftarrow "),
        ("\u27F6", "\\longrightarrow "),
        ("\u27F7", "\\longleftrightarrow "),
        ("\u27F8", "\\Longleftarrow "),
        ("\u27F9", "\\Longrightarrow "),
        ("\u27FA", "\\Longleftrightarrow "),
        ("\u27FC", "\\longmapsto "),
        ("\u27FF", "\\sim\\joinrel\\leadsto"),
        ("\u2905", "\\ElsevierGlyph{E212}"),
        ("\u2912", "\\UpArrowBar "),
        ("\u2913", "\\DownArrowBar "),
        ("\u2923", "\\ElsevierGlyph{E20C}"),
        ("\u2924", "\\ElsevierGlyph{E20D}"),
        ("\u2925", "\\ElsevierGlyph{E20B}"),
        ("\u2926", "\\ElsevierGlyph{E20A}"),
        ("\u2927", "\\ElsevierGlyph{E211}"),
        ("\u2928", "\\ElsevierGlyph{E20E}"),
        ("\u2929", "\\ElsevierGlyph{E20F}"),
        ("\u292A", "\\ElsevierGlyph{E210}"),
        ("\u2933", "\\ElsevierGlyph{E21C}"),
        ("\u2933-00338", "\\ElsevierGlyph{E21D}"),
        ("\u2936", "\\ElsevierGlyph{E21A}"),
        ("\u2937", "\\ElsevierGlyph{E219}"),
        ("\u2940", "\\Elolarr "),
        ("\u2941", "\\Elorarr "),
        ("\u2942", "\\ElzRlarr "),
        ("\u2944", "\\ElzrLarr "),
        ("\u2947", "\\Elzrarrx "),
        ("\u294E", "\\LeftRightVector "),
        ("\u294F", "\\RightUpDownVector "),
        ("\u2950", "\\DownLeftRightVector "),
        ("\u2951", "\\LeftUpDownVector "),
        ("\u2952", "\\LeftVectorBar "),
        ("\u2953", "\\RightVectorBar "),
        ("\u2954", "\\RightUpVectorBar "),
        ("\u2955", "\\RightDownVectorBar "),
        ("\u2956", "\\DownLeftVectorBar "),
        ("\u2957", "\\DownRightVectorBar "),
        ("\u2958", "\\LeftUpVectorBar "),
        ("\u2959", "\\LeftDownVectorBar "),
        ("\u295A", "\\LeftTeeVector "),
        ("\u295B", "\\RightTeeVector "),
        ("\u295C", "\\RightUpTeeVector "),
        ("\u295D", "\\RightDownTeeVector "),
        ("\u295E", "\\DownLeftTeeVector "),
        ("\u295F", "\\DownRightTeeVector "),
        ("\u2960", "\\LeftUpTeeVector "),
        ("\u2961", "\\LeftDownTeeVector "),
        ("\u296E", "\\UpEquilibrium "),
        ("\u296F", "\\ReverseUpEquilibrium "),
        ("\u2970", "\\RoundImplies "),
        ("\u297C", "\\ElsevierGlyph{E214}"),
        ("\u297D", "\\ElsevierGlyph{E215}"),
        ("\u2980", "\\Elztfnc "),
        ("\u2985", "\\ElsevierGlyph{3018}"),
        ("\u2986", "\\Elroang "),
        ("\u2993", "<\\kern-0.58em("),
        ("\u2994", "\\ElsevierGlyph{E291}"),
        ("\u2999", "\\Elzddfnc "),
        ("\u299C", "\\Angle "),
        ("\u29A0", "\\Elzlpargt "),
        ("\u29B5", "\\ElsevierGlyph{E260}"),
        ("\u29B6", "\\ElsevierGlyph{E61B}"),
        ("\u29CA", "\\ElzLap "),
        ("\u29CB", "\\Elzdefas "),
        ("\u29CF", "\\LeftTriangleBar "),
        ("\u29CF-00338", "\\NotLeftTriangleBar "),
        ("\u29D0", "\\RightTriangleBar "),
        ("\u29D0-00338", "\\NotRightTriangleBar "),
        ("\u29DC", "\\ElsevierGlyph{E372}"),
        ("\u29EB", "\\blacklozenge "),
        ("\u29F4", "\\RuleDelayed "),
        ("\u2A04", "\\Elxuplus "),
        ("\u2A05", "\\ElzThr "),
        ("\u2A06", "\\Elxsqcup "),
        ("\u2A07", "\\ElzInf "),
        ("\u2A08", "\\ElzSup "),
        ("\u2A0D", "\\ElzCint "),
        ("\u2A0F", "\\clockoint "),
        ("\u2A10", "\\ElsevierGlyph{E395}"),
        ("\u2A16", "\\sqrint "),
        ("\u2A25", "\\ElsevierGlyph{E25A}"),
        ("\u2A2A", "\\ElsevierGlyph{E25B}"),
        ("\u2A2D", "\\ElsevierGlyph{E25C}"),
        ("\u2A2E", "\\ElsevierGlyph{E25D}"),
        ("\u2A2F", "\\ElzTimes "),
        ("\u2A34", "\\ElsevierGlyph{E25E}"),
        ("\u2A35", "\\ElsevierGlyph{E25E}"),
        ("\u2A3C", "\\ElsevierGlyph{E259}"),
        ("\u2A3F", "\\amalg "),
        ("\u2A53", "\\ElzAnd "),
        ("\u2A54", "\\ElzOr "),
        ("\u2A55", "\\ElsevierGlyph{E36E}"),
        ("\u2A56", "\\ElOr "),
        ("\u2A5E", "\\perspcorrespond "),
        ("\u2A5F", "\\Elzminhat "),
        ("\u2A63", "\\ElsevierGlyph{225A}"),
        ("\u2A6E", "\\stackrel{*}{=}"),
        ("\u2A75", "\\Equal "),
        ("\u2A7D", "\\leqslant "),
        ("\u2A7D-00338", "\\nleqslant "),
        ("\u2A7E", "\\geqslant "),
        ("\u2A7E-00338", "\\ngeqslant "),
        ("\u2A85", "\\lessapprox "),
        ("\u2A86", "\\gtrapprox "),
        ("\u2A87", "\\lneq "),
        ("\u2A88", "\\gneq "),
        ("\u2A89", "\\lnapprox "),
        ("\u2A8A", "\\gnapprox "),
        ("\u2A8B", "\\lesseqqgtr "),
        ("\u2A8C", "\\gtreqqless "),
        ("\u2A95", "\\eqslantless "),
        ("\u2A96", "\\eqslantgtr "),
        ("\u2A9D", "\\Pisymbol{ppi020}{117}"),
        ("\u2A9E", "\\Pisymbol{ppi020}{105}"),
        ("\u2AA1", "\\NestedLessLess "),
        ("\u2AA1-00338", "\\NotNestedLessLess "),
        ("\u2AA2", "\\NestedGreaterGreater "),
        ("\u2AA2-00338", "\\NotNestedGreaterGreater "),
        ("\u2AAF", "\\preceq "),
        ("\u2AAF-00338", "\\not\\preceq "),
        ("\u2AB0", "\\succeq "),
        ("\u2AB0-00338", "\\not\\succeq "),
        ("\u2AB5", "\\precneqq "),
        ("\u2AB6", "\\succneqq "),
        ("\u2AB7", "\\precapprox "),
        ("\u2AB8", "\\succapprox "),
        ("\u2AB9", "\\precnapprox "),
        ("\u2ABA", "\\succnapprox "),
        ("\u2AC5", "\\subseteqq "),
        ("\u2AC5-00338", "\\nsubseteqq "),
        ("\u2AC6", "\\supseteqq "),
        ("\u2AC6-00338", "\\nsupseteqq"),
        ("\u2ACB", "\\subsetneqq "),
        ("\u2ACC", "\\supsetneqq "),
        ("\u2AEB", "\\ElsevierGlyph{E30D}"),
        ("\u2AF6", "\\Elztdcol "),
        ("\u2AFD", "{{/}\\!\\!{/}}"),
        ("\u2AFD-020E5", "{\\rlap{\\textbackslash}{{/}\\!\\!{/}}}"),
        ("\u300A", "\\ElsevierGlyph{300A}"),
        ("\u300B", "\\ElsevierGlyph{300B}"),
        ("\u3018", "\\ElsevierGlyph{3018}"),
        ("\u3019", "\\ElsevierGlyph{3019}"),
        ("\u301A", "\\openbracketleft "),
        ("\u301B", "\\openbracketright "),
#        (u"\uFB00", "ff"),
#        (u"\uFB01", "fi"),
#        (u"\uFB02", "fl"),
#        (u"\uFB03", "ffi"),
#        (u"\uFB04", "ffl"),
        ("\uD400", "\\mathbf{A}"),
        ("\uD401", "\\mathbf{B}"),
        ("\uD402", "\\mathbf{C}"),
        ("\uD403", "\\mathbf{D}"),
        ("\uD404", "\\mathbf{E}"),
        ("\uD405", "\\mathbf{F}"),
        ("\uD406", "\\mathbf{G}"),
        ("\uD407", "\\mathbf{H}"),
        ("\uD408", "\\mathbf{I}"),
        ("\uD409", "\\mathbf{J}"),
        ("\uD40A", "\\mathbf{K}"),
        ("\uD40B", "\\mathbf{L}"),
        ("\uD40C", "\\mathbf{M}"),
        ("\uD40D", "\\mathbf{N}"),
        ("\uD40E", "\\mathbf{O}"),
        ("\uD40F", "\\mathbf{P}"),
        ("\uD410", "\\mathbf{Q}"),
        ("\uD411", "\\mathbf{R}"),
        ("\uD412", "\\mathbf{S}"),
        ("\uD413", "\\mathbf{T}"),
        ("\uD414", "\\mathbf{U}"),
        ("\uD415", "\\mathbf{V}"),
        ("\uD416", "\\mathbf{W}"),
        ("\uD417", "\\mathbf{X}"),
        ("\uD418", "\\mathbf{Y}"),
        ("\uD419", "\\mathbf{Z}"),
        ("\uD41A", "\\mathbf{a}"),
        ("\uD41B", "\\mathbf{b}"),
        ("\uD41C", "\\mathbf{c}"),
        ("\uD41D", "\\mathbf{d}"),
        ("\uD41E", "\\mathbf{e}"),
        ("\uD41F", "\\mathbf{f}"),
        ("\uD420", "\\mathbf{g}"),
        ("\uD421", "\\mathbf{h}"),
        ("\uD422", "\\mathbf{i}"),
        ("\uD423", "\\mathbf{j}"),
        ("\uD424", "\\mathbf{k}"),
        ("\uD425", "\\mathbf{l}"),
        ("\uD426", "\\mathbf{m}"),
        ("\uD427", "\\mathbf{n}"),
        ("\uD428", "\\mathbf{o}"),
        ("\uD429", "\\mathbf{p}"),
        ("\uD42A", "\\mathbf{q}"),
        ("\uD42B", "\\mathbf{r}"),
        ("\uD42C", "\\mathbf{s}"),
        ("\uD42D", "\\mathbf{t}"),
        ("\uD42E", "\\mathbf{u}"),
        ("\uD42F", "\\mathbf{v}"),
        ("\uD430", "\\mathbf{w}"),
        ("\uD431", "\\mathbf{x}"),
        ("\uD432", "\\mathbf{y}"),
        ("\uD433", "\\mathbf{z}"),
        ("\uD434", "\\mathsl{A}"),
        ("\uD435", "\\mathsl{B}"),
        ("\uD436", "\\mathsl{C}"),
        ("\uD437", "\\mathsl{D}"),
        ("\uD438", "\\mathsl{E}"),
        ("\uD439", "\\mathsl{F}"),
        ("\uD43A", "\\mathsl{G}"),
        ("\uD43B", "\\mathsl{H}"),
        ("\uD43C", "\\mathsl{I}"),
        ("\uD43D", "\\mathsl{J}"),
        ("\uD43E", "\\mathsl{K}"),
        ("\uD43F", "\\mathsl{L}"),
        ("\uD440", "\\mathsl{M}"),
        ("\uD441", "\\mathsl{N}"),
        ("\uD442", "\\mathsl{O}"),
        ("\uD443", "\\mathsl{P}"),
        ("\uD444", "\\mathsl{Q}"),
        ("\uD445", "\\mathsl{R}"),
        ("\uD446", "\\mathsl{S}"),
        ("\uD447", "\\mathsl{T}"),
        ("\uD448", "\\mathsl{U}"),
        ("\uD449", "\\mathsl{V}"),
        ("\uD44A", "\\mathsl{W}"),
        ("\uD44B", "\\mathsl{X}"),
        ("\uD44C", "\\mathsl{Y}"),
        ("\uD44D", "\\mathsl{Z}"),
        ("\uD44E", "\\mathsl{a}"),
        ("\uD44F", "\\mathsl{b}"),
        ("\uD450", "\\mathsl{c}"),
        ("\uD451", "\\mathsl{d}"),
        ("\uD452", "\\mathsl{e}"),
        ("\uD453", "\\mathsl{f}"),
        ("\uD454", "\\mathsl{g}"),
        ("\uD456", "\\mathsl{i}"),
        ("\uD457", "\\mathsl{j}"),
        ("\uD458", "\\mathsl{k}"),
        ("\uD459", "\\mathsl{l}"),
        ("\uD45A", "\\mathsl{m}"),
        ("\uD45B", "\\mathsl{n}"),
        ("\uD45C", "\\mathsl{o}"),
        ("\uD45D", "\\mathsl{p}"),
        ("\uD45E", "\\mathsl{q}"),
        ("\uD45F", "\\mathsl{r}"),
        ("\uD460", "\\mathsl{s}"),
        ("\uD461", "\\mathsl{t}"),
        ("\uD462", "\\mathsl{u}"),
        ("\uD463", "\\mathsl{v}"),
        ("\uD464", "\\mathsl{w}"),
        ("\uD465", "\\mathsl{x}"),
        ("\uD466", "\\mathsl{y}"),
        ("\uD467", "\\mathsl{z}"),
        ("\uD468", "\\mathbit{A}"),
        ("\uD469", "\\mathbit{B}"),
        ("\uD46A", "\\mathbit{C}"),
        ("\uD46B", "\\mathbit{D}"),
        ("\uD46C", "\\mathbit{E}"),
        ("\uD46D", "\\mathbit{F}"),
        ("\uD46E", "\\mathbit{G}"),
        ("\uD46F", "\\mathbit{H}"),
        ("\uD470", "\\mathbit{I}"),
        ("\uD471", "\\mathbit{J}"),
        ("\uD472", "\\mathbit{K}"),
        ("\uD473", "\\mathbit{L}"),
        ("\uD474", "\\mathbit{M}"),
        ("\uD475", "\\mathbit{N}"),
        ("\uD476", "\\mathbit{O}"),
        ("\uD477", "\\mathbit{P}"),
        ("\uD478", "\\mathbit{Q}"),
        ("\uD479", "\\mathbit{R}"),
        ("\uD47A", "\\mathbit{S}"),
        ("\uD47B", "\\mathbit{T}"),
        ("\uD47C", "\\mathbit{U}"),
        ("\uD47D", "\\mathbit{V}"),
        ("\uD47E", "\\mathbit{W}"),
        ("\uD47F", "\\mathbit{X}"),
        ("\uD480", "\\mathbit{Y}"),
        ("\uD481", "\\mathbit{Z}"),
        ("\uD482", "\\mathbit{a}"),
        ("\uD483", "\\mathbit{b}"),
        ("\uD484", "\\mathbit{c}"),
        ("\uD485", "\\mathbit{d}"),
        ("\uD486", "\\mathbit{e}"),
        ("\uD487", "\\mathbit{f}"),
        ("\uD488", "\\mathbit{g}"),
        ("\uD489", "\\mathbit{h}"),
        ("\uD48A", "\\mathbit{i}"),
        ("\uD48B", "\\mathbit{j}"),
        ("\uD48C", "\\mathbit{k}"),
        ("\uD48D", "\\mathbit{l}"),
        ("\uD48E", "\\mathbit{m}"),
        ("\uD48F", "\\mathbit{n}"),
        ("\uD490", "\\mathbit{o}"),
        ("\uD491", "\\mathbit{p}"),
        ("\uD492", "\\mathbit{q}"),
        ("\uD493", "\\mathbit{r}"),
        ("\uD494", "\\mathbit{s}"),
        ("\uD495", "\\mathbit{t}"),
        ("\uD496", "\\mathbit{u}"),
        ("\uD497", "\\mathbit{v}"),
        ("\uD498", "\\mathbit{w}"),
        ("\uD499", "\\mathbit{x}"),
        ("\uD49A", "\\mathbit{y}"),
        ("\uD49B", "\\mathbit{z}"),
        ("\uD49C", "\\mathscr{A}"),
        ("\uD49E", "\\mathscr{C}"),
        ("\uD49F", "\\mathscr{D}"),
        ("\uD4A2", "\\mathscr{G}"),
        ("\uD4A5", "\\mathscr{J}"),
        ("\uD4A6", "\\mathscr{K}"),
        ("\uD4A9", "\\mathscr{N}"),
        ("\uD4AA", "\\mathscr{O}"),
        ("\uD4AB", "\\mathscr{P}"),
        ("\uD4AC", "\\mathscr{Q}"),
        ("\uD4AE", "\\mathscr{S}"),
        ("\uD4AF", "\\mathscr{T}"),
        ("\uD4B0", "\\mathscr{U}"),
        ("\uD4B1", "\\mathscr{V}"),
        ("\uD4B2", "\\mathscr{W}"),
        ("\uD4B3", "\\mathscr{X}"),
        ("\uD4B4", "\\mathscr{Y}"),
        ("\uD4B5", "\\mathscr{Z}"),
        ("\uD4B6", "\\mathscr{a}"),
        ("\uD4B7", "\\mathscr{b}"),
        ("\uD4B8", "\\mathscr{c}"),
        ("\uD4B9", "\\mathscr{d}"),
        ("\uD4BB", "\\mathscr{f}"),
        ("\uD4BD", "\\mathscr{h}"),
        ("\uD4BE", "\\mathscr{i}"),
        ("\uD4BF", "\\mathscr{j}"),
        ("\uD4C0", "\\mathscr{k}"),
        ("\uD4C1", "\\mathscr{l}"),
        ("\uD4C2", "\\mathscr{m}"),
        ("\uD4C3", "\\mathscr{n}"),
        ("\uD4C5", "\\mathscr{p}"),
        ("\uD4C6", "\\mathscr{q}"),
        ("\uD4C7", "\\mathscr{r}"),
        ("\uD4C8", "\\mathscr{s}"),
        ("\uD4C9", "\\mathscr{t}"),
        ("\uD4CA", "\\mathscr{u}"),
        ("\uD4CB", "\\mathscr{v}"),
        ("\uD4CC", "\\mathscr{w}"),
        ("\uD4CD", "\\mathscr{x}"),
        ("\uD4CE", "\\mathscr{y}"),
        ("\uD4CF", "\\mathscr{z}"),
        ("\uD4D0", "\\mathmit{A}"),
        ("\uD4D1", "\\mathmit{B}"),
        ("\uD4D2", "\\mathmit{C}"),
        ("\uD4D3", "\\mathmit{D}"),
        ("\uD4D4", "\\mathmit{E}"),
        ("\uD4D5", "\\mathmit{F}"),
        ("\uD4D6", "\\mathmit{G}"),
        ("\uD4D7", "\\mathmit{H}"),
        ("\uD4D8", "\\mathmit{I}"),
        ("\uD4D9", "\\mathmit{J}"),
        ("\uD4DA", "\\mathmit{K}"),
        ("\uD4DB", "\\mathmit{L}"),
        ("\uD4DC", "\\mathmit{M}"),
        ("\uD4DD", "\\mathmit{N}"),
        ("\uD4DE", "\\mathmit{O}"),
        ("\uD4DF", "\\mathmit{P}"),
        ("\uD4E0", "\\mathmit{Q}"),
        ("\uD4E1", "\\mathmit{R}"),
        ("\uD4E2", "\\mathmit{S}"),
        ("\uD4E3", "\\mathmit{T}"),
        ("\uD4E4", "\\mathmit{U}"),
        ("\uD4E5", "\\mathmit{V}"),
        ("\uD4E6", "\\mathmit{W}"),
        ("\uD4E7", "\\mathmit{X}"),
        ("\uD4E8", "\\mathmit{Y}"),
        ("\uD4E9", "\\mathmit{Z}"),
        ("\uD4EA", "\\mathmit{a}"),
        ("\uD4EB", "\\mathmit{b}"),
        ("\uD4EC", "\\mathmit{c}"),
        ("\uD4ED", "\\mathmit{d}"),
        ("\uD4EE", "\\mathmit{e}"),
        ("\uD4EF", "\\mathmit{f}"),
        ("\uD4F0", "\\mathmit{g}"),
        ("\uD4F1", "\\mathmit{h}"),
        ("\uD4F2", "\\mathmit{i}"),
        ("\uD4F3", "\\mathmit{j}"),
        ("\uD4F4", "\\mathmit{k}"),
        ("\uD4F5", "\\mathmit{l}"),
        ("\uD4F6", "\\mathmit{m}"),
        ("\uD4F7", "\\mathmit{n}"),
        ("\uD4F8", "\\mathmit{o}"),
        ("\uD4F9", "\\mathmit{p}"),
        ("\uD4FA", "\\mathmit{q}"),
        ("\uD4FB", "\\mathmit{r}"),
        ("\uD4FC", "\\mathmit{s}"),
        ("\uD4FD", "\\mathmit{t}"),
        ("\uD4FE", "\\mathmit{u}"),
        ("\uD4FF", "\\mathmit{v}"),
        ("\uD500", "\\mathmit{w}"),
        ("\uD501", "\\mathmit{x}"),
        ("\uD502", "\\mathmit{y}"),
        ("\uD503", "\\mathmit{z}"),
        ("\uD504", "\\mathfrak{A}"),
        ("\uD505", "\\mathfrak{B}"),
        ("\uD507", "\\mathfrak{D}"),
        ("\uD508", "\\mathfrak{E}"),
        ("\uD509", "\\mathfrak{F}"),
        ("\uD50A", "\\mathfrak{G}"),
        ("\uD50D", "\\mathfrak{J}"),
        ("\uD50E", "\\mathfrak{K}"),
        ("\uD50F", "\\mathfrak{L}"),
        ("\uD510", "\\mathfrak{M}"),
        ("\uD511", "\\mathfrak{N}"),
        ("\uD512", "\\mathfrak{O}"),
        ("\uD513", "\\mathfrak{P}"),
        ("\uD514", "\\mathfrak{Q}"),
        ("\uD516", "\\mathfrak{S}"),
        ("\uD517", "\\mathfrak{T}"),
        ("\uD518", "\\mathfrak{U}"),
        ("\uD519", "\\mathfrak{V}"),
        ("\uD51A", "\\mathfrak{W}"),
        ("\uD51B", "\\mathfrak{X}"),
        ("\uD51C", "\\mathfrak{Y}"),
        ("\uD51E", "\\mathfrak{a}"),
        ("\uD51F", "\\mathfrak{b}"),
        ("\uD520", "\\mathfrak{c}"),
        ("\uD521", "\\mathfrak{d}"),
        ("\uD522", "\\mathfrak{e}"),
        ("\uD523", "\\mathfrak{f}"),
        ("\uD524", "\\mathfrak{g}"),
        ("\uD525", "\\mathfrak{h}"),
        ("\uD526", "\\mathfrak{i}"),
        ("\uD527", "\\mathfrak{j}"),
        ("\uD528", "\\mathfrak{k}"),
        ("\uD529", "\\mathfrak{l}"),
        ("\uD52A", "\\mathfrak{m}"),
        ("\uD52B", "\\mathfrak{n}"),
        ("\uD52C", "\\mathfrak{o}"),
        ("\uD52D", "\\mathfrak{p}"),
        ("\uD52E", "\\mathfrak{q}"),
        ("\uD52F", "\\mathfrak{r}"),
        ("\uD530", "\\mathfrak{s}"),
        ("\uD531", "\\mathfrak{t}"),
        ("\uD532", "\\mathfrak{u}"),
        ("\uD533", "\\mathfrak{v}"),
        ("\uD534", "\\mathfrak{w}"),
        ("\uD535", "\\mathfrak{x}"),
        ("\uD536", "\\mathfrak{y}"),
        ("\uD537", "\\mathfrak{z}"),
        ("\uD538", "\\mathbb{A}"),
        ("\uD539", "\\mathbb{B}"),
        ("\uD53B", "\\mathbb{D}"),
        ("\uD53C", "\\mathbb{E}"),
        ("\uD53D", "\\mathbb{F}"),
        ("\uD53E", "\\mathbb{G}"),
        ("\uD540", "\\mathbb{I}"),
        ("\uD541", "\\mathbb{J}"),
        ("\uD542", "\\mathbb{K}"),
        ("\uD543", "\\mathbb{L}"),
        ("\uD544", "\\mathbb{M}"),
        ("\uD546", "\\mathbb{O}"),
        ("\uD54A", "\\mathbb{S}"),
        ("\uD54B", "\\mathbb{T}"),
        ("\uD54C", "\\mathbb{U}"),
        ("\uD54D", "\\mathbb{V}"),
        ("\uD54E", "\\mathbb{W}"),
        ("\uD54F", "\\mathbb{X}"),
        ("\uD550", "\\mathbb{Y}"),
        ("\uD552", "\\mathbb{a}"),
        ("\uD553", "\\mathbb{b}"),
        ("\uD554", "\\mathbb{c}"),
        ("\uD555", "\\mathbb{d}"),
        ("\uD556", "\\mathbb{e}"),
        ("\uD557", "\\mathbb{f}"),
        ("\uD558", "\\mathbb{g}"),
        ("\uD559", "\\mathbb{h}"),
        ("\uD55A", "\\mathbb{i}"),
        ("\uD55B", "\\mathbb{j}"),
        ("\uD55C", "\\mathbb{k}"),
        ("\uD55D", "\\mathbb{l}"),
        ("\uD55E", "\\mathbb{m}"),
        ("\uD55F", "\\mathbb{n}"),
        ("\uD560", "\\mathbb{o}"),
        ("\uD561", "\\mathbb{p}"),
        ("\uD562", "\\mathbb{q}"),
        ("\uD563", "\\mathbb{r}"),
        ("\uD564", "\\mathbb{s}"),
        ("\uD565", "\\mathbb{t}"),
        ("\uD566", "\\mathbb{u}"),
        ("\uD567", "\\mathbb{v}"),
        ("\uD568", "\\mathbb{w}"),
        ("\uD569", "\\mathbb{x}"),
        ("\uD56A", "\\mathbb{y}"),
        ("\uD56B", "\\mathbb{z}"),
        ("\uD56C", "\\mathslbb{A}"),
        ("\uD56D", "\\mathslbb{B}"),
        ("\uD56E", "\\mathslbb{C}"),
        ("\uD56F", "\\mathslbb{D}"),
        ("\uD570", "\\mathslbb{E}"),
        ("\uD571", "\\mathslbb{F}"),
        ("\uD572", "\\mathslbb{G}"),
        ("\uD573", "\\mathslbb{H}"),
        ("\uD574", "\\mathslbb{I}"),
        ("\uD575", "\\mathslbb{J}"),
        ("\uD576", "\\mathslbb{K}"),
        ("\uD577", "\\mathslbb{L}"),
        ("\uD578", "\\mathslbb{M}"),
        ("\uD579", "\\mathslbb{N}"),
        ("\uD57A", "\\mathslbb{O}"),
        ("\uD57B", "\\mathslbb{P}"),
        ("\uD57C", "\\mathslbb{Q}"),
        ("\uD57D", "\\mathslbb{R}"),
        ("\uD57E", "\\mathslbb{S}"),
        ("\uD57F", "\\mathslbb{T}"),
        ("\uD580", "\\mathslbb{U}"),
        ("\uD581", "\\mathslbb{V}"),
        ("\uD582", "\\mathslbb{W}"),
        ("\uD583", "\\mathslbb{X}"),
        ("\uD584", "\\mathslbb{Y}"),
        ("\uD585", "\\mathslbb{Z}"),
        ("\uD586", "\\mathslbb{a}"),
        ("\uD587", "\\mathslbb{b}"),
        ("\uD588", "\\mathslbb{c}"),
        ("\uD589", "\\mathslbb{d}"),
        ("\uD58A", "\\mathslbb{e}"),
        ("\uD58B", "\\mathslbb{f}"),
        ("\uD58C", "\\mathslbb{g}"),
        ("\uD58D", "\\mathslbb{h}"),
        ("\uD58E", "\\mathslbb{i}"),
        ("\uD58F", "\\mathslbb{j}"),
        ("\uD590", "\\mathslbb{k}"),
        ("\uD591", "\\mathslbb{l}"),
        ("\uD592", "\\mathslbb{m}"),
        ("\uD593", "\\mathslbb{n}"),
        ("\uD594", "\\mathslbb{o}"),
        ("\uD595", "\\mathslbb{p}"),
        ("\uD596", "\\mathslbb{q}"),
        ("\uD597", "\\mathslbb{r}"),
        ("\uD598", "\\mathslbb{s}"),
        ("\uD599", "\\mathslbb{t}"),
        ("\uD59A", "\\mathslbb{u}"),
        ("\uD59B", "\\mathslbb{v}"),
        ("\uD59C", "\\mathslbb{w}"),
        ("\uD59D", "\\mathslbb{x}"),
        ("\uD59E", "\\mathslbb{y}"),
        ("\uD59F", "\\mathslbb{z}"),
        ("\uD5A0", "\\mathsf{A}"),
        ("\uD5A1", "\\mathsf{B}"),
        ("\uD5A2", "\\mathsf{C}"),
        ("\uD5A3", "\\mathsf{D}"),
        ("\uD5A4", "\\mathsf{E}"),
        ("\uD5A5", "\\mathsf{F}"),
        ("\uD5A6", "\\mathsf{G}"),
        ("\uD5A7", "\\mathsf{H}"),
        ("\uD5A8", "\\mathsf{I}"),
        ("\uD5A9", "\\mathsf{J}"),
        ("\uD5AA", "\\mathsf{K}"),
        ("\uD5AB", "\\mathsf{L}"),
        ("\uD5AC", "\\mathsf{M}"),
        ("\uD5AD", "\\mathsf{N}"),
        ("\uD5AE", "\\mathsf{O}"),
        ("\uD5AF", "\\mathsf{P}"),
        ("\uD5B0", "\\mathsf{Q}"),
        ("\uD5B1", "\\mathsf{R}"),
        ("\uD5B2", "\\mathsf{S}"),
        ("\uD5B3", "\\mathsf{T}"),
        ("\uD5B4", "\\mathsf{U}"),
        ("\uD5B5", "\\mathsf{V}"),
        ("\uD5B6", "\\mathsf{W}"),
        ("\uD5B7", "\\mathsf{X}"),
        ("\uD5B8", "\\mathsf{Y}"),
        ("\uD5B9", "\\mathsf{Z}"),
        ("\uD5BA", "\\mathsf{a}"),
        ("\uD5BB", "\\mathsf{b}"),
        ("\uD5BC", "\\mathsf{c}"),
        ("\uD5BD", "\\mathsf{d}"),
        ("\uD5BE", "\\mathsf{e}"),
        ("\uD5BF", "\\mathsf{f}"),
        ("\uD5C0", "\\mathsf{g}"),
        ("\uD5C1", "\\mathsf{h}"),
        ("\uD5C2", "\\mathsf{i}"),
        ("\uD5C3", "\\mathsf{j}"),
        ("\uD5C4", "\\mathsf{k}"),
        ("\uD5C5", "\\mathsf{l}"),
        ("\uD5C6", "\\mathsf{m}"),
        ("\uD5C7", "\\mathsf{n}"),
        ("\uD5C8", "\\mathsf{o}"),
        ("\uD5C9", "\\mathsf{p}"),
        ("\uD5CA", "\\mathsf{q}"),
        ("\uD5CB", "\\mathsf{r}"),
        ("\uD5CC", "\\mathsf{s}"),
        ("\uD5CD", "\\mathsf{t}"),
        ("\uD5CE", "\\mathsf{u}"),
        ("\uD5CF", "\\mathsf{v}"),
        ("\uD5D0", "\\mathsf{w}"),
        ("\uD5D1", "\\mathsf{x}"),
        ("\uD5D2", "\\mathsf{y}"),
        ("\uD5D3", "\\mathsf{z}"),
        ("\uD5D4", "\\mathsfbf{A}"),
        ("\uD5D5", "\\mathsfbf{B}"),
        ("\uD5D6", "\\mathsfbf{C}"),
        ("\uD5D7", "\\mathsfbf{D}"),
        ("\uD5D8", "\\mathsfbf{E}"),
        ("\uD5D9", "\\mathsfbf{F}"),
        ("\uD5DA", "\\mathsfbf{G}"),
        ("\uD5DB", "\\mathsfbf{H}"),
        ("\uD5DC", "\\mathsfbf{I}"),
        ("\uD5DD", "\\mathsfbf{J}"),
        ("\uD5DE", "\\mathsfbf{K}"),
        ("\uD5DF", "\\mathsfbf{L}"),
        ("\uD5E0", "\\mathsfbf{M}"),
        ("\uD5E1", "\\mathsfbf{N}"),
        ("\uD5E2", "\\mathsfbf{O}"),
        ("\uD5E3", "\\mathsfbf{P}"),
        ("\uD5E4", "\\mathsfbf{Q}"),
        ("\uD5E5", "\\mathsfbf{R}"),
        ("\uD5E6", "\\mathsfbf{S}"),
        ("\uD5E7", "\\mathsfbf{T}"),
        ("\uD5E8", "\\mathsfbf{U}"),
        ("\uD5E9", "\\mathsfbf{V}"),
        ("\uD5EA", "\\mathsfbf{W}"),
        ("\uD5EB", "\\mathsfbf{X}"),
        ("\uD5EC", "\\mathsfbf{Y}"),
        ("\uD5ED", "\\mathsfbf{Z}"),
        ("\uD5EE", "\\mathsfbf{a}"),
        ("\uD5EF", "\\mathsfbf{b}"),
        ("\uD5F0", "\\mathsfbf{c}"),
        ("\uD5F1", "\\mathsfbf{d}"),
        ("\uD5F2", "\\mathsfbf{e}"),
        ("\uD5F3", "\\mathsfbf{f}"),
        ("\uD5F4", "\\mathsfbf{g}"),
        ("\uD5F5", "\\mathsfbf{h}"),
        ("\uD5F6", "\\mathsfbf{i}"),
        ("\uD5F7", "\\mathsfbf{j}"),
        ("\uD5F8", "\\mathsfbf{k}"),
        ("\uD5F9", "\\mathsfbf{l}"),
        ("\uD5FA", "\\mathsfbf{m}"),
        ("\uD5FB", "\\mathsfbf{n}"),
        ("\uD5FC", "\\mathsfbf{o}"),
        ("\uD5FD", "\\mathsfbf{p}"),
        ("\uD5FE", "\\mathsfbf{q}"),
        ("\uD5FF", "\\mathsfbf{r}"),
        ("\uD600", "\\mathsfbf{s}"),
        ("\uD601", "\\mathsfbf{t}"),
        ("\uD602", "\\mathsfbf{u}"),
        ("\uD603", "\\mathsfbf{v}"),
        ("\uD604", "\\mathsfbf{w}"),
        ("\uD605", "\\mathsfbf{x}"),
        ("\uD606", "\\mathsfbf{y}"),
        ("\uD607", "\\mathsfbf{z}"),
        ("\uD608", "\\mathsfsl{A}"),
        ("\uD609", "\\mathsfsl{B}"),
        ("\uD60A", "\\mathsfsl{C}"),
        ("\uD60B", "\\mathsfsl{D}"),
        ("\uD60C", "\\mathsfsl{E}"),
        ("\uD60D", "\\mathsfsl{F}"),
        ("\uD60E", "\\mathsfsl{G}"),
        ("\uD60F", "\\mathsfsl{H}"),
        ("\uD610", "\\mathsfsl{I}"),
        ("\uD611", "\\mathsfsl{J}"),
        ("\uD612", "\\mathsfsl{K}"),
        ("\uD613", "\\mathsfsl{L}"),
        ("\uD614", "\\mathsfsl{M}"),
        ("\uD615", "\\mathsfsl{N}"),
        ("\uD616", "\\mathsfsl{O}"),
        ("\uD617", "\\mathsfsl{P}"),
        ("\uD618", "\\mathsfsl{Q}"),
        ("\uD619", "\\mathsfsl{R}"),
        ("\uD61A", "\\mathsfsl{S}"),
        ("\uD61B", "\\mathsfsl{T}"),
        ("\uD61C", "\\mathsfsl{U}"),
        ("\uD61D", "\\mathsfsl{V}"),
        ("\uD61E", "\\mathsfsl{W}"),
        ("\uD61F", "\\mathsfsl{X}"),
        ("\uD620", "\\mathsfsl{Y}"),
        ("\uD621", "\\mathsfsl{Z}"),
        ("\uD622", "\\mathsfsl{a}"),
        ("\uD623", "\\mathsfsl{b}"),
        ("\uD624", "\\mathsfsl{c}"),
        ("\uD625", "\\mathsfsl{d}"),
        ("\uD626", "\\mathsfsl{e}"),
        ("\uD627", "\\mathsfsl{f}"),
        ("\uD628", "\\mathsfsl{g}"),
        ("\uD629", "\\mathsfsl{h}"),
        ("\uD62A", "\\mathsfsl{i}"),
        ("\uD62B", "\\mathsfsl{j}"),
        ("\uD62C", "\\mathsfsl{k}"),
        ("\uD62D", "\\mathsfsl{l}"),
        ("\uD62E", "\\mathsfsl{m}"),
        ("\uD62F", "\\mathsfsl{n}"),
        ("\uD630", "\\mathsfsl{o}"),
        ("\uD631", "\\mathsfsl{p}"),
        ("\uD632", "\\mathsfsl{q}"),
        ("\uD633", "\\mathsfsl{r}"),
        ("\uD634", "\\mathsfsl{s}"),
        ("\uD635", "\\mathsfsl{t}"),
        ("\uD636", "\\mathsfsl{u}"),
        ("\uD637", "\\mathsfsl{v}"),
        ("\uD638", "\\mathsfsl{w}"),
        ("\uD639", "\\mathsfsl{x}"),
        ("\uD63A", "\\mathsfsl{y}"),
        ("\uD63B", "\\mathsfsl{z}"),
        ("\uD63C", "\\mathsfbfsl{A}"),
        ("\uD63D", "\\mathsfbfsl{B}"),
        ("\uD63E", "\\mathsfbfsl{C}"),
        ("\uD63F", "\\mathsfbfsl{D}"),
        ("\uD640", "\\mathsfbfsl{E}"),
        ("\uD641", "\\mathsfbfsl{F}"),
        ("\uD642", "\\mathsfbfsl{G}"),
        ("\uD643", "\\mathsfbfsl{H}"),
        ("\uD644", "\\mathsfbfsl{I}"),
        ("\uD645", "\\mathsfbfsl{J}"),
        ("\uD646", "\\mathsfbfsl{K}"),
        ("\uD647", "\\mathsfbfsl{L}"),
        ("\uD648", "\\mathsfbfsl{M}"),
        ("\uD649", "\\mathsfbfsl{N}"),
        ("\uD64A", "\\mathsfbfsl{O}"),
        ("\uD64B", "\\mathsfbfsl{P}"),
        ("\uD64C", "\\mathsfbfsl{Q}"),
        ("\uD64D", "\\mathsfbfsl{R}"),
        ("\uD64E", "\\mathsfbfsl{S}"),
        ("\uD64F", "\\mathsfbfsl{T}"),
        ("\uD650", "\\mathsfbfsl{U}"),
        ("\uD651", "\\mathsfbfsl{V}"),
        ("\uD652", "\\mathsfbfsl{W}"),
        ("\uD653", "\\mathsfbfsl{X}"),
        ("\uD654", "\\mathsfbfsl{Y}"),
        ("\uD655", "\\mathsfbfsl{Z}"),
        ("\uD656", "\\mathsfbfsl{a}"),
        ("\uD657", "\\mathsfbfsl{b}"),
        ("\uD658", "\\mathsfbfsl{c}"),
        ("\uD659", "\\mathsfbfsl{d}"),
        ("\uD65A", "\\mathsfbfsl{e}"),
        ("\uD65B", "\\mathsfbfsl{f}"),
        ("\uD65C", "\\mathsfbfsl{g}"),
        ("\uD65D", "\\mathsfbfsl{h}"),
        ("\uD65E", "\\mathsfbfsl{i}"),
        ("\uD65F", "\\mathsfbfsl{j}"),
        ("\uD660", "\\mathsfbfsl{k}"),
        ("\uD661", "\\mathsfbfsl{l}"),
        ("\uD662", "\\mathsfbfsl{m}"),
        ("\uD663", "\\mathsfbfsl{n}"),
        ("\uD664", "\\mathsfbfsl{o}"),
        ("\uD665", "\\mathsfbfsl{p}"),
        ("\uD666", "\\mathsfbfsl{q}"),
        ("\uD667", "\\mathsfbfsl{r}"),
        ("\uD668", "\\mathsfbfsl{s}"),
        ("\uD669", "\\mathsfbfsl{t}"),
        ("\uD66A", "\\mathsfbfsl{u}"),
        ("\uD66B", "\\mathsfbfsl{v}"),
        ("\uD66C", "\\mathsfbfsl{w}"),
        ("\uD66D", "\\mathsfbfsl{x}"),
        ("\uD66E", "\\mathsfbfsl{y}"),
        ("\uD66F", "\\mathsfbfsl{z}"),
        ("\uD670", "\\mathtt{A}"),
        ("\uD671", "\\mathtt{B}"),
        ("\uD672", "\\mathtt{C}"),
        ("\uD673", "\\mathtt{D}"),
        ("\uD674", "\\mathtt{E}"),
        ("\uD675", "\\mathtt{F}"),
        ("\uD676", "\\mathtt{G}"),
        ("\uD677", "\\mathtt{H}"),
        ("\uD678", "\\mathtt{I}"),
        ("\uD679", "\\mathtt{J}"),
        ("\uD67A", "\\mathtt{K}"),
        ("\uD67B", "\\mathtt{L}"),
        ("\uD67C", "\\mathtt{M}"),
        ("\uD67D", "\\mathtt{N}"),
        ("\uD67E", "\\mathtt{O}"),
        ("\uD67F", "\\mathtt{P}"),
        ("\uD680", "\\mathtt{Q}"),
        ("\uD681", "\\mathtt{R}"),
        ("\uD682", "\\mathtt{S}"),
        ("\uD683", "\\mathtt{T}"),
        ("\uD684", "\\mathtt{U}"),
        ("\uD685", "\\mathtt{V}"),
        ("\uD686", "\\mathtt{W}"),
        ("\uD687", "\\mathtt{X}"),
        ("\uD688", "\\mathtt{Y}"),
        ("\uD689", "\\mathtt{Z}"),
        ("\uD68A", "\\mathtt{a}"),
        ("\uD68B", "\\mathtt{b}"),
        ("\uD68C", "\\mathtt{c}"),
        ("\uD68D", "\\mathtt{d}"),
        ("\uD68E", "\\mathtt{e}"),
        ("\uD68F", "\\mathtt{f}"),
        ("\uD690", "\\mathtt{g}"),
        ("\uD691", "\\mathtt{h}"),
        ("\uD692", "\\mathtt{i}"),
        ("\uD693", "\\mathtt{j}"),
        ("\uD694", "\\mathtt{k}"),
        ("\uD695", "\\mathtt{l}"),
        ("\uD696", "\\mathtt{m}"),
        ("\uD697", "\\mathtt{n}"),
        ("\uD698", "\\mathtt{o}"),
        ("\uD699", "\\mathtt{p}"),
        ("\uD69A", "\\mathtt{q}"),
        ("\uD69B", "\\mathtt{r}"),
        ("\uD69C", "\\mathtt{s}"),
        ("\uD69D", "\\mathtt{t}"),
        ("\uD69E", "\\mathtt{u}"),
        ("\uD69F", "\\mathtt{v}"),
        ("\uD6A0", "\\mathtt{w}"),
        ("\uD6A1", "\\mathtt{x}"),
        ("\uD6A2", "\\mathtt{y}"),
        ("\uD6A3", "\\mathtt{z}"),
        ("\uD6A8", "\\mathbf{\\Alpha}"),
        ("\uD6A9", "\\mathbf{\\Beta}"),
        ("\uD6AA", "\\mathbf{\\Gamma}"),
        ("\uD6AB", "\\mathbf{\\Delta}"),
        ("\uD6AC", "\\mathbf{\\Epsilon}"),
        ("\uD6AD", "\\mathbf{\\Zeta}"),
        ("\uD6AE", "\\mathbf{\\Eta}"),
        ("\uD6AF", "\\mathbf{\\Theta}"),
        ("\uD6B0", "\\mathbf{\\Iota}"),
        ("\uD6B1", "\\mathbf{\\Kappa}"),
        ("\uD6B2", "\\mathbf{\\Lambda}"),
        ("\uD6B5", "\\mathbf{\\Xi}"),
        ("\uD6B7", "\\mathbf{\\Pi}"),
        ("\uD6B8", "\\mathbf{\\Rho}"),
        ("\uD6B9", "\\mathbf{\\vartheta}"),
        ("\uD6BA", "\\mathbf{\\Sigma}"),
        ("\uD6BB", "\\mathbf{\\Tau}"),
        ("\uD6BC", "\\mathbf{\\Upsilon}"),
        ("\uD6BD", "\\mathbf{\\Phi}"),
        ("\uD6BE", "\\mathbf{\\Chi}"),
        ("\uD6BF", "\\mathbf{\\Psi}"),
        ("\uD6C0", "\\mathbf{\\Omega}"),
        ("\uD6C1", "\\mathbf{\\nabla}"),
        ("\uD6C2", "\\mathbf{\\Alpha}"),
        ("\uD6C3", "\\mathbf{\\Beta}"),
        ("\uD6C4", "\\mathbf{\\Gamma}"),
        ("\uD6C5", "\\mathbf{\\Delta}"),
        ("\uD6C6", "\\mathbf{\\Epsilon}"),
        ("\uD6C7", "\\mathbf{\\Zeta}"),
        ("\uD6C8", "\\mathbf{\\Eta}"),
        ("\uD6C9", "\\mathbf{\\theta}"),
        ("\uD6CA", "\\mathbf{\\Iota}"),
        ("\uD6CB", "\\mathbf{\\Kappa}"),
        ("\uD6CC", "\\mathbf{\\Lambda}"),
        ("\uD6CF", "\\mathbf{\\Xi}"),
        ("\uD6D1", "\\mathbf{\\Pi}"),
        ("\uD6D2", "\\mathbf{\\Rho}"),
        ("\uD6D3", "\\mathbf{\\varsigma}"),
        ("\uD6D4", "\\mathbf{\\Sigma}"),
        ("\uD6D5", "\\mathbf{\\Tau}"),
        ("\uD6D6", "\\mathbf{\\Upsilon}"),
        ("\uD6D7", "\\mathbf{\\Phi}"),
        ("\uD6D8", "\\mathbf{\\Chi}"),
        ("\uD6D9", "\\mathbf{\\Psi}"),
        ("\uD6DA", "\\mathbf{\\Omega}"),
        ("\uD6DB", "\\partial "),
        ("\uD6DC", "\\in"),
        ("\uD6DD", "\\mathbf{\\vartheta}"),
        ("\uD6DE", "\\mathbf{\\varkappa}"),
        ("\uD6DF", "\\mathbf{\\phi}"),
        ("\uD6E0", "\\mathbf{\\varrho}"),
        ("\uD6E1", "\\mathbf{\\varpi}"),
        ("\uD6E2", "\\mathsl{\\Alpha}"),
        ("\uD6E3", "\\mathsl{\\Beta}"),
        ("\uD6E4", "\\mathsl{\\Gamma}"),
        ("\uD6E5", "\\mathsl{\\Delta}"),
        ("\uD6E6", "\\mathsl{\\Epsilon}"),
        ("\uD6E7", "\\mathsl{\\Zeta}"),
        ("\uD6E8", "\\mathsl{\\Eta}"),
        ("\uD6E9", "\\mathsl{\\Theta}"),
        ("\uD6EA", "\\mathsl{\\Iota}"),
        ("\uD6EB", "\\mathsl{\\Kappa}"),
        ("\uD6EC", "\\mathsl{\\Lambda}"),
        ("\uD6EF", "\\mathsl{\\Xi}"),
        ("\uD6F1", "\\mathsl{\\Pi}"),
        ("\uD6F2", "\\mathsl{\\Rho}"),
        ("\uD6F3", "\\mathsl{\\vartheta}"),
        ("\uD6F4", "\\mathsl{\\Sigma}"),
        ("\uD6F5", "\\mathsl{\\Tau}"),
        ("\uD6F6", "\\mathsl{\\Upsilon}"),
        ("\uD6F7", "\\mathsl{\\Phi}"),
        ("\uD6F8", "\\mathsl{\\Chi}"),
        ("\uD6F9", "\\mathsl{\\Psi}"),
        ("\uD6FA", "\\mathsl{\\Omega}"),
        ("\uD6FB", "\\mathsl{\\nabla}"),
        ("\uD6FC", "\\mathsl{\\Alpha}"),
        ("\uD6FD", "\\mathsl{\\Beta}"),
        ("\uD6FE", "\\mathsl{\\Gamma}"),
        ("\uD6FF", "\\mathsl{\\Delta}"),
        ("\uD700", "\\mathsl{\\Epsilon}"),
        ("\uD701", "\\mathsl{\\Zeta}"),
        ("\uD702", "\\mathsl{\\Eta}"),
        ("\uD703", "\\mathsl{\\Theta}"),
        ("\uD704", "\\mathsl{\\Iota}"),
        ("\uD705", "\\mathsl{\\Kappa}"),
        ("\uD706", "\\mathsl{\\Lambda}"),
        ("\uD709", "\\mathsl{\\Xi}"),
        ("\uD70B", "\\mathsl{\\Pi}"),
        ("\uD70C", "\\mathsl{\\Rho}"),
        ("\uD70D", "\\mathsl{\\varsigma}"),
        ("\uD70E", "\\mathsl{\\Sigma}"),
        ("\uD70F", "\\mathsl{\\Tau}"),
        ("\uD710", "\\mathsl{\\Upsilon}"),
        ("\uD711", "\\mathsl{\\Phi}"),
        ("\uD712", "\\mathsl{\\Chi}"),
        ("\uD713", "\\mathsl{\\Psi}"),
        ("\uD714", "\\mathsl{\\Omega}"),
        ("\uD715", "\\partial "),
        ("\uD716", "\\in"),
        ("\uD717", "\\mathsl{\\vartheta}"),
        ("\uD718", "\\mathsl{\\varkappa}"),
        ("\uD719", "\\mathsl{\\phi}"),
        ("\uD71A", "\\mathsl{\\varrho}"),
        ("\uD71B", "\\mathsl{\\varpi}"),
        ("\uD71C", "\\mathbit{\\Alpha}"),
        ("\uD71D", "\\mathbit{\\Beta}"),
        ("\uD71E", "\\mathbit{\\Gamma}"),
        ("\uD71F", "\\mathbit{\\Delta}"),
        ("\uD720", "\\mathbit{\\Epsilon}"),
        ("\uD721", "\\mathbit{\\Zeta}"),
        ("\uD722", "\\mathbit{\\Eta}"),
        ("\uD723", "\\mathbit{\\Theta}"),
        ("\uD724", "\\mathbit{\\Iota}"),
        ("\uD725", "\\mathbit{\\Kappa}"),
        ("\uD726", "\\mathbit{\\Lambda}"),
        ("\uD729", "\\mathbit{\\Xi}"),
        ("\uD72B", "\\mathbit{\\Pi}"),
        ("\uD72C", "\\mathbit{\\Rho}"),
        ("\uD72D", "\\mathbit{O}"),
        ("\uD72E", "\\mathbit{\\Sigma}"),
        ("\uD72F", "\\mathbit{\\Tau}"),
        ("\uD730", "\\mathbit{\\Upsilon}"),
        ("\uD731", "\\mathbit{\\Phi}"),
        ("\uD732", "\\mathbit{\\Chi}"),
        ("\uD733", "\\mathbit{\\Psi}"),
        ("\uD734", "\\mathbit{\\Omega}"),
        ("\uD735", "\\mathbit{\\nabla}"),
        ("\uD736", "\\mathbit{\\Alpha}"),
        ("\uD737", "\\mathbit{\\Beta}"),
        ("\uD738", "\\mathbit{\\Gamma}"),
        ("\uD739", "\\mathbit{\\Delta}"),
        ("\uD73A", "\\mathbit{\\Epsilon}"),
        ("\uD73B", "\\mathbit{\\Zeta}"),
        ("\uD73C", "\\mathbit{\\Eta}"),
        ("\uD73D", "\\mathbit{\\Theta}"),
        ("\uD73E", "\\mathbit{\\Iota}"),
        ("\uD73F", "\\mathbit{\\Kappa}"),
        ("\uD740", "\\mathbit{\\Lambda}"),
        ("\uD743", "\\mathbit{\\Xi}"),
        ("\uD745", "\\mathbit{\\Pi}"),
        ("\uD746", "\\mathbit{\\Rho}"),
        ("\uD747", "\\mathbit{\\varsigma}"),
        ("\uD748", "\\mathbit{\\Sigma}"),
        ("\uD749", "\\mathbit{\\Tau}"),
        ("\uD74A", "\\mathbit{\\Upsilon}"),
        ("\uD74B", "\\mathbit{\\Phi}"),
        ("\uD74C", "\\mathbit{\\Chi}"),
        ("\uD74D", "\\mathbit{\\Psi}"),
        ("\uD74E", "\\mathbit{\\Omega}"),
        ("\uD74F", "\\partial "),
        ("\uD750", "\\in"),
        ("\uD751", "\\mathbit{\\vartheta}"),
        ("\uD752", "\\mathbit{\\varkappa}"),
        ("\uD753", "\\mathbit{\\phi}"),
        ("\uD754", "\\mathbit{\\varrho}"),
        ("\uD755", "\\mathbit{\\varpi}"),
        ("\uD756", "\\mathsfbf{\\Alpha}"),
        ("\uD757", "\\mathsfbf{\\Beta}"),
        ("\uD758", "\\mathsfbf{\\Gamma}"),
        ("\uD759", "\\mathsfbf{\\Delta}"),
        ("\uD75A", "\\mathsfbf{\\Epsilon}"),
        ("\uD75B", "\\mathsfbf{\\Zeta}"),
        ("\uD75C", "\\mathsfbf{\\Eta}"),
        ("\uD75D", "\\mathsfbf{\\Theta}"),
        ("\uD75E", "\\mathsfbf{\\Iota}"),
        ("\uD75F", "\\mathsfbf{\\Kappa}"),
        ("\uD760", "\\mathsfbf{\\Lambda}"),
        ("\uD763", "\\mathsfbf{\\Xi}"),
        ("\uD765", "\\mathsfbf{\\Pi}"),
        ("\uD766", "\\mathsfbf{\\Rho}"),
        ("\uD767", "\\mathsfbf{\\vartheta}"),
        ("\uD768", "\\mathsfbf{\\Sigma}"),
        ("\uD769", "\\mathsfbf{\\Tau}"),
        ("\uD76A", "\\mathsfbf{\\Upsilon}"),
        ("\uD76B", "\\mathsfbf{\\Phi}"),
        ("\uD76C", "\\mathsfbf{\\Chi}"),
        ("\uD76D", "\\mathsfbf{\\Psi}"),
        ("\uD76E", "\\mathsfbf{\\Omega}"),
        ("\uD76F", "\\mathsfbf{\\nabla}"),
        ("\uD770", "\\mathsfbf{\\Alpha}"),
        ("\uD771", "\\mathsfbf{\\Beta}"),
        ("\uD772", "\\mathsfbf{\\Gamma}"),
        ("\uD773", "\\mathsfbf{\\Delta}"),
        ("\uD774", "\\mathsfbf{\\Epsilon}"),
        ("\uD775", "\\mathsfbf{\\Zeta}"),
        ("\uD776", "\\mathsfbf{\\Eta}"),
        ("\uD777", "\\mathsfbf{\\Theta}"),
        ("\uD778", "\\mathsfbf{\\Iota}"),
        ("\uD779", "\\mathsfbf{\\Kappa}"),
        ("\uD77A", "\\mathsfbf{\\Lambda}"),
        ("\uD77D", "\\mathsfbf{\\Xi}"),
        ("\uD77F", "\\mathsfbf{\\Pi}"),
        ("\uD780", "\\mathsfbf{\\Rho}"),
        ("\uD781", "\\mathsfbf{\\varsigma}"),
        ("\uD782", "\\mathsfbf{\\Sigma}"),
        ("\uD783", "\\mathsfbf{\\Tau}"),
        ("\uD784", "\\mathsfbf{\\Upsilon}"),
        ("\uD785", "\\mathsfbf{\\Phi}"),
        ("\uD786", "\\mathsfbf{\\Chi}"),
        ("\uD787", "\\mathsfbf{\\Psi}"),
        ("\uD788", "\\mathsfbf{\\Omega}"),
        ("\uD789", "\\partial "),
        ("\uD78A", "\\in"),
        ("\uD78B", "\\mathsfbf{\\vartheta}"),
        ("\uD78C", "\\mathsfbf{\\varkappa}"),
        ("\uD78D", "\\mathsfbf{\\phi}"),
        ("\uD78E", "\\mathsfbf{\\varrho}"),
        ("\uD78F", "\\mathsfbf{\\varpi}"),
        ("\uD790", "\\mathsfbfsl{\\Alpha}"),
        ("\uD791", "\\mathsfbfsl{\\Beta}"),
        ("\uD792", "\\mathsfbfsl{\\Gamma}"),
        ("\uD793", "\\mathsfbfsl{\\Delta}"),
        ("\uD794", "\\mathsfbfsl{\\Epsilon}"),
        ("\uD795", "\\mathsfbfsl{\\Zeta}"),
        ("\uD796", "\\mathsfbfsl{\\Eta}"),
        ("\uD797", "\\mathsfbfsl{\\vartheta}"),
        ("\uD798", "\\mathsfbfsl{\\Iota}"),
        ("\uD799", "\\mathsfbfsl{\\Kappa}"),
        ("\uD79A", "\\mathsfbfsl{\\Lambda}"),
        ("\uD79D", "\\mathsfbfsl{\\Xi}"),
        ("\uD79F", "\\mathsfbfsl{\\Pi}"),
        ("\uD7A0", "\\mathsfbfsl{\\Rho}"),
        ("\uD7A1", "\\mathsfbfsl{\\vartheta}"),
        ("\uD7A2", "\\mathsfbfsl{\\Sigma}"),
        ("\uD7A3", "\\mathsfbfsl{\\Tau}"),
        ("\uD7A4", "\\mathsfbfsl{\\Upsilon}"),
        ("\uD7A5", "\\mathsfbfsl{\\Phi}"),
        ("\uD7A6", "\\mathsfbfsl{\\Chi}"),
        ("\uD7A7", "\\mathsfbfsl{\\Psi}"),
        ("\uD7A8", "\\mathsfbfsl{\\Omega}"),
        ("\uD7A9", "\\mathsfbfsl{\\nabla}"),
        ("\uD7AA", "\\mathsfbfsl{\\Alpha}"),
        ("\uD7AB", "\\mathsfbfsl{\\Beta}"),
        ("\uD7AC", "\\mathsfbfsl{\\Gamma}"),
        ("\uD7AD", "\\mathsfbfsl{\\Delta}"),
        ("\uD7AE", "\\mathsfbfsl{\\Epsilon}"),
        ("\uD7AF", "\\mathsfbfsl{\\Zeta}"),
        ("\uD7B0", "\\mathsfbfsl{\\Eta}"),
        ("\uD7B1", "\\mathsfbfsl{\\vartheta}"),
        ("\uD7B2", "\\mathsfbfsl{\\Iota}"),
        ("\uD7B3", "\\mathsfbfsl{\\Kappa}"),
        ("\uD7B4", "\\mathsfbfsl{\\Lambda}"),
        ("\uD7B7", "\\mathsfbfsl{\\Xi}"),
        ("\uD7B9", "\\mathsfbfsl{\\Pi}"),
        ("\uD7BA", "\\mathsfbfsl{\\Rho}"),
        ("\uD7BB", "\\mathsfbfsl{\\varsigma}"),
        ("\uD7BC", "\\mathsfbfsl{\\Sigma}"),
        ("\uD7BD", "\\mathsfbfsl{\\Tau}"),
        ("\uD7BE", "\\mathsfbfsl{\\Upsilon}"),
        ("\uD7BF", "\\mathsfbfsl{\\Phi}"),
        ("\uD7C0", "\\mathsfbfsl{\\Chi}"),
        ("\uD7C1", "\\mathsfbfsl{\\Psi}"),
        ("\uD7C2", "\\mathsfbfsl{\\Omega}"),
        ("\uD7C3", "\\partial "),
        ("\uD7C4", "\\in"),
        ("\uD7C5", "\\mathsfbfsl{\\vartheta}"),
        ("\uD7C6", "\\mathsfbfsl{\\varkappa}"),
        ("\uD7C7", "\\mathsfbfsl{\\phi}"),
        ("\uD7C8", "\\mathsfbfsl{\\varrho}"),
        ("\uD7C9", "\\mathsfbfsl{\\varpi}"),
        ("\uD7CE", "\\mathbf{0}"),
        ("\uD7CF", "\\mathbf{1}"),
        ("\uD7D0", "\\mathbf{2}"),
        ("\uD7D1", "\\mathbf{3}"),
        ("\uD7D2", "\\mathbf{4}"),
        ("\uD7D3", "\\mathbf{5}"),
        ("\uD7D4", "\\mathbf{6}"),
        ("\uD7D5", "\\mathbf{7}"),
        ("\uD7D6", "\\mathbf{8}"),
        ("\uD7D7", "\\mathbf{9}"),
        ("\uD7D8", "\\mathbb{0}"),
        ("\uD7D9", "\\mathbb{1}"),
        ("\uD7DA", "\\mathbb{2}"),
        ("\uD7DB", "\\mathbb{3}"),
        ("\uD7DC", "\\mathbb{4}"),
        ("\uD7DD", "\\mathbb{5}"),
        ("\uD7DE", "\\mathbb{6}"),
        ("\uD7DF", "\\mathbb{7}"),
        ("\uD7E0", "\\mathbb{8}"),
        ("\uD7E1", "\\mathbb{9}"),
        ("\uD7E2", "\\mathsf{0}"),
        ("\uD7E3", "\\mathsf{1}"),
        ("\uD7E4", "\\mathsf{2}"),
        ("\uD7E5", "\\mathsf{3}"),
        ("\uD7E6", "\\mathsf{4}"),
        ("\uD7E7", "\\mathsf{5}"),
        ("\uD7E8", "\\mathsf{6}"),
        ("\uD7E9", "\\mathsf{7}"),
        ("\uD7EA", "\\mathsf{8}"),
        ("\uD7EB", "\\mathsf{9}"),
        ("\uD7EC", "\\mathsfbf{0}"),
        ("\uD7ED", "\\mathsfbf{1}"),
        ("\uD7EE", "\\mathsfbf{2}"),
        ("\uD7EF", "\\mathsfbf{3}"),
        ("\uD7F0", "\\mathsfbf{4}"),
        ("\uD7F1", "\\mathsfbf{5}"),
        ("\uD7F2", "\\mathsfbf{6}"),
        ("\uD7F3", "\\mathsfbf{7}"),
        ("\uD7F4", "\\mathsfbf{8}"),
        ("\uD7F5", "\\mathsfbf{9}"),
        ("\uD7F6", "\\mathtt{0}"),
        ("\uD7F7", "\\mathtt{1}"),
        ("\uD7F8", "\\mathtt{2}"),
        ("\uD7F9", "\\mathtt{3}"),
        ("\uD7FA", "\\mathtt{4}"),
        ("\uD7FB", "\\mathtt{5}"),
        ("\uD7FC", "\\mathtt{6}"),
        ("\uD7FD", "\\mathtt{7}"),
        ("\uD7FE", "\\mathtt{8}"),
        ("\uD7FF", "\\mathtt{9}"),
    )

    if sys.version_info >= (3, 0):
        unicode_to_latex = to_latex
        unicode_to_crappy_latex1 = to_crappy1
        unicode_to_crappy_latex2 = to_crappy2
        unicode_to_latex_map = dict(unicode_to_latex)
    else:
        unicode_to_latex = tuple((k.decode('unicode-escape'), v) for k, v in to_latex)
        unicode_to_crappy_latex1 = tuple((k.decode('unicode-escape'), v) for k, v in to_crappy1)
        unicode_to_crappy_latex2 = tuple((k.decode('unicode-escape'), v) for k, v in to_crappy2)
        unicode_to_latex_map = dict(unicode_to_latex)

prepare_unicode_to_latex()
python-bibtexparser-0.6.1/bibtexparser/tests/000077500000000000000000000000001255747214700214015ustar00rootroot00000000000000python-bibtexparser-0.6.1/bibtexparser/tests/data/000077500000000000000000000000001255747214700223125ustar00rootroot00000000000000python-bibtexparser-0.6.1/bibtexparser/tests/data/article.bib000066400000000000000000000005441255747214700244160ustar00rootroot00000000000000@ARTICLE{Cesar2013,
  author = {Jean César},
  title = {An amazing title},
  year = {2013},
  month = jan,
  volume = {12},
  pages = {12-23},
  journal = {Nice Journal},
  abstract = {This is an abstract. This line should be long enough to test
multilines... and with a french érudit word},
  comments = {A comment},
  keyword = {keyword1, keyword2},
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/article_comma_first.bib000066400000000000000000000006751255747214700270060ustar00rootroot00000000000000@ARTICLE{Cesar2013
, author = {Jean Cesar}
, title = {An amazing title}
, year = {2013}
, volume = {12}
, journal = {Nice Journal}
, comments = {A comment}
, keyword = {keyword1, keyword2}
}

@ARTICLE{ Baltazar2013
        , author = {Jean Baltazar}
        , title = {An amazing title}
        , year = {2013}
        , volume = {12}
        , journal = {Nice Journal}
        , comments = {A comment}
        , keyword = {keyword1, keyword2}}
python-bibtexparser-0.6.1/bibtexparser/tests/data/article_missing_coma.bib000066400000000000000000000006221255747214700271430ustar00rootroot00000000000000@ARTICLE{Cesar2013,
  author = {Jean Cesar},
  title = {An amazing title},
  year = {2013},
  volume = {12},
  journal = {Nice Journal},
  comments = {A comment},
  keyword = {keyword1, keyword2}
}

@ARTICLE{Baltazar2013,
  author = {Jean Baltazar},
  title = {An amazing title},
  year = {2013},
  volume = {12},
  journal = {Nice Journal},
  comments = {A comment},
  keyword = {keyword1, keyword2}}
python-bibtexparser-0.6.1/bibtexparser/tests/data/article_output.bib000066400000000000000000000005341255747214700260350ustar00rootroot00000000000000@article{Cesar2013,
 abstract = {This is an abstract. This line should be long enough to test
multilines... and with a french érudit word},
 author = {Jean César},
 comments = {A comment},
 journal = {Nice Journal},
 keyword = {keyword1, keyword2},
 month = {jan},
 pages = {12-23},
 title = {An amazing title},
 volume = {12},
 year = {2013}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/article_start_with_whitespace.bib000066400000000000000000000004311255747214700310750ustar00rootroot00000000000000 @ARTICLE{Cesar2013,
  author = {Jean Cesar},
  title = {An amazing title},
  year = {2013},
  volume = {12},
  journal = {Nice Journal}
}

    @ARTICLE{Cesar2014,
  author = {Jean Cesar},
  title = {An amazing title},
  year = {2014},
  volume = {12},
  journal = {Nice Journal}
}python-bibtexparser-0.6.1/bibtexparser/tests/data/book.bib000066400000000000000000000003131255747214700237170ustar00rootroot00000000000000@BOOK{Bird1987,
  title = {Dynamics of Polymeric Liquid},
  publisher = {Wiley Edition},
  year = {1987},
  author = {Bird, R.B. and Armstrong, R.C. and Hassager, O.},
  volume = {1},
  edition = {2},
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/book_comma_first.bib000066400000000000000000000003211255747214700263010ustar00rootroot00000000000000@book{Bird1987
,   author = {Bird, R.B. and Armstrong, R.C. and Hassager, O.}
,   edition = {2}
,   publisher = {Wiley Edition}
,   title = {Dynamics of Polymeric Liquid}
,   volume = {1}
,   year = {1987}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/book_output.bib000066400000000000000000000003051255747214700253400ustar00rootroot00000000000000@book{Bird1987,
 author = {Bird, R.B. and Armstrong, R.C. and Hassager, O.},
 edition = {2},
 publisher = {Wiley Edition},
 title = {Dynamics of Polymeric Liquid},
 volume = {1},
 year = {1987}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/comments_only.bib000066400000000000000000000001401255747214700256510ustar00rootroot00000000000000@comment{ignore this line!}
@Comment{ignore this line too!}
@COMMENT{and ignore this line too!}
python-bibtexparser-0.6.1/bibtexparser/tests/data/comments_only_output.bib000066400000000000000000000001431255747214700272740ustar00rootroot00000000000000@comment{ignore this line!}

@comment{ignore this line too!}

@comment{and ignore this line too!}

python-bibtexparser-0.6.1/bibtexparser/tests/data/encoding.bib000066400000000000000000000005541255747214700245620ustar00rootroot00000000000000@ARTICLE{Cesar_2013,
  author = {Jean César},
  title = {An amazing title: à},
  year = {2013},
  month = jan,
  volume = {12},
  pages = {12-23},
  journal = {Elémentaire},
  abstract = {This is an abstract. This line should be long enough to test
	 multilines... and with a french érudit word},
  comments = {A comment},
  keywords = {keyword1, keyword2},
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/features.bib000066400000000000000000000006451255747214700246130ustar00rootroot00000000000000@comment{ignore this line!}
@Comment{ignore this line too!}
@COMMENT{and ignore this line too!}

@preamble{ "\makeatletter" }
@preamble{ "\@ifundefined{url}{\def\url#1{\texttt{#1}}}{}" }
@preamble{ "\makeatother" }

@string{mystring = "Hello"}
@string{myconf = "My International Conference"}
@string{myname = "Doe"}

@inproceedings{mykey,
  author = "John",
  title = {Cool Stuff},
  booktitle = myconf,
  year = 2014,
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/features2.bib000066400000000000000000000011011255747214700246610ustar00rootroot00000000000000@string{CoOl = "Cool"}
@string{stuff = "Stuff"}
@string{myTitle = cool # " " # stuff}

@string{int = "International"}
@string{myconf = "My "#int#" Conference"}

@string{myname = "Doe"}

@String {firstname = "John"}
@String {lastname  = myname}
@String {domain  = "example"}
@String {tld  = "com"}

@String {foo = "1--10"}
@String {BaR = FOO}
@String {pages = baR}

@inproceedings{mykey,
  author = "John " # mynamE,
  title = mytitle,
  booktitle = myconf,
  pages = pages,
  year = 2014,
  note = "Email: " # firstname # "." # lastname #
          "@" # domain # "." # tld,
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/features_output.bib000066400000000000000000000007001255747214700262230ustar00rootroot00000000000000@comment{ignore this line!}

@comment{ignore this line too!}

@comment{and ignore this line too!}

@preamble{ "\makeatletter" }

@preamble{ "\@ifundefined{url}{\def\url#1{\texttt{#1}}}{}" }

@preamble{ "\makeatother" }

@string{mystring = "Hello"}

@string{myconf = "My International Conference"}

@string{myname = "Doe"}

@inproceedings{mykey,
 author = {John},
 booktitle = {My International Conference},
 title = {Cool Stuff},
 year = {2014}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/multiline_comments.bib000066400000000000000000000007671255747214700267110ustar00rootroot00000000000000@comment{Lorem ipsum dolor sit amet,
consectetur adipisicing elit}

@comment{
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident.
 ,
}

@comment{


Sunt in culpa qui officia deserunt mollit anim id est laborum.


}

@comment{}

python-bibtexparser-0.6.1/bibtexparser/tests/data/multiple_entries.bib000066400000000000000000000014361255747214700263600ustar00rootroot00000000000000@Book{Yablon2005,
  Title                    = {Optical fiber fusion slicing},
  Author                   = {Yablon, A.D.},
  Publisher                = {Springer},
  Year                     = {2005},
}

@Article{Wigner1938,
  Title                    = {The transition state method},
  Author                   = {Wigner, E.},
  Journal                  = {Trans. Faraday Soc.},
  Year                     = {1938},
  Pages                    = {29--41},
  Volume                   = {34},
  Doi                      = {10.1039/TF9383400029},
  ISSN                     = {0014-7672},
  Owner                    = {fr},
  Publisher                = {The Royal Society of Chemistry},
}

@Book{Toto3000,
  Title                    = {A title},
  Author                   = {Toto, A and Titi, B},
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/multiple_entries_and_comments.bib000066400000000000000000000015001255747214700310770ustar00rootroot00000000000000@Book{Yablon2005,
  Title                    = {Optical fiber fusion slicing},
  Author                   = {Yablon, A.D.},
  Publisher                = {Springer},
  Year                     = {2005},
}

@Article{Wigner1938,
  Title                    = {The transition state method},
  Author                   = {Wigner, E.},
  Journal                  = {Trans. Faraday Soc.},
  Year                     = {1938},
  Pages                    = {29--41},
  Volume                   = {34},
  Doi                      = {10.1039/TF9383400029},
  ISSN                     = {0014-7672},
  Owner                    = {fr},
  Publisher                = {The Royal Society of Chemistry},
}

@Book{Toto3000,
  Title                    = {A title},
  Author                   = {Toto, A and Titi, B},
}

@Comment{}

@Comment{A comment}

python-bibtexparser-0.6.1/bibtexparser/tests/data/multiple_entries_and_comments_output.bib000066400000000000000000000010061255747214700325200ustar00rootroot00000000000000@comment{}

@comment{A comment}

@book{Toto3000,
 author = {Toto, A and Titi, B},
 title = {A title}
}

@article{Wigner1938,
 author = {Wigner, E.},
 doi = {10.1039/TF9383400029},
 issn = {0014-7672},
 journal = {Trans. Faraday Soc.},
 owner = {fr},
 pages = {29--41},
 publisher = {The Royal Society of Chemistry},
 title = {The transition state method},
 volume = {34},
 year = {1938}
}

@book{Yablon2005,
 author = {Yablon, A.D.},
 publisher = {Springer},
 title = {Optical fiber fusion slicing},
 year = {2005}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/multiple_entries_output.bib000066400000000000000000000007451255747214700300020ustar00rootroot00000000000000@book{Toto3000,
 author = {Toto, A and Titi, B},
 title = {A title}
}

@article{Wigner1938,
 author = {Wigner, E.},
 doi = {10.1039/TF9383400029},
 issn = {0014-7672},
 journal = {Trans. Faraday Soc.},
 owner = {fr},
 pages = {29--41},
 publisher = {The Royal Society of Chemistry},
 title = {The transition state method},
 volume = {34},
 year = {1938}
}

@book{Yablon2005,
 author = {Yablon, A.D.},
 publisher = {Springer},
 title = {Optical fiber fusion slicing},
 year = {2005}
}

python-bibtexparser-0.6.1/bibtexparser/tests/data/traps.bib000066400000000000000000000005731255747214700241260ustar00rootroot00000000000000@ARTICLE{Laide2013,
  author = {Jean Laid{\'e},
  Ben Loaeb},
  title = {{An} amazing {title}},
  year = {2013},
  month = jan,
  volume = {12},
  pages = {12-23},
  journal = {Nice Journal},
  abstract = {This is an abstract. This line should be long enough to test
	 multilines... and with a french érudit word},
  comments = {A comment},
  keywords = {keyword1, keyword2},
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/website.bib000066400000000000000000000001561255747214700244340ustar00rootroot00000000000000@misc{feder2006,
 title = {BibTeX},
 author = {Alexander Feder},
 url = {http://bibtex.org},
 year = {2006}
}
python-bibtexparser-0.6.1/bibtexparser/tests/data/wrong.bib000066400000000000000000000001151255747214700241210ustar00rootroot00000000000000

@wrong{foo,
    author = {wrong}
}

@article{bar,
    author = {correct}
}
python-bibtexparser-0.6.1/bibtexparser/tests/test_bibdatabase.py000066400000000000000000000015541255747214700252400ustar00rootroot00000000000000import unittest
from bibtexparser.bibdatabase import BibDatabase


class TestBibDatabase(unittest.TestCase):
    entries = [{'ENTRYTYPE': 'book',
                'year': '1987',
                'edition': '2',
                'publisher': 'Wiley Edition',
                'ID': 'Bird1987',
                'volume': '1',
                'title': 'Dynamics of Polymeric Liquid',
                'author': 'Bird, R.B. and Armstrong, R.C. and Hassager, O.'
               }]

    def test_entries_list_method(self):
        bib_db = BibDatabase()
        bib_db.entries = self.entries
        self.assertEqual(bib_db.entries, bib_db.get_entry_list())

    def test_entries_dict_prop(self):
        bib_db = BibDatabase()
        bib_db.entries = self.entries
        self.assertEqual(bib_db.entries_dict, bib_db.get_entry_dict())


if __name__ == '__main__':
    unittest.main()
python-bibtexparser-0.6.1/bibtexparser/tests/test_bibtex_strings.py000066400000000000000000000035371255747214700260500ustar00rootroot00000000000000import unittest
import bibtexparser
from bibtexparser.bibdatabase import BibDatabase
from collections import OrderedDict


class TestStringParse(unittest.TestCase):
    def test_single_string_parse_count(self):
        bibtex_str = '@string{name1 = "value1"}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        self.assertEqual(len(bib_database.strings), 1)

    def test_multiple_string_parse_count(self):
        bibtex_str = '@string{name1 = "value1"}\n\n@string{name2 = "value2"}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        self.assertEqual(len(bib_database.strings), 2)

    def test_single_string_parse(self):
        bibtex_str = '@string{name1 = "value1"}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        expected = {'name1': 'value1'}
        self.assertEqual(bib_database.strings, expected)

    def test_multiple_string_parse(self):
        bibtex_str = '@string{name1 = "value1"}\n\n@string{name2 = "value2"}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        expected = OrderedDict()
        expected['name1'] = 'value1'
        expected['name2'] = 'value2'
        self.assertEqual(bib_database.strings, expected)


class TestStringWrite(unittest.TestCase):
    def test_single_string_write(self):
        bib_database = BibDatabase()
        bib_database.strings['name1'] = 'value1'
        result = bibtexparser.dumps(bib_database)
        expected = '@string{name1 = "value1"}\n\n'
        self.assertEqual(result, expected)

    def test_multiple_string_write(self):
        bib_database = BibDatabase()
        bib_database.strings['name1'] = 'value1'
        bib_database.strings['name2'] = 'value2'  # Order is important!
        result = bibtexparser.dumps(bib_database)
        expected = '@string{name1 = "value1"}\n\n@string{name2 = "value2"}\n\n'
        self.assertEqual(result, expected)python-bibtexparser-0.6.1/bibtexparser/tests/test_bibtexparser.py000066400000000000000000000057231255747214700255130ustar00rootroot00000000000000import unittest
import bibtexparser
from bibtexparser.bparser import BibTexParser
from tempfile import TemporaryFile


class TestBibtexParserParserMethods(unittest.TestCase):
    input_file_path = 'bibtexparser/tests/data/book.bib'
    entries_expected = [{'ENTRYTYPE': 'book',
                         'year': '1987',
                         'edition': '2',
                         'publisher': 'Wiley Edition',
                         'ID': 'Bird1987',
                         'volume': '1',
                         'title': 'Dynamics of Polymeric Liquid',
                         'author': 'Bird, R.B. and Armstrong, R.C. and Hassager, O.'
                        }]

    def test_parse_immediately(self):
        with open(self.input_file_path) as bibtex_file:
            bibtex_str = bibtex_file.read()
        bibtex_database = BibTexParser(bibtex_str)
        self.assertEqual(bibtex_database.entries, self.entries_expected)

    def test_parse_str(self):
        parser = BibTexParser()
        with open(self.input_file_path) as bibtex_file:
            bibtex_str = bibtex_file.read()
        bibtex_database = parser.parse(bibtex_str)
        self.assertEqual(bibtex_database.entries, self.entries_expected)

    def test_parse_file(self):
        parser = BibTexParser()
        with open(self.input_file_path) as bibtex_file:
            bibtex_database = parser.parse_file(bibtex_file)
        self.assertEqual(bibtex_database.entries, self.entries_expected)

    def test_parse_str_module(self):
        with open(self.input_file_path) as bibtex_file:
            bibtex_str = bibtex_file.read()
        bibtex_database = bibtexparser.loads(bibtex_str)
        self.assertEqual(bibtex_database.entries, self.entries_expected)

    def test_parse_file_module(self):
        with open(self.input_file_path) as bibtex_file:
            bibtex_database = bibtexparser.load(bibtex_file)
        self.assertEqual(bibtex_database.entries, self.entries_expected)


class TestBibtexparserWriteMethods(unittest.TestCase):
    input_file_path = 'bibtexparser/tests/data/book.bib'
    expected = \
"""@book{Bird1987,
 author = {Bird, R.B. and Armstrong, R.C. and Hassager, O.},
 edition = {2},
 publisher = {Wiley Edition},
 title = {Dynamics of Polymeric Liquid},
 volume = {1},
 year = {1987}
}

"""

    def test_write_str(self):
        with open(self.input_file_path) as bibtex_file:
            bibtex_database = bibtexparser.load(bibtex_file)
        result = bibtexparser.dumps(bibtex_database)
        self.assertEqual(result, self.expected)

    def test_write_file(self):
        with open(self.input_file_path) as bibtex_file:
            bibtex_database = bibtexparser.load(bibtex_file)

        with TemporaryFile(mode='w+') as bibtex_out_file:
            bibtexparser.dump(bibtex_database, bibtex_out_file)
            bibtex_out_file.seek(0)
            bibtex_out_str = bibtex_out_file.read()

        self.assertEqual(bibtex_out_str, self.expected)


if __name__ == '__main__':
    unittest.main()
python-bibtexparser-0.6.1/bibtexparser/tests/test_bibtexwriter.py000066400000000000000000000113321255747214700255240ustar00rootroot00000000000000import unittest
import bibtexparser
from bibtexparser.bwriter import BibTexWriter
from bibtexparser.bibdatabase import BibDatabase


class TestBibTexWriter(unittest.TestCase):
    def test_content_entries_only(self):
        with open('bibtexparser/tests/data/multiple_entries_and_comments.bib') as bibtex_file:
            bib_database = bibtexparser.load(bibtex_file)
        writer = BibTexWriter()
        writer.contents = ['entries']
        result = bibtexparser.dumps(bib_database, writer)
        expected = \
"""@book{Toto3000,
 author = {Toto, A and Titi, B},
 title = {A title}
}

@article{Wigner1938,
 author = {Wigner, E.},
 doi = {10.1039/TF9383400029},
 issn = {0014-7672},
 journal = {Trans. Faraday Soc.},
 owner = {fr},
 pages = {29--41},
 publisher = {The Royal Society of Chemistry},
 title = {The transition state method},
 volume = {34},
 year = {1938}
}

@book{Yablon2005,
 author = {Yablon, A.D.},
 publisher = {Springer},
 title = {Optical fiber fusion slicing},
 year = {2005}
}

"""
        self.assertEqual(result, expected)

    def test_content_comment_only(self):
        with open('bibtexparser/tests/data/multiple_entries_and_comments.bib') as bibtex_file:
            bib_database = bibtexparser.load(bibtex_file)
        writer = BibTexWriter()
        writer.contents = ['comments']
        result = bibtexparser.dumps(bib_database, writer)
        expected = \
"""@comment{}

@comment{A comment}

"""
        self.assertEqual(result, expected)

    def test_indent(self):
        bib_database = BibDatabase()
        bib_database.entries = [{'ID': 'abc123',
                                 'ENTRYTYPE': 'book',
                                 'author': 'test'}]
        writer = BibTexWriter()
        writer.indent = '  '
        result = bibtexparser.dumps(bib_database, writer)
        expected = \
"""@book{abc123,
  author = {test}
}

"""
        self.assertEqual(result, expected)

    def test_entry_separator(self):
        bib_database = BibDatabase()
        bib_database.entries = [{'ID': 'abc123',
                                 'ENTRYTYPE': 'book',
                                 'author': 'test'}]
        writer = BibTexWriter()
        writer.entry_separator = ''
        result = bibtexparser.dumps(bib_database, writer)
        expected = \
"""@book{abc123,
 author = {test}
}
"""
        self.assertEqual(result, expected)


class TestEntrySorting(unittest.TestCase):
    bib_database = BibDatabase()
    bib_database.entries = [{'ID': 'b',
                             'ENTRYTYPE': 'article'},
                            {'ID': 'c',
                             'ENTRYTYPE': 'book'},
                            {'ID': 'a',
                             'ENTRYTYPE': 'book'}]

    def test_sort_default(self):
        result = bibtexparser.dumps(self.bib_database)
        expected = "@book{a\n}\n\n@article{b\n}\n\n@book{c\n}\n\n"
        self.assertEqual(result, expected)

    def test_sort_none(self):
        writer = BibTexWriter()
        writer.order_entries_by = None
        result = bibtexparser.dumps(self.bib_database, writer)
        expected = "@article{b\n}\n\n@book{c\n}\n\n@book{a\n}\n\n"
        self.assertEqual(result, expected)

    def test_sort_id(self):
        writer = BibTexWriter()
        writer.order_entries_by = ('ID', )
        result = bibtexparser.dumps(self.bib_database, writer)
        expected = "@book{a\n}\n\n@article{b\n}\n\n@book{c\n}\n\n"
        self.assertEqual(result, expected)

    def test_sort_type(self):
        writer = BibTexWriter()
        writer.order_entries_by = ('ENTRYTYPE', )
        result = bibtexparser.dumps(self.bib_database, writer)
        expected = "@article{b\n}\n\n@book{c\n}\n\n@book{a\n}\n\n"
        self.assertEqual(result, expected)

    def test_sort_type_id(self):
        writer = BibTexWriter()
        writer.order_entries_by = ('ENTRYTYPE', 'ID')
        result = bibtexparser.dumps(self.bib_database, writer)
        expected = "@article{b\n}\n\n@book{a\n}\n\n@book{c\n}\n\n"
        self.assertEqual(result, expected)

    def test_sort_missing_field(self):
        bib_database = BibDatabase()
        bib_database.entries = [{'ID': 'b',
                                 'ENTRYTYPE': 'article',
                                 'year': '2000'},
                                {'ID': 'c',
                                 'ENTRYTYPE': 'book',
                                 'year': '2010'},
                                {'ID': 'a',
                                 'ENTRYTYPE': 'book'}]
        writer = BibTexWriter()
        writer.order_entries_by = ('year', )
        result = bibtexparser.dumps(bib_database, writer)
        expected = "@book{a\n}\n\n@article{b,\n year = {2000}\n}\n\n@book{c,\n year = {2010}\n}\n\n"
        self.assertEqual(result, expected)


python-bibtexparser-0.6.1/bibtexparser/tests/test_bparser.py000066400000000000000000000414311255747214700244530ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import unittest
import codecs

from bibtexparser.bparser import BibTexParser
from bibtexparser.customization import *
from bibtexparser import customization


def customizations_unicode(record):
    """Use all functions related to specific fields
    + converter to unicode.

    :param record: a record
    :returns: -- customized record
    """

    record = type(record)
    record = author(record)
    record = editor(record)
    record = journal(record)
    record = keyword(record)
    record = link(record)
    record = page_double_hyphen(record)
    record = doi(record)
    record = convert_to_unicode(record)
    return record


def customizations_latex(record):
    """Use all functions related to specific fields
    + converter to latex.

    :param record: a record
    :returns: -- customized record
    """

    record = homogeneize_latex_encoding(record)
    record = type(record)
    record = author(record)
    record = editor(record)
    record = journal(record)
    record = keyword(record)
    record = link(record)
    record = page_double_hyphen(record)
    record = doi(record)
    return record


class TestBibtexParserFunc(unittest.TestCase):
    def test_strip_quotes(self):
        parser = BibTexParser()
        result = parser._strip_quotes('"before remove after"')
        expected = 'before remove after'
        self.assertEqual(result, expected)

    def test_strip_quotes_n(self):
        parser = BibTexParser()
        result = parser._strip_quotes('"before remove after"\n')
        expected = 'before remove after'
        self.assertEqual(result, expected)

    def test_strip_quotes2(self):
        parser = BibTexParser()
        result = parser._strip_quotes('before "remove" after')
        expected = 'before "remove" after'
        self.assertEqual(result, expected)

    def test_strip_braces(self):
        parser = BibTexParser()
        result = parser._strip_braces('{before remove after}')
        expected = 'before remove after'
        self.assertEqual(result, expected)

    def test_strip_braces2(self):
        parser = BibTexParser()
        result = parser._strip_braces('before {remove} after')
        expected = 'before {remove} after'
        self.assertEqual(result, expected)

    def test_strip_braces_n(self):
        parser = BibTexParser()
        result = parser._strip_braces('{before remove after}\n')
        expected = 'before remove after'
        self.assertEqual(result, expected)


class TestBibtexParserList(unittest.TestCase):

    def test_wrong(self):
        """
        Wrong entry type
        """
        with open('bibtexparser/tests/data/wrong.bib', 'r') as bibfile:
            self.assetRaises(TypeError, BibTexParser, bibfile)

    ###########
    # ARTICLE
    ###########
    # test also that list and dict are equivalent
    def test_article(self):
        with codecs.open('bibtexparser/tests/data/article.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read())
            res_list = bib.get_entry_list()
            res_dict = bib.get_entry_dict()
            expected_list = [{'keyword': 'keyword1, keyword2',
                              'ENTRYTYPE': 'article',
                              'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french érudit word',
                              'year': '2013',
                              'journal': 'Nice Journal',
                              'ID': 'Cesar2013',
                              'pages': '12-23',
                              'title': 'An amazing title',
                              'comments': 'A comment',
                              'author': 'Jean César',
                              'volume': '12',
                              'month': 'jan'
                              }]
            expected_dict = {'Cesar2013': {'keyword': 'keyword1, keyword2',
                              'ENTRYTYPE': 'article',
                              'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french érudit word',
                              'year': '2013',
                              'journal': 'Nice Journal',
                              'ID': 'Cesar2013',
                              'pages': '12-23',
                              'title': 'An amazing title',
                              'comments': 'A comment',
                              'author': 'Jean César',
                              'volume': '12',
                              'month': 'jan'
                              }}
        self.assertEqual(res_list, expected_list)
        self.assertEqual(res_dict, expected_dict)

    def test_article_cust_unicode(self):
        with codecs.open('bibtexparser/tests/data/article.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=customizations_unicode)
            res = bib.get_entry_list()
        expected = [{'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french érudit word',
                     'ENTRYTYPE': 'article',
                     'pages': '12--23',
                     'volume': '12',
                     'ID': 'Cesar2013',
                     'year': '2013',
                     'author': ['César, Jean'],
                     'journal': {'ID': 'NiceJournal', 'name': 'Nice Journal'},
                     'comments': 'A comment',
                     'month': 'jan',
                     'keyword': ['keyword1', 'keyword2'],
                     'title': 'An amazing title'
                     }]
        self.assertEqual(res, expected)

    def test_article_cust_latex(self):
        with codecs.open('bibtexparser/tests/data/article.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=customizations_latex)
            res = bib.get_entry_list()
        expected = [{'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french {\\\'e}rudit word',
                     'ENTRYTYPE': 'article',
                     'pages': '12--23',
                     'volume': '12',
                     'ID': 'Cesar2013',
                     'year': '2013',
                     'author': ['C{\\\'e}sar, Jean'],
                     'journal': {'ID': 'NiceJournal', 'name': 'Nice Journal'},
                     'comments': 'A comment',
                     'month': 'jan',
                     'keyword': ['keyword1', 'keyword2'],
                     'title': '{A}n amazing title'
                     }]
        self.assertEqual(res, expected)

    def test_article_cust_order(self):
        def cust(record):
            record = customization.page_double_hyphen(record)
            record = customization.homogeneize_latex_encoding(record)
            record = customization.author(record)
            return record

        def cust2(record):
            record = customization.author(record)
            record = customization.page_double_hyphen(record)
            record = customization.homogeneize_latex_encoding(record)
            return record

        with open('bibtexparser/tests/data/multiple_entries.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=cust)
            res = bib.get_entry_list()
        with open('bibtexparser/tests/data/multiple_entries.bib', 'r') as bibfile:
            bib2 = BibTexParser(bibfile.read(), customization=cust2)
            res2 = bib.get_entry_list()
        self.assertEqual(res, res2)

    def test_article_missing_coma(self):
        with open('bibtexparser/tests/data/article_missing_coma.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
        expected = [{'ENTRYTYPE': 'article',
                     'journal': 'Nice Journal',
                     'volume': '12',
                     'ID': 'Cesar2013',
                     'year': '2013',
                     'author': 'Jean Cesar',
                     'comments': 'A comment',
                     'keyword': 'keyword1, keyword2',
                     'title': 'An amazing title'
                     },
                    {'ENTRYTYPE': 'article',
                     'journal': 'Nice Journal',
                     'volume': '12',
                     'ID': 'Baltazar2013',
                     'year': '2013',
                     'author': 'Jean Baltazar',
                     'comments': 'A comment',
                     'keyword': 'keyword1, keyword2',
                     'title': 'An amazing title'
                     }]
        self.assertEqual(res, expected)

    def test_article_start_with_whitespace(self):
        with open('bibtexparser/tests/data/article_start_with_whitespace.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            self.assertEqual(len(bib.get_entry_list()), 2)

    def test_article_comma_first(self):
        with open('bibtexparser/tests/data/article_comma_first.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
        expected = [{'ENTRYTYPE': 'article',
                     'journal': 'Nice Journal',
                     'volume': '12',
                     'ID': 'Cesar2013',
                     'year': '2013',
                     'author': 'Jean Cesar',
                     'comments': 'A comment',
                     'keyword': 'keyword1, keyword2',
                     'title': 'An amazing title'
                     },
                    {'ENTRYTYPE': 'article',
                     'journal': 'Nice Journal',
                     'volume': '12',
                     'ID': 'Baltazar2013',
                     'year': '2013',
                     'author': 'Jean Baltazar',
                     'comments': 'A comment',
                     'keyword': 'keyword1, keyword2',
                     'title': 'An amazing title'
                     }]
        self.assertEqual(res, expected)

    ###########
    # BOOK
    ###########
    def test_book(self):
        with open('bibtexparser/tests/data/book.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'ENTRYTYPE': 'book',
                         'year': '1987',
                         'edition': '2',
                         'publisher': 'Wiley Edition',
                         'ID': 'Bird1987',
                         'volume': '1',
                         'title': 'Dynamics of Polymeric Liquid',
                         'author': 'Bird, R.B. and Armstrong, R.C. and Hassager, O.'
                         }]

        self.assertEqual(res, expected)

    def test_book_cust_unicode(self):
        with open('bibtexparser/tests/data/book.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=customizations_unicode)
            res = bib.get_entry_list()
            expected = [{'ENTRYTYPE': 'book',
                         'year': '1987',
                         'edition': '2',
                         'publisher': 'Wiley Edition',
                         'ID': 'Bird1987',
                         'volume': '1',
                         'title': 'Dynamics of Polymeric Liquid',
                         'author': ['Bird, R.B.', 'Armstrong, R.C.', 'Hassager, O.']
                         }]

        self.assertEqual(res, expected)

    def test_book_cust_latex(self):
        with open('bibtexparser/tests/data/book.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=customizations_latex)
            res = bib.get_entry_list()
            expected = [{'ENTRYTYPE': 'book',
                         'year': '1987',
                         'edition': '2',
                         'publisher': 'Wiley Edition',
                         'ID': 'Bird1987',
                         'volume': '1',
                         'title': '{D}ynamics of {P}olymeric {L}iquid',
                         'author': ['Bird, R.B.', 'Armstrong, R.C.', 'Hassager, O.']
                         }]

        self.assertEqual(res, expected)

    ###########
    # TRAPS
    ###########
    def test_traps(self):
        with codecs.open('bibtexparser/tests/data/traps.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'keyword': 'keyword1, keyword2',
                         'ENTRYTYPE': 'article',
                         'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french érudit word',
                         'year': '2013',
                         'journal': 'Nice Journal',
                         'ID': 'Laide2013',
                         'pages': '12-23',
                         'title': '{An} amazing {title}',
                         'comments': 'A comment',
                         'author': 'Jean Laid{\\\'e}, Ben Loaeb',
                         'volume': '12',
                         'month': 'jan'
                         }]
        self.assertEqual(res, expected)

    ###########
    # FEATURES
    ###########
    def test_features(self):
        with open('bibtexparser/tests/data/features.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'ENTRYTYPE': 'inproceedings',
                         'year': '2014',
                         'title': 'Cool Stuff',
                         'author': 'John',
                         'ID': 'mykey',
                         'booktitle': 'My International Conference',
                         }]
        self.assertEqual(res, expected)

    def test_features2(self):
        with open('bibtexparser/tests/data/features2.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'ENTRYTYPE': 'inproceedings',
                         'year': '2014',
                         'title': 'Cool Stuff',
                         'author': 'John Doe',
                         'ID': 'mykey',
                         'booktitle': 'My International Conference',
                         'note': 'Email: John.Doe@example.com',
                         'pages': '1--10',
                         }]
        self.assertEqual(res, expected)

    ###########
    # WRONG
    ###########
    def test_wrong(self):
        with open('bibtexparser/tests/data/wrong.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'author': 'correct',
                         'ID': 'bar',
                         'ENTRYTYPE': 'article'}]
        self.assertEqual(res, expected)

    ###########
    # ENCODING
    ###########
    def test_encoding(self):
        with codecs.open('bibtexparser/tests/data/encoding.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read())
            res = bib.get_entry_list()
            expected = [{'keyword': 'keyword1, keyword2',
                              'ENTRYTYPE': 'article',
                              'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french érudit word',
                              'year': '2013',
                              'journal': 'Elémentaire',
                              'ID': 'Cesar_2013',
                              'pages': '12-23',
                              'title': 'An amazing title: à',
                              'comments': 'A comment',
                              'author': 'Jean César',
                              'volume': '12',
                              'month': 'jan'
                         }]
        self.assertEqual(res, expected)

    def test_encoding_with_homogeneize(self):
        with codecs.open('bibtexparser/tests/data/encoding.bib', 'r', 'utf-8') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=homogeneize_latex_encoding)
            res = bib.get_entry_list()
            expected = [{'keyword': 'keyword1, keyword2',
                              'ENTRYTYPE': 'article',
                              'abstract': 'This is an abstract. This line should be long enough to test\nmultilines... and with a french {\\\'e}rudit word',
                              'year': '2013',
                              'journal': 'El{\\\'e}mentaire',
                              'ID': 'Cesar_2013',
                              'pages': '12-23',
                              'title': '{A}n amazing title: {\\`a}',
                              'comments': 'A comment',
                              'author': 'Jean C{\\\'e}sar',
                              'volume': '12',
                              'month': 'jan'
                         }]
        self.assertEqual(res, expected)


if __name__ == '__main__':
    unittest.main()
python-bibtexparser-0.6.1/bibtexparser/tests/test_bwriter.py000066400000000000000000000050041255747214700244670ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Francois Boulogne
# License:

from __future__ import unicode_literals

import unittest
import sys

from bibtexparser.bparser import BibTexParser
from bibtexparser.bwriter import BibTexWriter, to_bibtex
from bibtexparser.customization import author


class TestBibtexWriterList(unittest.TestCase):

    ###########
    # ARTICLE
    ###########
    def test_article(self):
        with open('bibtexparser/tests/data/article.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())

        with open('bibtexparser/tests/data/article_output.bib', 'r') as bibfile:
            expected = bibfile.read()
        result = to_bibtex(bib)
        if not sys.version_info >= (3, 0):
            if isinstance(result, unicode):
                result = result.encode('utf-8')
        self.maxDiff = None
        self.assertEqual(expected, result)

    ###########
    # BOOK
    ###########
    def test_book(self):
        with open('bibtexparser/tests/data/book.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())

        with open('bibtexparser/tests/data/book_output.bib', 'r') as bibfile:
            expected = bibfile.read()
        result = to_bibtex(bib)
        self.maxDiff = None
        self.assertEqual(expected, result)

    ###########
    # COMMA FIRST
    ###########
    def test_comma_first(self):
        with open('bibtexparser/tests/data/book.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())

        with open('bibtexparser/tests/data/book_comma_first.bib', 'r') as bibfile:
            expected = bibfile.read()
        writer = BibTexWriter()
        writer.indent = '   '
        writer.comma_first = True
        result = writer.write(bib)
        self.maxDiff = None
        self.assertEqual(expected, result)

    ###########
    # MULTIPLE
    ###########
    def test_multiple(self):
        with open('bibtexparser/tests/data/multiple_entries.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())

        with open('bibtexparser/tests/data/multiple_entries_output.bib', 'r') as bibfile:
            expected = bibfile.read()
        result = to_bibtex(bib)
        self.maxDiff = None
        self.assertEqual(expected, result)

    ###########
    # Exception
    ###########
    def test_exception_typeerror(self):
        with open('bibtexparser/tests/data/article.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), customization=author)
        self.assertRaises(TypeError, to_bibtex, bib)

python-bibtexparser-0.6.1/bibtexparser/tests/test_comments.py000066400000000000000000000053361255747214700246460ustar00rootroot00000000000000import unittest
from bibtexparser.bparser import BibTexParser
from bibtexparser.bwriter import to_bibtex


class TestParseComment(unittest.TestCase):
    def test_comment_count(self):
        with open('bibtexparser/tests/data/features.bib') as bibfile:
            bib = BibTexParser(bibfile.read())
        self.assertEqual(len(bib.comments), 3)

    def test_comment_list(self):
        with open('bibtexparser/tests/data/features.bib') as bibfile:
            bib = BibTexParser(bibfile.read())
        expected = ["ignore this line!",
                    "ignore this line too!",
                    "and ignore this line too!"]
        self.assertEqual(bib.comments, expected)

    def test_multiline_comments(self):
        with open('bibtexparser/tests/data/multiline_comments.bib') as bibfile:
            bib = BibTexParser(bibfile.read())
        expected = [
"""Lorem ipsum dolor sit amet,
consectetur adipisicing elit""",
"""
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident.
 ,
""",
"""


Sunt in culpa qui officia deserunt mollit anim id est laborum.


""",
""
        ]
        self.maxDiff = None
        self.assertEqual(bib.comments, expected)

    def test_multiple_entries(self):
        with open('bibtexparser/tests/data/multiple_entries_and_comments.bib') as bibfile:
            bib = BibTexParser(bibfile.read())
        expected = ["",
                    "A comment"]
        self.assertEqual(bib.comments, expected)


class TestWriteComment(unittest.TestCase):
    def test_comment_write(self):
        with open('bibtexparser/tests/data/comments_only.bib') as bibfile:
            bib = BibTexParser(bibfile.read())

        with open('bibtexparser/tests/data/comments_only_output.bib') as bibfile:
            expected = bibfile.read()
        result = to_bibtex(bib)
        self.assertEqual(result, expected)

    def test_multiline_comment_write(self):
        with open('bibtexparser/tests/data/multiline_comments.bib') as bibfile:
            expected = bibfile.read()

        bib = BibTexParser(expected)
        result = to_bibtex(bib)
        self.assertEqual(result, expected)

    def test_multiple_entries(self):
        with open('bibtexparser/tests/data/multiple_entries_and_comments.bib') as bibfile:
            bib = BibTexParser(bibfile.read())
        with open('bibtexparser/tests/data/multiple_entries_and_comments_output.bib') as bibfile:
            expected = bibfile.read()
        result = to_bibtex(bib)
        self.assertEqual(result, expected)
python-bibtexparser-0.6.1/bibtexparser/tests/test_customization.py000066400000000000000000000065271255747214700257340ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import unittest

from bibtexparser.customization import getnames, convert_to_unicode, homogeneize_latex_encoding, page_double_hyphen, keyword


class TestBibtexParserMethod(unittest.TestCase):

    ###########
    # getnames
    ###########
    def test_getnames(self):
        names = ['Foo Bar',
                 'Foo B. Bar',
                 'F. B. Bar',
                 'F.B. Bar',
                 'F. Bar',
                 'Jean de Savigny',
                 'Jean la Tour',
                 'Jean le Tour',
                 'Mike ben Akar',
                 #'Jean de la Tour',
                 #'Johannes Diderik van der Waals',
                 ]
        result = getnames(names)
        expected = ['Bar, Foo',
                    'Bar, Foo B.',
                    'Bar, F. B.',
                    'Bar, F. B.',
                    'Bar, F.',
                    'de Savigny, Jean',
                    'la Tour, Jean',
                    'le Tour, Jean',
                    'ben Akar, Mike',
                    #'de la Tour, Jean',
                    #'van der Waals, Johannes Diderik',
                    ]
        self.assertEqual(result, expected)

    @unittest.skip('Bug #9')
    def test_getnames_braces(self):
        names = ['A. {Delgado de Molina}', 'M. Vign{\\\'e}']
        result = getnames(names)
        expected = ['Delgado de Molina, A.', 'Vigné, M.']
        self.assertEqual(result, expected)

    ###########
    # page_double_hyphen
    ###########
    def test_page_double_hyphen_alreadyOK(self):
        record = {'pages': '12--24'}
        result = page_double_hyphen(record)
        expected = record
        self.assertEqual(result, expected)

    def test_page_double_hyphen_simple(self):
        record = {'pages': '12-24'}
        result = page_double_hyphen(record)
        expected = {'pages': '12--24'}
        self.assertEqual(result, expected)

    def test_page_double_hyphen_space(self):
        record = {'pages': '12 - 24'}
        result = page_double_hyphen(record)
        expected = {'pages': '12--24'}
        self.assertEqual(result, expected)

    def test_page_double_hyphen_nothing(self):
        record = {'pages': '12 24'}
        result = page_double_hyphen(record)
        expected = {'pages': '12 24'}
        self.assertEqual(result, expected)

    ###########
    # convert to unicode
    ###########
    def test_convert_to_unicode(self):
        record = {'toto': '{\`a} \`{a}'}
        result = convert_to_unicode(record)
        expected = {'toto': 'à à'}
        self.assertEqual(result, expected)
        record = {'toto': '{\\"u} \\"{u}'}
        result = convert_to_unicode(record)
        expected = {'toto': 'ü ü'}
        self.assertEqual(result, expected)

    ###########
    # homogeneize
    ###########
    def test_homogeneize(self):
        record = {'toto': 'à {\`a} \`{a}'}
        result = homogeneize_latex_encoding(record)
        expected = {'toto': '{\`a} {\`a} {\`a}'}
        self.assertEqual(result, expected)

    ###########
    # keywords
    ###########
    def test_keywords(self):
        record = {'keyword': "a b, a b , a b;a b ; a b, a b\n"}
        result = keyword(record)
        expected = {'keyword': ['a b'] * 6}
        self.assertEqual(result, expected)

if __name__ == '__main__':
    unittest.main()
python-bibtexparser-0.6.1/bibtexparser/tests/test_homogenise_fields.py000066400000000000000000000020241255747214700264730ustar00rootroot00000000000000import unittest
from bibtexparser.bparser import BibTexParser


class TestHomogeniseFields(unittest.TestCase):
    def test_homogenise_default(self):
        with open('bibtexparser/tests/data/website.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read())
            entries = bib.get_entry_list()
            self.assertIn('link', entries[0])
            self.assertNotIn('url', entries[0])

    def test_homogenise_on(self):
        with open('bibtexparser/tests/data/website.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), homogenise_fields=True)
            entries = bib.get_entry_list()
            self.assertIn('link', entries[0])
            self.assertNotIn('url', entries[0])

    def test_homogenise_off(self):
        with open('bibtexparser/tests/data/website.bib', 'r') as bibfile:
            bib = BibTexParser(bibfile.read(), homogenise_fields=False)
            entries = bib.get_entry_list()
            self.assertNotIn('link', entries[0])
            self.assertIn('url', entries[0])
python-bibtexparser-0.6.1/bibtexparser/tests/test_latexenc.py000066400000000000000000000044711255747214700246230ustar00rootroot00000000000000#!/usr/bin/env python
# -*- coding: utf-8 -*-
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see 
#
# Author: Francois Boulogne , 2012

from __future__ import unicode_literals
import unittest

from bibtexparser.latexenc import *

class TestLatexConverter(unittest.TestCase):

    def test_accent(self):
        string = 'à é è ö'
        result = string_to_latex(string)
        expected = "{\`a} {\\\'e} {\`e} {\\\"o}"
        self.assertEqual(result, expected)

    def test_special_caracter(self):
        string = 'ç'
        result = string_to_latex(string)
        expected = '{\c c}'
        self.assertEqual(result, expected)

class TestUppercaseProtection(unittest.TestCase):

    def test_uppercase(self):
        string = 'An upPer Case A'
        result = protect_uppercase(string)
        expected = '{A}n up{P}er {C}ase {A}'
        self.assertEqual(result, expected)

    def test_lowercase(self):
        string = 'a'
        result = protect_uppercase(string)
        expected = 'a'
        self.assertEqual(result, expected)

    def test_alreadyprotected(self):
        string = '{A}, m{A}gnificient, it is a {A}...'
        result = protect_uppercase(string)
        expected = '{A}, m{A}gnificient, it is a {A}...'
        self.assertEqual(result, expected)

    def test_traps(self):
        string = '{A, m{Agnificient, it is a {A'
        result = protect_uppercase(string)
        expected = '{A, m{Agnificient, it is a {A'
        self.assertEqual(result, expected)

    def test_traps2(self):
        string = 'A}, mA}gnificient, it is a A}'
        result = protect_uppercase(string)
        expected = 'A}, mA}gnificient, it is a A}'
        self.assertEqual(result, expected)


if __name__ == '__main__':
    unittest.main()
python-bibtexparser-0.6.1/bibtexparser/tests/test_preambles.py000066400000000000000000000031421255747214700247640ustar00rootroot00000000000000import unittest
import bibtexparser
from bibtexparser.bibdatabase import BibDatabase
from collections import OrderedDict


class TestPreambleParse(unittest.TestCase):
    def test_single_preamble_parse_count(self):
        bibtex_str = '@preamble{ a }\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        self.assertEqual(len(bib_database.preambles), 1)

    def test_multiple_preamble_parse_count(self):
        bibtex_str = '@preamble{ a }\n\n@preamble{b}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        self.assertEqual(len(bib_database.preambles), 2)

    def test_single_preamble_parse(self):
        bibtex_str = '@preamble{ a }\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        expected = [' a ']
        self.assertEqual(bib_database.preambles, expected)

    def test_multiple_preamble_parse(self):
        bibtex_str = '@preamble{ a }\n\n@preamble{b}\n\n'
        bib_database = bibtexparser.loads(bibtex_str)
        expected = [' a ', 'b']
        self.assertEqual(bib_database.preambles, expected)


class TestPreambleWrite(unittest.TestCase):
    def test_single_preamble_write(self):
        bib_database = BibDatabase()
        bib_database.preambles = [' a ']
        result = bibtexparser.dumps(bib_database)
        expected = '@preamble{ a }\n\n'
        self.assertEqual(result, expected)

    def test_multiple_string_write(self):
        bib_database = BibDatabase()
        bib_database.preambles = [' a ', 'b']
        result = bibtexparser.dumps(bib_database)
        expected = '@preamble{ a }\n\n@preamble{b}\n\n'
        self.assertEqual(result, expected)python-bibtexparser-0.6.1/docs/000077500000000000000000000000001255747214700164755ustar00rootroot00000000000000python-bibtexparser-0.6.1/docs/Makefile000066400000000000000000000127351255747214700201450ustar00rootroot00000000000000# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext

help:
	@echo "Please use \`make ' where  is one of"
	@echo "  html       to make standalone HTML files"
	@echo "  dirhtml    to make HTML files named index.html in directories"
	@echo "  singlehtml to make a single large HTML file"
	@echo "  pickle     to make pickle files"
	@echo "  json       to make JSON files"
	@echo "  htmlhelp   to make HTML files and a HTML help project"
	@echo "  qthelp     to make HTML files and a qthelp project"
	@echo "  devhelp    to make HTML files and a Devhelp project"
	@echo "  epub       to make an epub"
	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
	@echo "  text       to make text files"
	@echo "  man        to make manual pages"
	@echo "  texinfo    to make Texinfo files"
	@echo "  info       to make Texinfo files and run them through makeinfo"
	@echo "  gettext    to make PO message catalogs"
	@echo "  changes    to make an overview of all changed/added/deprecated items"
	@echo "  linkcheck  to check all external links for integrity"
	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"

clean:
	-rm -rf $(BUILDDIR)/*

html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BibtexParser.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BibtexParser.qhc"

devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/BibtexParser"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BibtexParser"
	@echo "# devhelp"

epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

texinfo:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo
	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
	@echo "Run \`make' in that directory to run these through makeinfo" \
	      "(use \`make info' here to do that automatically)."

info:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo "Running Texinfo files through makeinfo..."
	make -C $(BUILDDIR)/texinfo info
	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

gettext:
	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
	@echo
	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."
python-bibtexparser-0.6.1/docs/source/000077500000000000000000000000001255747214700177755ustar00rootroot00000000000000python-bibtexparser-0.6.1/docs/source/bibtex_conv.rst000066400000000000000000000017071255747214700230360ustar00rootroot00000000000000Bibtex tips and conventions
===========================

Format
------

http://maverick.inria.fr/~Xavier.Decoret/resources/xdkbibtex/bibtex_summary.html

* Comments
* Variable
* @preamble
* Name convention

Display your bibliography in html pages
---------------------------------------

Have a look to this project: http://www.monperrus.net/martin/bibtexbrowser/

Upper case letters in titles
----------------------------

Put the letter/word in curly braces like {this}.


How to handle accents and special characters?
---------------------------------------------

TODO

IEEE citation reference
-----------------------

* https://origin.www.ieee.org/documents/ieeecitationref.pdf


Common Errors in Bibliographies John Owens
------------------------------------------

* http://www.ece.ucdavis.edu/~jowens/biberrors.html

Common abbreviations for journals
---------------------------------

* Jabref list http://jabref.sourceforge.net/resources.php#downloadlists

python-bibtexparser-0.6.1/docs/source/bibtexparser.rst000066400000000000000000000020421255747214700232170ustar00rootroot00000000000000.. _bibtexparser_api:

bibtexparser: API
=================

:mod:`bibtexparser` --- Parsing and writing BibTeX files
--------------------------------------------------------

.. automodule:: bibtexparser
    :members: load, loads, dumps, dump

:mod:`bibtexparser.bibdatabase` --- The bibliographic database object
---------------------------------------------------------------------

.. autoclass:: bibdatabase.BibDatabase
    :members: entries, entries_dict, comments, strings, preambles

:mod:`bibtexparser.bparser` --- Modifying the default parser
------------------------------------------------------------

.. automodule:: bparser
    :members:

:mod:`bibtexparser.customization` --- Record customization functions
--------------------------------------------------------------------

.. automodule:: customization
    :members:
    :inherited-members:
    :show-inheritance:


:mod:`bibtexparser.bwriter` --- Modifying the default writer
------------------------------------------------------------

.. autoclass:: bwriter.BibTexWriter
    :members:
python-bibtexparser-0.6.1/docs/source/conf.py000066400000000000000000000175501255747214700213040ustar00rootroot00000000000000#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# BibtexParser documentation build configuration file, created by
# sphinx-quickstart on Thu Aug  1 13:30:23 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys, os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath('../../bibtexparser'))

# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix of source filenames.
source_suffix = '.rst'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'BibtexParser'
copyright = '2013-2014, F. Boulogne'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
try:
    import bibtexparser as bp
    # The short X.Y version.
    version = bp.__version__
    # The full version, including alpha/beta/rc tags.
    release = bp.__version__
except ImportError:
    version = 'latest'
    release = 'latest'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# -- Options for HTML output ---------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'default'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []

# The name for this set of Sphinx documents.  If None, it defaults to
# " v documentation".
#html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
#html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}

# If false, no module index is generated.
#html_domain_indices = True

# If false, no index is generated.
#html_use_index = True

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a  tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'BibtexParserdoc'


# -- Options for LaTeX output --------------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('index', 'BibtexParser.tex', 'BibtexParser Documentation',
   'F. Boulogne', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
#latex_domain_indices = True


# -- Options for manual page output --------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('index', 'bibtexparser', 'BibtexParser Documentation',
     ['F. Boulogne'], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False


# -- Options for Texinfo output ------------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
  ('index', 'BibtexParser', 'BibtexParser Documentation',
   'F. Boulogne', 'BibtexParser', 'One line description of project.',
   'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
python-bibtexparser-0.6.1/docs/source/index.rst000066400000000000000000000022671255747214700216450ustar00rootroot00000000000000.. BibtexParser documentation master file, created by
   sphinx-quickstart on Thu Aug  1 13:30:23 2013.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to BibtexParser's documentation!
========================================


:Author: François Boulogne and other contributors
:Download: `Stable version `_
:Developer's corner: `github.com project `_
:Generated: |today|
:License: LGPL v3 or BSD
:Version: |release|

BibtexParser is a python library to parse bibtex files. The code is tested with unittests.

If you use BibtexParser for your project, feel free to send me an email. I would be happy to hear that and to mention your project in the documentation.

Contents:

.. toctree::
    :maxdepth: 2

    install.rst
    tutorial.rst
    bibtexparser.rst
    logging.rst
    bibtex_conv.rst
    who.rst


Other projects
==============

* http://pybtex.sourceforge.net/
* http://pybliographer.org/
* https://github.com/matthew-brett/babybib

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

python-bibtexparser-0.6.1/docs/source/install.rst000066400000000000000000000010341255747214700221730ustar00rootroot00000000000000How to install?
===============

Requirements
------------

* python **2.7** or later
* python **3.2** or later

Package manager
---------------

* [Archlinux](https://aur.archlinux.org/packages/python-bibtexparser/)

PyPI
----

`See Pypi `_

To install with pip:

.. code-block:: sh

    pip install bibtexparser


Manual installation
-------------------

`Download `_ the archive.

.. code-block:: sh

    python setup.py install --root=/usr/local/bin


python-bibtexparser-0.6.1/docs/source/logging.rst000066400000000000000000000037571255747214700221710ustar00rootroot00000000000000Logging module to understand failures
=====================================

Syntax of bibtex files is simple but there are many possible variations. This library probably fails for some of them.

Bibtexparser includes a large quantity of debug messages which helps to understand why and where the parser fails.
The example below can be used to print these messages in the console.

.. code-block:: python

    import logging
    import logging.config

    logger = logging.getLogger(__name__)

    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s %(funcName)s:%(lineno)d: %(message)s'
            },
        },
        'handlers': {
            'default': {
                'level':'DEBUG',
                'formatter': 'standard',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            '': {
                'handlers': ['default'],
                'level': 'DEBUG',
                'formatter': 'standard',
                'propagate': True
            }
        }
    })


    if __name__ == '__main__':
        bibtex = """@ARTICLE{Cesar2013,
          author = {Jean César},
          title = {An amazing title},
          year = {2013},
          month = jan,
          volume = {12},
          pages = {12--23},
          journal = {Nice Journal},
          abstract = {This is an abstract. This line should be long enough to test
        	 multilines...},
          comments = {A comment},
          keywords = {keyword1, keyword2},
        }
        """

        with open('/tmp/bibtex.bib', 'w') as bibfile:
            bibfile.write(bibtex)

        from bibtexparser.bparser import BibTexParser

        with open('/tmp/bibtex.bib', 'r') as bibfile:
            bp = BibTexParser(bibfile.read())
            print(bp.get_entry_list())

I recommend you to use this output if you would like to report a bug.
python-bibtexparser-0.6.1/docs/source/tutorial.rst000066400000000000000000000202021255747214700223660ustar00rootroot00000000000000Tutorial
========

Preparing a BibTeX file
-----------------------

Prepare a BibTeX sample file for illustration purpose:

.. code-block:: python

    bibtex = """@ARTICLE{Cesar2013,
      author = {Jean César},
      title = {An amazing title},
      year = {2013},
      month = jan,
      volume = {12},
      pages = {12--23},
      journal = {Nice Journal},
      abstract = {This is an abstract. This line should be long enough to test
    	 multilines...},
      comments = {A comment},
      keywords = {keyword1, keyword2}
    }
    """

    with open('bibtex.bib', 'w') as bibfile:
        bibfile.write(bibtex)

Parsing the file into a bibliographic database object
-----------------------------------------------------

OK. Everything is in place. Let's parse the BibTeX file.

.. code-block:: python

    import bibtexparser

    with open('bibtex.bib') as bibtex_file:
        bibtex_str = bibtex_file.read()

    bib_database = bibtexparser.loads(bibtex_str)
    print(bib_database.entries)


It prints a list of dictionaries for reference entries, for example books, articles:

.. code-block:: python

    [{'journal': 'Nice Journal',
      'comments': 'A comment',
      'pages': '12--23',
      'month': 'jan',
      'abstract': 'This is an abstract. This line should be long enough to test\nmultilines...',
      'title': 'An amazing title',
      'year': '2013',
      'volume': '12',
      'ID': 'Cesar2013',
      'author': 'Jean César',
      'keyword': 'keyword1, keyword2',
      'ENTRYTYPE': 'article'}]

Note that, by convention, uppercase keys are auto-generated data, while lowercase keys come from the original bibtex file.

Alternatively, you can parse a file-like object directly like this:

.. code-block:: python

    import bibtexparser

    with open('bibtex.bib') as bibtex_file:
        bib_database = bibtexparser.load(bibtex_file)


Creating a BibTeX file or string
--------------------------------

The bibliographic data can be converted back into a BibTeX file like this:

.. code-block:: python

    import bibtexparser

    bibtex_str = bibtexparser.dumps(bib_database)


Customizations
--------------

By default, the parser does not alter the content of each field and keeps it as a simple string. There are many cases
where this is not desired. For example, instead of a string with a multiple of authors, it could be parsed as a list.

To modify field values during parsing, a callback function can be supplied to the parser which can be used to modify
BibTeX entries. The library includes several functions which may be used. Alternatively, you can read them to create
your own functions.

.. code-block:: python

    import bibtexparser
    from bibtexparser.bparser import BibTexParser
    from bibtexparser.customization import *

    # Let's define a function to customize our entries.
    # It takes a record and return this record.
    def customizations(record):
        """Use some functions delivered by the library

        :param record: a record
        :returns: -- customized record
        """
        record = type(record)
        record = author(record)
        record = editor(record)
        record = journal(record)
        record = keyword(record)
        record = link(record)
        record = page_double_hyphen(record)
        record = doi(record)
        return record

    with open('bibtex.bib') as bibtex_file:
        parser = BibTexParser()
        parser.customization = customizations
        bib_database = bibtexparser.load(bibtex_file, parser=parser)
        print(bib_database.entries)


If you think that you have a customization which could be useful to others, please share with us!


Accents and weird characters
----------------------------

Your bibtex may content accents and specific characters.
They are sometimes coded like this ``\'{e}`` but this is not the correct way, ``{\'e}`` is prefered. Moreover, you may want to manipulate ``é``. There is different situations:

* Case 1: you plan to use this library to work with latex and you assume that the original bibtex is clean. You have nothing to do.

* Case 2: you plan to use this library to work with latex but your bibtex is not really clean.

.. code-block:: python

    import bibtexparser
    from bibtexparser.bparser import BibTexParser
    from bibtexparser.customization import homogeneize_latex_encoding

    with open('bibtex.bib') as bibtex_file:
        parser = BibTexParser()
        parser.customization = homogeneize_latex_encoding
        bib_database = bibtexparser.load(bibtex_file, parser=parser)
        print(bib_database.entries)


* Case 3: you plan to use this library to work with something different and your bibtex is not really clean.
  Then, you probably want to use unicode.

.. code-block:: python

    import bibtexparser
    from bibtexparser.bparser import BibTexParser
    from bibtexparser.customization import convert_to_unicode

    with open('bibtex.bib') as bibtex_file:
        parser = BibTexParser()
        parser.customization = convert_to_unicode
        bib_database = bibtexparser.load(bibtex_file, parser=parser)
        print(bib_database.entries)


Note: if you want to mix different customization functions, you can write your own function.


Using the writer
----------------

In the first section we prepared a BibTeX sample file, we can prepare the same file using pure python and the ``BibTexWriter`` class.

.. code-block:: python

    from bibtexparser.bwriter import BibTexWriter
    from bibtexparser.bibdatabase import BibDatabase

    db = BibDatabase()
    db.entries = [
        {'journal': 'Nice Journal',
         'comments': 'A comment',
         'pages': '12--23',
         'month': 'jan',
         'abstract': 'This is an abstract. This line should be long enough to test\nmultilines...',
         'title': 'An amazing title',
         'year': '2013',
         'volume': '12',
         'id': 'Cesar2013',
         'author': 'Jean César',
         'keyword': 'keyword1, keyword2',
         'type': 'article'}]

    writer = BibTexWriter()
    with open('bibtex.bib', 'w') as bibfile:
        bibfile.write(writer.write(db))

This code generates the following file:

.. code-block:: latex

    @article{Cesar2013,
     abstract = {This is an abstract. This line should be long enough to test
    multilines...},
     author = {Jean César},
     comments = {A comment},
     journal = {Nice Journal},
     keyword = {keyword1, keyword2},
     month = {jan},
     pages = {12--23},
     title = {An amazing title},
     volume = {12},
     year = {2013}
    }

The writer also has several flags that can be enabled to customize the output file.
For example we can use ``indent`` and ``comma_first`` to customize the previous entry, first the code:

.. code-block:: python

    from bibtexparser.bwriter import BibTexWriter
    from bibtexparser.bibdatabase import BibDatabase

    db = BibDatabase()
    db.entries = [
        {'journal': 'Nice Journal',
         'comments': 'A comment',
         'pages': '12--23',
         'month': 'jan',
         'abstract': 'This is an abstract. This line should be long enough to test\nmultilines...',
         'title': 'An amazing title',
         'year': '2013',
         'volume': '12',
         'id': 'Cesar2013',
         'author': 'Jean César',
         'keyword': 'keyword1, keyword2',
         'type': 'article'}]

    writer = BibTexWriter()
    writer.indent = '    '     # indent entries with 4 spaces instead of one
    writer.comma_first = True  # place the comma at the beginning of the line
    with open('bibtex.bib', 'w') as bibfile:
        bibfile.write(writer.write(db))

This code results in the following, customized, file:

.. code-block:: latex

    @article{Cesar2013
    ,    abstract = {This is an abstract. This line should be long enough to test
    multilines...}
    ,    author = {Jean César}
    ,    comments = {A comment}
    ,    journal = {Nice Journal}
    ,    keyword = {keyword1, keyword2}
    ,    month = {jan}
    ,    pages = {12--23}
    ,    title = {An amazing title}
    ,    volume = {12}
    ,    year = {2013}
    }

Flags to the writer object can modify not only how an entry is printed but how several BibTeX entries are sorted and separated.
See the :ref:`bibtexparser_api` for the full list of flags.
python-bibtexparser-0.6.1/docs/source/who.rst000066400000000000000000000005601255747214700213250ustar00rootroot00000000000000Who uses BibtexParser?
======================

If your project uses BibtexParser, you can ask for the addition of a link in this list.

* http://timotheepoisot.fr/2013/11/10/shared-bibtex-file-markdown/
* https://github.com/Phyks/BMC
* http://aurelien.naldi.info/research/publications.html
* http://robot.kut.ac.kr/publications
* https://git.atelo.org/etlapale/bibgen
python-bibtexparser-0.6.1/setup.py000066400000000000000000000011751255747214700172630ustar00rootroot00000000000000#!/usr/bin/env python

try:
    from setuptools import setup
except ImportError as ex:
    print('[python-bibtexparser] setuptools not found. Falling back to distutils.core')
    from distutils.core import setup
from bibtexparser import __version__ as version

setup(
    name         = 'bibtexparser',
    version      = version,
    url          = "https://github.com/sciunto-org/python-bibtexparser",
    author       = "Francois Boulogne and other contributors",
    license      = "LGPLv3 or BSD",
    author_email = "fboulogne@sciunto.org",
    description  = "Bibtex parser for python 2 and 3",
    packages = ['bibtexparser'],
)
python-bibtexparser-0.6.1/tox.ini000066400000000000000000000001051255747214700170540ustar00rootroot00000000000000[tox]
envlist = py27,py34
[testenv]
deps = nose
commands = nosetests