Repository navigation
Keep smart quotes off --option mentions in help text - #104
Open
chanellebingham wants to merge 1 commit into
Open
chanellebingham wants to merge 1 commit into
chanellebingham wants to merge 1 commit into
Conversation
With Sphinx's default smartquotes = True, an option mentioned in a description, epilog or help string was rendered as "–option" (en dash), so the documented text no longer matched what the command line accepts. This is based on Michael Mulqueen's implementation in sphinx-doc#101, which he withdrew in July: the same regular expression, helper functions and call sites, wrapping each "--option" mention in an inline node with support_smartquotes=False. Differences from sphinx-doc#101: - The skip check uses sphinx.util.nodes.is_smartquotable, the check the SmartQuotes transform itself uses, instead of looking only at the direct parent. Text nested deeper inside a literal block (emphasis in a parsed-literal) is no longer wrapped. The tested output is the same. - The sub-command usage line in :manpage: output is a strong node that smart quotes also rewrote ("[–fast]"); it is now marked as not smart-quotable as a whole. - The test sample is loaded with :module: rather than :filename:, so coverage measures it. Its file name is importable, so no .ruff.toml change is needed. - A second test page covers the :manpage: output. - The etree test fixture reads the built HTML as UTF-8. The new pages contain curly quotes, and the default encoding on Windows is cp1252. Fixes sphinx-doc#100 Co-authored-by: Michael Mulqueen <6616321+mmulqueen@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #104 +/- ##
==========================================
+ Coverage 50.79% 56.25% +5.46%
==========================================
Files 19 20 +1
Lines 1323 1367 +44
Branches 269 277 +8
==========================================
+ Hits 672 769 +97
+ Misses 605 543 -62
- Partials 46 55 +9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #100
With Sphinx's default
smartquotes = True, an option mentioned in a description, epilog or help string renders as–option(en dash), so the documented text no longer matches what the command line accepts. The option names in the option list are not affected; only prose is.This is based on @mmulqueen's implementation in #101, which he withdrew in July. The regular expression, the
_protect_option_dashes()and_option_safe_paragraph()helpers (apart from the skip check below) and all the call sites are his: each--optionmention in parser-supplied text is wrapped in a plaininlinenode withsupport_smartquotes=False, which the SmartQuotes transform skips. The commit has aCo-authored-bytrailer for him.What differs from #101
:manpage:usage line. The sub-command usage line is astrongnode, and smart quotes rewrote it too (run [-h] [–fast]). It is now markedsupport_smartquotes=Falseas a whole. Built with Prevent smartquotes from rewriting option dashes. #101's code, this is the only thing the new tests catch: 27 of their 29 assertions pass, and the 2 that fail are this line.literalorFixedTextElement. This usessphinx.util.nodes.is_smartquotable, the check the SmartQuotes transform itself uses, which looks at every ancestor. So text deeper inside a literal block (for example emphasis in aparsed-literal) is not wrapped. The tested output is the same either way.:module:instead of:filename:, so coverage measures it (Prevent smartquotes from rewriting option dashes. #101's sample showed as 0%). Its file name is importable, so no.ruff.tomlchange is needed. A second test page covers:manpage:output.cached_etree_parsenow opens the built HTML withencoding='utf-8'. The new pages contain curly quotes, and the default encoding on Windows is cp1252. Linux CI is unaffected.Tests
Two pages in the
default-htmltest root loadtest/sample_smartquotes.py:smartquotes.html(default output): option mentions in the description, option help, epilog and sub-command help keep both hyphens, and no–input,–output,–verboseor–quietappears anywhere on the page. An option already written as an inline literal (--modein double backticks) is not wrapped a second time. The epilog still reads “like these”,– like this –andeast–west, and prose written in the directive body still gets its en dash.smartquotes-manpage.html(:manpage:): the same for the description, epilog, option help, sub-command help and thePossible choices:line, and the usage line readsrun [-h] [--fast]. In this mode help text is not parsed as reST (that was already the case), so the inline-literal check applies to the default page only.Local results with the CI command,
python -m pytest -vv --cov . --cov-append --cov-config pyproject.toml(Windows, Python 3.13, Sphinx 9.1.0, docutils 0.22.4):main: 50 passed, 1 skipped.sphinxarg/ext.pyput back tomain: 2 failed, 50 passed, 1 skipped (did not find any node matching xpath './/p/span'). The page contains<p>Read –input and write the result to –output.</p>.<p>Read <span>--input</span> and write the result to <span>--output</span>.</p>.ruff check . --output-format github,ruff format . --diff,mypy,python -m buildandtwine checkpass.Sphinx 5.1.0, the minimum in
pyproject.toml: the test suite doesn't run there, onmaineither, because therootdirfixture returns apathlib.Pathand Sphinx 5.1's fixtures call.copytree()on it. Instead, the two test pages were built withsphinx-buildunder Sphinx 5.1.0 and docutils 0.19 (Python 3.12), and the test's 29 xpath assertions were checked against that HTML: 29 of 29 pass with this change, 12 of 29 onmain.Notes
_format_positional_arguments()gets the same change but is unreachable today:parse_parser()never sets anargskey. So those lines show as uncovered.The Markdown help path (
:markdownhelp:) goes through the same helper. CommonMark isn't in thetestextra, so CI doesn't cover it. Built by hand with CommonMark 0.9.2,mainrenders–inputthree times,–outputtwice,–verboseand–quiet; with this change all seven are<span>--option</span>.The other test roots use
:filename:. Happy to switch this one to match if you prefer; the sample would then show as uncovered.No changelog entry, since the changelog looks like it's written at release time. If you'd like one in this PR, this fits the existing style: