diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 02e3b33..0fd888e 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -13,14 +13,20 @@ on: # Run by default Sunday morning at 3:30: # Scheduled workflows run on the latest commit on the default or base branch. # (from https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule) + # + # GitHub disables a scheduled workflow after 60 days without a commit to the + # repository, and disabling it stops the push and pull_request triggers too. + # If the badge goes stale, re-enable it on the Actions tab; workflow_dispatch + # below gives a way to run it by hand. - cron: "30 3 * * 0" + workflow_dispatch: jobs: lint: - name: Lint ubuntu-latest Py3.8 + name: Lint ubuntu-latest Py3.12 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Additional info about the build shell: bash run: | @@ -28,9 +34,9 @@ jobs: df -h ulimit -a # More info on options: https://github.com/conda-incubator/setup-miniconda - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: - python-version: 3.8 + python-version: "3.12" environment-file: devtools/conda-envs/test_env.yaml activate-environment: test auto-update-conda: false @@ -45,8 +51,9 @@ jobs: - name: Run linters shell: bash -l {0} run: | - flake8 reference_handler - yapf --diff --recursive reference_handler + black --extend-exclude '_version.py' --check --diff \ + reference_handler reference_handler/tests + flake8 --color never reference_handler reference_handler/tests test: name: Test ${{ matrix.os }} Py${{ matrix.python-version }} @@ -55,16 +62,16 @@ jobs: strategy: matrix: os: [macOS-latest, ubuntu-latest] - python-version: [3.7, 3.8] + python-version: ["3.11", "3.12"] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Additional info about the build shell: bash run: | uname -a df -h ulimit -a - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: python-version: ${{ matrix.python-version }} environment-file: devtools/conda-envs/test_env.yaml @@ -82,7 +89,7 @@ jobs: run: | pytest -v --cov=reference_handler --cov-report=xml --color=yes reference_handler/tests/ - name: CodeCov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: file: ./coverage.xml flags: unittests diff --git a/.github/workflows/Release.yaml b/.github/workflows/Release.yaml index 36639a6..a99f15e 100644 --- a/.github/workflows/Release.yaml +++ b/.github/workflows/Release.yaml @@ -17,10 +17,10 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: [3.8] + python-version: ["3.12"] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Additional info about the build shell: bash @@ -30,7 +30,7 @@ jobs: ulimit -a # More info on options: https://github.com/conda-incubator/setup-miniconda - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: python-version: ${{ matrix.python-version }} environment-file: devtools/conda-envs/test_env.yaml @@ -56,8 +56,9 @@ jobs: shell: bash -l {0} run: | - flake8 reference_handler reference_handler/tests - yapf --diff --recursive reference_handler + black --extend-exclude '_version.py' --check --diff \ + reference_handler reference_handler/tests + flake8 --color never reference_handler reference_handler/tests test: name: Test ${{ matrix.os }} Py${{ matrix.python-version }} @@ -66,10 +67,10 @@ jobs: strategy: matrix: os: [macOS-latest, ubuntu-latest] - python-version: [3.7, 3.8] + python-version: ["3.11", "3.12"] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Additional info about the build shell: bash @@ -80,7 +81,7 @@ jobs: # More info on options: https://github.com/conda-incubator/setup-miniconda - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: python-version: ${{ matrix.python-version }} environment-file: devtools/conda-envs/test_env.yaml @@ -107,7 +108,7 @@ jobs: pytest -v --cov=reference_handler --cov-report=xml --color=yes reference_handler/tests/ - name: CodeCov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: file: ./coverage.xml flags: unittests @@ -119,27 +120,25 @@ jobs: if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags') runs-on: ${{ matrix.os }} needs: [lint, test] + + # Trusted publishing: PyPI checks this token against the publisher registered + # for the project, so there is no API token to store or rotate. + permissions: + id-token: write + contents: read strategy: matrix: os: [ubuntu-latest] - python-version: [3.8] + python-version: ["3.12"] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Install package - - # conda setup requires this special shell - shell: bash -l {0} - run: | - python -m pip install . --no-deps - conda list - - name: Install pypa/build run: | python -m pip install build --user @@ -149,14 +148,5 @@ jobs: python -m build --sdist --wheel --outdir dist/ ls -l dist/ - - name: Publish distribution 📦 to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{ secrets.test_pypi_password }} - repository_url: https://test.pypi.org/legacy/ - skip_existing: true - - name: Publish distribution 📦 to PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{ secrets.pypi_password }} + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 81a1b4f..2b2de0e 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -1,11 +1,15 @@ name: test + channels: + - conda-forge + dependencies: # Base depends - python - pip # Testing + - black - codecov - coverage - flake8 @@ -16,7 +20,4 @@ dependencies: # Pip-only installs - pip: - bibtexparser<2 - - # Testing - - yapf diff --git a/reference_handler/__init__.py b/reference_handler/__init__.py index 7e93eff..d142fc0 100644 --- a/reference_handler/__init__.py +++ b/reference_handler/__init__.py @@ -12,6 +12,6 @@ from ._version import get_versions versions = get_versions() -__version__ = versions['version'] -__git_revision__ = versions['full-revisionid'] +__version__ = versions["version"] +__git_revision__ = versions["full-revisionid"] del get_versions, versions diff --git a/reference_handler/latex_utf8.py b/reference_handler/latex_utf8.py index a86eca8..6cf0034 100644 --- a/reference_handler/latex_utf8.py +++ b/reference_handler/latex_utf8.py @@ -70,54 +70,53 @@ import typing import unicodedata -alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" # LaTeX characters in accent macros of form \{}, i.e. \"{u} accent = { - '"': '\N{Combining Diaeresis}', - "'": '\N{Combining Acute Accent}', - '.': '\N{Combining Dot Above}', - '=': '\N{Combining Macron}', - '^': '\N{Combining Circumflex Accent}', - '`': '\N{Combining Grave Accent}', - '|': '\N{Combining Vertical Line Above}', - '~': '\N{Combining Tilde}', - 'b': '\N{Combining Macron Below}', - 'c': '\N{Combining Cedilla}', - 'C': '\N{Combining Double Grave Accent}', - 'd': '\N{Combining Dot Below}', - 'f': '\N{Combining Inverted Breve}', - 'h': '\N{Combining Hook Above}', - 'H': '\N{Combining Double Acute Accent}', - 'k': '\N{Combining Ogonek}', - 'r': '\N{Combining Ring Above}', - 't': '\N{Combining Double Inverted Breve}', - 'u': '\N{Combining Breve}', - 'U': '\N{Combining Double Vertical Line Above}', - 'v': '\N{Combining Caron}' + '"': "\N{COMBINING DIAERESIS}", + "'": "\N{COMBINING ACUTE ACCENT}", + ".": "\N{COMBINING DOT ABOVE}", + "=": "\N{COMBINING MACRON}", + "^": "\N{COMBINING CIRCUMFLEX ACCENT}", + "`": "\N{COMBINING GRAVE ACCENT}", + "|": "\N{COMBINING VERTICAL LINE ABOVE}", + "~": "\N{COMBINING TILDE}", + "b": "\N{COMBINING MACRON BELOW}", + "c": "\N{COMBINING CEDILLA}", + "C": "\N{COMBINING DOUBLE GRAVE ACCENT}", + "d": "\N{COMBINING DOT BELOW}", + "f": "\N{COMBINING INVERTED BREVE}", + "h": "\N{COMBINING HOOK ABOVE}", + "H": "\N{COMBINING DOUBLE ACUTE ACCENT}", + "k": "\N{COMBINING OGONEK}", + "r": "\N{COMBINING RING ABOVE}", + "t": "\N{COMBINING DOUBLE INVERTED BREVE}", + "u": "\N{COMBINING BREVE}", + "U": "\N{COMBINING DOUBLE VERTICAL LINE ABOVE}", + "v": "\N{COMBINING CARON}", } # The regexp to detect the LaTeX accent commands. The two added characters # are the dotless i and j. -accent_re = re.compile( - r'\\([' + ''.join(accent.keys()) + r']){([a-zA-Z\u0131\u0237])}' -) +accent_re = re.compile(r"\\([" + "".join(accent.keys()) + r"]){([a-zA-Z\u0131\u0237])}") # Invert the accent dictionary for each letter in the alphabet to make # a dictionary of LaTeX encodings. encoding = {} for key, val in accent.items(): for char in list(alphabet): - encoding[char + val] = '\\' + key + '{' + char + '}' + encoding[char + val] = "\\" + key + "{" + char + "}" # handle any precombined versions of the character - string = unicodedata.normalize('NFC', char + val) + string = unicodedata.normalize("NFC", char + val) if len(string) == 1: encoding[string] = encoding[char + val] for char in [ - '\N{Latin Small Letter Dotless I}', '\N{Latin Small Letter Dotless J}' + "\N{LATIN SMALL LETTER DOTLESS I}", + "\N{LATIN SMALL LETTER DOTLESS J}", ]: - encoding[char + val] = r'\%s{%s}' % (key, char) - string = unicodedata.normalize('NFC', char + val) + encoding[char + val] = r"\%s{%s}" % (key, char) + string = unicodedata.normalize("NFC", char + val) # These characters have no precombined versions, but check anyway if len(string) == 1: encoding[string] = encoding[char + val] @@ -137,20 +136,20 @@ def _decode_latex_accent(match: typing.Match) -> str: # LaTeX single character symbols symbol = { - 'i': '\N{Latin Small Letter Dotless I}', - 'j': '\N{Latin Small Letter Dotless J}', - 'l': '\N{Latin Small Letter L With Stroke}', - 'L': '\N{Latin Capital Letter L With Stroke}', - 'o': '\N{Latin Small Letter O With Stroke}', - 'O': '\N{Latin Capital Letter O With Stroke}' + "i": "\N{LATIN SMALL LETTER DOTLESS I}", + "j": "\N{LATIN SMALL LETTER DOTLESS J}", + "l": "\N{LATIN SMALL LETTER L WITH STROKE}", + "L": "\N{LATIN CAPITAL LETTER L WITH STROKE}", + "o": "\N{LATIN SMALL LETTER O WITH STROKE}", + "O": "\N{LATIN CAPITAL LETTER O WITH STROKE}", } # The regexp to detect the LaTeX commands for special characters -symbol_re = re.compile(r'\\([' + ''.join(symbol.keys()) + '])') +symbol_re = re.compile(r"\\([" + "".join(symbol.keys()) + "])") # Invert the symbol dictionary to make a dictionary of LaTeX encodings. for key, val in symbol.items(): - encoding[val] = '\\' + key + encoding[val] = "\\" + key def _decode_latex_symbol(match: typing.Match) -> str: @@ -166,10 +165,10 @@ def _decode_latex_symbol(match: typing.Match) -> str: # LaTeX dashes -dash = {'--': '\N{EN Dash}', '---': '\N{EM Dash}'} +dash = {"--": "\N{EN DASH}", "---": "\N{EM DASH}"} # The regexp to detect the LaTeX commands for dashes -dash_re = re.compile(r'([^-]?)(-{2,3})([^-]?)') +dash_re = re.compile(r"([^-]?)(-{2,3})([^-]?)") # Invert the dictionary tomake a dictionary of LaTeX encodings. for key, val in dash.items(): @@ -205,13 +204,11 @@ def decode_latex(text: str) -> str: """ return brace_re.sub( - r'\1', + r"\1", accent_re.sub( _decode_latex_accent, - symbol_re.sub( - _decode_latex_symbol, dash_re.sub(_decode_latex_dash, text) - ) - ) + symbol_re.sub(_decode_latex_symbol, dash_re.sub(_decode_latex_dash, text)), + ), ) @@ -228,7 +225,7 @@ def encode_latex(text: str) -> str: """ # Map the double character representations - text2 = '' + text2 = "" char1 = text[0] i = 1 len_text = len(text) @@ -250,7 +247,7 @@ def encode_latex(text: str) -> str: text2 += char1 # Map the single characters representations - result = '' + result = "" for char in list(text2): if char in encoding: result += encoding[char] @@ -260,7 +257,7 @@ def encode_latex(text: str) -> str: return result -if __name__ == '__main__': # pragma: no cover +if __name__ == "__main__": # pragma: no cover text = r""" (Vorlova_2015) Barbora Vorlov{\'{a}} and Dana Nachtigallov{\'{a}} and Jana Jir{\'{a}}skov{\'{a}}-Van{\'{\i}}{\v{c}}kov{\'{a}} and Haresh Ajani and Petr diff --git a/reference_handler/reference_handler.py b/reference_handler/reference_handler.py index 566ef6f..8b02eb7 100644 --- a/reference_handler/reference_handler.py +++ b/reference_handler/reference_handler.py @@ -13,143 +13,143 @@ from .latex_utf8 import decode_latex from .utils import entry_to_bibtex -supported_fmts = ['bibtex', 'text'] +supported_fmts = ["bibtex", "text"] # '-' must be first for the regex to work. subscript = { - '-': '\N{Subscript Minus}', - '0': '\N{Subscript Zero}', - '1': '\N{Subscript One}', - '2': '\N{Subscript Two}', - '3': '\N{Subscript Three}', - '4': '\N{Subscript Four}', - '5': '\N{Subscript Five}', - '6': '\N{Subscript Six}', - '7': '\N{Subscript Seven}', - '8': '\N{Subscript Eight}', - '9': '\N{Subscript Nine}', - '+': '\N{Subscript Plus Sign}', - '=': '\N{Subscript Equals Sign}', - '(': '\N{Subscript Left Parenthesis}', - ')': '\N{Subscript Right Parenthesis}', - 'a': '\N{Latin Subscript Small Letter A}', - 'e': '\N{Latin Subscript Small Letter E}', - 'o': '\N{Latin Subscript Small Letter O}', - 'x': '\N{Latin Subscript Small Letter X}', - 'h': '\N{Latin Subscript Small Letter H}', - 'k': '\N{Latin Subscript Small Letter K}', - 'l': '\N{Latin Subscript Small Letter L}', - 'm': '\N{Latin Subscript Small Letter M}', - 'n': '\N{Latin Subscript Small Letter N}', - 'p': '\N{Latin Subscript Small Letter P}', - 's': '\N{Latin Subscript Small Letter S}', - 't': '\N{Latin Subscript Small Letter T}', - 'i': '\N{Latin Subscript Small Letter I}', - 'r': '\N{Latin Subscript Small Letter R}', - 'u': '\N{Latin Subscript Small Letter U}', - 'v': '\N{Latin Subscript Small Letter V}', - r'.': '.' + "-": "\N{SUBSCRIPT MINUS}", + "0": "\N{SUBSCRIPT ZERO}", + "1": "\N{SUBSCRIPT ONE}", + "2": "\N{SUBSCRIPT TWO}", + "3": "\N{SUBSCRIPT THREE}", + "4": "\N{SUBSCRIPT FOUR}", + "5": "\N{SUBSCRIPT FIVE}", + "6": "\N{SUBSCRIPT SIX}", + "7": "\N{SUBSCRIPT SEVEN}", + "8": "\N{SUBSCRIPT EIGHT}", + "9": "\N{SUBSCRIPT NINE}", + "+": "\N{SUBSCRIPT PLUS SIGN}", + "=": "\N{SUBSCRIPT EQUALS SIGN}", + "(": "\N{SUBSCRIPT LEFT PARENTHESIS}", + ")": "\N{SUBSCRIPT RIGHT PARENTHESIS}", + "a": "\N{LATIN SUBSCRIPT SMALL LETTER A}", + "e": "\N{LATIN SUBSCRIPT SMALL LETTER E}", + "o": "\N{LATIN SUBSCRIPT SMALL LETTER O}", + "x": "\N{LATIN SUBSCRIPT SMALL LETTER X}", + "h": "\N{LATIN SUBSCRIPT SMALL LETTER H}", + "k": "\N{LATIN SUBSCRIPT SMALL LETTER K}", + "l": "\N{LATIN SUBSCRIPT SMALL LETTER L}", + "m": "\N{LATIN SUBSCRIPT SMALL LETTER M}", + "n": "\N{LATIN SUBSCRIPT SMALL LETTER N}", + "p": "\N{LATIN SUBSCRIPT SMALL LETTER P}", + "s": "\N{LATIN SUBSCRIPT SMALL LETTER S}", + "t": "\N{LATIN SUBSCRIPT SMALL LETTER T}", + "i": "\N{LATIN SUBSCRIPT SMALL LETTER I}", + "r": "\N{LATIN SUBSCRIPT SMALL LETTER R}", + "u": "\N{LATIN SUBSCRIPT SMALL LETTER U}", + "v": "\N{LATIN SUBSCRIPT SMALL LETTER V}", + r".": ".", } -subscript_re = re.compile(r'\$_([' + ''.join(subscript.keys()) + r']+)\$') +subscript_re = re.compile(r"\$_([" + "".join(subscript.keys()) + r"]+)\$") # '-' must be first for the regex to work. superscript = { - '-': '\N{Superscript Minus}', - '0': '\N{Superscript Zero}', - '1': '\N{Superscript One}', - '2': '\N{Superscript Two}', - '3': '\N{Superscript Three}', - '4': '\N{Superscript Four}', - '5': '\N{Superscript Five}', - '6': '\N{Superscript Six}', - '7': '\N{Superscript Seven}', - '8': '\N{Superscript Eight}', - '9': '\N{Superscript Nine}', - '+': '\N{Superscript Plus Sign}', - '=': '\N{Superscript Equals Sign}', - '(': '\N{Superscript Left Parenthesis}', - ')': '\N{Superscript Right Parenthesis}', - 'a': '\N{Feminine Ordinal Indicator}', - 'b': 'ᵇ', - 'c': 'ᶜ', - 'd': 'ᵈ', - 'e': 'ᵉ', - 'f': 'ᶠ', - 'g': 'ᵍ', - 'h': 'ʰ', - 'i': 'ⁱ', - 'j': 'ʲ', - 'k': 'ᵏ', - 'l': 'ˡ', - 'm': 'ᵐ', - 'n': 'ⁿ', - 'o': '\N{Masculine Ordinal Indicator}', - 'p': 'ᵖ', - 'r': 'ʳ', - 's': 'ˢ', - 't': 'ᵗ', - 'u': 'ᵘ', - 'v': 'ᵛ', - 'w': 'ʷ', - 'x': 'ˣ', - 'y': 'ʸ', - 'z': 'ᶻ' + "-": "\N{SUPERSCRIPT MINUS}", + "0": "\N{SUPERSCRIPT ZERO}", + "1": "\N{SUPERSCRIPT ONE}", + "2": "\N{SUPERSCRIPT TWO}", + "3": "\N{SUPERSCRIPT THREE}", + "4": "\N{SUPERSCRIPT FOUR}", + "5": "\N{SUPERSCRIPT FIVE}", + "6": "\N{SUPERSCRIPT SIX}", + "7": "\N{SUPERSCRIPT SEVEN}", + "8": "\N{SUPERSCRIPT EIGHT}", + "9": "\N{SUPERSCRIPT NINE}", + "+": "\N{SUPERSCRIPT PLUS SIGN}", + "=": "\N{SUPERSCRIPT EQUALS SIGN}", + "(": "\N{SUPERSCRIPT LEFT PARENTHESIS}", + ")": "\N{SUPERSCRIPT RIGHT PARENTHESIS}", + "a": "\N{FEMININE ORDINAL INDICATOR}", + "b": "ᵇ", + "c": "ᶜ", + "d": "ᵈ", + "e": "ᵉ", + "f": "ᶠ", + "g": "ᵍ", + "h": "ʰ", + "i": "ⁱ", + "j": "ʲ", + "k": "ᵏ", + "l": "ˡ", + "m": "ᵐ", + "n": "ⁿ", + "o": "\N{MASCULINE ORDINAL INDICATOR}", + "p": "ᵖ", + "r": "ʳ", + "s": "ˢ", + "t": "ᵗ", + "u": "ᵘ", + "v": "ᵛ", + "w": "ʷ", + "x": "ˣ", + "y": "ʸ", + "z": "ᶻ", } -superscript_re = re.compile(r'\$\^([' + ''.join(superscript.keys()) + r']+)\$') +superscript_re = re.compile(r"\$\^([" + "".join(superscript.keys()) + r"]+)\$") greek_symbol = { - 'alpha': '\N{Greek Small Letter Alpha}', - 'beta': '\N{Greek Small Letter Beta}', - 'gamma': '\N{Greek Small Letter Gamma}', - 'delta': '\N{Greek Small Letter Delta}', - 'epsilon': '\N{Greek Small Letter Epsilon}', - 'zeta': '\N{Greek Small Letter Zeta}', - 'eta': '\N{Greek Small Letter Eta}', - 'theta': '\N{Greek Small Letter Theta}', - 'iota': '\N{Greek Small Letter Iota}', - 'kappa': '\N{Greek Small Letter Kappa}', - 'lamda': '\N{Greek Small Letter Lamda}', - 'lambda': '\N{Greek Small Letter Lamda}', - 'mu': '\N{Greek Small Letter Mu}', - 'nu': '\N{Greek Small Letter Nu}', - 'xi': '\N{Greek Small Letter Xi}', - 'omicron': '\N{Greek Small Letter Omicron}', - 'pi': '\N{Greek Small Letter Pi}', - 'rho': '\N{Greek Small Letter Rho}', - 'sigma': '\N{Greek Small Letter Sigma}', - 'tau': '\N{Greek Small Letter Tau}', - 'upsilon': '\N{Greek Small Letter Upsilon}', - 'phi': '\N{Greek Small Letter Phi}', - 'chi': '\N{Greek Small Letter Chi}', - 'psi': '\N{Greek Small Letter Psi}', - 'omega': '\N{Greek Small Letter Omega}', - 'Alpha': '\N{Greek Capital Letter Alpha}', - 'Beta': '\N{Greek Capital Letter Beta}', - 'Gamma': '\N{Greek Capital Letter Gamma}', - 'Delta': '\N{Greek Capital Letter Delta}', - 'Epsilon': '\N{Greek Capital Letter Epsilon}', - 'Zeta': '\N{Greek Capital Letter Zeta}', - 'Eta': '\N{Greek Capital Letter Eta}', - 'Theta': '\N{Greek Capital Letter Theta}', - 'Iota': '\N{Greek Capital Letter Iota}', - 'Kappa': '\N{Greek Capital Letter Kappa}', - 'Lamda': '\N{Greek Capital Letter Lamda}', - 'Lambda': '\N{Greek Capital Letter Lamda}', - 'Mu': '\N{Greek Capital Letter Mu}', - 'Nu': '\N{Greek Capital Letter Nu}', - 'Xi': '\N{Greek Capital Letter Xi}', - 'Omicron': '\N{Greek Capital Letter Omicron}', - 'Pi': '\N{Greek Capital Letter Pi}', - 'Rho': '\N{Greek Capital Letter Rho}', - 'Sigma': '\N{Greek Capital Letter Sigma}', - 'Tau': '\N{Greek Capital Letter Tau}', - 'Upsilon': '\N{Greek Capital Letter Upsilon}', - 'Phi': '\N{Greek Capital Letter Phi}', - 'Chi': '\N{Greek Capital Letter Chi}', - 'Psi': '\N{Greek Capital Letter Psi}', - 'Omega': '\N{Greek Capital Letter Omega}', + "alpha": "\N{GREEK SMALL LETTER ALPHA}", + "beta": "\N{GREEK SMALL LETTER BETA}", + "gamma": "\N{GREEK SMALL LETTER GAMMA}", + "delta": "\N{GREEK SMALL LETTER DELTA}", + "epsilon": "\N{GREEK SMALL LETTER EPSILON}", + "zeta": "\N{GREEK SMALL LETTER ZETA}", + "eta": "\N{GREEK SMALL LETTER ETA}", + "theta": "\N{GREEK SMALL LETTER THETA}", + "iota": "\N{GREEK SMALL LETTER IOTA}", + "kappa": "\N{GREEK SMALL LETTER KAPPA}", + "lamda": "\N{GREEK SMALL LETTER LAMDA}", + "lambda": "\N{GREEK SMALL LETTER LAMDA}", + "mu": "\N{GREEK SMALL LETTER MU}", + "nu": "\N{GREEK SMALL LETTER NU}", + "xi": "\N{GREEK SMALL LETTER XI}", + "omicron": "\N{GREEK SMALL LETTER OMICRON}", + "pi": "\N{GREEK SMALL LETTER PI}", + "rho": "\N{GREEK SMALL LETTER RHO}", + "sigma": "\N{GREEK SMALL LETTER SIGMA}", + "tau": "\N{GREEK SMALL LETTER TAU}", + "upsilon": "\N{GREEK SMALL LETTER UPSILON}", + "phi": "\N{GREEK SMALL LETTER PHI}", + "chi": "\N{GREEK SMALL LETTER CHI}", + "psi": "\N{GREEK SMALL LETTER PSI}", + "omega": "\N{GREEK SMALL LETTER OMEGA}", + "Alpha": "\N{GREEK CAPITAL LETTER ALPHA}", + "Beta": "\N{GREEK CAPITAL LETTER BETA}", + "Gamma": "\N{GREEK CAPITAL LETTER GAMMA}", + "Delta": "\N{GREEK CAPITAL LETTER DELTA}", + "Epsilon": "\N{GREEK CAPITAL LETTER EPSILON}", + "Zeta": "\N{GREEK CAPITAL LETTER ZETA}", + "Eta": "\N{GREEK CAPITAL LETTER ETA}", + "Theta": "\N{GREEK CAPITAL LETTER THETA}", + "Iota": "\N{GREEK CAPITAL LETTER IOTA}", + "Kappa": "\N{GREEK CAPITAL LETTER KAPPA}", + "Lamda": "\N{GREEK CAPITAL LETTER LAMDA}", + "Lambda": "\N{GREEK CAPITAL LETTER LAMDA}", + "Mu": "\N{GREEK CAPITAL LETTER MU}", + "Nu": "\N{GREEK CAPITAL LETTER NU}", + "Xi": "\N{GREEK CAPITAL LETTER XI}", + "Omicron": "\N{GREEK CAPITAL LETTER OMICRON}", + "Pi": "\N{GREEK CAPITAL LETTER PI}", + "Rho": "\N{GREEK CAPITAL LETTER RHO}", + "Sigma": "\N{GREEK CAPITAL LETTER SIGMA}", + "Tau": "\N{GREEK CAPITAL LETTER TAU}", + "Upsilon": "\N{GREEK CAPITAL LETTER UPSILON}", + "Phi": "\N{GREEK CAPITAL LETTER PHI}", + "Chi": "\N{GREEK CAPITAL LETTER CHI}", + "Psi": "\N{GREEK CAPITAL LETTER PSI}", + "Omega": "\N{GREEK CAPITAL LETTER OMEGA}", } -greek_symbol_re = re.compile(r'\$\\(' + '|'.join(greek_symbol.keys()) + r')\$') +greek_symbol_re = re.compile(r"\$\\(" + "|".join(greek_symbol.keys()) + r")\$") class Reference_Handler(object): @@ -173,7 +173,7 @@ def __del__(self): pass # print('Database was already closed.') - def dump(self, outfile=None, fmt='bibtex', level=3): + def dump(self, outfile=None, fmt="bibtex", level=3): """ Retrieves the individual citations that were collected during the execution of a program and tallies the number of times each citation @@ -199,15 +199,14 @@ def dump(self, outfile=None, fmt='bibtex', level=3): """ if fmt not in supported_fmts: - raise NameError('Format %s not currently supported.' % (fmt)) + raise NameError("Format %s not currently supported." % (fmt)) if fmt not in supported_fmts: - raise NameError('Format %s not currently supported.' % (fmt)) + raise NameError("Format %s not currently supported." % (fmt)) if level not in range(1, 4) and level is not None: raise ValueError( - 'Invalid value for level. Please input a value in the range ' - '[1,3]' + "Invalid value for level. Please input a value in the range [1,3]" ) self.cur.execute( @@ -220,46 +219,49 @@ def dump(self, outfile=None, fmt='bibtex', level=3): GROUP BY reference_id ) t2 ON t1.id = t2.reference_id WHERE counts > 0 ORDER BY counts DESC - """, (level,) + """, + (level,), ) query = self.cur.fetchall() - if fmt == 'bibtex': + if fmt == "bibtex": ret = query if outfile is not None: if type(outfile) is not str: raise TypeError( - 'The name of the output file must be a string but it ' - 'is %s' % type(outfile) + "The name of the output file must be a string but it " + "is %s" % type(outfile) ) - with open(outfile, 'w') as f: + with open(outfile, "w") as f: for item in query: - f.write('TOTAL_MENTIONS: %s \n' % str(item[2])) - f.write('LEVEL: %s \n' % str(item[3])) + f.write("TOTAL_MENTIONS: %s \n" % str(item[2])) + f.write("LEVEL: %s \n" % str(item[3])) f.write(item[1]) - elif fmt == 'text': + elif fmt == "text": ret = [] for item in query: parse = bibtexparser.loads(item[1]).entries[0] - entry_type = parse['ENTRYTYPE'] - if entry_type == 'misc': + entry_type = parse["ENTRYTYPE"] + if entry_type == "misc": plain_text = self.format_misc(parse) - elif entry_type == 'article': + elif entry_type == "software": + plain_text = self.format_software(parse) + elif entry_type == "article": plain_text = self.format_article(parse) - elif entry_type == 'inbook': + elif entry_type == "inbook": plain_text = self.format_inbook(parse) - elif entry_type == 'phdthesis': + elif entry_type == "phdthesis": plain_text = self.format_phdthesis(parse) else: plain_text = f"Do not have a handler for '{entry_type}':" - plain_text += '\n' + plain_text += "\n" plain_text += pprint.pformat(parse) plain_text = decode_latex(plain_text) @@ -269,7 +271,7 @@ def dump(self, outfile=None, fmt='bibtex', level=3): return ret @staticmethod - def load_bibliography(bibfile=None, fmt='bibtex'): + def load_bibliography(bibfile=None, fmt="bibtex"): """ Utility function to read a bibliographic file in common formats. The current supported formats are BibTeX. @@ -293,19 +295,19 @@ def load_bibliography(bibfile=None, fmt='bibtex'): """ if bibfile is None: - raise FileNotFoundError('A bibliography file must be specified.') + raise FileNotFoundError("A bibliography file must be specified.") if fmt not in supported_fmts: - raise NameError('Format %s not currently supported.' % (fmt)) + raise NameError("Format %s not currently supported." % (fmt)) - with open(bibfile, 'r') as f: + with open(bibfile, "r") as f: parser = bibtexparser.bparser.BibTexParser(common_strings=True) bibliography = bibtexparser.load(f, parser=parser).entries - ret = {k['ID']: {} for k in bibliography} + ret = {k["ID"]: {} for k in bibliography} for entry in bibliography: - ret[entry['ID']] = entry_to_bibtex(entry) + ret[entry["ID"]] = entry_to_bibtex(entry) return ret @@ -316,8 +318,8 @@ def cite( module=None, level=1, note=None, - fmt='bibtex', - doi=None + fmt="bibtex", + doi=None, ): """ Adds a given reference to the internal database. @@ -353,8 +355,7 @@ def cite( if alias is None or raw is None or module is None or note is None: raise NameError( - 'Need to provide the "alias", "raw", "module" and "note" ' - 'arguments' + 'Need to provide the "alias", "raw", "module" and "note" arguments' ) doi = self._extract_doi(raw, fmt) @@ -365,25 +366,16 @@ def cite( self._create_citation(raw=raw, alias=alias, doi=doi) reference_id = self.cur.lastrowid self._create_context( - reference_id=reference_id, - module=module, - note=note, - level=level + reference_id=reference_id, module=module, note=note, level=level ) else: context_id = self._get_context_id( - reference_id=reference_id, - module=module, - note=note, - level=level + reference_id=reference_id, module=module, note=note, level=level ) if context_id is None: self._create_context( - reference_id=reference_id, - module=module, - note=note, - level=level + reference_id=reference_id, module=module, note=note, level=level ) else: self._update_counter(context_id=context_id) @@ -404,47 +396,38 @@ def _update_counter(self, context_id=None): "UPDATE context SET count = count + 1 WHERE id=?;", (context_id,) ) - def _extract_doi(self, raw=None, fmt='bibtex'): + def _extract_doi(self, raw=None, fmt="bibtex"): """ Parses DOI from bibliographic format """ if fmt not in supported_fmts: - raise NameError('Format %s not currently supported.' % (fmt)) + raise NameError("Format %s not currently supported." % (fmt)) - if fmt == 'bibtex': + if fmt == "bibtex": ret = bibtexparser.loads(raw) ret = ret.entries[0] - if 'doi' in ret.keys(): - return ret['doi'] + if "doi" in ret.keys(): + return ret["doi"] def _initialize_tables(self): """ Initializes the citation and context tables """ - self.cur.execute( - """CREATE TABLE IF NOT EXISTS "citation" ( + self.cur.execute("""CREATE TABLE IF NOT EXISTS "citation" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT, "alias" TEXT NOT NULL UNIQUE, "raw" TEXT NOT NULL UNIQUE, "doi" TEXT UNIQUE ); - """ - ) + """) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_raw on citation (raw);" - ) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_alias on citation (alias);" - ) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_doi on citation (doi);" - ) + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_raw on citation (raw);") + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_alias on citation (alias);") + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_doi on citation (doi);") - self.cur.execute( - """ + self.cur.execute(""" CREATE TABLE IF NOT EXISTS "context" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT, "reference_id" INTEGER NOT NULL, @@ -454,21 +437,14 @@ def _initialize_tables(self): "level" INTEGER NOT NULL, FOREIGN KEY(reference_id) REFERENCES Citation(id) ); - """ - ) + """) self.cur.execute( "CREATE INDEX IF NOT EXISTS idx_refid on context (reference_id);" ) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_module on context (module);" - ) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_count on context (count);" - ) - self.cur.execute( - "CREATE INDEX IF NOT EXISTS idx_level on context (level);" - ) + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_module on context (module);") + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_count on context (count);") + self.cur.execute("CREATE INDEX IF NOT EXISTS idx_level on context (level);") self.conn.commit() @@ -484,13 +460,9 @@ def _get_reference_id(self, raw=None, alias=None, doi=None): 'Variables "raw" or "alias" or "DOI" must be input.' ) else: - self.cur.execute( - "SELECT id FROM citation WHERE doi=?;" (doi,) - ) + self.cur.execute("SELECT id FROM citation WHERE doi=?;", (doi,)) else: - self.cur.execute( - "SELECT id FROM citation WHERE alias=?;" (alias,) - ) + self.cur.execute("SELECT id FROM citation WHERE alias=?;", (alias,)) else: self.cur.execute("SELECT id FROM citation WHERE raw=?;", (raw,)) @@ -501,18 +473,13 @@ def _get_reference_id(self, raw=None, alias=None, doi=None): return ret[0][0] - def _get_context_id( - self, reference_id=None, module=None, note=None, level=None - ): + def _get_context_id(self, reference_id=None, module=None, note=None, level=None): """ Gets the ID of the context if exists. A context is specified by (reference_id, module, note, level) combination """ - if ( - reference_id is None or module is None or note is None or - level is None - ): + if reference_id is None or module is None or note is None or level is None: raise NameError( 'The variables "reference_id" and "module" and "note" and ' '"level" must be specified' @@ -520,7 +487,8 @@ def _get_context_id( self.cur.execute( "SELECT id FROM context WHERE reference_id=? AND module=? AND " - "note=? AND level=?;", (reference_id, module, note, level) + "note=? AND level=?;", + (reference_id, module, note, level), ) ret = self.cur.fetchall() @@ -536,18 +504,16 @@ def _create_citation(self, raw=None, alias=None, doi=None): """ if raw is None or alias is None: - raise NameError('The value for raw and alias must be provided') + raise NameError("The value for raw and alias must be provided") else: self.cur.execute( "INSERT INTO citation (raw, alias, doi) VALUES (?, ?, ?);", - (raw, alias, doi) + (raw, alias, doi), ) self.conn.commit() - def _create_context( - self, reference_id=None, module=None, note=None, level=None - ): + def _create_context(self, reference_id=None, module=None, note=None, level=None): """ Adds a new record to the context table using the combination of the provided arguments. @@ -558,7 +524,8 @@ def _create_context( self.cur.execute( "INSERT INTO context (reference_id, module, note, count, level) " - "VALUES (?, ?, ?, ?, ?)", (reference_id, module, note, 1, level) + "VALUES (?, ?, ?, ?, ?)", + (reference_id, module, note, 1, level), ) self.conn.commit() @@ -569,9 +536,7 @@ def total_mentions(self, reference_id=None, alias=None): """ if reference_id is None: if alias is None: - raise NameError( - "The 'reference_id' or 'alias' must be provided." - ) + raise NameError("The 'reference_id' or 'alias' must be provided.") else: self.cur.execute( """ @@ -583,7 +548,8 @@ def total_mentions(self, reference_id=None, alias=None): ) t2 ON t1.id = t2.reference_id WHERE alias = ? - """, (alias,) + """, + (alias,), ) else: @@ -597,7 +563,8 @@ def total_mentions(self, reference_id=None, alias=None): ) t2 ON t1.id = t2.reference_id WHERE id = ? - """, (reference_id,) + """, + (reference_id,), ) ret = self.cur.fetchall() @@ -658,13 +625,13 @@ def total_contexts(self, reference_id=None, alias=None): SELECT id, reference_id FROM context ) t2 ON citation.id = t2.reference_id WHERE alias=? - """, (alias,) + """, + (alias,), ) else: self.cur.execute( - "SELECT COUNT(*) FROM context WHERE reference_id = ?;", - (reference_id,) + "SELECT COUNT(*) FROM context WHERE reference_id = ?;", (reference_id,) ) return self.cur.fetchall()[0][0] @@ -683,22 +650,22 @@ def format_article(self, data): DOI: 10.1021/jacs.8b08648 """ - result = '' - if 'author' in data: - result += '; '.join(data['author'].split(' and ')) - if result[-1] != '.': - result += '.' - if 'title' in data: - result += ' ' + data['title'].rstrip('.') + '.' - if 'journal' in data: - result += ' ' + data['journal'] - if 'year' in data: + result = "" + if "author" in data: + result += "; ".join(data["author"].split(" and ")) + if result[-1] != ".": + result += "." + if "title" in data: + result += " " + data["title"].rstrip(".") + "." + if "journal" in data: + result += " " + data["journal"] + if "year" in data: result += f" {data['year']}," - if 'volume' in data: + if "volume" in data: result += f" {data['volume']}," - if 'pages' in data: + if "pages" in data: result += f" {data['pages']}." - if 'doi' in data: + if "doi" in data: result += f" DOI: {data['doi']}" return result @@ -715,23 +682,23 @@ def format_phdthesis(self, data): (accessed 2019-09-10). """ - result = '' - if 'author' in data: - result += '; '.join(data['author'].split(' and ')) - if result[-1] != '.': - result += '.' - if 'title' in data: - result += ' ' + data['title'].rstrip('.') + '.' + result = "" + if "author" in data: + result += "; ".join(data["author"].split(" and ")) + if result[-1] != ".": + result += "." + if "title" in data: + result += " " + data["title"].rstrip(".") + "." result += " Ph.D. Dissertation" - if 'school' in data: + if "school" in data: result += f", {data['school']}" - if 'address' in data: + if "address" in data: result += f", {data['address']}" - if 'year' in data: + if "year" in data: result += f", {data['year']}." - if 'url' in data: + if "url" in data: result += f", {data['url']}" - if 'doi' in data: + if "doi" in data: result += f", DOI: {data['doi']}" return result @@ -747,30 +714,34 @@ def format_misc(self, data): University: Pittsburgh, PA, 1982. """ - result = '' + result = "" - if 'author' in data: - result += '; '.join(data['author'].split(' and ')) - if result[-1] != '.': - result += '.' - if 'title' in data: - result += ' ' + data['title'] - if 'version' in data: + if "author" in data: + result += "; ".join(data["author"].split(" and ")) + if result[-1] != ".": + result += "." + result += " " + if "title" in data: + result += data["title"] + if "version" in data: result += f", version {data['version']};" else: - result += ';' + result += ";" - if 'organization' in data: - result += ' ' + data['organization'] - if 'address' in data: + if "organization" in data: + result += " " + data["organization"] + if "address" in data: result += f": {data['address']}" - if 'url' in data: + if "url" in data: result += f", {data['url']}" - if 'doi' in data: + if "doi" in data: result += f", DOI: {data['doi']}" return result + def format_software(self, data): + return self.format_misc(self, data) + def format_inbook(self, data): """Format a chapter or part of a book or series BibTex record @@ -786,26 +757,26 @@ def format_inbook(self, data): 2018; pp 33−44. DOI: 10.1021/bk-2018-1295.ch003 """ - result = '' - if 'author' in data: - result += '; '.join(data['author'].split(' and ')) - if result[-1] != '.': - result += '.' - if 'title' in data: - result += ' ' + data['title'].rstrip('.') + '. In' - if 'booktitle' in data: + result = "" + if "author" in data: + result += "; ".join(data["author"].split(" and ")) + if result[-1] != ".": + result += "." + if "title" in data: + result += " " + data["title"].rstrip(".") + ". In" + if "booktitle" in data: result += f" {data['booktitle']}" - if 'series' in data: + if "series" in data: result += f"; {data['series']}" - if 'publisher' in data: + if "publisher" in data: result += f"; {data['publisher']}" - if 'place' in data: + if "place" in data: result += f", {data['place']}" - if 'year' in data: + if "year" in data: result += f", {data['year']}." - if 'url' in data: + if "url" in data: result += f", {data['url']}" - if 'doi' in data: + if "doi" in data: result += f", DOI: {data['doi']}" return result @@ -817,13 +788,13 @@ def decode_math_symbols(self, text): return subscript_re.sub(self._decode_subscript, text) def _decode_subscript(self, match): - result = '' + result = "" for digit in list(match[1]): result += subscript[digit] return result def _decode_superscript(self, match): - result = '' + result = "" for digit in list(match[1]): result += superscript[digit] return result diff --git a/reference_handler/tests/test_exceptions.py b/reference_handler/tests/test_exceptions.py index 81cfe29..c9e7a26 100644 --- a/reference_handler/tests/test_exceptions.py +++ b/reference_handler/tests/test_exceptions.py @@ -9,7 +9,7 @@ from . import build_filenames from inspect import signature -database = build_filenames.build_data_filename('database.db') +database = build_filenames.build_data_filename("database.db") lammps_citation = """ @article{PLIMPTON19951, @@ -47,10 +47,8 @@ def _create_db(): """Boiler plate""" - database_name = 'tmp.db' - database = build_filenames.build_scratch_filename( - database_name - ) # noqa: F821 + database_name = "tmp.db" + database = build_filenames.build_scratch_filename(database_name) # noqa: F821 if os.path.exists(database): os.remove(database) @@ -58,20 +56,19 @@ def _create_db(): @pytest.fixture( - scope='function', + scope="function", params=[ - x for x in range( - len( - signature(reference_handler.Reference_Handler.cite).parameters - ) - 1 + x + for x in range( + len(signature(reference_handler.Reference_Handler.cite).parameters) - 1 ) - ] + ], ) def create_test_arg(request): test_arg = [None] * ( len(signature(reference_handler.Reference_Handler.cite).parameters) - 1 ) - test_arg[request.param] = 'string' + test_arg[request.param] = "string" yield tuple(test_arg) diff --git a/reference_handler/tests/test_latex.py b/reference_handler/tests/test_latex.py index 14af3ea..943c9c7 100644 --- a/reference_handler/tests/test_latex.py +++ b/reference_handler/tests/test_latex.py @@ -8,378 +8,378 @@ from reference_handler import encode_latex import sys -alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" def test_latex_utf8_imported(): """Sample test, will always pass so long as import statement worked""" - assert 'reference_handler' in sys.modules + assert "reference_handler" in sys.modules def test_latex_umlauts(): """LaTex command for an umlaut on a character, e.g. \"{a}""" - answer = 'ÄB̈C̈D̈ËF̈G̈ḦÏJ̈K̈L̈M̈N̈ÖP̈Q̈R̈S̈T̈ÜV̈ẄẌŸZ̈äb̈c̈d̈ëf̈g̈ḧïj̈k̈l̈m̈n̈öp̈q̈r̈s̈ẗüv̈ẅẍÿz̈ı̈ȷ̈' # noqa: E501 + answer = "ÄB̈C̈D̈ËF̈G̈ḦÏJ̈K̈L̈M̈N̈ÖP̈Q̈R̈S̈T̈ÜV̈ẄẌŸZ̈äb̈c̈d̈ëf̈g̈ḧïj̈k̈l̈m̈n̈öp̈q̈r̈s̈ẗüv̈ẅẍÿz̈ı̈ȷ̈" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\"{' + char + '}' - text += r'\"{\i}' # dotless i - text += r'\"{\j}' # dotless j + text += r"\"{" + char + "}" + text += r"\"{\i}" # dotless i + text += r"\"{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_acute_accents(): """LaTex command for an acute accent character, e.g. \'{a}""" - answer = 'ÁB́ĆD́ÉF́ǴH́ÍJ́ḰĹḾŃÓṔQ́ŔŚT́ÚV́ẂX́ÝŹáb́ćd́éf́ǵh́íj́ḱĺḿńóṕq́ŕśt́úv́ẃx́ýźı́ȷ́' # noqa: E501 + answer = "ÁB́ĆD́ÉF́ǴH́ÍJ́ḰĹḾŃÓṔQ́ŔŚT́ÚV́ẂX́ÝŹáb́ćd́éf́ǵh́íj́ḱĺḿńóṕq́ŕśt́úv́ẃx́ýźı́ȷ́" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r"\'{" + char + '}' + text += r"\'{" + char + "}" text += r"\'{\i}" # dotless i text += r"\'{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_dot_above(): r"""LaTex command for a dot above the character, e.g. \.{a}""" - answer = 'ȦḂĊḊĖḞĠḢİJ̇K̇L̇ṀṄȮṖQ̇ṘṠṪU̇V̇ẆẊẎŻȧḃċḋėḟġḣi̇j̇k̇l̇ṁṅȯṗq̇ṙṡṫu̇v̇ẇẋẏżı̇ȷ̇' # noqa: E501 + answer = "ȦḂĊḊĖḞĠḢİJ̇K̇L̇ṀṄȮṖQ̇ṘṠṪU̇V̇ẆẊẎŻȧḃċḋėḟġḣi̇j̇k̇l̇ṁṅȯṗq̇ṙṡṫu̇v̇ẇẋẏżı̇ȷ̇" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\.{' + char + '}' - text += r'\.{\i}' # dotless i - text += r'\.{\j}' # dotless j + text += r"\.{" + char + "}" + text += r"\.{\i}" # dotless i + text += r"\.{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_macron_above(): r"""LaTex command for a macron above the character, e.g. \={a}""" - answer = 'ĀB̄C̄D̄ĒF̄ḠH̄ĪJ̄K̄L̄M̄N̄ŌP̄Q̄R̄S̄T̄ŪV̄W̄X̄ȲZ̄āb̄c̄d̄ēf̄ḡh̄īj̄k̄l̄m̄n̄ōp̄q̄r̄s̄t̄ūv̄w̄x̄ȳz̄ı̄ȷ̄' # noqa: E501 + answer = "ĀB̄C̄D̄ĒF̄ḠH̄ĪJ̄K̄L̄M̄N̄ŌP̄Q̄R̄S̄T̄ŪV̄W̄X̄ȲZ̄āb̄c̄d̄ēf̄ḡh̄īj̄k̄l̄m̄n̄ōp̄q̄r̄s̄t̄ūv̄w̄x̄ȳz̄ı̄ȷ̄" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\={' + char + '}' - text += r'\={\i}' # dotless i - text += r'\={\j}' # dotless j + text += r"\={" + char + "}" + text += r"\={\i}" # dotless i + text += r"\={\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_circumflex_above(): r"""LaTex command for a circumflex above the character, e.g. \^{a}""" - answer = 'ÂB̂ĈD̂ÊF̂ĜĤÎĴK̂L̂M̂N̂ÔP̂Q̂R̂ŜT̂ÛV̂ŴX̂ŶẐâb̂ĉd̂êf̂ĝĥîĵk̂l̂m̂n̂ôp̂q̂r̂ŝt̂ûv̂ŵx̂ŷẑı̂ȷ̂' # noqa: E501 + answer = "ÂB̂ĈD̂ÊF̂ĜĤÎĴK̂L̂M̂N̂ÔP̂Q̂R̂ŜT̂ÛV̂ŴX̂ŶẐâb̂ĉd̂êf̂ĝĥîĵk̂l̂m̂n̂ôp̂q̂r̂ŝt̂ûv̂ŵx̂ŷẑı̂ȷ̂" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\^{' + char + '}' - text += r'\^{\i}' # dotless i - text += r'\^{\j}' # dotless j + text += r"\^{" + char + "}" + text += r"\^{\i}" # dotless i + text += r"\^{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_grave_accent(): r"""LaTex command for a grave accent on the character, e.g. \`{a}""" - answer = 'ÀB̀C̀D̀ÈF̀G̀H̀ÌJ̀K̀L̀M̀ǸÒP̀Q̀R̀S̀T̀ÙV̀ẀX̀ỲZ̀àb̀c̀d̀èf̀g̀h̀ìj̀k̀l̀m̀ǹòp̀q̀r̀s̀t̀ùv̀ẁx̀ỳz̀ı̀ȷ̀' # noqa: E501 + answer = "ÀB̀C̀D̀ÈF̀G̀H̀ÌJ̀K̀L̀M̀ǸÒP̀Q̀R̀S̀T̀ÙV̀ẀX̀ỲZ̀àb̀c̀d̀èf̀g̀h̀ìj̀k̀l̀m̀ǹòp̀q̀r̀s̀t̀ùv̀ẁx̀ỳz̀ı̀ȷ̀" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\`{' + char + '}' - text += r'\`{\i}' # dotless i - text += r'\`{\j}' # dotless j + text += r"\`{" + char + "}" + text += r"\`{\i}" # dotless i + text += r"\`{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_vertical_line_above(): r"""LaTex command for a vertical line above the character, e.g. \|{a}""" - answer = 'A̍B̍C̍D̍E̍F̍G̍H̍I̍J̍K̍L̍M̍N̍O̍P̍Q̍R̍S̍T̍U̍V̍W̍X̍Y̍Z̍a̍b̍c̍d̍e̍f̍g̍h̍i̍j̍k̍l̍m̍n̍o̍p̍q̍r̍s̍t̍u̍v̍w̍x̍y̍z̍ı̍ȷ̍' # noqa: E501 + answer = "A̍B̍C̍D̍E̍F̍G̍H̍I̍J̍K̍L̍M̍N̍O̍P̍Q̍R̍S̍T̍U̍V̍W̍X̍Y̍Z̍a̍b̍c̍d̍e̍f̍g̍h̍i̍j̍k̍l̍m̍n̍o̍p̍q̍r̍s̍t̍u̍v̍w̍x̍y̍z̍ı̍ȷ̍" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\|{' + char + '}' - text += r'\|{\i}' # dotless i - text += r'\|{\j}' # dotless j + text += r"\|{" + char + "}" + text += r"\|{\i}" # dotless i + text += r"\|{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_tilde_above(): r"""LaTex command for a tilde above the character, e.g. \~{a}""" - answer = 'ÃB̃C̃D̃ẼF̃G̃H̃ĨJ̃K̃L̃M̃ÑÕP̃Q̃R̃S̃T̃ŨṼW̃X̃ỸZ̃ãb̃c̃d̃ẽf̃g̃h̃ĩj̃k̃l̃m̃ñõp̃q̃r̃s̃t̃ũṽw̃x̃ỹz̃ı̃ȷ̃' # noqa: E501 + answer = "ÃB̃C̃D̃ẼF̃G̃H̃ĨJ̃K̃L̃M̃ÑÕP̃Q̃R̃S̃T̃ŨṼW̃X̃ỸZ̃ãb̃c̃d̃ẽf̃g̃h̃ĩj̃k̃l̃m̃ñõp̃q̃r̃s̃t̃ũṽw̃x̃ỹz̃ı̃ȷ̃" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\~{' + char + '}' - text += r'\~{\i}' # dotless i - text += r'\~{\j}' # dotless j + text += r"\~{" + char + "}" + text += r"\~{\i}" # dotless i + text += r"\~{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_macron_below(): r"""LaTex command for a macron below the character, e.g. \b{a}""" - answer = 'A̱ḆC̱ḎE̱F̱G̱H̱I̱J̱ḴḺM̱ṈO̱P̱Q̱ṞS̱ṮU̱V̱W̱X̱Y̱Ẕa̱ḇc̱ḏe̱f̱g̱ẖi̱j̱ḵḻm̱ṉo̱p̱q̱ṟs̱ṯu̱v̱w̱x̱y̱ẕı̱ȷ̱' # noqa: E501 + answer = "A̱ḆC̱ḎE̱F̱G̱H̱I̱J̱ḴḺM̱ṈO̱P̱Q̱ṞS̱ṮU̱V̱W̱X̱Y̱Ẕa̱ḇc̱ḏe̱f̱g̱ẖi̱j̱ḵḻm̱ṉo̱p̱q̱ṟs̱ṯu̱v̱w̱x̱y̱ẕı̱ȷ̱" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\b{' + char + '}' - text += r'\b{\i}' # dotless i - text += r'\b{\j}' # dotless j + text += r"\b{" + char + "}" + text += r"\b{\i}" # dotless i + text += r"\b{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_cedilla(): r"""LaTex command for a cedilla on the character, e.g. \c{a}""" - answer = 'A̧B̧ÇḐȨF̧ĢḨI̧J̧ĶĻM̧ŅO̧P̧Q̧ŖŞŢU̧V̧W̧X̧Y̧Z̧a̧b̧çḑȩf̧ģḩi̧j̧ķļm̧ņo̧p̧q̧ŗşţu̧v̧w̧x̧y̧z̧ı̧ȷ̧' # noqa: E501 + answer = "A̧B̧ÇḐȨF̧ĢḨI̧J̧ĶĻM̧ŅO̧P̧Q̧ŖŞŢU̧V̧W̧X̧Y̧Z̧a̧b̧çḑȩf̧ģḩi̧j̧ķļm̧ņo̧p̧q̧ŗşţu̧v̧w̧x̧y̧z̧ı̧ȷ̧" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\c{' + char + '}' - text += r'\c{\i}' # dotless i - text += r'\c{\j}' # dotless j + text += r"\c{" + char + "}" + text += r"\c{\i}" # dotless i + text += r"\c{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_double_grave_accent(): r"""LaTex command for a double grave accent on the character, e.g. \C{a}""" - answer = 'ȀB̏C̏D̏ȄF̏G̏H̏ȈJ̏K̏L̏M̏N̏ȌP̏Q̏ȐS̏T̏ȔV̏W̏X̏Y̏Z̏ȁb̏c̏d̏ȅf̏g̏h̏ȉj̏k̏l̏m̏n̏ȍp̏q̏ȑs̏t̏ȕv̏w̏x̏y̏z̏ı̏ȷ̏' # noqa: E501 + answer = "ȀB̏C̏D̏ȄF̏G̏H̏ȈJ̏K̏L̏M̏N̏ȌP̏Q̏ȐS̏T̏ȔV̏W̏X̏Y̏Z̏ȁb̏c̏d̏ȅf̏g̏h̏ȉj̏k̏l̏m̏n̏ȍp̏q̏ȑs̏t̏ȕv̏w̏x̏y̏z̏ı̏ȷ̏" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\C{' + char + '}' - text += r'\C{\i}' # dotless i - text += r'\C{\j}' # dotless j + text += r"\C{" + char + "}" + text += r"\C{\i}" # dotless i + text += r"\C{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_dot_below(): r"""LaTex command for a dot below the character, e.g. \d{a}""" - answer = 'ẠḄC̣ḌẸF̣G̣ḤỊJ̣ḲḶṂṆỌP̣Q̣ṚṢṬỤṾẈX̣ỴẒạḅc̣ḍẹf̣g̣ḥịj̣ḳḷṃṇọp̣q̣ṛṣṭụṿẉx̣ỵẓı̣ȷ̣' # noqa: E501 + answer = "ẠḄC̣ḌẸF̣G̣ḤỊJ̣ḲḶṂṆỌP̣Q̣ṚṢṬỤṾẈX̣ỴẒạḅc̣ḍẹf̣g̣ḥịj̣ḳḷṃṇọp̣q̣ṛṣṭụṿẉx̣ỵẓı̣ȷ̣" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\d{' + char + '}' - text += r'\d{\i}' # dotless i - text += r'\d{\j}' # dotless j + text += r"\d{" + char + "}" + text += r"\d{\i}" # dotless i + text += r"\d{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_inverted_breve(): r"""LaTex command for an inverted breve above the character, e.g. \f{a}""" - answer = 'ȂB̑C̑D̑ȆF̑G̑H̑ȊJ̑K̑L̑M̑N̑ȎP̑Q̑ȒS̑T̑ȖV̑W̑X̑Y̑Z̑ȃb̑c̑d̑ȇf̑g̑h̑ȋj̑k̑l̑m̑n̑ȏp̑q̑ȓs̑t̑ȗv̑w̑x̑y̑z̑ı̑ȷ̑' # noqa: E501 + answer = "ȂB̑C̑D̑ȆF̑G̑H̑ȊJ̑K̑L̑M̑N̑ȎP̑Q̑ȒS̑T̑ȖV̑W̑X̑Y̑Z̑ȃb̑c̑d̑ȇf̑g̑h̑ȋj̑k̑l̑m̑n̑ȏp̑q̑ȓs̑t̑ȗv̑w̑x̑y̑z̑ı̑ȷ̑" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\f{' + char + '}' - text += r'\f{\i}' # dotless i - text += r'\f{\j}' # dotless j + text += r"\f{" + char + "}" + text += r"\f{\i}" # dotless i + text += r"\f{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_hook_above(): r"""LaTex command for a hook above the character, e.g. \h{a}""" - answer = 'ẢB̉C̉D̉ẺF̉G̉H̉ỈJ̉K̉L̉M̉N̉ỎP̉Q̉R̉S̉T̉ỦV̉W̉X̉ỶZ̉ảb̉c̉d̉ẻf̉g̉h̉ỉj̉k̉l̉m̉n̉ỏp̉q̉r̉s̉t̉ủv̉w̉x̉ỷz̉ı̉ȷ̉' # noqa: E501 + answer = "ẢB̉C̉D̉ẺF̉G̉H̉ỈJ̉K̉L̉M̉N̉ỎP̉Q̉R̉S̉T̉ỦV̉W̉X̉ỶZ̉ảb̉c̉d̉ẻf̉g̉h̉ỉj̉k̉l̉m̉n̉ỏp̉q̉r̉s̉t̉ủv̉w̉x̉ỷz̉ı̉ȷ̉" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\h{' + char + '}' - text += r'\h{\i}' # dotless i - text += r'\h{\j}' # dotless j + text += r"\h{" + char + "}" + text += r"\h{\i}" # dotless i + text += r"\h{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_double_acute_accent(): r"""LaTex command for a double acute accent on the character, e.g. \H{a}""" - answer = 'A̋B̋C̋D̋E̋F̋G̋H̋I̋J̋K̋L̋M̋N̋ŐP̋Q̋R̋S̋T̋ŰV̋W̋X̋Y̋Z̋a̋b̋c̋d̋e̋f̋g̋h̋i̋j̋k̋l̋m̋n̋őp̋q̋r̋s̋t̋űv̋w̋x̋y̋z̋ı̋ȷ̋' # noqa: E501 + answer = "A̋B̋C̋D̋E̋F̋G̋H̋I̋J̋K̋L̋M̋N̋ŐP̋Q̋R̋S̋T̋ŰV̋W̋X̋Y̋Z̋a̋b̋c̋d̋e̋f̋g̋h̋i̋j̋k̋l̋m̋n̋őp̋q̋r̋s̋t̋űv̋w̋x̋y̋z̋ı̋ȷ̋" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\H{' + char + '}' - text += r'\H{\i}' # dotless i - text += r'\H{\j}' # dotless j + text += r"\H{" + char + "}" + text += r"\H{\i}" # dotless i + text += r"\H{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_ogonek(): r"""LaTex command for a ogonek on the character, e.g. \k{a}""" - answer = 'ĄB̨C̨D̨ĘF̨G̨H̨ĮJ̨K̨L̨M̨N̨ǪP̨Q̨R̨S̨T̨ŲV̨W̨X̨Y̨Z̨ąb̨c̨d̨ęf̨g̨h̨įj̨k̨l̨m̨n̨ǫp̨q̨r̨s̨t̨ųv̨w̨x̨y̨z̨ı̨ȷ̨' # noqa: E501 + answer = "ĄB̨C̨D̨ĘF̨G̨H̨ĮJ̨K̨L̨M̨N̨ǪP̨Q̨R̨S̨T̨ŲV̨W̨X̨Y̨Z̨ąb̨c̨d̨ęf̨g̨h̨įj̨k̨l̨m̨n̨ǫp̨q̨r̨s̨t̨ųv̨w̨x̨y̨z̨ı̨ȷ̨" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\k{' + char + '}' - text += r'\k{\i}' # dotless i - text += r'\k{\j}' # dotless j + text += r"\k{" + char + "}" + text += r"\k{\i}" # dotless i + text += r"\k{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_ring_above(): r"""LaTex command for a ring above the character, e.g. \r{a}""" - answer = 'ÅB̊C̊D̊E̊F̊G̊H̊I̊J̊K̊L̊M̊N̊O̊P̊Q̊R̊S̊T̊ŮV̊W̊X̊Y̊Z̊åb̊c̊d̊e̊f̊g̊h̊i̊j̊k̊l̊m̊n̊o̊p̊q̊r̊s̊t̊ův̊ẘx̊ẙz̊ı̊ȷ̊' # noqa: E501 + answer = "ÅB̊C̊D̊E̊F̊G̊H̊I̊J̊K̊L̊M̊N̊O̊P̊Q̊R̊S̊T̊ŮV̊W̊X̊Y̊Z̊åb̊c̊d̊e̊f̊g̊h̊i̊j̊k̊l̊m̊n̊o̊p̊q̊r̊s̊t̊ův̊ẘx̊ẙz̊ı̊ȷ̊" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\r{' + char + '}' - text += r'\r{\i}' # dotless i - text += r'\r{\j}' # dotless j + text += r"\r{" + char + "}" + text += r"\r{\i}" # dotless i + text += r"\r{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_double_inverted_breve(): r"""LaTex command for a double inverted breve on the character, e.g. \t{a}""" - answer = 'A͡AB͡BC͡CD͡DE͡EF͡FG͡GH͡HI͡IJ͡JK͡KL͡LM͡MN͡NO͡OP͡PQ͡QR͡RS͡ST͡TU͡UV͡VW͡WX͡XY͡YZ͡Za͡ab͡bc͡cd͡de͡ef͡fg͡gh͡hi͡ij͡jk͡kl͡lm͡mn͡no͡op͡pq͡qr͡rs͡st͡tu͡uv͡vw͡wx͡xy͡yz͡zı͡ıȷ͡ȷ' # noqa: E501 + answer = "A͡AB͡BC͡CD͡DE͡EF͡FG͡GH͡HI͡IJ͡JK͡KL͡LM͡MN͡NO͡OP͡PQ͡QR͡RS͡ST͡TU͡UV͡VW͡WX͡XY͡YZ͡Za͡ab͡bc͡cd͡de͡ef͡fg͡gh͡hi͡ij͡jk͡kl͡lm͡mn͡no͡op͡pq͡qr͡rs͡st͡tu͡uv͡vw͡wx͡xy͡yz͡zı͡ıȷ͡ȷ" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\t{' + char + '}' + char - text += r'\t{\i}\i' # dotless i - text += r'\t{\j}\j' # dotless j + text += r"\t{" + char + "}" + char + text += r"\t{\i}\i" # dotless i + text += r"\t{\j}\j" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_breve(): r"""LaTex command for a breve on the character, e.g. \u{a}""" - answer = 'ĂB̆C̆D̆ĔF̆ĞH̆ĬJ̆K̆L̆M̆N̆ŎP̆Q̆R̆S̆T̆ŬV̆W̆X̆Y̆Z̆ăb̆c̆d̆ĕf̆ğh̆ĭj̆k̆l̆m̆n̆ŏp̆q̆r̆s̆t̆ŭv̆w̆x̆y̆z̆ı̆ȷ̆' # noqa: E501 + answer = "ĂB̆C̆D̆ĔF̆ĞH̆ĬJ̆K̆L̆M̆N̆ŎP̆Q̆R̆S̆T̆ŬV̆W̆X̆Y̆Z̆ăb̆c̆d̆ĕf̆ğh̆ĭj̆k̆l̆m̆n̆ŏp̆q̆r̆s̆t̆ŭv̆w̆x̆y̆z̆ı̆ȷ̆" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\u{' + char + '}' - text += r'\u{\i}' # dotless i - text += r'\u{\j}' # dotless j + text += r"\u{" + char + "}" + text += r"\u{\i}" # dotless i + text += r"\u{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_double_vertical_line_above(): r"""LaTex command for a double vertical line above the character, e.g. \b{a}""" - answer = 'A̎B̎C̎D̎E̎F̎G̎H̎I̎J̎K̎L̎M̎N̎O̎P̎Q̎R̎S̎T̎U̎V̎W̎X̎Y̎Z̎a̎b̎c̎d̎e̎f̎g̎h̎i̎j̎k̎l̎m̎n̎o̎p̎q̎r̎s̎t̎u̎v̎w̎x̎y̎z̎ı̎ȷ̎' # noqa: E501 + answer = "A̎B̎C̎D̎E̎F̎G̎H̎I̎J̎K̎L̎M̎N̎O̎P̎Q̎R̎S̎T̎U̎V̎W̎X̎Y̎Z̎a̎b̎c̎d̎e̎f̎g̎h̎i̎j̎k̎l̎m̎n̎o̎p̎q̎r̎s̎t̎u̎v̎w̎x̎y̎z̎ı̎ȷ̎" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\U{' + char + '}' - text += r'\U{\i}' # dotless i - text += r'\U{\j}' # dotless j + text += r"\U{" + char + "}" + text += r"\U{\i}" # dotless i + text += r"\U{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_caron(): r"""LaTex command for a caron on the character, e.g. \v{a}""" - answer = 'ǍB̌ČĎĚF̌ǦȞǏJ̌ǨĽM̌ŇǑP̌Q̌ŘŠŤǓV̌W̌X̌Y̌Žǎb̌čďěf̌ǧȟǐǰǩľm̌ňǒp̌q̌řšťǔv̌w̌x̌y̌žı̌ȷ̌' # noqa: E501 + answer = "ǍB̌ČĎĚF̌ǦȞǏJ̌ǨĽM̌ŇǑP̌Q̌ŘŠŤǓV̌W̌X̌Y̌Žǎb̌čďěf̌ǧȟǐǰǩľm̌ňǒp̌q̌řšťǔv̌w̌x̌y̌žı̌ȷ̌" # noqa: E501 - text = '' + text = "" for char in list(alphabet): - text += r'\v{' + char + '}' - text += r'\v{\i}' # dotless i - text += r'\v{\j}' # dotless j + text += r"\v{" + char + "}" + text += r"\v{\i}" # dotless i + text += r"\v{\j}" # dotless j result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_symbols(): r"""LaTex command for symbols, e.g. \i""" - answer = 'ıȷłŁøØ' # noqa: E501 + answer = "ıȷłŁøØ" # noqa: E501 - text = '' - for char in list('ijlLoO'): - text += '\\' + char + text = "" + for char in list("ijlLoO"): + text += "\\" + char result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text def test_latex_dashes(): r"""LaTex command for dashes, e.g. \i""" - answer = '- – —' # noqa: E501 + answer = "- – —" # noqa: E501 - text = '- -- ---' + text = "- -- ---" result = decode_latex(text) check = encode_latex(result) - assert (result == answer and check == text) + assert result == answer and check == text diff --git a/reference_handler/tests/test_reference_handler.py b/reference_handler/tests/test_reference_handler.py index 094c69c..09477be 100644 --- a/reference_handler/tests/test_reference_handler.py +++ b/reference_handler/tests/test_reference_handler.py @@ -63,161 +63,157 @@ def test_reference_handler_imported(): def test_initialization(): - rf = _create_db('database.db') + rf = _create_db("database.db") assert rf.total_citations() == 0 - assert rf.total_citations(alias='my_alias') == 0 + assert rf.total_citations(alias="my_alias") == 0 assert rf.total_citations(reference_id=1) == 0 - assert rf.total_mentions(alias='my_alias') == 0 + assert rf.total_mentions(alias="my_alias") == 0 assert rf.total_mentions(reference_id=1) == 0 - assert rf.total_contexts(alias='my_alias') == 0 + assert rf.total_contexts(alias="my_alias") == 0 assert rf.total_contexts(reference_id=1) == 0 def test_add_new_cite_to_empty_db(): - rf = _create_db('database.db') + rf = _create_db("database.db") rf.cite( raw=lammps_citation, - alias='new_citation', - module='test_add_new_cite', + alias="new_citation", + module="test_add_new_cite", level=1, - note='This is a test' + note="This is a test", ) assert rf.total_citations() == 1 assert rf.total_citations(reference_id=1) == 1 - assert rf.total_citations(alias='new_citation') == 1 + assert rf.total_citations(alias="new_citation") == 1 assert rf.total_mentions(reference_id=1) == 1 - assert rf.total_mentions(alias='new_citation') == 1 + assert rf.total_mentions(alias="new_citation") == 1 assert rf.total_contexts(reference_id=1) == 1 - assert rf.total_contexts(alias='new_citation') == 1 + assert rf.total_contexts(alias="new_citation") == 1 def test_add_existing_citation(): - rf = _create_db('database.db') + rf = _create_db("database.db") rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='The main LAMMPS paper' + note="The main LAMMPS paper", ) rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='The main LAMMPS paper' + note="The main LAMMPS paper", ) assert rf.total_citations() == 1 assert rf.total_citations(reference_id=1) == 1 - assert rf.total_citations(alias='lammps_paper') == 1 + assert rf.total_citations(alias="lammps_paper") == 1 assert rf.total_mentions(reference_id=1) == 2 - assert rf.total_mentions(alias='lammps_paper') == 2 + assert rf.total_mentions(alias="lammps_paper") == 2 assert rf.total_contexts(reference_id=1) == 1 - assert rf.total_contexts(alias='lammps_paper') == 1 + assert rf.total_contexts(alias="lammps_paper") == 1 def test_add_new_context(): - rf = _create_db('database.db') + rf = _create_db("database.db") rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 1' + note="Context 1", ) rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 2' + note="Context 2", ) assert rf.total_citations() == 1 assert rf.total_citations(reference_id=1) == 1 - assert rf.total_citations(alias='lammps_paper') == 1 + assert rf.total_citations(alias="lammps_paper") == 1 assert rf.total_mentions(reference_id=1) == 2 - assert rf.total_mentions(alias='lammps_paper') == 2 + assert rf.total_mentions(alias="lammps_paper") == 2 assert rf.total_contexts(reference_id=1) == 2 - assert rf.total_contexts(alias='lammps_paper') == 2 + assert rf.total_contexts(alias="lammps_paper") == 2 rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=2, - note='Context 1' + note="Context 1", ) assert rf.total_citations() == 1 assert rf.total_citations(reference_id=1) == 1 - assert rf.total_citations(alias='lammps_paper') == 1 + assert rf.total_citations(alias="lammps_paper") == 1 assert rf.total_mentions(reference_id=1) == 3 - assert rf.total_mentions(alias='lammps_paper') == 3 + assert rf.total_mentions(alias="lammps_paper") == 3 assert rf.total_contexts(reference_id=1) == 3 - assert rf.total_contexts(alias='lammps_paper') == 3 + assert rf.total_contexts(alias="lammps_paper") == 3 rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS_2', + alias="lammps_paper", + module="LAMMPS_2", level=2, - note='Context 1' + note="Context 1", ) assert rf.total_citations() == 1 assert rf.total_citations(reference_id=1) == 1 - assert rf.total_citations(alias='lammps_paper') == 1 + assert rf.total_citations(alias="lammps_paper") == 1 assert rf.total_mentions(reference_id=1) == 4 - assert rf.total_mentions(alias='lammps_paper') == 4 + assert rf.total_mentions(alias="lammps_paper") == 4 assert rf.total_contexts(reference_id=1) == 4 - assert rf.total_contexts(alias='lammps_paper') == 4 + assert rf.total_contexts(alias="lammps_paper") == 4 def test_add_new_cite_to_existing_db(): - rf = _create_db('database.db') + rf = _create_db("database.db") rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 1' + note="Context 1", ) rf.cite( - raw=namd_citation, - alias='namd_paper', - module='NAMD', - level=1, - note='Context 1' + raw=namd_citation, alias="namd_paper", module="NAMD", level=1, note="Context 1" ) assert rf.total_citations() == 2 @@ -227,23 +223,23 @@ def test_add_new_cite_to_existing_db(): assert rf.total_mentions(reference_id=1) == 1 assert rf.total_mentions(reference_id=2) == 1 - assert rf.total_citations(alias='lammps_paper') == 1 - assert rf.total_citations(alias='namd_paper') == 1 + assert rf.total_citations(alias="lammps_paper") == 1 + assert rf.total_citations(alias="namd_paper") == 1 assert rf.total_mentions(alias="lammps_paper") == 1 - assert rf.total_mentions(alias='namd_paper') == 1 + assert rf.total_mentions(alias="namd_paper") == 1 assert rf.total_contexts(reference_id=1) == 1 assert rf.total_contexts(reference_id=2) == 1 - assert rf.total_contexts(alias='lammps_paper') == 1 - assert rf.total_contexts(alias='namd_paper') == 1 + assert rf.total_contexts(alias="lammps_paper") == 1 + assert rf.total_contexts(alias="namd_paper") == 1 def test_load_bibliography(): - rf = _create_db('database.db') + rf = _create_db("database.db") - bibfile = build_filenames.build_data_filename('library.bib') + bibfile = build_filenames.build_data_filename("library.bib") bib = rf.load_bibliography(bibfile=bibfile) @@ -257,62 +253,62 @@ def test_add_many_cites_and_many_contexts(): def _get_dump(outfile=None, level=None): - rf = _create_db('database.db') + rf = _create_db("database.db") - bibfile = build_filenames.build_data_filename('library.bib') + bibfile = build_filenames.build_data_filename("library.bib") bib = reference_handler.Reference_Handler.load_bibliography( - bibfile=bibfile, fmt='bibtex' + bibfile=bibfile, fmt="bibtex" ) rf.cite( - raw=bib['Jakobtorweihen.JCP.2006.125.224709'], - alias='Jakobtorweihen', - module='Code1', + raw=bib["Jakobtorweihen.JCP.2006.125.224709"], + alias="Jakobtorweihen", + module="Code1", level=1, - note='Context1' + note="Context1", ) rf.cite( - raw=bib['Afzal.JCED.2014.59.954'], - alias='Afzal', - module='Code2', + raw=bib["Afzal.JCED.2014.59.954"], + alias="Afzal", + module="Code2", level=1, - note='Context1' + note="Context1", ) rf.cite( - raw=bib['Kilaru.IECR.2008.47.910'], - alias='Kilaru', - module='Code3', + raw=bib["Kilaru.IECR.2008.47.910"], + alias="Kilaru", + module="Code3", level=1, - note='Context1' + note="Context1", ) rf.cite( - raw=bib['Argauer.USPatent.1972.3702886'], - alias='Argauer', - module='Code1', + raw=bib["Argauer.USPatent.1972.3702886"], + alias="Argauer", + module="Code1", level=3, - note='Context2' + note="Context2", ) rf.cite( - raw=bib['Afzal.JCED.2014.59.954'], - alias='Afzal', - module='Code4', + raw=bib["Afzal.JCED.2014.59.954"], + alias="Afzal", + module="Code4", level=1, - note='Context1' + note="Context1", ) rf.cite( - raw=bib['Jakobtorweihen.JCP.2006.125.224709'], - alias='Jakobtorweihen', - module='Code2', + raw=bib["Jakobtorweihen.JCP.2006.125.224709"], + alias="Jakobtorweihen", + module="Code2", level=3, - note='Context1' + note="Context1", ) rf.cite( - raw=bib['Afzal.JCED.2014.59.954'], - alias='Afzal', - module='Code2', + raw=bib["Afzal.JCED.2014.59.954"], + alias="Afzal", + module="Code2", level=1, - note='Context1' + note="Context1", ) dump = rf.dump(outfile=outfile, level=level) @@ -320,8 +316,7 @@ def _get_dump(outfile=None, level=None): @pytest.mark.parametrize( - 'name, count', - [('Afzal', 3), ('Jakobtorweihen', 2), ('Kilaru', 1), ('Argauer', 1)] + "name, count", [("Afzal", 3), ("Jakobtorweihen", 2), ("Kilaru", 1), ("Argauer", 1)] ) def test_dump(name, count): @@ -332,12 +327,11 @@ def test_dump(name, count): @pytest.mark.parametrize( - 'name, count', - [('Afzal', 3), ('Jakobtorweihen', 1), ('Kilaru', 1), ('Argauer', 0)] + "name, count", [("Afzal", 3), ("Jakobtorweihen", 1), ("Kilaru", 1), ("Argauer", 0)] ) def test_dump_with_level(name, count): - outfile = build_filenames.build_scratch_filename('outfile.bib') + outfile = build_filenames.build_scratch_filename("outfile.bib") dump = _get_dump(outfile=outfile, level=2) for item in dump: if name in item[1]: @@ -346,7 +340,7 @@ def test_dump_with_level(name, count): def test_dump_output(): - outfile = build_filenames.build_scratch_filename('outfile.bib') + outfile = build_filenames.build_scratch_filename("outfile.bib") dump = _get_dump(outfile=outfile) # noqa: F841 assert os.path.exists(outfile) is True @@ -354,35 +348,31 @@ def test_dump_output(): def test_cite_return(): - rf = _create_db('database.db') + rf = _create_db("database.db") lammps_id1 = rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 1' + note="Context 1", ) lammps_id2 = rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 1' + note="Context 1", ) lammps_id3 = rf.cite( raw=lammps_citation, - alias='lammps_paper', - module='LAMMPS', + alias="lammps_paper", + module="LAMMPS", level=1, - note='Context 2' + note="Context 2", ) namd_id = rf.cite( - raw=namd_citation, - alias='namd_paper', - module='NAMD', - level=1, - note='Context 1' + raw=namd_citation, alias="namd_paper", module="NAMD", level=1, note="Context 1" ) assert lammps_id1 == lammps_id2 diff --git a/reference_handler/utils.py b/reference_handler/utils.py index 9b32edc..12a3dd9 100644 --- a/reference_handler/utils.py +++ b/reference_handler/utils.py @@ -3,34 +3,33 @@ def _str_or_expr_to_bibtex(e): if isinstance(e, bibtexparser.bibdatabase.BibDataStringExpression): - return ' # '.join([_str_or_expr_to_bibtex(s) for s in e.expr]) + return " # ".join([_str_or_expr_to_bibtex(s) for s in e.expr]) elif isinstance(e, bibtexparser.bibdatabase.BibDataString): return e.name else: - return '{' + e + '}' + return "{" + e + "}" def entry_to_bibtex(entry): - bibtex = '' + bibtex = "" - bibtex += '@' + entry['ENTRYTYPE'] + '{' + entry['ID'] + bibtex += "@" + entry["ENTRYTYPE"] + "{" + entry["ID"] display_order = [i for i in sorted(entry)] - field_fmt = u",\n{indent}{field:<{field_max_w}} = {value}" + field_fmt = ",\n{indent}{field:<{field_max_w}} = {value}" - for field in [i for i in display_order if i not in ['ENTRYTYPE', 'ID']]: + for field in [i for i in display_order if i not in ["ENTRYTYPE", "ID"]]: try: bibtex += field_fmt.format( - indent=' ', + indent=" ", field=field, field_max_w=0, - value=_str_or_expr_to_bibtex(entry[field]) + value=_str_or_expr_to_bibtex(entry[field]), ) except TypeError: raise TypeError( - u"The field %s in entry %s must be a string" % - (field, entry['ID']) + "The field %s in entry %s must be a string" % (field, entry["ID"]) ) bibtex += "\n}\n\n" diff --git a/setup.cfg b/setup.cfg index c4caeeb..72b639c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,6 +15,8 @@ omit = [flake8] exclude = docs +max-line-length = 88 +extend-ignore = E203 [versioneer] # Automatic version numbering scheme @@ -23,11 +25,3 @@ style = pep440 versionfile_source = reference_handler/_version.py versionfile_build = reference_handler/_version.py tag_prefix = '' - -[yapf] -based_on_style = google -column_limit = 79 -dedent_closing_brackets = True -each_dict_entry_on_separate_line = True -split_before_dot = True -blank_line_before_module_docstring = True diff --git a/versioneer.py b/versioneer.py index 64fea1c..3aa5da3 100644 --- a/versioneer.py +++ b/versioneer.py @@ -339,9 +339,9 @@ def get_config_from_root(root): # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . setup_cfg = os.path.join(root, "setup.cfg") - parser = configparser.SafeConfigParser() + parser = configparser.ConfigParser() with open(setup_cfg, "r") as f: - parser.readfp(f) + parser.read_file(f) VCS = parser.get("versioneer", "VCS") # mandatory def get(parser, name):