Housekeeping: rename the API, add ktfmt, detekt and Konsist - #3
Merged
Conversation
The factory functions and exception base class still carried the name of the upstream project this was ported from, which no longer matches anything in the library. - MarkItDown() -> MikroMarkdown() (JVM), MarkItDown(context) -> MikroMarkdown(context) - MarkItDownException -> MikroMarkdownException - CLI command class and its help name now read mikromarkdown - README updated; the remaining MarkItDown mention is the upstream project link Breaking for 0.1.0 consumers, with no deprecated aliases, matching the convert -> parse change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The benchmark compares our Markdown against anydoc, and its parsers are the reference for the document-model architecture. Pinning it next to the existing markitdown submodule keeps both references at a known revision. Pinned at v0.1.7. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three guards, wired into `check` and a CI lint job: - ktfmt (kotlinlang style, 120 columns) formats every source set. ktfmt-gradle only derives tasks for the common and JVM ones, so the library registers matching tasks for androidMain/androidHostTest/androidDeviceTest, which hold half the converters and would otherwise go unchecked. - detekt on top of its default config, with overrides in config/detekt/detekt.yml limited to rules that clash with deliberate choices here (broad catches in converters, PascalCase factory functions). - Konsist encodes the pipeline's boundaries as tests: the model depends on nothing and stays platform-free, converters never import the renderer, and Markdown syntax only appears under render/. Each rule was verified to fail against a deliberate violation. Fixing detekt's findings turned up a real bug: the escaping pass tracked line-start state in a mutable flag that was already false by the time it reached an ordered-list delimiter, so both the digit and delimiter branches were dead and "1. item" in running text could still open a list. Escaping is now position-based, and honours leading indentation. Other cleanups it prompted: - PPTX chart extraction collapsed from eight near-identical loops to five toSeries() helpers, since bar/bar3D, line/line3D and area/area3D each share a generated series type - MikroMarkdown.parse selects the converter first, with failure wrapping in a single parseOrFail helper - the EPUB manifest predicate and the CLI command class each moved out into their own named unit The bulk of the diff is the one-time ktfmt sweep. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits, reviewable in order.
1. Rename the MarkItDown API surface to MikroMarkdown
The factory functions and exception base class still carried the name of the upstream project this was ported from.
MarkItDown()→MikroMarkdown()(JVM),MarkItDown(context)→MikroMarkdown(context)(Android)MarkItDownException→MikroMarkdownExceptionmikromarkdownMarkItDownmention is the upstream project linkBreaking for 0.1.0 consumers, with no deprecated aliases, matching the
convert→parsechange.2. Vendor anydoc as a submodule
This is a cherry-pick of #2, which never reached
main. #2 was based ondocument-model-pipelineand merged into it at 22:53 — but that branch had already merged to main at 11:36, so the submodule landed on a dead branch.main's.gitmoduleshas onlymarkitdown. This commit fixes that.3. ktfmt, detekt and Konsist
All three run under
./gradlew check, plus a new CIlintjob.config/detekt/detekt.ymlArchitectureTestinlibrary/jvmTestktfmt gap: ktfmt-gradle only derives tasks for the common and JVM source sets.
androidMain,androidHostTestandandroidDeviceTestget none — half the converters live there.library/build.gradle.ktsregisters matching format/check tasks and wires them intoktfmtCheckandcheck.detekt config overrides only rules that clash with deliberate choices here: broad
catchin converters (format libraries throw widely and converters degrade instead of propagating), PascalCase factory functions, and complexity thresholds for the format-walking parsers.Konsist rules, each verified to fail against a planted violation:
layers depend in one direction only— model depends on nothing; render and converters depend on modelconverters do not reach into the renderer— nothing under..converters..imports.render.markdown syntax only lives in the renderer— no table pipes, ATX headings, bold markers, image syntax or code fences in string literals outsiderender/converters implement DocumentConverter and are named accordinglythe model stays free of platform dependencies— nojava.*orandroid.*undermodel/, keeping the model usable from any KMP targetRule 3 is a text scan rather than an AST rule, so it is blunt on purpose: a legitimate
"**"in a converter would trip it. That is the trade that keeps Markdown building out of converters.Bug found while clearing detekt
The escaping pass tracked line-start position in a mutable flag that was already
falseby the time it reached an ordered-list delimiter, so both the digit and delimiter branches were dead —1. itemin running text could still open a list. Escaping is now position-based and honours leading indentation.Other cleanups it prompted:
toSeries()helpers; bar/bar3D, line/line3D and area/area3D each share a generated series typeMikroMarkdown.parseselects the converter first, with failure wrapping in a singleparseOrFailMost of commit 3's diff is the one-time ktfmt sweep. Happy to split that into a formatting-only commit if it makes review easier.
Verification
./gradlew checkpasses: JVM tests, Android host tests, CLI build, detekt, ktfmtCheck and the Konsist rules.🤖 Generated with Claude Code