spec icon indicating copy to clipboard operation
spec copied to clipboard

Bikeshed is stripping backslashes from some latex newline commands

Open dschuff opened this issue 1 year ago • 5 comments

Some latex tables in the core spec use the extra space argument to add extra vertical space between table rows, e.g. the \\[1ex] on line 660 of this example from https://github.com/WebAssembly/spec/blob/main/document/core/exec/runtime.rst?plain=1#L655-L664

.. math::
   \begin{array}{rcl}
   S; F; E[\instr^\ast] &\stepto& S'; F'; E[{\instr'}^\ast] \\
     && (\iff S; F; \instr^\ast \stepto S'; F'; {\instr'}^\ast) \\
   S; F; \FRAME_n\{F'\}~\instr^\ast~\END &\stepto& S'; F; \FRAME_n\{F''\}~\instr'^\ast~\END \\
     && (\iff S; F'; \instr^\ast \stepto S'; F''; {\instr'}^\ast) \\[1ex]
   S; F; E[\TRAP] &\stepto& S; F; \TRAP
     \qquad (\iff E \neq [\_]) \\
   S; F; \FRAME_n\{F'\}~\TRAP~\END &\stepto& S; F; \TRAP \\
   \end{array}

After sphinx, the content of bikeshed_singlehtml/index_fixed.html is

<div class="math notranslate nohighlight">
\[\begin{split}\begin{array}{rcl}
S; F; E[\href{#syntax-instr}{\mathit{instr}}^\ast] &amp;\href{#exec-notation}{\hookrightarrow}&amp; S'; F'; E[{\href{#syntax-instr}{\mathit{instr}}'}^\ast] \\
  &amp;&amp; (\mathrel{\mbox{if}} S; F; \href{#syntax-instr}{\mathit{instr}}^\ast \href{#exec-notation}{\hookrightarrow} S'; F'; {\href{#syntax-instr}{\mathit{instr}}'}^\ast) \\
S; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F'\}~\href{#syntax-instr}{\mathit{instr}}^\ast~\href{#syntax-instr-control}{\mathsf{end}} &amp;\href{#exec-notation}{\hookrightarrow}&amp; S'; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F''\}~\href{#syntax-instr}{\mathit{instr}}'^\ast~\href{#syntax-instr-control}{\mathsf{end}} \\
  &amp;&amp; (\mathrel{\mbox{if}} S; F'; \href{#syntax-instr}{\mathit{instr}}^\ast \href{#exec-notation}{\hookrightarrow} S'; F''; {\href{#syntax-instr}{\mathit{instr}}'}^\ast) \\[1ex]
S; F; E[\href{#syntax-trap}{\mathsf{trap}}] &amp;\href{#exec-notation}{\hookrightarrow}&amp; S; F; \href{#syntax-trap}{\mathsf{trap}}
  \qquad (\mathrel{\mbox{if}} E \neq [\_]) \\
S; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F'\}~\href{#syntax-trap}{\mathsf{trap}}~\href{#syntax-instr-control}{\mathsf{end}} &amp;\href{#exec-notation}{\hookrightarrow}&amp; S; F; \href{#syntax-trap}{\mathsf{trap}} \\
\end{array}\end{split}\]</div>

When Bikeshed processes the file, it strips out one of the backslashes:

         <div class="math notranslate nohighlight"> \[\begin{split}\begin{array}{rcl}
S; F; E[\href{#syntax-instr}{\mathit{instr}}^\ast] &amp;\href{#exec-notation}{\hookrightarrow}&amp; S'; F'; E[{\href{#syntax-instr}{\mathit{instr}}'}^\ast] \\
  &amp;&amp; (\mathrel{\mbox{if}} S; F; \href{#syntax-instr}{\mathit{instr}}^\ast \href{#exec-notation}{\hookrightarrow} S'; F'; {\href{#syntax-instr}{\mathit{instr}}'}^\ast) \\
S; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F'\}~\href{#syntax-instr}{\mathit{instr}}^\ast~\href{#syntax-instr-control}{\mathsf{end}} &amp;\href{#exec-notation}{\hookrightarrow}&amp; S'; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F''\}~\href{#syntax-instr}{\mathit{instr}}'^\ast~\href{#syntax-instr-control}{\mathsf{end}} \\
  &amp;&amp; (\mathrel{\mbox{if}} S; F'; \href{#syntax-instr}{\mathit{instr}}^\ast \href{#exec-notation}{\hookrightarrow} S'; F''; {\href{#syntax-instr}{\mathit{instr}}'}^\ast) \[1ex]
S; F; E[\href{#syntax-trap}{\mathsf{trap}}] &amp;\href{#exec-notation}{\hookrightarrow}&amp; S; F; \href{#syntax-trap}{\mathsf{trap}}
  \qquad (\mathrel{\mbox{if}} E \neq [\_]) \\
S; F; \href{#syntax-frame}{\mathsf{frame}}_n\{F'\}~\href{#syntax-trap}{\mathsf{trap}}~\href{#syntax-instr-control}{\mathsf{end}} &amp;\href{#exec-notation}{\hookrightarrow}&amp; S; F; \href{#syntax-trap}{\mathsf{trap}} \\
\end{array}\end{split}\]</div>

Later this break's katex's rendering of the latex. I'm not yet sure what's happening here, e.g. whether this is somehow an intended behavior of Bikeshed, or a bug, or what.

dschuff avatar Oct 04 '24 18:10 dschuff

@tabatkins maybe you can give some insight on what might be happening? I'm happy to send you a full reproducer or chat offline.

dschuff avatar Oct 04 '24 18:10 dschuff

Yes, this is intended, and is part of Bikeshed's Markdown support. Whenever it sees \[, it converts it to [ and skips ahead (this allows you to escape macros; if you wanted a literal [FOO] in your spec, you'd write it as \[FOO] to avoid it being parsed as a macro).

Bikeshed recognizes the concept of "opaque elements" within which it skips its Markdown and Markdown-adjacent processing, like autolinks (this happens in pre/xmp/style/script elements, and anything with a bs-opaque attribute), but macro handling is still done inside of these elements (and this is depended on by a number of specs).

For now, the easy fix is to escape the offending \ character - output \&#x5c;[1ex] instead. I should add an option to turn off macro processing in a subtree, tho.

tabatkins avatar Oct 04 '24 19:10 tabatkins

It's odd actually, because there are a lot of instances of \[ in the document, and they don't get touched. There are also instances such as ... \phantom{thisshouldbeenough} \\[-2ex] &amp;&amp;|&amp; and ~\\[1ex] (inside similar divs) that don't get touched, It only seems to be \\[1ex];

dschuff avatar Oct 04 '24 22:10 dschuff

Also, applying the escape sequence above works perfectly for the \\[1ex] sequences (i.e. replace them with \&#x5c;\[1ex] in the source)... but doing the same for the \\[-2ex] sequences that weren't being touched before (or escaping the second slash instead of the first, i.e. \\[1ex]->\\&#x5c;[1ex]) the result is a triple slash...🤔

Anyway thanks for the help, I can get by with a narrowly targeted replacement for now.

dschuff avatar Oct 05 '24 01:10 dschuff

Sorry, yeah, to be more specific, it only triggers when the stuff following the \[ "looks like a macro", which is pretty limited.

Anyway, I'll fix this with https://github.com/speced/bikeshed/issues/2931 soon so you can avoid having to worry about this.

tabatkins avatar Oct 20 '24 18:10 tabatkins