texmath 0.13.1.2 → 0.13.2
raw patch · 139 files changed
+3776/−22 lines, 139 filesdep ~typst-symbolsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: typst-symbols
API changes (from Hackage documentation)
+ Text.TeXMath: writeStarMath :: DisplayType -> [Exp] -> Text
+ Text.TeXMath.Writers.StarMath: instance GHC.Classes.Eq Text.TeXMath.Writers.StarMath.AlignContext
+ Text.TeXMath.Writers.StarMath: writeStarMath :: DisplayType -> [Exp] -> Text
Files
- README.md +8/−8
- changelog.md +16/−0
- extra/texmath.hs +1/−0
- man/texmath.1.md +2/−2
- server/Main.hs +5/−1
- src/Text/TeXMath.hs +2/−0
- src/Text/TeXMath/Writers/StarMath.hs +1598/−0
- test/reader/tex/macros.test +2/−2
- test/test-texmath.hs +4/−0
- test/writer/starmath/001_dot_text_subscript.test +4/−0
- test/writer/starmath/002_common_accents.test +4/−0
- test/writer/starmath/003_fraction.test +4/−0
- test/writer/starmath/004_square_root.test +4/−0
- test/writer/starmath/005_nth_root.test +4/−0
- test/writer/starmath/006_subscript_and_superscript.test +4/−0
- test/writer/starmath/007_superscript_with_grouped_base.test +4/−0
- test/writer/starmath/008_delimited_fraction.test +4/−0
- test/writer/starmath/009_delimited_braces.test +4/−0
- test/writer/starmath/01.test +22/−0
- test/writer/starmath/010_absolute_value_bars_normalize_to_delimiters.test +4/−0
- test/writer/starmath/011_double_bars_normalize_to_norm_delimiters.test +4/−0
- test/writer/starmath/012_one_sided_delimiter_uses_none.test +4/−0
- test/writer/starmath/013_middle_delimiter_uses_mline.test +4/−0
- test/writer/starmath/014_operator_mapping_cdot.test +4/−0
- test/writer/starmath/015_binomial_nolinefrac.test +4/−0
- test/writer/starmath/016_integral_without_limits.test +4/−0
- test/writer/starmath/017_integral_with_lower_and_upper_limits.test +4/−0
- test/writer/starmath/018_integral_with_infinite_upper_limit.test +4/−0
- test/writer/starmath/019_sum_with_lower_and_upper_limits.test +4/−0
- test/writer/starmath/02.test +25/−0
- test/writer/starmath/020_sum_with_symbolic_term.test +4/−0
- test/writer/starmath/021_greek_letter_mapping.test +4/−0
- test/writer/starmath/022_greek_variant_mapping.test +4/−0
- test/writer/starmath/023_arrow_mapping.test +4/−0
- test/writer/starmath/024_set_and_relation_symbol_mapping.test +4/−0
- test/writer/starmath/025_logic_and_calculus_symbol_mapping.test +4/−0
- test/writer/starmath/026_greek_identifier_spacing_in_products.test +4/−0
- test/writer/starmath/027_math_operators_rendered_as_functions.test +4/−0
- test/writer/starmath/028_nested_function_with_left_delimiter_spacing.test +4/−0
- test/writer/starmath/029_quad_spacing_command.test +4/−0
- test/writer/starmath/03.test +13/−0
- test/writer/starmath/030_qquad_spacing_command.test +4/−0
- test/writer/starmath/031_greek_token_separator_before_scripted_identifier.test +4/−0
- test/writer/starmath/032_mathrm_text_in_subscripts_stays_quoted.test +4/−0
- test/writer/starmath/033_escaped_underscore_in_mathrm_stays_literal.test +4/−0
- test/writer/starmath/034_numeric_chemistry_subscripts_in_mathrm_stay_structural.test +4/−0
- test/writer/starmath/035_circ_operator_maps_to_starmath_command.test +4/−0
- test/writer/starmath/036_min_with_bold_limit_variable_uses_operator_limits.test +4/−0
- test/writer/starmath/037_identifier_before_function_gets_separator.test +4/−0
- test/writer/starmath/038_greek_identifier_before_punctuation_gets_separator.test +4/−0
- test/writer/starmath/039_greek_identifier_before_punctuation_in_larger_expression.test +4/−0
- test/writer/starmath/04.test +20/−0
- test/writer/starmath/040_bare_recognized_math_operators_omit_func_and_keep_spacing.test +4/−0
- test/writer/starmath/041_ordinary_function_with_subscript_keeps_ordinary_script_syntax.test +4/−0
- test/writer/starmath/042_adjacent_bold_terms_get_separator.test +4/−0
- test/writer/starmath/043_mathcal_styled_token_before_left_delimiter.test +4/−0
- test/writer/starmath/044_leading_binary_operator_gets_neutral_lhs.test +4/−0
- test/writer/starmath/045_standalone_binary_operator_gets_neutral_operands.test +4/−0
- test/writer/starmath/046_trailing_binary_operator_gets_neutral_rhs.test +4/−0
- test/writer/starmath/047_standalone_relation_gets_neutral_operands.test +4/−0
- test/writer/starmath/048_standalone_arrow_gets_neutral_operands.test +4/−0
- test/writer/starmath/049_subscript_only_fragment_gets_neutral_base.test +4/−0
- test/writer/starmath/05.test +33/−0
- test/writer/starmath/050_superscript_only_fragment_gets_neutral_base.test +4/−0
- test/writer/starmath/051_grouped_subscript_only_fragment_gets_neutral_base.test +4/−0
- test/writer/starmath/052_matrix_environment.test +4/−0
- test/writer/starmath/053_pmatrix_environment.test +4/−0
- test/writer/starmath/054_bmatrix_environment.test +4/−0
- test/writer/starmath/055_vmatrix_environment.test +4/−0
- test/writer/starmath/056_vmatrix_environment.test +4/−0
- test/writer/starmath/057_array_with_left_right_alignment.test +4/−0
- test/writer/starmath/058_aligned_array_keeps_fractions_centered.test +4/−0
- test/writer/starmath/059_cases_environment.test +4/−0
- test/writer/starmath/06.test +35/−0
- test/writer/starmath/060_cases_with_negative_log_fraction.test +4/−0
- test/writer/starmath/061_phantom_alignment.test +7/−0
- test/writer/starmath/062_fallback_to_tex_for_under_over_constructs.test +4/−0
- test/writer/starmath/063_demorgans_law.test +5/−0
- test/writer/starmath/063_extensible_arrows_use_centered_scripts.test +10/−0
- test/writer/starmath/064_centered_array_omits_explicit_alignc.test +13/−0
- test/writer/starmath/065_reserved_word_in_uptext_subscript_is_quoted.test +4/−0
- test/writer/starmath/066_standalone_plus_minus_scripts_get_neutral_operands.test +4/−0
- test/writer/starmath/067_integral_default_limits_use_scripts.test +4/−0
- test/writer/starmath/068_integral_limits_use_from_to.test +4/−0
- test/writer/starmath/069_integral_nolimits_use_scripts.test +4/−0
- test/writer/starmath/07.test +27/−0
- test/writer/starmath/070_normal_fraction_display_inline_uses_inline_size.test +4/−0
- test/writer/starmath/071_grouped_mathrm_alpha_subscripts_stay_structural.test +4/−0
- test/writer/starmath/08.test +32/−0
- test/writer/starmath/09.test +21/−0
- test/writer/starmath/10.test +51/−0
- test/writer/starmath/11.test +28/−0
- test/writer/starmath/12.test +35/−0
- test/writer/starmath/13.test +51/−0
- test/writer/starmath/14.test +7/−0
- test/writer/starmath/15.test +4/−0
- test/writer/starmath/16.test +4/−0
- test/writer/starmath/17.test +11/−0
- test/writer/starmath/18.test +4/−0
- test/writer/starmath/19.test +83/−0
- test/writer/starmath/20.test +119/−0
- test/writer/starmath/21.test +9/−0
- test/writer/starmath/22.test +256/−0
- test/writer/starmath/23.test +4/−0
- test/writer/starmath/axiom_of_power_set.test +31/−0
- test/writer/starmath/binomial_coefficient.test +41/−0
- test/writer/starmath/boxed.test +12/−0
- test/writer/starmath/cancel.test +12/−0
- test/writer/starmath/choose.test +21/−0
- test/writer/starmath/complex_number.test +27/−0
- test/writer/starmath/cospan.test +11/−0
- test/writer/starmath/deMorgans_law.test +41/−0
- test/writer/starmath/differentiable_manifold.test +70/−0
- test/writer/starmath/divergence.test +25/−0
- test/writer/starmath/ensuremath.test +4/−0
- test/writer/starmath/genfrac.test +9/−0
- test/writer/starmath/issue109.test +11/−0
- test/writer/starmath/issue204.test +7/−0
- test/writer/starmath/issue229.test +13/−0
- test/writer/starmath/labels.test +4/−0
- test/writer/starmath/macros.test +15/−0
- test/writer/starmath/math-in-text.test +20/−0
- test/writer/starmath/moore_determinant.test +54/−0
- test/writer/starmath/notin.test +11/−0
- test/writer/starmath/operatorname.test +71/−0
- test/writer/starmath/phantom.test +10/−0
- test/writer/starmath/quadratic_formula.test +22/−0
- test/writer/starmath/schwinger_dyson.test +63/−0
- test/writer/starmath/simple_sum_formula.test +15/−0
- test/writer/starmath/sophomores_dream.test +27/−0
- test/writer/starmath/span.test +9/−0
- test/writer/starmath/sphere_volume.test +127/−0
- test/writer/starmath/stackrel.test +7/−0
- test/writer/starmath/substack.test +34/−0
- test/writer/starmath/subsup.test +68/−0
- test/writer/starmath/text.test +8/−0
- test/writer/starmath/tokens.test +14/−0
- test/writer/starmath/unicode.test +9/−0
- texmath.cabal +14/−9
README.md view
@@ -6,14 +6,14 @@ texmath is a Haskell library for converting between formats used to represent mathematics. Currently it provides functions to read and write TeX math, presentation MathML, and OMML (Office Math Markup-Language, used in Microsoft Office), and to write Gnu eqn, typst, and-[pandoc]'s native format (allowing conversion, using pandoc, to-a variety of different markup formats). The TeX reader and-writer supports basic LaTeX and AMS extensions, and it can parse-and apply LaTeX macros. The package also includes several-utility modules which may be useful for anyone looking to-manipulate either TeX math or MathML. For example, a copy of-the MathML operator dictionary is included.+Language, used in Microsoft Office), and to write Gnu eqn, typst,+StarMath (used by LibreOffice), and [pandoc]'s native format+(allowing conversion, using pandoc, to a variety of different+markup formats). The TeX reader and writer supports basic LaTeX+and AMS extensions, and it can parse and apply LaTeX macros. The+package also includes several utility modules which may be useful+for anyone looking to manipulate either TeX math or MathML. For+example, a copy of the MathML operator dictionary is included. [pandoc]: http://github.com/jgm/pandoc
changelog.md view
@@ -1,3 +1,19 @@+texmath (0.13.2)++ * Require typst-symbols 0.3++ * Add starmath as output format (#289, John Pye).+ [API change] New Text.TeXMath.Writers.StarMath module, exporting+ `writeStarMath`. The function is also exported by Text.TeXMath.+ Starmath is the format used by LibreOffice. Although LibreOffice+ supports equations in MathML, it converts these to starmath (often+ badly), and the starmath version is the user-editable one. The+ starmath writer is provided in order to better support math in ODT+ generated by pandoc. An extensive review (see the tools+ subdirectory for the scripts that produce it) shows that this+ writer's starmath produces better results in LibreOffice than the+ mathml writer.+ texmath (0.13.1.2) * Typst writer: Avoid using deprecated symbols (#287).
extra/texmath.hs view
@@ -62,6 +62,7 @@ , ("omml", XMLWriter writeOMML) , ("xhtml", XMLWriter (\dt e -> inHtml (writeMathML dt e))) , ("mathml", XMLWriter writeMathML)+ , ("starmath", StringWriter writeStarMath) , ("pandoc", PandocWriter writePandoc)] data Options = Options {
man/texmath.1.md view
@@ -33,8 +33,8 @@ Defaults to `tex`. `-t` *FORMAT*-: Specify output ("to") format: `tex`, `omml`,- `xhtml`, `mathml`, `pandoc`, `native`. Defaults to `mathml`.+: Specify output ("to") format: `tex`, `omml`, `xhtml`, `mathml`,+ `typst`, `eqn`, `starmath`, `pandoc`, `native`. Defaults to `mathml`. `--inline` : Use the inline display style.
server/Main.hs view
@@ -35,7 +35,7 @@ } deriving (Show) data Format =- TeX | MathML | Eqn | OMML | Typst+ TeX | MathML | Eqn | OMML | Typst | StarMath deriving (Show, Ord, Eq) instance FromJSON Format where@@ -46,6 +46,7 @@ "eqn" -> pure Eqn "typst" -> pure Typst "omml" -> pure OMML+ "starmath" -> pure StarMath _ -> fail $ "Unknown format " <> T.unpack s parseJSON _ = fail "Expecting string format" @@ -60,6 +61,7 @@ "eqn" -> pure Eqn "typst" -> pure Typst "omml" -> pure OMML+ "starmath" -> pure StarMath _ -> Left $ "Unknown format " <> t -- Automatically derive code to convert to/from JSON.@@ -132,12 +134,14 @@ MathML -> readMathML Eqn -> \_ -> Left "eqn reader not implemented" Typst -> \_ -> Left "typst reader not implemented"+ StarMath -> \_ -> Left "StarMath reader not implemented" writer = case to params of Eqn -> writeEqn dt Typst -> writeTypst dt OMML -> T.pack . ppElement . writeOMML dt TeX -> writeTeX MathML -> T.pack . ppElement . writeMathML dt+ StarMath -> writeStarMath dt in handleErr $ writer <$> reader txt handleErr (Right t) = return t
src/Text/TeXMath.hs view
@@ -62,6 +62,7 @@ writeTeXWith, addLaTeXEnvironment, writeEqn,+ writeStarMath, writeTypst, writeOMML, writeMathML,@@ -78,5 +79,6 @@ import Text.TeXMath.Writers.Pandoc import Text.TeXMath.Writers.TeX import Text.TeXMath.Writers.Eqn+import Text.TeXMath.Writers.StarMath import Text.TeXMath.Writers.Typst import Text.TeXMath.Types
+ src/Text/TeXMath/Writers/StarMath.hs view
@@ -0,0 +1,1598 @@+{-# LANGUAGE OverloadedStrings #-}+module Text.TeXMath.Writers.StarMath+ ( writeStarMath+ ) where++import Data.Char (isLetter)+import Data.Generics (everywhere, mkT)+import qualified Data.List as List+import qualified Data.Text as T+import qualified Text.TeXMath.Shared as S+import Text.TeXMath.Unicode.ToUnicode (toUnicodeChar)+import Text.TeXMath.Types+ ( Alignment(..)+ , DisplayType(..)+ , Exp(..)+ , FractionType(..)+ , TeXSymbolType(..)+ , TextType(..)+ )+import Text.TeXMath.Writers.TeX (writeTeX)++-- | Render TeXMath expressions as StarMath syntax.+-- Falls back to TeX output for expressions that are not yet supported.+writeStarMath :: DisplayType -> [Exp] -> T.Text+writeStarMath dt exps =+ case renderExps dt (normalizeExps (everywhere (mkT $ S.handleDownup dt) exps)) of+ Just rendered -> T.strip rendered+ Nothing -> writeTeX exps++data AlignContext = AlignDefault | AlignLeftCtx | AlignRightCtx+ deriving (Eq)++renderExps :: DisplayType -> [Exp] -> Maybe T.Text+renderExps dt = renderExpsIn dt AlignDefault++normalizeExps :: [Exp] -> [Exp]+normalizeExps =+ normalizeBareBars+ . normalizeEvaluationBars+ . mergeAdjacentUnicodeSerifStyled+ . normalizeBareBraces+ . map normalizeExp++normalizeExp :: Exp -> Exp+normalizeExp e =+ case e of+ EGrouped xs -> EGrouped (normalizeExps xs)+ EStyled sty xs -> EStyled sty (normalizeExps xs)+ EFraction ft num den -> EFraction ft (normalizeExp num) (normalizeExp den)+ ESqrt x -> ESqrt (normalizeExp x)+ ERoot idx rad -> ERoot (normalizeExp idx) (normalizeExp rad)+ EDelimited op cl xs -> EDelimited op cl (map normalizeDelimitedPiece xs)+ ESub base sub -> ESub (normalizeExp base) (normalizeExp sub)+ ESuper base sup -> ESuper (normalizeExp base) (normalizeExp sup)+ ESubsup base sub sup -> ESubsup (normalizeExp base) (normalizeExp sub) (normalizeExp sup)+ EOver b base over -> EOver b (normalizeExp base) (normalizeExp over)+ EUnder b base under -> EUnder b (normalizeExp base) (normalizeExp under)+ EUnderover b base u o -> EUnderover b (normalizeExp base) (normalizeExp u) (normalizeExp o)+ EArray aligns rows -> EArray aligns (map (map normalizeExps) rows)+ EPhantom x -> EPhantom (normalizeExp x)+ _ -> e++normalizeDelimitedPiece :: Either T.Text Exp -> Either T.Text Exp+normalizeDelimitedPiece p =+ case p of+ Left t -> Left t+ Right e -> Right (normalizeExp e)++normalizeBareBars :: [Exp] -> [Exp]+normalizeBareBars [] = []+normalizeBareBars (x : xs)+ | Just sym <- bareBarSymbol x =+ case collectBareDelimited sym [] xs of+ Just (mid, trailingScript, rest) ->+ let delimited = EDelimited sym sym (map Right mid)+ scripted = maybe delimited ($ delimited) trailingScript+ in scripted : normalizeBareBars rest+ _ ->+ x : normalizeBareBars xs+normalizeBareBars (x:xs) = x : normalizeBareBars xs++normalizeBareBraces :: [Exp] -> [Exp]+normalizeBareBraces [] = []+normalizeBareBraces (ESymbol Open "{" : xs) =+ case collectBareBraces [] xs of+ Just (mid, rest) -> EDelimited "{" "}" (map Right mid) : normalizeBareBraces rest+ Nothing -> ESymbol Open "{" : normalizeBareBraces xs+normalizeBareBraces (x:xs) = x : normalizeBareBraces xs++mergeAdjacentUnicodeSerifStyled :: [Exp] -> [Exp]+mergeAdjacentUnicodeSerifStyled [] = []+mergeAdjacentUnicodeSerifStyled (EStyled sty xs : EStyled sty' ys : rest)+ | sty == sty' && isUnicodeSerifStyle sty =+ mergeAdjacentUnicodeSerifStyled (EStyled sty (xs <> [ESpace 1] <> ys) : rest)+mergeAdjacentUnicodeSerifStyled (x:xs) = x : mergeAdjacentUnicodeSerifStyled xs++isUnicodeSerifStyle :: TextType -> Bool+isUnicodeSerifStyle sty =+ sty `elem`+ [ TextScript+ , TextFraktur+ , TextDoubleStruck+ , TextBoldScript+ , TextBoldFraktur+ ]++normalizeEvaluationBars :: [Exp] -> [Exp]+normalizeEvaluationBars = reverse . go []+ where+ go acc [] = acc+ go acc (cur : xs)+ | Just script <- evaluationBarScript cur+ , Just (rest, target) <- takeEvaluationTarget acc =+ go (script target : rest) xs+ | otherwise =+ go (cur : acc) xs++evaluationBarScript :: Exp -> Maybe (Exp -> Exp)+evaluationBarScript cur =+ case cur of+ ESub base sub+ | isEvaluationBarBase base ->+ Just (\target -> ESub (EDelimited "." "|" [Right target]) sub)+ ESuper base sup+ | isEvaluationBarBase base ->+ Just (\target -> ESuper (EDelimited "." "|" [Right target]) sup)+ ESubsup base sub sup+ | isEvaluationBarBase base ->+ Just (\target -> ESubsup (EDelimited "." "|" [Right target]) sub sup)+ _ -> Nothing++takeEvaluationTarget :: [Exp] -> Maybe ([Exp], Exp)+takeEvaluationTarget [] = Nothing+takeEvaluationTarget (e : rest) =+ case e of+ EDelimited{} -> Just (rest, e)+ ESymbol Close c+ | Just (rest', target) <- takeDelimitedTarget c rest ->+ Just (rest', target)+ _ -> Just (rest, e)++takeDelimitedTarget :: T.Text -> [Exp] -> Maybe ([Exp], Exp)+takeDelimitedTarget closeTxt = go 0 []+ where+ openTxt =+ case closeTxt of+ ")" -> Just "("+ "]" -> Just "["+ "}" -> Just "{"+ _ -> Nothing++ go _ _ [] = Nothing+ go depth inner (e : rest) =+ case (openTxt, e) of+ (Just open, ESymbol Close c)+ | c == closeTxt ->+ go (depth + 1) (e : inner) rest+ (Just open, ESymbol Open o)+ | o == open ->+ if depth == 0+ then Just (rest, EDelimited open closeTxt (map Right inner))+ else go (depth - 1) (e : inner) rest+ _ ->+ go depth (e : inner) rest++isEvaluationBarBase :: Exp -> Bool+isEvaluationBarBase e =+ case e of+ EScaled _ (ESymbol Open "|") -> True+ EScaled _ (ESymbol Close "|") -> True+ _ -> False++collectBareBraces :: [Exp] -> [Exp] -> Maybe ([Exp], [Exp])+collectBareBraces _ [] = Nothing+collectBareBraces acc (ESymbol Close "}" : xs) = Just (reverse acc, xs)+collectBareBraces acc (x:xs) = collectBareBraces (x:acc) xs++collectBareDelimited :: T.Text -> [Exp] -> [Exp]+ -> Maybe ([Exp], Maybe (Exp -> Exp), [Exp])+collectBareDelimited _ acc [] = Nothing+collectBareDelimited sym acc (y:ys)+ | matchesBareBar sym y = Just (reverse acc, Nothing, ys)+ | Just apply <- scriptedBareBar sym y = Just (reverse acc, Just apply, ys)+ | otherwise = collectBareDelimited sym (y:acc) ys++bareBarSymbol :: Exp -> Maybe T.Text+bareBarSymbol e =+ case e of+ ESymbol _ "|" -> Just "|"+ ESymbol _ "∣" -> Just "|"+ ESymbol _ "∥" -> Just "∥"+ _ -> Nothing++matchesBareBar :: T.Text -> Exp -> Bool+matchesBareBar sym e =+ case bareBarSymbol e of+ Just sym' -> sym == sym'+ Nothing -> False++scriptedBareBar :: T.Text -> Exp -> Maybe (Exp -> Exp)+scriptedBareBar sym e =+ case e of+ ESub base sub+ | matchesBareBar sym base -> Just (\del -> ESub del sub)+ ESuper base sup+ | matchesBareBar sym base -> Just (\del -> ESuper del sup)+ ESubsup base sub sup+ | matchesBareBar sym base -> Just (\del -> ESubsup del sub sup)+ _ -> Nothing++renderExpsIn :: DisplayType -> AlignContext -> [Exp] -> Maybe T.Text+renderExpsIn dt ctx exps = do+ rendered <- mapM (renderExpIn dt ctx) exps+ let pieces = zip exps rendered+ let merged = mergePieces pieces+ let withLhs =+ if startsWithInfixNeedingLhs exps+ then "{} " <> T.stripStart merged+ else merged+ pure $ if endsWithInfixNeedingRhs exps+ then T.stripEnd withLhs <> " {}"+ else withLhs++mergePieces :: [(Exp, T.Text)] -> T.Text+mergePieces [] = ""+mergePieces ((e0, t0) : rest) = snd $ List.foldl' step (e0, t0) rest+ where+ step (prevE, acc) (curE, curT) =+ if T.null curT+ then (prevE, acc)+ else+ (curE, appendRendered (needsSeparator prevE curE) acc curT)++appendRendered :: Bool -> T.Text -> T.Text -> T.Text+appendRendered needSep left right+ | T.null left = T.stripStart right+ | T.null right = T.stripEnd left+ | otherwise =+ let leftHadWs = endsWithAsciiSpace left+ rightHadWs = startsWithAsciiSpace right+ left' = T.dropWhileEnd isAsciiSpaceChar left+ right' = T.dropWhile isAsciiSpaceChar right+ sep = if leftHadWs || rightHadWs || needSep then " " else ""+ in left' <> sep <> right'++startsWithAsciiSpace :: T.Text -> Bool+startsWithAsciiSpace t =+ case T.uncons t of+ Just (c, _) -> isAsciiSpaceChar c+ Nothing -> False++endsWithAsciiSpace :: T.Text -> Bool+endsWithAsciiSpace t =+ case T.unsnoc t of+ Just (_, c) -> isAsciiSpaceChar c+ Nothing -> False++isAsciiSpaceChar :: Char -> Bool+isAsciiSpaceChar c = c == ' ' || c == '\t' || c == '\n'++needsSeparator :: Exp -> Exp -> Bool+needsSeparator prevE curE+ | isGreekIdentifierExp prevE && isIdentifierLike curE = True+ | isGreekIdentifierExp prevE && isRootLike curE = True+ | isGreekIdentifierExp prevE && isTerminatingPunctuation curE = True+ | isWordSymbolLike prevE && isIdentifierLike curE = True+ | isWordSymbolLike prevE && isOpenLike curE = True+ | isWordStyledExp prevE && isIdentifierLike curE = True+ | isAccentCommandExp prevE && isIdentifierLike curE = True+ | isAccentCommandExp prevE && isOpenLike curE = True+ | isAccentCommandExp prevE && isRootLike curE = True+ | isMathOperatorExp prevE && isIdentifierLike curE = True+ | isUnaryMinusSymbol prevE && isIdentifierLike curE = True+ | isIdentifierLike prevE && isMathOperatorExp curE = True+ | isIdentifierLike prevE && isRootLike curE = True+ | isIdentifierLike prevE && isArrowScriptedExp curE = True+ | isIdentifierLike prevE && isScriptedMathOperatorExp curE = True+ | isIdentifierLike prevE && isWordSymbolLike curE = True+ | isLargeOpScriptedExp prevE && isIdentifierLike curE = True+ | isLargeOpScriptedExp prevE && isFractionLike curE = True+ | isLargeOpScriptedExp prevE && isAccentCommandExp curE = True+ | isScripted prevE && isIdentifierLike curE = True+ | isArrowScriptedExp prevE && isIdentifierLike curE = True+ | isScriptedMathOperatorExp prevE && isIdentifierLike curE = True+ | isDelimited prevE && isDelimited curE = True+ | isCloseLike prevE && isIdentifierLike curE = True+ | isCloseLike prevE && isWordSymbolLike curE = True+ | isCloseLike prevE && isAccentCommandExp curE = True+ | isCloseLike prevE && isArrayLike curE = True+ | isIdentifierLike prevE && isWordStyledExp curE = True+ | isIdentifierLike prevE && isUprightMathTextExp curE = True+ | isIdentifierLike prevE && isAccentCommandExp curE = True+ | isIdentifierLike prevE && isWideSpace curE = True+ | isIdentifierLike prevE && isDelimited curE = True+ | isIdentifierLike prevE && isNonNormalTextExp curE = True+ | isQuotedTextExp prevE && isItalicTextExp curE = True+ | otherwise = False++isGreekIdentifierExp :: Exp -> Bool+isGreekIdentifierExp e =+ case e of+ EIdentifier t -> greekName t /= Nothing+ _ -> False++isIdentifierLike :: Exp -> Bool+isIdentifierLike e =+ case e of+ EIdentifier{} -> True+ ENumber{} -> True+ EMathOperator{} -> True+ ESub{} -> True+ ESuper{} -> True+ ESubsup{} -> True+ EStyled{} -> True+ _ -> False++isMathOperatorExp :: Exp -> Bool+isMathOperatorExp e =+ case e of+ EMathOperator{} -> True+ _ -> False++isDelimited :: Exp -> Bool+isDelimited e =+ case e of+ EDelimited{} -> True+ _ -> False++isArrayLike :: Exp -> Bool+isArrayLike e =+ case e of+ EArray{} -> True+ _ -> False++isFractionLike :: Exp -> Bool+isFractionLike e =+ case e of+ EFraction{} -> True+ _ -> False++isWideSpace :: Exp -> Bool+isWideSpace e =+ case e of+ ESpace w -> w >= 1+ _ -> False++isWordSymbolLike :: Exp -> Bool+isWordSymbolLike e =+ case e of+ ESymbol _ "∀" -> True+ ESymbol _ "∃" -> True+ ESymbol _ "∇" -> True+ ESymbol _ "∂" -> True+ ESymbol _ "¬" -> True+ ESymbol _ "∧" -> True+ ESymbol _ "∨" -> True+ ESymbol _ "and" -> True+ ESymbol _ "or" -> True+ _ -> False++isOpenLike :: Exp -> Bool+isOpenLike e =+ case e of+ ESymbol Open _ -> True+ _ -> False++isRootLike :: Exp -> Bool+isRootLike e =+ case e of+ ESqrt{} -> True+ ERoot{} -> True+ _ -> False++isWordStyledExp :: Exp -> Bool+isWordStyledExp e =+ case e of+ EStyled TextNormal [x] -> isWordStyledExp x+ EStyled TextItalic _ -> True+ EStyled TextBold _ -> True+ EStyled TextScript _ -> True+ EStyled TextFraktur _ -> True+ EStyled TextDoubleStruck _ -> True+ _ -> False++isUprightMathTextExp :: Exp -> Bool+isUprightMathTextExp e =+ case e of+ EStyled TextNormal [EIdentifier _] -> True+ _ -> False++isItalicTextExp :: Exp -> Bool+isItalicTextExp e =+ case e of+ EText TextItalic _ -> True+ _ -> False++isQuotedTextExp :: Exp -> Bool+isQuotedTextExp e =+ case e of+ EText TextNormal _ -> True+ _ -> False++isNonNormalTextExp :: Exp -> Bool+isNonNormalTextExp e =+ case e of+ EText sty _ -> sty /= TextNormal+ _ -> False++isAccentCommandExp :: Exp -> Bool+isAccentCommandExp e =+ case e of+ EOver _ _ over -> accentName over /= Nothing+ _ -> False++isTerminatingPunctuation :: Exp -> Bool+isTerminatingPunctuation e =+ case e of+ ESymbol _ "." -> True+ ESymbol _ "," -> True+ ESymbol _ ";" -> True+ ESymbol _ ":" -> True+ _ -> False++isCloseLike :: Exp -> Bool+isCloseLike e =+ case e of+ ESymbol Close _ -> True+ EDelimited{} -> True+ _ -> False++isScripted :: Exp -> Bool+isScripted e =+ case e of+ ESub{} -> True+ ESuper{} -> True+ ESubsup{} -> True+ _ -> False++isArrowScriptedExp :: Exp -> Bool+isArrowScriptedExp e =+ case e of+ EUnder _ base _ -> isArrowBase base+ EOver _ base _ -> isArrowBase base+ EUnderover _ base _ _ -> isArrowBase base+ ESub base _ -> isArrowBase base+ ESuper base _ -> isArrowBase base+ ESubsup base _ _ -> isArrowBase base+ _ -> False++isScriptedMathOperatorExp :: Exp -> Bool+isScriptedMathOperatorExp e =+ case e of+ ESub base _ -> isMathOperatorExp base+ ESuper base _ -> isMathOperatorExp base+ ESubsup base _ _ -> isMathOperatorExp base+ EUnder _ base _ -> isMathOperatorExp base+ EOver _ base _ -> isMathOperatorExp base+ EUnderover _ base _ _ -> isMathOperatorExp base+ _ -> False++isArrowBase :: Exp -> Bool+isArrowBase e =+ case e of+ ESymbol _ "←" -> True+ ESymbol _ "→" -> True+ ESymbol _ "↔" -> True+ ESymbol _ "⇐" -> True+ ESymbol _ "⇒" -> True+ ESymbol _ "⇔" -> True+ ESymbol _ "↦" -> True+ _ -> False++isUnaryMinusSymbol :: Exp -> Bool+isUnaryMinusSymbol e =+ case e of+ ESymbol t "-" -> t /= Bin+ ESymbol t "−" -> t /= Bin+ _ -> False++isLargeOpScriptedExp :: Exp -> Bool+isLargeOpScriptedExp e =+ case e of+ EUnder _ base _ -> largeOpName base /= Nothing+ EOver _ base _ -> largeOpName base /= Nothing+ EUnderover _ base _ _ -> largeOpName base /= Nothing+ ESub base _ -> largeOpName base /= Nothing+ ESuper base _ -> largeOpName base /= Nothing+ ESubsup base _ _ -> largeOpName base /= Nothing+ _ -> False++startsWithInfixNeedingLhs :: [Exp] -> Bool+startsWithInfixNeedingLhs exps =+ case exps of+ (e : _) -> needsNeutralLhs e+ _ -> False++endsWithInfixNeedingRhs :: [Exp] -> Bool+endsWithInfixNeedingRhs exps =+ case reverse exps of+ (e : _) -> needsNeutralRhs e+ _ -> False++needsNeutralLhs :: Exp -> Bool+needsNeutralLhs = isInfixLikeExp++needsNeutralRhs :: Exp -> Bool+needsNeutralRhs = isInfixLikeExp++needsNeutralScriptOperands :: Exp -> Bool+needsNeutralScriptOperands e =+ isInfixLikeExp e && not (isAtomicScriptOperator e)++isAtomicScriptOperator :: Exp -> Bool+isAtomicScriptOperator e =+ case e of+ ESymbol _ "∘" -> True+ _ -> False++isInfixLikeExp :: Exp -> Bool+isInfixLikeExp e =+ case e of+ ESymbol t s+ | t == Bin -> True+ | t == Rel -> True+ | otherwise -> s `elem`+ [ "×", "⋅", "·", "∘"+ , "∈", "∉", "∋"+ , "∩", "∪"+ , "⊂", "⊆", "⊃", "⊇"+ , "≤", "≥", "≠", "≈", "≡", "∝"+ , "∥", "⊥"+ , "±", "∓"+ , "/", "←", "→", "↔", "⇐", "⇒", "⇔", "↦"+ ]+ _ -> False++renderExpIn :: DisplayType -> AlignContext -> Exp -> Maybe T.Text+renderExpIn dt ctx e =+ case e of+ ENumber t -> Just t+ EIdentifier t -> Just (renderIdentifier t)+ EMathOperator t -> Just (renderMathOperator t)+ ESymbol t s -> Just (renderSymbol t s)+ EText sty t -> Just (renderTextAtom sty t)+ ESpace w -> Just (renderSpace w)+ EGrouped xs -> ("{" <>) . (<> "}") <$> renderExpsIn dt ctx xs+ EStyled sty xs -> renderStyled dt ctx sty xs++ EFraction frac num den -> do+ num' <- renderExpIn dt AlignDefault num+ den' <- renderExpIn dt AlignDefault den+ let num'' = maybeCenterFractionArg ctx num'+ let den'' = maybeCenterFractionArg ctx den'+ pure $ case frac of+ NoLineFrac -> "binom" <> asDelimitedArg num'' <> asDelimitedArg den''+ InlineFrac -> renderInlineFraction num'' den''+ NormalFrac+ | dt == DisplayInline -> renderInlineFraction num'' den''+ _ -> "{" <> num'' <> " over " <> den'' <> "}"++ ESqrt x -> ("sqrt {" <>) . (<> "}") <$> renderExpIn dt ctx x+ ERoot idx rad -> do+ idx' <- renderExpIn dt ctx idx+ rad' <- renderExpIn dt ctx rad+ pure $ "nroot {" <> idx' <> "} {" <> rad' <> "}"++ EScaled _ (ESymbol Open "|") ->+ Just "mline"+ EScaled _ (ESymbol Close "|") ->+ Just "mline"+ EScaled _ x ->+ renderExpIn dt ctx x++ EDelimited op cl xs -> do+ body <- renderDelimitedBody dt ctx xs+ let op' = delimToken DelimLeft op+ let cl' = delimToken DelimRight cl+ pure $ "left " <> op' <> " " <> body <> " right " <> cl'++ ESub base sub -> do+ base' <- renderExpIn dt ctx base+ sub' <- renderScriptArg dt ctx sub+ pure $ renderScriptBase base base' <> "_" <> sub'++ ESuper base sup -> do+ baseRendered <- renderExpIn dt ctx base+ case renderPrimeSuffix sup of+ Just primes ->+ pure $ renderScriptBase base baseRendered <> primes+ Nothing -> do+ supRendered <- renderScriptArg dt ctx sup+ pure $ renderScriptBase base baseRendered <> "^" <> supRendered++ ESubsup base sub sup -> do+ baseRendered <- renderExpIn dt ctx base+ subRendered <- renderScriptArg dt ctx sub+ case renderPrimeSuffix sup of+ Just primes ->+ pure $ renderScriptBase base baseRendered <> "_" <> subRendered <> primes+ Nothing -> do+ supRendered <- renderScriptArg dt ctx sup+ pure $ renderScriptBase base baseRendered <> "_" <> subRendered <> "^" <> supRendered++ EOver _ base over+ | Just arrow <- arrowScriptOpName base -> do+ if isEmptyScriptArg over+ then pure arrow+ else do+ over' <- renderScriptArg dt ctx over+ pure $ arrow <> " csup " <> centerScriptArg over'+ | Just op <- centeredScriptOpName base -> do+ over' <- renderScriptArg dt ctx over+ pure $ "{" <> op <> "} csup " <> centerScriptArg over'+ | Just brace <- braceAnnotationName over -> do+ base' <- renderExpIn dt ctx base+ pure $ renderScriptBase base base' <> " " <> brace+ | isBraceAnnotatedExp base -> do+ base' <- renderExpIn dt ctx base+ over' <- renderBraceLabel dt ctx over+ pure $ base' <> " " <> over'+ | Just accent <- accentName over -> do+ base' <- renderExpIn dt ctx base+ pure $ accent <> " " <> renderAccentArg base base'+ | Just op <- limitOpName base -> do+ over' <- renderLimitArg dt ctx over+ pure $ op <> " to " <> over' <> " "+ | otherwise -> Nothing++ EUnder _ base under ->+ case arrowScriptOpName base of+ Just arrow ->+ if isEmptyScriptArg under+ then pure arrow+ else do+ under' <- renderScriptArg dt ctx under+ pure $ arrow <> " csub " <> centerScriptArg under'+ Nothing ->+ case underlineMarkerName under of+ Just marker -> do+ base' <- renderExpIn dt ctx base+ pure $ marker <> " " <> renderAccentArg base base'+ Nothing ->+ case braceAnnotationName under of+ Just brace -> do+ base' <- renderExpIn dt ctx base+ pure $ renderScriptBase base base' <> " " <> brace+ Nothing ->+ if isBraceAnnotatedExp base+ then do+ base' <- renderExpIn dt ctx base+ under' <- renderBraceLabel dt ctx under+ pure $ base' <> " " <> under'+ else+ case centeredScriptOpName base of+ Just op -> do+ under' <- renderScriptArg dt ctx under+ pure $ "{" <> op <> "} csub " <> centerScriptArg under'+ Nothing ->+ case limitOpName base of+ Just op -> do+ under' <- renderLimitArg dt ctx under+ pure $ op <> " from " <> under' <> " "+ Nothing -> do+ base' <- renderExpIn dt ctx base+ under' <- renderScriptArg dt ctx under+ pure $ renderScriptBase base base' <> "_" <> under'+ EUnderover _ base under over ->+ case arrowScriptOpName base of+ Just arrow ->+ case (isEmptyScriptArg under, isEmptyScriptArg over) of+ (True, True) -> pure arrow+ (False, True) -> do+ under' <- renderScriptArg dt ctx under+ pure $ arrow <> " csub " <> centerScriptArg under'+ (True, False) -> do+ over' <- renderScriptArg dt ctx over+ pure $ arrow <> " csup " <> centerScriptArg over'+ (False, False) -> do+ under' <- renderScriptArg dt ctx under+ over' <- renderScriptArg dt ctx over+ pure $ arrow <> " csub " <> centerScriptArg under'+ <> " csup " <> centerScriptArg over'+ Nothing ->+ case centeredScriptOpName base of+ Just op -> do+ under' <- renderScriptArg dt ctx under+ over' <- renderScriptArg dt ctx over+ pure $ "{" <> op <> "} csub " <> centerScriptArg under'+ <> " csup " <> centerScriptArg over'+ Nothing ->+ case limitOpName base of+ Just op -> do+ under' <- renderLimitArg dt ctx under+ over' <- renderLimitArg dt ctx over+ pure $ op <> " from " <> under' <> " to " <> over' <> " "+ Nothing -> do+ base' <- renderExpIn dt ctx base+ under' <- renderScriptArg dt ctx under+ over' <- renderScriptArg dt ctx over+ pure $ renderScriptBase base base' <> "_" <> under' <> "^" <> over'+ EArray aligns rows -> renderMatrix dt aligns rows+ EPhantom x -> do+ x' <- renderExpIn dt ctx x+ pure $ "phantom " <> renderPhantomArg x x'+ _ -> Nothing++renderDelimitedBody :: DisplayType -> AlignContext -> [Either T.Text Exp] -> Maybe T.Text+renderDelimitedBody dt ctx xs = do+ chunks <- mapM (renderDelimitedChunk dt ctx) xs+ pure $ T.strip (mergeDelimitedChunks chunks)++data DelimitedChunk = DelimRaw T.Text | DelimExp Exp T.Text++renderDelimitedChunk :: DisplayType -> AlignContext -> Either T.Text Exp -> Maybe DelimitedChunk+renderDelimitedChunk dt ctx p =+ case p of+ Left t -> Just $ DelimRaw (" " <> delimToken DelimMiddle t <> " ")+ Right x -> DelimExp x <$> renderExpIn dt ctx x++mergeDelimitedChunks :: [DelimitedChunk] -> T.Text+mergeDelimitedChunks [] = ""+mergeDelimitedChunks (c0:cs) = snd $ List.foldl' step (chunkExp c0, chunkText c0) cs+ where+ step (prevExp, acc) cur+ | T.null curText = (prevExp, acc)+ | otherwise =+ case cur of+ DelimRaw _ -> (Nothing, appendRendered False acc curText)+ DelimExp curExp _ ->+ let needSep = case prevExp of+ Just pe -> needsSeparator pe curExp+ Nothing -> False+ in (Just curExp, appendRendered needSep acc curText)+ where+ curText = chunkText cur++ chunkText c =+ case c of+ DelimRaw t -> t+ DelimExp _ t -> t++ chunkExp c =+ case c of+ DelimRaw _ -> Nothing+ DelimExp e _ -> Just e++renderMatrix :: DisplayType -> [Alignment] -> [[[Exp]]] -> Maybe T.Text+renderMatrix dt aligns rows = do+ rows' <- mapM (renderMatrixRow dt aligns) rows+ pure $ "matrix { " <> T.intercalate " ## " rows' <> " }"++renderMatrixRow :: DisplayType -> [Alignment] -> [[Exp]] -> Maybe T.Text+renderMatrixRow dt aligns cells = do+ let explicitCenter = any (/= AlignCenter) aligns+ let columnCount = max (length aligns) (length cells)+ let paddedCells = take columnCount (cells ++ repeat [])+ cells' <- sequence+ [ renderMatrixCellWithAlign dt explicitCenter (columnAlign aligns i) c+ | (i, c) <- zip [(0 :: Int) ..] paddedCells+ ]+ pure $ T.intercalate " # " cells'++renderMatrixCell :: DisplayType -> AlignContext -> [Exp] -> Maybe T.Text+renderMatrixCell _ _ [] = Just "{}"+renderMatrixCell dt ctx xs = do+ rendered <- renderExpsIn dt ctx xs+ let stripped = T.strip rendered+ pure $ if T.null stripped then "{}" else stripped++renderMatrixCellWithAlign :: DisplayType -> Bool -> Alignment -> [Exp] -> Maybe T.Text+renderMatrixCellWithAlign dt explicitCenter align xs = do+ cell <- renderMatrixCell dt (alignmentContext align) xs+ pure $ case align of+ AlignLeft -> "alignl " <> cell+ AlignRight -> "alignr " <> cell+ AlignCenter | explicitCenter -> "alignc " <> cell+ _ -> cell++columnAlign :: [Alignment] -> Int -> Alignment+columnAlign aligns i =+ case drop i aligns of+ (a : _) -> a+ [] -> AlignCenter++renderStyled :: DisplayType -> AlignContext -> TextType -> [Exp] -> Maybe T.Text+renderStyled dt ctx sty xs = do+ body <- renderExpsIn dt ctx xs+ pure $ case sty of+ _+ | Just unicodeBody <- renderUnicodeSerifStyled sty xs ->+ "nitalic " <> styleArg unicodeBody+ TextNormal+ | Just ident <- singleUprightIdentifier xs ->+ "nitalic " <> renderTextNormalIdentifier ident+ | not (hasStructuralScript xs)+ , Just txt <- styledText xs -> quoteText txt+ | Just txt <- renderTextNormalStyled dt xs+ , shouldForceUprightTextNormal xs -> "nitalic{" <> txt <> "}"+ | Just txt <- renderTextNormalStyled dt xs -> txt+ TextItalic -> "ital " <> styleArg body+ TextBold+ | shouldForceUprightBold xs -> "bold nitalic " <> styleArg body+ | otherwise -> "bold " <> styleArg body+ TextBoldItalic -> "bold " <> styleArg ("ital " <> styleArg body)+ TextMonospace -> "font fixed nitalic " <> styleArg body+ TextSansSerif -> "font sans nitalic " <> styleArg body+ TextSansSerifBold -> "bold " <> styleArg ("font sans nitalic " <> styleArg body)+ TextSansSerifBoldItalic -> "bold " <> styleArg ("font sans ital " <> styleArg body)+ TextSansSerifItalic -> "font sans ital " <> styleArg body+ TextScript -> "ital " <> styleArg body+ TextFraktur -> "bold " <> styleArg body+ TextDoubleStruck -> "bold nitalic " <> styleArg body+ _ -> body+ where+ styleArg t+ | T.null t = "{}"+ | T.length t == 1 = t+ | otherwise = "{" <> t <> "}"++renderUnicodeSerifStyled :: TextType -> [Exp] -> Maybe T.Text+renderUnicodeSerifStyled sty xs =+ case sty of+ TextScript -> styledUnicodeText sty xs+ TextFraktur -> styledUnicodeText sty xs+ TextDoubleStruck -> styledUnicodeText sty xs+ TextBoldScript -> styledUnicodeText sty xs+ TextBoldFraktur -> styledUnicodeText sty xs+ _ -> Nothing++styledUnicodeText :: TextType -> [Exp] -> Maybe T.Text+styledUnicodeText sty = fmap T.concat . mapM (styledUnicodeExp sty)++styledUnicodeExp :: TextType -> Exp -> Maybe T.Text+styledUnicodeExp sty e =+ case e of+ EIdentifier t -> mapStyledUnicode sty t+ ENumber t -> mapStyledUnicode sty t+ EGrouped xs -> styledUnicodeText sty xs+ EStyled TextNormal xs -> styledUnicodeText sty xs+ ESpace w+ | w <= 0 -> Just ""+ | w >= 2 -> Just " "+ | otherwise -> Just " "+ _ -> Nothing++mapStyledUnicode :: TextType -> T.Text -> Maybe T.Text+mapStyledUnicode sty t = T.pack <$> mapM (\c -> toUnicodeChar (sty, c)) (T.unpack t)++hasStructuralScript :: [Exp] -> Bool+hasStructuralScript = any go+ where+ go e =+ case e of+ ESub{} -> True+ ESuper{} -> True+ ESubsup{} -> True+ EGrouped xs -> hasStructuralScript xs+ EStyled TextNormal xs -> hasStructuralScript xs+ _ -> False++styledText :: [Exp] -> Maybe T.Text+styledText = fmap T.concat . mapM styledTextExp++styledTextExp :: Exp -> Maybe T.Text+styledTextExp e =+ case e of+ ENumber t -> Just t+ EIdentifier t -> Just t+ EText _ t -> Just t+ ESpace w+ | w <= 0 -> Just ""+ | w >= 2 -> Just " "+ | otherwise -> Just " "+ EGrouped xs -> styledText xs+ EStyled TextNormal xs -> styledText xs+ ESub base sub -> do+ base' <- styledTextExp base+ sub' <- styledTextNonNumericExp sub+ pure $ base' <> "_" <> sub'+ ESuper base sup -> do+ base' <- styledTextExp base+ sup' <- styledTextNonNumericExp sup+ pure $ base' <> "^" <> sup'+ ESubsup base sub sup -> do+ base' <- styledTextExp base+ sub' <- styledTextNonNumericExp sub+ sup' <- styledTextNonNumericExp sup+ pure $ base' <> "_" <> sub' <> "^" <> sup'+ ESymbol _ s+ | isPlainTextSymbol s -> Just s+ _ -> Nothing++styledTextNonNumericExp :: Exp -> Maybe T.Text+styledTextNonNumericExp e = do+ txt <- styledTextExp e+ if T.any isAsciiDigit txt+ then Nothing+ else Just txt++isAsciiDigit :: Char -> Bool+isAsciiDigit c = c >= '0' && c <= '9'++isPlainTextSymbol :: T.Text -> Bool+isPlainTextSymbol s =+ s `elem`+ [ "_", ",", ".", ":", ";", "-", "−", "/", "(", ")", "[", "]"+ , "+", "=", "'", "′"+ ]++renderTextNormalStyled :: DisplayType -> [Exp] -> Maybe T.Text+renderTextNormalStyled dt xs = do+ let xs' = quoteStarMathKeywordRuns xs+ rendered <- mapM (renderTextNormalExp dt) xs'+ pure $ mergePieces (zip xs' rendered)++quoteStarMathKeywordRuns :: [Exp] -> [Exp]+quoteStarMathKeywordRuns [] = []+quoteStarMathKeywordRuns xs@(x : rest)+ | Just _ <- asciiIdentifierWord x =+ let (word, wordExps, rest') = takeIdentifierWordRun xs+ in if isStarMathReservedWord word+ then EText TextNormal word : quoteStarMathKeywordRuns rest'+ else wordExps <> quoteStarMathKeywordRuns rest'+ | otherwise = x : quoteStarMathKeywordRuns rest++takeIdentifierWordRun :: [Exp] -> (T.Text, [Exp], [Exp])+takeIdentifierWordRun = go [] []+ where+ go pieces exps (e : rest)+ | Just piece <- asciiIdentifierWord e = go (piece : pieces) (e : exps) rest+ go pieces exps rest = (T.concat (reverse pieces), reverse exps, rest)++asciiIdentifierWord :: Exp -> Maybe T.Text+asciiIdentifierWord e =+ case e of+ EIdentifier t+ | not (T.null t) && T.all isAsciiAlpha t -> Just t+ _ -> Nothing++renderTextNormalExp :: DisplayType -> Exp -> Maybe T.Text+renderTextNormalExp dt e =+ case e of+ ENumber t -> Just t+ EIdentifier t -> Just (renderIdentifier t)+ EText sty t -> Just (renderTextAtom sty t)+ ESpace w -> Just (renderSpace w)+ EGrouped xs -> renderTextNormalStyled dt xs+ EStyled TextNormal xs -> renderTextNormalStyled dt xs+ EStyled TextBold xs -> do+ body <- renderExpsIn dt AlignDefault xs+ pure $ "bold nitalic " <> styleArg body+ EStyled sty xs -> renderStyled dt AlignDefault sty xs+ ESub base sub -> do+ base' <- renderTextNormalExp dt base+ sub' <- renderTextNormalExp dt sub+ pure $ base' <> "_" <> sub'+ ESuper base sup -> do+ base' <- renderTextNormalExp dt base+ sup' <- renderTextNormalExp dt sup+ pure $ base' <> "^" <> sup'+ ESubsup base sub sup -> do+ base' <- renderTextNormalExp dt base+ sub' <- renderTextNormalExp dt sub+ sup' <- renderTextNormalExp dt sup+ pure $ base' <> "_" <> sub' <> "^" <> sup'+ ESymbol t s -> Just (T.strip (renderSymbol t s))+ _ -> Nothing++shouldForceUprightTextNormal :: [Exp] -> Bool+shouldForceUprightTextNormal = all isUprightTextNormalExp++shouldForceUprightBold :: [Exp] -> Bool+shouldForceUprightBold = all isUprightBoldExp++isUprightBoldExp :: Exp -> Bool+isUprightBoldExp e =+ case e of+ ENumber{} -> True+ EIdentifier t -> T.all isAsciiAlphaNum t+ EText{} -> True+ ESpace{} -> True+ ESymbol _ s -> isPlainTextSymbol s+ EGrouped xs -> shouldForceUprightBold xs+ EStyled TextNormal xs -> shouldForceUprightBold xs+ ESub base sub -> isUprightBoldExp base && isUprightBoldExp sub+ ESuper base sup -> isUprightBoldExp base && isUprightBoldExp sup+ ESubsup base sub sup -> isUprightBoldExp base+ && isUprightBoldExp sub+ && isUprightBoldExp sup+ _ -> False++isUprightTextNormalExp :: Exp -> Bool+isUprightTextNormalExp e =+ case e of+ ENumber{} -> True+ EIdentifier{} -> True+ EText{} -> True+ ESpace{} -> True+ ESymbol _ s -> isPlainTextSymbol s+ EGrouped xs -> shouldForceUprightTextNormal xs+ EStyled TextNormal xs -> shouldForceUprightTextNormal xs+ ESub base sub -> isUprightTextNormalExp base && isUprightTextNormalExp sub+ ESuper base sup -> isUprightTextNormalExp base && isUprightTextNormalExp sup+ ESubsup base sub sup -> isUprightTextNormalExp base+ && isUprightTextNormalExp sub+ && isUprightTextNormalExp sup+ _ -> False++isAsciiAlpha :: Char -> Bool+isAsciiAlpha c =+ (c >= 'A' && c <= 'Z') ||+ (c >= 'a' && c <= 'z')++isAsciiAlphaNum :: Char -> Bool+isAsciiAlphaNum c =+ isAsciiAlpha c ||+ (c >= '0' && c <= '9')++styleArg :: T.Text -> T.Text+styleArg t+ | T.null t = "{}"+ | T.length t == 1 = t+ | otherwise = "{" <> t <> "}"++singleUprightIdentifier :: [Exp] -> Maybe T.Text+singleUprightIdentifier xs =+ case xs of+ [EIdentifier t] -> Just t+ _ -> Nothing++alignmentContext :: Alignment -> AlignContext+alignmentContext a =+ case a of+ AlignLeft -> AlignLeftCtx+ AlignRight -> AlignRightCtx+ _ -> AlignDefault++maybeCenterFractionArg :: AlignContext -> T.Text -> T.Text+maybeCenterFractionArg ctx t+ | ctx == AlignLeftCtx || ctx == AlignRightCtx = "{alignc " <> asArg t <> "}"+ | otherwise = t+ where+ asArg x =+ let s = T.strip x+ in if T.null s+ then "{}"+ else if T.length s == 1+ then s+ else if T.head s == '{' && T.last s == '}'+ then s+ else "{" <> s <> "}"++asDelimitedArg :: T.Text -> T.Text+asDelimitedArg t =+ let s = T.strip t+ in if T.null s+ then "{}"+ else if T.head s == '{' && T.last s == '}'+ then s+ else "{" <> s <> "}"++renderInlineFraction :: T.Text -> T.Text -> T.Text+renderInlineFraction num den =+ "size*0.7 {" <> num <> " over " <> den <> "}"++renderSpace :: Rational -> T.Text+renderSpace w+ | w <= 0 = ""+ | w >= 2 = "~~ "+ | w >= 1 = "~ "+ | otherwise = " "++renderIdentifier :: T.Text -> T.Text+renderIdentifier ident =+ case greekName ident of+ Just name+ | shouldItalicizeGreek ident -> "%i" <> name+ | otherwise -> "%" <> name+ Nothing -> ident++renderTextNormalIdentifier :: T.Text -> T.Text+renderTextNormalIdentifier ident =+ case greekName ident of+ Just{} -> renderIdentifier ident+ Nothing+ | isStarMathReservedWord ident -> quoteText ident+ | otherwise -> ident++isStarMathReservedWord :: T.Text -> Bool+isStarMathReservedWord t =+ t `elem`+ [ "alignc", "alignl", "alignr"+ , "and", "approx"+ , "bar", "binom", "bold", "breve"+ , "cdot", "check", "circ", "cos", "cosh", "cot", "csub", "csup"+ , "dlarrow", "dlrarrow", "dot", "dotsaxis", "dotsdown", "dotslow"+ , "dotsup", "dotsvert", "downarrow", "drarrow"+ , "emptyset", "equiv", "exists", "exp"+ , "fixed", "font", "forall", "from", "func"+ , "gg"+ , "hat"+ , "in", "infinity", "int", "intersection", "ital", "iiint"+ , "langle", "lbrace", "lceil", "ldbracket", "ldline", "left"+ , "leftarrow", "leftrightarrow", "lfloor", "lim", "liminf"+ , "limsup", "ll", "lline", "ln", "log"+ , "mapsto", "matrix", "max", "min", "minusplus", "mline"+ , "nabla", "neg", "none", "notin", "nitalic", "nroot"+ , "or", "ortho", "over", "overbrace", "overline", "owns"+ , "parallel", "phantom", "plusminus", "partial", "prod", "prop"+ , "rangle", "rbrace", "rceil", "rdbracket", "rdline", "rfloor"+ , "right", "rline"+ , "sans", "sin", "sinh", "sqrt", "subset", "subseteq", "sum"+ , "supset", "supseteq"+ , "tilde", "times", "to", "toward"+ , "underbrace", "underline", "union", "uparrow"+ , "vec"+ ]++renderMathOperator :: T.Text -> T.Text+renderMathOperator t+ | t == "min" = "func min"+ | t == "max" = "func max"+ | isBareMathOperator t = t+ | shouldQuoteMathOperator t = "func " <> quoteText t+ | otherwise = "func " <> t++isBareMathOperator :: T.Text -> Bool+isBareMathOperator t =+ t `elem`+ [ "min", "max", "log", "sin", "cos", "cosh", "sinh"+ , "cot", "ln", "exp"+ ]++shouldQuoteMathOperator :: T.Text -> Bool+shouldQuoteMathOperator = not . T.all isLetter++shouldItalicizeGreek :: T.Text -> Bool+shouldItalicizeGreek ident =+ case ident of+ "α" -> True+ "β" -> True+ "γ" -> True+ "δ" -> True+ "ϵ" -> True+ "ε" -> True+ "ζ" -> True+ "η" -> True+ "θ" -> True+ "ϑ" -> True+ "ι" -> True+ "κ" -> True+ "λ" -> True+ "μ" -> True+ "ν" -> True+ "ξ" -> True+ "ο" -> True+ "π" -> True+ "ϖ" -> True+ "ρ" -> True+ "ϱ" -> True+ "𝜚" -> True+ "σ" -> True+ "ς" -> True+ "𝜍" -> True+ "τ" -> True+ "υ" -> True+ "ϕ" -> True+ "φ" -> True+ "χ" -> True+ "ψ" -> True+ "ω" -> True+ _ -> False++greekName :: T.Text -> Maybe T.Text+greekName ident =+ case ident of+ "α" -> Just "alpha"+ "β" -> Just "beta"+ "γ" -> Just "gamma"+ "δ" -> Just "delta"+ "ϵ" -> Just "epsilon"+ "ε" -> Just "varepsilon"+ "ζ" -> Just "zeta"+ "η" -> Just "eta"+ "θ" -> Just "theta"+ "ϑ" -> Just "vartheta"+ "ι" -> Just "iota"+ "κ" -> Just "kappa"+ "λ" -> Just "lambda"+ "μ" -> Just "mu"+ "ν" -> Just "nu"+ "ξ" -> Just "xi"+ "ο" -> Just "omicron"+ "π" -> Just "pi"+ "ϖ" -> Just "varpi"+ "ρ" -> Just "rho"+ "ϱ" -> Just "varrho"+ "𝜚" -> Just "varrho"+ "σ" -> Just "sigma"+ "ς" -> Just "varsigma"+ "𝜍" -> Just "varsigma"+ "τ" -> Just "tau"+ "υ" -> Just "upsilon"+ "ϕ" -> Just "phi"+ "φ" -> Just "varphi"+ "χ" -> Just "chi"+ "ψ" -> Just "psi"+ "ω" -> Just "omega"+ "Γ" -> Just "GAMMA"+ "Δ" -> Just "DELTA"+ "Θ" -> Just "THETA"+ "Λ" -> Just "LAMBDA"+ "Ξ" -> Just "XI"+ "Π" -> Just "PI"+ "Σ" -> Just "SIGMA"+ "Υ" -> Just "UPSILON"+ "Φ" -> Just "PHI"+ "Ψ" -> Just "PSI"+ "Ω" -> Just "OMEGA"+ _ -> Nothing++renderScriptBase :: Exp -> T.Text -> T.Text+renderScriptBase e rendered0 =+ let rendered = T.strip rendered0+ in if isEmptyScriptBase e || T.null rendered+ then "{}"+ else if isWrapped rendered+ then rendered+ else if isAtomic e+ then rendered+ else "{" <> rendered <> "}"++renderScriptArg :: DisplayType -> AlignContext -> Exp -> Maybe T.Text+renderScriptArg dt ctx e = do+ rendered0 <-+ if needsNeutralScriptOperands e+ then renderExpsIn dt ctx [e]+ else renderExpIn dt ctx e+ let rendered = T.strip rendered0+ pure $ if (isAtomic e && not (needsNeutralScriptOperands e)) || isQuotedText rendered+ then rendered+ else "{" <> rendered <> "}"++renderPrimeSuffix :: Exp -> Maybe T.Text+renderPrimeSuffix e =+ case e of+ ESymbol Pun "'" -> Just "'"+ ESymbol Pun "′" -> Just "'"+ ESymbol Pun "″" -> Just "''"+ ESymbol Pun "‴" -> Just "'''"+ _ -> Nothing++renderLimitArg :: DisplayType -> AlignContext -> Exp -> Maybe T.Text+renderLimitArg dt ctx e =+ case e of+ EGrouped xs -> do+ rendered <- renderExpsIn dt ctx xs+ let stripped = T.strip rendered+ pure $+ if T.null stripped+ then "{}"+ else if containsRelationLike xs+ then stripped+ else if isQuotedText stripped || isWrapped stripped || T.length stripped == 1+ then stripped+ else "{" <> stripped <> "}"+ _ -> T.strip <$> renderExpIn dt ctx e++containsRelationLike :: [Exp] -> Bool+containsRelationLike = any isRelationLike+ where+ isRelationLike expn =+ case expn of+ ESymbol Rel _ -> True+ ESymbol Bin _ -> True+ EGrouped ys -> containsRelationLike ys+ _ -> False++renderAccentArg :: Exp -> T.Text -> T.Text+renderAccentArg e rendered0 =+ let rendered = T.strip rendered0+ in if isAtomic e+ then rendered+ else "{" <> rendered <> "}"++renderPhantomArg :: Exp -> T.Text -> T.Text+renderPhantomArg e rendered0 =+ let rendered = T.strip rendered0+ in if isAtomic e+ then rendered+ else if isWrapped rendered+ then rendered+ else "{" <> rendered <> "}"++centerScriptArg :: T.Text -> T.Text+centerScriptArg rendered+ | isWrapped rendered = rendered+ | otherwise = "{" <> rendered <> "}"++isWrapped :: T.Text -> Bool+isWrapped t = T.length t >= 2 && T.head t == '{' && T.last t == '}'++isAtomic :: Exp -> Bool+isAtomic e =+ case e of+ ENumber{} -> True+ EIdentifier{} -> True+ EMathOperator{} -> True+ EText{} -> True+ ESymbol{} -> True+ _ -> False++isEmptyScriptBase :: Exp -> Bool+isEmptyScriptBase e =+ case e of+ EIdentifier t -> T.null t+ _ -> False++isEmptyScriptArg :: Exp -> Bool+isEmptyScriptArg e =+ case e of+ EGrouped [] -> True+ EIdentifier t -> T.null t+ _ -> False++isBraceAnnotatedExp :: Exp -> Bool+isBraceAnnotatedExp e =+ case e of+ EOver _ _ over -> braceAnnotationName over /= Nothing+ EUnder _ _ under -> braceAnnotationName under /= Nothing+ _ -> False++braceAnnotationName :: Exp -> Maybe T.Text+braceAnnotationName e =+ case e of+ ESymbol TOver "\9182" -> Just "overbrace"+ ESymbol TOver "\9140" -> Just "overbrace"+ ESymbol TUnder "\9183" -> Just "underbrace"+ ESymbol TUnder "\9141" -> Just "underbrace"+ _ -> Nothing++underlineMarkerName :: Exp -> Maybe T.Text+underlineMarkerName e =+ case e of+ ESymbol TUnder "_" -> Just "underline"+ _ -> Nothing++renderBraceLabel :: DisplayType -> AlignContext -> Exp -> Maybe T.Text+renderBraceLabel dt ctx e = do+ rendered0 <- renderExpIn dt ctx e+ let rendered = T.strip rendered0+ pure $ if isQuotedText rendered || isAtomic e+ then rendered+ else "{" <> rendered <> "}"++arrowScriptOpName :: Exp -> Maybe T.Text+arrowScriptOpName e =+ case e of+ ESymbol _ "←" -> Just "leftarrow"+ ESymbol _ "→" -> Just "toward"+ ESymbol _ "↔" -> Just "leftrightarrow"+ ESymbol _ "⇐" -> Just "dlarrow"+ ESymbol _ "⇒" -> Just "drarrow"+ ESymbol _ "⇔" -> Just "dlrarrow"+ ESymbol _ "↦" -> Just "mapsto"+ ESymbol _ "↑" -> Just "uparrow"+ ESymbol _ "↓" -> Just "downarrow"+ _ -> Nothing++accentName :: Exp -> Maybe T.Text+accentName e =+ case e of+ ESymbol Accent s -> accentFromChar s+ ESymbol TOver s -> overAccentFromChar s+ ESymbol _ s -> accentFromChar s+ _ -> Nothing++overAccentFromChar :: T.Text -> Maybe T.Text+overAccentFromChar s =+ case s of+ "\772" -> Just "overline"+ "\8254" -> Just "overline"+ "¯" -> Just "overline"+ _ -> accentFromChar s++accentFromChar :: T.Text -> Maybe T.Text+accentFromChar s =+ case s of+ "\775" -> Just "dot"+ "˙" -> Just "dot"+ "\776" -> Just "ddot"+ "¨" -> Just "ddot"+ "\770" -> Just "hat"+ "ˆ" -> Just "hat"+ "\780" -> Just "check"+ "ˇ" -> Just "check"+ "\771" -> Just "tilde"+ "˜" -> Just "tilde"+ "\772" -> Just "bar"+ "\8254" -> Just "bar"+ "¯" -> Just "bar"+ "\8407" -> Just "vec"+ "→" -> Just "vec"+ "\774" -> Just "breve"+ "˘" -> Just "breve"+ _ -> Nothing++data DelimSide = DelimLeft | DelimRight | DelimMiddle++delimToken :: DelimSide -> T.Text -> T.Text+delimToken side raw =+ case raw of+ "" -> "none"+ "." -> "none"+ "(" -> "("+ ")" -> ")"+ "[" -> "["+ "]" -> "]"+ "{" -> case side of+ DelimLeft -> "lbrace"+ DelimRight -> "rbrace"+ DelimMiddle -> "{"+ "}" -> case side of+ DelimLeft -> "lbrace"+ DelimRight -> "rbrace"+ DelimMiddle -> "}"+ "|" -> case side of+ DelimLeft -> "lline"+ DelimRight -> "rline"+ DelimMiddle -> "mline"+ "∣" -> case side of+ DelimLeft -> "lline"+ DelimRight -> "rline"+ DelimMiddle -> "mline"+ "∥" -> case side of+ DelimLeft -> "ldline"+ DelimRight -> "rdline"+ DelimMiddle -> "mline"+ "⟨" -> "langle"+ "⟩" -> "rangle"+ "⌊" -> "lfloor"+ "⌋" -> "rfloor"+ "⌈" -> "lceil"+ "⌉" -> "rceil"+ "⟦" -> "ldbracket"+ "⟧" -> "rdbracket"+ _ -> raw++renderSymbol :: TeXSymbolType -> T.Text -> T.Text+renderSymbol t s =+ case s of+ "∫" -> "int "+ "∑" -> "sum "+ "←" -> " leftarrow "+ "→" -> " toward "+ "↔" -> " leftrightarrow "+ "⇐" -> " dlarrow "+ "⇒" -> " drarrow "+ "⇔" -> " dlrarrow "+ "↑" -> " uparrow "+ "↓" -> " downarrow "+ "↦" -> " mapsto "+ "\8230 " -> " dotslow "+ "… " -> " dotslow "+ "\8230" -> " dotslow "+ "…" -> " dotslow "+ "\8943" -> " dotsaxis "+ "⋯" -> " dotsaxis "+ "⋮" -> " dotsvert "+ "⋱" -> " dotsdown "+ "⋰" -> " dotsup "+ "∈" -> " in "+ "∉" -> " notin "+ "∋" -> " owns "+ "∩" -> " intersection "+ "∪" -> " union "+ "⊂" -> " subset "+ "⊆" -> " subseteq "+ "⊃" -> " supset "+ "⊇" -> " supseteq "+ "≤" -> " <= "+ "≥" -> " >= "+ "≠" -> " <> "+ "≈" -> " approx "+ "≡" -> " equiv "+ "\8810" -> " ll "+ "≪" -> " ll "+ "\8811" -> " gg "+ "≫" -> " gg "+ "∝" -> " prop "+ "∥" -> " parallel "+ "⊥" -> " ortho "+ "±" -> " plusminus "+ "∓" -> " minusplus "+ "×" -> " times "+ "⋅" -> " cdot "+ "·" -> " cdot "+ "∘" -> " circ "+ "/" -> " / "+ "∂" -> "partial"+ "∇" -> "nabla"+ "∀" -> "forall"+ "∃" -> "exists"+ "¬" -> "neg"+ "∧" -> "and"+ "∨" -> "or"+ "∞" -> "infinity"+ "∅" -> "emptyset"+ "+" -> " + "+ "-" | t == Bin -> " - "+ "-" -> "-"+ "−" | t == Bin -> " - "+ "−" -> "-"+ "<" -> " < "+ ">" -> " > "+ "=" -> " = "+ "," -> ", "+ ";" -> "; "+ ":" -> " : "+ "!" -> " ! "+ "'" -> "'"+ "′" -> "'"+ "″" -> "''"+ "‴" -> "'''"+ _ | isWordLiteralSymbol s -> quoteText s+ | otherwise -> s++isWordLiteralSymbol :: T.Text -> Bool+isWordLiteralSymbol s =+ not (T.null s) && T.all isWordLiteralChar s++isWordLiteralChar :: Char -> Bool+isWordLiteralChar c =+ (c >= 'A' && c <= 'Z') ||+ (c >= 'a' && c <= 'z') ||+ c == ' ' || c == '-'++quoteText :: T.Text -> T.Text+quoteText t = "\"" <> escapeQuotes t <> "\""++escapeQuotes :: T.Text -> T.Text+escapeQuotes = T.replace "\"" "\\\""++isQuotedText :: T.Text -> Bool+isQuotedText t =+ T.length t >= 2 && T.head t == '"' && T.last t == '"'++largeOpName :: Exp -> Maybe T.Text+largeOpName e =+ case e of+ ESymbol Op "\8747" -> Just "int"+ ESymbol Op "\8751" -> Just "iiint"+ ESymbol Op "\8721" -> Just "sum"+ ESymbol Op "\8719" -> Just "prod"+ ESymbol Op "\8899" -> Just "oper ∪"+ ESymbol Op "\8898" -> Just "oper ∩"+ ESymbol Op "∫" -> Just "int"+ ESymbol Op "∭" -> Just "iiint"+ ESymbol Op "∑" -> Just "sum"+ ESymbol Op "∏" -> Just "prod"+ ESymbol Op "⋃" -> Just "oper ∪"+ ESymbol Op "⋂" -> Just "oper ∩"+ _ -> Nothing++limitOpName :: Exp -> Maybe T.Text+limitOpName e =+ case largeOpName e of+ Just op -> Just op+ Nothing ->+ case e of+ EMathOperator "lim" -> Just "lim"+ EMathOperator "liminf" -> Just "liminf"+ EMathOperator "limsup" -> Just "limsup"+ EMathOperator "min" -> Nothing+ EMathOperator "max" -> Nothing+ _ -> Nothing++centeredScriptOpName :: Exp -> Maybe T.Text+centeredScriptOpName e =+ case e of+ EMathOperator "min" -> Just "func min"+ EMathOperator "max" -> Just "func max"+ EMathOperator "det" -> Just "func det"+ EMathOperator "Pr" -> Just "func Pr"+ EMathOperator "gcd" -> Just "func gcd"+ EMathOperator "lim" -> Nothing+ EMathOperator "liminf" -> Nothing+ EMathOperator "limsup" -> Nothing+ EMathOperator t -> Just (renderMathOperator t)+ _ -> Nothing+renderTextAtom :: TextType -> T.Text -> T.Text+renderTextAtom sty t =+ case sty of+ TextItalic -> "ital " <> styleArg t+ TextBold -> "bold " <> styleArg (quoteText t)+ TextMonospace -> "font fixed " <> quoteText t+ TextSansSerif -> "font sans " <> quoteText t+ _ -> quoteText t
test/reader/tex/macros.test view
@@ -9,9 +9,9 @@ \theta% } % comment-\newcommand{\aaa}{\b{2}}+\newcommand{\aaa}{\bb{2}} \renewcommand{\phi}{\aaa}-\newcommand{\b}[1]{#1}+\newcommand{\bb}[1]{#1} \newenvironment{ary} {\begin{array}{cc}
test/test-texmath.hs view
@@ -37,6 +37,7 @@ mmlWriterTests <- getFiles "test/writer/mml" ommlWriterTests <- getFiles "test/writer/omml" eqnWriterTests <- getFiles "test/writer/eqn"+ starmathWriterTests <- getFiles "test/writer/starmath" typstWriterTests <- getFiles "test/writer/typst" regressionTests <- getFiles "test/regression" roundtripTests <- getFiles "test/roundtrip"@@ -63,6 +64,7 @@ , testGroup "mml" $ map toGoldenTest mmlWriterTests , testGroup "omml" $ map toGoldenTest ommlWriterTests , testGroup "eqn" $ map toGoldenTest eqnWriterTests+ , testGroup "starmath" $ map toGoldenTest starmathWriterTests , testGroup "typst" $ map toGoldenTest typstWriterTests ], testGroup "regression" $ map toGoldenTest regressionTests@@ -148,6 +150,8 @@ , ("tex", writeTeX) , ("omml", T.pack . ppTopElement . writeOMML DisplayBlock) , ("eqn", writeEqn DisplayBlock)+ , ("starmath", writeStarMath DisplayBlock)+ , ("starmath-inline", writeStarMath DisplayInline) , ("typst", writeTypst DisplayBlock) , ("native", T.pack . ppShow) , ("pandoc", maybe "" (T.pack . ppShow) . writePandoc DisplayBlock)
+ test/writer/starmath/001_dot_text_subscript.test view
@@ -0,0 +1,4 @@+<<< tex+\dot{Q}_{\text{dem}}(t)=\dot{Q}_{\text{eb}}(t)+\dot{Q}_{\text{dis}}(t)+\dot{Q}_{\text{boil}}(t),+>>> starmath+{dot Q}_"dem"(t) = {dot Q}_"eb"(t) + {dot Q}_"dis"(t) + {dot Q}_"boil"(t),
+ test/writer/starmath/002_common_accents.test view
@@ -0,0 +1,4 @@+<<< tex+\ddot{x}+\hat{x}+\tilde{x}+\vec{x}+\bar{x}+>>> starmath+ddot x + hat x + tilde x + vec x + bar x
+ test/writer/starmath/003_fraction.test view
@@ -0,0 +1,4 @@+<<< tex+\frac{a+b}{c}+>>> starmath+{{a + b} over c}
+ test/writer/starmath/004_square_root.test view
@@ -0,0 +1,4 @@+<<< tex+\sqrt{x+1}+>>> starmath+sqrt {{x + 1}}
+ test/writer/starmath/005_nth_root.test view
@@ -0,0 +1,4 @@+<<< tex+\sqrt[3]{x}+>>> starmath+nroot {3} {x}
+ test/writer/starmath/006_subscript_and_superscript.test view
@@ -0,0 +1,4 @@+<<< tex+x_i^2+>>> starmath+x_i^2
+ test/writer/starmath/007_superscript_with_grouped_base.test view
@@ -0,0 +1,4 @@+<<< tex+(a+b)^2+>>> starmath+(a + b)^2
+ test/writer/starmath/008_delimited_fraction.test view
@@ -0,0 +1,4 @@+<<< tex+\left(\frac{a}{b}\right)+>>> starmath+left ( {a over b} right )
+ test/writer/starmath/009_delimited_braces.test view
@@ -0,0 +1,4 @@+<<< tex+\left\{\frac{a}{b}\right\}+>>> starmath+left lbrace {a over b} right rbrace
+ test/writer/starmath/01.test view
@@ -0,0 +1,22 @@+<<< native+[ EIdentifier "x"+, ESymbol Rel "="+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8722"+ , EIdentifier "b"+ , ESymbol Bin "\177"+ , ESqrt+ (EGrouped+ [ ESuper (EIdentifier "b") (ENumber "2")+ , ESymbol Bin "\8722"+ , ENumber "4"+ , EIdentifier "a"+ , EIdentifier "c"+ ])+ ])+ (EGrouped [ ENumber "2" , EIdentifier "a" ])+]+>>> starmath+x = {{- b plusminus sqrt {{b^2 - 4ac}}} over {2a}}
+ test/writer/starmath/010_absolute_value_bars_normalize_to_delimiters.test view
@@ -0,0 +1,4 @@+<<< tex+|r_i| \le \varepsilon_{\mathrm{free}}+>>> starmath+left lline r_i right rline <= %ivarepsilon_"free"
+ test/writer/starmath/011_double_bars_normalize_to_norm_delimiters.test view
@@ -0,0 +1,4 @@+<<< tex+\|\mathbf{A}\mathbf{n} - \mathbf{b}\|+>>> starmath+left ldline bold nitalic A bold nitalic n - bold nitalic b right rdline
+ test/writer/starmath/012_one_sided_delimiter_uses_none.test view
@@ -0,0 +1,4 @@+<<< tex+\left. x \right|+>>> starmath+left none x right rline
+ test/writer/starmath/013_middle_delimiter_uses_mline.test view
@@ -0,0 +1,4 @@+<<< tex+\left( x \middle| y \right)+>>> starmath+left ( x mline y right )
+ test/writer/starmath/014_operator_mapping_cdot.test view
@@ -0,0 +1,4 @@+<<< tex+a\cdot b+>>> starmath+a cdot b
+ test/writer/starmath/015_binomial_nolinefrac.test view
@@ -0,0 +1,4 @@+<<< tex+\binom{n}{k}+>>> starmath+left ( binom{n}{k} right )
+ test/writer/starmath/016_integral_without_limits.test view
@@ -0,0 +1,4 @@+<<< tex+\int x\,dx+>>> starmath+int x dx
+ test/writer/starmath/017_integral_with_lower_and_upper_limits.test view
@@ -0,0 +1,4 @@+<<< tex+\int_0^1 x\,dx+>>> starmath+int_0^1 x dx
+ test/writer/starmath/018_integral_with_infinite_upper_limit.test view
@@ -0,0 +1,4 @@+<<< tex+\int_{0}^{\infty} e^{-x}\,dx+>>> starmath+int_0^infinity e^{{- x}} dx
+ test/writer/starmath/019_sum_with_lower_and_upper_limits.test view
@@ -0,0 +1,4 @@+<<< tex+\sum_{i=1}^{n} i+>>> starmath+sum from i = 1 to n i
+ test/writer/starmath/02.test view
@@ -0,0 +1,25 @@+<<< native+[ ENumber "2"+, ESymbol Rel "="+, EDelimited+ "("+ ")"+ [ Right+ (EFraction+ NormalFrac+ (EGrouped+ [ EDelimited+ "("+ ")"+ [ Right (ENumber "3")+ , Right (ESymbol Bin "\8722")+ , Right (EIdentifier "x")+ ]+ , ESymbol Bin "\215"+ , ENumber "2"+ ])+ (EGrouped [ ENumber "3" , ESymbol Bin "\8722" , EIdentifier "x" ]))+ ]+]+>>> starmath+2 = left ( {{left ( 3 - x right ) times 2} over {3 - x}} right )
+ test/writer/starmath/020_sum_with_symbolic_term.test view
@@ -0,0 +1,4 @@+<<< tex+\sum_{k=1}^{n} a_k+>>> starmath+sum from k = 1 to n a_k
+ test/writer/starmath/021_greek_letter_mapping.test view
@@ -0,0 +1,4 @@+<<< tex+\alpha + \beta + \Gamma + \Omega+>>> starmath+%ialpha + %ibeta + %GAMMA + %OMEGA
+ test/writer/starmath/022_greek_variant_mapping.test view
@@ -0,0 +1,4 @@+<<< tex+\phi + \varphi + \epsilon + \varepsilon + \vartheta+>>> starmath+%iphi + %ivarphi + %iepsilon + %ivarepsilon + %ivartheta
+ test/writer/starmath/023_arrow_mapping.test view
@@ -0,0 +1,4 @@+<<< tex+x \to y, x \leftarrow y, x \Rightarrow y, x \Leftrightarrow y+>>> starmath+x toward y, x leftarrow y, x drarrow y, x dlrarrow y
+ test/writer/starmath/024_set_and_relation_symbol_mapping.test view
@@ -0,0 +1,4 @@+<<< tex+A \subseteq B, A \cup B, x \in A, x \notin B+>>> starmath+A subseteq B, A union B, x in A, x notin B
+ test/writer/starmath/025_logic_and_calculus_symbol_mapping.test view
@@ -0,0 +1,4 @@+<<< tex+\forall x \exists y, \nabla f = 0, \partial_t u+>>> starmath+forall x exists y, nabla f = 0, partial_t u
+ test/writer/starmath/026_greek_identifier_spacing_in_products.test view
@@ -0,0 +1,4 @@+<<< tex+E_{k+1}=E_{k+\frac12}-\frac{\dot{Q}_{\text{dis},k}\Delta t}{\eta_{\text{dis}}},+>>> starmath+E_{{k + 1}} = E_{{k + {1 over 2}}} - {{{dot Q}_{{"dis", k}} %DELTA t} over %ieta_"dis"},
+ test/writer/starmath/027_math_operators_rendered_as_functions.test view
@@ -0,0 +1,4 @@+<<< tex+E_{k+1}\leftarrow\min\!\left(E^{\text{cap}}_{\text{s}},\max(0,E_{k+1})\right).+>>> starmath+E_{{k + 1}} leftarrow func min left ( E_"s"^"cap", func max(0, E_{{k + 1}}) right ).
+ test/writer/starmath/028_nested_function_with_left_delimiter_spacing.test view
@@ -0,0 +1,4 @@+<<< tex+P_{\text{ch}, k}=\max\!\left(0,\min\!\left(P'_{\text{pv}, k},\,P^{\text{cap}}_{\text{ch}},\,P_{\text{ch,head}, k}\right)\right).+>>> starmath+P_{{"ch", k}} = func max left ( 0, func min left ( P_{{"pv", k}}', P_"ch"^"cap", P_{{"ch,head", k}} right ) right ).
+ test/writer/starmath/029_quad_spacing_command.test view
@@ -0,0 +1,4 @@+<<< tex+a,\quad b+>>> starmath+a, ~ b
+ test/writer/starmath/03.test view
@@ -0,0 +1,13 @@+<<< native+[ EIdentifier "a"+, ESuper (EIdentifier "x") (ENumber "2")+, ESymbol Bin "+"+, EIdentifier "b"+, EIdentifier "x"+, ESymbol Bin "+"+, EIdentifier "c"+, ESymbol Rel "="+, ENumber "0"+]+>>> starmath+ax^2 + bx + c = 0
+ test/writer/starmath/030_qquad_spacing_command.test view
@@ -0,0 +1,4 @@+<<< tex+a,\qquad b+>>> starmath+a, ~~ b
+ test/writer/starmath/031_greek_token_separator_before_scripted_identifier.test view
@@ -0,0 +1,4 @@+<<< tex+f_{\text{eff}}=(1-\lambda)f_{\text{m}}+\lambda f_{\text{l}}.+>>> starmath+f_"eff" = (1 - %ilambda) f_"m" + %ilambda f_"l".
+ test/writer/starmath/032_mathrm_text_in_subscripts_stays_quoted.test view
@@ -0,0 +1,4 @@+<<< tex+n_{\mathrm{Fe,metal}} = n_{\mathrm{Fe_bcc}} + n_{\mathrm{Fe_fcc}}+>>> starmath+n_"Fe,metal" = n_{nitalic{Fe_b cc}} + n_{nitalic{Fe_f cc}}
+ test/writer/starmath/033_escaped_underscore_in_mathrm_stays_literal.test view
@@ -0,0 +1,4 @@+<<< tex+n_{\mathrm{wus}} = n_{\mathrm{Wus\_FeO}} + n_{\mathrm{Wus\_FeO1p5}}+>>> starmath+n_"wus" = n_"Wus_FeO" + n_"Wus_FeO1p5"
+ test/writer/starmath/034_numeric_chemistry_subscripts_in_mathrm_stay_structural.test view
@@ -0,0 +1,4 @@+<<< tex+\frac{n_{\mathrm{H_2O}}}{n_{\mathrm{H_2}}}\qquad \text{or} \qquad \frac{p_{\mathrm{H_2O}}}{p_{\mathrm{H_2}}}+>>> starmath+{n_{nitalic{H_2 O}} over n_{nitalic{H_2}}}~~ "or"~~ {p_{nitalic{H_2 O}} over p_{nitalic{H_2}}}
+ test/writer/starmath/035_circ_operator_maps_to_starmath_command.test view
@@ -0,0 +1,4 @@+<<< tex+\mu_i^\circ(T, P^\circ)+>>> starmath+%imu_i^circ(T, P^circ)
+ test/writer/starmath/036_min_with_bold_limit_variable_uses_operator_limits.test view
@@ -0,0 +1,4 @@+<<< tex+\min_{\mathbf{n}}\; G(\mathbf{n})+>>> starmath+{func min} csub {bold nitalic n} G(bold nitalic n)
+ test/writer/starmath/037_identifier_before_function_gets_separator.test view
@@ -0,0 +1,4 @@+<<< tex+\mu_i(T,P,\mathbf{n}) = \mu_i^\circ(T,P^\circ) + RT\ln\left(\frac{y_i P}{P^\circ}\right)+>>> starmath+%imu_i(T, P, bold nitalic n) = %imu_i^circ(T, P^circ) + RT ln left ( {{y_i P} over P^circ} right )
+ test/writer/starmath/038_greek_identifier_before_punctuation_gets_separator.test view
@@ -0,0 +1,4 @@+<<< tex+\xi.+>>> starmath+%ixi .
+ test/writer/starmath/039_greek_identifier_before_punctuation_in_larger_expression.test view
@@ -0,0 +1,4 @@+<<< tex+(\mathbf{H}+\lambda\mathbf{I})\Delta\mathbf{z} = -\nabla\phi.+>>> starmath+(bold nitalic H + %ilambda bold nitalic I) %DELTA bold nitalic z = -nabla %iphi .
+ test/writer/starmath/04.test view
@@ -0,0 +1,20 @@+<<< native+[ ESub (EIdentifier "S") (EText TextNormal "new")+, ESymbol Rel "="+, ESub (EIdentifier "S") (EText TextNormal "old")+, ESymbol Bin "\8722"+, EFraction+ NormalFrac+ (ESuper+ (EDelimited+ "("+ ")"+ [ Right (ENumber "5")+ , Right (ESymbol Bin "\8722")+ , Right (EIdentifier "T")+ ])+ (ENumber "2"))+ (ENumber "2")+]+>>> starmath+S_"new" = S_"old" - {{left ( 5 - T right )}^2 over 2}
+ test/writer/starmath/040_bare_recognized_math_operators_omit_func_and_keep_spacing.test view
@@ -0,0 +1,4 @@+<<< tex+\min x\log x\operatorname{log} x\sin x\cos x\max x\cosh x\sinh x\cot x\ln x\exp x+>>> starmath+func min x log x log x sin x cos x func max x cosh x sinh x cot x ln x exp x
+ test/writer/starmath/041_ordinary_function_with_subscript_keeps_ordinary_script_syntax.test view
@@ -0,0 +1,4 @@+<<< tex+\Delta\log_{10}K_j = \log_{10}K_{j,\mathrm{FPROPS}} - \log_{10}K_{j,\mathrm{ref}},\qquad j=1,\dots,r.+>>> starmath+%DELTA log_10 K_j = log_10 K_{{j, "FPROPS"}} - log_10 K_{{j, "ref"}}, ~~ j = 1, dotslow , r.
+ test/writer/starmath/042_adjacent_bold_terms_get_separator.test view
@@ -0,0 +1,4 @@+<<< tex+\mathcal{L}(\mathbf{n},\boldsymbol\lambda,\mathbf{s}) = G(\mathbf{n}) + \boldsymbol\lambda^T(\mathbf{A}\mathbf{n}-\mathbf{b}) - \mathbf{s}^T\mathbf{n}.+>>> starmath+nitalic ℒ(bold nitalic n, bold {%ilambda}, bold nitalic s) = G(bold nitalic n) + {bold {%ilambda}}^T(bold nitalic A bold nitalic n - bold nitalic b) - {bold nitalic s}^T bold nitalic n.
+ test/writer/starmath/043_mathcal_styled_token_before_left_delimiter.test view
@@ -0,0 +1,4 @@+<<< tex+\min\ \mathcal{J}\left(P^{\text{cap}}_{\text{pv}},N_{\text{u}},P^{\text{cap}}_{\text{eb}}\right)+>>> starmath+func min nitalic 𝒥 left ( P_"pv"^"cap", N_"u", P_"eb"^"cap" right )
+ test/writer/starmath/044_leading_binary_operator_gets_neutral_lhs.test view
@@ -0,0 +1,4 @@+<<< tex+\times\Delta t+>>> starmath+{} times %DELTA t
+ test/writer/starmath/045_standalone_binary_operator_gets_neutral_operands.test view
@@ -0,0 +1,4 @@+<<< tex+\times+>>> starmath+{} times {}
+ test/writer/starmath/046_trailing_binary_operator_gets_neutral_rhs.test view
@@ -0,0 +1,4 @@+<<< tex+a\times+>>> starmath+a times {}
+ test/writer/starmath/047_standalone_relation_gets_neutral_operands.test view
@@ -0,0 +1,4 @@+<<< tex+\leq+>>> starmath+{} <= {}
+ test/writer/starmath/048_standalone_arrow_gets_neutral_operands.test view
@@ -0,0 +1,4 @@+<<< tex+\rightarrow+>>> starmath+{} toward {}
+ test/writer/starmath/049_subscript_only_fragment_gets_neutral_base.test view
@@ -0,0 +1,4 @@+<<< tex+_2+>>> starmath+{}_2
+ test/writer/starmath/05.test view
@@ -0,0 +1,33 @@+<<< native+[ ESubsup (ESymbol Op "\8747") (EIdentifier "a") (EIdentifier "x")+, ESpace ((-1) % 6)+, ESpace ((-1) % 6)+, ESpace ((-1) % 6)+, ESubsup (ESymbol Op "\8747") (EIdentifier "a") (EIdentifier "s")+, EIdentifier "f"+, ESymbol Open "("+, EIdentifier "y"+, ESymbol Close ")"+, ESpace (1 % 6)+, EIdentifier "d"+, EIdentifier "y"+, ESpace (1 % 6)+, EIdentifier "d"+, EIdentifier "s"+, ESymbol Rel "="+, ESubsup (ESymbol Op "\8747") (EIdentifier "a") (EIdentifier "x")+, EIdentifier "f"+, ESymbol Open "("+, EIdentifier "y"+, ESymbol Close ")"+, ESymbol Open "("+, EIdentifier "x"+, ESymbol Bin "\8722"+, EIdentifier "y"+, ESymbol Close ")"+, ESpace (1 % 6)+, EIdentifier "d"+, EIdentifier "y"+]+>>> starmath+int_a^x int_a^s f(y) dy ds = int_a^x f(y)(x - y) dy
+ test/writer/starmath/050_superscript_only_fragment_gets_neutral_base.test view
@@ -0,0 +1,4 @@+<<< tex+^++>>> starmath+{}^{{} + {}}
+ test/writer/starmath/051_grouped_subscript_only_fragment_gets_neutral_base.test view
@@ -0,0 +1,4 @@+<<< tex+_{j,\mathrm{ref}}+>>> starmath+{}_{{j, "ref"}}
+ test/writer/starmath/052_matrix_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{matrix}a&b\\c&d\end{matrix}+>>> starmath+matrix { a # b ## c # d }
+ test/writer/starmath/053_pmatrix_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{pmatrix}a&b\\c&d\end{pmatrix}+>>> starmath+left ( matrix { a # b ## c # d } right )
+ test/writer/starmath/054_bmatrix_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{bmatrix}a&b\\c&d\end{bmatrix}+>>> starmath+left [ matrix { a # b ## c # d } right ]
+ test/writer/starmath/055_vmatrix_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{vmatrix}a&b\\c&d\end{vmatrix}+>>> starmath+left lline matrix { a # b ## c # d } right rline
+ test/writer/starmath/056_vmatrix_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{Vmatrix}a&b\\c&d\end{Vmatrix}+>>> starmath+left ldline matrix { a # b ## c # d } right rdline
+ test/writer/starmath/057_array_with_left_right_alignment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{array}{lr}a&bbb\\ccc&d\end{array}+>>> starmath+matrix { alignl a # alignr bbb ## alignl ccc # alignr d }
+ test/writer/starmath/058_aligned_array_keeps_fractions_centered.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{array}{l}\frac{AAA}{B}\end{array}+>>> starmath+matrix { alignl {{alignc {AAA}} over {alignc B}} }
+ test/writer/starmath/059_cases_environment.test view
@@ -0,0 +1,4 @@+<<< tex+\begin{cases}a, & x>0\\ b, & x\le 0\end{cases}+>>> starmath+left lbrace matrix { alignl a, # alignl x > 0 ## alignl b, # alignl x <= 0 } right none
+ test/writer/starmath/06.test view
@@ -0,0 +1,35 @@+<<< native+[ EUnderover+ True+ (ESymbol Op "\8721")+ (EGrouped [ EIdentifier "m" , ESymbol Rel "=" , ENumber "1" ])+ (ESymbol Ord "\8734")+, EUnderover+ True+ (ESymbol Op "\8721")+ (EGrouped [ EIdentifier "n" , ESymbol Rel "=" , ENumber "1" ])+ (ESymbol Ord "\8734")+, EFraction+ NormalFrac+ (EGrouped+ [ ESuper (EIdentifier "m") (ENumber "2")+ , ESpace (1 % 6)+ , EIdentifier "n"+ ])+ (EGrouped+ [ ESuper (ENumber "3") (EIdentifier "m")+ , EDelimited+ "("+ ")"+ [ Right (EIdentifier "m")+ , Right (ESpace (1 % 6))+ , Right (ESuper (ENumber "3") (EIdentifier "n"))+ , Right (ESymbol Bin "+")+ , Right (EIdentifier "n")+ , Right (ESpace (1 % 6))+ , Right (ESuper (ENumber "3") (EIdentifier "m"))+ ]+ ])+]+>>> starmath+sum from m = 1 to infinity sum from n = 1 to infinity {{m^2 n} over {3^m left ( m 3^n + n 3^m right )}}
+ test/writer/starmath/060_cases_with_negative_log_fraction.test view
@@ -0,0 +1,4 @@+<<< tex+t_{\text{pb,disc}}=\begin{cases}\dfrac{C_{\text{tot}}}{B}, & r=0,\\\dfrac{-\ln\!\left(1-rC_{\text{tot}}/B\right)}{\ln(1+r)}, & r>0\text{ and }1-rC_{\text{tot}}/B>0,\\\infty, & \text{otherwise}.\end{cases}+>>> starmath+t_"pb,disc" = left lbrace matrix { alignl {{alignc {C_"tot"}} over {alignc B}}, # alignl r = 0, ## alignl {{alignc {- ln left ( 1 - rC_"tot" / B right )}} over {alignc {ln(1 + r)}}}, # alignl r > 0" and "1 - rC_"tot" / B > 0, ## alignl infinity, # alignl "otherwise". } right none
+ test/writer/starmath/061_phantom_alignment.test view
@@ -0,0 +1,7 @@+<<< tex+\begin{gathered}+x + y = 2x + y - x \\+\phantom{x+y} = 3x + y - 2x+\end{gathered}+>>> starmath+matrix { x + y = 2x + y - x ## phantom {x + y} = 3x + y - 2x }
+ test/writer/starmath/062_fallback_to_tex_for_under_over_constructs.test view
@@ -0,0 +1,4 @@+<<< tex+\underbrace{x+y}_{z}+\overbrace{x+y}^{z}+>>> starmath+{x + y} underbrace z + {x + y} overbrace z
+ test/writer/starmath/063_demorgans_law.test view
@@ -0,0 +1,5 @@+<<< tex+\neg(p\wedge q)\iff(\neg p)\vee(\neg q)+ \overline{\bigcup_{i=1}^{n} A_{i}}=\bigcap_{i=1}^{n} \overline{A_{i}}+>>> starmath+neg (p and q) dlrarrow (neg p) or (neg q) overline {{oper ∪ from i = 1 to n A_i}} = oper ∩ from i = 1 to n overline {A_i}
+ test/writer/starmath/063_extensible_arrows_use_centered_scripts.test view
@@ -0,0 +1,10 @@+<<< native+[ EIdentifier "X"+, EOver False (ESymbol Op "\8660") (EIdentifier "h")+, EIdentifier "Y"+, EUnderover+ False (ESymbol Op "\8658") (EIdentifier "k") (EGrouped [])+, EIdentifier "Z"+]+>>> starmath+X dlrarrow csup {h} Y drarrow csub {k} Z
+ test/writer/starmath/064_centered_array_omits_explicit_alignc.test view
@@ -0,0 +1,13 @@+<<< native+[ EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ EIdentifier "a" ]+ , [ EIdentifier "b" ]+ ]+ , [ [ EIdentifier "c" ]+ , [ EIdentifier "d" ]+ ]+ ]+]+>>> starmath+matrix { a # b ## c # d }
+ test/writer/starmath/065_reserved_word_in_uptext_subscript_is_quoted.test view
@@ -0,0 +1,4 @@+<<< tex+y_{\mathrm{H_2,in}} = 1+>>> starmath+y_{nitalic{H_2,"in"}} = 1
+ test/writer/starmath/066_standalone_plus_minus_scripts_get_neutral_operands.test view
@@ -0,0 +1,4 @@+<<< tex+r_{r,e}=r_{r,e}^{+}-r_{r,e}^{-}+>>> starmath+r_{{r, e}} = r_{{r, e}}^{{} + {}} - r_{{r, e}}^{{} - {}}
+ test/writer/starmath/067_integral_default_limits_use_scripts.test view
@@ -0,0 +1,4 @@+<<< tex+\int_0^1 f(x)\,dx+>>> starmath+int_0^1 f(x) dx
+ test/writer/starmath/068_integral_limits_use_from_to.test view
@@ -0,0 +1,4 @@+<<< tex+\int\limits_0^1 f(x)\,dx+>>> starmath+int from 0 to 1 f(x) dx
+ test/writer/starmath/069_integral_nolimits_use_scripts.test view
@@ -0,0 +1,4 @@+<<< tex+\int\nolimits_0^1 f(x)\,dx+>>> starmath+int_0^1 f(x) dx
+ test/writer/starmath/07.test view
@@ -0,0 +1,27 @@+<<< native+[ ESuper (EIdentifier "u") (ESymbol Pun "\8243")+, ESymbol Bin "+"+, EIdentifier "p"+, ESymbol Open "("+, EIdentifier "x"+, ESymbol Close ")"+, ESuper (EIdentifier "u") (ESymbol Pun "\8242")+, ESymbol Bin "+"+, EIdentifier "q"+, ESymbol Open "("+, EIdentifier "x"+, ESymbol Close ")"+, EIdentifier "u"+, ESymbol Rel "="+, EIdentifier "f"+, ESymbol Open "("+, EIdentifier "x"+, ESymbol Close ")"+, ESymbol Pun ","+, ESpace (1 % 1)+, EIdentifier "x"+, ESymbol Rel ">"+, EIdentifier "a"+]+>>> starmath+u'' + p(x) u' + q(x) u = f(x), ~ x > a
+ test/writer/starmath/070_normal_fraction_display_inline_uses_inline_size.test view
@@ -0,0 +1,4 @@+<<< native+[ EFraction NormalFrac (EIdentifier "a") (EIdentifier "b") ]+>>> starmath-inline+size*0.7 {a over b}
+ test/writer/starmath/071_grouped_mathrm_alpha_subscripts_stay_structural.test view
@@ -0,0 +1,4 @@+<<< tex+n_{\mathrm{Fe_{bcc}}} + n_{\mathrm{Fe_{fcc}}}+>>> starmath+n_{nitalic{Fe_bcc}} + n_{nitalic{Fe_fcc}}
+ test/writer/starmath/08.test view
@@ -0,0 +1,32 @@+<<< native+[ ESymbol Open "|"+, EOver False (EIdentifier "z") (ESymbol Accent "\8254")+, ESymbol Open "|"+, ESymbol Rel "="+, ESymbol Open "|"+, EIdentifier "z"+, ESymbol Open "|"+, ESymbol Pun ","+, ESymbol Open "|"+, ESymbol Open "("+, EOver False (EIdentifier "z") (ESymbol Accent "\8254")+, ESuper (ESymbol Close ")") (EIdentifier "n")+, ESymbol Open "|"+, ESymbol Rel "="+, ESymbol Open "|"+, EIdentifier "z"+, ESuper (ESymbol Open "|") (EIdentifier "n")+, ESymbol Pun ","+, EMathOperator "arg"+, ESymbol Open "("+, ESuper (EIdentifier "z") (EIdentifier "n")+, ESymbol Close ")"+, ESymbol Rel "="+, EIdentifier "n"+, EMathOperator "arg"+, ESymbol Open "("+, EIdentifier "z"+, ESymbol Close ")"+]+>>> starmath+left lline bar z right rline = left lline z right rline, left lline (bar z )^n right rline = {left lline z right rline}^n, func arg(z^n) = n func arg(z)
+ test/writer/starmath/09.test view
@@ -0,0 +1,21 @@+<<< native+[ EUnder+ True+ (EMathOperator "lim")+ (EGrouped+ [ EIdentifier "z"+ , ESymbol Rel "\8594"+ , ESub (EIdentifier "z") (ENumber "0")+ ])+, EIdentifier "f"+, ESymbol Open "("+, EIdentifier "z"+, ESymbol Close ")"+, ESymbol Rel "="+, EIdentifier "f"+, ESymbol Open "("+, ESub (EIdentifier "z") (ENumber "0")+, ESymbol Close ")"+]+>>> starmath+lim from z toward z_0 f(z) = f(z_0)
+ test/writer/starmath/10.test view
@@ -0,0 +1,51 @@+<<< native+[ ESub (EIdentifier "\981") (EIdentifier "n")+, ESymbol Open "("+, EIdentifier "\954"+, ESymbol Close ")"+, ESymbol Rel "="+, EFraction+ NormalFrac+ (ENumber "1")+ (EGrouped+ [ ENumber "4"+ , ESuper (EIdentifier "\960") (ENumber "2")+ , ESuper (EIdentifier "\954") (ENumber "2")+ ])+, ESubsup (ESymbol Op "\8747") (ENumber "0") (ESymbol Ord "\8734")+, EFraction+ NormalFrac+ (EGrouped+ [ EMathOperator "sin"+ , ESymbol Open "("+ , EIdentifier "\954"+ , EIdentifier "R"+ , ESymbol Close ")"+ ])+ (EGrouped [ EIdentifier "\954" , EIdentifier "R" ])+, EFraction+ NormalFrac+ (ESymbol Ord "\8706")+ (EGrouped [ ESymbol Ord "\8706" , EIdentifier "R" ])+, EDelimited+ "["+ "]"+ [ Right (ESuper (EIdentifier "R") (ENumber "2"))+ , Right+ (EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8706"+ , ESub (EIdentifier "D") (EIdentifier "n")+ , ESymbol Open "("+ , EIdentifier "R"+ , ESymbol Close ")"+ ])+ (EGrouped [ ESymbol Ord "\8706" , EIdentifier "R" ]))+ ]+, ESpace (1 % 6)+, EIdentifier "d"+, EIdentifier "R"+]+>>> starmath+%iphi_n(%ikappa) = {1 over {4%ipi^2 %ikappa^2}}int_0^infinity {{sin(%ikappa R)} over {%ikappa R}}{partial over {partial R}}left [ R^2{{partial D_n(R)} over {partial R}} right ] dR
+ test/writer/starmath/11.test view
@@ -0,0 +1,28 @@+<<< native+[ ESub (EIdentifier "\981") (EIdentifier "n")+, ESymbol Open "("+, EIdentifier "\954"+, ESymbol Close ")"+, ESymbol Rel "="+, ENumber "0.033"+, ESubsup (EIdentifier "C") (EIdentifier "n") (ENumber "2")+, ESuper+ (EIdentifier "\954")+ (EGrouped+ [ ESymbol Ord "\8722"+ , ENumber "11"+ , ESymbol Ord "/"+ , ENumber "3"+ ])+, ESymbol Pun ","+, ESpace (1 % 1)+, EFraction+ NormalFrac (ENumber "1") (ESub (EIdentifier "L") (ENumber "0"))+, ESymbol Rel "\8810"+, EIdentifier "\954"+, ESymbol Rel "\8810"+, EFraction+ NormalFrac (ENumber "1") (ESub (EIdentifier "l") (ENumber "0"))+]+>>> starmath+%iphi_n(%ikappa) = 0.033C_n^2 %ikappa^{{- 11 / 3}}, ~ {1 over L_0} ll %ikappa ll {1 over l_0}
+ test/writer/starmath/12.test view
@@ -0,0 +1,35 @@+<<< native+[ EIdentifier "f"+, ESymbol Open "("+, EIdentifier "x"+, ESymbol Close ")"+, ESymbol Rel "="+, EDelimited+ "{"+ ""+ [ Right+ (EArray+ [ AlignLeft , AlignLeft ]+ [ [ [ ENumber "1" ]+ , [ ESymbol Ord "\8722"+ , ENumber "1"+ , ESymbol Rel "\8804"+ , EIdentifier "x"+ , ESymbol Rel "<"+ , ENumber "0"+ ]+ ]+ , [ [ EFraction NormalFrac (ENumber "1") (ENumber "2") ]+ , [ EIdentifier "x" , ESymbol Rel "=" , ENumber "0" ]+ ]+ , [ [ ENumber "1"+ , ESymbol Bin "\8722"+ , ESuper (EIdentifier "x") (ENumber "2")+ ]+ , [ EText TextNormal "otherwise" ]+ ]+ ])+ ]+]+>>> starmath+f(x) = left lbrace matrix { alignl 1 # alignl - 1 <= x < 0 ## alignl {{alignc 1} over {alignc 2}} # alignl x = 0 ## alignl 1 - x^2 # alignl "otherwise" } right none
+ test/writer/starmath/13.test view
@@ -0,0 +1,51 @@+<<< native+[ ESub (EGrouped []) (EIdentifier "p")+, ESub (EIdentifier "F") (EIdentifier "q")+, ESymbol Open "("+, ESub (EIdentifier "a") (ENumber "1")+, ESymbol Pun ","+, ESymbol Ord "\8230"+, ESymbol Pun ","+, ESub (EIdentifier "a") (EIdentifier "p")+, ESymbol Pun ";"+, ESub (EIdentifier "c") (ENumber "1")+, ESymbol Pun ","+, ESymbol Ord "\8230"+, ESymbol Pun ","+, ESub (EIdentifier "c") (EIdentifier "q")+, ESymbol Pun ";"+, EIdentifier "z"+, ESymbol Close ")"+, ESymbol Rel "="+, EUnderover+ True+ (ESymbol Op "\8721")+ (EGrouped [ EIdentifier "n" , ESymbol Rel "=" , ENumber "0" ])+ (ESymbol Ord "\8734")+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Open "("+ , ESub (EIdentifier "a") (ENumber "1")+ , ESub (ESymbol Close ")") (EIdentifier "n")+ , ESymbol Ord "\8943"+ , ESymbol Open "("+ , ESub (EIdentifier "a") (EIdentifier "p")+ , ESub (ESymbol Close ")") (EIdentifier "n")+ ])+ (EGrouped+ [ ESymbol Open "("+ , ESub (EIdentifier "c") (ENumber "1")+ , ESub (ESymbol Close ")") (EIdentifier "n")+ , ESymbol Ord "\8943"+ , ESymbol Open "("+ , ESub (EIdentifier "c") (EIdentifier "q")+ , ESub (ESymbol Close ")") (EIdentifier "n")+ ])+, EFraction+ NormalFrac+ (ESuper (EIdentifier "z") (EIdentifier "n"))+ (EGrouped [ EIdentifier "n" , ESymbol Ord "!" ])+]+>>> starmath+{}_p F_q(a_1, dotslow , a_p; c_1, dotslow , c_q; z) = sum from n = 0 to infinity {{(a_1 )_n dotsaxis (a_p )_n} over {(c_1 )_n dotsaxis (c_q )_n}}{z^n over {n ! }}
+ test/writer/starmath/14.test view
@@ -0,0 +1,7 @@+<<< native+[ EFraction NormalFrac (EIdentifier "a") (EIdentifier "b")+, ESpace (2 % 9)+, EFraction InlineFrac (EIdentifier "a") (EIdentifier "b")+]+>>> starmath+{a over b} size*0.7 {a over b}
+ test/writer/starmath/15.test view
@@ -0,0 +1,4 @@+<<< native+[ EFraction NormalFrac (EIdentifier "a") (ENumber "2") ]+>>> starmath+{a over 2}
+ test/writer/starmath/16.test view
@@ -0,0 +1,4 @@+<<< native+[ ENumber "3" , ESymbol Bin "\215" , ENumber "4" ]+>>> starmath+3 times 4
+ test/writer/starmath/17.test view
@@ -0,0 +1,11 @@+<<< native+[ EIdentifier "x"+, ESymbol Bin "*"+, ENumber "4"+, ESymbol Rel "="+, ENumber "4"+, ESymbol Bin "*"+, EIdentifier "x"+]+>>> starmath+x*4 = 4*x
+ test/writer/starmath/18.test view
@@ -0,0 +1,4 @@+<<< native+[ ENumber "1.3" , ESymbol Bin "\215" , ENumber ".2" ]+>>> starmath+1.3 times .2
+ test/writer/starmath/19.test view
@@ -0,0 +1,83 @@+<<< native+[ EDelimited+ "["+ "]"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ EFraction+ DisplayFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "x") (ENumber "1") ])+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "y") (ENumber "1") ])+ ]+ , [ EFraction+ DisplayFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "x") (ENumber "2") ])+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "y") (ENumber "1") ])+ ]+ ]+ , [ [ ESpace (2 % 9) ] ]+ , [ [ EFraction+ DisplayFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "x") (ENumber "1") ])+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "y") (ENumber "2") ])+ ]+ , [ EFraction+ DisplayFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "x") (ENumber "2") ])+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "y") (ENumber "2") ])+ ]+ ]+ ])+ ]+, EDelimited+ "("+ ")"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ ENumber "1" ] , [ ENumber "2" ] ]+ , [ [ ENumber "3" ] , [ ENumber "4" ] ]+ ])+ ]+, EDelimited+ "{"+ "}"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ ENumber "1" ] , [ ENumber "2" ] ]+ , [ [ ENumber "3" ] , [ ENumber "4" ] ]+ ])+ ]+, EDelimited+ "\8739"+ "\8739"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ ENumber "1" ] , [ ENumber "2" ] ]+ , [ [ ENumber "3" ] , [ ENumber "4" ] ]+ ])+ ]+, EDelimited+ "\8741"+ "\8741"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ ENumber "1" ] , [ ENumber "2" ] ]+ , [ [ ENumber "3" ] , [ ENumber "4" ] ]+ ])+ ]+]+>>> starmath+left [ matrix { {{partial x_1} over {partial y_1}} # {{partial x_2} over {partial y_1}} ## {} # {} ## {{partial x_1} over {partial y_2}} # {{partial x_2} over {partial y_2}} } right ] left ( matrix { 1 # 2 ## 3 # 4 } right ) left lbrace matrix { 1 # 2 ## 3 # 4 } right rbrace left lline matrix { 1 # 2 ## 3 # 4 } right rline left ldline matrix { 1 # 2 ## 3 # 4 } right rdline
+ test/writer/starmath/20.test view
@@ -0,0 +1,119 @@+<<< native+[ EStyled TextScript [ EIdentifier "A" ]+, EStyled TextScript [ EIdentifier "B" ]+, EStyled TextScript [ EIdentifier "C" ]+, EStyled TextScript [ EIdentifier "D" ]+, EStyled TextScript [ EIdentifier "E" ]+, EStyled TextScript [ EIdentifier "F" ]+, EStyled TextScript [ EIdentifier "G" ]+, EStyled TextScript [ EIdentifier "H" ]+, EStyled TextScript [ EIdentifier "I" ]+, EStyled TextScript [ EIdentifier "J" ]+, EStyled TextScript [ EIdentifier "K" ]+, EStyled TextScript [ EIdentifier "L" ]+, EStyled TextScript [ EIdentifier "M" ]+, EStyled TextScript [ EIdentifier "N" ]+, EStyled TextScript [ EIdentifier "O" ]+, EStyled TextScript [ EIdentifier "P" ]+, EStyled TextScript [ EIdentifier "Q" ]+, EStyled TextScript [ EIdentifier "R" ]+, EStyled TextScript [ EIdentifier "S" ]+, EStyled TextScript [ EIdentifier "T" ]+, EStyled TextScript [ EIdentifier "U" ]+, EStyled TextScript [ EIdentifier "V" ]+, EStyled TextScript [ EIdentifier "W" ]+, EStyled TextScript [ EIdentifier "X" ]+, EStyled TextScript [ EIdentifier "Y" ]+, EStyled TextScript [ EIdentifier "Z" ]+, EStyled TextScript [ EIdentifier "a" ]+, EStyled TextScript [ EIdentifier "b" ]+, EStyled TextScript [ EIdentifier "c" ]+, EStyled TextScript [ EIdentifier "d" ]+, EStyled TextScript [ EIdentifier "e" ]+, EStyled TextScript [ EIdentifier "f" ]+, EStyled TextScript [ EIdentifier "g" ]+, EStyled TextScript [ EIdentifier "h" ]+, EStyled TextScript [ EIdentifier "i" ]+, EStyled TextScript [ EIdentifier "j" ]+, EStyled TextScript [ EIdentifier "k" ]+, EStyled TextScript [ EIdentifier "l" ]+, EStyled TextScript [ EIdentifier "m" ]+, EStyled TextScript [ EIdentifier "n" ]+, EStyled TextScript [ EIdentifier "o" ]+, EStyled TextScript [ EIdentifier "p" ]+, EStyled TextScript [ EIdentifier "q" ]+, EStyled TextScript [ EIdentifier "r" ]+, EStyled TextScript [ EIdentifier "s" ]+, EStyled TextScript [ EIdentifier "t" ]+, EStyled TextScript [ EIdentifier "u" ]+, EStyled TextScript [ EIdentifier "v" ]+, EStyled TextScript [ EIdentifier "w" ]+, EStyled TextScript [ EIdentifier "x" ]+, EStyled TextScript [ EIdentifier "y" ]+, EStyled TextScript [ EIdentifier "z" ]+, EStyled TextDoubleStruck [ EIdentifier "A" ]+, EStyled TextDoubleStruck [ EIdentifier "B" ]+, EStyled TextDoubleStruck [ EIdentifier "C" ]+, EStyled TextDoubleStruck [ EIdentifier "D" ]+, EStyled TextDoubleStruck [ EIdentifier "E" ]+, EStyled TextDoubleStruck [ EIdentifier "F" ]+, EStyled TextDoubleStruck [ EIdentifier "G" ]+, EStyled TextDoubleStruck [ EIdentifier "H" ]+, EStyled TextDoubleStruck [ EIdentifier "I" ]+, EStyled TextDoubleStruck [ EIdentifier "J" ]+, EStyled TextDoubleStruck [ EIdentifier "K" ]+, EStyled TextDoubleStruck [ EIdentifier "L" ]+, EStyled TextDoubleStruck [ EIdentifier "M" ]+, EStyled TextDoubleStruck [ EIdentifier "N" ]+, EStyled TextDoubleStruck [ EIdentifier "O" ]+, EStyled TextDoubleStruck [ EIdentifier "P" ]+, EStyled TextDoubleStruck [ EIdentifier "Q" ]+, EStyled TextDoubleStruck [ EIdentifier "R" ]+, EStyled TextDoubleStruck [ EIdentifier "S" ]+, EStyled TextDoubleStruck [ EIdentifier "T" ]+, EStyled TextDoubleStruck [ EIdentifier "U" ]+, EStyled TextDoubleStruck [ EIdentifier "V" ]+, EStyled TextDoubleStruck [ EIdentifier "W" ]+, EStyled TextDoubleStruck [ EIdentifier "X" ]+, EStyled TextDoubleStruck [ EIdentifier "Y" ]+, EStyled TextDoubleStruck [ EIdentifier "Z" ]+, EStyled TextDoubleStruck [ EIdentifier "a" ]+, EStyled TextDoubleStruck [ EIdentifier "b" ]+, EStyled TextDoubleStruck [ EIdentifier "c" ]+, EStyled TextDoubleStruck [ EIdentifier "d" ]+, EStyled TextDoubleStruck [ EIdentifier "e" ]+, EStyled TextDoubleStruck [ EIdentifier "f" ]+, EStyled TextDoubleStruck [ EIdentifier "g" ]+, EStyled TextDoubleStruck [ EIdentifier "h" ]+, EStyled TextDoubleStruck [ EIdentifier "i" ]+, EStyled TextDoubleStruck [ EIdentifier "j" ]+, EStyled TextDoubleStruck [ EIdentifier "k" ]+, EStyled TextDoubleStruck [ EIdentifier "l" ]+, EStyled TextDoubleStruck [ EIdentifier "m" ]+, EStyled TextDoubleStruck [ EIdentifier "n" ]+, EStyled TextDoubleStruck [ EIdentifier "o" ]+, EStyled TextDoubleStruck [ EIdentifier "p" ]+, EStyled TextDoubleStruck [ EIdentifier "q" ]+, EStyled TextDoubleStruck [ EIdentifier "r" ]+, EStyled TextDoubleStruck [ EIdentifier "s" ]+, EStyled TextDoubleStruck [ EIdentifier "t" ]+, EStyled TextDoubleStruck [ EIdentifier "u" ]+, EStyled TextDoubleStruck [ EIdentifier "v" ]+, EStyled TextDoubleStruck [ EIdentifier "w" ]+, EStyled TextDoubleStruck [ EIdentifier "x" ]+, EStyled TextDoubleStruck [ EIdentifier "y" ]+, EStyled TextDoubleStruck [ EIdentifier "z" ]+, EStyled TextDoubleStruck [ ENumber "0" ]+, EStyled TextDoubleStruck [ ENumber "1" ]+, EStyled TextDoubleStruck [ ENumber "2" ]+, EStyled TextDoubleStruck [ ENumber "3" ]+, EStyled TextDoubleStruck [ ENumber "4" ]+, EStyled TextDoubleStruck [ ENumber "5" ]+, EStyled TextDoubleStruck [ ENumber "6" ]+, EStyled TextDoubleStruck [ ENumber "7" ]+, EStyled TextDoubleStruck [ ENumber "8" ]+, EStyled TextDoubleStruck [ ENumber "9" ]+, EStyled TextDoubleStruck [ ENumber "0" ]+]+>>> starmath+nitalic {𝒜 ℬ 𝒞 𝒟 ℰ ℱ 𝒢 ℋ ℐ 𝒥 𝒦 ℒ ℳ 𝒩 𝒪 𝒫 𝒬 ℛ 𝒮 𝒯 𝒰 𝒱 𝒲 𝒳 𝒴 𝒵 𝒶 𝒷 𝒸 𝒹 ℯ 𝒻 ℊ 𝒽 𝒾 𝒿 𝓀 𝓁 𝓂 𝓃 ℴ 𝓅 𝓆 𝓇 𝓈 𝓉 𝓊 𝓋 𝓌 𝓍 𝓎 𝓏} nitalic {𝔸 𝔹 ℂ 𝔻 𝔼 𝔽 𝔾 ℍ 𝕀 𝕁 𝕂 𝕃 𝕄 ℕ 𝕆 ℙ ℚ ℝ 𝕊 𝕋 𝕌 𝕍 𝕎 𝕏 𝕐 ℤ 𝕒 𝕓 𝕔 𝕕 𝕖 𝕗 𝕘 𝕙 𝕚 𝕛 𝕜 𝕝 𝕞 𝕟 𝕠 𝕡 𝕢 𝕣 𝕤 𝕥 𝕦 𝕧 𝕨 𝕩 𝕪 𝕫 𝟘 𝟙 𝟚 𝟛 𝟜 𝟝 𝟞 𝟟 𝟠 𝟡 𝟘}
+ test/writer/starmath/21.test view
@@ -0,0 +1,9 @@+<<< native+[ ESub (EIdentifier "e") (ENumber "1")+, ESymbol Rel "="+, ESuper (EIdentifier "b") (ENumber "2")+, ESymbol Bin "+"+, ESuper (EIdentifier "c") (ENumber "22")+]+>>> starmath+e_1 = b^2 + c^22
+ test/writer/starmath/22.test view
@@ -0,0 +1,256 @@+<<< native+[ EArray+ [ AlignLeft , AlignLeft ]+ [ [ [ EText TextMonospace "textrm" ]+ , [ EText TextNormal "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mathrm" ]+ , [ EStyled+ TextNormal+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathup" ]+ , [ EStyled+ TextNormal+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "text" ]+ , [ EText TextNormal "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mbox" ]+ , [ EText TextNormal "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mathbf" ]+ , [ EStyled+ TextNormal+ [ EStyled+ TextBold+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfup" ]+ , [ EStyled+ TextBold+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "textbf" ]+ , [ EText TextBold "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mathit" ]+ , [ EStyled+ TextItalic+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "textit" ]+ , [ EText TextItalic "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mathtt" ]+ , [ EStyled+ TextMonospace+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "texttt" ]+ , [ EText TextMonospace "ABCabc" ]+ ]+ , [ [ EText TextMonospace "mathsf" ]+ , [ EStyled+ TextSansSerif+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathsfup" ]+ , [ EStyled+ TextSansSerif+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbb" ]+ , [ EStyled+ TextDoubleStruck+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathcal" ]+ , [ EStyled+ TextScript+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathscr" ]+ , [ EStyled+ TextScript+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathfrak" ]+ , [ EStyled+ TextFraktur+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfit" ]+ , [ EStyled+ TextBoldItalic+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfsfup" ]+ , [ EStyled+ TextSansSerifBold+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfsfit" ]+ , [ EStyled+ TextSansSerifBoldItalic+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfscr" ]+ , [ EStyled+ TextBoldScript+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbffrak" ]+ , [ EStyled+ TextBoldFraktur+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathbfcal" ]+ , [ EStyled+ TextBoldScript+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ , [ [ EText TextMonospace "mathsfit" ]+ , [ EStyled+ TextSansSerifItalic+ [ EIdentifier "A"+ , EIdentifier "B"+ , EIdentifier "C"+ , EIdentifier "a"+ , EIdentifier "b"+ , EIdentifier "c"+ ]+ ]+ ]+ ]+]+>>> starmath+matrix { alignl font fixed "textrm" # alignl "ABCabc" ## alignl font fixed "mathrm" # alignl "ABCabc" ## alignl font fixed "mathup" # alignl "ABCabc" ## alignl font fixed "text" # alignl "ABCabc" ## alignl font fixed "mbox" # alignl "ABCabc" ## alignl font fixed "mathbf" # alignl bold nitalic {ABCabc} ## alignl font fixed "mathbfup" # alignl bold nitalic {ABCabc} ## alignl font fixed "textbf" # alignl bold {"ABCabc"} ## alignl font fixed "mathit" # alignl ital {ABCabc} ## alignl font fixed "textit" # alignl ital {ABCabc} ## alignl font fixed "mathtt" # alignl font fixed nitalic {ABCabc} ## alignl font fixed "texttt" # alignl font fixed "ABCabc" ## alignl font fixed "mathsf" # alignl font sans nitalic {ABCabc} ## alignl font fixed "mathsfup" # alignl font sans nitalic {ABCabc} ## alignl font fixed "mathbb" # alignl nitalic {𝔸𝔹ℂ𝕒𝕓𝕔} ## alignl font fixed "mathcal" # alignl nitalic {𝒜ℬ𝒞𝒶𝒷𝒸} ## alignl font fixed "mathscr" # alignl nitalic {𝒜ℬ𝒞𝒶𝒷𝒸} ## alignl font fixed "mathfrak" # alignl nitalic {𝔄𝔅ℭ𝔞𝔟𝔠} ## alignl font fixed "mathbfit" # alignl bold {ital {ABCabc}} ## alignl font fixed "mathbfsfup" # alignl bold {font sans nitalic {ABCabc}} ## alignl font fixed "mathbfsfit" # alignl bold {font sans ital {ABCabc}} ## alignl font fixed "mathbfscr" # alignl nitalic {𝓐𝓑𝓒𝓪𝓫𝓬} ## alignl font fixed "mathbffrak" # alignl nitalic {𝕬𝕭𝕮𝖆𝖇𝖈} ## alignl font fixed "mathbfcal" # alignl nitalic {𝓐𝓑𝓒𝓪𝓫𝓬} ## alignl font fixed "mathsfit" # alignl font sans ital {ABCabc} }
+ test/writer/starmath/23.test view
@@ -0,0 +1,4 @@+<<< native+[ ENumber "1" , ESymbol Ord "." ]+>>> starmath+1.
+ test/writer/starmath/axiom_of_power_set.test view
@@ -0,0 +1,31 @@+<<< native+[ ESymbol Op "\8704"+, EIdentifier "A"+, ESpace (1 % 6)+, ESymbol Op "\8707"+, EIdentifier "P"+, ESpace (1 % 6)+, ESymbol Op "\8704"+, EIdentifier "B"+, ESpace (1 % 6)+, ESymbol Open "["+, EIdentifier "B"+, ESymbol Rel "\8712"+, EIdentifier "P"+, ESymbol Rel "\8660"+, ESymbol Op "\8704"+, EIdentifier "C"+, ESpace (1 % 6)+, ESymbol Open "("+, EIdentifier "C"+, ESymbol Rel "\8712"+, EIdentifier "B"+, ESymbol Rel "\8658"+, EIdentifier "C"+, ESymbol Rel "\8712"+, EIdentifier "A"+, ESymbol Close ")"+, ESymbol Close "]"+]+>>> starmath+forall A exists P forall B [B in P dlrarrow forall C (C in B drarrow C in A)]
+ test/writer/starmath/binomial_coefficient.test view
@@ -0,0 +1,41 @@+<<< native+[ EStyled TextNormal [ EStyled TextBold [ EIdentifier "C" ] ]+, ESymbol Open "("+, EIdentifier "n"+, ESymbol Pun ","+, EIdentifier "k"+, ESymbol Close ")"+, ESymbol Rel "="+, ESubsup+ (EStyled TextNormal [ EStyled TextBold [ EIdentifier "C" ] ])+ (EIdentifier "k")+ (EIdentifier "n")+, ESymbol Rel "="+, ESub (EGrouped []) (EIdentifier "n")+, ESub+ (EStyled TextNormal [ EStyled TextBold [ EIdentifier "C" ] ])+ (EIdentifier "k")+, ESymbol Rel "="+, EDelimited+ "("+ ")"+ [ Right (EFraction NoLineFrac (EIdentifier "n") (EIdentifier "k"))+ ]+, ESymbol Rel "="+, EFraction+ NormalFrac+ (EGrouped [ EIdentifier "n" , ESymbol Ord "!" ])+ (EGrouped+ [ EIdentifier "k"+ , ESymbol Ord "!"+ , ESpace (1 % 6)+ , ESymbol Open "("+ , EIdentifier "n"+ , ESymbol Bin "\8722"+ , EIdentifier "k"+ , ESymbol Close ")"+ , ESymbol Ord "!"+ ])+]+>>> starmath+bold nitalic C(n, k) = {bold nitalic C}_k^n = {}_n {bold nitalic C}_k = left ( binom{n}{k} right ) = {{n ! } over {k ! (n - k) ! }}
+ test/writer/starmath/boxed.test view
@@ -0,0 +1,12 @@+<<< native+[ EBoxed+ (EGrouped+ [ ESuper (EIdentifier "x") (ENumber "2")+ , ESymbol Bin "+"+ , ESuper (EIdentifier "y") (ENumber "2")+ , ESymbol Bin "+"+ , ESuper (EIdentifier "z") (ENumber "2")+ ])+]+>>> starmath+\boxed{x^{2} + y^{2} + z^{2}}
+ test/writer/starmath/cancel.test view
@@ -0,0 +1,12 @@+<<< native+[ EBoxed+ (EGrouped+ [ ECancel ForwardSlash (EIdentifier "x")+ , ESymbol Bin "+"+ , ECancel BackSlash (EIdentifier "y")+ , ESymbol Rel "="+ , ECancel XSlash (EIdentifier "z")+ ])+]+>>> starmath+\boxed{\cancel{x} + \bcancel{y} = \xcancel{z}}
+ test/writer/starmath/choose.test view
@@ -0,0 +1,21 @@+<<< native+[ EDelimited+ "("+ ")"+ [ Right+ (EFraction+ NoLineFrac+ (EIdentifier "a")+ (EDelimited+ "{"+ "}"+ [ Right+ (EFraction+ NoLineFrac+ (EIdentifier "b")+ (EGrouped [ EIdentifier "c" , ESymbol Bin "+" , ENumber "2" ]))+ ]))+ ]+]+>>> starmath+left ( binom{a}{left lbrace binom{b}{c + 2} right rbrace} right )
+ test/writer/starmath/complex_number.test view
@@ -0,0 +1,27 @@+<<< native+[ EIdentifier "c"+, ESymbol Rel "="+, EOver+ False+ (EOver+ False+ (EGrouped+ [ EUnder+ False+ (EUnder False (EIdentifier "a") (ESymbol TUnder "\9183"))+ (EText TextNormal "real")+ , ESymbol Bin "+"+ , EUnder+ False+ (EUnder+ False+ (EGrouped+ [ EIdentifier "b" , EStyled TextNormal [ EIdentifier "i" ] ])+ (ESymbol TUnder "\9183"))+ (EText TextNormal "imaginary")+ ])+ (ESymbol TOver "\9182"))+ (EText TextNormal "complex number")+]+>>> starmath+c = {a underbrace "real" + {b nitalic i} underbrace "imaginary"} overbrace "complex number"
+ test/writer/starmath/cospan.test view
@@ -0,0 +1,11 @@+<<< native+[ EIdentifier "B"+, EUnderover+ False (ESymbol Op "\8594") (EIdentifier "f") (EGrouped [])+, EIdentifier "A"+, EUnderover+ False (ESymbol Op "\8592") (EIdentifier "f") (EGrouped [])+, EIdentifier "C"+]+>>> starmath+B toward csub {f} A leftarrow csub {f} C
+ test/writer/starmath/deMorgans_law.test view
@@ -0,0 +1,41 @@+<<< native+[ ESymbol Op "\172"+, ESymbol Open "("+, EIdentifier "p"+, ESymbol Bin "\8743"+, EIdentifier "q"+, ESymbol Close ")"+, ESymbol Rel "\8660"+, ESymbol Open "("+, ESymbol Op "\172"+, EIdentifier "p"+, ESymbol Close ")"+, ESymbol Bin "\8744"+, ESymbol Open "("+, ESymbol Op "\172"+, EIdentifier "q"+, ESymbol Close ")"+, EOver+ False+ (EGrouped+ [ EUnderover+ True+ (ESymbol Op "\8899")+ (EGrouped [ EIdentifier "i" , ESymbol Rel "=" , ENumber "1" ])+ (EIdentifier "n")+ , ESub (EIdentifier "A") (EIdentifier "i")+ ])+ (ESymbol TOver "\175")+, ESymbol Rel "="+, EUnderover+ True+ (ESymbol Op "\8898")+ (EGrouped [ EIdentifier "i" , ESymbol Rel "=" , ENumber "1" ])+ (EIdentifier "n")+, EOver+ False+ (ESub (EIdentifier "A") (EIdentifier "i"))+ (ESymbol TOver "\175")+]+>>> starmath+neg (p and q) dlrarrow (neg p) or (neg q) overline {{oper ∪ from i = 1 to n A_i}} = oper ∩ from i = 1 to n overline {A_i}
+ test/writer/starmath/differentiable_manifold.test view
@@ -0,0 +1,70 @@+<<< native+[ ESub (EIdentifier "\947") (ENumber "1")+, ESymbol Rel "\8801"+, ESub (EIdentifier "\947") (ENumber "2")+, ESymbol Rel "\8660"+, EDelimited+ "{"+ ""+ [ Right+ (EArray+ [ AlignLeft ]+ [ [ [ ESub (EIdentifier "\947") (ENumber "1")+ , ESymbol Open "("+ , ENumber "0"+ , ESymbol Close ")"+ , ESymbol Rel "="+ , ESub (EIdentifier "\947") (ENumber "2")+ , ESymbol Open "("+ , ENumber "0"+ , ESymbol Close ")"+ , ESymbol Rel "="+ , EIdentifier "p"+ , ESymbol Pun ","+ , EText TextNormal " and "+ ]+ ]+ , [ [ ESub+ (EDelimited+ ""+ "|"+ [ Right+ (EFraction+ NormalFrac+ (EStyled TextNormal [ EIdentifier "d" ])+ (EGrouped+ [ EStyled TextNormal [ EIdentifier "d" ] , EIdentifier "t" ]))+ , Right (EIdentifier "\981")+ , Right (ESymbol Bin "\8728")+ , Right (ESub (EIdentifier "\947") (ENumber "1"))+ , Right (ESymbol Open "(")+ , Right (EIdentifier "t")+ , Right (ESymbol Close ")")+ ])+ (EGrouped [ EIdentifier "t" , ESymbol Rel "=" , ENumber "0" ])+ , ESymbol Rel "="+ , ESub+ (EDelimited+ ""+ "|"+ [ Right+ (EFraction+ NormalFrac+ (EStyled TextNormal [ EIdentifier "d" ])+ (EGrouped+ [ EStyled TextNormal [ EIdentifier "d" ] , EIdentifier "t" ]))+ , Right (EIdentifier "\981")+ , Right (ESymbol Bin "\8728")+ , Right (ESub (EIdentifier "\947") (ENumber "2"))+ , Right (ESymbol Open "(")+ , Right (EIdentifier "t")+ , Right (ESymbol Close ")")+ ])+ (EGrouped [ EIdentifier "t" , ESymbol Rel "=" , ENumber "0" ])+ ]+ ]+ ])+ ]+]+>>> starmath+%igamma_1 equiv %igamma_2 dlrarrow left lbrace matrix { alignl %igamma_1(0) = %igamma_2(0) = p, " and " ## alignl {left none {{alignc {nitalic d}} over {alignc {nitalic dt}}}%iphi circ %igamma_1(t) right rline}_{{t = 0}} = {left none {{alignc {nitalic d}} over {alignc {nitalic dt}}}%iphi circ %igamma_2(t) right rline}_{{t = 0}} } right none
+ test/writer/starmath/divergence.test view
@@ -0,0 +1,25 @@+<<< native+[ ESymbol Ord "\8711"+, ESymbol Bin "\8901"+, EOver False (EIdentifier "v") (ESymbol Accent "\8407")+, ESymbol Rel "="+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "v") (EIdentifier "x") ])+ (EGrouped [ ESymbol Ord "\8706" , EIdentifier "x" ])+, ESymbol Bin "+"+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "v") (EIdentifier "y") ])+ (EGrouped [ ESymbol Ord "\8706" , EIdentifier "y" ])+, ESymbol Bin "+"+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8706" , ESub (EIdentifier "v") (EIdentifier "z") ])+ (EGrouped [ ESymbol Ord "\8706" , EIdentifier "z" ])+]+>>> starmath+nabla cdot vec v = {{partial v_x} over {partial x}} + {{partial v_y} over {partial y}} + {{partial v_z} over {partial z}}
+ test/writer/starmath/ensuremath.test view
@@ -0,0 +1,4 @@+<<< native+[ ESuper (EIdentifier "\960") (ENumber "2") ]+>>> starmath+%ipi^2
+ test/writer/starmath/genfrac.test view
@@ -0,0 +1,9 @@+<<< native+[ EDelimited+ "{"+ "}"+ [ Right (EFraction NoLineFrac (EIdentifier "x") (EIdentifier "y"))+ ]+]+>>> starmath+left lbrace binom{x}{y} right rbrace
+ test/writer/starmath/issue109.test view
@@ -0,0 +1,11 @@+<<< native+[ EIdentifier "a"+, ESymbol Rel ">"+, EIdentifier "b"+, ESymbol Rel "or"+, EIdentifier "a"+, ESymbol Rel ">"+, EIdentifier "c"+]+>>> starmath+a > b "or" a > c
+ test/writer/starmath/issue204.test view
@@ -0,0 +1,7 @@+<<< native+[ EIdentifier "a"+, ESub (ESymbol Rel "\8829") (EIdentifier "i")+, EIdentifier "b"+]+>>> starmath+a≽_i b
+ test/writer/starmath/issue229.test view
@@ -0,0 +1,13 @@+<<< native+[ EArray+ [ AlignLeft , AlignRight , AlignCenter , AlignRight , AlignCenter ]+ [ [ [ ENumber "1" ]+ , [ ENumber "2" ]+ , [ ENumber "3" ]+ , [ ENumber "4" ]+ , [ ENumber "5" ]+ ]+ ]+]+>>> starmath+matrix { alignl 1 # alignr 2 # alignc 3 # alignr 4 # alignc 5 }
+ test/writer/starmath/labels.test view
@@ -0,0 +1,4 @@+<<< native+[ ENumber "2" , ESymbol Bin "+" , ENumber "2" ]+>>> starmath+2 + 2
+ test/writer/starmath/macros.test view
@@ -0,0 +1,15 @@+<<< native+[ ENumber "2"+, ENumber "5"+, EGrouped [ EIdentifier "y" , ESymbol Bin "+" , ENumber "3" ]+, EGrouped [ EIdentifier "x" , ESymbol Bin "+" , ENumber "3" ]+, EGrouped+ [ EIdentifier "x" , ESymbol Bin "+" , EIdentifier "\945" ]+, EArray+ [ AlignCenter , AlignCenter ]+ [ [ [ ENumber "2" ] , [ ENumber "3" ] ]+ , [ [ ENumber "4" ] , [ ENumber "5" ] ]+ ]+]+>>> starmath+25{y + 3}{x + 3}{x + %ialpha}matrix { 2 # 3 ## 4 # 5 }
+ test/writer/starmath/math-in-text.test view
@@ -0,0 +1,20 @@+<<< native+[ ESuper (EIdentifier "X") (ENumber "2")+, ESymbol Rel "="+, EIdentifier "y"+, EGrouped+ [ EText TextNormal " under "+ , ESub (EIdentifier "H") (ENumber "0")+ , EText TextNormal " except when "+ , EGrouped+ [ EIdentifier "x"+ , EGrouped+ [ EText TextBold " is less than "+ , EIdentifier "z"+ , EText TextBold "."+ ]+ ]+ ]+]+>>> starmath+X^2 = y{" under "H_0" except when "{x{bold {" is less than "}z bold {"."}}}}
+ test/writer/starmath/moore_determinant.test view
@@ -0,0 +1,54 @@+<<< native+[ EIdentifier "M"+, ESymbol Rel "="+, EDelimited+ "["+ "]"+ [ Right+ (EArray+ [ AlignCenter , AlignCenter , AlignCenter , AlignCenter ]+ [ [ [ ESub (EIdentifier "\945") (ENumber "1") ]+ , [ ESubsup (EIdentifier "\945") (ENumber "1") (EIdentifier "q") ]+ , [ ESymbol Ord "\8943" ]+ , [ ESubsup+ (EIdentifier "\945")+ (ENumber "1")+ (ESuper+ (EIdentifier "q")+ (EGrouped [ EIdentifier "n" , ESymbol Bin "\8722" , ENumber "1" ]))+ ]+ ]+ , [ [ ESub (EIdentifier "\945") (ENumber "2") ]+ , [ ESubsup (EIdentifier "\945") (ENumber "2") (EIdentifier "q") ]+ , [ ESymbol Ord "\8943" ]+ , [ ESubsup+ (EIdentifier "\945")+ (ENumber "2")+ (ESuper+ (EIdentifier "q")+ (EGrouped [ EIdentifier "n" , ESymbol Bin "\8722" , ENumber "1" ]))+ ]+ ]+ , [ [ ESymbol Ord "\8942" ]+ , [ ESymbol Ord "\8942" ]+ , [ ESymbol Rel "\8945" ]+ , [ ESymbol Ord "\8942" ]+ ]+ , [ [ ESub (EIdentifier "\945") (EIdentifier "m") ]+ , [ ESubsup+ (EIdentifier "\945") (EIdentifier "m") (EIdentifier "q")+ ]+ , [ ESymbol Ord "\8943" ]+ , [ ESubsup+ (EIdentifier "\945")+ (EIdentifier "m")+ (ESuper+ (EIdentifier "q")+ (EGrouped [ EIdentifier "n" , ESymbol Bin "\8722" , ENumber "1" ]))+ ]+ ]+ ])+ ]+]+>>> starmath+M = left [ matrix { %ialpha_1 # %ialpha_1^q # dotsaxis # %ialpha_1^{q^{{n - 1}}} ## %ialpha_2 # %ialpha_2^q # dotsaxis # %ialpha_2^{q^{{n - 1}}} ## dotsvert # dotsvert # {} dotsdown {} # dotsvert ## %ialpha_m # %ialpha_m^q # dotsaxis # %ialpha_m^{q^{{n - 1}}} } right ]
+ test/writer/starmath/notin.test view
@@ -0,0 +1,11 @@+<<< native+[ EIdentifier "x"+, ESymbol Rel "\8712"+, EIdentifier "y"+, ESymbol Bin "\8743"+, EIdentifier "x"+, ESymbol Rel "\8713"+, EIdentifier "y"+]+>>> starmath+x in y and x notin y
+ test/writer/starmath/operatorname.test view
@@ -0,0 +1,71 @@+<<< native+[ EDelimited+ "{"+ ""+ [ Right+ (EArray+ [ AlignLeft , AlignLeft ]+ [ [ [ ESub (EMathOperator "div") (EIdentifier "x")+ , EIdentifier "u"+ , ESuper (EMathOperator "div") (EIdentifier "x")+ , EIdentifier "u"+ , ESubsup (EMathOperator "div") (EIdentifier "x") (EIdentifier "y")+ , EIdentifier "u"+ , ESubsup (EMathOperator "div") (EIdentifier "x") (EIdentifier "y")+ , EIdentifier "u"+ ]+ , [ EText TextNormal "operatorname" ]+ ]+ , [ [ EUnder+ True+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ , EIdentifier "u"+ , EOver True (EMathOperator "\8902-lim'sup") (EIdentifier "w")+ , EIdentifier "u"+ , EUnderover+ True+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ (EIdentifier "w")+ , EIdentifier "u"+ , EUnderover+ True+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ (EIdentifier "w")+ , EIdentifier "u"+ ]+ , [ EText TextNormal "operatorname*" ]+ ]+ , [ [ ESub+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ , EIdentifier "u"+ , ESuper (EMathOperator "\8902-lim'sup") (EIdentifier "w")+ , EIdentifier "u"+ , ESubsup+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ (EIdentifier "w")+ , EIdentifier "u"+ , ESubsup+ (EMathOperator "\8902-lim'sup")+ (EGrouped [ EIdentifier "x" , ESymbol Rel "\8594" , ENumber "0" ])+ (EIdentifier "w")+ , EIdentifier "u"+ ]+ , [ EText TextNormal "operatorname*:nolimits" ]+ ]+ , [ [ ESub (EMathOperator "curl") (EIdentifier "x")+ , EIdentifier "v"+ , EUnder True (EMathOperator "argmax") (EIdentifier "K")+ , EIdentifier "u"+ ]+ , [ EText TextNormal "DeclareMathOperator" ]+ ]+ ])+ ]+]+>>> starmath+left lbrace matrix { alignl func div_x u func div^x u func div_x^y u func div_x^y u # alignl "operatorname" ## alignl {func "⋆-lim'sup"} csub {{x toward 0}} u {func "⋆-lim'sup"} csup {w} u {func "⋆-lim'sup"} csub {{x toward 0}} csup {w} u {func "⋆-lim'sup"} csub {{x toward 0}} csup {w} u # alignl "operatorname*" ## alignl func "⋆-lim'sup"_{{x toward 0}} u func "⋆-lim'sup"^w u func "⋆-lim'sup"_{{x toward 0}}^w u func "⋆-lim'sup"_{{x toward 0}}^w u # alignl "operatorname*:nolimits" ## alignl func curl_x v {func argmax} csub {K} u # alignl "DeclareMathOperator" } right none
+ test/writer/starmath/phantom.test view
@@ -0,0 +1,10 @@+<<< native+[ EDelimited+ "("+ ")"+ [ Right+ (EPhantom (EFraction NormalFrac (ENumber "1") (ENumber "2")))+ ]+]+>>> starmath+left ( phantom {1 over 2} right )
+ test/writer/starmath/quadratic_formula.test view
@@ -0,0 +1,22 @@+<<< native+[ EIdentifier "x"+, ESymbol Rel "="+, EFraction+ NormalFrac+ (EGrouped+ [ ESymbol Ord "\8722"+ , EIdentifier "b"+ , ESymbol Bin "\177"+ , ESqrt+ (EGrouped+ [ ESuper (EIdentifier "b") (ENumber "2")+ , ESymbol Bin "\8722"+ , ENumber "4"+ , EIdentifier "a"+ , EIdentifier "c"+ ])+ ])+ (EGrouped [ ENumber "2" , EIdentifier "a" ])+]+>>> starmath+x = {{- b plusminus sqrt {{b^2 - 4ac}}} over {2a}}
+ test/writer/starmath/schwinger_dyson.test view
@@ -0,0 +1,63 @@+<<< native+[ EDelimited+ "\10216"+ "\10217"+ [ Right (EIdentifier "\968")+ , Right+ (EDelimited+ "|"+ "|"+ [ Right (EStyled TextScript [ EIdentifier "T" ])+ , Right+ (EDelimited+ "{"+ "}"+ [ Right+ (EFraction+ NormalFrac+ (EIdentifier "\948")+ (EGrouped [ EIdentifier "\948" , EIdentifier "\981" ]))+ , Right (EIdentifier "F")+ , Right (ESymbol Open "[")+ , Right (EIdentifier "\981")+ , Right (ESymbol Close "]")+ ])+ ])+ , Right (EIdentifier "\968")+ ]+, ESymbol Rel "="+, ESymbol Ord "\8722"+, EStyled TextNormal [ EIdentifier "i" ]+, EDelimited+ "\10216"+ "\10217"+ [ Right (EIdentifier "\968")+ , Right+ (EDelimited+ "|"+ "|"+ [ Right (EStyled TextScript [ EIdentifier "T" ])+ , Right+ (EDelimited+ "{"+ "}"+ [ Right (EIdentifier "F")+ , Right (ESymbol Open "[")+ , Right (EIdentifier "\981")+ , Right (ESymbol Close "]")+ , Right+ (EFraction+ NormalFrac+ (EIdentifier "\948")+ (EGrouped [ EIdentifier "\948" , EIdentifier "\981" ]))+ , Right (EIdentifier "S")+ , Right (ESymbol Open "[")+ , Right (EIdentifier "\981")+ , Right (ESymbol Close "]")+ ])+ ])+ , Right (EIdentifier "\968")+ ]+]+>>> starmath+left langle %ipsi left lline nitalic 𝒯 left lbrace {%idelta over {%idelta %iphi}}F[%iphi] right rbrace right rline %ipsi right rangle = - nitalic i left langle %ipsi left lline nitalic 𝒯 left lbrace F[%iphi]{%idelta over {%idelta %iphi}}S[%iphi] right rbrace right rline %ipsi right rangle
+ test/writer/starmath/simple_sum_formula.test view
@@ -0,0 +1,15 @@+<<< native+[ EUnderover+ True+ (ESymbol Op "\8721")+ (EGrouped [ EIdentifier "i" , ESymbol Rel "=" , ENumber "1" ])+ (ENumber "100")+, EIdentifier "x"+, ESymbol Rel "="+, EFraction+ NormalFrac+ (EGrouped [ ENumber "100" , ESymbol Bin "*" , ENumber "101" ])+ (ENumber "2")+]+>>> starmath+sum from i = 1 to 100 x = {{100*101} over 2}
+ test/writer/starmath/sophomores_dream.test view
@@ -0,0 +1,27 @@+<<< native+[ ESubsup (ESymbol Op "\8747") (ENumber "0") (ENumber "1")+, ESuper (EIdentifier "x") (EIdentifier "x")+, ESpace (1 % 6)+, EStyled TextNormal [ EIdentifier "d" ]+, EIdentifier "x"+, ESymbol Rel "="+, EUnderover+ True+ (ESymbol Op "\8721")+ (EGrouped [ EIdentifier "n" , ESymbol Rel "=" , ENumber "1" ])+ (ESymbol Ord "\8734")+, EGrouped+ [ ESymbol Open "("+ , ESymbol Ord "\8722"+ , ENumber "1"+ , ESuper+ (ESymbol Close ")")+ (EGrouped [ EIdentifier "n" , ESymbol Bin "+" , ENumber "1" ])+ , ESpace (1 % 6)+ , ESuper+ (EIdentifier "n")+ (EGrouped [ ESymbol Ord "\8722" , EIdentifier "n" ])+ ]+]+>>> starmath+int_0^1 x^x nitalic dx = sum from n = 1 to infinity {(- 1)^{{n + 1}} n^{{- n}}}
+ test/writer/starmath/span.test view
@@ -0,0 +1,9 @@+<<< native+[ EIdentifier "Y"+, EOver False (ESymbol Op "\8592") (EIdentifier "f")+, EIdentifier "X"+, EOver False (ESymbol Op "\8594") (EIdentifier "g")+, EIdentifier "Z"+]+>>> starmath+Y leftarrow csup {f} X toward csup {g} Z
+ test/writer/starmath/sphere_volume.test view
@@ -0,0 +1,127 @@+<<< native+[ EIdentifier "S"+, ESymbol Rel "="+, ESymbol Open "{"+, ENumber "0"+, ESymbol Rel "\8804"+, EIdentifier "\981"+, ESymbol Rel "\8804"+, ENumber "2"+, EIdentifier "\960"+, ESymbol Pun ","+, ESpace (2 % 9)+, ENumber "0"+, ESymbol Rel "\8804"+, EIdentifier "\952"+, ESymbol Rel "\8804"+, EIdentifier "\960"+, ESymbol Pun ","+, ESpace (2 % 9)+, ENumber "0"+, ESymbol Rel "\8804"+, EIdentifier "\961"+, ESymbol Rel "\8804"+, EIdentifier "R"+, ESymbol Close "}"+, EArray+ [ AlignRight , AlignLeft ]+ [ [ [ EStyled+ TextNormal+ [ EIdentifier "V"+ , EIdentifier "o"+ , EIdentifier "l"+ , EIdentifier "u"+ , EIdentifier "m"+ , EIdentifier "e"+ ]+ ]+ , [ ESymbol Rel "="+ , EUnder False (ESymbol Op "\8749") (EIdentifier "S")+ , ESpace ((-1) % 6)+ , ESuper (EIdentifier "\961") (ENumber "2")+ , EMathOperator "sin"+ , EIdentifier "\952"+ , ESpace (1 % 6)+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\961"+ , ESpace (1 % 6)+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\952"+ , ESpace (1 % 6)+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\981"+ ]+ ]+ , [ []+ , [ ESymbol Rel "="+ , ESubsup+ (ESymbol Op "\8747")+ (ENumber "0")+ (EGrouped [ ENumber "2" , EIdentifier "\960" ])+ , ESpace ((-1) % 6)+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\981"+ , ESpace (1 % 6)+ , ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "\960")+ , ESpace ((-1) % 6)+ , EMathOperator "sin"+ , EIdentifier "\952"+ , ESpace (1 % 6)+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\952"+ , ESpace (1 % 6)+ , ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "R")+ , ESpace ((-1) % 6)+ , ESuper (EIdentifier "\961") (ENumber "2")+ , EStyled TextNormal [ EIdentifier "d" ]+ , EIdentifier "\961"+ ]+ ]+ , [ []+ , [ ESymbol Rel "="+ , EIdentifier "\981"+ , ESubsup+ (EScaled (9 % 5) (ESymbol Open "|"))+ (ENumber "0")+ (EGrouped [ ENumber "2" , EIdentifier "\960" ])+ , ESpace (2 % 9)+ , ESymbol Open "("+ , ESymbol Ord "\8722"+ , EMathOperator "cos"+ , EIdentifier "\952"+ , ESymbol Close ")"+ , ESubsup+ (EScaled (9 % 5) (ESymbol Open "|"))+ (ENumber "0")+ (EIdentifier "\960")+ , ESpace (2 % 9)+ , EFraction InlineFrac (ENumber "1") (ENumber "3")+ , ESuper (EIdentifier "\961") (ENumber "3")+ , ESubsup+ (EScaled (9 % 5) (ESymbol Open "|"))+ (ENumber "0")+ (EIdentifier "R")+ ]+ ]+ , [ []+ , [ ESymbol Rel "="+ , ENumber "2"+ , EIdentifier "\960"+ , ESymbol Bin "\215"+ , ENumber "2"+ , ESymbol Bin "\215"+ , EFraction InlineFrac (ENumber "1") (ENumber "3")+ , ESuper (EIdentifier "R") (ENumber "3")+ ]+ ]+ , [ []+ , [ ESymbol Rel "="+ , EFraction InlineFrac (ENumber "4") (ENumber "3")+ , EIdentifier "\960"+ , ESuper (EIdentifier "R") (ENumber "3")+ ]+ ]+ ]+]+>>> starmath+S = left lbrace 0 <= %iphi <= 2%ipi , 0 <= %itheta <= %ipi , 0 <= %irho <= R right rbrace matrix { alignr "Volume" # alignl {} = iiint from S %irho^2 sin %itheta nitalic d%irho nitalic d%itheta nitalic d%iphi ## alignr {} # alignl {} = int_0^{{2%ipi}} nitalic d%iphi int_0^%ipi sin %itheta nitalic d%itheta int_0^R %irho^2 nitalic d%irho ## alignr {} # alignl {} = {left none %iphi right rline}_0^{{2%ipi}} {left none left ( - cos %itheta right ) right rline}_0^%ipi size*0.7 {{alignc 1} over {alignc 3}}{left none %irho^3 right rline}_0^R ## alignr {} # alignl {} = 2%ipi times 2 times size*0.7 {{alignc 1} over {alignc 3}}R^3 ## alignr {} # alignl {} = size*0.7 {{alignc 4} over {alignc 3}}%ipi R^3 }
+ test/writer/starmath/stackrel.test view
@@ -0,0 +1,7 @@+<<< native+[ ESub (EIdentifier "u") (EIdentifier "n")+, EOver False (ESymbol Rel "\8594") (EIdentifier "w")+, EIdentifier "u"+]+>>> starmath+u_n toward csup {w} u
+ test/writer/starmath/substack.test view
@@ -0,0 +1,34 @@+<<< native+[ EUnder+ True+ (ESymbol Op "\8721")+ (EArray+ [ AlignCenter ]+ [ [ [ EGrouped+ [ ENumber "0"+ , ESymbol Rel "<"+ , EIdentifier "i"+ , ESymbol Rel "<"+ , EIdentifier "m"+ ]+ ]+ ]+ , [ [ EGrouped+ [ ENumber "0"+ , ESymbol Rel "<"+ , EIdentifier "j"+ , ESymbol Rel "<"+ , EIdentifier "n"+ ]+ ]+ ]+ ])+, EIdentifier "P"+, ESymbol Open "("+, EIdentifier "i"+, ESymbol Pun ","+, EIdentifier "j"+, ESymbol Close ")"+]+>>> starmath+sum from matrix { {0 < i < m} ## {0 < j < n} } P(i, j)
+ test/writer/starmath/subsup.test view
@@ -0,0 +1,68 @@+<<< native+[ ESubsup (EIdentifier "x") (EIdentifier "b") (EIdentifier "a")+, ESpace (1 % 1)+, ESubsup (EIdentifier "x") (EIdentifier "b") (EIdentifier "a")+, ESpace (1 % 1)+, EUnder True (EMathOperator "min") (EIdentifier "A")+, ESpace (1 % 1)+, EUnder True (EMathOperator "max") (EIdentifier "B")+, ESpace (1 % 1)+, EUnder True (EMathOperator "det") (EIdentifier "C")+, ESpace (1 % 1)+, EUnder True (EMathOperator "Pr") (EIdentifier "A")+, ESpace (1 % 1)+, EUnder True (EMathOperator "gcd") (EIdentifier "A")+, ESpace (1 % 1)+, ESuper+ (EOver False (EIdentifier "u") (ESymbol Accent "\775"))+ (ENumber "2")+, ESpace (1 % 1)+, ESub+ (EOver False (EIdentifier "u") (ESymbol TOver "\175"))+ (EIdentifier "\949")+, ESpace (1 % 1)+, ESubsup+ (EUnder False (EIdentifier "u") (ESymbol TUnder "_"))+ (EIdentifier "b")+ (EIdentifier "a")+, ESpace (1 % 1)+, EOver+ False+ (EOver+ False+ (EGrouped [ EIdentifier "a" , ESymbol Bin "+" , EIdentifier "b" ])+ (ESymbol TOver "\9182"))+ (EText TextNormal "term")+, ESpace (1 % 1)+, EOver+ False+ (EOver+ False+ (EGrouped [ EIdentifier "a" , ESymbol Bin "+" , EIdentifier "b" ])+ (ESymbol TOver "\9140"))+ (EIdentifier "c")+, ESpace (1 % 1)+, EUnder+ False+ (EUnder+ False+ (EGrouped [ EIdentifier "a" , ESymbol Bin "+" , EIdentifier "b" ])+ (ESymbol TUnder "\9183"))+ (EIdentifier "c")+, ESpace (1 % 1)+, EUnder+ False+ (EUnder+ False+ (EGrouped [ EIdentifier "a" , ESymbol Bin "+" , EIdentifier "b" ])+ (ESymbol TUnder "\9141"))+ (EIdentifier "c")+, ESuper (ESpace (1 % 1)) (EIdentifier "H")+, EIdentifier "e"+, ENumber "3"+, ESub (ESpace (1 % 1)) (EIdentifier "x")+, EIdentifier "A"+, ESubsup (ESpace (1 % 1)) (EIdentifier "x") (ENumber "3")+]+>>> starmath+x_b^a ~ x_b^a ~ {func min} csub {A}~ {func max} csub {B}~ {func det} csub {C}~ {func Pr} csub {A}~ {func gcd} csub {A}~ {dot u}^2 ~ {overline u}_%ivarepsilon ~ {underline u}_b^a ~ {a + b} overbrace "term"~ {a + b} overbrace c~ {a + b} underbrace c~ {a + b} underbrace c{~}^H e3{~}_x A{~}_x^3
+ test/writer/starmath/text.test view
@@ -0,0 +1,8 @@+<<< native+[ EText TextNormal "(\321ukasiewicz, G\246del, and G\246del)"+, EText+ TextItalic+ "\8230\8211\8220double quotes\8221\8212\8216single quotes\8217"+]+>>> starmath+"(Łukasiewicz, Gödel, and Gödel)" ital {…–“double quotes”—‘single quotes’}
+ test/writer/starmath/tokens.test view
@@ -0,0 +1,14 @@+<<< native+[ EOver False (EIdentifier "\981") (ESymbol Accent "\771")+, ESqrt (EIdentifier "\981")+, EFraction NormalFrac (EIdentifier "\981") (EIdentifier "\958")+, EFraction NormalFrac (EIdentifier "\981") (EIdentifier "\958")+, EFraction NormalFrac (EIdentifier "\981") (EIdentifier "\958")+, EGrouped+ [ ESymbol Open "(" , EIdentifier "\981" , ESymbol Close ")" ]+, EGrouped+ [ ESymbol Open "(" , EIdentifier "\981" , ESymbol Close ")" ]+, EIdentifier "\958"+]+>>> starmath+tilde %iphi sqrt {%iphi}{%iphi over %ixi}{%iphi over %ixi}{%iphi over %ixi}{(%iphi)}{(%iphi)}%ixi
+ test/writer/starmath/unicode.test view
@@ -0,0 +1,9 @@+<<< native+[ EIdentifier "f"+, ESymbol Rel ":"+, EIdentifier "X"+, ESymbol Rel "\8594"+, EIdentifier "Y"+]+>>> starmath+f : X toward Y
texmath.cabal view
@@ -1,16 +1,17 @@ Name: texmath-Version: 0.13.1.2+Version: 0.13.2 Cabal-Version: >= 1.10 Build-type: Simple Synopsis: Conversion between math formats. Description: The texmath library provides functions to read- and write TeX math, presentation MathML, and OMML (Office- Math Markup Language, used in Microsoft Office). Support is also- included for converting math formats to Gnu eqn, typst, and pandoc's- native format (allowing conversion, via pandoc, to a variety of- different markup formats). The TeX reader supports basic LaTeX- and AMS extensions, and it can parse and apply LaTeX macros.- (See <https://johnmacfarlane.net/texmath here> for a live demo of+ and write TeX math, presentation MathML, and OMML (Office Math+ Markup Language, used in Microsoft Office). Support is also+ included for converting math formats to Gnu eqn, typst,+ StarMath, and pandoc's native format (allowing conversion, via+ pandoc, to a variety of different markup formats). The TeX+ reader supports basic LaTeX and AMS extensions, and it can+ parse and apply LaTeX macros. (See+ <https://johnmacfarlane.net/texmath here> for a live demo of bidirectional conversion between LaTeX and MathML.) . The package also includes several utility modules which may be@@ -43,6 +44,7 @@ test/writer/mml/*.test test/writer/omml/*.test test/writer/tex/*.test+ test/writer/starmath/*.test test/writer/typst/*.test test/writer/eqn/*.test test/reader/mml/*.test@@ -66,10 +68,12 @@ Flag executable description: Compile test executable. default: False+ manual: True Flag server description: Compile webserver. default: False+ manual: True Library Build-depends: base >= 4.11 && < 5,@@ -80,7 +84,7 @@ pandoc-types >= 1.20 && < 1.24, mtl >= 2.2.1, text,- typst-symbols >= 0.2 && < 0.2.1,+ typst-symbols >= 0.3 && < 0.3.1, split Exposed-modules: Text.TeXMath,@@ -96,6 +100,7 @@ Text.TeXMath.Writers.OMML, Text.TeXMath.Writers.Pandoc, Text.TeXMath.Writers.TeX,+ Text.TeXMath.Writers.StarMath, Text.TeXMath.Writers.Typst, Text.TeXMath.Writers.Eqn, Text.TeXMath.Unicode.ToUnicode,