summaryrefslogtreecommitdiff
path: root/tex/context/base/x-asciimath.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/x-asciimath.lua')
-rw-r--r--tex/context/base/x-asciimath.lua2209
1 files changed, 0 insertions, 2209 deletions
diff --git a/tex/context/base/x-asciimath.lua b/tex/context/base/x-asciimath.lua
deleted file mode 100644
index e0a4a714b..000000000
--- a/tex/context/base/x-asciimath.lua
+++ /dev/null
@@ -1,2209 +0,0 @@
-if not modules then modules = { } end modules ['x-asciimath'] = {
- version = 1.001,
- comment = "companion to x-asciimath.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-<p>Some backgrounds are discussed in <t>x-asciimath.mkiv</t>. This is a third version. I first
-tried a to make a proper expression parser but it's not that easy. First we have to avoid left
-recursion, which is not that trivial (maybe a future version of lpeg will provide that), and
-second there is not really a syntax but a mix of expressions and sequences with some fuzzy logic
-applied. Most problematic are fractions and we also need to handle incomplete expressions. So,
-instead we (sort of) tokenize the string and then do some passes over the result. Yes, it's real
-ugly and unsatisfying code mess down here. Don't take this as an example.</p>
---ldx]]--
-
--- todo: spaces around all elements in cleanup?
--- todo: filter from files listed in tuc file
-
-local trace_mapping = false if trackers then trackers.register("modules.asciimath.mapping", function(v) trace_mapping = v end) end
-local trace_detail = false if trackers then trackers.register("modules.asciimath.detail", function(v) trace_detail = v end) end
-local trace_digits = false if trackers then trackers.register("modules.asciimath.digits", function(v) trace_digits = v end) end
-
-local report_asciimath = logs.reporter("mathematics","asciimath")
-
-local asciimath = { }
-local moduledata = moduledata or { }
-moduledata.asciimath = asciimath
-
-if not characters then
- require("char-def")
- require("char-ini")
- require("char-ent")
-end
-
-local type, rawget = type, rawget
-local concat, insert, remove = table.concat, table.insert, table.remove
-local rep, gmatch, gsub, find = string.rep, string.gmatch, string.gsub, string.find
-local utfchar, utfbyte = utf.char, utf.byte
-
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
-local S, P, R, C, V, Cc, Ct, Cs, Carg = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct, lpeg.Cs, lpeg.Carg
-
-local sortedhash = table.sortedhash
-local sortedkeys = table.sortedkeys
-local formatters = string.formatters
-
-local entities = characters.entities or { }
-
-local xmltext = xml.text
-local xmlinclusion = xml.inclusion
-local xmlcollected = xml.collected
-
--- todo: use private unicodes as temporary slots ... easier to compare
-
-local s_lparent = "\\left\\lparent"
-local s_lbrace = "\\left\\lbrace"
-local s_lbracket = "\\left\\lbracket"
-local s_langle = "\\left\\langle"
-local s_lfloor = "\\left\\lfloor"
-local s_lceil = "\\left\\lceil"
-local s_left = "\\left."
-
-local s_rparent = "\\right\\rparent"
-local s_rbrace = "\\right\\rbrace"
-local s_rbracket = "\\right\\rbracket"
-local s_rangle = "\\right\\rangle"
-local s_rfloor = "\\right\\rfloor"
-local s_rceil = "\\right\\rceil"
-local s_right = "\\right."
-
-local s_mslash = "\\middle/"
-
-local s_lbar = "\\left\\|"
-local s_mbar = "\\middle\\|"
-local s_rbar = "\\right\\|"
-
-local s_lnothing = "\\left ." -- space fools checker
-local s_rnothing = "\\right ." -- space fools checker
-
-local reserved = {
-
- ["prod"] = { false, "\\prod" },
- ["sinh"] = { false, "\\sinh" },
- ["cosh"] = { false, "\\cosh" },
- ["tanh"] = { false, "\\tanh" },
- ["sum"] = { false, "\\sum" },
- ["int"] = { false, "\\int" },
- ["sin"] = { false, "\\sin" },
- ["cos"] = { false, "\\cos" },
- ["tan"] = { false, "\\tan" },
- ["csc"] = { false, "\\csc" },
- ["sec"] = { false, "\\sec" },
- ["cot"] = { false, "\\cot" },
- ["log"] = { false, "\\log" },
- ["det"] = { false, "\\det" },
- ["lim"] = { false, "\\lim" },
- ["mod"] = { false, "\\mod" },
- ["gcd"] = { false, "\\gcd" },
- ["min"] = { false, "\\min" },
- ["max"] = { false, "\\max" },
- ["ln"] = { false, "\\ln" },
-
- ["atan"] = { false, "\\atan" }, -- extra
- ["acos"] = { false, "\\acos" }, -- extra
- ["asin"] = { false, "\\asin" }, -- extra
-
- ["arctan"] = { false, "\\arctan" }, -- extra
- ["arccos"] = { false, "\\arccos" }, -- extra
- ["arcsin"] = { false, "\\arcsin" }, -- extra
-
- ["and"] = { false, "\\text{and}" },
- ["or"] = { false, "\\text{or}" },
- ["if"] = { false, "\\text{if}" },
-
- ["sqrt"] = { false, "\\asciimathsqrt", "unary" },
- ["root"] = { false, "\\asciimathroot", "binary" },
- -- ["\\frac"] = { false, "\\frac", "binary" },
- ["frac"] = { false, "\\frac", "binary" },
- ["stackrel"] = { false, "\\asciimathstackrel", "binary" },
- ["hat"] = { false, "\\widehat", "unary" },
- ["bar"] = { false, "\\overbar", "unary" },
- ["overbar"] = { false, "\\overbar", "unary" },
- ["underline"] = { false, "\\underline", "unary" },
- ["ul"] = { false, "\\underline", "unary" },
- ["vec"] = { false, "\\overrightarrow", "unary" },
- ["dot"] = { false, "\\dot", "unary" }, -- 0x2D9
- ["ddot"] = { false, "\\ddot", "unary" }, -- 0xA8
-
- -- binary operators
-
- ["+"] = { true, "+" },
- ["-"] = { true, "-" },
- ["*"] = { true, "⋅" },
- ["**"] = { true, "⋆" },
- ["//"] = { true, "⁄" }, -- \slash
- ["\\"] = { true, "\\" },
- ["xx"] = { true, "×" },
- ["times"] = { true, "×" },
- ["-:"] = { true, "÷" },
- ["@"] = { true, "∘" },
- ["circ"] = { true, "∘" },
- ["o+"] = { true, "⊕" },
- ["ox"] = { true, "⊗" },
- ["o."] = { true, "⊙" },
- ["^^"] = { true, "∧" },
- ["vv"] = { true, "∨" },
- ["nn"] = { true, "∩" },
- ["uu"] = { true, "∪" },
-
- -- big operators
-
- ["^^^"] = { true, "⋀" },
- ["vvv"] = { true, "⋁" },
- ["nnn"] = { true, "⋂" },
- ["uuu"] = { true, "⋃" },
- ["int"] = { true, "∫" },
- ["oint"] = { true, "∮" },
-
- -- brackets
-
- ["("] = { true, "(" },
- [")"] = { true, ")" },
- ["["] = { true, "[" },
- ["]"] = { true, "]" },
- ["{"] = { true, "{" },
- ["}"] = { true, "}" },
-
- -- binary relations
-
- ["="] = { true, "=" },
- ["eq"] = { true, "=" },
- ["!="] = { true, "≠" },
- ["ne"] = { true, "≠" },
- ["neq"] = { true, "≠" },
- ["<"] = { true, "<" },
- ["lt"] = { true, "<" },
- [">"] = { true, ">" },
- ["gt"] = { true, ">" },
- ["<="] = { true, "≤" },
- ["le"] = { true, "≤" },
- ["leq"] = { true, "≤" },
- [">="] = { true, "≥" },
- ["ge"] = { true, "≥" },
- ["geq"] = { true, "≥" },
- ["-<"] = { true, "≺" },
- [">-"] = { true, "≻" },
- ["in"] = { true, "∈" },
- ["!in"] = { true, "∉" },
- ["sub"] = { true, "⊂" },
- ["sup"] = { true, "⊃" },
- ["sube"] = { true, "⊆" },
- ["supe"] = { true, "⊇" },
- ["-="] = { true, "≡" },
- ["~="] = { true, "≅" },
- ["~~"] = { true, "≈" },
- ["prop"] = { true, "∝" },
-
- -- arrows
-
- ["rarr"] = { true, "→" },
- ["->"] = { true, "→" },
- ["larr"] = { true, "←" },
- ["harr"] = { true, "↔" },
- ["uarr"] = { true, "↑" },
- ["darr"] = { true, "↓" },
- ["rArr"] = { true, "⇒" },
- ["lArr"] = { true, "⇐" },
- ["hArr"] = { true, "⇔" },
- ["|->"] = { true, "↦" },
-
- -- logical
-
- ["not"] = { true, "¬" },
- ["=>"] = { true, "⇒" },
- ["iff"] = { true, "⇔" },
- ["AA"] = { true, "∀" },
- ["EE"] = { true, "∃" },
- ["_|_"] = { true, "⊥" },
- ["TT"] = { true, "⊤" },
- ["|--"] = { true, "⊢" },
- ["|=="] = { true, "⊨" },
-
- -- miscellaneous
-
- ["del"] = { true, "∂" },
- ["grad"] = { true, "∇" },
- ["+-"] = { true, "±" },
- ["O/"] = { true, "∅" },
- ["oo"] = { true, "∞" },
- ["aleph"] = { true, "ℵ" },
- ["angle"] = { true, "∠" },
- ["/_"] = { true, "∠" },
- [":."] = { true, "∴" },
- ["..."] = { true, "..." }, -- ldots
- ["ldots"] = { true, "..." }, -- ldots
- ["cdots"] = { true, "⋯" },
- ["vdots"] = { true, "⋮" },
- ["ddots"] = { true, "⋱" },
- ["diamond"] = { true, "⋄" },
- ["square"] = { true, "□" },
- ["|__"] = { true, "⌊" },
- ["__|"] = { true, "⌋" },
- ["|~"] = { true, "⌈" },
- ["~|"] = { true, "⌉" },
-
- -- more
-
- ["_="] = { true, "≡" },
-
- -- bonus
-
- ["prime"] = { true, "′" }, -- bonus
- ["'"] = { true, "′" }, -- bonus
- ["''"] = { true, "″" }, -- bonus
- ["'''"] = { true, "‴" }, -- bonus
-
- -- special
-
- ["%"] = { false, "\\mathpercent" },
- ["&"] = { false, "\\mathampersand" },
- ["#"] = { false, "\\mathhash" },
- ["$"] = { false, "\\mathdollar" },
-
- -- blackboard
-
- ["CC"] = { true, "ℂ" },
- ["NN"] = { true, "ℕ" },
- ["QQ"] = { true, "ℚ" },
- ["RR"] = { true, "ℝ" },
- ["ZZ"] = { true, "ℤ" },
-
- -- greek lowercase
-
- ["alpha"] = { true, "α" },
- ["beta"] = { true, "β" },
- ["gamma"] = { true, "γ" },
- ["delta"] = { true, "δ" },
- ["epsilon"] = { true, "ε" },
- ["varepsilon"] = { true, "ɛ" },
- ["zeta"] = { true, "ζ" },
- ["eta"] = { true, "η" },
- ["theta"] = { true, "θ" },
- ["vartheta"] = { true, "ϑ" },
- ["iota"] = { true, "ι" },
- ["kappa"] = { true, "κ" },
- ["lambda"] = { true, "λ" },
- ["mu"] = { true, "μ" },
- ["nu"] = { true, "ν" },
- ["xi"] = { true, "ξ" },
- ["pi"] = { true, "π" },
- ["rho"] = { true, "ρ" },
- ["sigma"] = { true, "σ" },
- ["tau"] = { true, "τ" },
- ["upsilon"] = { true, "υ" },
- ["phi"] = { true, "φ" },
- ["varphi"] = { true, "ϕ" },
- ["chi"] = { true, "χ" },
- ["psi"] = { true, "ψ" },
- ["omega"] = { true, "ω" },
-
- -- greek uppercase
-
- ["Gamma"] = { true, "Γ" },
- ["Delta"] = { true, "Δ" },
- ["Theta"] = { true, "Θ" },
- ["Lambda"] = { true, "Λ" },
- ["Xi"] = { true, "Ξ" },
- ["Pi"] = { true, "Π" },
- ["Sigma"] = { true, "Σ" },
- ["Phi"] = { true, "Φ" },
- ["Psi"] = { true, "Ψ" },
- ["Omega"] = { true, "Ω" },
-
- -- blackboard
-
- ["bbb a"] = { true, "𝕒" },
- ["bbb b"] = { true, "𝕓" },
- ["bbb c"] = { true, "𝕔" },
- ["bbb d"] = { true, "𝕕" },
- ["bbb e"] = { true, "𝕖" },
- ["bbb f"] = { true, "𝕗" },
- ["bbb g"] = { true, "𝕘" },
- ["bbb h"] = { true, "𝕙" },
- ["bbb i"] = { true, "𝕚" },
- ["bbb j"] = { true, "𝕛" },
- ["bbb k"] = { true, "𝕜" },
- ["bbb l"] = { true, "𝕝" },
- ["bbb m"] = { true, "𝕞" },
- ["bbb n"] = { true, "𝕟" },
- ["bbb o"] = { true, "𝕠" },
- ["bbb p"] = { true, "𝕡" },
- ["bbb q"] = { true, "𝕢" },
- ["bbb r"] = { true, "𝕣" },
- ["bbb s"] = { true, "𝕤" },
- ["bbb t"] = { true, "𝕥" },
- ["bbb u"] = { true, "𝕦" },
- ["bbb v"] = { true, "𝕧" },
- ["bbb w"] = { true, "𝕨" },
- ["bbb x"] = { true, "𝕩" },
- ["bbb y"] = { true, "𝕪" },
- ["bbb z"] = { true, "𝕫" },
-
- ["bbb A"] = { true, "𝔸" },
- ["bbb B"] = { true, "𝔹" },
- ["bbb C"] = { true, "ℂ" },
- ["bbb D"] = { true, "𝔻" },
- ["bbb E"] = { true, "𝔼" },
- ["bbb F"] = { true, "𝔽" },
- ["bbb G"] = { true, "𝔾" },
- ["bbb H"] = { true, "ℍ" },
- ["bbb I"] = { true, "𝕀" },
- ["bbb J"] = { true, "𝕁" },
- ["bbb K"] = { true, "𝕂" },
- ["bbb L"] = { true, "𝕃" },
- ["bbb M"] = { true, "𝕄" },
- ["bbb N"] = { true, "ℕ" },
- ["bbb O"] = { true, "𝕆" },
- ["bbb P"] = { true, "ℙ" },
- ["bbb Q"] = { true, "ℚ" },
- ["bbb R"] = { true, "ℝ" },
- ["bbb S"] = { true, "𝕊" },
- ["bbb T"] = { true, "𝕋" },
- ["bbb U"] = { true, "𝕌" },
- ["bbb V"] = { true, "𝕍" },
- ["bbb W"] = { true, "𝕎" },
- ["bbb X"] = { true, "𝕏" },
- ["bbb Y"] = { true, "𝕐" },
- ["bbb Z"] = { true, "ℤ" },
-
- -- fraktur
-
- ["fr a"] = { true, "𝔞" },
- ["fr b"] = { true, "𝔟" },
- ["fr c"] = { true, "𝔠" },
- ["fr d"] = { true, "𝔡" },
- ["fr e"] = { true, "𝔢" },
- ["fr f"] = { true, "𝔣" },
- ["fr g"] = { true, "𝔤" },
- ["fr h"] = { true, "𝔥" },
- ["fr i"] = { true, "𝔦" },
- ["fr j"] = { true, "𝔧" },
- ["fr k"] = { true, "𝔨" },
- ["fr l"] = { true, "𝔩" },
- ["fr m"] = { true, "𝔪" },
- ["fr n"] = { true, "𝔫" },
- ["fr o"] = { true, "𝔬" },
- ["fr p"] = { true, "𝔭" },
- ["fr q"] = { true, "𝔮" },
- ["fr r"] = { true, "𝔯" },
- ["fr s"] = { true, "𝔰" },
- ["fr t"] = { true, "𝔱" },
- ["fr u"] = { true, "𝔲" },
- ["fr v"] = { true, "𝔳" },
- ["fr w"] = { true, "𝔴" },
- ["fr x"] = { true, "𝔵" },
- ["fr y"] = { true, "𝔶" },
- ["fr z"] = { true, "𝔷" },
-
- ["fr A"] = { true, "𝔄" },
- ["fr B"] = { true, "𝔅" },
- ["fr C"] = { true, "ℭ" },
- ["fr D"] = { true, "𝔇" },
- ["fr E"] = { true, "𝔈" },
- ["fr F"] = { true, "𝔉" },
- ["fr G"] = { true, "𝔊" },
- ["fr H"] = { true, "ℌ" },
- ["fr I"] = { true, "ℑ" },
- ["fr J"] = { true, "𝔍" },
- ["fr K"] = { true, "𝔎" },
- ["fr L"] = { true, "𝔏" },
- ["fr M"] = { true, "𝔐" },
- ["fr N"] = { true, "𝔑" },
- ["fr O"] = { true, "𝔒" },
- ["fr P"] = { true, "𝔓" },
- ["fr Q"] = { true, "𝔔" },
- ["fr R"] = { true, "ℜ" },
- ["fr S"] = { true, "𝔖" },
- ["fr T"] = { true, "𝔗" },
- ["fr U"] = { true, "𝔘" },
- ["fr V"] = { true, "𝔙" },
- ["fr W"] = { true, "𝔚" },
- ["fr X"] = { true, "𝔛" },
- ["fr Y"] = { true, "𝔜" },
- ["fr Z"] = { true, "ℨ" },
-
- -- script
-
- ["cc a"] = { true, "𝒶" },
- ["cc b"] = { true, "𝒷" },
- ["cc c"] = { true, "𝒸" },
- ["cc d"] = { true, "𝒹" },
- ["cc e"] = { true, "ℯ" },
- ["cc f"] = { true, "𝒻" },
- ["cc g"] = { true, "ℊ" },
- ["cc h"] = { true, "𝒽" },
- ["cc i"] = { true, "𝒾" },
- ["cc j"] = { true, "𝒿" },
- ["cc k"] = { true, "𝓀" },
- ["cc l"] = { true, "𝓁" },
- ["cc m"] = { true, "𝓂" },
- ["cc n"] = { true, "𝓃" },
- ["cc o"] = { true, "ℴ" },
- ["cc p"] = { true, "𝓅" },
- ["cc q"] = { true, "𝓆" },
- ["cc r"] = { true, "𝓇" },
- ["cc s"] = { true, "𝓈" },
- ["cc t"] = { true, "𝓉" },
- ["cc u"] = { true, "𝓊" },
- ["cc v"] = { true, "𝓋" },
- ["cc w"] = { true, "𝓌" },
- ["cc x"] = { true, "𝓍" },
- ["cc y"] = { true, "𝓎" },
- ["cc z"] = { true, "𝓏" },
-
- ["cc A"] = { true, "𝒜" },
- ["cc B"] = { true, "ℬ" },
- ["cc C"] = { true, "𝒞" },
- ["cc D"] = { true, "𝒟" },
- ["cc E"] = { true, "ℰ" },
- ["cc F"] = { true, "ℱ" },
- ["cc G"] = { true, "𝒢" },
- ["cc H"] = { true, "ℋ" },
- ["cc I"] = { true, "ℐ" },
- ["cc J"] = { true, "𝒥" },
- ["cc K"] = { true, "𝒦" },
- ["cc L"] = { true, "ℒ" },
- ["cc M"] = { true, "ℳ" },
- ["cc N"] = { true, "𝒩" },
- ["cc O"] = { true, "𝒪" },
- ["cc P"] = { true, "𝒫" },
- ["cc Q"] = { true, "𝒬" },
- ["cc R"] = { true, "ℛ" },
- ["cc S"] = { true, "𝒮" },
- ["cc T"] = { true, "𝒯" },
- ["cc U"] = { true, "𝒰" },
- ["cc V"] = { true, "𝒱" },
- ["cc W"] = { true, "𝒲" },
- ["cc X"] = { true, "𝒳" },
- ["cc Y"] = { true, "𝒴" },
- ["cc Z"] = { true, "𝒵" },
-
- -- bold
-
- ["bb a"] = { true, "𝒂" },
- ["bb b"] = { true, "𝒃" },
- ["bb c"] = { true, "𝒄" },
- ["bb d"] = { true, "𝒅" },
- ["bb e"] = { true, "𝒆" },
- ["bb f"] = { true, "𝒇" },
- ["bb g"] = { true, "𝒈" },
- ["bb h"] = { true, "𝒉" },
- ["bb i"] = { true, "𝒊" },
- ["bb j"] = { true, "𝒋" },
- ["bb k"] = { true, "𝒌" },
- ["bb l"] = { true, "𝒍" },
- ["bb m"] = { true, "𝒎" },
- ["bb n"] = { true, "𝒏" },
- ["bb o"] = { true, "𝒐" },
- ["bb p"] = { true, "𝒑" },
- ["bb q"] = { true, "𝒒" },
- ["bb r"] = { true, "𝒓" },
- ["bb s"] = { true, "𝒔" },
- ["bb t"] = { true, "𝒕" },
- ["bb u"] = { true, "𝒖" },
- ["bb v"] = { true, "𝒗" },
- ["bb w"] = { true, "𝒘" },
- ["bb x"] = { true, "𝒙" },
- ["bb y"] = { true, "𝒚" },
- ["bb z"] = { true, "𝒛" },
-
- ["bb A"] = { true, "𝑨" },
- ["bb B"] = { true, "𝑩" },
- ["bb C"] = { true, "𝑪" },
- ["bb D"] = { true, "𝑫" },
- ["bb E"] = { true, "𝑬" },
- ["bb F"] = { true, "𝑭" },
- ["bb G"] = { true, "𝑮" },
- ["bb H"] = { true, "𝑯" },
- ["bb I"] = { true, "𝑰" },
- ["bb J"] = { true, "𝑱" },
- ["bb K"] = { true, "𝑲" },
- ["bb L"] = { true, "𝑳" },
- ["bb M"] = { true, "𝑴" },
- ["bb N"] = { true, "𝑵" },
- ["bb O"] = { true, "𝑶" },
- ["bb P"] = { true, "𝑷" },
- ["bb Q"] = { true, "𝑸" },
- ["bb R"] = { true, "𝑹" },
- ["bb S"] = { true, "𝑺" },
- ["bb T"] = { true, "𝑻" },
- ["bb U"] = { true, "𝑼" },
- ["bb V"] = { true, "𝑽" },
- ["bb W"] = { true, "𝑾" },
- ["bb X"] = { true, "𝑿" },
- ["bb Y"] = { true, "𝒀" },
- ["bb Z"] = { true, "𝒁" },
-
- -- sans
-
- ["sf a"] = { true, "𝖺" },
- ["sf b"] = { true, "𝖻" },
- ["sf c"] = { true, "𝖼" },
- ["sf d"] = { true, "𝖽" },
- ["sf e"] = { true, "𝖾" },
- ["sf f"] = { true, "𝖿" },
- ["sf g"] = { true, "𝗀" },
- ["sf h"] = { true, "𝗁" },
- ["sf i"] = { true, "𝗂" },
- ["sf j"] = { true, "𝗃" },
- ["sf k"] = { true, "𝗄" },
- ["sf l"] = { true, "𝗅" },
- ["sf m"] = { true, "𝗆" },
- ["sf n"] = { true, "𝗇" },
- ["sf o"] = { true, "𝗈" },
- ["sf p"] = { true, "𝗉" },
- ["sf q"] = { true, "𝗊" },
- ["sf r"] = { true, "𝗋" },
- ["sf s"] = { true, "𝗌" },
- ["sf t"] = { true, "𝗍" },
- ["sf u"] = { true, "𝗎" },
- ["sf v"] = { true, "𝗏" },
- ["sf w"] = { true, "𝗐" },
- ["sf x"] = { true, "𝗑" },
- ["sf y"] = { true, "𝗒" },
- ["sf z"] = { true, "𝗓" },
-
- ["sf A"] = { true, "𝖠" },
- ["sf B"] = { true, "𝖡" },
- ["sf C"] = { true, "𝖢" },
- ["sf D"] = { true, "𝖣" },
- ["sf E"] = { true, "𝖤" },
- ["sf F"] = { true, "𝖥" },
- ["sf G"] = { true, "𝖦" },
- ["sf H"] = { true, "𝖧" },
- ["sf I"] = { true, "𝖨" },
- ["sf J"] = { true, "𝖩" },
- ["sf K"] = { true, "𝖪" },
- ["sf L"] = { true, "𝖫" },
- ["sf M"] = { true, "𝖬" },
- ["sf N"] = { true, "𝖭" },
- ["sf O"] = { true, "𝖮" },
- ["sf P"] = { true, "𝖯" },
- ["sf Q"] = { true, "𝖰" },
- ["sf R"] = { true, "𝖱" },
- ["sf S"] = { true, "𝖲" },
- ["sf T"] = { true, "𝖳" },
- ["sf U"] = { true, "𝖴" },
- ["sf V"] = { true, "𝖵" },
- ["sf W"] = { true, "𝖶" },
- ["sf X"] = { true, "𝖷" },
- ["sf Y"] = { true, "𝖸" },
- ["sf Z"] = { true, "𝖹" },
-
- -- monospace
-
- ["tt a"] = { true, "𝚊" },
- ["tt b"] = { true, "𝚋" },
- ["tt c"] = { true, "𝚌" },
- ["tt d"] = { true, "𝚍" },
- ["tt e"] = { true, "𝚎" },
- ["tt f"] = { true, "𝚏" },
- ["tt g"] = { true, "𝚐" },
- ["tt h"] = { true, "𝚑" },
- ["tt i"] = { true, "𝚒" },
- ["tt j"] = { true, "𝚓" },
- ["tt k"] = { true, "𝚔" },
- ["tt l"] = { true, "𝚕" },
- ["tt m"] = { true, "𝚖" },
- ["tt n"] = { true, "𝚗" },
- ["tt o"] = { true, "𝚘" },
- ["tt p"] = { true, "𝚙" },
- ["tt q"] = { true, "𝚚" },
- ["tt r"] = { true, "𝚛" },
- ["tt s"] = { true, "𝚜" },
- ["tt t"] = { true, "𝚝" },
- ["tt u"] = { true, "𝚞" },
- ["tt v"] = { true, "𝚟" },
- ["tt w"] = { true, "𝚠" },
- ["tt x"] = { true, "𝚡" },
- ["tt y"] = { true, "𝚢" },
- ["tt z"] = { true, "𝚣" },
-
- ["tt A"] = { true, "𝙰" },
- ["tt B"] = { true, "𝙱" },
- ["tt C"] = { true, "𝙲" },
- ["tt D"] = { true, "𝙳" },
- ["tt E"] = { true, "𝙴" },
- ["tt F"] = { true, "𝙵" },
- ["tt G"] = { true, "𝙶" },
- ["tt H"] = { true, "𝙷" },
- ["tt I"] = { true, "𝙸" },
- ["tt J"] = { true, "𝙹" },
- ["tt K"] = { true, "𝙺" },
- ["tt L"] = { true, "𝙻" },
- ["tt M"] = { true, "𝙼" },
- ["tt N"] = { true, "𝙽" },
- ["tt O"] = { true, "𝙾" },
- ["tt P"] = { true, "𝙿" },
- ["tt Q"] = { true, "𝚀" },
- ["tt R"] = { true, "𝚁" },
- ["tt S"] = { true, "𝚂" },
- ["tt T"] = { true, "𝚃" },
- ["tt U"] = { true, "𝚄" },
- ["tt V"] = { true, "𝚅" },
- ["tt W"] = { true, "𝚆" },
- ["tt X"] = { true, "𝚇" },
- ["tt Y"] = { true, "𝚈" },
- ["tt Z"] = { true, "𝚉" },
-
- -- some more undocumented
-
- ["dx"] = { false, { "d", "x" } }, -- "{dx}" "\\left(dx\\right)"
- ["dy"] = { false, { "d", "y" } }, -- "{dy}" "\\left(dy\\right)"
- ["dz"] = { false, { "d", "z" } }, -- "{dz}" "\\left(dz\\right)"
-
- -- fences
-
- ["(:"] = { true, "(:" },
- ["{:"] = { true, "{:" },
- ["[:"] = { true, "[:" },
- ["("] = { true, "(" },
- ["["] = { true, "[" },
- ["{"] = { true, "{" },
- ["<<"] = { true, "⟨" }, -- why not <:
- ["|_"] = { true, "⌊" },
- ["|~"] = { true, "⌈" },
- ["⟨"] = { true, "⟨" },
- ["〈"] = { true, "⟨" },
- ["〈"] = { true, "⟨" },
-
- [":)"] = { true, ":)" },
- [":}"] = { true, ":}" },
- [":]"] = { true, ":]" },
- [")"] = { true, ")" },
- ["]"] = { true, "]" },
- ["}"] = { true, "}" },
- [">>"] = { true, "⟩" }, -- why not :>
- ["~|"] = { true, "⌉" },
- ["_|"] = { true, "⌋" },
- ["⟩"] = { true, "⟩" },
- ["〉"] = { true, "⟩" },
- ["〉"] = { true, "⟩" },
-
- ["lparent"] = { true, "(" },
- ["lbracket"] = { true, "[" },
- ["lbrace"] = { true, "{" },
- ["langle"] = { true, "⟨" },
- ["lfloor"] = { true, "⌊" },
- ["lceil"] = { true, "⌈" },
-
- ["rparent"] = { true, ")" },
- ["rbracket"] = { true, "]" },
- ["rbrace"] = { true, "}" },
- ["rangle"] = { true, "⟩" },
- ["rfloor"] = { true, "⌋" },
- ["rceil"] = { true, "⌉" },
-
- -- a bit special:
-
--- ["\\frac"] = { true, "frac" },
-
- -- now it gets real crazy, only these two:
-
- ["&gt;"] = { true, ">" },
- ["&lt;"] = { true, "<" },
-
- -- extra:
-
- -- also, invisible times
-
- ["dd"] = { false, "{\\tf d}" },
- ["ee"] = { false, "{\\tf e}" },
- ["xxx"] = { true, utfchar(0x2063) }, -- invisible times
-
-}
-
--- a..z A..Z : allemaal op italic alphabet
--- en dan default naar upright "upr a"
-
-for k, v in next, characters.data do
- local name = v.mathname
- if name and not reserved[name] then
- local char = { true, utfchar(k) }
- reserved[ name] = char
- -- reserved["\\" .. name] = char
- end
- -- local spec = v.mathspec
- -- if spec then
- -- for i=1,#spec do
- -- local name = spec[i].name
- -- if name and not reserved[name] then
- -- reserved[name] = { true, utfchar(k) }
- -- end
- -- end
- -- end
-end
-
-reserved.P = nil
-reserved.S = nil
-
-local isbinary = {
- ["\\frac"] = true,
- ["\\root"] = true,
- ["\\asciimathroot"] = true,
- ["\\asciimathstackrel"] = true,
-}
-
-local isunary = { -- can be taken from reserved
- ["\\sqrt"] = true,
- ["\\asciimathsqrt"] = true,
- ["\\text"] = true, -- mathoptext
- ["\\mathoptext"] = true, -- mathoptext
- ["\\asciimathoptext"] = true, -- mathoptext
- ["\\hat"] = true, -- widehat
- ["\\widehat"] = true, -- widehat
- ["\\bar"] = true, --
- ["\\overbar"] = true, --
- ["\\underline"] = true, --
- ["\\vec"] = true, -- overrightarrow
- ["\\overrightarrow"] = true, -- overrightarrow
- ["\\dot"] = true, --
- ["\\ddot"] = true, --
-
-}
-
-local isfunny = {
- ["\\sin"] = true,
-}
-
-local isinfix = {
- ["^"] = true,
- ["_"] = true,
-}
-
-local isstupid = {
- ["\\prod"] = true,
- ["\\sinh"] = true,
- ["\\cosh"] = true,
- ["\\tanh"] = true,
- ["\\sum"] = true,
- ["\\int"] = true,
- ["\\sin"] = true,
- ["\\cos"] = true,
- ["\\tan"] = true,
- ["\\csc"] = true,
- ["\\sec"] = true,
- ["\\cot"] = true,
- ["\\log"] = true,
- ["\\det"] = true,
- ["\\lim"] = true,
- ["\\mod"] = true,
- ["\\gcd"] = true,
- ["\\min"] = true,
- ["\\max"] = true,
- ["\\ln"] = true,
-
- ["\\atan"] = true,
- ["\\acos"] = true,
- ["\\asin"] = true,
- true,
- ["\\arctan"] = true,
- ["\\arccos"] = true,
- ["\\arcsin"] = true,
-
- ["f"] = true,
- ["g"] = true,
-}
-
-local isleft = {
- [s_lparent] = true,
- [s_lbrace] = true,
- [s_lbracket] = true,
- [s_langle] = true,
- [s_lfloor] = true,
- [s_lceil] = true,
- [s_left] = true,
-}
-
-local isright = {
- [s_rparent] = true,
- [s_rbrace] = true,
- [s_rbracket] = true,
- [s_rangle] = true,
- [s_rfloor] = true,
- [s_rceil] = true,
- [s_right] = true,
-}
-
-local issimplified = {
-}
-
---
-
--- special mess
-
-local d_one = R("09")
-local d_two = d_one * d_one
-local d_three = d_two * d_one
-local d_four = d_three * d_one
-local d_split = P(-1) + Carg(2) * (S(".") /"")
-
-local d_spaced = (Carg(1) * d_three)^1
-
-local digitized_1 = Cs ( (
- d_three * d_spaced * d_split +
- d_two * d_spaced * d_split +
- d_one * d_spaced * d_split +
- P(1)
- )^1 )
-
-local p_fourbefore = d_four * d_split
-local p_fourafter = d_four * P(-1)
-
-local p_beforecomma = d_three * d_spaced^0 * d_split
- + d_two * d_spaced^0 * d_split
- + d_one * d_spaced^0 * d_split
- + d_one * d_split
-
-local p_aftercomma = p_fourafter
- + d_three * d_spaced
- + d_two * d_spaced
- + d_one * d_spaced
-
-local digitized_2 = Cs (
- p_fourbefore * (p_aftercomma^0) +
- p_beforecomma * ((p_aftercomma + d_one^1)^0)
- )
-
-local p_fourbefore = d_four * d_split
-local p_fourafter = d_four
-local d_spaced = (Carg(1) * (d_three + d_two + d_one))^1
-local p_aftercomma = p_fourafter * P(-1)
- + d_three * d_spaced * P(1)^0
- + d_one^1
-
--- local digitized_3 = Cs (
--- p_fourbefore * p_aftercomma^0 +
--- p_beforecomma * p_aftercomma^0
--- )
-
-local digitized_3 = Cs((p_fourbefore + p_beforecomma) * p_aftercomma^0)
-
-local splitmethods = {
- digitized_1,
- digitized_2,
- digitized_3,
-}
-
-local splitmethod = nil
-local symbolmethod = nil
-local digitseparator = utfchar(0x2008)
-local digitsymbol = "."
-
-function asciimath.setup(settings)
- splitmethod = splitmethods[tonumber(settings.splitmethod) or 0]
- if splitmethod then
- digitsymbol = settings.symbol
- if not digitsymbol or digitsymbol == "" then
- digitsymbol = "."
- end
- local separator = settings.separator
- if separator == true or not interfaces or interfaces.variables.yes then
- digitseparator = utfchar(0x2008)
- elseif type(separator) == "string" and separator ~= "" then
- digitseparator = separator
- else
- splitmethod = nil
- end
- if digitsymbol ~= "." then
- symbolmethod = lpeg.replacer(".",digitsymbol)
- else
- symbolmethod = nil
- end
- end
-end
-
-local collected_digits = { }
-local collected_filename = "asciimath-digits.lua"
-
-function numbermess(s)
- if splitmethod then
- local d = lpegmatch(splitmethod,s,1,digitseparator,digitsymbol)
- if not d and symbolmethod then
- d = lpegmatch(symbolmethod,s)
- end
- if d then
- if trace_digits and s ~= d then
- collected_digits[s] = d
- end
- return d
- end
- end
- return s
-end
-
--- asciimath.setup { splitmethod = 3, symbol = "," }
--- local t = {
--- "0.00002",
--- "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678", "123456789",
--- "1.1",
--- "12.12",
--- "123.123",
--- "1234.123",
--- "1234.1234",
--- "12345.1234",
--- "1234.12345",
--- "12345.12345",
--- "123456.123456",
--- "1234567.1234567",
--- "12345678.12345678",
--- "123456789.123456789",
--- "0.1234",
--- "1234.0",
--- "1234.00",
--- "0.123456789",
--- "100.00005",
--- "0.80018",
--- "10.80018",
--- "100.80018",
--- "1000.80018",
--- "10000.80018",
--- }
--- for i=1,#t do print(formatters["%-20s : [%s]"](t[i],numbermess(t[i]))) end
-
-statistics.register("asciimath",function()
- if trace_digits then
- local n = table.count(collected_digits)
- if n > 0 then
- table.save(collected_filename,collected_digits)
- return string.format("%s digit conversions saved in %s",n,collected_filename)
- else
- os.remove(collected_filename)
- end
- end
-end)
-
-local p_number_base = patterns.cpnumber or patterns.cnumber or patterns.number
-local p_number = C(p_number_base)
------ p_number = p_number_base
-local p_spaces = patterns.whitespace
-
-local p_utf_base = patterns.utf8character
-local p_utf = C(p_utf_base)
--- local p_entity = (P("&") * C((1-P(";"))^2) * P(";"))/ entities
-
--- entities["gt"] = ">"
--- entities["lt"] = "<"
--- entities["amp"] = "&"
--- entities["dquot"] = '"'
--- entities["quot"] = "'"
-
-local p_onechar = p_utf_base * P(-1)
-
------ p_number = Cs((patterns.cpnumber or patterns.cnumber or patterns.number)/function(s) return (gsub(s,",","{,}")) end)
-
-local sign = P("-")^-1
-local digits = R("09")^1
-local integer = sign * digits
-local real = digits * (S(".") * digits)^-1
-local float = real * (P("E") * integer)^-1
-
--- local number = C(float + integer)
--- local p_number = C(float)
-local p_number = float / numbermess
-
-local k_reserved = sortedkeys(reserved)
-local k_commands = { }
-local k_unicode = { }
-
-asciimath.keys = {
- reserved = k_reserved
-}
-
-local k_reserved_different = { }
-local k_reserved_words = { }
-
-for k, v in sortedhash(reserved) do
- local replacement = v[2]
- if v[1] then
- k_unicode[k] = replacement
- else
- k_unicode[k] = k -- keep them ... later we remap these
- if k ~= replacement then
- k_reserved_different[#k_reserved_different+1] = k
- end
- end
- if find(k,"^[a-zA-Z]+$") then
- k_unicode["\\"..k] = replacement
- else
- k_unicode["\\"..k] = k -- dirty trick, no real unicode (still needed ?)
- end
- if not find(k,"[^a-zA-Z]") then
- k_reserved_words[#k_reserved_words+1] = k
- end
- k_commands[k] = replacement
-end
-
-local p_reserved =
- lpeg.utfchartabletopattern(k_reserved_different) / k_commands
-
-local p_unicode =
--- lpeg.utfchartabletopattern(table.keys(k_unicode)) / k_unicode
- lpeg.utfchartabletopattern(k_unicode) / k_unicode
-
-local p_texescape = patterns.texescape
-
-local function texescaped(s)
- return lpegmatch(p_texescape,s) or s
-end
-
-local p_text =
- P("text")
- * p_spaces^0
- * Cc("\\asciimathoptext")
- * ( -- maybe balanced
- Cs( P("{") * ((1-P("}"))^0/texescaped) * P("}") )
- + Cs((P("(")/"{") * ((1-P(")"))^0/texescaped) * (P(")")/"}"))
- )
- + Cc("\\asciimathoptext") * Cs(Cc("{") * (C(patterns.undouble)/texescaped) * Cc("}"))
-
-local m_left = {
- ["(:"] = s_langle,
- ["{:"] = s_left,
- ["[:"] = s_left,
- ["("] = s_lparent,
- ["["] = s_lbracket,
- ["{"] = s_lbrace,
- ["⟨"] = s_langle,
- ["⌈"] = s_lceil,
- ["⌊"] = s_lfloor,
-
- -- ["<<"] = s_langle, -- why not <:
- -- ["|_"] = s_lfloor,
- -- ["|~"] = s_lceil,
- -- ["〈"] = s_langle,
- -- ["〈"] = s_langle,
-
- -- ["lparent"] = s_lparent,
- -- ["lbracket"] = s_lbracket,
- -- ["lbrace"] = s_lbrace,
- -- ["langle"] = s_langle,
- -- ["lfloor"] = s_lfloor,
- -- ["lceil"] = s_lceil,
-}
-
-local m_right = {
- [":)"] = s_rangle,
- [":}"] = s_right,
- [":]"] = s_right,
- [")"] = s_rparent,
- ["]"] = s_rbracket,
- ["}"] = s_rbrace,
- ["⟩"] = s_rangle,
- ["⌉"] = s_rceil,
- ["⌋"] = s_rfloor,
-
- -- [">>"] = s_rangle, -- why not :>
- -- ["~|"] = s_rceil,
- -- ["_|"] = s_rfloor,
- -- ["〉"] = s_rangle,
- -- ["〉"] = s_rangle,
-
- -- ["rparent"] = s_rparent,
- -- ["rbracket"] = s_rbracket,
- -- ["rbrace"] = s_rbrace,
- -- ["rangle"] = s_rangle,
- -- ["rfloor"] = s_rfloor,
- -- ["rceil"] = s_rceil,
-}
-
-local islimits = {
- ["\\sum"] = true,
- -- ["∑"] = true,
- ["\\prod"] = true,
- -- ["∏"] = true,
- ["\\lim"] = true,
-}
-
-local p_left =
- lpeg.utfchartabletopattern(m_left) / m_left
-local p_right =
- lpeg.utfchartabletopattern(m_right) / m_right
-
--- special cases
-
--- local p_special =
--- C("/")
--- + P("\\ ") * Cc("{}") * p_spaces^0 * C(S("^_"))
--- + P("\\ ") * Cc("\\space")
--- + P("\\\\") * Cc("\\backslash")
--- + P("\\") * (R("az","AZ")^1/entities)
--- + P("|") * Cc("\\|")
---
--- faster bug also uglier:
-
-local p_special =
- P("|") * Cc("\\|") -- s_mbar -- maybe always add left / right as in mml ?
- + P("\\") * (
- (
- P(" ") * (
- Cc("{}") * p_spaces^0 * C(S("^_"))
- + Cc("\\space")
- )
- )
- + P("\\") * Cc("\\backslash")
- -- + (R("az","AZ")^1/entities)
- + C(R("az","AZ")^1)
- )
-
--- open | close :: {: | :}
-
-local u_parser = Cs ( (
- patterns.doublequoted +
- P("text") * p_spaces^0 * P("(") * (1-P(")"))^0 * P(")") + -- -- todo: balanced
- P("\\frac") / "frac" + -- bah
- p_unicode +
- p_utf_base
-)^0 )
-
-local a_parser = Ct { "tokenizer",
- tokenizer = (
- p_spaces
- + p_number
- + p_text
- -- + Ct(p_open * V("tokenizer") * p_close) -- {: (a+b,=,1),(a+b,=,7) :}
- -- + Ct(p_open * V("tokenizer") * p_close_right) -- { (a+b,=,1),(a+b,=,7) :}
- -- + Ct(p_open_left * V("tokenizer") * p_right) -- {: (a+b,=,1),(a+b,=,7) }
- + Ct(p_left * V("tokenizer") * p_right) -- { (a+b,=,1),(a+b,=,7) }
- + p_special
- + p_reserved
- -- + p_utf - p_close - p_right
- + (p_utf - p_right)
- )^1,
-}
-
-local collapse = nil
-local serialize = table.serialize
-local f_state = formatters["level %s : %s : intermediate"]
-
-local function show_state(t,level,state)
- report_asciimath(serialize(t,f_state(level,state)))
-end
-
-local function show_result(original,unicoded,texcoded)
- report_asciimath("original > %s",original)
- report_asciimath("unicoded > %s",unicoded)
- report_asciimath("texcoded > %s",texcoded)
-end
-
-local function collapse_matrices(t)
- local n = #t
- if n > 4 and t[3] == "," then
- local l1 = t[1]
- local r1 = t[n]
- if isleft[l1] and isright[r1] then
- local l2 = t[2]
- local r2 = t[n-1]
- if type(l2) == "table" and type(r2) == "table" then
- -- we have a matrix
- local valid = true
- for i=3,n-2,2 do
- if t[i] ~= "," then
- valid = false
- break
- end
- end
- if valid then
- for i=2,n-1,2 do
- local ti = t[i]
- local tl = ti[1]
- local tr = ti[#ti]
- if isleft[tl] and isright[tr] then
- -- ok
- else
- valid = false
- break
- end
- end
- if valid then
- local omit = l1 == s_left and r1 == s_right
- if omit then
- t[1] = "\\startmatrix"
- else
- t[1] = l1 .. "\\startmatrix"
- end
- for i=2,n-1 do
- if t[i] == "," then
- t[i] = "\\NR"
- else
- local ti = t[i]
- ti[1] = "\\NC"
- for i=2,#ti-1 do
- if ti[i] == "," then
- ti[i] = "\\NC"
- end
- end
- ti[#ti] = nil
- end
- end
- if omit then
- t[n] = "\\NR\\stopmatrix"
- else
- t[n] = "\\NR\\stopmatrix" .. r1
- end
- end
- end
- end
- end
- end
- return t
-end
-
-local function collapse_bars(t)
- local n, i, l, m = #t, 1, false, 0
- while i <= n do
- local current = t[i]
- if current == "\\|" then
- if l then
- m = m + 1
- t[l] = s_lbar
- t[i] = s_rbar
- t[m] = { unpack(t,l,i) }
- l = false
- else
- l = i
- end
- elseif not l then
- m = m + 1
- t[m] = current
- end
- i = i + 1
- end
- if l then
- local tt = { s_lnothing } -- space fools final checker
- local tm = 1
- for i=1,m do
- tm = tm + 1
- tt[tm] = t[i]
- end
- tm = tm + 1
- tt[tm] = s_mbar
- for i=l+1,n do
- tm = tm + 1
- tt[tm] = t[i]
- end
- tm = tm + 1
- tt[tm] = s_rnothing -- space fools final checker
- m = tm
- t = tt
- elseif m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_pairs(t)
- local n, i = #t, 1
- while i < n do
- local current = t[i]
- if current == "/" and i > 1 then
- local tl = t[i-1]
- local tr = t[i+1]
- local tn = t[i+2]
- if type(tl) == "table" then
- if isleft[tl[1]] and isright[tl[#tl]] then
- tl[1] = "" -- todo: remove
- tl[#tl] = nil
- end
- end
- if type(tr) == "table" then
- if tn == "^" then
- -- brr 1/(1+x)^2
- elseif isleft[tr[1]] and isright[tr[#tr]] then
- tr[1] = "" -- todo: remove
- tr[#tr] = nil
- end
- end
- i = i + 2
- elseif current == "," or current == ";" then
- -- t[i] = current .. "\\thinspace" -- look sbad in (a,b)
- i = i + 1
- else
- i = i + 1
- end
- end
- return t
-end
-
-local function collapse_parentheses(t)
- local n, i = #t, 1
- if n > 2 then
- while i < n do
- local current = t[i]
- if type(current) == "table" and isleft[t[i-1]] and isright[t[i+1]] then
- local c = #current
- if c > 2 and isleft[current[1]] and isright[current[c]] then
- remove(current,c)
- remove(current,1)
- end
- i = i + 3
- else
- i = i + 1
- end
- end
- end
- return t
-end
-
-local function collapse_stupids(t)
- local n, m, i = #t, 0, 1
- while i <= n do
- m = m + 1
- local current = t[i]
- if isstupid[current] then
- local one = t[i+1]
- if type(one) == "table" then
- one = collapse(one,level)
- t[m] = current .. "{" .. one .. "}"
- i = i + 2
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- end
- if i == n then -- yes?
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_signs(t)
- local n, m, i = #t, 0, 1
- while i <= n do
- m = m + 1
- local current = t[i]
- if isunary[current] then
- local one = t[i+1]
- if not one then
--- m = m + 1
- t[m] = current .. "{}" -- error
- return t
--- break
- end
- if type(one) == "table" then
- if isleft[one[1]] and isright[one[#one]] then
- remove(one,#one)
- remove(one,1)
- end
- one = collapse(one,level)
- elseif one == "-" and i + 2 <= n then -- or another sign ? or unary ?
- local t2 = t[i+2]
- if type(t2) == "string" then
- one = one .. t2
- i = i + 1
- end
- end
- t[m] = current .. "{" .. one .. "}"
- i = i + 2
- elseif i + 2 <= n and isfunny[current] then
- local one = t[i+1]
- if isinfix[one] then
- local two = t[i+2]
- if two == "-" then -- or another sign ? or unary ?
- local three = t[i+3]
- if three then
- if type(three) == "table" then
- three = collapse(three,level)
- end
- t[m] = current .. one .. "{" .. two .. three .. "}"
- i = i + 4
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- end
- if i == n then -- yes?
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_binaries(t)
- local n, m, i = #t, 0, 1
- while i <= n do
- m = m + 1
- local current = t[i]
- if isbinary[current] then
- local one = t[i+1]
- local two = t[i+2]
- if not one then
- t[m] = current .. "{}{}" -- error
-return t
--- break
- end
- if type(one) == "table" then
- if isleft[one[1]] and isright[one[#one]] then
- remove(one,#one)
- remove(one,1)
- end
- one = collapse(one,level)
- end
- if not two then
- t[m] = current .. "{" .. one .. "}{}"
-return t
--- break
- end
- if type(two) == "table" then
- if isleft[two[1]] and isright[two[#two]] then
- remove(two,#two)
- remove(two,1)
- end
- two = collapse(two,level)
- end
- t[m] = current .. "{" .. one .. "}{" .. two .. "}"
- i = i + 3
- else
- t[m] = current
- i = i + 1
- end
- end
- if i == n then -- yes?
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_infixes_1(t)
- local n, i = #t, 1
- while i <= n do
- local current = t[i]
- if isinfix[current] then
- local what = t[i+1]
- if what then
- if type(what) == "table" then
- local f, l = what[1], what[#what]
- if isleft[f] and isright[l] then
- remove(what,#what)
- remove(what,1)
- end
- t[i+1] = collapse(what,level) -- collapse ?
- end
- i = i + 2
- else
- break
- end
- else
- i = i + 1
- end
- end
- return t
-end
-
-function collapse_limits(t)
- local n, m, i = #t, 0, 1
- while i <= n do
- m = m + 1
- local current = t[i]
- if islimits[current] then
- local one, two, first, second = nil, nil, t[i+1], t[i+3]
- if first and isinfix[first] then
- one = t[i+2]
- if one then
- -- if type(one) == "table" then
- -- if isleft[one[1]] and isright[one[#one]] then
- -- remove(one,#one)
- -- remove(one,1)
- -- end
- -- one = collapse(one,level)
- -- end
- if second and isinfix[second] then
- two = t[i+4]
- -- if type(two) == "table" then
- -- if isleft[two[1]] and isright[two[#two]] then
- -- remove(two,#two)
- -- remove(two,1)
- -- end
- -- two = collapse(two,level)
- -- end
- end
- if two then
- t[m] = current .. "\\limits" .. first .. "{" .. one .. "}" .. second .. "{" .. two .. "}"
- i = i + 5
- else
- t[m] = current .. "\\limits" .. first .. "{" .. one .. "}"
- i = i + 3
- end
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- else
- t[m] = current
- i = i + 1
- end
- end
- if i == n then -- yes?
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_tables(t)
- local n, m, i = #t, 0, 1
- while i <= n do
- m = m + 1
- local current = t[i]
- if type(current) == "table" then
- if current[1] == "\\NC" then
- t[m] = collapse(current,level)
- else
- t[m] = "{" .. collapse(current,level) .. "}"
- end
- i = i + 1
- else
- t[m] = current
- i = i + 1
- end
- end
- if i == n then -- yes?
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_infixes_2(t)
- local n, m, i = #t, 0, 1
- while i < n do
- local current = t[i]
- if isinfix[current] and i > 1 then
- local tl = t[i-1]
- local tr = t[i+1]
- local ti = t[i+2]
- local tn = t[i+3]
- if ti and tn and isinfix[ti] then
- t[m] = tl .. current .. "{" .. tr .. "}" .. ti .. "{" .. tn .. "}"
- i = i + 4
- else
- t[m] = tl .. current .. "{" .. tr .. "}"
- i = i + 2
- end
- else
- m = m + 1
- t[m] = current
- i = i + 1
- end
- end
- if i == n then
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_fractions_1(t)
- local n, m, i = #t, 0, 1
- while i < n do
- local current = t[i]
- if current == "/" and i > 1 then
- local tl = t[i-1]
- local tr = t[i+1]
- t[m] = "\\frac{" .. tl .. "}{" .. tr .. "}"
- i = i + 2
- if i < n then
- m = m + 1
- t[m] = t[i]
- i = i + 1
- end
- else
- m = m + 1
- t[m] = current
- i = i + 1
- end
- end
- if i == n then
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_fractions_2(t)
- local n, m, i = #t, 0, 1
- while i < n do
- local current = t[i]
- if current == "⁄" and i > 1 then -- \slash
- t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. t[i+1] .. s_right .. "}"
- i = i + 2
- if i < n then
- m = m + 1
- t[m] = t[i]
- i = i + 1
- end
- else
- m = m + 1
- t[m] = current
- i = i + 1
- end
- end
- if i == n then
- m = m + 1
- t[m] = t[n]
- end
- if m < n then
- for i=n,m+1,-1 do
- t[i] = nil
- end
- end
- return t
-end
-
-local function collapse_result(t)
- local n = #t
- if t[1] == s_left and t[n] == s_right then -- see bar .. space needed there
- return concat(t," ",2,n-1)
- else
- return concat(t," ")
- end
-end
-
-collapse = function(t,level)
- -- check
- if not t then
- return ""
- end
- -- tracing
- if trace_detail then
- if level then
- level = level + 1
- else
- level = 1
- end
- show_state(t,level,"parsed")
- end
- -- steps
- t = collapse_matrices (t) if trace_detail then show_state(t,level,"matrices") end
- t = collapse_bars (t) if trace_detail then show_state(t,level,"bars") end
-t = collapse_stupids (t) if trace_detail then show_state(t,level,"stupids") end
- t = collapse_pairs (t) if trace_detail then show_state(t,level,"pairs") end
- t = collapse_parentheses(t) if trace_detail then show_state(t,level,"parentheses") end
- t = collapse_signs (t) if trace_detail then show_state(t,level,"signs") end
- t = collapse_binaries (t) if trace_detail then show_state(t,level,"binaries") end
- t = collapse_infixes_1 (t) if trace_detail then show_state(t,level,"infixes (1)") end
- t = collapse_limits (t) if trace_detail then show_state(t,level,"limits") end
- t = collapse_tables (t) if trace_detail then show_state(t,level,"tables") end
- t = collapse_infixes_2 (t) if trace_detail then show_state(t,level,"infixes (2)") end
- t = collapse_fractions_1(t) if trace_detail then show_state(t,level,"fractions (1)") end
- t = collapse_fractions_2(t) if trace_detail then show_state(t,level,"fractions (2)") end
- -- done
- return collapse_result(t)
-end
-
--- todo: cache simple ones, say #str < 10, maybe weak
-
-local context = context
-local ctx_mathematics = context and context.mathematics or report_asciimath
-local ctx_type = context and context.type or function() end
-local ctx_inleft = context and context.inleft or function() end
-
-local function convert(str,totex)
- local unicoded = lpegmatch(u_parser,str) or str
- local texcoded = collapse(lpegmatch(a_parser,unicoded))
- if trace_mapping then
- show_result(str,unicoded,texcoded)
- end
- if totex then
- ctx_mathematics(texcoded)
- else
- return texcoded
- end
-end
-
-local n = 0
-local p = (
- (S("{[(") + P("\\left" )) / function() n = n + 1 end
- + (S("}])") + P("\\right")) / function() n = n - 1 end
- + p_utf_base
-)^0
-
-local function invalidtex(str)
- n = 0
- lpegmatch(p,str)
- if n == 0 then
- return false
- elseif n < 0 then
- return formatters["too many left fences: %s"](-n)
- elseif n > 0 then
- return formatters["not enough right fences: %s"](n)
- end
-end
-
-local collected = { }
-local indexed = { }
-
--- bonus
-
-local p_reserved_spaced =
- C(lpeg.utfchartabletopattern(k_reserved_words)) / " %1 "
-
-local p_text =
- C(P("text")) / " %1 "
- * p_spaces^0
- * ( -- maybe balanced
- (P("{") * (1-P("}"))^0 * P("}"))
- + (P("(") * (1-P(")"))^0 * P(")"))
- )
- + patterns.doublequoted
-
-local p_expand = Cs((p_text + p_reserved_spaced + p_utf_base)^0)
-local p_compress = patterns.collapser
-
-local function cleanedup(str)
- return lpegmatch(p_compress,lpegmatch(p_expand,str)) or str
-end
-
--- so far
-
-local function register(s,cleanedup,collected,shortname)
- local c = cleanedup(s)
- local f = collected[c]
- if f then
- f.count = f.count + 1
- f.files[shortname] = (f.files[shortname] or 0) + 1
- if s ~= c then
- f.cleanedup = f.cleanedup + 1
- end
- f.dirty[s] = (f.dirty[s] or 0) + 1
- else
- local texcoded = convert(s)
- local message = invalidtex(texcoded)
- if message then
- report_asciimath("%s: %s : %s",message,s,texcoded)
- end
- collected[c] = {
- count = 1,
- files = { [shortname] = 1 },
- texcoded = texcoded,
- message = message,
- cleanedup = s ~= c and 1 or 0,
- dirty = { [s] = 1 }
- }
- end
-end
-
-local function wrapup(collected,indexed)
- local n = 0
- for k, v in sortedhash(collected) do
- n = n + 1
- v.n= n
- indexed[n] = k
- end
-end
-
-function collect(fpattern,element,collected,indexed)
- local element = element or "am"
- local mpattern = formatters["<%s>(.-)</%s>"](element,element)
- local filenames = resolvers.findtexfile(fpattern)
- if filenames and filenames ~= "" then
- filenames = { filenames }
- else
- filenames = dir.glob(fpattern)
- end
- local cfpattern = gsub(fpattern,"^%./",lfs.currentdir())
- local cfpattern = gsub(cfpattern,"\\","/")
- local wildcard = string.split(cfpattern,"*")[1]
- if not collected then
- collected = { }
- indexed = { }
- end
- for i=1,#filenames do
- filename = gsub(filenames[i],"\\","/")
- local splitname = (wildcard and wildcard ~= "" and string.split(filename,wildcard)[2]) or filename
- local shortname = gsub(splitname or file.basename(filename),"^%./","")
- if shortname == "" then
- shortname = filename
- end
- local fullname = resolvers.findtexfile(filename) or filename
- if fullname ~= "" then
- for s in gmatch(io.loaddata(fullname),mpattern) do
- register(s,cleanedup,collected,shortname)
- end
- end
- end
- wrapup(collected,indexed)
- return collected, indexed
-end
-
-function filter(root,pattern,collected,indexed)
- if not pattern or pattern == "" then
- pattern = "am"
- end
- if not collected then
- collected = { }
- indexed = { }
- end
- for c in xmlcollected(root,pattern) do
- register(xmltext(c),cleanedup,collected,xmlinclusion(c) or "" )
- end
- wrapup(collected,indexed)
- return collected, indexed
-end
-
-asciimath.convert = convert
-asciimath.reserved = reserved
-asciimath.collect = collect
-asciimath.filter = filter
-asciimath.invalidtex = invalidtex
-asciimath.cleanedup = cleanedup
-
--- sin(x) = 1 : 3.3 uncached 1.2 cached , so no real gain (better optimize the converter then)
-
-local uncrapped = {
- ["%"] = "\\mathpercent",
- ["&"] = "\\mathampersand",
- ["#"] = "\\mathhash",
- ["$"] = "\\mathdollar",
- ["^"] = "\\Hat{\\enspace}", -- terrible hack ... tex really does it sbest to turn any ^ into a superscript
- ["_"] = "\\underline{\\enspace}",
-}
-
-local function convert(str,nowrap)
- if #str > 0 then
- local unicoded = lpegmatch(u_parser,str) or str
- if lpegmatch(p_onechar,unicoded) then
- ctx_mathematics(uncrapped[unicoded] or unicoded)
- else
- local texcoded = collapse(lpegmatch(a_parser,unicoded))
- if trace_mapping then
- show_result(str,unicoded,texcoded)
- end
- if #texcoded == 0 then
- report_asciimath("error in asciimath: %s",str)
- else
- local message = invalidtex(texcoded)
- if message then
- report_asciimath("%s: %s : %s",message,str,texcoded)
- ctx_type(formatters["<%s>"](message))
- elseif nowrap then
- context(texcoded)
- else
- ctx_mathematics(texcoded)
- end
- end
- end
- end
-end
-
-local context = context
-
-if not context then
-
--- trace_mapping = true
--- trace_detail = true
-
--- report_asciimath(cleanedup([[ac+sinx+xsqrtx+sinsqrtx+sinsqrt(x)]]))
--- report_asciimath(cleanedup([[a "αsinsqrtx" b]]))
--- convert([[a "αsinsqrtx" b]])
--- report_asciimath(cleanedup([[a "α" b]]))
--- report_asciimath(cleanedup([[//4]]))
-
--- convert("leq\\leq")
--- convert([[\^{1/5}log]])
--- convert("sqrt")
--- convert("^")
-
--- convert[[\frac{a}{b}]]
--- convert[[frac{a}{b}]]
-
--- convert("frac{a}{b}")
--- convert("\\sin{a}{b}")
--- convert("sin{a}{b}")
--- convert("1: rightarrow")
--- convert("2: \\rightarrow")
-
--- convert("((1,2,3),(4,5,6),(7,8,9))")
-
--- convert("1/(t+x)^2")
-
--- convert("AA a > 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b")
--- convert("AA a &gt; 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b")
-
--- convert("10000,00001")
--- convert("4/18*100text(%)~~22,2")
--- convert("4/18*100text(%)≈22,2")
--- convert("62541/(197,6)≈316,05")
-
--- convert([[sum x]])
--- convert([[sum^(1)_(2) x]])
--- convert([[lim_(1)^(2) x]])
--- convert([[lim_(1) x]])
--- convert([[lim^(2) x]])
-
--- convert([[{: rangle]])
--- convert([[\langle\larr]])
--- convert([[langlelarr]])
--- convert([[D_f=[0 ,→〉]])
--- convert([[ac+sinx+xsqrtx]])
--- convert([[ac+\alpha x+xsqrtx-cc b*pi**psi-3alephx / bb X]])
--- convert([[ac+\ ^ x+xsqrtx]])
--- convert([[d/dx(x^2+1)]])
--- convert([[a "αsinsqrtx" b]])
--- convert([[a "α" b]])
--- convert([[//4]])
--- convert([[ {(a+b,=,1),(a+b,=,7)) ]])
-
--- convert([[ 2/a // 5/b = (2 b) / ( a b) // ( 5 a ) / ( a b ) = (2 b ) / ( 5 a ) ]])
--- convert([[ (2+x)/a // 5/b ]])
-
--- convert([[ ( 2/a ) // ( 5/b ) = ( (2 b) / ( a b) ) // ( ( 5 a ) / ( a b ) ) = (2 b ) / ( 5 a ) ]])
-
--- convert([[ (x/y)^3 = x^3/y^3 ]])
-
--- convert([[ {: (1,2) :} ]])
--- convert([[ {: (a+b,=,1),(a+b,=,7) :} ]])
--- convert([[ { (a+b,=,1),(a+b,=,7) :} ]])
--- convert([[ {: (a+b,=,1),(a+b,=,7) } ]])
--- convert([[ { (a+b,=,1),(a+b,=,7) } ]])
-
--- convert([[(1,5 ±sqrt(1,25 ),0 )]])
--- convert([[1//2]])
--- convert([[(p)/sqrt(p)]])
--- convert([[u_tot]])
--- convert([[u_tot=4,4 L+0,054 T]])
-
--- convert([[ [←;0,2] ]])
--- convert([[ [←;0,2⟩ ]])
--- convert([[ ⟨←;0,2 ) ]])
--- convert([[ ⟨←;0,2 ] ]])
--- convert([[ ⟨←;0,2⟩ ]])
-
--- convert([[ x^2(x-1/16)=0 ]])
--- convert([[ y = ax + 3 - 3a ]])
--- convert([[ y= ((1/4)) ^x ]])
--- convert([[ x=\ ^ (1/4) log(0 ,002 )= log(0,002) / (log(1/4) ]])
--- convert([[ x=\ ^glog(y) ]])
--- convert([[ x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x)) ]])
--- convert([[ x^2(10 -x)&gt;2 x^2 ]])
--- convert([[ x^4&gt;x ]])
-
- return
-
-end
-
-interfaces.implement {
- name = "asciimath",
- actions = convert,
- arguments = "string"
-}
-
-interfaces.implement {
- name = "justasciimath",
- actions = convert,
- arguments = { "string", true },
-}
-
-local ctx_typebuffer = context.typebuffer
-local ctx_mathematics = context.mathematics
-local ctx_color = context.color
-
-local sequenced = table.sequenced
-local assign_buffer = buffers.assign
-
-local show = { }
-asciimath.show = show
-
-local collected, indexed, ignored = { }, { }, { }
-
-local color = { "darkred" }
-
-function show.ignore(n)
- if type(n) == "string" then
- local c = collected[n]
- n = c and c.n
- end
- if n then
- ignored[n] = true
- end
-end
-
-function show.count(n,showcleanedup)
- local v = collected[indexed[n]]
- local count = v.count
- local cleanedup = v.cleanedup
- if not showcleanedup or cleanedup == 0 then
- context(count)
- elseif count == cleanedup then
- ctx_color(color,count)
- else
- context("%s+",count-cleanedup)
- ctx_color(color,cleanedup)
- end
-end
-
-local h = { }
-local am = { "am" }
-
-function show.nofdirty(n)
- local k = indexed[n]
- local v = collected[k]
- local n = v.cleanedup
- h = { }
- if n > 0 then
- for d, n in sortedhash(v.dirty) do
- if d ~= k then
- h[#h+1] = { d, n }
- end
- end
- end
- context(#h)
-end
-
-function show.dirty(m,wrapped)
- local d = h[m]
- if d then
- ctx_inleft(d[2])
- if wrapped then
- assign_buffer("am",'"' .. d[1] .. '"')
- else
- assign_buffer("am",d[1])
- end
- ctx_typebuffer(am)
- end
-end
-
-function show.files(n)
- context(sequenced(collected[indexed[n]].files," "))
-end
-
-function show.input(n,wrapped)
- if wrapped then
- assign_buffer("am",'"' .. indexed[n] .. '"')
- else
- assign_buffer("am",indexed[n])
- end
- ctx_typebuffer(am)
-end
-
-function show.result(n)
- local v = collected[indexed[n]]
- if ignored[n] then
- context("ignored")
- elseif v.message then
- ctx_color(color, v.message)
- else
- ctx_mathematics(v.texcoded)
- end
-end
-
-function show.load(str,element)
- collected, indexed, ignored = { }, { }, { }
- local t = utilities.parsers.settings_to_array(str)
- for i=1,#t do
- asciimath.collect(t[i],element or "am",collected,indexed)
- end
-end
-
-function show.filter(id,element)
- collected, indexed, ignored = { }, { }, { }
- asciimath.filter(lxml.getid(id),element or "am",collected,indexed)
-end
-
-function show.max()
- context(#indexed)
-end
-
-function show.statistics()
- local usedfiles = { }
- local noffiles = 0
- local nofokay = 0
- local nofbad = 0
- local nofcleanedup = 0
- for k, v in next, collected do
- if ignored[v.n] then
- nofbad = nofbad + v.count
- elseif v.message then
- nofbad = nofbad + v.count
- else
- nofokay = nofokay + v.count
- end
- nofcleanedup = nofcleanedup + v.cleanedup
- for k, v in next, v.files do
- local u = usedfiles[k]
- if u then
- usedfiles[k] = u + 1
- else
- noffiles = noffiles + 1
- usedfiles[k] = 1
- end
- end
- end
- local NC = context.NC
- local NR = context.NR
- local EQ = context.EQ
- context.starttabulate { "|B||" }
- NC() context("files") EQ() context(noffiles) NC() NR()
- NC() context("formulas") EQ() context(nofokay+nofbad) NC() NR()
- NC() context("uniques") EQ() context(#indexed) NC() NR()
- NC() context("cleanedup") EQ() context(nofcleanedup) NC() NR()
- NC() context("errors") EQ() context(nofbad) NC() NR()
- context.stoptabulate()
-end
-
-function show.save(name)
- table.save(name ~= "" and name or "dummy.lua",collected)
-end