Documentation
¶
Index ¶
- func ApplyDefaults(fm map[string]interface{}, schema *engine.FrontmatterSchema) map[string]interface{}
- func ClassifyLang(cf *ContentFile, languages map[string]bool, defaultLang string)
- func ClassifyVersion(cf *ContentFile, versionIDs map[string]map[string]bool)
- func ComputePatternPermalink(pattern string, vars PermalinkVars) string
- func ComputePermalink(contentDir, filePath string) string
- func ComputePermalinkFromRelPath(relPath string) string
- func DetectUnknownFields(fmMap map[string]any, schema *engine.FrontmatterSchema, ...) []engine.ValidationWarning
- func ExtractFirstH1(markdown string) string
- func ExtractNumericPrefix(name string) (weight int, slug string, found bool)
- func FilenameSlug(filename string) (slug string, weight int)
- func FilenameToTitle(filename string) string
- func GetLastUpdated(filePath, strategy string, idx *GitLastModIndex) *time.Time
- func HasIgnoredSegment(rel string) bool
- func IsExpired(expiryDate time.Time, now time.Time) bool
- func IsIgnoredDirName(name string) bool
- func IsIgnoredFileName(name string) bool
- func IsScheduled(publishDate time.Time, now time.Time) bool
- func LoadSchema(collectionDir string) (*engine.FrontmatterSchema, error)
- func NormalizePermalink(permalink string) string
- func ParseAll(raw []byte) (map[string]interface{}, *engine.Frontmatter, string, int, error)
- func ParseFrontmatter(raw []byte) (*engine.Frontmatter, string, error)
- func PrefixPermalink(permalink, lang, defaultLang string) string
- func ShouldExclude(draft bool, publishDate, expiryDate time.Time, ...) bool
- func Slugify(s string) string
- func ValidatePageFields(page *engine.Page, fm *engine.Frontmatter) []engine.ValidationWarning
- func VersionFreeRelPath(cf *ContentFile) string
- type Collision
- type ContentFile
- type GitLastModIndex
- type Inferrer
- type PageIndex
- func (idx *PageIndex) AddAssets(dir string)
- func (idx *PageIndex) Collisions() []Collision
- func (idx *PageIndex) CopyAssetsFrom(prev *PageIndex)
- func (idx *PageIndex) CopyHeadingsFrom(prev *PageIndex, exclude map[string]struct{})
- func (idx *PageIndex) HasAsset(path string) bool
- func (idx *PageIndex) HasHeading(permalink, headingID string) bool
- func (idx *PageIndex) HasPage(permalink string) bool
- func (idx *PageIndex) HeadingsFor(permalink string) []string
- func (idx *PageIndex) LookupByPermalink(permalink string) *engine.Page
- func (idx *PageIndex) LookupBySlug(slug string) *engine.Page
- func (idx *PageIndex) LookupInLane(relPermalink, lang, version string) *engine.Page
- func (idx *PageIndex) PageCount() int
- func (idx *PageIndex) Permalinks() []string
- func (idx *PageIndex) SetHeadings(permalink string, headingIDs []string)
- type Parser
- type PermalinkVars
- type Scanner
- type Transformer
- type Validator
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyDefaults ¶
func ApplyDefaults(fm map[string]interface{}, schema *engine.FrontmatterSchema) map[string]interface{}
ApplyDefaults fills in missing frontmatter fields from schema defaults. Returns a new map (does not mutate the input).
func ClassifyLang ¶
func ClassifyLang(cf *ContentFile, languages map[string]bool, defaultLang string)
ClassifyLang sets the Lang, LangRelPath, and adjusts CollectionName on a ContentFile based on whether its first path segment matches a configured language code.
For single-language sites (languages is nil/empty), this is a no-op.
func ClassifyVersion ¶
func ClassifyVersion(cf *ContentFile, versionIDs map[string]map[string]bool)
ClassifyVersion sets the Version and VersionRelPath on a ContentFile based on whether the path segment after the collection name matches a configured version ID. Must be called after ClassifyLang.
For single-version sites (versionIDs is nil/empty), this is a no-op.
func ComputePatternPermalink ¶
func ComputePatternPermalink(pattern string, vars PermalinkVars) string
ComputePatternPermalink generates a permalink from a pattern string. Supported variables: :slug, :year, :month, :day, :section, :collection, :title
func ComputePermalink ¶
func ComputePermalinkFromRelPath ¶
ComputePermalinkFromRelPath computes a permalink from a forward-slash relative path (e.g. cf.LangRelPath). Unlike ComputePermalink, this operates on a path already stripped of any language directory prefix, producing a language-free RelPermalink that is identical across translations.
func DetectUnknownFields ¶
func DetectUnknownFields(fmMap map[string]any, schema *engine.FrontmatterSchema, taxCfg map[string]config.TaxonomyConfig, filePath string) []engine.ValidationWarning
DetectUnknownFields warns about frontmatter keys not recognized by Sarde. Schema-defined custom fields, taxonomy keys from taxCfg, and children of cascade/params are excluded.
func ExtractFirstH1 ¶
ExtractFirstH1 finds the first Markdown H1 heading (# Title) in raw markdown. Returns empty string if no H1 is found.
func ExtractNumericPrefix ¶
ExtractNumericPrefix parses a leading numeric prefix from a filename (without extension). "01-intro" returns (1, "intro", true). "intro" returns (0, "intro", false).
func FilenameSlug ¶
FilenameSlug extracts a slug from a filename, stripping extension and numeric prefix.
func FilenameToTitle ¶
FilenameToTitle converts a filename to a human-readable title. Strips extension, strips numeric prefix, replaces hyphens/underscores with spaces, title cases.
func GetLastUpdated ¶
func GetLastUpdated(filePath, strategy string, idx *GitLastModIndex) *time.Time
GetLastUpdated returns the "last updated" timestamp for a file according to the configured strategy. It returns nil when disabled or when no timestamp can be determined.
Strategies:
- "false" / "off" / "none" — disabled, returns nil
- "git" (default) — commit time, falls back to mtime when unavailable
- "mtime" — file modification time
The git strategy has three cases depending on idx:
- nil index: resolve per file (one subprocess), for callers with no index
- index present but unavailable: git was already probed and found unusable, so fall straight back to mtime rather than retrying per file
- index available: O(1) map lookup, no subprocess
func HasIgnoredSegment ¶ added in v1.0.0
HasIgnoredSegment reports whether any directory segment of the slash-separated content-relative path is ignored, or its leaf is an ignored file. Used by the incremental-rebuild path, which resolves single changed files without a directory walk.
func IsIgnoredDirName ¶ added in v1.0.0
IsIgnoredDirName reports whether a directory is excluded from content discovery. Dot- and underscore-prefixed directories (.trash, .obsidian, _drafts) are never content — the same convention the collection enumerators in internal/collection and internal/project apply.
func IsIgnoredFileName ¶ added in v1.0.0
IsIgnoredFileName reports whether a file is excluded from discovery. Only dot-prefixed (hidden) files are skipped — underscore-prefixed files such as _index.md are meaningful content.
func IsScheduled ¶
IsScheduled returns true if publishDate is non-zero and in the future.
func LoadSchema ¶
func LoadSchema(collectionDir string) (*engine.FrontmatterSchema, error)
LoadSchema reads config.yaml from a collection directory and returns the schema. Returns (nil, nil) if no config file exists.
func NormalizePermalink ¶
NormalizePermalink ensures a permalink has a trailing slash (unless it's a file path with extension).
func ParseAll ¶
ParseAll parses raw file bytes into both an untyped map (for schema validation) and a typed Frontmatter struct. For YAML input (the common case), the struct is unmarshaled directly from the raw frontmatter bytes, avoiding a redundant marshal+unmarshal round-trip.
func ParseFrontmatter ¶
func ParseFrontmatter(raw []byte) (*engine.Frontmatter, string, error)
ParseFrontmatter is a convenience function that parses raw file bytes into a typed Frontmatter struct and the Markdown body. It handles all three frontmatter formats (YAML, TOML, JSON) uniformly by converting through YAML.
func PrefixPermalink ¶
ComputePermalink returns the clean URL for a content file. All permalinks end with "/" and use forward slashes.
Examples:
content/_index.md → "/" content/about.md → "/about/" content/docs/_index.md → "/docs/" content/docs/getting-started.md → "/docs/getting-started/" content/docs/guide/index.md → "/docs/guide/"
PrefixPermalink prepends a language prefix to a permalink for non-default languages. Used when generating fallback pages that need language-prefixed URLs. For the default language, it returns the permalink unchanged.
func ShouldExclude ¶
func ShouldExclude(draft bool, publishDate, expiryDate time.Time, includeDrafts, includeFuture, includeExpired bool, now time.Time) bool
ShouldExclude returns true if a page should be excluded from output based on draft status, scheduling, and expiry.
func Slugify ¶
Slugify converts a string to a URL-safe slug. Lowercase, spaces/underscores become hyphens, non-alphanumeric stripped, collapsed.
func ValidatePageFields ¶
func ValidatePageFields(page *engine.Page, fm *engine.Frontmatter) []engine.ValidationWarning
func VersionFreeRelPath ¶
func VersionFreeRelPath(cf *ContentFile) string
VersionFreeRelPath returns a LangRelPath with the version segment removed. Used for computing a version-free RelPermalink.
"docs/v1/guides/auth.md" → "docs/guides/auth.md" "docs/intro.md" → "docs/intro.md" (unversioned, unchanged)
Types ¶
type Collision ¶
type Collision struct {
Permalink string
KeptFile string // first page registered at this URL
DroppedFile string // a later page that resolved to the same URL
}
Collision records two distinct pages that resolve to the same Permalink. The first page registered at a URL is kept; later pages are dropped (first-match semantics). These are accumulated rather than logged inline so the builder can dedupe and cap them once per build (see emitCollisionWarnings).
type ContentFile ¶
type ContentFile struct {
FilePath string // absolute path
RelPath string // relative to content dir (forward slashes)
Kind engine.NodeKind // home, section, page, bundle, standalone
CollectionName string // top-level dir name, "" for root-level files
Slug string // derived from filename
Order int // from numeric prefix
IsBundle bool // true if index.md with sibling assets
BundleAssets []string // sibling non-.md files (bundles only)
Lang string // language code (set by i18n detector)
LangRelPath string // relative path within language root (for translation matching)
Version string // version ID (set by version detector), e.g. "v1"
VersionRelPath string // path within the version root (cross-version key)
}
ContentFile holds metadata about a discovered content file.
type GitLastModIndex ¶ added in v1.1.0
type GitLastModIndex struct {
// contains filtered or unexported fields
}
GitLastModIndex holds the most recent commit time for each content path, built from a single `git log` walk instead of one subprocess per file.
A nil index means no index was built and callers should use the per-file path. A non-nil index with available == false means git was probed and found unusable; callers must fall straight back to mtime rather than retrying per file.
func BuildGitLastModIndex ¶ added in v1.1.0
func BuildGitLastModIndex(contentDir string, wantedPaths []string) (*GitLastModIndex, error)
BuildGitLastModIndex walks git history once for contentDir and records the most recent commit time for every path in wantedPaths that git knows about.
It never fails the build: any git problem yields an index with available == false plus a descriptive error the caller folds into a single build warning.
func (*GitLastModIndex) Available ¶ added in v1.1.0
func (idx *GitLastModIndex) Available() bool
Available reports whether the index holds usable git data.
func (*GitLastModIndex) Lookup ¶ added in v1.1.0
func (idx *GitLastModIndex) Lookup(absPath string) (time.Time, bool)
Lookup returns the most recent commit time for absPath. The second result is false when the path is untracked, was deleted from git after its last commit (tombstoned), or no index is available. Renamed files resolve normally: the walk keys the rename destination, so they carry the rename-commit time.
func (*GitLastModIndex) Shallow ¶ added in v1.1.0
func (idx *GitLastModIndex) Shallow() bool
Shallow reports whether the repository is a shallow clone, in which case history predating the shallow boundary is missing and affected pages fall back to mtime.
func (*GitLastModIndex) Stale ¶ added in v1.1.0
func (idx *GitLastModIndex) Stale() bool
Stale reports whether HEAD moved since the index was built, which happens when a commit lands outside the dev server (for example in another terminal). One `git rev-parse`, no history walk.
type Inferrer ¶
type Inferrer struct {
// LastUpdatedStrategy selects how missing Updated timestamps are resolved:
// "git" (via `git log`), "mtime" (default), or "false"/"off"/"none" (disabled).
LastUpdatedStrategy string
// GitIndex is the batched git-history snapshot used by the "git" strategy.
// Nil falls back to resolving each file with its own subprocess.
GitIndex *GitLastModIndex
}
Inferrer fills missing frontmatter values using filesystem metadata. This is the "zero-config magic" — users get sensible defaults without specifying title, date, weight, or slug in frontmatter.
func (*Inferrer) Infer ¶
Infer populates empty fields on a Page from the filesystem and content.
Inference cascade:
- Title: frontmatter �� first H1 in RawContent → filename title-cased
- Date: frontmatter → file modification time
- Updated: frontmatter → git commit time or file mtime, per LastUpdatedStrategy
- Weight: frontmatter → numeric prefix from filename → 0
- Slug: frontmatter → filename with prefix stripped, slugified
- Template: "splash" for home pages if not set
type PageIndex ¶
type PageIndex struct {
// contains filtered or unexported fields
}
PageIndex provides O(1) lookups of pages by permalink, slug, heading ID, and lane-scoped RelPermalink for internal link resolution.
func BuildPageIndex ¶
BuildPageIndex constructs a PageIndex from all pages. The bySlug map uses first-match semantics for duplicate slugs. The byLane map indexes each page by its RelPermalink within its (lang, version) lane.
func (*PageIndex) AddAssets ¶
AddAssets walks a public directory and indexes all files as root-relative paths.
func (*PageIndex) Collisions ¶
Collisions returns the distinct-page permalink collisions recorded during BuildPageIndex (first-match kept). Empty when no two pages share a URL.
func (*PageIndex) CopyAssetsFrom ¶ added in v1.0.0
CopyAssetsFrom copies another index's asset set. Used by the incremental rebuild's body-only fast path, which skips the public/ directory walk: public file changes never route through ContentRebuild (the dev-server watcher classifies them as ChangeStatic, which take the full-build path), so the previous build's asset set is still valid.
func (*PageIndex) CopyHeadingsFrom ¶ added in v1.0.0
CopyHeadingsFrom copies heading entries from a previous build's PageIndex, skipping any permalink in exclude. Used by incremental rebuilds to reuse unchanged pages' headings; changed pages populate their own entries afterward via SetHeadings.
func (*PageIndex) HasAsset ¶
HasAsset reports whether a public asset with the given root-relative path exists.
func (*PageIndex) HasHeading ¶
HasHeading reports whether the given heading ID exists on the page. Safe for concurrent use.
func (*PageIndex) HeadingsFor ¶
HeadingsFor returns the heading IDs for a page, or nil if not set.
func (*PageIndex) LookupByPermalink ¶
LookupByPermalink returns the page with the given permalink, or nil.
func (*PageIndex) LookupBySlug ¶
LookupBySlug returns the first page matching the given slug, or nil.
func (*PageIndex) LookupInLane ¶
LookupInLane returns the page with the given RelPermalink in the specified (lang, version) lane. Returns nil if not found.
func (*PageIndex) Permalinks ¶
Permalinks returns all indexed permalinks. Used for testing and debugging.
func (*PageIndex) SetHeadings ¶
SetHeadings stores heading IDs for a page. "_top" is always prepended. Safe for concurrent use.
type Parser ¶
type Parser struct{}
Parser auto-detects YAML (---), TOML (+++), and JSON ({}) frontmatter delimiters.
type PermalinkVars ¶
type PermalinkVars struct {
Slug string
Year string
Month string
Day string
Section string
Collection string
Title string
}
PermalinkVars holds the values available for pattern interpolation.
type Scanner ¶
type Scanner struct {
Languages map[string]bool // configured language codes (nil = single-language)
DefaultLang string // default language code
VersionIDs map[string]map[string]bool // collection name → set of version IDs (nil = no versioning)
}
Scanner walks the content directory and returns file paths grouped by collection.
func (*Scanner) ClassifyFile ¶
func (s *Scanner) ClassifyFile(contentDir, filePath string) (ContentFile, error)
ClassifyFile constructs a ContentFile for a single file path without walking the entire content directory. Used by incremental rebuild.
func (*Scanner) Discover ¶
Discover walks contentDir and returns file paths grouped by collection name. Root-level files (standalone, home) are grouped under the "" key.
func (*Scanner) DiscoverFiles ¶
func (s *Scanner) DiscoverFiles(contentDir string) ([]ContentFile, error)
DiscoverFiles walks contentDir and returns a richer ContentFile for each .md file found.
type Transformer ¶
type Transformer struct {
SummaryLength int // max words in auto-generated summary (from config)
}
Transformer enriches a Page with computed fields: word count, reading time, and summary.
type Validator ¶
type Validator struct{}
Validator validates frontmatter against a collection's schema definition.
func (*Validator) Validate ¶
func (v *Validator) Validate(fm map[string]interface{}, schema *engine.FrontmatterSchema) []engine.ValidationWarning
Validate checks frontmatter against a schema and returns warnings. A nil schema means no validation — returns nil. Never blocks the build; all issues are warnings.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
extensions/blockutil
Package blockutil provides shared helpers for container-style block directive parsers.
|
Package blockutil provides shared helpers for container-style block directive parsers. |
|
extensions/codediff
Package codediff is a stub extension for organizational completeness.
|
Package codediff is a stub extension for organizational completeness. |
|
extensions/genericdirective
Package genericdirective is the goldmark side of site- and theme-authored generic directives (internal/directive): one block parser and renderer handle every registered ::: directive, dispatching on the fence name.
|
Package genericdirective is the goldmark side of site- and theme-authored generic directives (internal/directive): one block parser and renderer handle every registered ::: directive, dispatching on the fence name. |