Merge "Make section titles have stable anchor links"
This commit is contained in:
commit
b09384dbd5
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added explicitly calculated anchors to ensure section links are both
|
||||||
|
unique and stable over time.
|
|
@ -25,6 +25,21 @@ def _indent_for_list(text, prefix=' '):
|
||||||
]) + '\n'
|
]) + '\n'
|
||||||
|
|
||||||
|
|
||||||
|
def _anchor(version_title, title):
|
||||||
|
title = title or 'relnotes'
|
||||||
|
return '.. _{title}_{version_title}:'.format(
|
||||||
|
title=title,
|
||||||
|
version_title=version_title)
|
||||||
|
|
||||||
|
|
||||||
|
def _section_anchor(section_title, version_title, title):
|
||||||
|
# Get the title and remove the trailing :
|
||||||
|
title = _anchor(version_title, title)[:-1]
|
||||||
|
return "{title}_{section_title}:".format(
|
||||||
|
title=title,
|
||||||
|
section_title=section_title)
|
||||||
|
|
||||||
|
|
||||||
def format_report(loader, config, versions_to_include, title=None,
|
def format_report(loader, config, versions_to_include, title=None,
|
||||||
show_source=True):
|
show_source=True):
|
||||||
report = []
|
report = []
|
||||||
|
@ -44,11 +59,13 @@ def format_report(loader, config, versions_to_include, title=None,
|
||||||
for version in versions_to_include:
|
for version in versions_to_include:
|
||||||
if '-' in version:
|
if '-' in version:
|
||||||
# This looks like an "unreleased version".
|
# This looks like an "unreleased version".
|
||||||
title = config.unreleased_version_title or version
|
version_title = config.unreleased_version_title or version
|
||||||
else:
|
else:
|
||||||
title = version
|
version_title = version
|
||||||
report.append(title)
|
report.append(_anchor(version_title, title))
|
||||||
report.append('=' * len(title))
|
report.append('')
|
||||||
|
report.append(version_title)
|
||||||
|
report.append('=' * len(version_title))
|
||||||
report.append('')
|
report.append('')
|
||||||
|
|
||||||
# Add the preludes.
|
# Add the preludes.
|
||||||
|
@ -57,7 +74,11 @@ def format_report(loader, config, versions_to_include, title=None,
|
||||||
notefiles_with_prelude = [(n, sha) for n, sha in notefiles
|
notefiles_with_prelude = [(n, sha) for n, sha in notefiles
|
||||||
if prelude_name in file_contents[n]]
|
if prelude_name in file_contents[n]]
|
||||||
if notefiles_with_prelude:
|
if notefiles_with_prelude:
|
||||||
report.append(prelude_name.replace('_', ' ').title())
|
prelude_title = prelude_name.replace('_', ' ').title()
|
||||||
|
report.append(_section_anchor(
|
||||||
|
prelude_title, version_title, title))
|
||||||
|
report.append('')
|
||||||
|
report.append(prelude_title)
|
||||||
report.append('-' * len(prelude_name))
|
report.append('-' * len(prelude_name))
|
||||||
report.append('')
|
report.append('')
|
||||||
|
|
||||||
|
@ -76,6 +97,9 @@ def format_report(loader, config, versions_to_include, title=None,
|
||||||
for n in file_contents[fn].get(section_name, [])
|
for n in file_contents[fn].get(section_name, [])
|
||||||
]
|
]
|
||||||
if notes:
|
if notes:
|
||||||
|
report.append(_section_anchor(
|
||||||
|
section_title, version_title, title))
|
||||||
|
report.append('')
|
||||||
report.append(section_title)
|
report.append(section_title)
|
||||||
report.append('-' * len(section_title))
|
report.append('-' * len(section_title))
|
||||||
report.append('')
|
report.append('')
|
||||||
|
|
|
@ -156,6 +156,7 @@ class TestFormatterCustomSections(TestFormatterBase):
|
||||||
expected = [prelude_pos, api_pos, features_pos]
|
expected = [prelude_pos, api_pos, features_pos]
|
||||||
actual = list(sorted([prelude_pos, features_pos, api_pos]))
|
actual = list(sorted([prelude_pos, features_pos, api_pos]))
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
self.assertIn('.. _relnotes_1.0.0_API Changes:', result)
|
||||||
|
|
||||||
|
|
||||||
class TestFormatterCustomUnreleaseTitle(TestFormatterBase):
|
class TestFormatterCustomUnreleaseTitle(TestFormatterBase):
|
||||||
|
@ -182,6 +183,7 @@ class TestFormatterCustomUnreleaseTitle(TestFormatterBase):
|
||||||
)
|
)
|
||||||
self.assertIn('Not Released', result)
|
self.assertIn('Not Released', result)
|
||||||
self.assertNotIn('0.1.0-1', result)
|
self.assertNotIn('0.1.0-1', result)
|
||||||
|
self.assertIn('.. _This is the title_Not Released:', result)
|
||||||
|
|
||||||
def test_without_title(self):
|
def test_without_title(self):
|
||||||
result = formatter.format_report(
|
result = formatter.format_report(
|
||||||
|
@ -191,3 +193,49 @@ class TestFormatterCustomUnreleaseTitle(TestFormatterBase):
|
||||||
title='This is the title',
|
title='This is the title',
|
||||||
)
|
)
|
||||||
self.assertIn('0.1.0-1', result)
|
self.assertIn('0.1.0-1', result)
|
||||||
|
self.assertIn('.. _This is the title_0.1.0-1:', result)
|
||||||
|
|
||||||
|
|
||||||
|
class TestFormatterAnchors(TestFormatterBase):
|
||||||
|
|
||||||
|
note_bodies = {
|
||||||
|
'note1': {
|
||||||
|
'prelude': 'This is the prelude.',
|
||||||
|
},
|
||||||
|
'note2': {
|
||||||
|
'issues': [
|
||||||
|
'This is the first issue.',
|
||||||
|
'This is the second issue.',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'note3': {
|
||||||
|
'features': [
|
||||||
|
'We added a feature!',
|
||||||
|
],
|
||||||
|
'upgrade': None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_with_title(self):
|
||||||
|
self.c.override(unreleased_version_title='Not Released')
|
||||||
|
result = formatter.format_report(
|
||||||
|
loader=self.ldr,
|
||||||
|
config=self.c,
|
||||||
|
versions_to_include=self.versions,
|
||||||
|
title='This is the title',
|
||||||
|
)
|
||||||
|
self.assertIn('.. _This is the title_0.0.0:', result)
|
||||||
|
self.assertIn('.. _This is the title_0.0.0_Prelude:', result)
|
||||||
|
self.assertIn('.. _This is the title_1.0.0:', result)
|
||||||
|
self.assertIn('.. _This is the title_1.0.0_Known Issues:', result)
|
||||||
|
|
||||||
|
def test_without_title(self):
|
||||||
|
result = formatter.format_report(
|
||||||
|
loader=self.ldr,
|
||||||
|
config=self.c,
|
||||||
|
versions_to_include=self.versions,
|
||||||
|
)
|
||||||
|
self.assertIn('.. _relnotes_0.0.0:', result)
|
||||||
|
self.assertIn('.. _relnotes_0.0.0_Prelude:', result)
|
||||||
|
self.assertIn('.. _relnotes_1.0.0:', result)
|
||||||
|
self.assertIn('.. _relnotes_1.0.0_Known Issues:', result)
|
||||||
|
|
Loading…
Reference in New Issue