Skip to content

Commit 76c6d83

Browse files
SeanESCAjgm
authored andcommitted
Add cancellation of terms for most formats. (#271)
* Added StrokeType [API change]. * Added ECancel constructor on Exp [API change]. * Added ECancel handling to all readers and writers. * Added tests for ECancel. Closes #251. Closes #269. This adds support for LaTeX `\cancel`, `\bcancel`, `\xcancel`, and their equivalents in OMML, MathML, and Typst.
1 parent 2a40f5d commit 76c6d83

File tree

19 files changed

+364
-6
lines changed

19 files changed

+364
-6
lines changed

src/Text/TeXMath/Readers/MathML.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ enclosed e = do
392392
mbNotation <- findAttrQ "notation" e
393393
case mbNotation of
394394
Just "box" -> EBoxed <$> row e
395+
Just "updiagonalstrike" -> ECancel ForwardSlash <$> row e
396+
Just "downdiagonalstrike" -> ECancel BackSlash <$> row e
397+
Just "updiagonalstrike downdiagonalstrike" -> ECancel XSlash <$> row e
395398
_ -> row e
396399

397400
action :: Element -> MML Exp

src/Text/TeXMath/Readers/OMML.hs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,18 @@ elemToExps' element | isElem "m" "box" element = do
278278
elemToExps' element | isElem "m" "borderBox" element = do
279279
baseExp <- filterChildName (hasElemName "m" "e") element >>=
280280
elemToBase
281-
return [EBoxed baseExp]
281+
let bbPr = filterChildName (hasElemName "m" "borderBoxPr") element
282+
bltr = bbPr >>= filterChildName (hasElemName "m" "strikeBLTR") >>=
283+
findAttrBy (hasElemName "m" "val")
284+
tlbr = bbPr >>= filterChildName (hasElemName "m" "strikeTLBR") >>=
285+
findAttrBy (hasElemName "m" "val")
286+
return $
287+
case (bltr, tlbr) of
288+
(Just "1", Just "1") -> [ECancel XSlash baseExp]
289+
(Just "1", _) -> [ECancel ForwardSlash baseExp]
290+
(_, Just "1") -> [ECancel BackSlash baseExp]
291+
_ -> [EBoxed baseExp]
292+
282293
elemToExps' element | isElem "m" "d" element =
283294
let baseExps = mapMaybe
284295
elemToBases

src/Text/TeXMath/Readers/TeX.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ command = try $ do
229229
, mathop c
230230
, phantom c
231231
, boxed c
232+
, cancel c
232233
, binary c
233234
, genfrac c
234235
, substack c
@@ -660,6 +661,14 @@ boxed :: Text -> TP Exp
660661
boxed "\\boxed" = EBoxed <$> texToken
661662
boxed _ = mzero
662663

664+
cancel :: Text -> TP Exp
665+
cancel c = do
666+
case c of
667+
"\\cancel" -> ECancel ForwardSlash <$> texToken
668+
"\\bcancel" -> ECancel BackSlash <$> texToken
669+
"\\xcancel" -> ECancel XSlash <$> texToken
670+
_ -> mzero
671+
663672
text :: Text -> TP Exp
664673
text c = do
665674
op <- maybe mzero return $ M.lookup c textOps

src/Text/TeXMath/Types.hs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ module Text.TeXMath.Types (Exp(..), TeXSymbolType(..), ArrayLine,
2424
FractionType(..), TextType(..),
2525
Alignment(..), DisplayType(..),
2626
Operator(..), FormType(..), Record(..),
27-
Property, Position(..), Env, defaultEnv,
28-
InEDelimited)
27+
Property, Position(..), StrokeType(..),
28+
Env, defaultEnv, InEDelimited)
2929
where
3030

3131
import Data.Generics
@@ -44,6 +44,9 @@ data FractionType = NormalFrac -- ^ Displayed or textual, acc to 'DisplayType'
4444
| NoLineFrac -- ^ No line between top and bottom
4545
deriving (Show, Read, Eq, Ord, Data, Typeable)
4646

47+
data StrokeType = ForwardSlash | BackSlash | XSlash
48+
deriving (Show, Read, Eq, Ord, Data, Typeable)
49+
4750
type ArrayLine = [[Exp]]
4851

4952
data Exp =
@@ -79,6 +82,7 @@ data Exp =
7982
-- something under it.
8083
| EPhantom Exp -- ^ A "phantom" operator that takes space but doesn't display.
8184
| EBoxed Exp -- ^ A boxed expression.
85+
| ECancel StrokeType Exp -- ^ A cancelled expression.
8286
| EFraction FractionType Exp Exp -- ^ A fraction. First argument is
8387
-- numerator, second denominator.
8488
| ERoot Exp Exp -- ^ An nth root. First argument is index, second is base.
@@ -152,6 +156,6 @@ data Position = Under | Over
152156
-- | List of available packages
153157
type Env = [T.Text]
154158

155-
-- | Contains @amsmath@ and @amssymbol@
159+
-- | Contains @amsmath@, @amssymbol@, and @cancel@
156160
defaultEnv :: [T.Text]
157-
defaultEnv = ["amsmath", "amssymb"]
161+
defaultEnv = ["amsmath", "amssymb", "cancel"]

src/Text/TeXMath/Writers/Eqn.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ writeExp (ESqrt e) = "sqrt " <> writeExp' e
187187
writeExp (ERoot i e) = "\"\" sup " <> writeExp' i <> " sqrt " <> writeExp' e
188188
writeExp (EPhantom e) = "hphantom " <> writeExp' e
189189
writeExp (EBoxed e) = writeExp e -- TODO: any way to do this?
190+
writeExp (ECancel _ e) = writeExp e -- TODO
190191
writeExp (EScaled _size e) = writeExp e -- TODO: any way?
191192
writeExp (EText ttype s) =
192193
let quoted = "\"" <> s <> "\""

src/Text/TeXMath/Writers/MathML.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ showExp tt e =
241241
EPhantom x -> unode "mphantom" $ showExps tt [x]
242242
EBoxed x -> withAttribute "notation" "box" .
243243
unode "menclose" $ showExp tt x
244+
ECancel ForwardSlash x -> withAttribute "notation" "updiagonalstrike" .
245+
unode "menclose" $ showExp tt x
246+
ECancel BackSlash x -> withAttribute "notation" "downdiagonalstrike" .
247+
unode "menclose" $ showExp tt x
248+
ECancel XSlash x -> withAttribute "notation" "updiagonalstrike downdiagonalstrike" .
249+
unode "menclose" $ showExp tt x
244250
ESqrt x -> unode "msqrt" $ showExp tt x
245251
ERoot i x -> unode "mroot" [showExp tt x, showExp tt i]
246252
EScaled s x -> makeScaled s $ showExp tt x

src/Text/TeXMath/Writers/OMML.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ showExp props e =
300300
[ mnodeA "show" "off" () ]
301301
, mnode "e" $ showExp props x]]
302302
EBoxed x -> [mnode "borderBox" [ mnode "e" $ showExp props x]]
303+
ECancel st x -> [makeCancel props st x]
303304
EScaled _ x -> showExp props x -- no support for scaler?
304305
EArray as ls -> [makeArray props as ls]
305306
EText a s -> [makeText a s]
@@ -342,3 +343,16 @@ makeNary props t s y z w =
342343
, mnode "sup" $ showExp props z
343344
, mnode "e" $ showExp props w ]
344345

346+
makeCancel :: [Element] -> StrokeType -> Exp -> Element
347+
makeCancel props st x = do
348+
let sn = case st of
349+
ForwardSlash -> [ mnodeA "strikeBLTR" "1" () ]
350+
BackSlash -> [ mnodeA "strikeTLBR" "1" () ]
351+
XSlash -> [ mnodeA "strikeBLTR" "1" ()
352+
, mnodeA "strikeTLBR" "1" () ]
353+
mnode "borderBox" [ mnode "borderBoxPr" $
354+
[ mnodeA "hideTop" "1" ()
355+
, mnodeA "hideBot" "1" ()
356+
, mnodeA "hideLeft" "1" ()
357+
, mnodeA "hideRight" "1" () ] ++ sn
358+
, mnode "e" $ showExp props x ]

src/Text/TeXMath/Writers/Pandoc.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,5 @@ expToInlines tt (EOver convertible b e)
156156
expToInlines _ (EUnderover _ _ _ _) = Nothing
157157
expToInlines _ (EPhantom _) = Nothing
158158
expToInlines _ (EBoxed _) = Nothing
159+
expToInlines _ (ECancel _ _) = Nothing
159160
expToInlines _ (EArray _ _) = Nothing

src/Text/TeXMath/Writers/TeX.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import Data.Either (isRight)
3737
-- tr' x = trace (show x) x
3838

3939
-- | Transforms an expression tree to equivalent LaTeX with the default
40-
-- packages (amsmath and amssymb)
40+
-- packages (amsmath, amssymb, and cancel)
4141
writeTeX :: [Exp] -> T.Text
4242
writeTeX = writeTeXWith defaultEnv
4343

@@ -262,6 +262,16 @@ writeExp (EBoxed e) = do
262262
tell [ControlSeq "\\boxed"]
263263
tellGroup (writeExp e)
264264
else writeExp e
265+
writeExp (ECancel st e) = do
266+
env <- asks mathEnv
267+
if "cancel" `elem` env
268+
then do
269+
case st of
270+
ForwardSlash -> tell [ControlSeq "\\cancel"]
271+
BackSlash -> tell [ControlSeq "\\bcancel"]
272+
XSlash -> tell [ControlSeq "\\xcancel"]
273+
tellGroup (writeExp e)
274+
else writeExp e
265275
writeExp (EScaled size e)
266276
| case e of
267277
(ESymbol Open _) -> True

src/Text/TeXMath/Writers/Typst.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ writeExp (EStyled ttype es) =
225225
TextBoldFraktur -> "bold" <> inParens ("frak" <> inParens contents)
226226
TextSansSerifItalic -> "italic" <> inParens ("sans" <> inParens contents)
227227
writeExp (EBoxed e) = "#box(stroke: black, inset: 3pt, [$ " <> writeExp e <> " $])"
228+
writeExp (ECancel ForwardSlash e) = "cancel(" <> writeExp e <> ")"
229+
writeExp (ECancel BackSlash e) = "cancel(" <> writeExp e <> ", inverted: #true)"
230+
writeExp (ECancel XSlash e) = "cancel(" <> writeExp e <> ", cross: #true)"
228231
writeExp (EPhantom e) = "#hide[" <> writeExp e <> "]"
229232
writeExp (EScaled size e) =
230233
"#scale(x: " <> tshow (floor (100 * size) :: Int) <>

0 commit comments

Comments
 (0)