Skip to content

fix(softbreak): Incorrect extra spaces in CJK paragraph soft line breaks#548

Merged
iamgio merged 5 commits into
iamgio:mainfrom
CarmJos:feature/soft-node-type
Jun 14, 2026
Merged

fix(softbreak): Incorrect extra spaces in CJK paragraph soft line breaks#548
iamgio merged 5 commits into
iamgio:mainfrom
CarmJos:feature/soft-node-type

Conversation

@CarmJos

@CarmJos CarmJos commented Jun 13, 2026

Copy link
Copy Markdown
Contributor
  • I have read the contributing guidelines.
  • I have tested the changes locally.
  • An issue for this change exists, and it was discussed with maintainers. This is required for new features and non-trivial changes. If present, append Closes #ISSUE_NUMBER at the end of this PR description.
  • (Optional) I have added necessary documentation to docs and CHANGELOG.md

Summary

When users split long paragraphs across multiple lines in .qd files (a common practice for readability), every soft line break is unconditionally rendered as a space. This produces visually incorrect output for CJK text, where adjacent characters should be joined without spaces.

Before (broken):

第一行内容,第二句话。
第二行内容,
第三行内容!

Renders as: 第一行内容,第二句话。 第二行内容, 第三行内容! (extra spaces inserted)

After (fixed):

Same source renders as: 第一行内容,第二句话。第二行内容,第三行内容! (no unwanted spaces)

Rationale

This issue affects all Quarkdown users writing CJK content. The current behavior is a side effect of HTML whitespace collapsing: each \n remains as a Text("\n") node in the AST, and the browser renders it as a space. The fix applies typographically correct rules at the parsing stage, where the character context is available, rather than at render time where the distinction between intentional and structural spaces is lost.

Hard line breaks (Markdown's two-space + newline or backslash + newline syntax) are unaffected, as the regex explicitly excludes them via negative lookbehind.

I got a severe scolding from my tutor for this problem. TvT

Summary by CodeRabbit

  • New Features

    • Added locale-aware line break rendering: soft line breaks now render as spaces in non-CJK languages and without spacing in CJK languages for improved text flow across different languages.
  • Bug Fixes

    • Improved distinction between soft and hard line breaks in markdown parsing for more accurate document rendering.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

A new SoftBreak singleton AST node is introduced to represent soft (non-hard) paragraph line breaks. The inline lexer pattern is updated to capture all mid-paragraph newlines (making the hard-break prefix optional), and the parser dispatches to SoftBreak or LineBreak based on token content. Both HTML and plain-text renderers emit locale-aware output: empty string for CJK, single space otherwise. Related tests and search-index fixtures are updated accordingly.

Changes

SoftBreak Inline Node and Locale-Aware Rendering

Layer / File(s) Summary
SoftBreak Node Definition
quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/base/inline/SoftBreak.kt
New singleton SoftBreak implements Node with visitor dispatch and KDoc describing language-dependent spacing semantics.
CJK Locale Detection
quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt
Private CJK_LANGUAGE_CODES set and Locale?.isCJK() extension function added, checking lowercased code or shortTag membership.
Lexer: Line-Break Pattern Made Optional
quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/tokens/InlineTokens.kt, quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt
LineBreakToken KDoc updated to distinguish hard vs soft breaks; lexer regex makes the hard-break prefix optional and renames the pattern identifier to InlineHardLineBreak.
Parser: LineBreakToken → SoftBreak or LineBreak
quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/InlineTokenParser.kt
visit(LineBreakToken) inspects the first character of the token text to emit LineBreak (space/backslash) or SoftBreak (all other newlines).
Rendering: Locale-Aware SoftBreak Output
quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt, quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
Both renderers add a lazy isCJK property and visit(SoftBreak) returning "" for CJK or " " otherwise. HTML renderer consolidates explicit imports to wildcards.
DSL Builder and Plain-Text Utility
quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/dsl/InlineAstBuilder.kt, quarkdown-core/src/main/kotlin/com/quarkdown/core/util/node/NodeUtils.kt
InlineAstBuilder.softBreak() DSL method appends a SoftBreak node; toPlainText() handles SoftBreak by emitting \n.
Tests and Fixture Updates
quarkdown-core/src/test/kotlin/com/quarkdown/core/BlockParserTest.kt, quarkdown-test/src/test/kotlin/com/quarkdown/test/..., quarkdown-test/src/test/resources/data/search-index/*.json
BlockParserTest joins multiple PlainTextNode children with \n and uses toPlainText() for multiline title assertions. Integration tests and search-index JSON fixtures replace \n-separated expected values with space-separated ones.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 A soft little break, not a hard one indeed,
CJK gets silence, the others get freed—
A space where there's language, naught where there's not,
The lexer made optional what once was a knot.
I hop through the AST, visitor in tow,
And render each newline with just the right flow! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the core issue: fixing incorrect extra spaces in CJK soft line breaks, which is the main objective of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt (1)

277-277: ⚖️ Poor tradeoff

Consider extracting duplicate SoftBreak rendering logic. Both renderers implement identical locale-aware whitespace logic: if (context.documentInfo.locale.isCJK()) "" else " ". While this is a simple one-liner, the coding guidelines emphasize avoiding repetitive code "at all costs."

  • quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt#L277-L277: Extract the SoftBreak rendering decision to a shared utility function in the core module.
  • quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt#L177-L177: Use the same shared utility function.

Given the cross-module nature and simplicity of the code, this refactor can be deferred if the added abstraction outweighs the benefit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt`
at line 277, Extract the duplicated SoftBreak whitespace logic into a shared
utility in the core module (e.g., add function softBreakFor(locale:
DocumentLocale): String in a new util object SoftBreakUtils under package
com.quarkdown.util that returns "" when locale.isCJK() else " "), then call that
utility from both renderers: in
quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt
(277-277) replace the inline if with
SoftBreakUtils.softBreakFor(context.documentInfo.locale), and in
quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
(177-177) do the same replacement so both visit(node: SoftBreak) implementations
delegate to the shared function.

Source: Coding guidelines

quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt (1)

61-61: Simplify Locale?.isCJK()code and shortTag are redundant with current implementations.

quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt line 61 checks both code.lowercase() and shortTag.lowercase() against CJK_LANGUAGE_CODES, but the sole Locale implementation (JVMLocale) sets both code and shortTag to jvmLocale.language, so they are always identical. Consider checking only code (or document why both are needed for potential future Locale implementations).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt` at
line 61, Simplify the nullable extension Locale?.isCJK(): replace the redundant
dual checks with a single check against code (i.e. implement as this != null &&
code.lowercase() in CJK_LANGUAGE_CODES) and remove shortTag from the condition;
if you prefer to preserve future-proofing, instead add a brief comment on
Locale/ JVMLocale noting that code and shortTag are identical in the current
JVMLocale implementation so only code is checked.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/BlockTokenParser.kt`:
- Around line 91-111: The replaceTextSoftBreaks implementation creates empty
Text("") nodes when splitting on '\n'; update
InlineContent.replaceTextSoftBreaks so you skip empty split parts and only emit
Text(part) for non-empty parts while still emitting a SoftBreak between parts
(but not after the final part). Concretely, in
InlineContent.replaceTextSoftBreaks (the function handling Text and SoftBreak
nodes), replace the current split(...).flatMap { ... }.dropLast(1) logic with a
loop or flatMapIndexed approach that: splits the text on '\n', iterates parts
with their index, emits Text(part) only if part.isNotEmpty(), and after each
part except the last emits a SoftBreak — this preserves SoftBreak counts for
consecutive/newline-only inputs while avoiding empty Text nodes.

---

Nitpick comments:
In `@quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt`:
- Line 61: Simplify the nullable extension Locale?.isCJK(): replace the
redundant dual checks with a single check against code (i.e. implement as this
!= null && code.lowercase() in CJK_LANGUAGE_CODES) and remove shortTag from the
condition; if you prefer to preserve future-proofing, instead add a brief
comment on Locale/ JVMLocale noting that code and shortTag are identical in the
current JVMLocale implementation so only code is checked.

In
`@quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt`:
- Line 277: Extract the duplicated SoftBreak whitespace logic into a shared
utility in the core module (e.g., add function softBreakFor(locale:
DocumentLocale): String in a new util object SoftBreakUtils under package
com.quarkdown.util that returns "" when locale.isCJK() else " "), then call that
utility from both renderers: in
quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt
(277-277) replace the inline if with
SoftBreakUtils.softBreakFor(context.documentInfo.locale), and in
quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
(177-177) do the same replacement so both visit(node: SoftBreak) implementations
delegate to the shared function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 19923fd7-0acd-4389-885d-d876bfc71595

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5f230 and d82f6d5.

📒 Files selected for processing (17)
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/base/inline/SoftBreak.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/dsl/InlineAstBuilder.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/tokens/InlineTokens.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/BlockTokenParser.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/util/node/NodeUtils.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/visitor/node/NodeVisitor.kt
  • quarkdown-core/src/test/kotlin/com/quarkdown/core/BlockParserTest.kt
  • quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt
  • quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/FunctionDefinitionTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/LayoutTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/MathFunctionsTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/TextTest.kt
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-no-metadata.json
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-with-metadata.json
  • quarkdown-test/src/test/resources/data/search-index/search-index-with-headings.json

Comment thread quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/BlockTokenParser.kt Outdated
Comment thread quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/BlockTokenParser.kt Outdated
@iamgio

iamgio commented Jun 13, 2026

Copy link
Copy Markdown
Owner

I got a severe scolding from my tutor for this problem. TvT

sorry about that! Quarkdown is meant to be globally accurate 🌍 but there are many typesetting rules I'm not familiar with. Feedback is crucial!

@CarmJos CarmJos force-pushed the feature/soft-node-type branch 2 times, most recently from d512714 to a7f74be Compare June 14, 2026 00:16
@CarmJos CarmJos requested a review from iamgio June 14, 2026 00:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/InlineTokenParser.kt (1)

161-164: ⚡ Quick win

Add documentation for the hard/soft break distinction logic.

The method now performs a non-trivial semantic distinction between hard and soft line breaks based on the first character. Per the coding guidelines, medium-sized documentation should be added for "non-public [methods] when the logic is not straightforward."

📝 Suggested documentation
+    /**
+     * Converts a [LineBreakToken] to either a [LineBreak] (hard break) or [SoftBreak] (soft break).
+     * A line break is hard if preceded by two or more spaces or a backslash; otherwise it is soft.
+     */
     override fun visit(token: LineBreakToken): Node {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/InlineTokenParser.kt`
around lines 161 - 164, Add KDoc documentation to the visit method that accepts
a LineBreakToken parameter in the InlineTokenParser class. The documentation
should explain the non-trivial semantic distinction being performed: that the
method checks if the first character of the token data is a space or backslash
to determine whether to return a hard LineBreak or a soft SoftBreak, and should
clarify the significance of this distinction for consumers of this method.

Source: Coding guidelines

quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt (2)

90-90: 💤 Low value

The capturing group in the regex appears unused.

The regex contains a capturing group ( {2,}|\\\\) inside the optional non-capturing group, but the parser only checks token.data.text.first() rather than using captured groups. Consider making it non-capturing for clarity: (?:(?: {2,}|\\\\))?\\R(?!\\s*$).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt`
at line 90, The regex pattern in BaseMarkdownInlineTokenRegexPatterns.kt
contains a capturing group `( {2,}|\\\\)` that is not being used by the parser
(which only checks token.data.text.first()). Convert this capturing group to a
non-capturing group by changing the opening parenthesis from a standard group
`(` to a non-capturing group `(?:` to improve code clarity and match the actual
parsing behavior.

85-92: ⚡ Quick win

Consider renaming to clarify that this pattern matches all line breaks.

The property name hardLineBreak suggests it matches only hard line breaks, but the regex (?:( {2,}|\\\\))?\\R(?!\\s*$) with the optional prefix matches BOTH hard and soft line breaks. The parser downstream (InlineTokenParser.kt lines 161-164) distinguishes between them by inspecting the first character.

Consider renaming to lineBreak or adding an explicit comment explaining that this pattern matches all line breaks and the parser later distinguishes hard vs soft. This would prevent future confusion and align the name with the actual behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt`
around lines 85 - 92, The property name hardLineBreak is misleading because its
regex pattern with an optional prefix group (?:( {2,}|\\\\))? actually matches
both hard line breaks (with spacing or backslash prefix) and soft line breaks
(without the prefix). Rename the property from hardLineBreak to lineBreak or add
an explicit comment explaining that this pattern matches all line breaks and the
downstream parser (referenced in InlineTokenParser.kt) later distinguishes
between hard and soft types based on the captured prefix. This will align the
property name with its actual behavior and prevent future confusion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt`:
- Line 90: The regex pattern in BaseMarkdownInlineTokenRegexPatterns.kt contains
a capturing group `( {2,}|\\\\)` that is not being used by the parser (which
only checks token.data.text.first()). Convert this capturing group to a
non-capturing group by changing the opening parenthesis from a standard group
`(` to a non-capturing group `(?:` to improve code clarity and match the actual
parsing behavior.
- Around line 85-92: The property name hardLineBreak is misleading because its
regex pattern with an optional prefix group (?:( {2,}|\\\\))? actually matches
both hard line breaks (with spacing or backslash prefix) and soft line breaks
(without the prefix). Rename the property from hardLineBreak to lineBreak or add
an explicit comment explaining that this pattern matches all line breaks and the
downstream parser (referenced in InlineTokenParser.kt) later distinguishes
between hard and soft types based on the captured prefix. This will align the
property name with its actual behavior and prevent future confusion.

In
`@quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/InlineTokenParser.kt`:
- Around line 161-164: Add KDoc documentation to the visit method that accepts a
LineBreakToken parameter in the InlineTokenParser class. The documentation
should explain the non-trivial semantic distinction being performed: that the
method checks if the first character of the token data is a space or backslash
to determine whether to return a hard LineBreak or a soft SoftBreak, and should
clarify the significance of this distinction for consumers of this method.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d35ea9b6-6876-46ec-9e5a-b11e37d6646f

📥 Commits

Reviewing files that changed from the base of the PR and between 66fa18c and a7f74be.

📒 Files selected for processing (19)
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/base/inline/SoftBreak.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/dsl/InlineAstBuilder.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/flavor/base/BaseMarkdownLexerFactory.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownInlineTokenRegexPatterns.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/tokens/InlineTokens.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/InlineTokenParser.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/util/node/NodeUtils.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/visitor/node/NodeVisitor.kt
  • quarkdown-core/src/test/kotlin/com/quarkdown/core/BlockParserTest.kt
  • quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt
  • quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/FunctionDefinitionTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/LayoutTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/MathFunctionsTest.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/TextTest.kt
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-no-metadata.json
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-with-metadata.json
  • quarkdown-test/src/test/resources/data/search-index/search-index-with-headings.json
✅ Files skipped from review due to trivial changes (6)
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-no-metadata.json
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/base/inline/SoftBreak.kt
  • quarkdown-test/src/test/resources/data/search-index/search-index-with-headings.json
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/tokens/InlineTokens.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/util/node/NodeUtils.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/TextTest.kt
🚧 Files skipped from review as they are similar to previous changes (11)
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/visitor/node/NodeVisitor.kt
  • quarkdown-test/src/test/resources/data/search-index/search-index-no-headings-with-metadata.json
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/flavor/base/BaseMarkdownLexerFactory.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/LayoutTest.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/localization/Locale.kt
  • quarkdown-core/src/main/kotlin/com/quarkdown/core/ast/dsl/InlineAstBuilder.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/FunctionDefinitionTest.kt
  • quarkdown-core/src/test/kotlin/com/quarkdown/core/BlockParserTest.kt
  • quarkdown-plaintext/src/main/kotlin/com/quarkdown/rendering/plaintext/node/PlainTextNodeRenderer.kt
  • quarkdown-test/src/test/kotlin/com/quarkdown/test/MathFunctionsTest.kt
  • quarkdown-html/src/main/kotlin/com/quarkdown/rendering/html/node/BaseHtmlNodeRenderer.kt

@CarmJos CarmJos force-pushed the feature/soft-node-type branch 2 times, most recently from c3b6d01 to b85a37f Compare June 14, 2026 00:32

@iamgio iamgio left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, just a nitpick about style and one comment to unblock the failing lint

@CarmJos CarmJos force-pushed the feature/soft-node-type branch from b85a37f to 503f846 Compare June 14, 2026 00:35
@CarmJos CarmJos force-pushed the feature/soft-node-type branch from 503f846 to e22fcb5 Compare June 14, 2026 00:57
@CarmJos CarmJos force-pushed the feature/soft-node-type branch from 4d87fbc to 0a9892e Compare June 14, 2026 02:28
@CarmJos CarmJos requested a review from iamgio June 14, 2026 02:35
@iamgio

iamgio commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Looks great, ty. I'm going to make some minor changes

@iamgio iamgio merged commit e2a33ae into iamgio:main Jun 14, 2026
11 checks passed
@CarmJos CarmJos deleted the feature/soft-node-type branch June 15, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants