### Install frontmatter Go Library Source: https://github.com/adrg/frontmatter/blob/master/README.md Use 'go get' to install the frontmatter library. This command fetches and installs the library and its dependencies. ```bash go get github.com/adrg/frontmatter ``` -------------------------------- ### Project Documentation Navigation Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/FILES_MANIFEST.md Follow these steps to navigate the project documentation. Start with overview files and progress to detailed API references. ```text 1. Read INDEX.md or README.md for navigation 2. Follow appropriate reading path for your level 3. Use cross-references to explore related topics ``` ```text 1. Go to INDEX.md search guide 2. Find relevant section 3. Navigate to appropriate documentation file ``` ```text 1. Read OVERVIEW.md for context 2. Review MODULE_REFERENCE.md for API surface 3. Check api-reference/ for detailed documentation 4. Reference errors.md for error handling 5. Explore ADVANCED_USAGE.md for patterns ``` -------------------------------- ### Go Import with Alias Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Shows how to import the frontmatter package with an alias for brevity in Go code. Includes a usage example. ```go import fm "github.com/adrg/frontmatter" // Usage rest, err := fm.Parse(reader, &metadata) ``` -------------------------------- ### YAML Front Matter Example Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/parser.md Illustrates the structure of input with YAML front matter, including the delimiters and content. ```markdown --- title: Test --- Content here ``` -------------------------------- ### Check Current Module Version Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Use this command to verify the currently installed version of the frontmatter module in your project. ```bash go list -m github.com/adrg/frontmatter ``` -------------------------------- ### Parse Configuration and Content Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/OVERVIEW.md Combines configuration settings and executable content within a single file. This example uses TOML for configuration parsing. ```go var config struct { Version string `toml:"version"` Enabled bool `toml:"enabled"` Options map[string]string `toml:"options"` } rest, _ := frontmatter.Parse(reader, &config) // Apply config, execute rest as content/template ``` -------------------------------- ### YAML Front Matter Example Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/00_START_HERE.md Demonstrates the structure of YAML front matter, including metadata fields and the separation from the main content. ```yaml --- title: "My Post" date: 2023-01-15 --- Rest of the content... ``` -------------------------------- ### Example: Creating Custom TOML Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Shows how to create a custom TOML front matter format with unique delimiters ('###') and parse content using this configuration. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" "github.com/BurntSushi/toml" ) func main() { // Create a custom TOML format with different delimiters customFormat := frontmatter.NewFormat("###", "###", toml.Unmarshal) input := `### title = "Custom TOML" version = "2.0" ### Content section.` var matter struct { Title string `toml:"title"` Version string `toml:"version"` } rest, err := frontmatter.Parse(strings.NewReader(input), &matter, customFormat) if err != nil { panic(err) } fmt.Printf("Title: %s, Version: %s\n", matter.Title, matter.Version) fmt.Printf("Content: %s\n", string(rest)) } ``` -------------------------------- ### Handling Missing Front Matter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/parse.md This example shows how to handle cases where front matter is expected but not present. It specifically checks for the ErrNotFound error. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func main() { input := `No front matter here.` var matter struct { Title string `yaml:"title"` } _, err := frontmatter.MustParse(strings.NewReader(input), &matter) if err == frontmatter.ErrNotFound { fmt.Println("Front matter is required but not found") } } ``` -------------------------------- ### Read Front Matter and Content from File Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Shows how to open a file, parse its front matter into a struct, and retrieve the content. Panics on error for simplicity in this example. ```go package main import ( "fmt" "os" "github.com/adrg/frontmatter" ) func main() { file, err := os.Open("article.md") if err != nil { panic(err) } defer file.Close() var metadata struct { Title string `yaml:"title"` } content, err := frontmatter.Parse(file, &metadata) if err != nil { panic(err) } fmt.Printf("Title: %s\n", metadata.Title) fmt.Printf("Content length: %d bytes\n", len(content)) } ``` -------------------------------- ### Example: Creating Custom YAML Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Demonstrates creating a custom YAML front matter format using NewFormat with non-standard delimiters ('...') and parsing input with this custom format. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" ) func main() { // Create a custom YAML format with different delimiters customFormat := frontmatter.NewFormat("...", "...", yaml.Unmarshal) input := `... title: "Custom Format" author: "John Doe" ... Content goes here.` var matter struct { Title string `yaml:"title"` Author string `yaml:"author"` } rest, err := frontmatter.Parse(strings.NewReader(input), &matter, customFormat) if err != nil { panic(err) } fmt.Printf("Title: %s\n", matter.Title) fmt.Printf("Author: %s\n", matter.Author) fmt.Printf("Content: %s\n", string(rest)) } ``` -------------------------------- ### YAML Parsing Error Example Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Demonstrates an invalid YAML input due to incorrect indentation, which will result in a YAML parsing error. ```go // Invalid YAML input := `--- list: - item 1 - bad indent ---` // Results in YAML parsing error ``` -------------------------------- ### Example: Using Multiple Custom Formats Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Illustrates defining and using an array of custom front matter formats (YAML, TOML, JSON) with distinct delimiters to parse different input strings. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" "github.com/BurntSushi/toml" "encoding/json" ) func main() { // Define multiple custom formats formats := []*frontmatter.Format{ frontmatter.NewFormat("~~~", "~~~", yaml.Unmarshal), frontmatter.NewFormat("###", "###", toml.Unmarshal), frontmatter.NewFormat(";;;", ";;;", json.Unmarshal), } yamlInput := `~~~ name: "Project" ~~~YAML content.` tomlInput := `### name = "Project" ### TOML content.` var matter struct { Name string `yaml:"name" toml:"name" json:"name"` } // Parse YAML rest, _ := frontmatter.Parse(strings.NewReader(yamlInput), &matter, formats...) fmt.Printf("YAML: %s, Content: %s\n", matter.Name, string(rest)) // Parse TOML rest, _ = frontmatter.Parse(strings.NewReader(tomlInput), &matter, formats...) fmt.Printf("TOML: %s, Content: %s\n", matter.Name, string(rest)) } ``` -------------------------------- ### Enforcing Front Matter Requirement Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/parse.md Use this example when front matter is mandatory. It demonstrates decoding YAML front matter into a struct and handling potential errors. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func main() { input := `--- author: "Jane Doe" version: "1.0" --- Article content goes here.` var matter struct { Author string `yaml:"author"` Version string `yaml:"version"` } rest, err := frontmatter.MustParse(strings.NewReader(input), &matter) if err != nil { panic(err) } fmt.Printf("Author: %s\n", matter.Author) fmt.Printf("Version: %s\n", matter.Version) } ``` -------------------------------- ### TOML Parsing Error Example Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Illustrates an invalid TOML input with a duplicate section definition, leading to a TOML parsing error. ```go // Invalid TOML input := `+++ [section] key = value [section] # Duplicate section +++` // Results in TOML parsing error ``` -------------------------------- ### Create Custom Format with Unmarshaler (Go) Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/types.md Example of creating a custom unmarshaler function and then using it to define a new front matter format. Requires importing the frontmatter package. ```go package main import "github.com/adrg/frontmatter" // Custom unmarshaler for a hypothetical format func customUnmarshal(data []byte, v interface{}) error { // Custom decoding logic here return nil } // Create a format using the custom unmarshaler format := frontmatter.NewFormat("##", "##", customUnmarshal) ``` -------------------------------- ### NewFormat Constructor Signature Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Function signature for creating a new front matter format instance. It takes start and end delimiters, and an unmarshal function as parameters. ```go func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format ``` -------------------------------- ### Handle Parsing Errors Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Provides a basic example of checking for and handling errors returned by the frontmatter.Parse function. It's recommended to log and manage these errors appropriately. ```go content, err := frontmatter.Parse(reader, &metadata) if err != nil { // Log and handle the error return err } ``` -------------------------------- ### NewFormat Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Creates a new custom front matter format with specified start and end delimiters and an unmarshal function. ```APIDOC ## NewFormat ### Description Creates a new custom front matter format with specified start and end delimiters and an unmarshal function. ### Signature `func(string, string, UnmarshalFunc) *Format` ### Parameters - `start` (string) - The delimiter indicating the start of the front matter. - `end` (string) - The delimiter indicating the end of the front matter. - `unmarshal` (UnmarshalFunc) - The function to use for unmarshalling the front matter data. ### Returns - `*Format` - A pointer to the newly created Format struct. ``` -------------------------------- ### Optimize Parsing with Reusable Buffers Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Reuse internal buffers for multiple parses to improve performance in high-volume scenarios. Pre-allocate formats for consistent setup across files. ```go package main import ( "bytes" "sync" "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" ) // ReusableParsing shows how to reuse buffers for multiple parses func processManyFiles(filePaths []string) error { // Pre-allocate formats formats := []*frontmatter.Format{ frontmatter.NewFormat("---", "---", yaml.Unmarshal), } // Process with consistent setup for _, path := range filePaths { var metadata struct { Title string `yaml:"title"` } // Each file is parsed independently // Parser reuses internal buffers efficiently // rest, err := frontmatter.Parse(reader, &metadata, formats...) } return nil } ``` -------------------------------- ### NewFormat Constructor Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md The NewFormat constructor creates a new front matter format instance. It takes the starting delimiter, ending delimiter, and an unmarshal function as parameters. The UnmarshalDelims and RequiresNewLine fields are automatically set to false. ```APIDOC ## NewFormat Constructor ### Description Creates a new front matter format with the specified delimiters and unmarshal function. ### Signature ```go func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | start | string | Yes | — | Starting delimiter of the front matter | | end | string | Yes | — | Ending delimiter of the front matter | | unmarshal | UnmarshalFunc | Yes | — | Function that decodes the front matter data | ### Return - **Type:** `*Format` - **Description:** A pointer to a new Format instance configured with the provided parameters. UnmarshalDelims and RequiresNewLine are set to false ``` -------------------------------- ### Default Formats Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Lists the default formats recognized by the package, specifying their start and end delimiters, the format type, and whether they require new lines or specific unmarshaling delimiters. ```APIDOC ## Default Formats The package defines default formats that are automatically used when no custom formats are provided: | Start | End | Format | UnmarshalDelims | RequiresNewLine | |-------|-----|--------|-----------------|-----------------| | --- | --- | YAML | false | false | | ---yaml | --- | YAML | false | false | | +++ | +++ | TOML | false | false | | ---toml | --- | TOML | false | false | | ;;; | ;;; | JSON | false | false | | ---json | --- | JSON | false | false | | { | } | JSON | true | true | ``` -------------------------------- ### Parse Content Without Front Matter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/parse.md This example demonstrates parsing content that does not contain any front matter. The `Parse` function will return the original input data unchanged, and the provided struct for decoding will remain unmodified. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func main() { input := `This content has no front matter. It will be returned unchanged.` var matter struct { Title string `yaml:"title"` } rest, err := frontmatter.Parse(strings.NewReader(input), &matter) if err != nil { panic(err) } fmt.Printf("Matter unchanged: %+v\n", matter) fmt.Printf("All content returned: %s\n", string(rest)) // Output: // Matter unchanged: {Title:} // All content returned: This content has no front matter. // It will be returned unchanged. } ``` -------------------------------- ### Create Custom Front Matter Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/configuration.md Define a new front matter format with custom start and end delimiters and an unmarshaling function. By default, UnmarshalDelims and RequiresNewLine are set to false. ```go customFormat := frontmatter.NewFormat(start, end, unmarshalFunc) ``` -------------------------------- ### Custom YAML Format with Dot Delimiters Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Define a custom frontmatter format for YAML using `...` as both start and end delimiters. This is useful when the default `---` delimiters might conflict with content. ```go format := frontmatter.NewFormat("...", "...", yaml.Unmarshal) input := `... name: Custom ... Content` ``` -------------------------------- ### Custom JSON Format with Angle Bracket Delimiters Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Define a custom frontmatter format for JSON using `<<<` and `>>>` as start and end delimiters, respectively. This allows for JSON content that might otherwise be misinterpreted. ```go format := frontmatter.NewFormat("<<<", ">>>", json.Unmarshal) input := `<<< {"name": "CustomJSON"} >>> Content` ``` -------------------------------- ### Format Type Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Describes a front matter format, including start and end delimiters, and the unmarshalling logic. ```APIDOC ## Format Type ### Description Describes a front matter format, including start and end delimiters, and the unmarshalling logic. ### Fields - `Start` (string) - The delimiter indicating the start of the front matter. - `End` (string) - The delimiter indicating the end of the front matter. - `Unmarshal` (UnmarshalFunc) - The function to use for unmarshalling the front matter data. - `UnmarshalDelims` (bool) - Whether to include delimiters in the unmarshalled data. - `RequiresNewLine` (bool) - Whether a new line is required after the end delimiter. ``` -------------------------------- ### JSON Parsing Error Example Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Shows an invalid JSON input where a value is unquoted, causing a JSON parsing error. ```go // Invalid JSON input := `;;; {"key": value} # Unquoted value ;;;` // Results in JSON parsing error ``` -------------------------------- ### NewFormat Function Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Creates a new custom format for parsing front matter, specifying start and end delimiters and an unmarshal function. ```APIDOC ## func NewFormat ### Description Constructs and returns a new `Format` struct, which defines custom delimiters and an unmarshal function for parsing specific front matter syntaxes. ### Signature ```go func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **start** (string) - The string that marks the beginning of the front matter block. - **end** (string) - The string that marks the end of the front matter block. - **unmarshal** (UnmarshalFunc) - A function that takes the raw front matter data (as bytes) and unmarshals it into the target interface. ### Returns - **Format** - A pointer to the newly created `Format` struct. ``` -------------------------------- ### Frontmatter Package Structure Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/OVERVIEW.md Illustrates the directory structure of the frontmatter package, outlining the purpose of each file. ```go frontmatter/ ├── frontmatter.go # Main API (Parse, MustParse, ErrNotFound) ├── format.go # Format type and NewFormat constructor ├── parser.go # Internal parser implementation ├── example_test.go # Usage examples ├── frontmatter_test.go # Comprehensive tests ├── go.mod # Module definition ├── go.sum # Dependency checksums ├── README.md # User documentation └── LICENSE # MIT license ``` -------------------------------- ### Parse File with Error Handling Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Demonstrates how to parse a file with front matter and handle potential errors during file opening and parsing. Ensures resources are closed using defer. ```go package main import ( "fmt" "os" "github.com/adrg/frontmatter" ) func parseFile(filename string) error { file, err := os.Open(filename) if err != nil { return fmt.Errorf("failed to open file: %w", err) } defer file.Close() var metadata struct { Title string `yaml:"title"` Author string `yaml:"author"` } _, err = frontmatter.Parse(file, &metadata) if err != nil { return fmt.Errorf("failed to parse front matter: %w", err) } fmt.Printf("Parsed: %s by %s\n", metadata.Title, metadata.Author) return nil } func main() { if err := parseFile("post.md"); err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } } ``` -------------------------------- ### Import Frontmatter Package Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/INDEX.md Import the necessary frontmatter package to use its functionalities. ```go import "github.com/adrg/frontmatter" ``` -------------------------------- ### Clone Fork and Configure Remotes Source: https://github.com/adrg/frontmatter/blob/master/CONTRIBUTING.md Commands to clone your forked repository and set up the upstream remote for the original project. ```bash git clone https://github.com// cd git remote add upstream https://github.com// ``` -------------------------------- ### Catching Simulated I/O Errors Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/errors.md Demonstrates how to catch errors that occur during the reading process, such as simulated read failures or unexpected reader closures. ```go package main import ( "fmt" "github.com/adrg/frontmatter" ) type failingReader struct{} func (f *failingReader) Read(p []byte) (int, error) { return 0, fmt.Errorf("simulated read failure") } func main() { var matter struct { Title string `yaml:"title"` } _, err := frontmatter.Parse(&failingReader{}, &matter) if err != nil { fmt.Printf("I/O error: %v\n", err) } } ``` -------------------------------- ### Custom TOML Format with Multi-Character Delimiters Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Define a custom frontmatter format for TOML using `[[` as both start and end delimiters. This demonstrates the flexibility in choosing multi-character delimiters. ```go format := frontmatter.NewFormat("[[", "][", toml.Unmarshal) input := `[[ title = "Multi-Char" [[ Content` ``` -------------------------------- ### Go Direct Dependencies Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Lists the direct external dependencies required for the frontmatter package, including TOML and YAML parsing libraries. ```go require ( github.com/BurntSushi/toml v1.6.0 gopkg.in/yaml.v2 v2.4.0 ) ``` -------------------------------- ### Parse Explicit YAML Front Matter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Parses input with explicitly marked YAML front matter, starting with '---yaml' and ending with '---'. Useful for disambiguation. ```Go input := `---yaml\ author: "Jane Smith"\ date: "2023-06-15"\ ---\ Article content.` var meta struct { Author string `yaml:"author"` Date string `yaml:"date"` } rest, _ := frontmatter.Parse(strings.NewReader(input), &meta) ``` -------------------------------- ### Select Formats Conditionally Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Dynamically select frontmatter formats based on file extensions to handle different metadata syntaxes like TOML and YAML. ```go package main import ( "fmt" "path/filepath" "strings" "github.com/adrg/frontmatter" "github.com/BurntSushi/toml" "gopkg.in/yaml.v2" ) func getFormatsForFile(filename string) []*frontmatter.Format { ext := strings.ToLower(filepath.Ext(filename)) switch ext { case ".toml": return []*frontmatter.Format{ frontmatter.NewFormat("+++", "+++", toml.Unmarshal), } case ".yaml", ".yml": return []*frontmatter.Format{ frontmatter.NewFormat("---", "---", yaml.Unmarshal), } default: // Default: support all formats return nil // nil uses default formats } } func processFile(filename string) error { var metadata struct { Title string `yaml:"title" toml:"title"` } formats := getFormatsForFile(filename) // Use default formats if none selected // rest, err := frontmatter.Parse(reader, &metadata, formats...) return nil } ``` -------------------------------- ### Project Directory Structure Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/FILES_MANIFEST.md Illustrates the hierarchical organization of documentation files within the project, including the root directory and the api-reference subdirectory. ```text output/ ├── INDEX.md (Comprehensive navigation index) ├── README.md (Primary entry point) ├── OVERVIEW.md (Project overview) ├── MODULE_REFERENCE.md (Module metadata) ├── QUICK_START.md (Practical examples) ├── ADVANCED_USAGE.md (Advanced patterns) ├── types.md (Type reference) ├── errors.md (Error reference) ├── configuration.md (Configuration reference) ├── GENERATION_SUMMARY.txt (Generation report) ├── FILES_MANIFEST.md (This file) └── api-reference/ ├── parse.md (Parse/MustParse API) ├── format.md (Format API) ├── format-details.md (Format specifications) └── parser.md (Parser implementation) ``` -------------------------------- ### Custom Unmarshal Function in Go Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Implement a custom unmarshal function to parse proprietary or specialized front matter formats. This example demonstrates parsing a simple key=value format. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) // SimpleKeyValueUnmarshal parses a simple key=value format func SimpleKeyValueUnmarshal(data []byte, v interface{}) error { meta, ok := v.(*map[string]string) if !ok { return fmt.Errorf("expected *map[string]string") } *meta = make(map[string]string) lines := strings.Split(string(data), "\n") for _, line := range lines { line = strings.TrimSpace(line) if line == "" || strings.HasPrefix(line, "#") { continue } parts := strings.SplitN(line, "=", 2) if len(parts) == 2 { key := strings.TrimSpace(parts[0]) value := strings.TrimSpace(parts[1]) (*meta)[key] = value } } return nil } func main() { input := `:: title=Custom Format author=John Doe version=1.0.0 :: Content here` customFormat := frontmatter.NewFormat("::", "::", SimpleKeyValueUnmarshal) metadata := make(map[string]string) rest, err := frontmatter.Parse(strings.NewReader(input), &metadata, customFormat) if err != nil { panic(err) } fmt.Printf("Title: %s\n", metadata["title"]) fmt.Printf("Author: %s\n", metadata["author"]) fmt.Printf("Content: %s\n", string(rest)) } ``` -------------------------------- ### Parse TOML Front Matter in Go Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Demonstrates parsing content with TOML-formatted front matter. Ensure the metadata struct tags match the TOML keys (e.g., `toml:"title"`). ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func main() { input := `+++ title = "TOML Post" author = "Bob Wilson" tags = ["rust", "systems", "performance"] +++ Rust is a systems programming language.` var metadata struct { Title string `toml:"title"` Author string `toml:"author"` Tags []string `toml:"tags"` } content, err := frontmatter.Parse(strings.NewReader(input), &metadata) if err != nil { panic(err) } fmt.Printf("Title: %s\n", metadata.Title) fmt.Printf("Content: %s\n", string(content)) } ``` -------------------------------- ### Parse Frontmatter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/parser.md Instantiates a new parser and orchestrates the parsing process. Use this for standard parsing where front matter is optional. ```go func Parse(r io.Reader, v interface{}, formats ...*Format) ([]byte, error) { return newParser(r).parse(v, formats, false) } ``` -------------------------------- ### Recommended Error Handling Pattern Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/errors.md Illustrates a robust pattern for handling frontmatter parsing errors, including distinguishing between general parsing failures and the specific case where front matter is not found. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func parseContent(input string) error { var matter struct { Title string `yaml:"title"` } _, err := frontmatter.Parse(strings.NewReader(input), &matter) if err != nil { return fmt.Errorf("failed to parse front matter: %w", err) } return nil } func mustParseContent(input string) error { var matter struct { Title string `yaml:"title"` } _, err := frontmatter.MustParse(strings.NewReader(input), &matter) if err == frontmatter.ErrNotFound { return fmt.Errorf("front matter is required but not found") } if err != nil { return fmt.Errorf("failed to parse front matter: %w", err) } return nil } func main() { if err := parseContent("No front matter content"); err != nil { fmt.Println(err) } if err := mustParseContent("No front matter content"); err != nil { fmt.Println(err) } } ``` -------------------------------- ### Explicit YAML Format Marker Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Use `---yaml` to explicitly mark content as YAML frontmatter, ensuring correct parsing even if the content starts with characters that could be ambiguous. ```yaml ---yaml # Use this to explicitly mark YAML ``` -------------------------------- ### Parse Explicit JSON Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Use this snippet to parse JSON content marked with a `---json` start delimiter and `---` end delimiter. Delimiters are excluded from the unmarshaled data. ```go input := `---json { "author": "Alice", "score": 95.5 } --- JSON-marked content` var meta struct { Author string `json:"author"` Score float64 `json:"score"` } rest, _ := frontmatter.Parse(strings.NewReader(input), &meta) ``` -------------------------------- ### Parse Explicit TOML Front Matter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format-details.md Parses input with explicitly marked TOML front matter, starting with '---toml' and ending with '---'. Ensures correct TOML parsing. ```Go input := `---toml\ name = "MyApp"\ version = "2.1.0"\ [config]\ debug = true ---\ Application content` var meta struct { Name string `toml:"name"` Version string `toml:"version"` } rest, _ := frontmatter.Parse(strings.NewReader(input), &meta) ``` -------------------------------- ### Handle Multiple Custom Frontmatter Formats Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/configuration.md Provide a slice of `frontmatter.Format` to `frontmatter.Parse` to support multiple delimiters and unmarshaling functions. The package will attempt to parse the frontmatter using each format in order. ```go package main import ( "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" "github.com/BurntSushi/toml" "strings" ) func main() { formats := []*frontmatter.Format{ frontmatter.NewFormat("~~~", "~~~", yaml.Unmarshal), frontmatter.NewFormat("###", "###", toml.Unmarshal), } input := `~~~ title: YAML Format ~~~ Content` var meta struct { Title string `yaml:"title" toml:"title"` } frontmatter.Parse(strings.NewReader(input), &meta, formats...) } ``` -------------------------------- ### Format Type Definition Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/api-reference/format.md Defines the structure for a front matter format, including start and end delimiters, an unmarshal function, and boolean flags for delimiter inclusion and requiring a new line. ```go type Format struct { Start string End string Unmarshal UnmarshalFunc UnmarshalDelims bool RequiresNewLine bool } ``` -------------------------------- ### Parse Front Matter with Multiple Formats Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/README.md Parses front matter by attempting to match against a list of provided formats (e.g., YAML and TOML). The first matching format is used. ```go formats := []*frontmatter.Format{ frontmatter.NewFormat("---", "---", yaml.Unmarshal), frontmatter.NewFormat("+++", "+++", toml.Unmarshal), } rest, err := frontmatter.Parse(reader, &meta, formats...) ``` -------------------------------- ### Parse and Copy with io.TeeReader Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Use io.TeeReader to read from a source while simultaneously copying the content to a destination. This is useful for parsing frontmatter and saving the original content. ```go package main import ( "io" "os" "github.com/adrg/frontmatter" ) func parseAndCopy(src io.Reader, dst io.Writer) error { // Read from src while copying to dst ee := io.TeeReader(src, dst) var metadata struct { Title string `yaml:"title"` } _, err := frontmatter.Parse(tee, &metadata) return err } ``` -------------------------------- ### Check Latest Module Version Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md This command shows the latest available version of the frontmatter module. ```bash go list -m -u github.com/adrg/frontmatter ``` -------------------------------- ### Go Front Matter Parsing Functions Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/00_START_HERE.md Provides the main functions for parsing front matter. `Parse` is optional, while `MustParse` will error if no front matter is found. ```go // Parse front matter (optional) func Parse(reader, &struct, formats...) (content, error) ``` ```go // Parse front matter (required) func MustParse(reader, &struct, formats...) (content, error) ``` ```go // Create custom format func NewFormat(start, end, unmarshalFunc) *Format ``` -------------------------------- ### Parse Frontmatter with Default Formats Source: https://github.com/adrg/frontmatter/blob/master/README.md Demonstrates parsing front matter using the library's default formats (YAML, JSON, TOML). The parsed front matter is stored in the 'matter' struct, and the rest of the content is returned as a byte slice. Use frontmatter.MustParse if front matter is mandatory. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) var input = ` --- name: "frontmatter" tags: ["go", "yaml", "json", "toml"] --- rest of the content` func main() { var matter struct { Name string `yaml:"name"` Tags []string `yaml:"tags"` } rest, err := frontmatter.Parse(strings.NewReader(input), &matter) if err != nil { // Treat error. } // NOTE: If a front matter must be present in the input data, use // frontmatter.MustParse instead. fmt.Printf("%+v\n", matter) fmt.Println(string(rest)) // Output: // {Name:frontmatter Tags:[go yaml json toml]} // rest of the content } ``` -------------------------------- ### Reuse Custom Format Definitions Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Shows how to define custom front matter formats once and reuse them across multiple parsing operations for consistency. This involves creating a slice of frontmatter.Format. ```go var formats = []*frontmatter.Format{ frontmatter.NewFormat("...", "...", yaml.Unmarshal), } // Use across multiple Parse calls frontmatter.Parse(reader1, &meta1, formats...) frontmatter.Parse(reader2, &meta2, formats...) ``` -------------------------------- ### Update Go Module Dependencies Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Run this command to update your go.mod file with the correct Go version and tidy up dependencies. ```go go mod tidy // Updates go.mod with correct Go version ``` -------------------------------- ### Define and Parse Custom Front Matter Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/README.md Creates a new front matter format with custom delimiters and an unmarshaling function, then parses content using this format. ```go format := frontmatter.NewFormat("..."."...", yaml.Unmarshal) rest, err := frontmatter.Parse(reader, &meta, format) ``` -------------------------------- ### Combine Inputs with io.MultiReader Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Utilize io.MultiReader to combine multiple input sources into a single reader. This allows parsing frontmatter from several combined inputs. ```go package main import ( "io" "strings" "github.com/adrg/frontmatter" ) func parseMultipleSources(sources ...io.Reader) error { combined := io.MultiReader(sources...) var metadata struct { Title string `yaml:"title"` } _, err := frontmatter.Parse(combined, &metadata) return err } ``` -------------------------------- ### Format Creation Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/README.md Function to create custom front matter formats. ```APIDOC ## NewFormat ### Description Creates a new custom `Format` for parsing front matter with specified delimiters and an unmarshal function. ### Signature ```go func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format ``` ``` -------------------------------- ### Module Declaration Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Declares the module path and the minimum required Go version. This is typically found in the go.mod file. ```go module github.com/adrg/frontmatter go 1.19 ``` -------------------------------- ### Public Function Declarations Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Lists the signatures for the main public functions available in the frontmatter package: Parse, MustParse, and NewFormat. ```go func Parse(r io.Reader, v interface{}, formats ...*Format) ([]byte, error) func MustParse(r io.Reader, v interface{}, formats ...*Format) ([]byte, error) func NewFormat(start, end string, unmarshal UnmarshalFunc) *Format ``` -------------------------------- ### Push Topic Branch to Fork Source: https://github.com/adrg/frontmatter/blob/master/CONTRIBUTING.md Upload your local topic branch to your forked repository on GitHub. ```bash git push origin ``` -------------------------------- ### Update Module to Latest Version Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/MODULE_REFERENCE.md Execute this command to update the frontmatter module to its latest available version. ```bash go get -u github.com/adrg/frontmatter ``` -------------------------------- ### Parse Blog Post Metadata Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/OVERVIEW.md Extracts metadata like title, date, and author from a blog post using YAML front matter. The remaining content is returned separately. ```go var post struct { Title string `yaml:"title"` Date string `yaml:"date"` Author string `yaml:"author"` } rest, _ := frontmatter.Parse(reader, &post) // Use post metadata, render rest as content ``` -------------------------------- ### Basic Frontmatter Parsing Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/INDEX.md Parse front matter from a reader into a struct. The remaining content is returned as 'rest'. ```go var meta struct { Title string `yaml:"title"` } rest, err := frontmatter.Parse(reader, &meta) ``` -------------------------------- ### Parse Basic YAML Front Matter Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Parse a string containing YAML front matter and extract metadata and content. Ensure the input string has valid YAML front matter delimited by '---'. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" ) func main() { input := `--- title: "My First Post" author: "John Doe" date: 2023-01-15 --- This is the content of the blog post.` var metadata struct { Title string `yaml:"title"` Author string `yaml:"author"` Date string `yaml:"date"` } content, err := frontmatter.Parse(strings.NewReader(input), &metadata) if err != nil { panic(err) } fmt.Printf("Title: %s\n", metadata.Title) fmt.Printf("Author: %s\n", metadata.Author) fmt.Printf("Date: %s\n", metadata.Date) fmt.Printf("Content:\n%s\n", string(content)) } ``` -------------------------------- ### Parse Multiple Custom Formats in Go Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/QUICK_START.md Handle multiple front matter formats (e.g., YAML and TOML) in a single run. Pass an array of `frontmatter.Format` objects to `Parse`. The library attempts to match the input against the provided formats. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" "github.com/BurntSushi/toml" ) func main() { // Support both custom YAML and custom TOML formats := []*frontmatter.Format{ frontmatter.NewFormat("~~~", "~~~", yaml.Unmarshal), frontmatter.NewFormat("###", "###", toml.Unmarshal), } yamlInput := `~~~ title: "YAML with tildes" version: "1.0" ~~~ Content in YAML format` tomlInput := `### title = "TOML with hashes" version = "2.0" ### Content in TOML format` var metadata struct { Title string `yaml:"title" toml:"title"` Version string `yaml:"version" toml:"version"` } // Parse YAML content1, _ := frontmatter.Parse(strings.NewReader(yamlInput), &metadata, formats...) fmt.Printf("YAML: Title=%s, Content=%s\n", metadata.Title, strings.TrimSpace(string(content1))) // Parse TOML metadata = struct { Title string `yaml:"title" toml:"title"` Version string `yaml:"version" toml:"version"` }{} content2, _ := frontmatter.Parse(strings.NewReader(tomlInput), &metadata, formats...) fmt.Printf("TOML: Title=%s, Content=%s\n", metadata.Title, strings.TrimSpace(string(content2))) } ``` -------------------------------- ### Parse Frontmatter with Fallback to Defaults Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/ADVANCED_USAGE.md Use this function when parsing might fail due to malformed frontmatter. It attempts to parse, and if an error occurs, it returns default metadata and the original input. It also fills in missing fields from the parsed metadata with defaults. ```go package main import ( "fmt" "strings" "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" ) type Metadata struct { Title string `yaml:"title"` Description string `yaml:"description"` } // ParseWithFallback attempts parsing; falls back to default metadata on error func ParseWithFallback(input string, defaults Metadata) (Metadata, string, error) { var meta Metadata rest, err := frontmatter.Parse(strings.NewReader(input), &meta) if err != nil { // Parsing failed, use defaults fmt.Printf("Warning: parsing failed (%v), using defaults\n", err) return defaults, input, nil } // Fill in missing fields with defaults if meta.Title == "" { meta.Title = defaults.Title } if meta.Description == "" { meta.Description = defaults.Description } return meta, string(rest), nil } func main() { defaults := Metadata{ Title: "Untitled", Description: "No description provided", } // Invalid YAML invalidInput := `--- title: Test invalid: [unclosed array --- Content` meta, content, err := ParseWithFallback(invalidInput, defaults) fmt.Printf("Title: %s\n", meta.Title) fmt.Printf("Description: %s\n", meta.Description) } ``` -------------------------------- ### Parse Static Site Generator Metadata Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/OVERVIEW.md Parses Hugo-style front matter, including title, description, and tags, from markdown files. The rest of the file is treated as content. ```go var metadata struct { Title string `yaml:"title"` Description string `yaml:"description"` Tags []string `yaml:"tags"` } rest, _ := frontmatter.Parse(reader, &metadata) // Generate site using metadata, content from rest ``` -------------------------------- ### Define Custom YAML Frontmatter Format Source: https://github.com/adrg/frontmatter/blob/master/_autodocs/configuration.md Use `frontmatter.NewFormat` to create a custom format with specific delimiters and an unmarshaling function. This is useful when your frontmatter is not in a standard format. ```go package main import ( "github.com/adrg/frontmatter" "gopkg.in/yaml.v2" "strings" ) func main() { customFormat := frontmatter.NewFormat("...", "...", yaml.Unmarshal) input := `... title: Custom Format ... Content` var meta struct { Title string `yaml:"title"` } frontmatter.Parse(strings.NewReader(input), &meta, customFormat) } ```