sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.44k stars 2.1k forks source link

improve width of tables in PDF, if ``:widths:`` option in use #3411

Open jfbu opened 7 years ago

jfbu commented 7 years ago

Currently on Sphinx master branch, the Docutils 0.13 new :widths: option for table is implemented via a tabular or a longtable environment with Sphinx custom \X column specifier. This column specifier specifies the width of the column as a fraction of \linewidth. This is not satisfying, obviously, when the table is a small one, as the columns are stretched horizontally to fill all available space. Problem is that LaTeX has no easy (immediate) means to guess what would be a good width.

Docutils in the case of grid tables offers the value grid for :widths:. The colspec then is a list of integers which give the widths in terms of how many ascii characters in the rst source of the grid table. A possibility then for LaTeX to guess a not too bad target width for the table would be to multiply some reasonable dimension, say the width of X in the current font by the sum of all these integers

It is easy to modify the \X specifier to accept the third argument replacing \linewidth. One could use the guessed width, and possibly replace it by \linewidth if it exceeds it.

The value of the unit width could also be made a latex conf.py variable, rather than the width of X as suggested above (some languages will not use Latin Alphabet anyhow).

Problem however is that :widths: is interpreted by Sphinx as proportions. Hence currently 300, 700 is equivalent to 30, 70. It is not clear from Docutils doc if this is correct way to interpret the :widths:. Further the case when grid value was used can not be distinguished it seems from case when user wrote the spec herself. Which is a pity because when grid value is used we could apply the recipe above to interpret the integers as some absolute targets of sorts.

By the way, tabulary has advantage that given a target width, if the natural table width (all cells of row on one line) is smaller, tabulary uses the smaller width. But there is no interface with tabulary to tell it: this column shall occupy 30% of final width. All that tabulary does is "that column will occupy a proportion given by the ratio of its natural width to the total natural width". Hence we can't use intelligently the colspec from Docutils :widths: option with tabulary, and we are back to having to guess final correct table width.

Things would become much easier if Docutils implemented (in addition to :widths:) also a :width: option as exists already for figures. Turns out a proposed patch exists already precisely about this, on the issue tracker. But currently, we can only imagine use of an extra directive on Sphinx side either of the .. tablewidth:: type or .. widthsunit:: type which would give the absolute dimension to be used for the :widths: colspec. But it is not too good to add directives specific to target format as it generally means mark-up is increased in the source.

jfbu commented 7 years ago

The tabu package is now five years old and its X column type, together with spread 0pt has the possibility to implement the integers from the :widths: Docutils colspec while escaping the need for an explicit target width, which was described at length above.

The package also provides a longtabu allowing page-breaks; but quick investigation shows there is some work needed to let it work with source code (code-block) in its contents, if at all possible, like is currently achieved using longtable and sphinxVerbatimintable.

tk0miya commented 7 years ago

FYI:

Further the case when grid value was used can not be distinguished it seems from case when user wrote the spec herself.

We can distinguish them by using table_node['classes']. If user specified the spec, the colwidths-given is added into the classes list.

jfbu commented 7 years ago

We can distinguish them by using table_node['classes']. If user specified the spec, the colwidths-given is added into the classes list.

ah thanks, I had wrongly thought colwidths-given was always present in case grid because default is auto, not grid.