From 7e208fa9703e9346e7dbdb461de98d2f379cf9b8 Mon Sep 17 00:00:00 2001 From: cesaryuan Date: Sat, 17 Jan 2026 15:03:16 +0800 Subject: [PATCH] TeX reader: handle \boldsymbol based on content style. Previously \boldsymbol always applied TextBold. Now it applies TextBoldItalic for content that is normally italic (latin letters, lowercase greek) and TextBold for content that is normally upright (uppercase greek, numbers). --- src/Text/TeXMath/Readers/TeX.hs | 35 +++++++++++++++++++++++- src/Text/TeXMath/Readers/TeX/Commands.hs | 3 +- test/reader/tex/boldsymbol.test | 17 ++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 test/reader/tex/boldsymbol.test diff --git a/src/Text/TeXMath/Readers/TeX.hs b/src/Text/TeXMath/Readers/TeX.hs index bf1f7920..4ca66b45 100644 --- a/src/Text/TeXMath/Readers/TeX.hs +++ b/src/Text/TeXMath/Readers/TeX.hs @@ -716,7 +716,40 @@ styled c = do return $ case x of EGrouped xs -> f xs _ -> f [x] - Nothing -> mzero + Nothing + | c == "\\boldsymbol" || c == "\\bm" -> do + x <- texSymbol <|> inbraces <|> texChar + return $ applyBoldsymbol x + | otherwise -> mzero + +-- | Apply \boldsymbol style: use TextBoldItalic for content that is +-- normally italic (latin letters, lowercase greek), and TextBold for +-- content that is normally upright (uppercase greek, numbers). +applyBoldsymbol :: Exp -> Exp +applyBoldsymbol e = + case e of + EGrouped xs -> EGrouped (map applyBoldsymbol xs) + EIdentifier t + | T.all isDefaultUpright t -> EStyled TextBold [e] + | otherwise -> EStyled TextBoldItalic [e] + ENumber _ -> EStyled TextBold [e] + ESymbol _ t + | T.all isDefaultUpright t -> EStyled TextBold [e] + | otherwise -> EStyled TextBoldItalic [e] + EStyled TextNormal xs -> EStyled TextBold xs + EStyled TextItalic xs -> EStyled TextBoldItalic xs + EStyled TextBold xs -> EStyled TextBold xs + EStyled TextBoldItalic xs -> EStyled TextBoldItalic xs + _ -> EStyled TextBoldItalic [e] + +-- | Returns True if a character is normally rendered upright in math mode. +-- This includes uppercase Greek letters. +isDefaultUpright :: Char -> Bool +isDefaultUpright c = + -- Uppercase Greek letters (Α-Ω, excluding lowercase range) + (c >= '\x0391' && c <= '\x03A9') || + -- Also handle digits + (c >= '0' && c <= '9') colored :: Text -> TP Exp colored "\\color" = do diff --git a/src/Text/TeXMath/Readers/TeX/Commands.hs b/src/Text/TeXMath/Readers/TeX/Commands.hs index 4cee422a..494b0e9e 100644 --- a/src/Text/TeXMath/Readers/TeX/Commands.hs +++ b/src/Text/TeXMath/Readers/TeX/Commands.hs @@ -37,13 +37,12 @@ import Data.Text (Text) import Data.Ratio ((%)) -- Note: cal and scr are treated the same way, as unicode is lacking such two different sets for those. +-- Note: \boldsymbol and \bm are handled specially in TeX.hs (styled function). styleOps :: M.Map Text ([Exp] -> Exp) styleOps = M.fromList [ ("\\mathrm", EStyled TextNormal) , ("\\mathup", EStyled TextNormal) , ("\\mathbf", EStyled TextNormal . (:[]) . EStyled TextBold) - , ("\\boldsymbol", EStyled TextBold) - , ("\\bm", EStyled TextBold) , ("\\symbf", EStyled TextBold) , ("\\mathbold", EStyled TextBold) , ("\\pmb", EStyled TextBold) diff --git a/test/reader/tex/boldsymbol.test b/test/reader/tex/boldsymbol.test new file mode 100644 index 00000000..d3fa4d05 --- /dev/null +++ b/test/reader/tex/boldsymbol.test @@ -0,0 +1,17 @@ +<<< tex +\boldsymbol{\alpha + b = \Gamma \div D} + \bm{y} + + +>>> native +[ EGrouped + [ EStyled TextBoldItalic [ EIdentifier "\945" ] + , EStyled TextBoldItalic [ ESymbol Ord "+" ] + , EStyled TextBoldItalic [ EIdentifier "b" ] + , EStyled TextBoldItalic [ ESymbol Rel "=" ] + , EStyled TextBold [ EIdentifier "\915" ] + , EStyled TextBoldItalic [ ESymbol Ord "\247" ] + , EStyled TextBoldItalic [ EIdentifier "D" ] + ] +, ESymbol Bin "+" +, EStyled TextBoldItalic [ EIdentifier "y" ] +]