diff --git a/LatexMathSymbols.pdf b/LatexMathSymbols.pdf new file mode 100644 index 0000000..7dab684 Binary files /dev/null and b/LatexMathSymbols.pdf differ diff --git a/Sources/MathTexParser/MathTexParser.swift b/Sources/MathTexParser/MathTexParser.swift new file mode 100644 index 0000000..b1b2997 --- /dev/null +++ b/Sources/MathTexParser/MathTexParser.swift @@ -0,0 +1,20 @@ +// +// MathTexParser.swift +// +// +// Created by Peter Tang on 22/9/2023. +// + +import Foundation +import Antlr4 +import TexParser + +internal class MathTexParser { + func parse(input: String) { + let iStream = ANTLRInputStream(input) + let lexer = TeXLexer(iStream) + let tokenStream = CommonTokenStream(lexer) + if let parser = try? TeXParser(tokenStream), let _ = try? parser.prog() { + } + } +} diff --git a/Sources/SwiftMath/MathBundle/MathImage.swift b/Sources/SwiftMath/MathBundle/MathImage.swift index ec745c6..1adc997 100644 --- a/Sources/SwiftMath/MathBundle/MathImage.swift +++ b/Sources/SwiftMath/MathBundle/MathImage.swift @@ -75,7 +75,7 @@ extension MathImage { intrinsicContentSize = intrinsicContentSize(displayList) displayList.textColor = textColor - let size = intrinsicContentSize + let size = intrinsicContentSize.integral layoutImage(size: size, displayList: displayList) #if os(iOS) @@ -107,3 +107,12 @@ private extension CGAffineTransform { return transform } } +extension CGSize: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine(width) + hasher.combine(height) + } + var integral: CGSize { + CGSize(width: ceil(width), height: ceil(height)) + } +} diff --git a/Sources/TexParser/TeX.g4 b/Sources/TexParser/TeX.g4 new file mode 100644 index 0000000..ac4e66d --- /dev/null +++ b/Sources/TexParser/TeX.g4 @@ -0,0 +1,122 @@ +// antlr4env.bat +// antlr TeX.g4 -visitor -no-listener -o gen +// antlr TeX.g4 -visitor -no-listener -Dlanguage=Swift -o Swift + +grammar TeX; + +prog: stat; + +stat: expr (NEWLINE|EOF ) # printExpr + | expr EQUAL expr (NEWLINE|EOF) # equal + | expr op=(LT|GT|LEQQ|GEQQ|LARROW|RARROW) expr (NEWLINE|EOF) # relation + ; + +expr: FLOAT # float + | INT # int + | SEQ_TERM L_BRACE expr R_BRACE # seqterm + | gz=(GAMMAF|ZETAF) expr R_PAREN # gammaf_zetaf + | FUNCTION expr R_PAREN # function + | const=(PI|IMAGINARY_UNIT|NAPIER_CONSTANT|INFTY) # mathconst + | GREEK # greek + | ALPHABET # alphabet + | expr FACTORIAL # factrial + | expr CARET expr # power + | MINUS expr # MinusExpr + | PLUS expr # PlusExpr + | expr DIV expr # div + | expr MULT expr # mult + | expr op=( PLUS | MINUS ) expr # AddSub + | expr expr # mull + | func=(SQRT|SIN|COS|TAN|LOG) L_BRACE expr R_BRACE # func + | func=(SIN|COS|TAN) CARET L_BRACE expr R_BRACE L_BRACE expr R_BRACE # trign + | SQRT L_BRACKET expr R_BRACKET L_BRACE expr R_BRACE # sqrtn + | LOG UB L_BRACE expr R_BRACE L_BRACE expr R_BRACE # logub + | L_PIPE expr R_PIPE # abs + | (DIFF|DDIFF) R_BRACE L_BRACE dxg=(DX|DGREEK) R_BRACE L_BRACE expr R_BRACE # diff + | L_PAREN (DIFF|DDIFF) R_BRACE L_BRACE dxg=(DX|DGREEK) R_BRACE R_PAREN CARET L_BRACE expr R_BRACE L_BRACE expr R_BRACE # diffn1 + | (DIFF|DDIFF) CARET L_BRACE expr R_BRACE R_BRACE L_BRACE dxg=(DX|DGREEK) CARET L_BRACE expr R_BRACE R_BRACE L_BRACE expr R_BRACE # diffn2 + | INTEGRATE L_BRACE expr dxg=(DX|DGREEK) R_BRACE # integrate + | INTEGRATE UB L_BRACE expr R_BRACE CARET L_BRACE expr R_BRACE L_BRACE expr dxg=(DX|DGREEK) R_BRACE # dintegrate + | LIM UB L_BRACE expr TO expr R_BRACE L_BRACE expr R_BRACE # lim + | (FRAC|DFRAC) L_BRACE expr R_BRACE L_BRACE expr R_BRACE # frac + | SUM UB L_BRACE expr EQUAL expr R_BRACE CARET L_BRACE expr R_BRACE L_BRACE expr R_BRACE # sum + | UB L_BRACE expr R_BRACE cp=(COMBI|PERMU) UB L_BRACE expr R_BRACE # combi_permu + | CS_L_PAREN expr CS_R_PAREN # cs_parens + | L_PAREN expr R_PAREN # parens + | CS_BS_L_BRACE expr CS_BS_R_BRACE # cs_bs_braces + | BS_L_BRACE expr BS_R_BRACE # bs_braces + | L_BRACE expr R_BRACE # braces + ; + + +GREEK : ('aalpha'|'bbeta'|'ggamma'|'ddelta'|'eepsilon'|'eeta'|'ttheta'|'iiota'|'kkappa'|'llambda'|'mmu'|'nnu'| + 'xxi'|'pppi'|'rrho'|'ssigma'|'ttau'|'uupsilon'|'pphi'|'cchi'|'ppsi'|'oomega') ; // except zeta, omicron +ALPHABET : [a-zA-DFGHJ-RT-Z] ; +FLOAT : [0-9]* '.'[0-9]+ ; +INT : [0-9]+ ; +NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal) +WS : [ \t]+ -> skip ; // toss out whitespace +LATEX_SP : ('\\!'|'\\,'|'\\:'|'\\;'|'~') -> skip ; + +// math constant +PI : '\\ppi'; +IMAGINARY_UNIT : '\\ii'; +NAPIER_CONSTANT : '\\ee' ; + +CS_L_PAREN: '\\left('; +CS_R_PAREN: '\\right)'; +L_PAREN: '('; +R_PAREN: ')'; +CS_BS_L_BRACE: '\\left\\{'; +CS_BS_R_BRACE: '\\right\\}'; +BS_L_BRACE: '\\{'; +BS_R_BRACE: '\\}'; +L_BRACE: '{'; +R_BRACE: '}'; +L_BRACKET: '['; +R_BRACKET: ']'; +L_PIPE : '\\left|' ; +R_PIPE : '\\right|' ; + +MULT : ('*'|'\\times'|'\\cdot') ; +DIV : '\\div' ; +PLUS : '+' ; +MINUS : '-' ; +CARET : ('^'|'**'); +UB : '_' ; +FACTORIAL : '!' ; + +DIFF : '\\frac{d'; +DDIFF : '\\dfrac{d'; +INTEGRATE : '\\int' ; +DX : [d][a-z] ; +DGREEK : [d]GREEK ; + +SQRT : '\\sqrt' ; +SIN : '\\sin' ; +COS : '\\cos' ; +TAN : '\\tan' ; +LOG : '\\log' ; + +FRAC : '\\frac' ; +DFRAC : '\\dfrac' ; +SUM : '\\sum' ; +LIM : '\\lim' ; +TO : '\\to' ; +INFTY : '\\infty' ; + +COMBI : '\\C' ; +PERMU : '\\P' ; +SEQ_TERM : [a-z] '_' ; +FUNCTION : 'f(' ; +GAMMAF: '\\Gamma(' ; +ZETAF : '\\zeta(' ; + +EQUAL : '='; +LT: '<'; +LEQQ: '\\leqq'; +GT: '>'; +GEQQ: '\\geqq'; + +LARROW: '<--'; +RARROW: '-->';