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

manpage builder doesn't put title in external references #10269

Closed
CendioOssman opened this issue Mar 16, 2022 · 5 comments
Closed

manpage builder doesn't put title in external references #10269

CendioOssman opened this issue Mar 16, 2022 · 5 comments

Comments

@CendioOssman
Copy link

Describe the bug

If I put references in a page that references another page then the produced man page will have the internal identifier rather than the title of the reference.

How to Reproduce

E.g.

Too see more details about this please see :ref:`foobar`.

This currently renders as Too see more details about this please see foobar..

Expected behavior

At the very least the title should replace the reference Too see more details about this please see "Foo bar feature".

Your project

N/A

Screenshots

No response

OS

Linux

Python version

3.6.12

Sphinx version

4.2.0

Sphinx extensions

No response

Extra tools

No response

Additional context

Given that the rest of the document isn't available, even more control would be nice. E.g. something like
numfig_format where you can give an expression for how external references should be handled.

You could then get something like: Too see more details about this please see "Foo bar feature" (in the System Manual).

@CendioOssman
Copy link
Author

The cause of this seems to be this code:

def get_target_uri(self, docname: str, typ: str = None) -> str:
if typ == 'token':
return ''
raise NoUri(docname, typ)

The fallback from NoURI seems to just inject the reference id. If I change that function to return something then I get the title in the output instead.

@CendioOssman
Copy link
Author

Quick hack extension to work around this:

#
# Extension that makes prettier external references in man pages
#

from docutils import nodes
from sphinx import addnodes
from sphinx.transforms.post_transforms import SphinxPostTransform

class ManReferenceTransform(SphinxPostTransform):
    default_priority = 9

    def is_supported(self):
        return self.app.builder.name == "man"

    def run(self):
        for node in self.document.traverse(addnodes.pending_xref):
            if 'refdomain' not in node:
                continue

            domain = self.env.domains[node['refdomain']]
            typ = node['reftype']
            target = node['reftarget']

            if typ == 'ref':
                typ = 'label'

            for name, dispname, objtype, docname, anchor, prio in domain.get_objects():
                if typ != objtype:
                    continue
                if name != target:
                    continue

                newnode = nodes.inline(dispname, '"%s" <%s>' % (dispname, self.app.config.project))
                node.replace_self(newnode)

def setup(app):
    app.add_post_transform(ManReferenceTransform)

    return { "parallel_read_safe": True,
             "parallel_write_safe": True }

@tk0miya
Copy link
Member

tk0miya commented Mar 20, 2022

On my local, it works well (replaced by its title). Could you share an example project to reproduce this trouble, please?

@CendioOssman
Copy link
Author

That's odd. I generated something with sphinx-quickstart here and could easily see the issue.

conf.py:

project = 'Foobar'
copyright = '2022, Me'
author = 'Me'

man_pages = [
    ('util', 'util', 'foo bar', None, 1),
]

index.rst:

.. Foobar documentation master file, created by
   sphinx-quickstart on Mon Mar 21 12:23:14 2022.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Foobar's documentation!
==================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   util

.. _index:

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

util.rst:

util
====

Synopsis
--------

**util** [*options*]

Description
-----------

**util** is great! See :ref:`index`.

From this I get:

..
.SH SYNOPSIS
.sp
\fButil\fP [\fIoptions\fP]
.SH DESCRIPTION
.sp
\fButil\fP is great! See index\&.
.SH COPYRIGHT
2022, Me
.\" Generated by docutils manpage writer.
.

@tk0miya
Copy link
Member

tk0miya commented Mar 21, 2022

Thank you for the info! Reproduced. I wrongly put a reference to the same page. Now I perfectly understand the problem. As you reported, the root cause of this problem is ManualPageBuilder.get_target_uri().

tk0miya added a commit to tk0miya/sphinx that referenced this issue Mar 21, 2022
@tk0miya tk0miya added this to the 4.5.0 milestone Mar 21, 2022
tk0miya added a commit that referenced this issue Mar 26, 2022
Fix #10269: manpage: Failed to resolve the title of :ref: cross references
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants