Skip to content

Commit

Permalink
Allow using rst_prolog with a role in a document title (#11445)
Browse files Browse the repository at this point in the history
Fix the field list field name recognition regular expression to avoid false positives,
as interpreted text roles may not be field name blocks.

Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
  • Loading branch information
picnixz and AA-Turner authored Jul 23, 2023
1 parent c583e0f commit 12e7cff
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 9 deletions.
15 changes: 15 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ Features added
Bugs fixed
----------

* #11437: Top-level headings starting with a reStructuredText role
now render properly when :confval:`rst_prolog` is set.
Previously, a file starting with the below would have
improperly rendered due to where the prologue text
was inserted into the document.

.. code:: rst

:mod:`lobster` -- The lobster module
====================================

...

Patch by Bénédikt Tran.

Testing
--------

Expand Down
14 changes: 5 additions & 9 deletions sphinx/util/rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,17 @@

from docutils.parsers.rst import roles
from docutils.parsers.rst.languages import en as english
from docutils.parsers.rst.states import Body
from docutils.statemachine import StringList
from docutils.utils import Reporter
from jinja2 import Environment
from jinja2 import Environment, pass_environment

from sphinx.locale import __
from sphinx.util import docutils, logging

try:
from jinja2.utils import pass_environment
except ImportError:
from jinja2 import environmentfilter as pass_environment


logger = logging.getLogger(__name__)

docinfo_re = re.compile(':\\w+:.*?')
FIELD_NAME_RE = re.compile(Body.patterns['field_marker'])
symbols_re = re.compile(r'([!-\-/:-@\[-`{-~])') # symbols without dot(0x2e)
SECTIONING_CHARS = ['=', '-', '~']

Expand Down Expand Up @@ -80,7 +75,7 @@ def prepend_prolog(content: StringList, prolog: str) -> None:
if prolog:
pos = 0
for line in content:
if docinfo_re.match(line):
if FIELD_NAME_RE.match(line):
pos += 1
else:
break
Expand All @@ -91,6 +86,7 @@ def prepend_prolog(content: StringList, prolog: str) -> None:
pos += 1

# insert prolog (after docinfo if exists)
lineno = 0
for lineno, line in enumerate(prolog.splitlines()):
content.insert(pos + lineno, line, '<rst_prolog>', lineno)

Expand Down
55 changes: 55 additions & 0 deletions tests/test_util_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,61 @@ def test_prepend_prolog_without_CR(app):
('dummy.rst', 1, 'Sphinx is a document generator')]


def test_prepend_prolog_with_roles_in_sections(app):
prolog = 'this is rst_prolog\nhello reST!'
content = StringList([':title: test of SphinxFileInput',
':author: Sphinx team',
'', # this newline is required
':mod:`foo`',
'----------',
'',
'hello'],
'dummy.rst')
prepend_prolog(content, prolog)

assert list(content.xitems()) == [('dummy.rst', 0, ':title: test of SphinxFileInput'),
('dummy.rst', 1, ':author: Sphinx team'),
('<generated>', 0, ''),
('<rst_prolog>', 0, 'this is rst_prolog'),
('<rst_prolog>', 1, 'hello reST!'),
('<generated>', 0, ''),
('dummy.rst', 2, ''),
('dummy.rst', 3, ':mod:`foo`'),
('dummy.rst', 4, '----------'),
('dummy.rst', 5, ''),
('dummy.rst', 6, 'hello')]


def test_prepend_prolog_with_roles_in_sections_with_newline(app):
# prologue with trailing line break
prolog = 'this is rst_prolog\nhello reST!\n'
content = StringList([':mod:`foo`', '-' * 10, '', 'hello'], 'dummy.rst')
prepend_prolog(content, prolog)

assert list(content.xitems()) == [('<rst_prolog>', 0, 'this is rst_prolog'),
('<rst_prolog>', 1, 'hello reST!'),
('<generated>', 0, ''),
('dummy.rst', 0, ':mod:`foo`'),
('dummy.rst', 1, '----------'),
('dummy.rst', 2, ''),
('dummy.rst', 3, 'hello')]


def test_prepend_prolog_with_roles_in_sections_without_newline(app):
# prologue with no trailing line break
prolog = 'this is rst_prolog\nhello reST!'
content = StringList([':mod:`foo`', '-' * 10, '', 'hello'], 'dummy.rst')
prepend_prolog(content, prolog)

assert list(content.xitems()) == [('<rst_prolog>', 0, 'this is rst_prolog'),
('<rst_prolog>', 1, 'hello reST!'),
('<generated>', 0, ''),
('dummy.rst', 0, ':mod:`foo`'),
('dummy.rst', 1, '----------'),
('dummy.rst', 2, ''),
('dummy.rst', 3, 'hello')]


def test_textwidth():
assert textwidth('Hello') == 5
assert textwidth('русский язык') == 12
Expand Down

0 comments on commit 12e7cff

Please sign in to comment.