markdownbodytext

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package markdownbodytext parses and encodes markdown body text with optional structured frontmatter.

A frontmatter block is the metadata document at the very top of a markdown file. Katalyst recognizes the three formats used by Hugo, Obsidian, and Jekyll, detected by the opening fence:

---            +++            {
title: Dune    title = "Dune"   "title": "Dune",
year: 1965     year = 1965      "year": 1965
---            +++            }
# Body         # Body         # Body
(YAML)         (TOML)         (JSON)

The parsed representation is format-agnostic: regardless of the source format, Parse returns a Document whose Meta is a map[string]any, so checks and inspectors never need to know which format a file used. The detected format is recorded in Document.Format so Encode can round-trip a file back into its own syntax rather than rewriting, say, TOML as YAML.

Source-line tracking (Document.Lines) is currently full for YAML only; for TOML and JSON the map is empty. Error messages degrade gracefully when a line is unknown. Richer line tracking for the other formats is a planned follow-up.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnterminated indicates a file started with a frontmatter fence
	// but never had a matching closing fence.
	ErrUnterminated = errors.New("frontmatter: unterminated block")

	// ErrInvalidYAML indicates the bytes between the fences were not
	// valid YAML. The wrapped error contains the underlying yaml.v3
	// parser message.
	ErrInvalidYAML = errors.New("frontmatter: invalid YAML")

	// ErrInvalidTOML indicates the bytes between the "+++" fences were
	// not valid TOML.
	ErrInvalidTOML = errors.New("frontmatter: invalid TOML")

	// ErrInvalidJSON indicates the bytes between the "{" / "}" fences
	// were not a valid JSON object.
	ErrInvalidJSON = errors.New("frontmatter: invalid JSON")
)

Sentinel errors. Callers should use errors.Is to identify them rather than relying on string matching.

Functions

func Encode

func Encode(doc *Document) ([]byte, error)

Encode serializes a parsed document back into bytes in canonical form — the dual of Parse:

  • the source format is preserved (TOML stays TOML, JSON stays JSON)
  • top-level keys sorted alphabetically
  • each format's default block/indent style
  • exactly one trailing newline on the whole file
  • body bytes preserved verbatim (leading blank lines trimmed)

It assumes doc.HasFrontmatter; the no-frontmatter passthrough is the caller's policy (see internal/fix). Why this canonical form is intentionally inflexible is documented in the fix deep-dive.

Types

type Document

type Document struct {
	HasFrontmatter bool
	// Format records the source syntax so the formatter can preserve it.
	Format   Kind
	Meta     map[string]any
	Body     []byte
	BodyLine int
	Lines    map[string]int
	// Frontmatter is the raw metadata block, for text search; Meta is
	// its parsed form. For YAML and TOML this is the bytes between the
	// fences (no fences). For JSON it is the object including its braces,
	// since the braces are part of the JSON. Nil when HasFrontmatter is
	// false.
	Frontmatter []byte
}

Document is the result of parsing a markdown file.

If HasFrontmatter is false, Meta is nil and Body holds the entire original input (verbatim).

Lines maps JSON-pointer paths into Meta ("/title", "/tags/0", etc.) to their 1-indexed source line numbers in the original file. The opening fence counts as line 1, so the first key is typically at line 2. Lines is empty when HasFrontmatter is false, and (today) for TOML and JSON frontmatter.

func Parse

func Parse(src []byte) (*Document, error)

Parse extracts frontmatter from src, detecting the format (YAML, TOML, or JSON) from the opening fence.

The function never modifies src. It returns a Document whose Body is a sub-slice of src (after BOM stripping); callers that mutate the result should copy first.

type Kind

type Kind int

Kind identifies which frontmatter syntax a document uses. (It is named Kind rather than Format to avoid colliding with the Format function.)

const (
	// KindYAML is "---"-fenced YAML. It is also the zero value, used for
	// documents that have no frontmatter at all (where it is moot).
	KindYAML Kind = iota
	// KindTOML is "+++"-fenced TOML.
	KindTOML
	// KindJSON is "{" / "}"-delimited JSON.
	KindJSON
)

func (Kind) String

func (k Kind) String() string

String returns the lowercase name of the format ("yaml", "toml", "json").

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL