Opened 10 years ago

Last modified 3 weeks ago

#11362 needs_review defect

Repair show for Cayley tables as MathJax does not support setlength

Reported by: was Owned by: joyner
Priority: minor Milestone: sage-9.3
Component: group theory Keywords: latex, jupyter, mathjax
Cc: slelievre, klee Merged in:
Authors: Dave Morris Reviewers:
Report Upstream: N/A Work issues:
Branch: public/11362 (Commits, GitHub, GitLab) Commit: 71b0986c0ce5f2d0a4e8cdd37483125d7350c667
Dependencies: Stopgaps:

Status badges

Description (last modified by slelievre)

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.

Change History (15)

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

  • Cc slelievre added
  • 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:

7381952trac 11362 configurable mathjax macros
71b0986update doctests

comment:9 Changed 3 weeks ago by mkoeppe

  • Cc klee added

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: 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

Replying to 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, ...

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 b class OperationTable(SageObject): 
    10781078        table.append('\\end{array}')
    10791079        table.append('}')
    10801080        return ''.join(table)
     1081
     1082    def _html_(self):
     1083        n = self._n
     1084        names = self._names
     1085
     1086        # Headers
     1087        table = ['\\begin{array}{r|*{'+str(n)+'}{r}}\n']
     1088        table.append(self._latex_symbol)
     1089        table += ['&'+names[i] for i in range(n)]
     1090        table.append('\\\\\\hline\n')
     1091
     1092        # Row label and body of table
     1093        for g in range(n):
     1094            table.append('{}')  # Interrupts newline and [], so not line spacing
     1095            table.append(names[g])
     1096            for h in range(n):
     1097                table.append('&'+names[self._table[g][h]])
     1098            table.append('\\\\\n')
     1099
     1100        # Finish
     1101        table.append('\\end{array}')
     1102        return ''.join(table)
     1103
Note: See TracTickets for help on using tickets.