Menu

#133 US-YW12: Handle yWriter Markup Conversion

v1.0.0-beta
closed
nobody
2026-01-20
2026-01-19
Anonymous
No

Originally created by: smith-and-web

User Story

As a yWriter user,
I want to have my text formatting preserved,
So that my prose displays correctly in Kindling.

Parent Epic: [#123]

yWriter Markup Reference

yWriter uses BBCode-style markup in <SceneContent>:

Supported Markup

yWriter Meaning HTML TipTap
[i]...[/i] Italic <em> Italic mark
[b]...[/b] Bold <strong> Bold mark
[s]...[/s] Strikethrough <s> Strike mark
[u]...[/u] Underline <u> Underline (if supported)

Special Content

Pattern Meaning Handling
/* ... */ Author comment Preserve as note or strip
> ... Quotation marker Convert to blockquote or preserve
--- Scene break Convert to horizontal rule
[note]...[/note] Inline note Preserve or convert to comment

Encoding Issues

Some yWriter files may contain:

  • HTML entities (&amp;, &lt;, etc.)
  • Numeric character references (&#8220; for smart quotes)
  • Mixed encoding (UTF-8 content in UTF-16 file)

Conversion Examples

Input (yWriter):

Sarah stared at the letter. [i]This can't be real[/i], she thought.

"You [b]knew[/b]," she said, her voice barely a whisper.

/* TODO: Add more tension here */

John's face went pale. He [s]reached for his coffee[/s] stood up abruptly.

Output (HTML for TipTap):

<p>Sarah stared at the letter. <em>This can't be real</em>, she thought.</p>

<p>"You <strong>knew</strong>," she said, her voice barely a whisper.</p>

<p>John's face went pale. He <s>reached for his coffee</s> stood up abruptly.</p>

Implementation

fn convert_ywriter_markup(text: &str) -> String {
    text
        .replace("[i]", "<em>")
        .replace("[/i]", "</em>")
        .replace("[b]", "<strong>")
        .replace("[/b]", "</strong>")
        .replace("[s]", "<s>")
        .replace("[/s]", "</s>")
        // Handle unclosed tags gracefully
        // Strip or preserve comments based on config
}

Acceptance Criteria

  • [ ] [i]...[/i] converts to italics
  • [ ] [b]...[/b] converts to bold
  • [ ] [s]...[/s] converts to strikethrough
  • [ ] [u]...[/u] converts to underline or stripped (configurable)
  • [ ] Nested markup handled correctly: [i]italic [b]bold italic[/b][/i]
  • [ ] Unclosed tags handled gracefully (close at end of paragraph)
  • [ ] Author comments /* ... */ optionally preserved or stripped
  • [ ] HTML entities decoded properly
  • [ ] Line breaks and paragraphs preserved
  • [ ] Unknown markup tags passed through or stripped

Edge Cases

  • Unclosed tags: [i]start of italic without [/i]
  • Mismatched nesting: [i][b]text[/i][/b]
  • Tags across paragraphs: [i]first para\n\nsecond para[/i]
  • Empty tags: [b][/b] (strip completely)
  • Escaped brackets: \[not a tag\] (rare but possible)

Related

Tickets: #123

Discussion

  • Anonymous

    Anonymous - 2026-01-20

    Originally posted by: smith-and-web

    Implemented in PR [#140]. yWriter markup ([b]bold[/b], [i]italic[/i]) is converted to HTML (, ) during import.

     

    Related

    Tickets: #140

  • Anonymous

    Anonymous - 2026-01-20

    Ticket changed by: smith-and-web

    • status: open --> closed
     

Log in to post a comment.

MongoDB Logo MongoDB