Configuration

FLM has a flexible configuration system. Configuration controls parser settings, renderer options, feature selection and options, and workflow behavior. Configuration can come from multiple sources that are merged together in a well-defined order.

Configuration Hierarchy

Configuration is merged from several sources. When the same setting appears in multiple sources, the highest priority source wins. From highest to lowest priority:

  1. CLI flags (-f, -w, etc.) and --inline-config

  2. YAML front matter in the input file

  3. Configuration file (flmconfig.yaml or specified with -C)

  4. Inline default config (--inline-default-config)

  5. Built-in defaults

Configuration File Discovery

When no explicit configuration file is given with -C, FLM looks for configuration files in the current directory. It tries the following name patterns, and all matching files are loaded and merged together (more specific patterns take higher priority):

  • flmconfig+WORKFLOW.FORMAT.yaml (or .yml)

  • flmconfig+WORKFLOW.yaml (or .yml)

  • flmconfig.FORMAT.yaml (or .yml)

  • flmconfig.yaml (or .yml)

Here, WORKFLOW and FORMAT are replaced by the selected workflow and output format names. For each pattern, if a .yaml file exists it is used; otherwise a .yml file is tried.

This allows you to maintain a base flmconfig.yaml with shared settings and override specific options in format- or workflow-specific files (e.g., flmconfig.html.yaml).

Configuration Structure

The top-level structure of an FLM configuration file is:

flm:
  parsing:
    # Parser settings
    ...
  features:
    # Feature selection and per-feature configuration
    ...
  renderer:
    # Per-format renderer options
    ...
  workflow:
    # Workflow-specific configuration
    ...

  # additional configuration possible: default format, default workflow,
  # template settings...  (cf. below)

You can also include top-level metadata such as a document title:

title: 'My Document Title'
flm:
  ...

Schema Validation

A JSON schema for FLM configuration files is available at:

You can use this schema to get autocompletion and validation in your editor.

VS Code: Install the Red Hat YAML extension and add the following comment as the first line of your flmconfig.yaml:

# yaml-language-server: $schema=https://flm-core.readthedocs.io/en/latest/flm-config-json-schema.json

flm:
  parsing:
    dollar_inline_math_mode: true
  features:
    headings: {}
    ...

You can also validate your configuration from the command line with --validate-config-only:

flm myfile.flm --validate-config-only

Or print the full JSON schema with --print-config-json-schema:

flm myfile.flm --print-config-json-schema

YAML Front Matter

FLM documents can include YAML front matter at the top of the file, delimited by --- lines. The front matter is merged into the configuration with higher priority than the flmconfig.yaml file:

---
title: 'My FLM Document'
author: 'John Doe'
date: 'May 1, 2026'
flm:
  parsing:
    dollar_inline_math_mode: true
  features:
    endnotes:
      categories:
        - category_name: footnote
          counter_formatter: unicodesuperscript
          heading_title: 'Footnotes'
          endnote_command: 'footnote'
---

\section{Greeting}
Hello, \emph{world}. Inline math can now also be typeset
as $a$ and $b$.

The $import Directive

Use the $import directive to import configuration from external files, URLs, or Python extension packages:

$import:
  - my-flm-config.yaml
flm:
  ...

The $import target can be:

  • A relative or absolute file path: my-flm-config.yaml or /path/to/my/flm-config.yaml

  • A URL: https://example.com/my/flm-config.yaml

  • A Python package prefixed with pkg:: pkg:flm_citations

When a package name is specified, the package is loaded and its default FLM configuration is extracted from its flm_default_import_config attribute (a dictionary or a callable that returns a dictionary).

You can optionally follow the package name with a path to specify submodules/attributes to read instead of flm_default_import_config. For example, pkg:mypackage/foo/bar will import the module mypackage and read the configuration dictionary stored in mypackage.foo.bar.

Multiple imports are specified as a list; they are processed in order. Configuration specified alongside the import is merged on top.

Parser Configuration

flm:
  parsing:
    # Enable/disable comments as in LaTeX, led by '%%'
    enable_comments: true

    # This string initiates a comment up to the end of
    # the line, if comments are enabled.  By default we
    # require TWO '%' signs to avoid accidental comments
    # (e.g., "... is up 10% from ...")
    comment_start: '%%'

    # Enable/disable math mode with $ signs as in LaTeX
    # in addition to \( ...\)
    dollar_inline_math_mode: false

    # Force parsing of the content in block-level mode
    # (paragraphs).  Here 'null' means to auto-detect
    force_block_level: null

Renderer Configuration

Renderer options are specified under the format name within the renderer key. Only the options for the selected output format are used.

HTML renderer

flm:
  renderer:
    html:
      use_link_target_blank: false
      html_blocks_joiner: ''
      # use 'heading_tags_by_level: null' for defaults
      heading_tags_by_level:
        1: h1
        2: h2
        3: h3
        4: span
        5: span
        6: span
      inline_heading_add_space: true

Text renderer

flm:
  renderer:
    text:
      display_href_urls: true

LaTeX renderer

flm:
  renderer:
    latex:
      heading_commands_by_level:
        1: "section"
        2: "subsection"
        3: "subsubsection"
        4: "paragraph"
        5: "subparagraph"
        6: null

Markdown renderer

flm:
  renderer:
    markdown:
      use_target_ids: 'github'  # or 'anchor' or 'pandoc' or null

Feature Configuration

Features are selected and configured under the features key. Each feature is identified by its name.

Enable a feature with default options (use an empty dict):

flm:
  features:
    headings: {}
    refs: {}

Disable a feature:

flm:
  features:
    theorems: false

Configure a feature by providing a dict of options:

flm:
  features:
    endnotes:
      categories:
        - category_name: footnote
          counter_formatter: alph
          heading_title: 'Footnotes'
          endnote_command: 'footnote'
      render_options:
        include_headings_at_level: 1
        set_headings_target_ids: true
        endnotes_heading_title: null
        endnotes_heading_level: 1

Here is a more comprehensive example showing several features with their configuration:

flm:
  features:
    enumeration:
      enumeration_environments:
        enumerate:
          counter_formatter: null  # use defaults
        itemize:
          counter_formatter:
            - "\u2022"
            - '-'
            - "\u25B8"
    refs: {}
    endnotes:
      categories:
        - category_name: footnote
          counter_formatter: alph
          endnote_command: footnote
          heading_title: Footnotes
      render_options:
        include_headings_at_level: 1
        set_headings_target_ids: true
    floats:
      float_types:
        - counter_formatter: Roman
          float_caption_name: Fig.
          float_type: figure
          content_handlers: ['includegraphics']
        - counter_formatter: Roman
          float_caption_name: Tab.
          float_type: table
          content_handlers: ['cells', 'includegraphics']
    defterm: {}
    graphics: {}

You can also load features from external packages by using their fully qualified Python module path as the feature name:

flm:
  features:
    'flm.main.feature_graphics_collection': {}

Some additional configuration options

Some additional keys inside the flm: block can help you set a default format, workflow, and template so you don’t have to specify them on the command line. You can also set configuration variables for the templates.

flm:
   # ...
   default_workflow: 'templatebasedworkflow'
   default_format: 'html'
   template:
     # template to use when rendering html
     html: 'simple'
     # template to use when rendering latex
     latex: 'revtex'
   template_config:
     html:
       simple:
         render_header: true
         display_toc: true
         font:
           family: 'Source Serif Pro'
           size: '16px'
         layout:
           content_width: '640px'
         style:
           extra_css: |
             body { background-color: #e7e7f7; }
     latex:
       simple:
         documentclass:
           fontsize: '12pt'
         preamble:
           fonts: |
             \usepackage{newtxtext}
             \usepackage{newtxmath}
         render_toc: true

Per-Format Configuration

The built-in defaults include per-format overrides for renderer options and feature settings. For example, when rendering to text output, the endnotes counter formatter is automatically set to unicodesuperscript instead of alph.

You do not usually need to worry about per-format configuration, as the defaults handle common cases. If you need to customize per-format behavior, you can use format-specific config files (e.g., flmconfig.html.yaml) or specify settings in the renderer section for each format.

Extension Packages

FLM can be extended with external Python packages that provide additional features, templates, and workflows.

flm-citations

Automatically fetch citations from arXiv, DOI cross-references, or bibliography files. Install and import:

pip install flm-citations
$import:
  - pkg:flm_citations
bibliography:
  - mybibliography.yaml
  - anotherbib.json

Citations are organized by prefix:

  • arxiv:<arXiv ID> — retrieved from the arXiv API

  • doi:<DOI> — retrieved from doi.org

  • manual:{Manual citation} — uses the text directly

  • bib:key — looks up a key in the specified bibliography files (CSL-JSON or CSL-YAML format)

flm-templates

Additional HTML templates and template engines. Install and use:

pip install flm-templates flm-htmlplus
flm mydocument.flm -o output.html -w flm_htmlplus \
    -P 'pkg:flm_templates' -t sunset

Try also the template -t oldtextbook.

Writing your own extension packages

Extension packages are Python packages that can expose:

  • A flm_default_import_config attribute (or callable) for use with the $import: pkg:... directive

  • A get_template_path() function for template discovery

  • Custom feature classes for use in the features configuration

See the flm-citations source for an example of how to structure an extension package.

Advanced: Config Merger Directives

The configuration merger supports several special directives for advanced use cases:

$import

Import configuration from a file, URL, or package. See The $import Directive.

$defaults

Pull in default values from lower-priority configuration sources. This is used internally by the default configuration to ensure that user configuration is merged with sensible defaults.

$merge-config

Merge configuration into a named item within a list. Useful for modifying a specific item (identified by its name field) without replacing the entire list:

- $merge-config:
    name: footnote
    config:
      counter_formatter: roman
$remove-item

Remove a named item from a list:

- $remove-item: footnote
$no-merge

Mark a dictionary as non-mergeable. When this directive is present, the dictionary replaces any lower-priority value entirely instead of being recursively merged:

heading_tags_by_level:
  $no-merge: true
  1: h2
  2: h3