diff --git a/CHANGES b/CHANGES index fcab95b7462..87631799952 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Features added 3.10 or above * #9447: html theme: Expose the version of Sphinx in the form of tuple as a template variable ``sphinx_version_tuple`` +* #9594: manpage: Suppress the title of man page if description is empty * #9445: py domain: ``:py:property:`` directive supports ``:classmethod:`` option to describe the class property * #9524: test: SphinxTestApp can take ``builddir`` as an argument diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index d3eb462a0d3..a6607e57eb9 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2331,6 +2331,8 @@ These options influence manual page output. *description* Description of the manual page. This is used in the NAME section. + Can be an empty string if you do not want to automatically generate + the NAME section. *authors* A list of strings with authors, or a single string. Can be an empty diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py index 90f3accbfd7..12fc31281bc 100644 --- a/sphinx/writers/manpage.py +++ b/sphinx/writers/manpage.py @@ -112,9 +112,10 @@ def __init__(self, document: nodes.document, builder: Builder) -> None: # overwritten -- added quotes around all .TH arguments def header(self) -> str: tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\"" - " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n" - ".SH NAME\n" - "%(title)s \\- %(subtitle)s\n") + " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n") + if self._docinfo['subtitle']: + tmpl += (".SH NAME\n" + "%(title)s \\- %(subtitle)s\n") return tmpl % self._docinfo def visit_start_of_file(self, node: Element) -> None: diff --git a/tests/test_build_manpage.py b/tests/test_build_manpage.py index 3680d8651be..e2479e4de77 100644 --- a/tests/test_build_manpage.py +++ b/tests/test_build_manpage.py @@ -23,6 +23,9 @@ def test_all(app, status, warning): assert r'\fBprint \fP\fIi\fP\fB\en\fP' in content assert r'\fBmanpage\en\fP' in content + # heading (title + description) + assert r'sphinxtests \- Sphinx 0.6alpha1' in content + # term of definition list including nodes.strong assert '\n.B term1\n' in content assert '\nterm2 (\\fBstronged partially\\fP)\n' in content @@ -35,6 +38,15 @@ def test_all(app, status, warning): assert 'Footnotes' not in content +@pytest.mark.sphinx('man', testroot='basic', + confoverrides={'man_pages': [('index', 'title', None, [], 1)]}) +def test_man_pages_empty_description(app, status, warning): + app.builder.build_all() + + content = (app.outdir / 'title.1').read_text() + assert r'title \-' not in content + + @pytest.mark.sphinx('man', testroot='basic', confoverrides={'man_make_section_directory': True}) def test_man_make_section_directory(app, status, warning):