- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Remove productionlist
hard-coding in translators
#13326
Conversation
@AA-Turner I will look on how to follow up on LaTeX aspects. Unrelated: I observed in HTML (and also PDF) output that with this change there is only one space after |
The current LaTeX code uses a table, and injects the With this change the As a try I decided to mimic the HTML which uses diff --git a/sphinx/texinputs/sphinxlatexobjects.sty b/sphinx/texinputs/sphinxlatexobjects.sty
index e960440ca..c62d414f6 100644
--- a/sphinx/texinputs/sphinxlatexobjects.sty
+++ b/sphinx/texinputs/sphinxlatexobjects.sty
@@ -281,16 +281,8 @@
% Production lists
%
\newenvironment{productionlist}{%
-% \def\sphinxoptional##1{{\Large[}##1{\Large]}}
- \def\production##1##2{\\\sphinxcode{\sphinxupquote{##1}}&::=&\sphinxcode{\sphinxupquote{##2}}}%
- \def\productioncont##1{\\& &\sphinxcode{\sphinxupquote{##1}}}%
- \parindent=2em
- \indent
- \setlength{\LTpre}{0pt}%
- \setlength{\LTpost}{0pt}%
- \begin{longtable}[l]{lcl}
-}{%
- \end{longtable}
+ \bigskip\obeylines\parskip\z@skip\@vobeyspaces\ttfamily
+}{\par
}
% Definition lists; requested by AMK for HOWTO documents. Probably useful
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 72c7e9b3b..59816c76c 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -678,20 +678,10 @@ def depart_productionlist(self, node: Element) -> None:
self.in_production_list = False
def visit_production(self, node: Element) -> None:
- if node['tokenname']:
- tn = node['tokenname']
- self.body.append(self.hypertarget(f'grammar-token-{tn}'))
- self.body.append(r'\production{%s}{' % self.encode(tn))
- else:
- self.body.append(r'\productioncont{')
-
- # remove name/padding and seperator child nodes,
- # these are handled by '\production' and '\productioncont'
- # TODO: remove special LaTeX handling of production nodes
- node[:] = node[2:]
+ pass
def depart_production(self, node: Element) -> None:
- self.body.append('}' + CR)
+ pass
def visit_transition(self, node: Element) -> None:
self.body.append(self.elements['transition']) This worked well but there is annoying problem with continuation lines: The original reST being:
The problem here is that inside the \begin{productionlist}
A ::= B C D E F G
\end{productionlist} where there are extra spaces before the But right now I discover that the "line continuation problem" exists with HTML even with current Sphinx master, unrelated to this branch. It did not show in PDF output because LaTeX collapses by default contiguous spaces. Here is a snapshot from an HTML produced from above reST using current master: Here it is with this branch: So the problem with line continuation rendering is not a disqualifier for the above proposed patch for LaTeX rendering. (I should probably try to imitate more the former vertical spacing, as per inducing some extra padding at start of lines as was induced by usage a "longtable" this is a bit more annoying and would have to go via a re-definition of the |
sorry, it is very easy actually I only have to use (edited) % Production lists
%
\newenvironment{productionlist}{%
\bigskip\obeylines\parindent10pt\parskip\z@skip\@vobeyspaces\ttfamily\indent
}{\par
} What do you think @picnixz about this somewhat basic but working LaTeX way with above environment |
There will be an issue when having a multi-line production list. Previously, we could write something like: .. productionlist::
try1_stmt: "try" ":" `suite`
: ("except" [`expression` ["as" `identifier`]] ":" `suite`)+
: ["else" ":" `suite`]
: ["finally" ":" `suite`] and this would render as https://docs.python.org/3/reference/compound_stmts.html#the-try-statement with something like
Without a longtable, we won't be able to align the multi-line declarations, unless the LaTeX writer recomputes the length to skip (we would need to compute how wide the prefix + separator are so that we can change the |
@picnixz It seems to render fine: (PDF with my patch on top of this branch) Here is how it looks currently with Sphinx master, to compare: (PDF with current master) I mentioned in previous comment about the spaces following But I see now a reduction in spacing around (in the above test I removed the ticks from input to avoid complaints about missing references in the build)
The spaces are there in the node, and via |
I tested the code is compatible with page breaks. |
Ah yes, we're keeping the whitespaces (and this is also the reason why the continuation line had issues). Ok my bad.
I had this follow-up question about production lists spanning multiple pages but you answered it :') |
I made the LaTeX support at latex_prodlist (HEAD commit, which is on top of current HEAD of the present branch; I hesitated to push directly to this PR, if at all possible). Afaict things are ok. Subtleties are documented for maintainers of the 22nd century.
|
Thank you for the suggested changes to the LaTeX writer!
I'm happy to revert to two spaces, we now normalise whitespace which explains the change to A |
@AA-Turner I am realizing only now something problematic. Even before this PR not all links worked in PDF output (if one uses for example the |
The HTML targets ( For the texinfo writer, I had to add: def visit_literal_strong(self, node: Element) -> None:
if self.in_production_list:
for id_ in node['ids']:
self.add_anchor(id_, node)
return |
@AA-Turner brief testing seems to indicate this commit is fine. I modelled it on your texinfo support code. (edit: CI test failure appears to be unrelated with this PR) It actually fixes an issue which had gone unnoticed! With the test as configured in |
Purpose
The
productionlist
directive operates in a line-based context, creating anaddnodes.productionlist
container ofaddnodes.production
nodes, with one per production in the directive. However, the full state of the abstract document tree is not included in the produced nodes, with each builder/translator implementing a different way of appending the fixed separator::=
and justifying the displayed text.This should not happen in the writer, and hard-coding such details hampers flexibility when documenting different abstract grammars (e.g. python/cpython#127835). We should move the specific form of the
.. productionlist::
directive to the logic in the directive body, and have the writers apply minimal custom logic.Open questions
The design as in this PR is split up into several different methods (e.g.
make_production
,production_separator
,production_definitions
) for overriding downstream to implement different grammars. However, we might want to introduce a more flexible alternate directive (such as @encukou's 'grammar-snippet
') instead. Is this extra complexity of several methods worth it?The LaTeX translator still uses the macros originally introduced in 2007, I am not confident about changing them. @jfbu would you be able to suggest an approach here?
https://github.com/sphinx-doc/sphinx/blob/master/sphinx/texinputs/sphinxlatexobjects.sty#L281-L294
References
grammar-snippet
directive & replaceproductionlist
python/cpython#127835A