sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.55k stars 2.12k forks source link

Inconsistent use of quotes and case in messages to user #12676

Open jfbu opened 3 months ago

jfbu commented 3 months ago

Describe the bug

  1. The main messages to user during build are currently all lowercased. In case of errors, other problems, or info messages there does not seem to be consistent rules.
sphinx$ grep -r 'logger.info(__("' --exclude-dir locale --exclude-dir __pycache__
config.py:        logger.info(__("Converting `source_suffix = %r` to `source_suffix = %r`."),
config.py:        logger.info(__("Converting `source_suffix = %r` to `source_suffix = %r`."),
util/inventory.py:            logger.info(__("inventory <%s> contains multiple definitions for %s"),
builders/texinfo.py:        logger.info(__("resolving references..."))
builders/latex/__init__.py:        logger.info(__("resolving references..."))
$ grep -r 'logger.warning(__("' --exclude-dir locale --exclude-dir __pycache__
directives/other.py:                    logger.warning(__("toctree glob pattern %r didn't match any documents"),
domains/std/__init__.py:            logger.warning(__("Failed to create a cross reference. Any number is not "
config.py:            logger.warning(__("Invalid configuration value found: 'language = None'. "
writers/texinfo.py:        logger.warning(__("unimplemented node type: %r"), node,
builders/texinfo.py:            logger.warning(__("error writing file Makefile: %s"), err)
builders/xml.py:            logger.warning(__("error writing file %s: %s"), outfilename, err)
builders/html/__init__.py:                    logger.warning(__("cannot copy image file '%s': %s"),
builders/html/__init__.py:                logger.warning(__("search index couldn't be loaded, but not all "
builders/html/__init__.py:            logger.warning(__("a Unicode error occurred when rendering the page %s. "
builders/html/__init__.py:            logger.warning(__("error writing file %s: %s"), outfilename, err)
builders/text.py:            logger.warning(__("error writing file %s: %s"), outfilename, err)
ext/autodoc/preserve_defaults.py:        logger.warning(__("Failed to parse a default argument value for %r: %s"), obj, exc)
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a function signature for %s: %s"),
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a function signature for %s: %s"),
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a constructor signature for %s: %s"),
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a method signature for %s: %s"),
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a method signature for %s: %s"),
ext/autodoc/__init__.py:            logger.warning(__("Failed to get a function signature for %s: %s"),
ext/autodoc/type_comment.py:        logger.warning(__("Failed to update signature for %r: parameter not found: %s"),
ext/autodoc/type_comment.py:        logger.warning(__("Failed to parse type_comment for %r: %s"), obj, exc)
ext/todo.py:                logger.warning(__("TODO entry found: %s"), todo[1].astext(),
transforms/post_transforms/__init__.py:            logger.warning(__("more than one target found for 'any' cross-"
environment/__init__.py:                logger.warning(__("document isn't included in any toctree"),
  1. One finds all three `foo`, `foo', or 'foo' types in messages to user.

For example

            msg = __(
                'Invalid value `%r` in intersphinx_mapping[%r]. '
                'Values must be a (target URI, inventory locations) pair.'
            )

in ext/intersphinx/_load.py which has a consistent use of left ticks but also contains right ticks as in

            LOGGER.info(__("loading intersphinx inventory '%s' from %s ..."),
                        project.name, _get_safe_url(inv))
sphinx$ grep -r '`%r' --exclude-dir locale --exclude-dir __pycache__
config.py:                 "a string, or a list of strings. Got `%r' instead (type %s).")
ext/intersphinx/_load.py:                'Invalid intersphinx project identifier `%r` in intersphinx_mapping. '
ext/intersphinx/_load.py:                'Invalid value `%r` in intersphinx_mapping[%r]. '
ext/intersphinx/_load.py:                'Invalid value `%r` in intersphinx_mapping[%r]. '
ext/intersphinx/_load.py:            msg = __('Invalid target URI value `%r` in intersphinx_mapping[%r][0]. '
ext/intersphinx/_load.py:                'Invalid target URI value `%r` in intersphinx_mapping[%r][0]. '
ext/intersphinx/_load.py:                    'Invalid inventory location value `%r` in intersphinx_mapping[%r][1]. '

File ext/intersphinx/_resolve.py for example contains usage of '%s'

                LOGGER.warning(__("inventory '%s': multiple matches found for %s:%s"),
                               inv_descriptor, objtype, target,
                               type='intersphinx',  subtype='external', location=node)

Examples (in random order) in config.py showing all three styles:

        if valid_types:
            msg = __("The config value `{name}' has type `{current.__name__}'; "
                     "expected {permitted}.")
        logger.info(__("Converting `source_suffix = %r` to `source_suffix = %r`."),
                    source_suffix, config.source_suffix)
    elif not isinstance(source_suffix, dict):
        msg = __("The config value `source_suffix' expects a dictionary, "
            f'The {self.__class__.__name__!r} object tuple interface is deprecated, '
            "use attribute access instead for 'default', 'rebuild', and 'valid_types'.",

It is a bit complicated (to me) to grep for such things, I initially spotted some of them from looking at chains to translate then I explored a bit more.

Such things are not unexpected with as large a code-base as Sphinx, but maybe some guidelines could be set-up for contributions. Admission of guilt: did not search our issues first for similar ones...

Changing a posteriori may cause major disturbance as it may require massive re-translation work.

How to Reproduce

Use Sphinx and observe console output under various conditions :smiley:

Environment Information

Sphinx v8.0.0rc1

Sphinx extensions

No response

Additional context

No response

electric-coder commented 3 months ago

Put all the strings in one file and write a console message style guide into that module's docstring.

picnixz commented 3 months ago

Yeah at some point it would be nice to have consistent error messages... But if we change one, translation needs to be updated. Do we have a script that could update the po files when a punctuation like this changes..?

jfbu commented 3 months ago

@picnixz It would be great to have such a tool, although I anticipate difficulties with non-Latin scripts where citing or quoting strings may be done differently. It seems to require suitable interfacing with transifex, but ping @shimizukawa.

shimizukawa commented 3 months ago

IMO, it is possible to change all the translation catalogs at once, but it seems that some ingenuity is required to do so while maintaining the translated messages.

I think it is probably possible to achieve this by following the steps below.

  1. Stop the daily update github actions for sphinx-doc-translations
  2. Modify the sphinx source code and merge it into the master branch
  3. Download all the po files for each language via the tx command of transifex-client
  4. Replace the msgid (original text) in the relevant po files while maintaining the msgstr. However, I have not confirmed how to do this.
  5. Upload all the po files of all languages to transifex again using the tx command. At this point, there will be a duplicate of the old msgid and the new msgid on transifex.
  6. Delete the old msgid on transifex
  7. Resume daily updates to sphinx-doc-translations github actions

Recently, @rffontenelle did a great job fixing the automatic update of the translation catalog. It would be helpful if we could get @rffontenelle's opinion.

rffontenelle commented 3 months ago

Languages might have different quotation marks, and might be hard for the maintainers/devs to keep without the guidance of a language team member. For instance, French uses guillemets. Brazilian Portuguese normally use double quotes instead of single quotes (although this is very flexible due to English influence).

My suggestion is to have writing style guide, reference it in the documentation, one of the Transifex admins make an in-Transifex announcement of the newly style guide so the translators are made aware. This way they can follow the guide as is or adjust to their case (e.g. French)

picnixz commented 3 months ago

For the use of single quotes, it should be independent of the language actually. In french, the « » are used to quote text, but not to quote, e.g., an argument name. For quoting something like an argument name, I'd recommend either always using 'arg' like in python or using `arg' like in shell.

Here the quotes are relevant in the sense that they are markers, or HTML tags if you want (like <b>) but they do not have the same meaning as in literature IMO.