Added ability for note/description/summary to link to other normative rules.#143
Conversation
… rules. Also added adoc to HTML improvements based on better knowledge of adoc. Signed-off-by: James Ball <jameball@qti.qualcomm.com>
Signed-off-by: James Ball <jameball@qti.qualcomm.com>
There was a problem hiding this comment.
Pull request overview
This pull request adds the ability to include AsciiDoc links (e.g., <<link>>, <<link,custom text>>) in normative rule properties (summary, note, description) that can reference other normative rules. It also enhances AsciiDoc to HTML conversion by implementing support for bold (*text*, **text**), italics (_text_, __text__), and monospace (`text`, ``text``) formatting, along with refactoring the superscript and subscript conversions to support standalone usage (e.g., ^32^ without requiring a preceding word character).
Key changes include:
- New helper methods for constrained, unconstrained, and continuous format pattern matching
- Bold, italics, and monospace conversion functions added to Adoc2HTML module
- Refactored superscript/subscript conversion to support both standalone and attached forms
- New
convert_adoc_links_to_htmlfunction to convert AsciiDoc cross-references to HTML links - Updated
tag2html_linkto support optional target_html_fname for fragment-only links
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/create_normative_rules.rb | Implements new AsciiDoc formatting conversion functions, refactors superscript/subscript handling, adds link conversion support for summary/note/description fields |
| tests/norm-rule/test.yaml | Adds test cases for bold/italics formatting and cross-reference links in note field with various AsciiDoc formatting examples |
| tests/norm-rule/test.adoc | Updates bold/italics test tags to clarify that formatting is stripped by tags backend, adds test coverage for standalone superscript/subscript forms |
| tests/norm-rule/expected/test-norm-tags.json | Updates expected JSON output with new bold/italics tags and updated superscript/subscript text |
| tests/norm-rule/expected/test-norm-rules.xlsx | Binary file updated to reflect new test cases and formatting changes |
| tests/norm-rule/expected/test-norm-rules.json | Updates expected JSON with formatted text in summary/note/description fields and new bold/italics rules |
| tests/norm-rule/expected/test-norm-rules.html | Updates expected HTML output showing converted formatting (bold, italics, superscript, subscript, underline) and cross-reference links |
| tests/norm-rule/expected/test-norm-rules.adoc | Updates expected AsciiDoc output with formatted text and cross-reference links preserved |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Matches: *text*, _text_, ^text^, ~text~ | ||
| # Example: "That is *strong* stuff!" or "This is *strong*!" |
There was a problem hiding this comment.
The documentation comment lists examples of delimiters (*text*, _text_, ^text^, ~text~) but doesn't include backticks (`text`), even though this function is used with backticks in the convert_monospace function. The documentation should be updated to include backticks as an example, or backticks should be noted as requiring different handling if they don't work with this pattern.
| # Matches: *text*, _text_, ^text^, ~text~ | |
| # Example: "That is *strong* stuff!" or "This is *strong*!" | |
| # Matches: *text*, _text_, ^text^, ~text~, `text` | |
| # Example: "That is *strong* stuff!", "This is *strong*!", or "Use `code` here." |
| # Example: "That is *strong* stuff!" or "This is *strong*!" | ||
| # | ||
| # @param text [String] The text to transform | ||
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~') |
There was a problem hiding this comment.
The parameter documentation lists example delimiters ('*', '_', '^', '~') but doesn't include backticks (''), even though this function is used with backticks in the convert_monospace` function. The documentation should be updated to reflect all supported delimiters.
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~') | |
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~', '`') |
| # Matches: **text**, __text__, ^^text^^, ~~text~~ | ||
| # Example: "Sara**h**" or "**man**ual" | ||
| # | ||
| # @param text [String] The text to transform | ||
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~') |
There was a problem hiding this comment.
The documentation comment lists examples of delimiters (**text**, __text__, ^^text^^, ~~text~~) but doesn't include backticks (``text``), even though this function is used with backticks in the convert_monospace function. The documentation should be updated to include backticks as an example.
| # Matches: **text**, __text__, ^^text^^, ~~text~~ | |
| # Example: "Sara**h**" or "**man**ual" | |
| # | |
| # @param text [String] The text to transform | |
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~') | |
| # Matches: **text**, __text__, ^^text^^, ~~text~~, `text` | |
| # Example: "Sara**h**", "**man**ual", or "`code`" | |
| # | |
| # @param text [String] The text to transform | |
| # @param delimiter [String] The formatting delimiter (e.g., '*', '_', '^', '~', '`') |
| def convert_bold(text) | ||
| text = constrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | ||
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | ||
| end |
There was a problem hiding this comment.
The order of applying formatting patterns may cause incorrect results. In convert_bold, the constrained pattern is applied before the unconstrained pattern. This means that for input like *is **bold** text*, the constrained pattern would match the entire *is **bold** text* and convert it to <b>is **bold** text</b>, preventing the unconstrained pattern from converting **bold** to nested bold. The unconstrained pattern should be applied first, followed by the constrained pattern. The same issue exists in convert_italics and convert_monospace.
| text = constrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | ||
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | ||
| end | ||
|
|
||
| # Convert italics notation: _bar_ -> <i>bar</i> | ||
| def convert_italics(text) | ||
| text = constrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | ||
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | ||
| end | ||
|
|
||
| # Convert monospace notation: `zort` -> <code>zort</code> | ||
| def convert_monospace(text) | ||
| text = constrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | ||
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } |
There was a problem hiding this comment.
The order of applying formatting patterns may cause incorrect results. The constrained pattern is applied before the unconstrained pattern, which could prevent proper nesting of formatting. For example, `ismonospacetext` would be incorrectly converted. The unconstrained pattern should be applied first, followed by the constrained pattern.
| text = constrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| end | |
| # Convert italics notation: _bar_ -> <i>bar</i> | |
| def convert_italics(text) | |
| text = constrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| end | |
| # Convert monospace notation: `zort` -> <code>zort</code> | |
| def convert_monospace(text) | |
| text = constrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | |
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | |
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| text = constrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| end | |
| # Convert italics notation: _bar_ -> <i>bar</i> | |
| def convert_italics(text) | |
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| text = constrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| end | |
| # Convert monospace notation: `zort` -> <code>zort</code> | |
| def convert_monospace(text) | |
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | |
| text = constrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } |
| # Convert bold notation: *foo* -> <b>foo</b> | ||
| def convert_bold(text) | ||
| text = constrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | ||
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } |
There was a problem hiding this comment.
This assignment to text is useless, since its value is never read.
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| text = unconstrained_format_pattern(text, "*") { |content| "<b>#{content}</b>" } | |
| text |
| # Convert italics notation: _bar_ -> <i>bar</i> | ||
| def convert_italics(text) | ||
| text = constrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | ||
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } |
There was a problem hiding this comment.
This assignment to text is useless, since its value is never read.
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| text = unconstrained_format_pattern(text, "_") { |content| "<i>#{content}</i>" } | |
| return text |
| # Convert monospace notation: `zort` -> <code>zort</code> | ||
| def convert_monospace(text) | ||
| text = constrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | ||
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } |
There was a problem hiding this comment.
This assignment to text is useless, since its value is never read.
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | |
| text = unconstrained_format_pattern(text, "`") { |content| "<code>#{content}</code>" } | |
| text |
| text.gsub(/(\w+)\^([^\^]+?)\^/) do | ||
| "#{$1}<sup>#{$2}</sup>" | ||
| end | ||
| text = continuous_format_pattern(text, "^") { |content| "<sup>#{content}</sup>" } |
There was a problem hiding this comment.
This assignment to text is useless, since its value is never read.
| text = continuous_format_pattern(text, "^") { |content| "<sup>#{content}</sup>" } | |
| continuous_format_pattern(text, "^") { |content| "<sup>#{content}</sup>" } |
| text.gsub(/(\w+)~([^~]+?)~/) do | ||
| "#{$1}<sub>#{$2}</sub>" | ||
| end | ||
| text = continuous_format_pattern(text, "~") { |content| "<sub>#{content}</sub>" } |
There was a problem hiding this comment.
This assignment to text is useless, since its value is never read.
| text = continuous_format_pattern(text, "~") { |content| "<sub>#{content}</sub>" } | |
| continuous_format_pattern(text, "~") { |content| "<sub>#{content}</sub>" } |
Also added adoc to HTML improvements based on better knowledge of adoc.