flatlatex-0.8/0000755000175000017500000000000013254305414013224 5ustar jbenjben00000000000000flatlatex-0.8/flatlatex/0000755000175000017500000000000013254305414015210 5ustar jbenjben00000000000000flatlatex-0.8/flatlatex/bin/0000755000175000017500000000000013254305414015760 5ustar jbenjben00000000000000flatlatex-0.8/flatlatex/bin/__init__.py0000644000175000017500000000000013253455602020063 0ustar jbenjben00000000000000flatlatex-0.8/flatlatex/bin/flatlatex.py0000644000175000017500000000465513254305270020330 0ustar jbenjben00000000000000#!/usr/bin/env python3 # # Copyright (c) 2018, Pierre-Elliott Bécue # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. """ This is a rough binary command that casts a converter and calls convert on the user's input. """ import argparse import flatlatex def do_convert(arguments): """Do the actual conversion""" converter = flatlatex.converter( arguments.disallow_zero_width, arguments.disallow_combinings, ) return converter.convert(arguments.input[0]) def main(): parser = argparse.ArgumentParser( description="Convert latex entries to flat unicode" ) parser.add_argument('-C', '--disallow-combinings', help="Disallow combining characters to be used", action="store_false", default=True) parser.add_argument('-Z', '--disallow-zero-width', help="Disallow zero-width characters to be used", action="store_false", default=True) parser.add_argument("input", type=str, nargs=1, help="The latex string to convert") args = parser.parse_args() ret = do_convert(args) print(ret) flatlatex-0.8/flatlatex/latexfuntypes.py0000644000175000017500000000275213125247223020503 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. class latexfun: def __init__(self, fun, nargs): self.fun = fun self.nargs = nargs class LatexSyntaxError(SyntaxError): pass flatlatex-0.8/flatlatex/__init__.py0000644000175000017500000000503713254305346017332 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. """ LaTeX math to Unicode text converter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ flatlatex is a basic converter from LaTeX math to human readable text math using unicode characters. Basic example: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert( ... ( ... r'\\forall \\eta>0\\, \\exists n\\in\\mathbb{N}\\, \\forall i>n\\,' ... r' |u_i-\\mathcal{l}|<\\eta' ... )) '∀η>0 ∃n∈ℕ ∀i>n |uᵢ-𝓵|<η' Commands can be added with LaTeX syntax: >>> import flatlatex >>> c = flatlatex.converter() >>> c.add_newcommand(r'\\newcommand\\prob{\\mathbb{P}}') >>> c.add_newcommand(r'\\newcommand\\binom[2]{\\frac{#2!}{#1!(#2-#1)!}}') >>> c.convert(r'\\prob(X=k)\\,=\\,\\binom{k}{n}\\times p^k(1-p)^{n-k}') 'ℙ(X=k) = (n!)/(k!(n-k)!)×pᵏ(1-p)ⁿ⁻ᵏ' The behavior can be change: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert(r'\\frac{8}{9}') '⁸⁄₉' >>> c.allow_zw = False >>> c.convert(r'\\frac{8}{9}') '8/9' """ __title__ = 'flatlatex' __author__ = 'Jean-Benoist Leger' __licence__ = 'BSD-2' version_info = (0, 8) __version__ = '.'.join(map(str, version_info)) from .conv import converter flatlatex-0.8/flatlatex/transliteration.py0000644000175000017500000000355513253455602021020 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. from . import latexfuntypes def transliterate(alphabet): alphabet_keys = alphabet.keys() def fun(flat_input): flat_output = '' success = True for c in flat_input: if c in alphabet_keys: flat_output += alphabet[c] else: flat_output += c success = False return (flat_output, success) return fun def transliterator(alphabet): return latexfuntypes.latexfun( lambda x: transliterate(alphabet)(x[0])[0], 1 ) flatlatex-0.8/flatlatex/data.py0000644000175000017500000004705513253446251016512 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. known_fracts = { ('1', '2'): '½', ('1', '3'): '⅓', ('2', '3'): '⅔', ('1', '4'): '¼', ('3', '4'): '¾', ('1', '5'): '⅕', ('2', '5'): '⅖', ('3', '5'): '⅗', ('4', '5'): '⅘', ('1', '6'): '⅙', ('5', '6'): '⅚', ('1', '7'): '⅐', ('1', '8'): '⅛', ('3', '8'): '⅜', ('5', '8'): '⅝', ('7', '8'): '⅞', ('1', '9'): '⅑', } subscript = { '0': '₀', '1': '₁', '2': '₂', '3': '₃', '4': '₄', '5': '₅', '6': '₆', '7': '₇', '8': '₈', '9': '₉', '+': '₊', '-': '₋', '=': '₌', '(': '₍', ')': '₎', 'a': 'ₐ', 'e': 'ₑ', 'i': 'ᵢ', 'j': '\N{LATIN SUBSCRIPT SMALL LETTER J}', 'o': 'ₒ', 'r': 'ᵣ', 'u': 'ᵤ', 'v': 'ᵥ', 'x': 'ₓ', 'β': 'ᵦ', 'γ': 'ᵧ', 'ρ': 'ᵨ', 'φ': 'ᵩ', 'χ': 'ᵪ', } superscript = { '0': '⁰', '1': '¹', '2': '²', '3': '³', '4': '⁴', '5': '⁵', '6': '⁶', '7': '⁷', '8': '⁸', '9': '⁹', '+': '⁺', '-': '⁻', '=': '⁼', '(': '⁽', ')': '⁾', 'a': 'ᵃ', 'b': 'ᵇ', 'c': 'ᶜ', 'd': 'ᵈ', 'e': 'ᵉ', 'f': 'ᶠ', 'g': 'ᵍ', 'h': 'ʰ', 'i': 'ⁱ', 'j': 'ʲ', 'k': 'ᵏ', 'l': 'ˡ', 'm': 'ᵐ', 'n': 'ⁿ', 'o': 'ᵒ', 'p': 'ᵖ', 'r': 'ʳ', 's': 'ˢ', 't': 'ᵗ', 'u': 'ᵘ', 'v': 'ᵛ', 'w': 'ʷ', 'x': 'ˣ', 'y': 'ʸ', 'z': 'ᶻ', 'A': 'ᴬ', 'B': 'ᴮ', 'D': 'ᴰ', 'E': 'ᴱ', 'G': 'ᴳ', 'H': 'ᴴ', 'I': 'ᴵ', 'J': 'ᴶ', 'K': 'ᴷ', 'L': 'ᴸ', 'M': 'ᴹ', 'N': 'ᴺ', 'O': 'ᴼ', 'P': 'ᴾ', 'R': 'ᴿ', 'T': 'ᵀ', 'U': 'ᵁ', 'V': 'ⱽ', 'W': 'ᵂ', 'α': 'ᵅ', 'β': 'ᵝ', 'γ': 'ᵞ', 'δ': 'ᵟ', '∊': 'ᵋ', 'θ': 'ᶿ', 'ι': 'ᶥ', 'Φ': 'ᶲ', 'φ': 'ᵠ', 'χ': 'ᵡ', } bb = { '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': '𝕫', '0': '𝟘', '1': '𝟙', '2': '𝟚', '3': '𝟛', '4': '𝟜', '5': '𝟝', '6': '𝟞', '7': '𝟟', '8': '𝟠', '9': '𝟡', } bf = { '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': '𝐳', 'Α': '𝚨', 'Β': '𝚩', 'Γ': '𝚪', 'Δ': '𝚫', 'Ε': '𝚬', 'Ζ': '𝚭', 'Η': '𝚮', 'Θ': '𝚯', 'Ι': '𝚰', 'Κ': '𝚱', 'Λ': '𝚲', 'Μ': '𝚳', 'Ν': '𝚴', 'Ξ': '𝚵', 'Ο': '𝚶', 'Π': '𝚷', 'Ρ': '𝚸', 'ϴ': '𝚹', 'Σ': '𝚺', 'Τ': '𝚻', 'Υ': '𝚼', 'Φ': '𝚽', 'Χ': '𝚾', 'Ψ': '𝚿', 'Ω': '𝛀', '∇': '𝛁', 'α': '𝛂', 'β': '𝛃', 'γ': '𝛄', 'δ': '𝛅', 'ε': '𝛆', 'ζ': '𝛇', 'η': '𝛈', 'θ': '𝛉', 'ι': '𝛊', 'κ': '𝛋', 'λ': '𝛌', 'μ': '𝛍', 'ν': '𝛎', 'ξ': '𝛏', 'ο': '𝛐', 'π': '𝛑', 'ρ': '𝛒', 'ς': '𝛓', 'σ': '𝛔', 'τ': '𝛕', 'υ': '𝛖', 'φ': '𝛗', 'χ': '𝛘', 'ψ': '𝛙', 'ω': '𝛚', '∂': '𝛛', 'ϵ': '𝛜', 'ϑ': '𝛝', 'ϰ': '𝛞', 'ϕ': '𝛟', 'ϱ': '𝛠', 'ϖ': '𝛡', '0': '𝟎', '1': '𝟏', '2': '𝟐', '3': '𝟑', '4': '𝟒', '5': '𝟓', '6': '𝟔', '7': '𝟕', '8': '𝟖', '9': '𝟗', } cal = { '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': '𝔃', } frak = { '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': '𝔷', } it = { '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': '𝑧', 'Α': '𝛢', 'Β': '𝛣', 'Γ': '𝛤', 'Δ': '𝛥', 'Ε': '𝛦', 'Ζ': '𝛧', 'Η': '𝛨', 'Θ': '𝛩', 'Ι': '𝛪', 'Κ': '𝛫', 'Λ': '𝛬', 'Μ': '𝛭', 'Ν': '𝛮', 'Ξ': '𝛯', 'Ο': '𝛰', 'Π': '𝛱', 'Ρ': '𝛲', 'ϴ': '𝛳', 'Σ': '𝛴', 'Τ': '𝛵', 'Υ': '𝛶', 'Φ': '𝛷', 'Χ': '𝛸', 'Ψ': '𝛹', 'Ω': '𝛺', '∇': '𝛻', 'α': '𝛼', 'β': '𝛽', 'γ': '𝛾', 'δ': '𝛿', 'ε': '𝜀', 'ζ': '𝜁', 'η': '𝜂', 'θ': '𝜃', 'ι': '𝜄', 'κ': '𝜅', 'λ': '𝜆', 'μ': '𝜇', 'ν': '𝜈', 'ξ': '𝜉', 'ο': '𝜊', 'π': '𝜋', 'ρ': '𝜌', 'ς': '𝜍', 'σ': '𝜎', 'τ': '𝜏', 'υ': '𝜐', 'φ': '𝜑', 'χ': '𝜒', 'ψ': '𝜓', 'ω': '𝜔', '∂': '𝜕', 'ϵ': '𝜖', 'ϑ': '𝜗', 'ϰ': '𝜘', 'ϕ': '𝜙', 'ϱ': '𝜚', 'ϖ': '𝜛', } mono = { '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': '𝚣', '0': '𝟶', '1': '𝟷', '2': '𝟸', '3': '𝟹', '4': '𝟺', '5': '𝟻', '6': '𝟼', '7': '𝟽', '8': '𝟾', '9': '𝟿', } transliterators = { r'\bb': bb, r'\bf': bf, r'\cal': cal, r'\frak': frak, r'\it': it, r'\mono': mono, } symbols = { r'\_': '_', r'\|': '‖', r'\lVert': '‖', r'\rVert': '‖', r'\\': '\\', r'\aleph': 'ℵ', r'\alpha': 'α', r'\amalg': '∐', r'\angle': '∠', r'\approx': '≈', r'\approxeq': '≊', r'\ast': '∗', r'\asymp': '≍', r'\backsim': '∽', r'\backsimeq': '⋍', r'\backslash': '\\', r'\barwedge': '⊼', r'\because': '∵', r'\beta': 'β', r'\beth': 'ℶ', r'\between': '≬', r'\bigcap': '⋂', r'\bigcup': '⋃', r'\bigvee': '⋁', r'\bigwedge': '⋀', r'\blacksquare': '∎', r'\bot': '⊤', r'\bowtie': '⋈', r'\boxdot': '⊡', r'\boxminus': '⊟', r'\boxplus': '⊞', r'\boxtimes': '⊠', r'\bullet': '•', r'\bumpeq': '≏', r'\Bumpeq': '≎', r'\cap': '∩', r'\Cap': '⋒', r'\cdot': '·', r'\cdots': '⋯', r'\chi': 'χ', r'\circ': '∘', r'\circeq': '≗', r'\circlearrowleft': '↺', r'\circlearrowright': '↻', r'\circledast': '⊛', r'\circledcirc': '⊚', r'\circleddash': '⊝', r'\clubsuit': '♣', r'\varclubsuit': '♧', r'\complement': '∁', r'\cong': '≅', r'\cup': '∪', r'\Cup': '⋓', r'\curlyeqprec': '⋞', r'\curlyeqsucc': '⋟', r'\curlyvee': '⋎', r'\curlywedge': '⋏', r'\curvearrowleft': '↶', r'\curvearrowright': '↷', r'\dag': '†', r'\daleth': 'ℸ', r'\dashleftarrow': '⇠', r'\dashrightarrow': '⇢', r'\dashv': '⊣', r'\ddag': '‡', r'\ddots': '⋱', r'\ddotsup': '⋰', r'\defeq': '≝', r'\delta': 'δ', r'\Delta': 'Δ', r'\diamond': '⋄', r'\diamondsuit': '♢', r'\vardiamondsuit': '♦', r'\div': '÷', r'\divideontimes': '⋇', r'\doteq': '≐', r'\doteqdot': '≑', r'\dotplus': '∔', r'\dots': '…', r'\downarrow': '↓', r'\Downarrow': '⇓', r'\downdownarrows': '⇊', r'\downharpoonleft': '⇃', r'\downharpoonright': '⇂', r'\ell': 'ℓ', r'\emptyset': '∅', r'\epsilon': 'ϵ', r'\eqcirc': '≖', r'\eqslantgtr': '⋝', r'\eqslantless': '⋜', r'\equiv': '≡', r'\eta': 'η', r'\exists': '∃', r'\fallingdotseq': '≒', r'\Finv': 'Ⅎ', r'\flat': '♭', r'\forall': '∀', r'\gamma': 'γ', r'\Gamma': 'Γ', r'\geq': '≥', r'\geqq': '≧', r'\gg': '≫', r'\ggg': '⋙', r'\gimel': 'ℷ', r'\gneqq': '≩', r'\gnsim': '⋧', r'\gtrdot': '⋗', r'\gtreqless': '⋛', r'\gtrless': '≷', r'\gtrsim': '≳', r'\hbar': 'ℏ', r'\heartsuit': '♡', r'\varheartsuit': '♥', r'\hookleftarrow': '↩', r'\hookrightarrow': '↪', r'\iiint': '∭', r'\iint': '∬', r'\Im': 'ℑ', r'\in': '∈', r'\infty': '∞', r'\int': '∫', r'\intercal': '⊺', r'\iota': 'ι', r'\kappa': 'κ', r'\lambda': 'λ', r'\Lambda': 'Λ', r'\leadsto': '↝', r'\leftarrow': '←', r'\Leftarrow': '⇐', r'\leftarrowtail': '↢', r'\leftharpoondown': '↽', r'\leftharpoonup': '↼', r'\leftleftarrows': '⇇', r'\leftrightarrow': '↔', r'\Leftrightarrow': '⇔', r'\leftrightarrows': '⇆', r'\leftrightharpoons': '⇋', r'\leftrightsquigarrow': '↭', r'\leftthreetimes': '⋋', r'\leq': '≤', r'\leqq': '≦', r'\lessdot': '⋖', r'\lesseqgtr': '⋚', r'\lessgtr': '≶', r'\lesssim': '≲', r'\lhd': '⊲', r'\ll': '≪', r'\Lleftarrow': '⇚', r'\lll': '⋘', r'\lneqq': '≨', r'\lnot': '¬', r'\lnsim': '⋦', r'\looparrowleft': '↫', r'\looparrowright': '↬', r'\Lsh': '↰', r'\ltimes': '⋉', r'\mapsto': '↦', r'\measuredangle': '∡', r'\mho': '℧', r'\mid': '∣', r'\models': '⊨', r'\mp': '∓', r'\multimap': '⊸', r'\multimapdotbothA': '⊶', r'\multimapdotbothB': '⊷', r'\mu': 'μ', r'\nabla': '∇', r'\natural': '♮', r'\ncong': '≇', r'\nearrow': '↗', r'\neq': '≠', r'\nexists': '∄', r'\ngeq': '≱', r'\ngtr': '≯', r'\ni': '∋', r'\nleftarrow': '↚', r'\nLeftarrow': '⇍', r'\nleftrightarrow': '↮', r'\nLeftrightarrow': '⇎', r'\nleq': '≰', r'\nless': '≮', r'\nmid': '∤', r'\notin': '∉', r'\nparallel': '∦', r'\nprec': '⊁', r'\nrightarrow': '↛', r'\nRightarrow': '⇏', r'\nsim': '≁', r'\nsubseteq': '⊈', r'\nsucc': '⊀', r'\nsupseteq': '⊉', r'\ntriangleleft': '⋪', r'\ntrianglelefteq': '⋬', r'\ntriangleright': '⋫', r'\ntrianglerighteq': '⋭', r'\nu': 'ν', r'\nvdash': '⊬', r'\nvDash': '⊭', r'\nVdash': '⊯', r'\nwarrow': '↖', r'\odot': '⊙', r'\oiiint': '∰', r'\oiint': '∯', r'\oint': '∮', r'\omega': 'ω', r'\Omega': 'Ω', r'\ominus': '⊖', r'\oplus': '⊕', r'\oslash': '⊘', r'\otimes': '⊗', r'\P': '¶', r'\parallel': '∥', r'\partial': '∂', r'\perp': '⊥', r'\phi': 'φ', r'\Phi': 'Φ', r'\pitchfork': '⋔', r'\pi': 'π', r'\Pi': 'Π', r'\pm': '±', r'\pounds': '£', r'\prec': '≺', r'\preccurlyeq': '≼', r'\precnsim': '⋨', r'\precsim': '≾', r'\prod': '∏', r'\propto': '∝', r'\psi': 'ψ', r'\Psi': 'Ψ', r'\Re': 'ℜ', r'\rhd': '⊳', r'\rho': 'ρ', r'\rightarrow': '→', r'\Rightarrow': '⇒', r'\rightarrowtail': '↣', r'\rightharpoondown': '⇁', r'\rightharpoonup': '⇀', r'\rightleftarrows': '⇄', r'\rightleftharpoons': '⇌', r'\rightrightarrows': '⇉', r'\rightsquigarrow': '⇝', r'\rightthreetimes': '⋌', r'\risingdotseq': '≓', r'\Rsh': '↱', r'\rtimes': '⋊', r'\S': '§', r'\searrow': '↘', r'\swarrow': '↙', r'\setminus': '∖', r'\sharp': '♯', r'\sigma': 'σ', r'\Sigma': 'Σ', r'\sim': '∼', r'\simeq': '≃', r'\spadesuit': '♠', r'\varspadesuit': '♤', r'\sphericalangle': '∢', r'\sqcap': '⊓', r'\sqcup': '⊔', r'\sqsubset': '⊏', r'\sqsubseteq': '⊑', r'\sqsupset': '⊐', r'\sqsupseteq': '⊒', r'\star': '⋆', r'\subset': '⊂', r'\Subset': '⋐', r'\subseteq': '⊆', r'\subsetneq': '⊊', r'\succ': '≻', r'\succcurlyeq': '≽', r'\succnsim': '⋩', r'\succsim': '≿', r'\sum': '∑', r'\supset': '⊃', r'\Supset': '⋑', r'\supseteq': '⊇', r'\supsetneq': '⊋', r'\surd': '√', r'\tau': 'τ', r'\therefore': '∴', r'\theta': 'θ', r'\Theta': 'Θ', r'\times': '×', r'\triangleq': '≜', r'\twoheadleftarrow': '↞', r'\twoheadrightarrow': '↠', r'\unlhd': '⊴', r'\unrhd': '⊵', r'\uparrow': '↑', r'\Uparrow': '⇑', r'\updownarrow': '↕', r'\Updownarrow': '⇕', r'\upharpoonleft': '↿', r'\upharpoonright': '↾', r'\uplus': '⊎', r'\upsilon': 'υ', r'\upuparrows': '⇈', r'\varepsilon': 'ε', r'\varphi': 'ϕ', r'\varpi': 'ϖ', r'\varrho': 'ϱ', r'\varsigma': 'ς', r'\vartheta': 'ϑ', r'\vdash': '⊢', r'\vDash': '⊧', r'\Vdash': '⊩', r'\vdots': '⋮', r'\vee': '∨', r'\veebar': '⊻', r'\Vvdash': '⊪', r'\wedge': '∧', r'\wp': '℘', r'\wr': '≀', r'\xi': 'ξ', r'\Xi': 'Ξ', r'\zeta': 'ζ', r'\ ': ' ', r'\,': ' ', r'\;': ' ', r'\quad': ' ', r'\qquad': ' ', } combinings = { r'\hat': ('\u0302', 'hat'), r'\grave': ('\u0301', 'grave'), r'\dot': ('\u0307', 'dot'), r'\not': ('\u0338', 'not'), r'\overrightarrow': ('\u20d7', 'overrightarrow'), r'\overline': ('\u0305', 'overline'), r'\tilde': ('\u0303', 'tilde'), r'\bar': ('\u0304', 'bar'), r'\acute': ('\u0300', 'acute'), r'\ddot': ('\u0308', 'ddot'), r'\overleftarrow': ('\u20d6', 'overleftarrow'), r'\check': ('\u030c', 'check'), r'\vec': ('\u20d7', 'vec'), r'\underline': ('\u0332', 'underline'), } newcommands = ( r'\newcommand\mathcal[1]{\cal{#1}}', r'\newcommand\mathit[1]{\it{#1}}', r'\newcommand\mathbf[1]{\bf{#1}}', r'\newcommand\mathbb[1]{\bb{#1}}', r'\newcommand\mathmono[1]{\mono{#1}}', r'\newcommand\mathfrak[1]{\frak{#1}}', ) flatlatex-0.8/flatlatex/parser.py0000644000175000017500000000370413253455602017066 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. import regex from .latexfuntypes import LatexSyntaxError def parse_one_element(s): R = r'((?>\\(?:[^A-Za-z]|[A-Za-z]+))|(?>[^\{\}\\])|\{(?1)*\})' r = regex.match(R, s) if not r: raise LatexSyntaxError s = s[r.span()[1]:] c = r.captures()[0] if c[0] == '\\': return (('cmd', c), s) if c[0] == '{': return (('subexpr', c[1:-1]), s) if c in ('_', '^'): return (('oper', c), s) return (('char', c), s) def parse(s): ret = [] while len(s) > 0: m, s = parse_one_element(s) if not (m[1] == ' '): ret.append(m) return ret flatlatex-0.8/flatlatex/tests/0000755000175000017500000000000013254305414016352 5ustar jbenjben00000000000000flatlatex-0.8/flatlatex/tests/__init__.py0000644000175000017500000000000013125247223020451 0ustar jbenjben00000000000000flatlatex-0.8/flatlatex/tests/test_data_consistancy.py0000644000175000017500000001030113253531724023310 0ustar jbenjben00000000000000# Copyright (c) 2017-2017, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. from .. import data from .. import parser import ast def test_known_fracts(): assert type(data.known_fracts) is dict for k, v in data.known_fracts.items(): assert type(k) is tuple assert len(k) == 2 assert all([type(x) is str for x in k]) assert type(v) is str def test_transliteration_consistancy(): for d in ( data.subscript, data.superscript, data.bb, data.bf, data.cal, data.frak, data.it, data.mono, ): assert type(d) is dict for k, v in d.items(): assert type(k) is str assert type(v) is str def test_symbols_consistancy(): assert type(data.symbols) is dict for k, v in data.symbols.items(): assert type(k) is str out = parser.parse(k) assert len(out) == 1 assert out[0][0] == 'cmd' assert type(v) is str def test_combining_consistancy(): assert type(data.combinings) is dict for k, v in data.combinings.items(): assert type(k) is str out = parser.parse(k) assert len(out) == 1 assert out[0][0] == 'cmd' assert type(v) is tuple assert len(v) == 2 assert all([type(x) is str for x in v]) def test_newcommands_consistancy(): assert type(data.newcommands) is tuple for k in data.newcommands: parsed = parser.parse(k) assert len(parsed) in (3, 6) assert parsed[0][0] == 'cmd' assert parsed[0][1] in (r'\newcommand', r'\renewcommand', r'\def') if len(parsed) == 6: assert parsed[2] == ('char', '[') assert parsed[4] == ('char', ']') assert type(parsed[3][0]) is str a = int(parsed[3][1]) assert a >= 0 def test_replicated_command(): datasets = [ data.symbols.keys(), data.combinings.keys(), data.transliterators.keys(), ] datasets.append([parser.parse(nc)[1][1] for nc in data.newcommands]) for i in range(len(datasets)): for j in range(i + 1, len(datasets)): s1 = set(datasets[i]) s2 = set(datasets[j]) assert len(s1.intersection(s2)) == 0 def test_replicated_in_the_same_dict(): with open(data.__file__, encoding='utf8') as f: data_ast = ast.parse(f.read()) def toobj(x): if type(x) is ast.Tuple: return tuple(toobj(v) for v in x.elts) return x.s for seg in data_ast.body: if type(seg) is ast.Assign: if type(seg.value) is ast.Dict: keys = [toobj(k) for k in seg.value.keys] count = {} for k in keys: count[k] = count[k] + 1 if k in count else 1 for k, c in count.items(): assert c == 1, "duplicated key in dict: %s" % k flatlatex-0.8/flatlatex/tests/test_parser.py0000644000175000017500000000426013253531714021264 0ustar jbenjben00000000000000# Copyright (c) 2017-2018, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. from .. import parser def test_parser(): expected = { r'\\': [('cmd', r'\\')], r'\cd': [('cmd', r'\cd')], r'ab': [('char', 'a'), ('char', 'b')], r'e{to{t}o}e': [ ('char', 'e'), ('subexpr', 'to{t}o'), ('char', 'e') ], r'g_f': [('char', 'g'), ('oper', '_'), ('char', 'f')], r'h^i': [('char', 'h'), ('oper', '^'), ('char', 'i')], } for k, v in expected.items(): assert all([ pki == vi for pki, vi in zip(parser.parse(k), v) ]), "parser '%s'" % k for k1, v1 in expected.items(): for k2, v2 in expected.items(): assert all([ pki == vi for pki, vi in zip(parser.parse(k1 + ' ' + k2), v1 + v2) ]), "parser '%s'+'%s'" % (k1, k2) flatlatex-0.8/flatlatex/tests/test_conv.py0000644000175000017500000000451213253531714020735 0ustar jbenjben00000000000000# Copyright (c) 2016-2018, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. from .. import converter def test_conv1(): c = converter() r = c.convert( ( r'\forall \eta>0\, \exists n\in\mathbb{N}\, \forall i>n\, ' r'|u_i-\mathcal{l}|<\eta' ) ) assert r == '∀η>0 ∃n∈ℕ ∀i>n |uᵢ-𝓵|<η' def test_conv2(): c = converter() c.add_newcommand(r'\newcommand\prob{\mathbb{P}}') c.add_newcommand(r'\newcommand\binom[2]{\frac{#2!}{#1!(#2-#1)!}}') r = c.convert(r'\prob(X=k)\,=\,\binom{k}{n}\times p^k(1-p)^{n-k}') assert r == 'ℙ(X=k) = (n!)/(k!(n-k)!)×pᵏ(1-p)ⁿ⁻ᵏ' def test_conv3(): c = converter() c.allow_zw = True r = c.convert(r'\frac{8}{9}') assert r == '⁸⁄₉' c.allow_zw = False r = c.convert(r'\frac{8}{9}') assert r == '8/9' def test_conv4(): c = converter() c.allow_combinings = True r = c.convert(r'\hat\alpha') assert r == '\u03B1\u0302' c.allow_combinings = False r = c.convert(r'\hat\alpha') assert r == 'hat(\u03B1)' flatlatex-0.8/flatlatex/conv.py0000644000175000017500000002303313253455602016534 0ustar jbenjben00000000000000# Copyright (c) 2016, Jean-Benoist Leger # All rights reserved. # # 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. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. from . import data from .transliteration import transliterator, transliterate import regex from . import latexfuntypes from . import parser from .latexfuntypes import LatexSyntaxError class converter: """flatlatex converter class :attrib allow_zw: boolean which indicate if zero width characters are allowed (True by default). :attrib allow_combinings: boolean which indicate if combining characters are allowed (True by default). """ def __init__(self, allow_zw=True, allow_combinings=True): """Initialize a convert method.""" self.__cmds = {} # transliteration for k, v in data.transliterators.items(): self.__cmds[k] = transliterator(v) # symbols def makefun(symb): return lambda x: symb for cmd in data.symbols: self.__cmds[cmd] = latexfuntypes.latexfun( makefun(data.symbols[cmd]), 0) # combinings def makefun(comb): return lambda x: self.__latexfun_comb(comb, x) for cmd in data.combinings: self.__cmds[cmd] = latexfuntypes.latexfun( makefun(data.combinings[cmd]), 1) # others self.__cmds[r'\frac'] = latexfuntypes.latexfun(self.__latexfun_frac, 2) self.__cmds[r'\sqrt'] = latexfuntypes.latexfun(self.__latexfun_sqrt, 1) # newcommands for nc in data.newcommands: self.add_newcommand(nc) # config section self.allow_zw = allow_zw self.allow_combinings = allow_combinings def convert(self, expr): """Convert LaTeX math to Unicode text. :param expr: LaTeX math expression to convert""" parsed = parser.parse(expr) outvec = [] idx = 0 while(idx < len(parsed)): element = parsed[idx] if element[0] == 'oper': outvec.append(('oper', element[1])) idx += 1 continue if element[0] == 'char': outvec.append(('char', element[1])) idx += 1 continue if element[0] == 'cmd': try: pycmd = self.__cmds[element[1]] except KeyError: outvec.append(('char', element[1])) idx += 1 continue if len(parsed) <= idx + pycmd.nargs: raise LatexSyntaxError args = [ self.convert(parsed[idx + k + 1][1]) for k in range(pycmd.nargs) ] outvec.append(('char', pycmd.fun(args))) idx += 1 + pycmd.nargs continue if element[0] == 'subexpr': outvec.append(('char', self.convert(element[1]))) idx += 1 continue raise Exception # subandsuperscript for idx in range(len(outvec)): if outvec[idx][0] == 'oper': if len(outvec) <= idx + 1: raise LatexSyntaxError if outvec[idx + 1][0] == 'oper': raise LatexSyntaxError for idx in range(len(outvec)): if outvec[idx][0] == 'oper' and outvec[idx][1] == '^': if idx + 2 < len(outvec): if (outvec[idx + 2][0] == 'oper' and outvec[idx + 2][1] == '_'): # we invert ^ and _ ( outvec[idx], outvec[idx + 1], outvec[idx + 2], outvec[idx + 3], ) = ( outvec[idx + 2], outvec[idx + 3], outvec[idx], outvec[idx + 1], ) # sub newoutvec = [] idx = 0 while idx < len(outvec): if idx + 1 < len(outvec): if outvec[idx + 1][0] == 'oper' and outvec[idx + 1][1] == '_': newoutvec.append( ( 'char', self.__indexed( outvec[idx][1], outvec[idx + 2][1] ), ) ) idx += 3 continue newoutvec.append(outvec[idx]) idx += 1 outvec = newoutvec # super newoutvec = [] idx = 0 while idx < len(outvec): if idx + 1 < len(outvec): if outvec[idx + 1][0] == 'oper' and outvec[idx + 1][1] == '^': newoutvec.append( ( 'char', self.__exponent( outvec[idx][1], outvec[idx + 2][1] ), ) ) idx += 3 continue newoutvec.append(outvec[idx]) idx += 1 outvec = newoutvec return ''.join([x[1] for x in outvec]) def __indexed(self, a, b): f_sub = transliterate(data.subscript) bsub, ok = f_sub(b) if self.__is_complex_expr(a): a = '(' + a + ')' if ok: return a + bsub return a + '[' + b + ']' def __exponent(self, a, b): f_sup = transliterate(data.superscript) bsup, ok = f_sup(b) if self.__is_complex_expr(a): a = '(' + a + ')' if ok: return a + bsup if self.__is_complex_expr(b): b = '(' + b + ')' return a + '^' + b def __is_complex_expr(self, expr): return (len(expr) > 1) def __latexfun_comb(self, comb, inputs): expr = inputs[0] if(len(expr) == 1): if self.allow_combinings: return expr + comb[0] return comb[1] + '(' + expr + ')' def add_newcommand(self, one_newcommand): """Add a command definiton using LaTeX syntax. :param expr: a valid \\newcommand (or \\renewcommand or \\def) definition. Examples: - r'\\newcommand\\prob{\\mathbb{P}}' - r'\\newcommand\\binom[2]{\\frac{#2!}{#1!(#2-#1)!}}' """ parsed = parser.parse(one_newcommand) if not (len(parsed) in (3, 6)): raise LatexSyntaxError ok = False if parsed[0][0] == 'cmd': if parsed[0][1] in ( r'\newcommand', r'\renewcommand', r'\def'): ok = True if not ok: raise LatexSyntaxError nargs = 0 if len(parsed) == 6: if parsed[2] == ('char', '[') and parsed[4] == ('char', ']'): nargs = int(parsed[3][1]) else: raise LatexSyntaxError cmdname = parsed[1][1] cmdexpr = parsed[-1][1] def thefun(args): expr = cmdexpr for i in range(len(args)): expr = regex.sub('#%i' % (i + 1), args[i], expr) return self.convert(expr) self.__cmds[cmdname] = latexfuntypes.latexfun( lambda x: thefun(x), nargs) return None def __latexfun_frac(self, inputs): a = inputs[0] b = inputs[1] try: ret = data.known_fracts[(a, b)] return ret except KeyError: pass if self.allow_zw: f_sub = transliterate(data.subscript) f_sup = transliterate(data.superscript) a_sup, ok_sup = f_sup(a) b_sub, ok_sub = f_sub(b) if ok_sup and ok_sub: return a_sup + '⁄' + b_sub if self.__is_complex_expr(a): a = '(' + a + ')' if self.__is_complex_expr(b): b = '(' + b + ')' return a + '/' + b def __latexfun_sqrt(self, inputs): a = inputs[0] if self.__is_complex_expr(a): a = '(' + a + ')' return '√' + a flatlatex-0.8/flatlatex.egg-info/0000755000175000017500000000000013254305414016702 5ustar jbenjben00000000000000flatlatex-0.8/flatlatex.egg-info/SOURCES.txt0000644000175000017500000000101413254305414020562 0ustar jbenjben00000000000000setup.py flatlatex/__init__.py flatlatex/conv.py flatlatex/data.py flatlatex/latexfuntypes.py flatlatex/parser.py flatlatex/transliteration.py flatlatex.egg-info/PKG-INFO flatlatex.egg-info/SOURCES.txt flatlatex.egg-info/dependency_links.txt flatlatex.egg-info/entry_points.txt flatlatex.egg-info/requires.txt flatlatex.egg-info/top_level.txt flatlatex/bin/__init__.py flatlatex/bin/flatlatex.py flatlatex/tests/__init__.py flatlatex/tests/test_conv.py flatlatex/tests/test_data_consistancy.py flatlatex/tests/test_parser.pyflatlatex-0.8/flatlatex.egg-info/dependency_links.txt0000644000175000017500000000000113254305414022750 0ustar jbenjben00000000000000 flatlatex-0.8/flatlatex.egg-info/entry_points.txt0000644000175000017500000000007413254305414022201 0ustar jbenjben00000000000000[console_scripts] flatlatex = flatlatex.bin.flatlatex:main flatlatex-0.8/flatlatex.egg-info/requires.txt0000644000175000017500000000002513254305414021277 0ustar jbenjben00000000000000regex [test] pytest flatlatex-0.8/flatlatex.egg-info/top_level.txt0000644000175000017500000000001213254305414021425 0ustar jbenjben00000000000000flatlatex flatlatex-0.8/flatlatex.egg-info/PKG-INFO0000644000175000017500000000351713254305414020005 0ustar jbenjben00000000000000Metadata-Version: 2.1 Name: flatlatex Version: 0.8 Summary: A LaTeX math converter to unicode text Home-page: https://gitlab.crans.org/leger/flatlatex Author: Jean-Benoist Leger Author-email: jb@leger.tf License: BSD-2 Description: LaTeX math to Unicode text converter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ flatlatex is a basic converter from LaTeX math to human readable text math using unicode characters. Basic example: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert( ... ( ... r'\forall \eta>0\, \exists n\in\mathbb{N}\, \forall i>n\,' ... r' |u_i-\mathcal{l}|<\eta' ... )) '∀η>0 ∃n∈ℕ ∀i>n |uᵢ-𝓵|<η' Commands can be added with LaTeX syntax: >>> import flatlatex >>> c = flatlatex.converter() >>> c.add_newcommand(r'\newcommand\prob{\mathbb{P}}') >>> c.add_newcommand(r'\newcommand\binom[2]{\frac{#2!}{#1!(#2-#1)!}}') >>> c.convert(r'\prob(X=k)\,=\,\binom{k}{n}\times p^k(1-p)^{n-k}') 'ℙ(X=k) = (n!)/(k!(n-k)!)×pᵏ(1-p)ⁿ⁻ᵏ' The behavior can be change: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert(r'\frac{8}{9}') '⁸⁄₉' >>> c.allow_zw = False >>> c.convert(r'\frac{8}{9}') '8/9' Keywords: latex math unicode Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Science/Research Classifier: Topic :: Text Processing :: Markup :: LaTeX Classifier: License :: OSI Approved Classifier: Programming Language :: Python :: 3 :: Only Requires-Python: >=3 Provides-Extra: test flatlatex-0.8/setup.cfg0000644000175000017500000000004613254305414015045 0ustar jbenjben00000000000000[egg_info] tag_build = tag_date = 0 flatlatex-0.8/PKG-INFO0000644000175000017500000000351713254305414014327 0ustar jbenjben00000000000000Metadata-Version: 2.1 Name: flatlatex Version: 0.8 Summary: A LaTeX math converter to unicode text Home-page: https://gitlab.crans.org/leger/flatlatex Author: Jean-Benoist Leger Author-email: jb@leger.tf License: BSD-2 Description: LaTeX math to Unicode text converter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ flatlatex is a basic converter from LaTeX math to human readable text math using unicode characters. Basic example: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert( ... ( ... r'\forall \eta>0\, \exists n\in\mathbb{N}\, \forall i>n\,' ... r' |u_i-\mathcal{l}|<\eta' ... )) '∀η>0 ∃n∈ℕ ∀i>n |uᵢ-𝓵|<η' Commands can be added with LaTeX syntax: >>> import flatlatex >>> c = flatlatex.converter() >>> c.add_newcommand(r'\newcommand\prob{\mathbb{P}}') >>> c.add_newcommand(r'\newcommand\binom[2]{\frac{#2!}{#1!(#2-#1)!}}') >>> c.convert(r'\prob(X=k)\,=\,\binom{k}{n}\times p^k(1-p)^{n-k}') 'ℙ(X=k) = (n!)/(k!(n-k)!)×pᵏ(1-p)ⁿ⁻ᵏ' The behavior can be change: >>> import flatlatex >>> c = flatlatex.converter() >>> c.convert(r'\frac{8}{9}') '⁸⁄₉' >>> c.allow_zw = False >>> c.convert(r'\frac{8}{9}') '8/9' Keywords: latex math unicode Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Science/Research Classifier: Topic :: Text Processing :: Markup :: LaTeX Classifier: License :: OSI Approved Classifier: Programming Language :: Python :: 3 :: Only Requires-Python: >=3 Provides-Extra: test flatlatex-0.8/setup.py0000644000175000017500000001001213253455602014734 0ustar jbenjben00000000000000"""Setup script for flatlatex Based on `sampleproject`, see: https://github.com/pypa/sampleproject """ # Always prefer setuptools over distutils from setuptools import setup, find_packages # To use a consistent encoding from codecs import open from os import path here = path.abspath(path.dirname(__file__)) # Get the long description from the __init__.py file ### # c'est toi qui extrait la doc comme ca ? sinon to peux exec' the module et # garder le `__doc__`, tu peux en profiter pour attraper le `__version__` en # meme temps. ### with open(path.join(here, 'flatlatex', '__init__.py'), encoding='utf-8') as f: ast = compile(f.read(), '__init__.py', 'exec') fake_global = {'__name__': '__main__'} try: exec(ast, fake_global) except (SystemError, ImportError) as e: print('System error') long_description = fake_global['__doc__'] version = fake_global['__version__'] setup( name='flatlatex', # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html version=version, description='A LaTeX math converter to unicode text', long_description=long_description, # The project's main homepage. url='https://gitlab.crans.org/leger/flatlatex', # Author details author='Jean-Benoist Leger', author_email='jb@leger.tf', # Choose your license license='BSD-2', # See https://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=[ # How mature is this project? Common values are # 3 - Alpha # 4 - Beta # 5 - Production/Stable 'Development Status :: 3 - Alpha', # Indicate who your project is intended for 'Intended Audience :: Science/Research', 'Topic :: Text Processing :: Markup :: LaTeX', # Pick your license as you wish (should match "license" above) 'License :: OSI Approved', # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. 'Programming Language :: Python :: 3 :: Only', ], # What does your project relate to? keywords='latex math unicode', # You can just specify the packages manually here if your project is # simple. Or you can use find_packages(). packages=find_packages(exclude=['contrib', 'docs', 'tests']), # Alternatively, if you want to distribute just a my_module.py, uncomment # this: # py_modules=["my_module"], # List run-time dependencies here. These will be installed by pip when # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html install_requires=['regex'], # List additional groups of dependencies here (e.g. development # dependencies). You can install these using the following syntax, # for example: # $ pip install -e .[dev,test] extras_require={ 'test': ['pytest'], }, # If there are data files included in your packages that need to be # installed, specify them here. If using Python 2.6 or less, then these # have to be included in MANIFEST.in as well. package_data={ }, # Although 'package_data' is the preferred approach, in some case you may # need to place data files outside of your packages. See: # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa # In this case, 'data_file' will be installed into '/my_data' data_files=[], python_requires='>=3', # To provide executable scripts, use entry points in preference to the # "scripts" keyword. Entry points provide cross-platform support and allow # pip to create the appropriate form of executable for the target platform. entry_points={ 'console_scripts': [ "flatlatex=flatlatex.bin.flatlatex:main", ], }, )