Index  Decision Records ISSUE-179: Quoted Asterisk Treated as Italic Marker

ISSUE-179: Quoted Asterisk Treated as Italic Marker

1 Status

Date Status
21-05-2026 Proposed
21-05-2026 Accepted
21-05-2026 In-Progress
21-05-2026 Implemented

2 Context

While reviewing the rendered HTML of issue-171-dash-unordered-list, it was observed that the first sentence of its Context section displayed an "asterisk" character as missing and the surrounding text in italic. The source Markdown reads:

Initially the only "*" markers were implemented in the Almirah Ruby gem for bullet lists (unordered lilsts). However Markdown format allows to use both "*" and "-" fur such purpose.

The renderer turned the first "*" opening quote-plus-asterisk into a literal " followed by an italic opener; everything up to the second "*" was then wrapped in <i>…</i>, and the second "*" was consumed as the italic closer. Visually, the first asterisk disappeared and the body up to the second "*" was italicised.

The root cause is in text_line.rb:73. TextLineParser#tokenize emitted an ItalicToken for every * character without any awareness of surrounding context. TextLineBuilder#restore then greedily paired the two ItalicTokens, producing the spurious italic span. The same defect applies to ** and ***: any quoted bold or bold-italic marker "**" / "***" would behave the same way.

Markdown specifications address this with delimiter "flanking" rules: an emphasis run can only open or close emphasis when its immediate neighbours qualify. The Almirah tokenizer had no such check.

3 Decision

Add flanking-aware filtering to the emphasis tokenization step. When tokenize matches an ItalicToken, BoldToken, or BoldAndItalicToken, compute whether the matched run is left-flanking or right-flanking based on the character immediately before and after the run in the source string. A run that is neither left-flanking nor right-flanking is emitted as literal text instead of an emphasis token.

Use a tightened CommonMark-style rule (stricter than vanilla CommonMark for the punctuation-on-both-sides case):

The "tightened" part is the removal of the "or preceded by punctuation" branch from the CommonMark left-flanking rule (and its symmetric counterpart for right-flanking). Vanilla CommonMark would still render "*" as italic; the stricter rule correctly leaves it as a literal asterisk while preserving legitimate cases such as *"foo"*, (*foo*), *foo*!, etc.

4 Scope

Item Status Start Date Target Date Description
Code Done 21-05-2026 21-05-2026 Add can_flank? / left_flanking? / right_flanking? helpers in text_line.rb and call them from tokenize before emitting emphasis tokens; fall through to literal text when neither flanking direction holds
Tests Done 21-05-2026 21-05-2026 Five new unit tests in text_line_spec.rb covering: single quoted asterisk, two quoted asterisks on the same line, quoted phrase *"foo"* still italicises, lone asterisks surrounded by spaces stay literal, quoted double-asterisk "**" stays literal

5 Out of Scope

6 Consequences

6.1 Positive

6.2 Negative

6.3 Neutral

7 Alternatives Considered

8 Software Versions

Software Version Category Software Version ID
Latest Released Version 0.3.1
Issue Found in Version 0.4.0
Target Release Version 0.4.0

9 References

10 Review Evidences