# SMathML: A Set of Programs to Write Math on the Web

**URL:** <https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444>\
**Category:** Show & Tell\
**Created:** [October 30, 2023, 6:23am UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444 "2023-10-30T06:23:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ulambda](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ulambda/32/1495_2.png) [@ulambda](https://racket.discourse.group/u/ulambda)\
**Post date:** [October 30, 2023, 6:23am UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444/1 "2023-10-30T06:23:05Z")

</div>

[SMathML](https://github.com/alpha-beta-eta/SMathML)  
Recently I decide to translate Hoffman & Kunze into Chinese. And I also want to put it on my homepage. Then I write down these programs to generate html, mathml, svg, and so on. Here is an example I pick up from the source code of the translation.

 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/7/7462c62f9bc9769757bfaf0444be67b73bf73c52.png)  
 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/f/f7466acf92b624af45ffe316e5f61a8122edc753.png)

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://avatars.discourse-cdn.com/v4/letter/h/b5e925/32.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [October 30, 2023, 7:07pm UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444/2 "2023-10-30T19:07:37Z")

</div>

These look useful.  
Are these to turn mathematical expressions into stand-lone images that  
are patched into a document by other means,  
or are they part of a larger document compiler?

-- hendrik

---

<div class="post-metadata">

**Author:** ![ulambda](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ulambda/32/1495_2.png) [@ulambda](https://racket.discourse.group/u/ulambda)\
**Post date:** [October 31, 2023, 12:04am UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444/3 "2023-10-31T00:04:55Z")

</div>

I think I have to explain my ideas in detail. There is no magic.  
In fact, mathematical expressions are rendered by the browser (Firefox) through MathML. MathML is a markup language based on XML.  
There is a hierarchical structure in my mind. First, I define a represention for XML, which is just kind of XML in S-exp (SXML).

```scheme
<xml> ::= <string>
       | (<symbol> (<attr>*) <xml>*)
<attr> ::= (<symbol> <string>)

```

In xml.rkt, I provide a procedure Xml for transformation. For example,

```scheme
> (Xml '(foo ((bar "baz")) "qux"))
<foo bar="baz">qux</foo>

```

In html.rkt, I provide lots of procedures to create HTML (in SXML). For instance,

```scheme
> (Xml (Prelude (H1 "foo") (P "foo " (B "bar") " baz")))
<html><head><meta charset="utf-8"/><title>index</title></head><body><h1>foo</h1><p>foo <b>bar</b> baz</p></body></html>

```

As you may expect, mathml.rkt provide tons of procedures to create MathML (in SXML) and to build abstractions for creating MathML. For example, we have procedure make-op which transforms an infix operator into a procedure by which you may write MathML in the style of Scheme.

```scheme
(define ((make-op op n u) . x*)
  (cond
    ((null? x*) (n))
    ((null? (cdr x*)) (u (car x*)))
    (else
     (let iter ((x (car x*)) (x* (cdr x*)) (r '()))
       (if (null? x*)
           (apply Mrow (reverse (cons x r)))
           (iter (car x*)
                 (cdr x*)
                 (cons op (cons x r))))))))

```

For example,

```scheme
(define &cm
  (make-op $cm
    (lambda () $)
    (lambda (x) x)))

```

```scheme
> (Xml (&cm))
<mrow/>
> (Xml (&cm $1))
<mn>1</mn>
> (Xml (&cm $1 $2))
<mrow><mn>1</mn><mo>,</mo><mn>2</mn></mrow>
> (Xml (&cm $1 $2 $3))
<mrow><mn>1</mn><mo>,</mo><mn>2</mn><mo>,</mo><mn>3</mn></mrow>

```

In slt.rkt, I provide some abstractions to build tree transformations. (These are inspired by Oleg Kiselyov's SXSLT.) For now they haven't been efficiently implemented and I'd like to modify them in the future. As an illustration of the usage, I provide a procdure Tm in math-styles.rkt.

```scheme
(define math-style*
  `(((default)
     *preorder*
     ,(lambda (tag attr* . xml*)
        (cond ((eq? tag 'math) `(,tag ,attr* . ,xml*))
              ((memq tag '(merror mfrac mi mmultiscripts mn mo mover
                                  mpadded mphantom mroot mrow
                                  ms mspace msqrt mstyle msub msubsup
                                  msup mtable mtd mtext mtr munder
                                  munderover))
               (Math `(,tag ,attr* . ,xml*)))
              (else `(,tag ,attr* . ,(map Tm xml*))))))
    ((text) ,(lambda (str) str))))
(define Tm (T math-style*))

```

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://avatars.discourse-cdn.com/v4/letter/h/b5e925/32.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [November 20, 2025, 9:48pm UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444/4 "2025-11-20T21:48:23Z")

</div>

So the idea is to use xml.rkt, htkl.rkt, and slt.rkt to embed mathematical notation into a Scribble document?

---

<div class="post-metadata">

**Author:** ![ulambda](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ulambda/32/1495_2.png) [@ulambda](https://racket.discourse.group/u/ulambda)\
**Post date:** [November 21, 2025, 3:40am UTC](https://racket.discourse.group/t/smathml-a-set-of-programs-to-write-math-on-the-web/2444/5 "2025-11-21T03:40:05Z")

</div>

In fact, you are writing html/xml directly in the guise of S-exp. Though, you can create abstrations or build transformations on such a structure.

A Simple Example:

```scheme
(define ((associative-law op) x y z)
  (&= (op x (@ (op y z)))
      (op (@ (op x y)) z)))
(define ((commutative-law op) x y)
  (&= (op x y) (op y x)))
(define ((distributive-law-right * +) x y z)
  (&= (* x (@ (+ y z)))
      (+ (* x y) (* x z))))

```

 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/0/0383da46d322e58d6ac82eb6a4c985d63d7e5b14.png)  
 ![image](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/3/3f80a4d5e6fefb722856be5d51b1ca8add01afd0.png)
