Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

have backslash also be an inline literal word wrap break character in LaTeX #6000

Closed
kenyon opened this issue Feb 2, 2019 · 8 comments
Closed
Assignees
Labels
type:enhancement enhance or introduce a new feature
Milestone

Comments

@kenyon
Copy link
Contributor

kenyon commented Feb 2, 2019

Is your feature request related to a problem? Please describe.
When long Windows filename paths (directories separated by backslash (\) characters) are used with the :file: role, they are not word wrapped, they just keep going off the side of the page.

Describe the solution you'd like
The backslash character should also be a word wrap break character.

Describe alternatives you've considered
Tried to use \renewcommand*\sphinxbreaksafteractivelist {\do\.\do\,\do\;\do\?\do\!\do\/\do\\} in my preamble to add backslash, but get this error when building:

! You can't use `macro parameter character #' in horizontal mode.

Additional context
#3116, #2943, #3110

@kenyon kenyon added the type:enhancement enhance or introduce a new feature label Feb 2, 2019
@jfbu
Copy link
Contributor

jfbu commented Feb 2, 2019

Thanks for reporting. When used as is \ in a ``\C\aaa``, or escaped as \\ in a :file:`\\C\\aaa` , the backslash ends us as \textbackslash{} in LaTeX code.

So the trick would be to hack into \sphinxupquote macro to modify behaviour of \textbackslash{} within it to allow line breaks. (I will provide a way later, unfortunately does not have it seems a clear hook entry point).

On the other hand inside a code-block, the backslash is escaped by Pygmentize library into \PYGbs macro. But your question made me realize that Sphinx does nothing special regarding linebreaks for this: it is omitted from both \sphinxbreaksbeforelist and \sphinxbreaksafterlist macros. Perhaps because it was not known what was best: to break before it or break after it at end of line, or perhaps simply an oversight. I will open an issue on this.

But your issue is another one, it regards \textbackslash{} behaviour.

@jfbu
Copy link
Contributor

jfbu commented Feb 2, 2019

As a temporary workaround, use either this

latex_elements = {
    'preamble': r'''
\let\origbs\textbackslash
\newcommand\allowbreaksbeforebackslashinliterals{%
  \def\textbackslash{\discretionary{}{\origbs}{\origbs}}% breaks before \
}%
\makeatletter
\g@addto@macro\sphinx@literal@nolig@list{\allowbreaksbeforebackslashinliterals}
\makeatother
''',
}

or that

latex_elements = {
    'preamble': r'''
\let\origbs\textbackslash
\newcommand\allowbreaksafterbackslashinliterals {%
  \def\textbackslash{\discretionary{\origbs}{}{\origbs}}% breaks after \
}%
\makeatletter
\g@addto@macro\sphinx@literal@nolig@list{\allowbreaksafterbackslashinliterals}
\makeatother
''',
}

depending on whether you want linebreak before or after. I don't know which is best. Notice that the above is a bit of a hack, mis-using internal macro \sphinx@literal@nolig@list which gets expanded only inside \sphinxupquote usage, but this is simplest manner to hack into the latter.

@jfbu
Copy link
Contributor

jfbu commented Feb 2, 2019

Memo: our doc says

... linebreaks inside inline literals: .. potential break-points (additionally to those allowed by LaTeX at spaces or for hyphenation) are currently inserted only after the characters . , ; ? ! /.

on the other hand linebreaks in code blocks may occur at more characters:

% Take advantage of the already applied Pygments mark-up to insert
% potential linebreaks for TeX processing.
%        {, <, #, %, $, ' and ": go to next line.
%        _, }, ^, &, >, - and ~: stay at end of broken line.

As said above, for some reason the backslash isn't in this list, but anyway this enhancement request could be taken as meaning to also handle (some of) the listed characters above as potential break points in inline literals.

@jfbu jfbu added this to the 2.3.0 milestone Sep 14, 2019
@jfbu jfbu self-assigned this Sep 14, 2019
@bradfox2
Copy link

bradfox2 commented Oct 29, 2019

Hi JFBU,

I am seeing similar behavior with long single strings inside of table cells, such as a long number or file paths. You may consider looking at this as well. It is causing hbox overfill warning, and then flowing through neighbor cells, and eventually off page.

@jfbu
Copy link
Contributor

jfbu commented Nov 6, 2019

@bradfox2 Unfortunately LaTeX (and Plain TeX) is unable by itself only without extra mark-up to split long numbers across lines. It has no mechanism for that. Even for letters, the existing mechanism is based on hyphenation patterns which might serve nothing for long URLs. Besides TeX can not split a long word which is the very first one in a paragraph, like in a table cell, but it is possible that if your LaTeX installation is recent enough the table environments incorporate a workaround (which consists of adding something invisible at start of table cell so that TeX does not consider the first word to be the first encountered thing).

There are somewhat complicated methods to allow linebreaking, like is done currently by Sphinx LaTeX for inline literals. To fix your issue with long numbers it would be needed to at least have some extra LaTeX markup to trigger the LaTeX macros achieving this. It could be envisioned to hack deep into LaTeX table environments to do that automatically but there are some many technical complications (making the digits "active TeX tokens" which would be an option is extremely fragile), so the only reasonable way would be to require extra mark-up in reST source. But then why not split oneself the number manually in source ? this looks like only general approach.

Sorry about that. Of course if someone has a pull request it will be examined with gratitude.

As for this issue, it regards only inline literals. I will take care of it shortly.

@jfbu
Copy link
Contributor

jfbu commented Nov 6, 2019

But then why not split oneself the number manually in source ? this looks like only general approach.

Here is very cumbersome approach:

.. |LH| raw:: latex

              \hspace{0pt}

.. tabularcolumns:: |p{2cm}|p{2cm}|p{2cm}|
.. list-table::

   * - |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234\ |LH|\ 1234
     - b
     - c

where LH stands for "LaTeX hyphenate". I did this once in the Sphinx doc itself, to allow hyphenation of first word in a cell. But then |LH|\ was used only once. Here I use it along the numbers.

PDF output:

Capture d’écran 2019-11-06 à 16 25 53

Of course something like this can only be used in an emergency situation and is not maintanable if source evolves a lot or is otherwise generated (by extensions for example)

jfbu added a commit to jfbu/sphinx that referenced this issue Nov 6, 2019
Default configuration is to allow the linebreak after the backslash.
It is possible at user side via 'preamble' key and some LaTeX code
to allow the linebreak before the backslash, but each of inline-literal,
code-block, and parsed-literal has its more or less cumbersome way for
that.

Closes: sphinx-doc#6000

This commit handles only the \ character, which had been left aside
by accident so far. Inline-literals could break at more characters
but this is not yet done in this commit. In this context, in future
it could be useful to modify sphinx.util.texescape to use mark-up
such as \sphinxtextbackslash rather than naked \textbackslash and
similarly for some other characters. This could then be used to
allow linebreaks even in regular text paragraphs.
jfbu added a commit to jfbu/sphinx that referenced this issue Nov 6, 2019
Default configuration is to allow the linebreak after the backslash.
It is possible at user side via 'preamble' key and some LaTeX code
to allow the linebreak before the backslash, but each of inline-literal,
code-block, and parsed-literal has its more or less cumbersome way for
that.

Closes: sphinx-doc#6000, sphinx-doc#6001

This commit handles only the \ character, which had been left aside
by accident so far. Inline-literals could break at more characters
but this is not yet done in this commit. In this context, in future
it could be useful to modify sphinx.util.texescape to use mark-up
such as \sphinxtextbackslash rather than naked \textbackslash and
similarly for some other characters. This could then be used to
allow linebreaks even in regular text paragraphs.
@jfbu
Copy link
Contributor

jfbu commented Nov 7, 2019

Done at a7f53a7. Once 2.3.0 is released, stop using the workarounds above.

Thanks for reporting.

@jfbu jfbu closed this as completed Nov 7, 2019
@bradfox2
Copy link

bradfox2 commented Nov 7, 2019

@jfbu

Thank you for taking the time to reply. I will evaluate your responses.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 31, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type:enhancement enhance or introduce a new feature
Projects
None yet
Development

No branches or pull requests

3 participants