typelevel/Laika
53.5
Adequate · 20 September 2026
44.2k
lines of production code
Scala
primary language
1
measurement over time
What this system is
Laika is a Scala library and sbt plugin for generating static sites and e-books from text markup sources like Markdown and reStructuredText. It provides a modular API to parse documents into an abstract syntax tree, apply rewrite rules, and render them into HTML, EPUB, or PDF formats. The system includes a built-in Helium theme for styling and an sbt plugin to automate the generation pipeline within Scala projects.
How it got here
2012–2020 — Helium theme and multi-format support
78 changes.
This period focused on establishing the project's foundational structure and migrating the build infrastructure to sbt 1.0 with multi-project support. It introduced the Helium theme as the default, expanding output capabilities to include PDF, EPUB, and XSL-FO generation alongside HTML. The work also involved significant API restructuring to improve modularity and adding comprehensive test coverage for these new features.
2021–2025 — API restructuring and format expansion
39 changes.
This period focused on a comprehensive restructuring of Laika's internal architecture, moving core logic into dedicated internal packages and introducing a new public configuration API. It also expanded format support by implementing GitHub Flavored Markdown extensions, raw HTML handling, and enhanced PDF features like embedded fonts and bookmarks.
Features
Add GitHub Flavored Markdown extensions
Laika now supports several GitHub Flavored Markdown (GFM) extensions, including auto-links for URLs and email addresses, fenced code blocks (using backticks and tildes), strikethrough text (wrapped in double tildes), and GFM-style tables with column alignment. These features are implemented via new internal parsers in the \laika.internal.markdown.github\ package, allowing users to write Markdown that closely matches GitHub's rendering behavior.
core/shared/src/main/scala/laika/internal/markdown/github · high confidence
Helium theme adds client-side JavaScript for tabs, navigation, and versioning
The Helium theme now includes three new JavaScript modules (preview.js, theme.js, versions.js) that enable interactive features in the browser. Users will see working tabbed content, toggleable navigation menus, and a dynamic version selector that populates from versionInfo.json. The version menu also automatically inserts canonical link tags for SEO, and the preview server uses Server-Sent Events to handle page refreshes while preserving scroll position.
io/src/main/resources/laika/helium/js · high confidence
IO syntax extensions for parallel and sequential execution
The \laika.io.syntax\ module now provides implicit classes that add \sequential\ and \parallel\ methods to parser, renderer, and transformer builders. This allows users to execute document processing tasks concurrently or sequentially within a chosen effect type (requiring \Async\ for parallel and \Sync\ for sequential), enabling efficient batch processing of directories and files for formats like HTML, EPUB, and PDF.
io/src/main/scala/laika/io · high confidence
Initial implementation of standard reStructuredText directives and text roles
Laika now supports the standard block, span, and text roles defined by the reStructuredText reference parser. This change introduces the \StandardBlockDirectives\ (including \admonition\, \table\, \contents\, \figure\, and \meta\), \StandardSpanDirectives\ (such as \replace\, \unicode\, and \date\), and \StandardTextRoles\ (like \emphasis\, \strong\, \literal\, and \code\). Users can now parse these standard RST constructs, though some features like syntax highlighting in code blocks and the \default-role\ directive remain unsupported or require explicit API configuration.
core/shared/src/main/scala/laika/internal/rst/std · high confidence
Initial project setup and repository configuration
This change establishes the foundational structure of the repository by adding essential configuration and documentation files. It introduces a \.scalafmt.conf\ file to enforce code formatting standards (version 3.8.6, Scala 2.12 dialect), a \.gitignore\ file to exclude build artifacts and IDE-specific files, and a \.jvmopts\ file to configure JVM memory and garbage collection settings. Additionally, it adds a \.scala-steward.conf\ file to manage automated dependency updates, a \.git-blame-ignore-revs\ file to ignore formatting commits, and a comprehensive \README.md\ that describes the project as a Site and E-book Generator and Customizable Text Markup Transformer for sbt, Scala, and Scala.js, highlighting its support for Scala 3, 2.13, and 2.12.
(repo-wide) · high confidence
Introduce XSLFO format support
Users can now render documents to XSL-FO output using the new \XSLFO\ format object, which integrates with the simplified \Formatter\ and \RenderFormat\ APIs. This allows XSL-FO to be used as an intermediate format for PDF generation or as a final output for external processing via the \Renderer\ and \Transformer\ APIs.
core/shared/src/main/scala/laika/format · high confidence
Introduction of internal XSL-FO and HTML rendering infrastructure
The \core/shared/src/main/scala/laika/internal/render\ package now includes new internal components to support XSL-FO and HTML output formats. \FOProperties.scala\ defines the mapping of XSL-FO tag names to supported properties, while \FORenderer.scala\ implements the default rendering logic for XSL-FO, handling elements like tables, lists, and links. Additionally, \HTMLFormatter.scala\ provides a base class for HTML tag formatting, managing attributes and empty tag closing styles. These changes establish the foundational rendering logic for these formats within the library's internal package structure.
core/shared/src/main/scala/laika/internal/render · high confidence
New combinator parsers for optional, lookahead, and repetition
The core parser library now includes new combinators in the \laika.parse.combinator\ package to enhance parsing flexibility. Users can now use \opt\ to parse optional elements that always succeed, and \not\ to assert that a parser fails without consuming input. Lookahead capabilities are expanded with \lookAhead\ (checking ahead without consuming) and \lookBehind\ (checking behind the current position), including support for specific offsets. Additionally, a new \Repeat\ class allows applying a base parser multiple times with configurable minimum, maximum, and separator constraints, enabling more precise control over repeated parsing patterns.
core/shared/src/main/scala/laika/parse/combinator · high confidence
New common code span parsers for syntax highlighting
The \laika.parse.code.common\ package now provides a comprehensive set of reusable base parsers for syntax highlighting, including \CodeSpanParser\ for managing ordered parser collections, and specific parsers for character, string, and regular expression literals, numeric literals, identifiers, keywords, comments, and HTML/XML tags. These components allow language-specific highlighters to easily compose standard lexical elements, with features like embedded child spans, configurable delimiters, and category assignment.
core/shared/src/main/scala/laika/parse/code/common · high confidence
New configuration keys, icon registry, and pretty URL extension
This change introduces several new configuration capabilities and structural additions to the core configuration package. It adds an IconRegistry to allow registering custom icons for use with directives, defines a comprehensive set of new configuration keys in LaikaKeys (including siteBaseURL, coverImage, and versioned settings), and introduces a PrettyURLs extension that automatically translates HTML output paths to remove file suffixes for cleaner URLs. Additionally, a PlatformDateTime abstraction is added to handle date parsing and formatting consistently across JVM and Scala.js platforms.
core/shared/src/main/scala/laika/config · high confidence
New descriptor types for parsing, rendering, and transformation operations
Added new descriptor classes in the \laika.io.descriptor\ package to provide structured descriptions of parsing, rendering, and transformation operations. These descriptors capture details such as input sources, output targets, extension bundles, themes, and configuration settings (like strict mode and compact rendering), primarily to support tooling and logging by offering a formatted summary of the operation's context.
io/src/main/scala/laika/io/descriptor · high confidence
New internal API for reStructuredText text roles
Added a new internal \TextRoles\ object in the \laika.internal.rst.ext\ package that provides the API for creating and parsing interpreted text roles in reStructuredText. This change introduces the underlying mechanism for handling inline elements and role directives, allowing users to define custom text roles with specific parsing rules and default values, although the API itself is marked as private/internal to the reStructuredText extension module.
core/shared/src/main/scala/laika/internal/rst/ext · high confidence
New public configuration API in laika.api.config
Laika now exposes a new public API for configuration management in the \laika.api.config\ package. This change introduces a \Config\ trait for retrieving values by key with built-in decoders for types like String, Int, Double, Boolean, Path, and URI, alongside a \ConfigParser\ for parsing HOCON strings and resolving substitution references. The API also includes \ConfigEncoder\ and \ConfigDecoder\ type classes for custom serialization, \DefaultKey\ for simplified access to common configuration objects, and \ConfigError\ types for handling parsing and decoding failures. This provides a cleaner, more functional interface for users to interact with configuration data in documents and directives.
core/shared/src/main/scala/laika/api/config · high confidence
New syntax highlighters for Alloy, CSS, Dart, Dhall, Diff, EBNF, HOCON, HTML, Haskell, JSON, JavaScript, Java, Laika AST, Laika Extensions, Markdown, Python, ReStructured Text, and SQL
Laika now includes built-in syntax highlighting for a wide range of new programming and markup languages. Users can now highlight code blocks for Alloy, CSS, Dart, Dhall, Diff, EBNF, HOCON, HTML, Haskell, JSON, JavaScript (including JSX), Java, Laika AST, Laika Extensions, Markdown, Python, ReStructured Text, and SQL. This expands the library's ability to render code snippets with appropriate colorization and structure recognition across these popular formats.
core/shared/src/main/scala/laika/parse/code/languages · high confidence
Optional verbatim HTML support for Markdown
Laika now supports embedding raw HTML within Markdown documents, but this feature is disabled by default to maintain compatibility with non-HTML output formats. Users can enable it by calling \.withRawContent\ on the Transformer API. When enabled, raw HTML tags, attributes, and comments are preserved in the output for HTML targets, while they are silently filtered out for XSL-FO (PDF) targets.
core/shared/src/main/scala/laika/internal/markdown/bundle · high confidence
PDF rendering now supports embedded fonts, cover images, and bookmarks
The PDF output module has been refactored to support richer document features. Users can now embed custom fonts defined in the configuration, include a cover image via the \coverImage\ config key, and generate PDF bookmarks based on the document structure (configurable via \pdf.bookmarks.depth\). The internal implementation moves PDF-specific logic into a new \laika.pdf.internal\ package, utilizing Apache FOP for the final XSL-FO to PDF transformation.
pdf/src/main/scala/laika/pdf · high confidence
Public API for theme color configuration and include directives
The \laika.theme.config\ package now exposes public configuration classes for theme customization. Users can define colors via the new \Color\ companion object (supporting RGB, RGBA, and hex formats) and configure CSS/JS inclusion for HTML and EPUB outputs using the \IncludeCSSConfig\ and \IncludeJSConfig\ builders, which allow linking external resources, auto-linking internal files, and inserting inline styles or scripts with conditional logic.
io/src/main/scala/laika/theme/config · high confidence
API
Restructured configuration and extension bundle APIs
The configuration and extension bundle APIs have been restructured to improve modularity and precedence handling. A new \OperationConfig\ class now serves as the central entry point for building operations, managing the merging of \ExtensionBundle\s, applying \BundleFilter\s, and handling \MessageFilters\. The \BundleOrigin\ trait has been introduced to distinguish between library, parser, theme, and user-provided bundles, ensuring correct precedence during merging. Configuration building is now handled by a dedicated \ConfigBuilder\ that supports programmatic value addition and fallback resolution, while configuration errors are consolidated into a new \ConfigError\ hierarchy (including \MultipleErrors\ and \DocumentErrors\). Additionally, new parser definition types (\BlockParserDefinition\, \SpanParserDefinition\) with explicit \Precedence\ and \BlockPosition\ allow for more precise control over markup parsing order and placement.
repository · high confidence
Architecture
Helium theme generators moved to internal package
The internal generators for the Helium theme (CSS variables, landing page, table of contents, downloads, FO styles, Mermaid initialization, and CSS merging) have been relocated from their previous location into the new \laika.helium.internal.generate\ package. This change is part of a broader restructuring to create separate internal packages within laika-io, improving code organization without altering the public API or user-facing behavior.
io/src/main/scala/laika/helium/internal/generate · high confidence
Internal runtime restructure for Laika I/O operations
The internal execution logic for parsing, transforming, and rendering documents has been reorganized into dedicated runtime components within the \laika.io.internal.runtime\ package. This change introduces a \Batch\ type class to manage sequential or parallel execution of operations, a \DirectoryScanner\ to handle file system input collection, and specific runtimes (\RendererRuntime\, \TransformerRuntime\) that coordinate the processing pipeline. Additionally, a \VersionInfoGenerator\ has been added to produce version metadata JSON. These changes refactor how the library internally manages I/O effects and document processing flows, without altering the public API surface.
io/src/main/scala/laika/io/internal/runtime · high confidence
Preview server internals moved to a dedicated internal package
The preview server's core implementation details—including the AST page transformer, HTTP route builder, caching mechanism, and static file scanner—have been reorganized into a new \laika.preview.internal\ package. This change encapsulates the internal logic of the preview server, separating it from the public API surface.
preview/src/main · high confidence
Behavioural changes
BinaryPostProcessor builder interface moved to nested Builder trait
The \BinaryPostProcessor\ in the \laika.api.format\ package now exposes its construction logic via a nested \Builder\ trait instead of a top-level \BinaryPostProcessorBuilder\ class. This change affects how users instantiate binary post-processors for intermediate formats like XSL-FO or XHTML, requiring them to use the new \Builder\ interface within the \BinaryPostProcessor\ companion object.
io/src/main/scala/laika/api · high confidence
EPUB generation implementation refactored into internal packages
The EPUB rendering logic has been reorganized into the \laika.epub.internal\ package, introducing dedicated components for container creation (\ContainerWriter\), navigation generation (\HtmlNavRenderer\, \NCXRenderer\, \NavigationBuilder\), and file packaging (\ZipWriter\). This change also adds support for EPUB-specific semantic attributes, such as \epub:type\ for citations and footnotes, and ensures compatibility with older e-book readers by maintaining NCX navigation files alongside HTML5 navigation.
io/src/main/scala/laika/epub · high confidence
Helium theme CSS stylesheets consolidated into resources
The Helium theme's CSS assets have been reorganized into the io module's resources directory, introducing dedicated stylesheets for code highlighting (including syntax colors and diff support), page layout and containers, general content elements (headers, links, callouts, inline messages), the landing page, navigation, and table of contents. Separate EPUB-specific stylesheets have also been added to ensure proper rendering in e-book formats, covering code, content, and typography adjustments.
io/src/main/resources/laika/helium/css · high confidence
Helium theme builder restructured into modular internal components
The Helium theme builder has been refactored into distinct internal modules to improve organization and separation of concerns. The new \HeliumInputBuilder\ handles the assembly of theme resources, including CSS/JS assets, embedded fonts, and default templates for HTML, EPUB, and PDF outputs. \HeliumDirectives\ centralizes template directives for versioning, preview initialization, and script/style includes. \HeliumRewriteRules\ manages content styling, specifically applying 'keep together' styles to code blocks and callouts based on configuration. \HeliumTreeProcessor\ orchestrates the generation of special pages (landing, download, table of contents) and handles static document cleanup. Finally, \HeliumThemeBuilder\ and \HeliumRenderOverrides\ wire these components together, registering the theme with Laika and applying format-specific render overrides.
io/src/main/scala/laika/helium/internal/builder · high confidence
Helium theme configuration API restructured with per-format selectors
The Helium theme configuration API has been restructured to allow settings to be applied specifically to Site, EPUB, or PDF output formats, or to all formats simultaneously via new \site\, \epub\, \pdf\, and \all\ selectors. The \Helium\ class now encapsulates separate settings objects for each format and exposes an \extendWith\ method to merge additional theme providers, while the \build\ method finalizes the configuration into a \ThemeProvider\ that can be passed to Laika transformers or the sbt plugin.
io/src/main/scala/laika/helium · high confidence
Helium theme default colors and font configuration
The Helium theme now applies specific default color palettes for both light and dark modes, including primary, secondary, and message colors, as well as syntax highlighting schemes. It also sets default fonts (Lato and Fira Mono) and font sizes for web and EPUB output, ensuring consistent visual styling out of the box.
io/src/main/scala/laika/helium/internal/config · high confidence
Helium theme icon configuration and API surface restructuring
The Helium theme's icon system has been restructured to support both font-based glyphs and inline SVGs, introducing a new \HeliumIcon\ enumeration in the \laika.helium.config\ package that registers built-in icons (such as Mastodon, GitHub, and API) via an \IconRegistry\. This change also moves most Helium configuration types into this new package and promotes the include directive configuration to the public API, while shrinking the overall public API surface of \laika.theme\ and \laika.helium\ to provide a cleaner, more focused configuration interface for users.
io/src/main/scala/laika/helium/config · high confidence
Helium theme templates moved to resources and restructured
The Helium theme's default templates for HTML, EPUB, and PDF (XSL-FO) have been moved into the \io/src/main/resources/laika/helium/templates\ directory as classpath resources. The HTML template now uses include directives to compose the page structure from separate fragments (head, navigation, footer), while the EPUB template has been updated to use the \laika.epub.scripted\ configuration key. A new landing page template has also been added to support customizable headers, teasers, and custom content.
io/src/main/resources/laika/helium/templates · high confidence
Helium theme templates refactored into modular includes
The Helium site template has been split into separate, reusable include files (footer, head, mainNav, pageNav, topNav) to support configurable navigation and layout components. This change introduces new configuration options for the main navigation (including prepend/append links and section exclusion), page navigation (enabling/disabling, depth, and keeping it visible on small screens), and footer content, allowing users to customize these UI elements via the Helium API.
io/src/main/resources/laika/helium/templates/includes · high confidence
Helium theme updates font assets and fixes icon font paths
The Helium theme now includes the SIL Open Font License text for the FiraMono and Lato fonts, ensuring proper attribution for PDF and EPUB embedding. Additionally, the IcoFont icon library has been reorganized into a new folder structure, with the CSS files updated to use correct relative paths to the font files, fixing broken icon rendering.
io/src/main/resources/laika/helium/fonts · high confidence
IO API builders now manage themes and renderers as Cats Effect Resources
The public builder APIs for parsing, rendering, and transforming document trees (TreeParser, TreeRenderer, TreeTransformer, and their binary counterparts) have been refactored so that themes and renderers are acquired via cats.effect.Resource. This ensures that theme resources are properly managed and released, and it shifts effect control to the user by requiring Async constraints, resulting in a more robust and predictable lifecycle for IO operations.
io/src/main/scala/laika/io/api · high confidence
Internal navigation and section-building logic restructured
The internal navigation package has been reorganized to improve code structure and behavior. A new \NavigationOrder\ object now handles document tree sorting based on user configuration or alphabetical order. \SectionBuilder\ has been refactored to flatten block containers that lack IDs or styles before processing section headers, ensuring a cleaner document structure. Additionally, \TitleDocumentConfig\ centralizes the configuration for input and output title document names (defaulting to 'README' and 'index' respectively).
core/shared/src/main/scala/laika/internal/nav · high confidence
Internal parsing infrastructure reorganized and expanded
The internal parsing implementation in laika-core has been restructured: the \laika.parse.implicits\ package is renamed to \laika.parse.syntax\, and several internal parser traits and classes (including \ConfigResolver\, \TemplateParsers\, \DefaultRecursiveParsers\, \DefaultRecursiveSpanParsers\, \DefaultEscapedTextParsers\, \RootParser\, \AutoLinkParsers\, and \URIParsers\) are moved into a new \laika.internal.parse\ package. Additionally, \ConfigResolver\ now resolves substitution references lazily, deferring resolution of references that depend on a fallback config that may change when a document is re-homed into a different document tree.
core/shared/src/main/scala/laika/internal/parse · high confidence
Internal refactoring of configuration and resource loading components
Moved internal configuration and resource loading utilities into a dedicated \laika.io.internal.config\ package to improve code organization. This change includes the introduction of a \ResourceLoader\ object for handling file, classpath, and URL-based resource loading, and a \SiteConfig\ object for managing site-specific output paths such as downloads and API documentation. These are internal implementation details and do not alter the public API or user-facing behavior.
io/src/main/scala/laika/io/internal/config · high confidence
Internal refactoring: new Stack collection and RST style constants
This change introduces two internal components to support Laika's core processing. First, a minimal \Stack\ implementation is added to \laika.internal.collection\ to replace the deprecated Scala 2.12 SDK \Stack\, ensuring compatibility with modern Scala versions. Second, a set of common reStructuredText style constants (such as \line\, \admonition\, and \sidebar\) is centralized in \laika.internal.rst.ast.RstStyle\ to provide consistent \Options\ instances for the RST parser and rewrite rules. These are internal utilities and do not expose new public APIs.
core/shared/src/main/scala/laika/internal/collection, core/shared/src/main/scala/laika/internal/rst/ast · high confidence
Introduce FilePath abstraction and effectful FileFilter
Laika replaces \java.io.File\ with a new \FilePath\ abstraction for file system paths, providing a unified API for path manipulation and conversion to NIO, fs2, and Java File types. This change is accompanied by a new \FileFilter\ trait that supports effectful filtering logic, allowing file exclusion rules to be defined within the effect system rather than as pure functions. These types are integrated into the \InputTreeBuilder\ and input/output models (\BinaryInput\, \TextInput\, etc.), enabling more flexible and platform-aware file handling in the input tree construction process.
io/src/main/scala/laika/io/model · high confidence
Laika core directives are now implemented in the internal directive package
The implementation of Laika's standard directives—including control flow (\if\, \for\), inclusions (\include\, \embed\), navigation (\api\, \source\), and formatting (\image\, \select\, \format\)—has been moved into the \laika.internal.directive\ package. This change reorganizes the internal structure of the core library to better encapsulate these directive implementations, but it does not alter the user-facing API or the behavior of the directives themselves.
core/shared/src/main/scala/laika/internal/directive · high confidence
New block and inline parser abstractions with improved position tracking
The core parsing library introduces dedicated \BlockParsers\ and \InlineParsers\ traits to standardize how blocks and inline spans are recognized, alongside a refactored \RecursiveParsers\ API. These changes enforce stricter position tracking by requiring \SourceFragment\ instances for recursive parsing operations, which ensures that error messages and source references remain accurate during nested parsing. The new \BlockParsers\ trait provides helpers for parsing block structures with indentation handling, while \InlineParsers\ offers optimized builders for nested span parsing, improving both the reliability of source location data and the consistency of parsing logic across different markup languages.
core/shared/src/main/scala/laika/parse/markup · high confidence
New internal reStructuredText extension and processing bundle
The \core/shared/src/main/scala/laika/internal/rst/bundle\ package now contains the internal implementation for reStructuredText extension support and document processing. This includes \RstExtensionRegistry\ and \RstExtensionSupport\ for registering and applying custom block directives, span directives, and text roles, as well as \RewriteRules\ for resolving substitution references and interpreted text. Additionally, \DocInfoExtractor\ handles the extraction of bibliographic fields into document configuration, and \LinkTargetProcessor\ manages the resolution of internal link targets within the document tree.
core/shared/src/main/scala/laika/internal/rst/bundle · high confidence
New internal rewrite rules for template processing and reference resolution
The rewrite module now includes new internal components to handle template application and reference resolution more robustly. TemplateRewriter applies templates to documents based on output format, while RecursiveResolverRules ensures that substitution references are resolved recursively across all rewrite phases. ReferenceResolver provides context for document metadata (title, content, siblings) during resolution, and TemplateFormatter handles text span joining and indentation. Additionally, UnresolvedNodeDetector converts unresolved references into visible invalid nodes rather than leaving them hidden.
core/shared/src/main/scala/laika/internal/rewrite · high confidence
New theme API with effect-type indirection and builder support
The \laika.theme\ package introduces a new way to define and compose themes. Themes are now built via \ThemeProvider\, which defers the choice of the effect type (e.g., Cats Effect \Async\) to the user, allowing themes to be composed and extended via \extendWith\. The \Theme\ trait itself provides hooks for pre-populating input trees, registering extension bundles, and processing the document AST via \treeProcessor\, which now operates on \OutputContext\ rather than just \Format\. Convenience builders like \ThemeBuilder\ and \TreeProcessorBuilder\ are provided to simplify theme construction.
io/src/main/scala/laika/theme · high confidence
PDF renderer now uses a two-phase render API with configurable book settings
The PDF output format has been refactored to implement the new \TwoPhaseRenderFormat\ API, separating tree preparation from binary post-processing. This change allows the PDF renderer to accept a \BookConfig\ (keyed by \laika.pdf\) to control metadata and other book-level settings, and introduces a dedicated post-processor that handles the conversion from XSL-FO to PDF using Apache FOP. Users benefit from more structured configuration options for PDF generation and a cleaner separation between document tree manipulation and final binary output.
pdf/src/main/scala/laika/format · high confidence
Platform-specific date-time implementations moved to laika.config
The platform-specific implementations for date and time handling (PlatformDateTimeImpl) have been moved into the laika.config package for both the JVM and JavaScript targets. This change consolidates the internal date-time logic, making the PlatformDateTimeImpl objects package-private within laika.config, which may affect internal access patterns but does not alter the public API surface for end users.
core/js/src/main, core/jvm/src/main · high confidence
Refactored Markdown parsing into internal modules and added \<script\> support
The Markdown parsing logic has been reorganized into new internal objects (BlockParsers, HTMLParsers, ListParsers) within the laika.internal.markdown package, moving implementation details out of the public API. This refactor includes a behavioral change to verbatim HTML handling: the parser now explicitly supports the \<script\> element as a root block element, allowing script tags to be parsed and preserved in the document tree rather than being ignored or treated as invalid markup.
core/shared/src/main/scala/laika/internal/markdown · high confidence
Refactored link resolution and validation into dedicated internal components
The link resolution logic has been restructured into three new internal classes: DocumentTargets, TreeTargets, and LinkValidator. DocumentTargets now handles the collection of referenceable elements (such as footnotes, citations, and headers) within a single document, while TreeTargets aggregates these targets across the entire document tree to support global lookups. LinkValidator manages the validation of internal links against target formats and configuration, including recovery strategies for format mismatches. This change improves the modularity of the link resolution process without altering the external behavior of link resolution for users.
core/shared/src/main/scala/laika/internal/link · high confidence
Refactored parser position tracking with SourceCursor and LineSource
The parser library now uses a new \SourceCursor\ trait (with \RootSource\, \LineSource\, and \BlockSource\ implementations) to track input position and context, replacing the previous \ParserContext\. This change ensures accurate position reporting for error messages and diagnostics, even when parsing fragments of input in multi-pass scenarios. Additionally, the \\~\ combinator and related syntax helpers have moved to \laika.parse.syntax\, requiring users to import from the new package to use concise parser definitions.
core/shared/src/main/scala/laika/parse · high confidence
Refactored text parsing infrastructure with new cursor and parser abstractions
The text parsing layer has been restructured to improve performance and position tracking. The \ParserContext\ has been renamed to \SourceCursor\ to better reflect its role in tracking document position, and the \\~\ type has been moved from \laika.ast\ to \laika.parse.builders\. A new \PrefixedParser\ trait and \PrefixCharacters\ class introduce trigger-character optimizations for span parsing, while \DelimiterParser\ provides a simplified API for defining inline delimiters with surrounding character constraints. The \Characters\ parser class has been rewritten for efficiency, and a new \CharGroup\ object offers predefined sets of ASCII characters (digits, hex, letters). Additionally, the \WhitespacePreprocessor\ now handles tab expansion and carriage return removal, and several deprecated APIs have been removed to shrink the public surface.
core/shared/src/main/scala/laika/parse/text · high confidence
Repackaged extension bundle APIs into laika.api.bundle
The core extension and configuration APIs have been moved into the new \laika.api.bundle\ package. This includes the central \ExtensionBundle\ trait for registering parsers, rewrite rules, and render overrides, as well as specialized components like \DirectiveRegistry\ for custom directives, \ParserBundle\ and \ParserBuilder\ for defining block and span parsers, \ConfigProvider\ for handling configuration headers, and utilities for syntax highlighting, slug building, and document type matching. Users extending Laika should now reference these classes within the \laika.api.bundle\ namespace.
core/shared/src/main/scala/laika/api/bundle · high confidence
Restructured AST package and introduced Cursor-based rewrite context
The \laika.ast\ package has been reorganized to improve code maintainability and API clarity. AST node definitions have been split across multiple files (e.g., \base.scala\, \containers.scala\, \Cursor.scala\) rather than being concentrated in a single large file. A new \Cursor\ system (\Cursor.scala\, \RootCursor\) has been introduced to provide context during rewrite operations, allowing access to parent/sibling nodes and configuration that was previously unavailable in the stateless tree. Additionally, helper utilities like \TreeBuilder\ and \ElementTraversal\ have been added to support tree construction and navigation.
core/shared/src/main/scala/laika/ast · high confidence
Restructured IO operations into dedicated builder traits
The IO builder API has been reorganized into specific operation traits (InputOps, TextOutputOps, BinaryOutputOps, TreeMapperOps, and IOBuilderOps) to provide a clearer and more modular flow for constructing document transformations. Users can now explicitly choose between sequential or parallel execution via the new builder methods, and the API exposes dedicated hooks for mapping or effectfully transforming documents and trees before rendering, replacing the previous monolithic approach with a composable set of builder steps.
io/src/main/scala/laika/io/ops · high confidence
Restructured builder APIs with new configuration and rewrite rule methods
The builder APIs in the \laika.api.builder\ package have been reorganized to improve configuration handling and rewrite rule management. \CommonBuilderOps\ now serves as the base for all operation builders, while \ParserBuilderOps\ and \RendererBuilderOps\ provide specific configuration methods. New methods like \withConfigValue\ allow setting configuration values with specific keys, and \withMessageFilters\ enables customizing how runtime messages are handled. The \TransformerBuilderOps\ introduces \buildingRules\ for more advanced rewrite rule management that can inspect the document before applying rules, alongside existing methods like \usingRules\, \usingBlockRule\, \usingSpanRule\, and \usingTemplateRule\. Additionally, \TwoPhaseRendererBuilder\ and \TwoPhaseTransformerBuilder\ support two-phase rendering formats.
core/shared/src/main/scala/laika/api/builder · high confidence
Restructured format API with new base traits and formatters
The \laika.api.format\ package has been reorganized to provide a clearer separation of concerns for format definitions. The previous generic \Format\ base trait has been removed and replaced with specific abstractions: \MarkupFormat\ for defining input markup parsers (including block and span parser registration), \TagFormatter\ as a base class for output formats that generate tag-based content like HTML or XML (providing utilities for escaping and element rendering), and \TwoPhaseRenderFormat\ to support output formats that require an intermediate representation, such as PDF via XSL-FO or EPUB via XHTML. This change refactors the core API surface for how formats are defined and rendered.
core/shared/src/main/scala/laika/api/format · high confidence
RestructuredText parser implementation refactored into internal package
The internal reStructuredText parsers have been reorganized into the \laika.internal.rst\ package, consolidating block, inline, list, and explicit block parsing logic into dedicated files (BaseParsers, BlockParsers, ExplicitBlockParsers, InlineParsers, ListParsers). This change moves parser-related implicits from \laika.parse.implicits\ to \laika.parse.syntax\ and updates internal ADT structures like \FootnoteLabel\ and \BulletFormat\ to use companion object members, while also applying scalafmt 3.8.2 formatting. Users should see no functional change, but the internal codebase is now more modular and consistently formatted.
core/shared/src/main/scala/laika/internal/rst · high confidence
Simplified public API with dedicated MarkupParser, Renderer, and Transformer classes
The core parsing and rendering capabilities are now exposed through three distinct, builder-based entry points: \MarkupParser\ for converting text markup into a document AST, \Renderer\ for converting a document AST into a target format string, and \Transformer\ for combining both steps into a single operation. This change replaces the previous unified API surface with a more modular structure, allowing users to choose whether they need parsing only, rendering only, or a full transformation, while maintaining the same underlying configuration and format support via \OperationConfig\.
core/shared/src/main/scala/laika/api · high confidence
Simplified sbt plugin API with dedicated extension and processor shortcuts
The sbt plugin now exposes a cleaner, more focused API for customization. Users can easily add custom logic via the new \laikaExtensions\ setting, which accepts \ExtensionBundle\ instances created through convenient shortcuts like \laikaHtmlRenderer\, \laikaSpanRewriteRule\, and \laikaDocTypeMatcher\ (defined in \ExtensionBundles.scala\). Additionally, a new \laikaTreeProcessors\ setting allows users to inject custom AST transformations between parsing and rendering (defined in \TreeProcessors.scala\). The plugin also introduces \laikaDescribe\ for inspecting the current configuration and \laikaInputs\ for freely composing input trees, while consolidating configuration into \LaikaConfig\ and \LaikaPreviewConfig\.
sbt/src/main · high confidence
Support for custom resource resolution in PDF generation
PDF rendering now correctly resolves resources relative to specific source paths rather than using a global default. This is achieved by introducing a custom FOUserAgentFactory that bridges Apache FOP's internal resource resolution with Laika's per-invocation source paths, ensuring that assets like images and stylesheets are found correctly during document conversion.
pdf/src/main/scala/org · high confidence
Test coverage
Add scripted test for EPUB site generation; Add scripted test for Helium theme site generation; Add scripted test for PDF inclusion feature; Add scripted test for multi-format site generation; Add scripted test for the new HTML generation task; Add scripted tests for API documentation inclusion; Added Akka reference configuration and Markdown test suite resources; Added comprehensive HTML renderer tests; Added comprehensive syntax highlighting tests for Scala and Dotty; Added comprehensive test suite for Markdown parsing and rendering; Added integration test for HOCON parser; Added integration tests for the preview server routes; Added scripted test for PDF generation task; Added scripted test for XSL-FO and AST generation; Added scripted test for XSL-FO output generation; Added scripted test for laikaTreeProcessors setting; Added scripted tests for EPUB output generation; Added scripted tests for site generation and packaging; Added test coverage for AST, Path, and DocumentTree APIs; Added test coverage for Helium theme rendering; Added test coverage for PDF rendering configuration and output; Added test coverage for ReStructuredText parsing and rendering; Added test coverage for block, span, and template directive APIs; Added test coverage for link validation, path translation, and rewrite rules; Added test coverage for text parsing and whitespace preprocessing; Added test coverage for the laikaAST prettyPrint task; Added test for RST-to-HTML specification compliance; Added test for laikaEPUB task; Added test for laikaInputs setting; Added test for message filtering with Laika configuration; Added test infrastructure and specs for the Laika IO module; Added test resources for configuration includes and document tree structures; Added test suite for FilePath API; Added test suite for HOCON parsing and configuration resolution; Added test suite for parser combinators, position tracking, and source cursors; Added test suite for the Laika API; Added test suites for standard directives; Added test support for the new BinaryPostProcessor API; Added test utilities for constructing ExtensionBundles; Added tests for @:include and @:embed directives; Added tests for BalancedGroups logic; Added tests for CSS parser selectors and declarations; Added tests for ConfigValue.eval; Added tests for JVM date directive and platform date-time parsing; Added tests for JavaScript date parsing and formatting; Added tests for Markdown to HTML transformation compliance; Added tests for XSL-FO rendering and test theme configuration; Added tests for common syntax parsing rules; Added tests for configuration parsing in markup documents; Added tests for directive template parsing; Added tests for the markup root parser provider; Added tests for theme bundle configuration and codec behavior; Added unit tests for EPUB internal rendering and configuration; New test helper utilities for Laika IO; New test utilities for AST sample trees and assertions; Updated scripted test expectations for the Helium theme; Updated scripted tests for Helium theme HTML output; Updated scripted tests for the Helium theme default template.
Dependencies
Build infrastructure and manual documentation configuration
This change introduces a new set of build configuration files for the project. It defines dependency versions for Scala (2.12.20, 2.13.16, 3.3.6), Cats, fs2, http4s, and testing libraries in \Dependencies.scala\. It upgrades the build tool to sbt 1.11.6 and updates various sbt plugins, including sbt-typelevel to 0.8.0, sbt-mdoc to 2.7.2, and laika-sbt to 1.3.2. Additionally, it adds configuration for the manual documentation site (\ManualSettings.scala\), including versioning, Helium theme settings, and API links, along with custom directives for rendering color boxes in PDFs (\ManualBundle.scala\, \FoColorBoxes.scala\). It also includes configuration for binary compatibility filtering (\MimaFilters.scala\) and Scaladoc cleanup for Scala 2.12.
project · high confidence
Upgrade to sbt 1.0 and migrate build infrastructure
The project has migrated from sbt 0.13 to sbt 1.0, introducing a modern multi-project build structure with a \build.sbt\ root file and distinct sub-projects for core, IO, PDF, preview, and the sbt plugin. This change includes adopting the Typelevel sbt plugin for CI and publishing, updating cross-compilation to support Scala 2.12, 2.13, and Scala 3, and upgrading key dependencies such as http4s (switching to the Ember server), cats-effect, and Apache FOP. The sbt plugin itself has been refactored as an \AutoPlugin\ with streamlined settings, and scripted tests have been updated to reflect the new API and configuration styles.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 53.
Lenses
- Code Health 91
- Architecture 84
- Maturity 45
- Readiness 50
- Security 70
- Accessibility 63
Changes since last survey
- 300 commits — 271 feature/other, 29 fixes
By area
- (repo) — 106 commits
- project/plugins.sbt — 38 commits
- project/Dependencies.scala — 36 commits
- core/shared — 28 commits
- (root) — 26 commits
- io/src — 19 commits
- project/build.properties — 17 commits
- docs/src — 9 commits
- .github/workflows — 6 commits
- project/ManualSettings.scala — 6 commits
- sbt/src — 6 commits
- core/js — 1 commit
- core/jvm — 1 commit
- pdf/src — 1 commit
Notable commits
- fix: Helium CSS - fix margins for h1 headers (#569)
- fix: Helium CSS - fix version menu background color (#583)
- fix: Merge pull request #649 from typelevel/fix/dup-imports
- fix: Merge pull request #652 from typelevel/fix/preview-server-pdf
- fix: Merge pull request #654 from typelevel/manual/misc-fixes
- fix: Merge pull request #655 from typelevel/helium/fix-font-resources
- fix: Merge pull request #656 from typelevel/core/fix-keys
- fix: Merge pull request #659 from typelevel/core/fix-datetime-spec
- fix: Merge pull request #669 from typelevel/fix/verbatim-html-script
- fix: Merge pull request #670 from typelevel/fix/include-rewrite-phase
- fix: Merge pull request #672 from typelevel/fix/ast-to-string
- fix: Merge pull request #676 from typelevel/fix/verbatim-html-in-fo
- fix: Merge pull request #677 from typelevel/fix/remove-excluded-earlier
- fix: Merge pull request #704 from typelevel/fix/lazy-substitutions
- fix: README - fix link to API docs
- fix: apply workaround for scaladoc bugs only for Scala 2.12
- fix: apply workaround for scaladoc bugs only for Scala 2.12 (#540)
- fix: core - fix apiPath & downloadPath constants in LaikaKeys
- fix: core - fix expectedOffset in PlatformDateTimeSpec
- fix: fix CI badge in README
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
typelevel/Laika was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 2f7483f5b0d11715cfca811d122a3136e740238a — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.