zim-to-markdown 0.3.0.2 → 0.3.0.3
raw patch · 10 files changed
+128/−32 lines, 10 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +17/−0
- README.md +29/−18
- app/Main.hs +3/−0
- docs/cli.md +8/−6
- docs/releasing.md +1/−1
- docs/roadmap.md +11/−0
- docs/versioning.md +1/−1
- src/ZimToMarkdown/Table.hs +1/−2
- test/Spec.hs +52/−3
- zim-to-markdown.cabal +5/−1
CHANGELOG.md view
@@ -4,6 +4,23 @@ ## [Unreleased] +## [0.3.0.3] - 2026-10-23++### Changed++- Documented the planned domain smart constructors and the remaining conversion gaps in `docs/roadmap.md`.+- Added a test that fails when any link target in the README is relative, so the Hackage readme keeps working, and made `directory` a test dependency.+- Documented the installed executable in the README and CLI examples, keeping `cabal run` as the development form.+- Updated the cache, artifact, attestation, and Gitleaks actions to Node 24 releases.+- Documented the `libgmp-dev` build prerequisite on Debian and Ubuntu.++### Fixed++- Replaced the partial `maximum` call in table normalization with a total fold.+- Enabled `-Wincomplete-patterns` and `-Werror` in the shared build options, as `LANGUAGE.md` requires, and documented the single process failure boundary.+- Replaced the relative documentation links in the README with absolute GitHub URLs, because Hackage resolves relative links against the package URL and they return 404 on the package page. Recorded the rule in `LANGUAGE.md` and `docs/releasing.md`.+- Removed the stale "available after the first publication" note from the README.+ ## [0.3.0.2] - 2026-10-23 ### Changed
README.md view
@@ -29,36 +29,45 @@ ## Links -- Hackage: <https://hackage.haskell.org/package/zim-to-markdown> (available after the first publication)+- Hackage: <https://hackage.haskell.org/package/zim-to-markdown> - GitHub: <https://github.com/Tralen/zim-to-markdown> ## Documentation -- [Architecture](docs/architecture.md)-- [Domain model](docs/domain.md)-- [Command line interface](docs/cli.md)-- [Conversion rules](docs/conversion.md)-- [Release guide](docs/releasing.md)-- [Versioning](docs/versioning.md)-- [Changelog](CHANGELOG.md)+- [Architecture](https://github.com/Tralen/zim-to-markdown/blob/main/docs/architecture.md)+- [Domain model](https://github.com/Tralen/zim-to-markdown/blob/main/docs/domain.md)+- [Command line interface](https://github.com/Tralen/zim-to-markdown/blob/main/docs/cli.md)+- [Conversion rules](https://github.com/Tralen/zim-to-markdown/blob/main/docs/conversion.md)+- [Release guide](https://github.com/Tralen/zim-to-markdown/blob/main/docs/releasing.md)+- [Roadmap](https://github.com/Tralen/zim-to-markdown/blob/main/docs/roadmap.md)+- [Versioning](https://github.com/Tralen/zim-to-markdown/blob/main/docs/versioning.md)+- [Changelog](https://github.com/Tralen/zim-to-markdown/blob/main/CHANGELOG.md) ## Installation -After the first Hackage publication, install with:+Install the published package from Hackage with: ```sh cabal install zim-to-markdown ``` +The executable is installed into the Cabal binary directory, usually `~/.cabal/bin`, which must be on `PATH`.+ ## Prebuilt binaries Prebuilt Linux, macOS, and Windows binaries are attached to [GitHub releases](https://github.com/Tralen/zim-to-markdown/releases/latest). The release workflow builds Linux x86_64 on Ubuntu 22.04 (glibc 2.35 or newer), macOS ARM64, and Windows x86_64 archives. Build from source for other Linux distributions. ## Requirements +Building from source or installing with `cabal install` requires:+ - GHC 9.14.1 - cabal-install 3.18.1.0 +On Debian and Ubuntu, install the `libgmp-dev` package before building, because GHC links against GMP.++The prebuilt binaries attached to the GitHub releases do not need a Haskell toolchain.+ ## Build and test ```sh@@ -89,46 +98,48 @@ ## Usage +The examples use the installed `zim-to-markdown` executable. From a repository checkout, replace `zim-to-markdown` with `cabal run zim-to-markdown --`.+ Convert a single Zim page to standard output: ```sh-cabal run zim-to-markdown -- page.txt+zim-to-markdown page.txt ``` Convert a single page to a Markdown file: ```sh-cabal run zim-to-markdown -- page.txt --output page.md+zim-to-markdown page.txt --output page.md ``` Convert a whole Zim notebook, preserving its folders: ```sh-cabal run zim-to-markdown -- my-notebook --output my-notebook-markdown+zim-to-markdown my-notebook --output my-notebook-markdown ``` The notebook directory or its `notebook.zim` file can be used as input: ```sh-cabal run zim-to-markdown -- my-notebook/notebook.zim --output my-notebook-markdown+zim-to-markdown my-notebook/notebook.zim --output my-notebook-markdown ``` Convert Markdown back to Zim: ```sh-cabal run zim-to-markdown -- --direction markdown-to-zim notes --output notes-zim+zim-to-markdown --direction markdown-to-zim notes --output notes-zim ``` -Run `cabal run zim-to-markdown -- --help` for the complete option list.+Run `zim-to-markdown --help` for the complete option list. ## Releasing -Follow the [release guide](docs/releasing.md).+Follow the [release guide](https://github.com/Tralen/zim-to-markdown/blob/main/docs/releasing.md). ## Status -The converter covers headings, emphasis, lists, task lists, links, images, anchors, tables, blockquotes, horizontal rules, and code blocks. Reference links, footnotes, nested links, raw HTML blocks, and Markdown indented code blocks are not converted yet. See [conversion rules](docs/conversion.md) for details and known limitations.+The converter covers headings, emphasis, lists, task lists, links, images, anchors, tables, blockquotes, horizontal rules, and code blocks. Reference links, footnotes, nested links, raw HTML blocks, and Markdown indented code blocks are not converted yet. See [conversion rules](https://github.com/Tralen/zim-to-markdown/blob/main/docs/conversion.md) for details and known limitations, and the [roadmap](https://github.com/Tralen/zim-to-markdown/blob/main/docs/roadmap.md) for the planned work. ## License -BSD-3-Clause. See [LICENSE](LICENSE).+BSD-3-Clause. See [LICENSE](https://github.com/Tralen/zim-to-markdown/blob/main/LICENSE).
app/Main.hs view
@@ -317,6 +317,9 @@ renderFileError path exception = Text.pack path <> ": " <> Text.pack (displayException exception) +{- | The single process boundary for expected failures: reports the message on+stderr and exits with a nonzero status.+-} failWith :: Text -> IO value failWith message = do TextIO.hPutStrLn stderr message
docs/cli.md view
@@ -8,6 +8,8 @@ zim-to-markdown --version ``` +The examples use the installed `zim-to-markdown` executable. From a repository checkout, replace `zim-to-markdown` with `cabal run zim-to-markdown --`.+ ## Options | Option | Meaning |@@ -22,9 +24,9 @@ When `INPUT` is a file, the result goes to standard output unless `--output` is given. In that case `PATH` must be a file path. ```sh-cabal run zim-to-markdown -- page.txt-cabal run zim-to-markdown -- page.txt --output page.md-cabal run zim-to-markdown -- --direction markdown-to-zim page.md --output page.txt+zim-to-markdown page.txt+zim-to-markdown page.txt --output page.md+zim-to-markdown --direction markdown-to-zim page.md --output page.txt ``` ## Notebooks@@ -40,9 +42,9 @@ - The output directory must not be inside the input directory. ```sh-cabal run zim-to-markdown -- my-notebook --output my-notebook-markdown-cabal run zim-to-markdown -- my-notebook/notebook.zim --output my-notebook-markdown-cabal run zim-to-markdown -- --direction markdown-to-zim notes --output notes-zim+zim-to-markdown my-notebook --output my-notebook-markdown+zim-to-markdown my-notebook/notebook.zim --output my-notebook-markdown+zim-to-markdown --direction markdown-to-zim notes --output notes-zim ``` ## Exit status
docs/releasing.md view
@@ -23,7 +23,7 @@ gitleaks git --redact --log-opts="--all" ``` -Check that `dist-newstyle/sdist/` and `dist-newstyle/` contain the expected source and documentation tarballs.+Check that `dist-newstyle/sdist/` and `dist-newstyle/` contain the expected source and documentation tarballs. Check that every link in `README.md` is absolute, because Hackage resolves relative links against the package URL and they return 404 on the package page. ## Candidate
+ docs/roadmap.md view
@@ -0,0 +1,11 @@+# Roadmap++Planned work that is not part of the current release. An item ships when its prerequisites are clear and the tests cover the new behavior.++## Domain smart constructors++`ZimToMarkdown.Domain` exports the constructors of `ZimPage`, `MarkdownDocument` and `RelativePath`, so code outside the module can build a `RelativePath` that holds an absolute path. The planned change exports the types without their constructors, adds smart constructors such as `mkRelativePath :: FilePath -> Either DomainError RelativePath`, and threads the results through the executable, the link resolver and the tests. It changes the public API, so it ships in a minor release.++## Remaining conversion gaps++Reference links, footnotes, nested links, raw HTML blocks, and Markdown indented code blocks are still not converted. The [conversion rules](conversion.md) describe the supported syntax and the current behavior for each gap.
docs/versioning.md view
@@ -1,6 +1,6 @@ # Versioning -The project follows the Package Version Policy with four components: `major.minor.patch.revision`. The current version is `0.3.0.2`.+The project follows the Package Version Policy with four components: `major.minor.patch.revision`. The current version is `0.3.0.3`. ## Source of truth
src/ZimToMarkdown/Table.hs view
@@ -40,8 +40,7 @@ _ -> ([], rest) bodyCells = map parseTableCells bodyLines width =- maximum- (length headerCells : map length bodyCells)+ foldr max 0 (length headerCells : map length bodyCells) paddedHeader = padTo width headerCells paddedAlignment = take
test/Spec.hs view
@@ -5,8 +5,10 @@ import Data.Set qualified as Set import Data.Text (Text) import Data.Text qualified as Text+import Data.Text.IO qualified as TextIO import Data.Version (showVersion) import Paths_zim_to_markdown (version)+import System.Directory (doesFileExist) import System.Exit (exitFailure) import System.FilePath ((</>)) @@ -29,15 +31,17 @@ main :: IO () main = do- let failures =+ readmeTest <- readmeLinksTest+ let allTests = readmeTest : tests+ failures = [ test- | test <- tests+ | test <- allTests , testExpected test /= testActual test ] if null failures then putStrLn- ("All " <> show (length tests) <> " tests passed.")+ ("All " <> show (length allTests) <> " tests passed.") else do mapM_ printFailure failures exitFailure@@ -47,6 +51,51 @@ putStrLn ("FAIL: " <> testName test) putStrLn (" expected: " <> show (testExpected test)) putStrLn (" actual: " <> show (testActual test))++{- | Checks that every link target in the readme is absolute. Hackage resolves+relative links against the package URL, so they break on the package page.+-}+readmeLinksTest :: IO TestCase+readmeLinksTest = do+ present <- doesFileExist readmePath+ content <- if present then TextIO.readFile readmePath else pure ""+ let relativeTargets =+ [ target+ | target <- markdownLinkTargets content+ , not (isAbsoluteLinkTarget target)+ ]+ actual+ | not present = "README.md not found"+ | null relativeTargets = "all link targets are absolute"+ | otherwise =+ Text.intercalate ", " (map Text.strip relativeTargets)+ pure+ TestCase+ { testName = "readme link targets are absolute"+ , testActual = actual+ , testExpected = "all link targets are absolute"+ }+ where+ readmePath = "README.md"++-- | Extracts the destination of every inline Markdown link or image.+markdownLinkTargets :: Text -> [Text]+markdownLinkTargets content =+ case Text.breakOn "](" content of+ (_, remainder)+ | Text.null remainder -> []+ | otherwise ->+ let afterOpening = Text.drop 2 remainder+ (target, next) = Text.breakOn ")" afterOpening+ in target : markdownLinkTargets next++isAbsoluteLinkTarget :: Text -> Bool+isAbsoluteLinkTarget rawTarget =+ let target = Text.strip rawTarget+ in any+ (`Text.isPrefixOf` target)+ ["https://", "http://", "mailto:"]+ || Text.isPrefixOf "#" target tests :: [TestCase] tests =
zim-to-markdown.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: zim-to-markdown-version: 0.3.0.2+version: 0.3.0.3 synopsis: Converts Zim wiki pages to Markdown and back. description: A command line converter between Zim wiki markup and Markdown.@@ -28,6 +28,7 @@ docs/conversion.md docs/domain.md docs/releasing.md+ docs/roadmap.md docs/versioning.md source-repository head@@ -38,7 +39,9 @@ ghc-options: -Wall -Wcompat+ -Werror -Widentities+ -Wincomplete-patterns -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists@@ -94,6 +97,7 @@ build-depends: base >=4.18 && <5, containers >=0.6 && <0.9,+ directory >=1.3 && <1.4, filepath >=1.4 && <1.6, text >=2.0 && <2.2, zim-to-markdown