Documentation
¶
Overview ¶
Example ¶
package main
import (
"bytes"
"fmt"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/text"
"go.abhg.dev/goldmark/hashtag"
"github.com/will-wow/larkdown"
"github.com/will-wow/larkdown/match"
)
var recipeMarkdown = `
# My Recipe
Here's a long story about making dinner.
## Tags
#dinner #chicken
## Ingredients
- Chicken
- Vegetables
- Salt
- Pepper
## Comments
| Name | Comment |
| --------- | ---------- |
| Alice | It's good! |
| Bob | It's bad |
`
type Comment struct {
Name string
Comment string
}
func (c Comment) String() string {
return fmt.Sprintf("%s: %s", c.Name, c.Comment)
}
type Recipe struct {
Tags []string
Ingredients []string
Comments []Comment
Html bytes.Buffer
}
func main() {
source := []byte(recipeMarkdown)
// Preprocess the markdown into goldmark AST
md := goldmark.New(
// Parse hashtags to they can be matched against.
goldmark.WithExtensions(
extension.Table,
&hashtag.Extender{Variant: hashtag.ObsidianVariant},
),
)
doc := md.Parser().Parse(text.NewReader(source))
recipe := Recipe{}
// ====
// Get the ingredients from the list
// ====
// Set up a ingredientsQuery for the first list under ## Ingredients
ingredientsQuery := []match.Node{
match.Branch{Level: 1},
match.Branch{Level: 2, Name: []byte("Ingredients")},
match.Index{Index: 0, Node: match.List{}},
}
// Decode the list items into a slice of strings
ingredients, err := larkdown.Find(doc, source, ingredientsQuery, larkdown.DecodeListItems)
if err != nil {
panic(fmt.Errorf("couldn't find an ingredients list: %w", err))
}
recipe.Ingredients = ingredients
// ====
// Get the tags from the file
// ====
// Matcher for the tags header
tagsQuery := []match.Node{
match.Branch{Level: 2, Name: []byte("Tags")},
}
// Find all Tags under the tags header, and decode their contents into strings.
tags, err := larkdown.FindAll(doc, source, tagsQuery, match.Tag{}, larkdown.DecodeTag)
if err != nil {
// This will not return an error if there are no tags, only if something else went wrong.
panic(fmt.Errorf("error finding tags: %w", err))
}
recipe.Tags = tags
tableQuery := []match.Node{
match.Branch{Level: 2, Name: []byte("Comments")},
match.Table{},
}
// ====
// Get the comments from a table
// ====
// Get data from the comments table
commentsTable, err := larkdown.Find(doc, source, tableQuery, larkdown.DecodeTableToMap)
if err != nil {
panic(fmt.Errorf("error finding comments: %w", err))
}
for _, comment := range commentsTable {
recipe.Comments = append(recipe.Comments, Comment{
Name: comment["Name"],
Comment: comment["Comment"],
})
}
fmt.Println(recipe.Ingredients)
fmt.Println(recipe.Tags)
fmt.Println(recipe.Comments)
}
Output: [Chicken Vegetables Salt Pepper] [dinner chicken] [Alice: It's good! Bob: It's bad]
Index ¶
- func DecodeListItems(node ast.Node, source []byte) (out []string, err error)
- func DecodeTableToMap(node ast.Node, source []byte) ([]map[string]string, error)
- func DecodeTag(node ast.Node, source []byte) (string, error)
- func DecodeText(node ast.Node, source []byte) (string, error)
- func Find[T any](doc ast.Node, source []byte, matcher []match.Node, ...) (out T, err error)
- func FindAll[T any](doc ast.Node, source []byte, matcher []match.Node, extractor match.Node, ...) (out []T, err error)
- func NewNodeRenderer(opts ...mdrender.Option) renderer.Renderer
- type FindAllConfig
- type FindAllOption
- type FindConfig
- type FindOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecodeListItems ¶ added in v0.0.1
Decode an ast.List into a slice of strings for each item
func DecodeTableToMap ¶ added in v0.0.7
DecodeTableToMap decodes a table node into a slice of maps of column names to column string values.
func DecodeTag ¶ added in v0.0.1
Decode a #tag parsed by go.abhg.dev/goldmark/hashtag into a string. Only the text content of the tag is returned, not the # prefix.
func DecodeText ¶ added in v0.0.1
Decode all the text inside any node
func Find ¶ added in v0.0.1
func Find[T any]( doc ast.Node, source []byte, matcher []match.Node, fn func(node ast.Node, source []byte) (T, error), opts ...FindOption, ) (out T, err error)
Use a matcher to find a node, and then decode its contents and return structured data.
Example ¶
package main
import (
"fmt"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/text"
"github.com/will-wow/larkdown"
"github.com/will-wow/larkdown/match"
)
var findMarkdown = `
# My Recipe
Here's a long story about making dinner.
## Tags
#dinner #chicken
## Ingredients
- Chicken
- Vegetables
- Salt
- Pepper
`
func main() {
source := []byte(findMarkdown)
// Preprocess the markdown into goldmark AST
md := goldmark.New()
doc := md.Parser().Parse(text.NewReader(source))
// Set up a ingredientsQuery for the first list under ## Ingredients
ingredientsQuery := []match.Node{
match.Branch{Level: 1},
match.Branch{Level: 2, Name: []byte("Ingredients")},
match.Index{Index: 0, Node: match.List{}},
}
// Decode the list items into a slice of strings
ingredients, err := larkdown.Find(doc, source, ingredientsQuery, larkdown.DecodeListItems)
if err != nil {
panic(fmt.Errorf("couldn't find an ingredients list: %w", err))
}
fmt.Println(ingredients)
}
Output: [Chicken Vegetables Salt Pepper]
func FindAll ¶ added in v0.0.1
func FindAll[T any]( doc ast.Node, source []byte, matcher []match.Node, extractor match.Node, fn func(node ast.Node, source []byte) (T, error), opts ...FindAllOption, ) (out []T, err error)
Use a matcher to find a all nodes, then decode its contents and return structured data.
Example ¶
package main
import (
"fmt"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/text"
"go.abhg.dev/goldmark/hashtag"
"github.com/will-wow/larkdown"
"github.com/will-wow/larkdown/match"
)
var findAllMarkdown = `
# My Recipe
Here's a long story about making dinner.
## Tags
#dinner #chicken
## Ingredients
- Chicken
- Vegetables
- Salt
- Pepper
`
func main() {
source := []byte(findAllMarkdown)
// Preprocess the markdown into goldmark AST
md := goldmark.New(
// Parse hashtags to they can be matched against.
goldmark.WithExtensions(
&hashtag.Extender{Variant: hashtag.ObsidianVariant},
),
)
doc := md.Parser().Parse(text.NewReader(source))
tagsQuery := []match.Node{
match.Branch{Level: 2, Name: []byte("Tags")},
}
// Find all Tags under the tags header, and decode their contents into strings.
tags, err := larkdown.FindAll(doc, source, tagsQuery, match.Tag{}, larkdown.DecodeTag)
if err != nil {
// This will not return an error if there are no tags, only if something else went wrong.
panic(fmt.Errorf("error finding tags: %w", err))
}
fmt.Println(tags)
}
Output: [dinner chicken]
Types ¶
type FindAllConfig ¶ added in v0.0.8
type FindAllConfig struct {
// AllowNoMatch allows FindAll to return nil when no match is found. By default it will return a query.QueryError.
AllowNoMatch bool
}
FindAllConfig configures the FindAll function.
type FindAllOption ¶ added in v0.0.8
type FindAllOption func(*FindAllConfig)
FindAllOption describes a functional option for FindAll.
func FindAllAllowNoMatch ¶ added in v0.0.8
func FindAllAllowNoMatch() FindAllOption
AllowNoMatch allows FindAll to return nil when no match is found. By default it will return a query.QueryError.
type FindConfig ¶ added in v0.0.8
type FindConfig struct {
// AllowNoMatch allows Find to return nil when no match is found. By default it will return a query.QueryError.
AllowNoMatch bool
}
FindConfig configures the Find function.
type FindOption ¶ added in v0.0.8
type FindOption func(*FindConfig)
FindOption describes a functional option for Find.
func FindAllowNoMatch ¶ added in v0.0.8
func FindAllowNoMatch() FindOption
FindAllowNoMatch allows Find to return nil when no match is found. By default it will return a query.QueryError.
Directories
¶
| Path | Synopsis |
|---|---|
|
gmast provides some helper functions for working with goldmark's AST.
|
gmast provides some helper functions for working with goldmark's AST. |
|
internal
|
|
|
test
Test helpers
|
Test helpers |
|
match provides a query language for matching nodes in a larkdown.Tree
|
match provides a query language for matching nodes in a larkdown.Tree |
|
Package mdfront adds support for rendering frontmatter to markdown for goldmark.
|
Package mdfront adds support for rendering frontmatter to markdown for goldmark. |
|
query handles finding a match in a tree, but not unmarshaling the node.
|
query handles finding a match in a tree, but not unmarshaling the node. |