Skip to content

Commit

Permalink
Fix handling of empty markup parameters for RST. (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein authored Jun 29, 2024
1 parent 9f3abb7 commit 5842088
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/262-rst.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- "Fix handling of empty markup parameters for RST (https://github.com/ansible-community/antsibull-docs-ts/pull/262)."
5 changes: 4 additions & 1 deletion src/rst.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ describe('quoteRST tests', (): void => {
expect(quoteRST(' foo ', false, true)).toBe(' foo \\ ');
});
it('simple string, escape spacing', (): void => {
expect(quoteRST(' foo ', true, true)).toBe('\\ foo \\ ');
expect(quoteRST(' foo ', true, true, true)).toBe('\\ foo \\ ');
});
it('simple string, escape empty', (): void => {
expect(quoteRST('', true, true, true)).toBe('\\ ');
});
it('more complex', (): void => {
expect(quoteRST('\\<_>`*<_>*`\\')).toBe('\\\\\\<\\_\\>\\`\\*\\<\\_\\>\\*\\`\\\\');
Expand Down
52 changes: 31 additions & 21 deletions src/rst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { RSTOptions, AllFormatOptions, mergeOpts } from './opts';
import { OptionNamePart, Paragraph, ReturnValuePart } from './dom';
import { addToDestination } from './format';

export function quoteRST(text: string, escape_starting_whitespace = false, escape_ending_whitespace = false): string {
export function quoteRST(
text: string,
escape_starting_whitespace = false,
escape_ending_whitespace = false,
must_not_be_empty = false,
): string {
text = text.replace(/([\\<>_*`])/g, '\\$1');

if (escape_ending_whitespace && text.endsWith(' ')) {
Expand All @@ -17,6 +22,9 @@ export function quoteRST(text: string, escape_starting_whitespace = false, escap
if (escape_starting_whitespace && text.startsWith(' ')) {
text = '\\ ' + text;
}
if (must_not_be_empty && text === '') {
text = '\\ ';
}
return text;
}

Expand All @@ -37,7 +45,7 @@ function formatAntsibullOptionLike(part: OptionNamePart | ReturnValuePart, role:
result.push('=');
result.push(part.value);
}
return `\\ :${role}:\`${quoteRST(result.join(''), true, true)}\`\\ `;
return `\\ :${role}:\`${quoteRST(result.join(''), true, true, true)}\`\\ `;
}

function formatPlainOptionLike(part: OptionNamePart | ReturnValuePart): string {
Expand All @@ -63,43 +71,45 @@ function formatPlainOptionLike(part: OptionNamePart | ReturnValuePart): string {
value = `${value}=${part.value}`;
}
const pluginText = plugin.length ? ` (of ${plugin.join('')})` : '';
const mainText = `:literal:\`${quoteRST(value, true, true)}\``;
const mainText = `:literal:\`${quoteRST(value, true, true, true)}\``;
return `\\ ${mainText}${pluginText}\\ `;
}

const DEFAULT_FORMATTER: AllFormatOptions = {
formatError: (part) => `\\ :strong:\`ERROR while parsing\`\\ : ${quoteRST(part.message, true, true)}\\ `,
formatBold: (part) => `\\ :strong:\`${quoteRST(part.text, true, true)}\`\\ `,
formatCode: (part) => `\\ :literal:\`${quoteRST(part.text, true, true)}\`\\ `,
formatError: (part) => `\\ :strong:\`ERROR while parsing\`\\ : ${quoteRST(part.message, true, true, true)}\\ `,
formatBold: (part) => `\\ :strong:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatCode: (part) => `\\ :literal:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatHorizontalLine: () => '\n\n.. raw:: html\n\n <hr>\n\n',
formatItalic: (part) => `\\ :emphasis:\`${quoteRST(part.text, true, true)}\`\\ `,
formatLink: (part) => `\\ \`${quoteRST(part.text)} <${encodeURI(part.url)}>\`__\\ `,
formatModule: (part) => `\\ :ref:\`${quoteRST(part.fqcn)} <ansible_collections.${part.fqcn}_module>\`\\ `,
formatRSTRef: (part) => `\\ :ref:\`${quoteRST(part.text)} <${part.ref}>\`\\ `,
formatItalic: (part) => `\\ :emphasis:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatLink: (part) => (part.text === '' ? '' : `\\ \`${quoteRST(part.text)} <${encodeURI(part.url)}>\`__\\ `),
formatModule: (part) =>
`\\ :ref:\`${quoteRST(part.fqcn, true, true, true)} <ansible_collections.${part.fqcn}_module>\`\\ `,
formatRSTRef: (part) => `\\ :ref:\`${quoteRST(part.text, true, true, true)} <${part.ref}>\`\\ `,
formatURL: (part) => `\\ ${encodeURI(part.url)}\\ `,
formatText: (part) => quoteRST(part.text),
formatEnvVariable: (part) => `\\ :envvar:\`${quoteRST(part.name, true, true)}\`\\ `,
formatEnvVariable: (part) => `\\ :envvar:\`${quoteRST(part.name, true, true, true)}\`\\ `,
formatOptionName: (part) => formatAntsibullOptionLike(part, 'ansopt'),
formatOptionValue: (part) => `\\ :ansval:\`${quoteRST(part.value, true, true)}\`\\ `,
formatOptionValue: (part) => `\\ :ansval:\`${quoteRST(part.value, true, true, true)}\`\\ `,
formatPlugin: (part) =>
`\\ :ref:\`${quoteRST(part.plugin.fqcn)} <ansible_collections.${part.plugin.fqcn}_${part.plugin.type}>\`\\ `,
formatReturnValue: (part) => formatAntsibullOptionLike(part, 'ansretval'),
};

const PLAIN_FORMATTER: AllFormatOptions = {
formatError: (part) => `\\ :strong:\`ERROR while parsing\`\\ : ${quoteRST(part.message, true, true)}\\ `,
formatBold: (part) => `\\ :strong:\`${quoteRST(part.text, true, true)}\`\\ `,
formatCode: (part) => `\\ :literal:\`${quoteRST(part.text, true, true)}\`\\ `,
formatError: (part) => `\\ :strong:\`ERROR while parsing\`\\ : ${quoteRST(part.message, true, true, true)}\\ `,
formatBold: (part) => `\\ :strong:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatCode: (part) => `\\ :literal:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatHorizontalLine: () => '\n\n------------\n\n',
formatItalic: (part) => `\\ :emphasis:\`${quoteRST(part.text, true, true)}\`\\ `,
formatLink: (part) => `\\ \`${quoteRST(part.text)} <${encodeURI(part.url)}>\`__\\ `,
formatModule: (part) => `\\ :ref:\`${quoteRST(part.fqcn)} <ansible_collections.${part.fqcn}_module>\`\\ `,
formatRSTRef: (part) => `\\ :ref:\`${quoteRST(part.text)} <${part.ref}>\`\\ `,
formatItalic: (part) => `\\ :emphasis:\`${quoteRST(part.text, true, true, true)}\`\\ `,
formatLink: (part) => (part.text === '' ? '' : `\\ \`${quoteRST(part.text)} <${encodeURI(part.url)}>\`__\\ `),
formatModule: (part) =>
`\\ :ref:\`${quoteRST(part.fqcn, true, true, true)} <ansible_collections.${part.fqcn}_module>\`\\ `,
formatRSTRef: (part) => `\\ :ref:\`${quoteRST(part.text, true, true, true)} <${part.ref}>\`\\ `,
formatURL: (part) => `\\ ${encodeURI(part.url)}\\ `,
formatText: (part) => quoteRST(part.text),
formatEnvVariable: (part) => `\\ :envvar:\`${quoteRST(part.name, true, true)}\`\\ `,
formatEnvVariable: (part) => `\\ :envvar:\`${quoteRST(part.name, true, true, true)}\`\\ `,
formatOptionName: (part) => formatPlainOptionLike(part),
formatOptionValue: (part) => `\\ :literal:\`${quoteRST(part.value, true, true)}\`\\ `,
formatOptionValue: (part) => `\\ :literal:\`${quoteRST(part.value, true, true, true)}\`\\ `,
formatPlugin: (part) =>
`\\ :ref:\`${quoteRST(part.plugin.fqcn)} <ansible_collections.${part.plugin.fqcn}_${part.plugin.type}>\`\\ `,
formatReturnValue: (part) => formatPlainOptionLike(part),
Expand Down
21 changes: 21 additions & 0 deletions test-vectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ test_vectors:
ansible_doc_text: This is a `test' `module' *markup*.
rst_plain: This is a \ :literal:`test`\ \ :emphasis:`module`\ \ :strong:`markup`\
.
empty_tags:
source: |-
C() I() B() C() U() L(,) R(,) V() O() RV() E()
html: <p><code class='docutils literal notranslate'></code> <em></em> <b></b>
<code class='docutils literal notranslate'></code> <a href=''></a> <a href=''></a>
<span class='module'></span> <code class="ansible-value literal notranslate"></code>
<code class="ansible-option literal notranslate"><strong></strong></code> <code
class="ansible-return-value literal notranslate"></code> <code class="xref std
std-envvar literal notranslate"></code></p>
html_plain: <p><code></code> <em></em> <b></b> <code></code> <a href=''></a> <a
href=''></a> <span></span> <code></code> <code><strong></strong></code> <code></code>
<code></code></p>
md: <code></code> <em></em> <b></b> <code></code> []() []() <code></code> <code><strong></strong></code>
<code></code> <code></code>
rst: '\ :literal:`\ `\ \ :emphasis:`\ `\ \ :strong:`\ `\ \ :literal:`\ `\ \
\ \ :ref:`\ <>`\ \ :ansval:`\ `\ \ :ansopt:`\ `\ \ :ansretval:`\ `\ \
:envvar:`\ `\ '
rst_plain: '\ :literal:`\ `\ \ :emphasis:`\ `\ \ :strong:`\ `\ \ :literal:`\
`\ \ \ \ :ref:`\ <>`\ \ :literal:`\ `\ \ :literal:`\ `\ \ :literal:`\
`\ \ :envvar:`\ `\ '
ansible_doc_text: "`' `' ** `' <> `' `' `' `'"
module:
source: |-
The M(a.b.c) module.
Expand Down

0 comments on commit 5842088

Please sign in to comment.