diff --git a/Makefile.template b/Makefile.template index c9df072..d4356dd 100644 --- a/Makefile.template +++ b/Makefile.template @@ -17,6 +17,8 @@ bib = # define index if an index is to be generated # index=yes +# override katex variables here if desired + include $(STEXLIB)/Mf-stex # define or override suffixes here diff --git a/Mf-stex b/Mf-stex index 09ec6f3..0ed795d 100644 --- a/Mf-stex +++ b/Mf-stex @@ -28,6 +28,30 @@ else fixbibtex = $(STEXLIB)/$m/fixbibtex endif +ifeq ($(origin KATEX), undefined) +KATEX:=$(if $(shell command -v katex),katex,) +endif +ifneq ($(strip $(KATEX)),) + ifeq ($(strip $(KATEX_CSS)),) + # try to infer KATEX_CSS + katexrealpath:=$(realpath $(shell command -v $(KATEX))) + katexrealdir:=$(dir $(katexrealpath)) + ifeq ($(katexrealpath),) + # can't infer; complain below + else ifneq ($(realpath $(katexrealdir)/dist/katex.css),) + # NPM installation layout (also release tarballs) + KATEX_CSS=$(katexrealdir)/dist/katex.css + else ifneq ($(realpath $(katexrealdir)/katex.css),) + # Debian installation layout + KATEX_CSS=$(katexrealdir)/katex.css + endif + ifeq ($(strip $(KATEX_CSS)),) + $(error cannot find KATEX_CSS for KATEX=$(KATEX)) + endif + endif +endif +export KATEX KATEX_FLAGS + mathdir=math/$(x) mathfiles=$(mathdir)/mathfiles @@ -104,35 +128,62 @@ $(x).firstrun: $(texsrc) all.tex: $(texsrc) +ifeq ($(strip $(KATEX)),) $(x).html: $(x).mathrun +else +$(x).hfourthrun: $(x).mathrun $(x).katex-css-link + $(Hprep) --mathdir $(mathdir) --use-katex --katex-finished --katex-css-link-file $(x).katex-css-link $(x) + chmod 444 *.html + touch $(x).hfourthrun + +# a project may supply one with content to override the default +$(x).katex-css-link: + touch $(x).katex-css-link + +ifeq ($(strip $(KATEX_CSS)),no) +$(x).html: $(x).hfourthrun +else +$(x).html: $(x).hfourthrun katex + +katex: + mkdir -p katex + cp $(KATEX_CSS) katex/katex.css + (cd katex; (cd $(dir $(KATEX_CSS)); tar -cf - --dereference fonts) | tar -xpf -) + chmod u+w katex/katex.css katex/fonts +endif +endif $(x).mathrun: gifs $(mathfiles) @(cd $(mathdir); make) touch $(x).mathrun gifs: - (cd $(STEXLIB); tar -cf - gifs) | tar -xpf - + (cd $(STEXLIB); tar -cf - --dereference gifs) | tar -xpf - + chmod u+w gifs math: - (cd $(STEXLIB); tar -cf - math) | tar -xpf - + (cd $(STEXLIB); tar -cf - --dereference math) | tar -xpf - + chmod u+w math $(mathfiles): $(x).hthirdrun $(figps) echo -n gifs= > $(mathfiles) (cd $(mathdir); echo *.tex | sed -e "s/\.tex/.gif/g") >> $(mathfiles) + echo -n htmls= >> $(mathfiles) + (cd $(mathdir); echo *.katex | sed -e "s/\.katex/.html/g") >> $(mathfiles) $(x).hthirdrun: $(x).hsecondrun - $(Hprep) --mathdir $(mathdir) $(x) + $(Hprep) --mathdir $(mathdir) $(if $(strip $(KATEX)),--use-katex,) $(x) chmod 444 *.html touch $(x).hthirdrun $(x).hsecondrun: $(x).hfirstrun - $(Hprep) --mathdir $(mathdir) $(x) + $(Hprep) --mathdir $(mathdir) $(if $(strip $(KATEX)),--use-katex,) $(x) chmod 444 *.html touch $(x).hsecondrun $(x).hfirstrun: math $(x).thirdrun - (if [ ! -e $(mathdir) ] ; then mkdir -p -m u=rwx,g=srx,o=rx $(mathdir); ln -s ../Makefile ../mathmacros $(mathdir); fi) - $(Hprep) --mathdir $(mathdir) $(x) + (if [ ! -e $(mathdir) ] ; then mkdir -p -m u=rwx,g=srx,o=rx $(mathdir); ln -s ../Makefile ../mathmacros ../katexmacros $(mathdir); fi) + $(Hprep) --mathdir $(mathdir) $(if $(strip $(KATEX)),--use-katex,) $(x) touch $(x).hfirstrun spell: $(spellobj) @@ -143,7 +194,7 @@ $(x).spell: $(x).bbl $(x).tex clean: $(x).clean -/bin/rm -f *.log *.dvi *.aux *.out *.toc *.tmp *.idx *.ilg *.ind *.blg *.bbl *.rfm *.sfm *.firstrun *.secondrun *.thirdrun - -/bin/rm -f *.haux *.htoc *.hidx *.hfirstrun *.hsecondrun *.hthirdrun *.mathrun + -/bin/rm -f *.haux *.htoc *.hidx *.hfirstrun *.hsecondrun *.hthirdrun *.mathrun *.hfourthrun -/bin/rm -f *.tex reallyclean: clean $(x).reallyclean diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..2b1858a --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,11 @@ +gifs/ +math/ +*.tex +*.log +*[.h]aux +*[.h]toc +*[.h]firstrun +*[.h]secondrun +*[.h]thirdrun +*.hfourthrun +*.mathrun diff --git a/doc/Makefile b/doc/Makefile index e2ccc0f..e5b8305 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -17,6 +17,9 @@ bib = # define index if an index is to be generated # index=yes +# override katex variables here if desired +KATEX_CSS=no # see comment in stex.katex-css-link + include $(STEXLIB)/Mf-stex # define or override suffixes here diff --git a/doc/stex.css b/doc/stex.css index 8950ff0..702c343 100644 --- a/doc/stex.css +++ b/doc/stex.css @@ -14,6 +14,9 @@ a.image:link, a.image:active, a.image:visited, a.image:hover { background: #FFFFFF; } +.schemedisplay { line-height: 1.0625; } +.schemedisplay .katex { font-size: 1em; } + ul.tocchapter { list-style: none; } ul.tocsection { list-style: circle; color: #923a3a } diff --git a/doc/stex.html b/doc/stex.html index 25a4a70..704cec1 100644 --- a/doc/stex.html +++ b/doc/stex.html @@ -1,10 +1,32 @@ - - + + + Introduction to stex + + @@ -77,6 +99,10 @@

April 2016

6. html-prep support for the tabular environment + + +7. Math in HTML + @@ -102,22 +128,22 @@

1. Overview

files. The two main programs are scheme-prep and html-prep. scheme-prep performs a conversion from "stex"-formatted files -into latex-formatted files, while html-prep converts (some) -latex-formatted files into html-formatted files. +into LaTeX\mbox{\LaTeX}-formatted files, while html-prep converts (some) +LaTeX\mbox{\LaTeX}-formatted files into html-formatted files.

-An stex file is really just a latex file extended with a handful of +An stex file is really just a LaTeX\mbox{\LaTeX} file extended with a handful of commands for including Scheme code (or pretty much any other kind of code, as long as you don't plan to use the Scheme-specific transcript support) in a document, plus a couple of additional features rather arbitrarily thrown in.

-The subset of latex-formatted files html-prep is capable of +The subset of LaTeX\mbox{\LaTeX}-formatted files html-prep is capable of handling is rather small but has nevertheless been useful for our purposes, which include producing html versions of a couple of books -(The Scheme Programming Language, Editions 2-4 and the Chez Scheme -User's Guides for Versions 6-9), the scheme.com web site, class websites, +(The Scheme Programming Language, Editions 2–4 and the Chez Scheme +User's Guides for Versions 6–10), the scheme.com web site, class websites, class assignments, and various other documents.

@@ -134,6 +160,8 @@

2. Installation

A prerequisite to building and using stex is to have Chez Scheme installed on your system. You'll also need pdflatex, dvips, ghostscript, and netpbm. +Additionally, you may want to have KaTeX\mbox{\KaTeX} installed: see "Math in HTML" +below. We've run stex under Linux and OS X but have not tried to run it under Windows. @@ -144,7 +172,7 @@

2. Installation

-

make Scheme=schemepath +

make Scheme=schemepath

where schemepath is the path to the scheme executable.

@@ -156,7 +184,7 @@

2. Installation

-

sudo make install Scheme=schemepath LIB=libdir +

sudo make install Scheme=schemepath LIB=libdir

where schemepath is as described above, and libdir is the directory where the stex library directory should be installed. If libdir is writable by the current user, then sudo @@ -167,7 +195,7 @@

2. Installation

-

sudo make install PREFIX=prefixdir +

sudo make install PREFIX=prefixdir

where prefixdir specifies in one shot the tree under which the Scheme executable is installed and under which the stex library should be installed. @@ -175,7 +203,7 @@

2. Installation

-

sudo make install Scheme=prefixdir/bin/scheme LIB=prefixdir/lib/stexversion +

sudo make install Scheme=prefixdir/bin/scheme LIB=prefixdir/lib/stexversion

where version is the stex version number.

@@ -298,7 +326,7 @@

4.2. Code displays

-

(define fact
+

(define fact
  (lambda (x)
@@ -314,7 +342,7 @@

4.2. Code displays

Within a Scheme display, ;=> is converted into a double right arrow -(<graphic>), ;-> into a single right arrow (<graphic>), and +(\Rightarrow), ;-> into a single right arrow (\rightarrow), and ;== into a phantom of the same size. This is useful for showing what a piece of code translates or evaluates to, e.g.: @@ -350,14 +378,14 @@

4.2. Code displays

A let expression expands into a call to a lambda expression, e.g.: -

(let ([a 17]) <graphic> ((lambda (a) (+ a a))
+

(let ([a 17]) \rightarrow ((lambda (a) (+ a a))
-  (+ a a))      17)
+  (+ a a))    \Rightarrow  17)

A let expression first evaluates the right-hand-side expression, then evaluates the body in an environment that binds the left-hand-side variable to the resulting value, e.g.: -

(let ([a 17]) <graphic> 17
+

(let ([a 17]) \Rightarrow 17
  (+ a a))

@@ -439,7 +467,18 @@

4.4. Raw text in code

-

(sqrt x<graphic> <graphic>. +

(sqrt x\Rightarrow x\sqrt{x}.

@@ -574,7 +613,7 @@

5.1. Automatic transcript generation

-

> (define f
+

> (define f
    (lambda (x)       ; indentation and comments are
@@ -676,7 +715,7 @@

5.1. Automatic transcript generation

-

> #e4.5
+

> #e4.5
9/2
@@ -786,7 +825,7 @@

5.1. Automatic transcript generation

-

> (begin (display "> \n") (exit))
+

> (begin (display "> \n") (exit))

@@ -817,7 +856,7 @@

5.1. Automatic transcript generation

-

> (waiter-prompt-string "antelope? ")
+

> (waiter-prompt-string "antelope? ")
antelope?  "no thanks"
@@ -883,7 +922,7 @@

5.2. Loading initialization code

The compute-length procedure behaves as follows: -

> (compute-length '())
+

> (compute-length '())
0
@@ -963,22 +1002,97 @@

6. html-prep support for the tabular envir

-
-y = f(x) without loss of generality
-z whee this is fun?
- -
- 1 2
- 3 4 -
-
-a b c d
-12345 z (define x "foo") -
+
+y = f(x) without loss of generality
+z whee this is fun?
+ +
+ 1 2
+ 3 4 +
+
+a b c d
+12345 z (define x "foo") +
+

+ + + + +

7. Math in HTML

+ + + + +

+A few very simple uses of LaTeX\mbox{\LaTeX}'s math mode are converted to HTML directly by +html-prep. For typesetting non-trivial math, there are two strategies +available: + +

+

    +
  1. Originally, stex used LaTeX\mbox{\LaTeX} to render math to GIF images. +
  2. Optionally, stex can use KaTeX\mbox{\KaTeX}, which generates MathML and/or HTML. +
+

+ +

+Using KaTeX\mbox{\KaTeX} makes the rendered math accessible to assistive technologies, +CSS, and other browser features. It also tends to look better than math in +GIFs. However, a few features that stex supports when rendering to GIFs, +notably including \epsfbox{} and the +eqnarray* environment, are not currently supported when rendering with +KaTeX\mbox{\KaTeX}. + +

+By default, stex will use KaTeX\mbox{\KaTeX} if the "katex" command is found; otherwise, +it will automatically fall back to generating GIFs. To prevent stex from using +KaTeX\mbox{\KaTeX} even if it is available, use make KATEX= or define +KATEX as empty in your makefile before including Mf-stex. The same +mechanisms can be used to supply a non-default "katex" command or even to +require that KaTeX\mbox{\KaTeX} be present, e.g. by writing: + +

+

+
+KATEX:=$(if $(shell command -v katex),katex,$(error katex not found))
+
+ +
+ +

+The variable KATEX_FLAGS may be used to supply additional options for +KaTeX\mbox{\KaTeX}. + +

+The output of KaTeX\mbox{\KaTeX} requires supporting CSS and font files. (Notably, it does +not require JavaScript. It is also possible to supply non-default options to +create output that can work without CSS and fonts by relying solely on the +native support for MathML in recent browsers and operating systems.) By +default, stex will attempt to find these files relative to the "katex" +command, and it should be able to handle the installation layouts used by both +Node.js and Debian. If the files cannot be found automatically, you will need +to define KATEX_CSS, either at the command line or in your makefile +(before including Mf-stex): likely values include +"./node_modules/katex/dist/katex.css" and +"/usr/share/javascript/katex/katex.css". + +

+By default, stex copies the needed CSS and font files into a directory named +"katex" alongside the generated HTML files: when using KaTeX\mbox{\KaTeX}, you need to +install this directory or upload it to your web server. + +

+As a special case, defining KATEX_CSS=no instructs stex not to copy +these files. If you use this option, you may also want to override the default +HTML link element used to load the CSS by creating a non-empty file +with the base name of your document and the extension ".katex-css-link": for +an example, see the "stex.katex-css-link" file used for this document. +

- © 1998-2016 R. Kent Dybvig and Oscar Waddell + © 1998–2016 R. Kent Dybvig and Oscar Waddell diff --git a/doc/stex.katex-css-link b/doc/stex.katex-css-link new file mode 100644 index 0000000..02e7a45 --- /dev/null +++ b/doc/stex.katex-css-link @@ -0,0 +1,22 @@ + + diff --git a/doc/stex.pdf b/doc/stex.pdf index a5e0043..02d9101 100644 Binary files a/doc/stex.pdf and b/doc/stex.pdf differ diff --git a/doc/stex.stex b/doc/stex.stex index 888addd..1eaaa53 100644 --- a/doc/stex.stex +++ b/doc/stex.stex @@ -42,20 +42,20 @@ items, such as make files, make-file templates, class files, and style files. The two main programs are \textbf{scheme-prep} and \textbf{html-prep}. \textbf{scheme-prep} performs a conversion from ``stex''-formatted files -into latex-formatted files, while \textbf{html-prep} converts (some) -latex-formatted files into html-formatted files. +into \LaTeX-formatted files, while \textbf{html-prep} converts (some) +\LaTeX-formatted files into html-formatted files. -An stex file is really just a latex file extended with a handful of +An stex file is really just a \LaTeX\ file extended with a handful of commands for including Scheme code (or pretty much any other kind of code, as long as you don't plan to use the Scheme-specific transcript support) in a document, plus a couple of additional features rather arbitrarily thrown in. -The subset of latex-formatted files \textbf{html-prep} is capable of +The subset of \LaTeX-formatted files \textbf{html-prep} is capable of handling is rather small but has nevertheless been useful for our purposes, which include producing html versions of a couple of books (\emph{The Scheme Programming Language}, Editions 2--4 and the Chez Scheme -User's Guides for Versions 6--9), the scheme.com web site, class websites, +User's Guides for Versions 6--10), the scheme.com web site, class websites, class assignments, and various other documents. \section{Installation} @@ -63,6 +63,8 @@ class assignments, and various other documents. A prerequisite to building and using stex is to have Chez Scheme installed on your system. You'll also need pdflatex, dvips, ghostscript, and netpbm. +Additionally, you may want to have \KaTeX\ installed: see ``Math in HTML'' +below. We've run stex under Linux and OS X but have not tried to run it under Windows. @@ -618,4 +620,60 @@ a & b & c & d \\ \end{tabular} \end{quotation} +\section{Math in HTML} + +A few very simple uses of \LaTeX's math mode are converted to HTML directly by +\textbf{html-prep}. For typesetting non-trivial math, there are two strategies +available: + +\begin{enumerate} + \item Originally, stex used \LaTeX\ to render math to GIF images. + \item Optionally, stex can use \KaTeX, which generates MathML and/or HTML. +\end{enumerate} + +Using \KaTeX\ makes the rendered math accessible to assistive technologies, +CSS, and other browser features. It also tends to look better than math in +GIFs. However, a few features that stex supports when rendering to GIFs, +notably including \scheme{\epsfbox\schlbrace\schrbrace} and the +\scheme{eqnarray*} environment, are not currently supported when rendering with +\KaTeX. + +By default, stex will use \KaTeX\ if the ``katex'' command is found; otherwise, +it will automatically fall back to generating GIFs. To prevent stex from using +\KaTeX\ even if it is available, use \scheme{make KATEX=} or define +\scheme{KATEX} as empty in your makefile before including Mf-stex. The same +mechanisms can be used to supply a non-default ``katex'' command or even to +require that \KaTeX\ be present, e.g.\ by writing: + +\begin{quotation} +\begin{verbatim} +KATEX:=$(if $(shell command -v katex),katex,$(error katex not found)) +\end{verbatim} +\end{quotation} + +The variable \scheme{KATEX_FLAGS} may be used to supply additional options for +\KaTeX. + +The output of \KaTeX\ requires supporting CSS and font files. (Notably, it does +not require JavaScript. It is also possible to supply non-default options to +create output that can work without CSS and fonts by relying solely on the +native support for MathML in recent browsers and operating systems.) By +default, stex will attempt to find these files relative to the ``katex'' +command, and it should be able to handle the installation layouts used by both +Node.js and Debian. If the files cannot be found automatically, you will need +to define \scheme{KATEX_CSS}, either at the command line or in your makefile +(before including Mf-stex): likely values include +``./node\_modules/katex/dist/katex.css'' and +``/usr/share/javascript/katex/katex.css''. + +By default, stex copies the needed CSS and font files into a directory named +``katex'' alongside the generated HTML files: when using \KaTeX, you need to +install this directory or upload it to your web server. + +As a special case, defining \scheme{KATEX_CSS=no} instructs stex not to copy +these files. If you use this option, you may also want to override the default +HTML \scheme{link} element used to load the CSS by creating a non-empty file +with the base name of your document and the extension ``.katex-css-link'': for +an example, see the ``stex.katex-css-link'' file used for this document. + \end{document} diff --git a/inputs/scheme.hsty b/inputs/scheme.hsty index 2b9499d..bbbd3ee 100644 --- a/inputs/scheme.hsty +++ b/inputs/scheme.hsty @@ -18,7 +18,8 @@ \def\scheme#1{{\tt #1}} \def\longcode\schemedisplay{\schemedisplay} \def\noskip\schemedisplay{\schemedisplay} -\def\schemedisplay{\par\begingroup\tt\hardspaces} +\def\schemedisplay{\begingroup\renewcommand{\par}{\raw{ +

}}\par\endgroup\begingroup\tt\hardspaces} \def\endschemedisplay{\endgroup\par} \def\schemeindent{} \def\schatsign{\raw{@}} @@ -31,7 +32,7 @@ \def\schunderscore{\raw{_}} \def\becomes{$\rightarrow$} \def\is{$\Rightarrow$} -\def\si{\raw{}} +\def\si{\schemeghostRightarrow} % handled specially by html-prep \def\var#1{\emph{#1}} % frame="border" rules="all" makes mozilla do it right @@ -40,3 +41,10 @@ \def\endrepl{\raw{}} \def\startinteraction{\raw{
}} \def\endinteraction{\raw{
}} + +% This seemingly circular definition works because the \KaTeX inside +% math mode is expanded with a different definition: either the +% primitive from KaTeX or, if rendering without KaTeX, the definition +% from scheme.sty. +\def\KaTeX{$\mbox{\KaTeX}$} +\def\LaTeX{$\mbox{\LaTeX}$} diff --git a/inputs/scheme.sty b/inputs/scheme.sty index 8f7276a..8e27c24 100644 --- a/inputs/scheme.sty +++ b/inputs/scheme.sty @@ -54,3 +54,13 @@ \def\beforeschemedisplay{\penalty-100\vskip\parskip\vskip5pt} \def\afterschemedisplay{\penalty-200\vskip5pt} +% From test/screenshotter/test.tex in the KaTeX source code, which says: +% > Based on LaTeX's definition of \LaTeX, with L changed to K and kerns +% > changed as in src/macros.js +\DeclareRobustCommand{\KaTeX}{\mbox{% +K\kern-.17em% +{\sbox0 T\vbox to\ht0{\hbox% + {\fontsize{.75em}{1em}\selectfont A}% +\vss}}% +\kern-.15em% +\TeX}} diff --git a/math/Makefile b/math/Makefile index b3ffae3..bfa935f 100644 --- a/math/Makefile +++ b/math/Makefile @@ -1,9 +1,10 @@ include mathfiles density=-r90x90 +runkatex=$(KATEX) $(KATEX_FLAGS) --macro-file katexmacros --trust .SUFFIXES: -.SUFFIXES: .tex .gif +.SUFFIXES: .tex .gif .katex .html # translate ps file to ppm, crop to minimum background, and translate ppm # to gif with white (background) transparent @@ -19,8 +20,18 @@ density=-r90x90 /bin/rm -f $*.dvi $*.log $*.aux test -f $*.gif && chmod 644 $*.gif +.katex.html: + $(runkatex) -i $*.katex -o $*.html + test -f $*.html && chmod 644 $*.html + +ifeq ($(strip $(KATEX)),) all: ${gifs} +else +all: ${htmls} +endif ${gifs}: mathmacros -clean: ; /bin/rm -f *.gif Make.out +${htmls}: katexmacros + +clean: ; /bin/rm -f *.gif *.html Make.out diff --git a/math/katexmacros b/math/katexmacros new file mode 100644 index 0000000..03c2dbb --- /dev/null +++ b/math/katexmacros @@ -0,0 +1,2 @@ +\mbox:\text{#1} +\emph:\textit{#1} diff --git a/src/VERSION b/src/VERSION index 5625e59..7e32cd5 100644 --- a/src/VERSION +++ b/src/VERSION @@ -1 +1 @@ -1.2 +1.3 diff --git a/src/html-prep.ss b/src/html-prep.ss index cc3e94e..ad57f2e 100755 --- a/src/html-prep.ss +++ b/src/html-prep.ss @@ -65,6 +65,7 @@ ;;; \emph{...} ;;; \epsfbox{...} ;;; \genlab +;;; \schemeghostRightarrow ;;; \hindex{label}{stuff} (see below) ;;; \include{filename} ;;; \input{filename} @@ -131,6 +132,10 @@ (import (except (chezscheme) open-input-file) (dsm) (preplib) (script)) (define math-directory (make-parameter "math")) +(define use-katex? (make-parameter #f)) +(define katex-finished? (make-parameter #f)) +(define katex-css-link + (make-parameter "")) (define push-ofile (lambda (op ofiles) @@ -188,11 +193,13 @@ (format "~a.html" root) (format "~a_~d.html" root n))))]) (open-output-file fn 'replace))]) - (fprintf op "") + (fprintf op "~%") (fprintf op "~%") - (fprintf op "~%~%") + (fprintf op "~%~%") (fprintf op "~%") (fprintf op "~%~a~%" title) + (when (use-katex?) + (fprintf op "~a~%" (katex-css-link))) (when (header-stuff) (display (header-stuff) op)) (when (style-sheet) (fprintf op "\n" @@ -280,6 +287,13 @@ (define seqnarray* (lambda (ip op) ; within \begin{eqnarray*} ... \end{eqnarray*} + (when (use-katex?) + (input-error "environment eqnarray* not supported by KaTeX")) + ;; Might be viable to translate to \begin{align*} ... \end{align*} syntax, + ;; which KaTeX does support, or to add support for align* and encourage + ;; users to port there documents. See discussion in: + ;; https://www.tug.org/pracjourn/2006-4/madsen/madsen.pdf + ;; (especially sections 2.3 and 3) (let ([s (let ([buf (open-output-string)]) (let loop () (state-case (c (read-char ip)) @@ -312,6 +326,7 @@ (loop)]))] [(eof) (unexpected-eof "within \\[ ... \\]")] [else (write-char c buf) (loop)])))]) + ;; could add support for display mode when rendering with KaTeX (emit-math s op)))) (define emit-math @@ -319,7 +334,10 @@ (cond [(htmlmath (open-input-string s) #f) => (lambda (html) (display html op))] - [else (punt-to-latex (format "$~a$" s) op)]))) + [else (punt-to-latex (if (use-katex?) + s + (format "$~a$" s)) + op)]))) (define htmlmath (lambda (ip compact?) @@ -420,6 +438,22 @@ [(eof) (get-output-string buf)] [else (input-error "unexpected character ~s in math mode" c)]))))) +(define (file->string-sans-newline fn) + (define s + (call-with-port (open-input-file fn) get-string-all)) + (if (eof-object? s) + "" + (let* ([pos (- (string-length s) 1)] + [pos (and (nonnegative? pos) + (eqv? #\newline (string-ref s pos)) + (or (and (positive? pos) + (eqv? #\return (string-ref s (- pos 1))) + (- pos 1)) + pos))]) + (if pos + (substring s 0 pos) + s)))) + (define punt-to-latex (lambda (s op) (define latex-header @@ -433,22 +467,37 @@ " \\end{document} ") + (define outfn + (cond + [(assoc s (latex-cache)) => cdr] + [else + (let* ([fn (math-file-name)] + [texfn (format "~a.~a" fn (if (use-katex?) "katex" "tex"))] + [outfn (format "~a.~a" fn (if (use-katex?) "html" "gif"))]) + (latex-cache (cons (cons s (format "~a" outfn)) (latex-cache))) + ; don't rewrite file unless different to avoid need to remake output + (let ([s (if (use-katex?) + s + (format "~a~a~a" latex-header s latex-trailer))]) + (unless (guard (c [else #f]) + (equal? s (call-with-port (open-input-file texfn) get-string-all))) + (call-with-port (open-output-file texfn 'replace) + (lambda (texop) (display s texop))))) + outfn)])) (cond - [(assoc s (latex-cache)) => - (lambda (a) - (fprintf op "\"<graphic\">" (cdr a)))] - [else - (let* ([fn (math-file-name)] - [texfn (format "~a.tex" fn)] - [giffn (format "~a.gif" fn)]) - (fprintf op "\"<graphic\">" giffn) - (latex-cache (cons (cons s (format "~a" giffn)) (latex-cache))) - ; don't rewrite file unless different to avoid need to remake gif file - (let ([s (format "~a~a~a" latex-header s latex-trailer)]) - (unless (guard (c [else #f]) - (equal? s (call-with-port (open-input-file texfn) get-string-all))) - (call-with-port (open-output-file texfn 'replace) - (lambda (texop) (display s texop))))))]))) + [(and (use-katex?) + (guard (c [(not (katex-finished?)) #f]) + (file->string-sans-newline outfn))) => + (lambda (html) + (define (comment what) + (fprintf op "" what outfn)) + (comment "Beginning") + (display html op) + (comment "End"))] + [(use-katex?) + (fprintf op "Placeholder for KaTeX output from \"~a\"." outfn)] + [else + (fprintf op "\"<graphic\">" outfn)]))) (define math-file-name (let ([seq -1]) @@ -960,16 +1009,14 @@ (P s0)] [(#\-) (if convert-quotes - ; emit - for -- and --- for ---. IE4 and older versions of netscape - ; can't handle the proper HTML en-dash and em-dash encodings. (if (eqv? (peek-char ip) #\-) (begin (read-char ip) (if (eqv? (peek-char ip) #\-) (begin (read-char ip) - (display "---" op)) ; should be — - (display "-" op))) ; should be – + (display "—" op)) + (display "–" op))) (write-char c op)) (write-char c op)) (P s0)] @@ -1039,7 +1086,7 @@ (define emit-td (P lambda (k) - (fprintf (car ops) "~a" + (fprintf (car ops) "~a" (vector-ref (table-col-format colfmt) column) (get-output-string op)) (case (car pending) @@ -1690,9 +1737,13 @@ (global-def epsfbox (P lambda () - (fprintf op "

~%") - (punt-to-latex (format "\\input{epsf.sty}\\epsfbox{~a}" (read-bracketed-text ip)) op) - (fprintf op "

~%") + (let ([file (read-bracketed-text ip)]) + (when (use-katex?) + (input-error "macro \\epsfbox{~a} not supported by KaTeX" file)) + ;; might be better to render to SVG ... + (fprintf op "

~%") + (punt-to-latex (format "\\input{epsf.sty}\\epsfbox{~a}" file) op) + (fprintf op "

~%")) (P s0))) (global-def bibitem @@ -1741,6 +1792,18 @@ (display (genlab) op) (P s0))) +(global-def schemeghostRightarrow + (P lambda () + (cond + [(use-katex?) + (display "" op) + (emit-math "\\Rightarrow" op) + (display "" op)] + [else + ;; uses a special build process without KaTeX + (display "" op)]) + (P s0))) + (global-def hindex (P lambda () (P process-string () (read-bracketed-text ip) @@ -1828,7 +1891,7 @@ (display (if hard-spaces " " #\space) op) (P s0))) -(global-def |\| scr) +(global-def |\| scr);|; this comment fixes syntax highlighting in emacs (global-def usepackage (P lambda () @@ -1934,7 +1997,15 @@ (command-line-case (command-line) [((keyword --help)) (usage)] [((keyword --version)) (version)] - [((flags [--mathdir mathdir $ (math-directory mathdir)]) + [((flags [--mathdir mathdir $ (math-directory mathdir)] + [--use-katex $ (use-katex? #t)] + [--katex-css-link-file + linkfile $ (let ([html (file->string-sans-newline linkfile)]) + (use-katex? #t) + (unless (equal? "" html) + (katex-css-link html)))] + [--katex-finished $ (begin (use-katex? #t) + (katex-finished? #t))]) filename* ...) (for-each go (let ([found (find-filename "html-prep.tex")])