// Ignore holds a set of patterns to ignore from parsing a .zsignore file
var Ignore *ignore.GitIgnore
+// Parser holds a configured global instance of the goldmark markdown parser
+var Parser goldmark.Markdown
+
var (
- configFile string
+ configFile string
+ enabledExtensions []string
// Title site title
Title string
Production = false
)
+// Extensions is a mapping of name to extension and the default set of extensions enabled
+// which can be overridden with -e/--extension or the extensions key
+// in ia config file such as .zs/config.yml
+var Extensions = map[string]goldmark.Extender{
+ "table": extension.Table,
+ "strikethrough": extension.Strikethrough,
+ "linkify": extension.Linkify,
+ "tasklist": extension.TaskList,
+ "definitionlist": extension.DefinitionList,
+ "footnote": extension.Footnote,
+ "typography": extension.Typographer,
+ "cjk": extension.CJK,
+ "highlighting": highlighting.NewHighlighting(
+ highlighting.WithStyle("github"),
+ highlighting.WithFormatOptions(
+ chromahtml.WithLineNumbers(true),
+ ),
+ ),
+ "anchor": &anchor.Extender{},
+ "d2": &d2.Extender{},
+ "embed": embed.New(),
+ "fences": &fences.Extender{},
+ "wikilink": &wikilink.Extender{},
+}
+
// Vars holds a map of global variables
type Vars map[string]string
+// MapKeys returns a slice of keys from a map
+func MapKeys[K comparable, V any](m map[K]V) []K {
+ r := make([]K, 0, len(m))
+ for k := range m {
+ r = append(r, k)
+ }
+ return r
+}
+
// NewTicker is a function that wraps a time.Ticker and ticks immediately instead of waiting for the first interval
func NewTicker(d time.Duration) *time.Ticker {
ticker := time.NewTicker(d)
log.SetLevel(log.InfoLevel)
}
+ var extensions []goldmark.Extender
+ for _, name := range enabledExtensions {
+ if extender, valid := Extensions[name]; valid {
+ extensions = append(extensions, extender)
+ } else {
+ log.Warnf("invalid extension: %s", name)
+ }
+ }
+
+ Parser = goldmark.New(
+ goldmark.WithExtensions(extensions...),
+ goldmark.WithParserOptions(
+ parser.WithAttribute(),
+ parser.WithAutoHeadingID(),
+ ),
+ goldmark.WithRendererOptions(
+ html.WithHardWraps(),
+ html.WithXHTML(),
+ html.WithUnsafe(),
+ ),
+ )
+
return nil
},
}
}
buf := &bytes.Buffer{}
- gm := goldmark.New(
- goldmark.WithExtensions(
- extension.Table,
- extension.Strikethrough,
- extension.Linkify,
- extension.TaskList,
- extension.DefinitionList,
- extension.Footnote,
- extension.Typographer,
- extension.CJK,
- highlighting.NewHighlighting(
- highlighting.WithStyle("github"),
- highlighting.WithFormatOptions(
- chromahtml.WithLineNumbers(true),
- ),
- ),
- &anchor.Extender{},
- &d2.Extender{},
- embed.New(),
- &fences.Extender{},
- &wikilink.Extender{},
- ),
- goldmark.WithParserOptions(
- parser.WithAttribute(),
- parser.WithAutoHeadingID(),
- ),
- goldmark.WithRendererOptions(
- html.WithHardWraps(),
- html.WithXHTML(),
- html.WithUnsafe(),
- ),
- )
- if err := gm.Convert([]byte(content), buf); err != nil {
+ if err := Parser.Convert([]byte(content), buf); err != nil {
return err
}
v["content"] = buf.String()
RootCmd.PersistentFlags().BoolP("debug", "D", false, "enable debug logging $($ZS_DEBUG)")
RootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "config file (default: .zs/config.yml)")
+ RootCmd.PersistentFlags().StringSliceVarP(&enabledExtensions, "extensions", "e", MapKeys(Extensions), "override and enable specific extensions")
RootCmd.PersistentFlags().BoolVarP(&Production, "production", "p", false, "enable production mode ($ZS_PRODUCTION)")
RootCmd.PersistentFlags().StringVarP(&Title, "title", "t", "", "site title ($ZS_TITLE)")
RootCmd.PersistentFlags().StringVarP(&Description, "description", "d", "", "site description ($ZS_DESCRIPTION)")