Opened 10 years ago

# Repair show for Cayley tables as MathJax does not support setlength

Reported by: Owned by: was joyner minor sage-9.3 group theory latex, jupyter, mathjax slelievre, klee Dave Morris N/A public/11362 71b0986c0ce5f2d0a4e8cdd37483125d7350c667

Define a finite group and its multiplication table:

sage: S = SymmetricGroup(3)
sage: T = S.multiplication_table()


The multiplication table can give latex code to be copy-pasted in a paper:

sage: latex(T)
\setlength{\arraycolsep}{2\ex}
\begin{array}{r|*{6}{r}}
\multicolumn{1}{c|}{\ast}&a&b&c&d&e&f\\\hline
{}a&a&b&c&d&e&f\\
{}b&b&a&d&c&f&e\\
{}c&c&e&a&f&b&d\\
{}d&d&f&b&e&a&c\\
{}e&e&c&f&a&d&b\\
{}f&f&d&e&b&c&a\\
\end{array}}


but is also used for showing the table in a notebook worksheet.

In Sage 4.8 with SageNB we used to have:

sage: show(T)
Unknown control sequence '\setlength'


In Sage 9.2.rc0 with Jupyter, show(T) does display a table but with \setlength displayed in red instead of contributing to the rendering.

### comment:1 Changed 10 years ago by rbeezer

I thought this was on #10787, but now I see it is not. I'm going to point it here.

I've been waiting on MathJax before tackling this, on the hope it has better support for tables.

### comment:2 Changed 8 years ago by jdemeyer

• Milestone changed from sage-5.11 to sage-5.12

### comment:3 Changed 7 years ago by vbraun_spam

• Milestone changed from sage-6.1 to sage-6.2

### comment:4 Changed 7 years ago by vbraun_spam

• Milestone changed from sage-6.2 to sage-6.3

### comment:5 Changed 7 years ago by vbraun_spam

• Milestone changed from sage-6.3 to sage-6.4

### comment:6 Changed 6 months ago by slelievre

• Description modified (diff)
• Keywords latex jupyter mathjax added
• Milestone changed from sage-6.4 to sage-9.3
• Summary changed from showing a Cayley table fails in the notebook due to bad latex code to Repair show for Cayley tables as MathJax does not support setlength

Still a problem in Jupyter Notebook with Sage 9.2.rc0.

### comment:7 Changed 7 weeks ago by gh-DaveWitteMorris

• Branch set to public/11362

### comment:8 Changed 7 weeks ago by gh-DaveWitteMorris

• Authors set to Dave Morris
• Commit set to 71b0986c0ce5f2d0a4e8cdd37483125d7350c667
• Status changed from new to needs_review

The PR adds a variable sage.misc.latex_macros.sage_configurable_mathjax_macros that holds a list of macro definitions that pretty_print will include in all LaTeX code that is sent to MathJax. The PR then solves the problem on this ticket by adding \multicolumn and \setlength to this list as no-ops that swallow their arguments.

New commits:

 ​7381952 trac 11362 configurable mathjax macros ​71b0986 update doctests

### comment:10 Changed 3 weeks ago by klee

I don't like the proposed solution. It seems a bandage.

A general solution that would also solve possible future problems would be to introduce a new magic method obj._mathjax_() which provides latex code renderable by mathjax and defaults to an alias of obj._latex_() when it is not defined for obj.

### comment:11 follow-up: ↓ 13 Changed 3 weeks ago by gh-DaveWitteMorris

I sympathize with what you are saying, and I considered that solution (except that my idea was to add a keyword (maybe style="MathJax") to the _latex_ command. But I don't see how to make it will work without massive changes, because an object that does not have a _mathjax_ method will presumably call the _latex_ method of its subobjects (or subexpressions) and will therefore not do the right thing for MathJax.

I think of MathJax as being a version of latex, rather than a completely different format, so I think it is reasonable to just add a tweak to make it work better (as in my PR). The variable I added simply makes it possible to add definitions for latex macros that MathJax does not understand, and is completely analogous to the variable sage_configurable_latex_macros that is already in sage, which makes it possible to add definitions for sage macros that vanilla latex does not understand.

### comment:12 Changed 3 weeks ago by klee

How about using _rich_repr_? This seems a general mechanism to serve the purpose that I have in mind about _mathjax_. There are many examples in Sage src.

### comment:13 in reply to: ↑ 11 Changed 3 weeks ago by klee

I sympathize with what you are saying, and I considered that solution (except that my idea was to add a keyword (maybe style="MathJax") to the _latex_ command. But I don't see how to make it will work without massive changes, because an object that does not have a _mathjax_ method will presumably call the _latex_ method of its subobjects (or subexpressions) and will therefore not do the right thing for MathJax.

I think of MathJax as being a version of latex, rather than a completely different format, ...

MathJax is a javascript renderer for latex in html, and also sometimes means the subset of latex it supports. On the other hand LaTeX is a format for TeX which primarily targets printing.

It seems to me currently there is some unfortunate confused code in this respect in the rich output system in Sage. Perhaps straightening the confused code would give a natural solution of this ticket's problem. I will investigate more.

### comment:14 Changed 3 weeks ago by slelievre

Related:

• #31536: Divorce MathJax from LaTeX and let it marry HTML

### comment:15 Changed 3 weeks ago by klee

With #31536, the following patch will solve the problem of this ticket.

• ## src/sage/matrix/operation_table.py

diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py
index 6feda2215a..8c066f11a9 100644
 a class OperationTable(SageObject): table.append('\\end{array}') table.append('}') return ''.join(table) def _html_(self): n = self._n names = self._names # Headers table = ['\\begin{array}{r|*{'+str(n)+'}{r}}\n'] table.append(self._latex_symbol) table += ['&'+names[i] for i in range(n)] table.append('\\\\\\hline\n') # Row label and body of table for g in range(n): table.append('{}')  # Interrupts newline and [], so not line spacing table.append(names[g]) for h in range(n): table.append('&'+names[self._table[g][h]]) table.append('\\\\\n') # Finish table.append('\\end{array}') return ''.join(table)
Note: See TracTickets for help on using tickets.