ktw

package module
v0.0.0-...-f3d1106 Latest Latest
Warning

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

Go to latest
Published: Dec 28, 2024 License: BSD-3-Clause Imports: 18 Imported by: 0

README ¶

ktw/web -- Markdown Renderer and Publisher

Warning: this is not production ready, and will change.

This is my feable attempt to create my own Markdown publishing framework. It is modeled after a number of projects that I've used and/or been involved with over the past few years. I take inspiration freely from Hugo and Caddy, as well as various Markdown interpreters. It is not meant to be a solution that fits anyone but myself, hence it'll be rather opinionated in what it implements and supports. IE: almost nothing. 😄

To install the web CLI:

$ go install github.com/nuttyswiss/ktw/cmd/web@latest

To run this, you point the CLI at site and do:

$ web --site ~/some/site verify
$ web --site ~/some/site generate
$ web --site ~/some/site publish

Where the site directory looks something like:

├── article.tmpl
├── config.yaml
└── htdocs
    ├── 404.html
    ├── 500.html
    ├── blog
    │   ├── article-01
    │   │   ├── index.html
    │   │   └── index.md
    │   ├── article-02
    │   │   ├── index.html
    │   │   └── index.md
    │   └── ...
    ├── index.html
    └── index.md

The generate sub-command will parse all the .md Markdown files and generate the analogous .html HTML file alongside the Markdown file. The verify command checks if there are any out of date files. And the publish command will copy the generated website to its final destination.

The config.yaml file contains the following:

# Config for github.com/nuttyswiss/ktw/cmd/web CLI
site: "example.com"
root: "sftp://host.example.com/tmp/testdir"
dir: "htdocs"

Note: the key names in this YAML file will likely change, as may the structure of the file. At the current time, web takes a --config argument, which can be used to point to the different config file. This can be used to publish the web site to a different place (for canary deployments, etc):

$ web --config canary.yaml --site ~/some/site publish

Future Work

  • Finish up transition to using html/template and allow for use of template variables within HTML templates as well as Markdown content.
  • Cleanup frontmatter parsing and passing of frontmatter to templating engine.
  • Integrate D2 parsing, maybe something like github.com/FurqanSoftware/goldmark-d2, or write our own to directly use oss.terrastruct.com/d2.
  • Write a code block parser that can use a "before"/"after" method to show the diff of a changed code block. Possibly using some separator, say :::, or something similar to separate before and after. Then using both colour and other visual indicators (strike-through, bold, etc) to show where and what the change in the code is.
  • Write our own Markdown parser, or use rsc.io/markdown as a starting point to write a smaller and more targeted Markdown parser and HTML converter.
  • Write an index generator, such that there is an easy method to generate an index of a set of pages.
  • Write support for "default frontmatter"/"metadata", such that we do not need to repeat ourselves ad'nauseum.
  • Think about how I'd like indexing to work; within article navigation, and possibly tags for articles.
  • Think about how to do other custom code snippet processing. Possibly by using something like htmx to send the contents of a code snippet to a backend processing service. This would take things from a purely static site to one that contacts other APIs to process the code snippets.
  • Add some sort of Bluesky integration to allow for comments on posts.
  • Add rsync support, sftp will get slow(er) over time.

Documentation ¶

Overview ¶

Package ktw implements fuctionality to write Web applications in a Go centric manner. It implements a simple Markdown converter with extra functionality.

It uses a customized Goldmark Markdown processor that contains a few enhancements. In particular, it allows for special styling of "Note:", "Info:", and "Warning:" paragraphs, which are paragraphs that start with the aforementioned words (with the following ":"). These will be rendered as HTML "<p>" elements with a class of "note", "info", and "warning" respectively.

The code fence has also been enhanced. It uses the Chroma extension to parse and provide spans with classes (as before), but it adds the ability to add attributes to the "<code>" element. In particular, it revives the "class=language-..." class, and adds any other classes and/or IDs that you mention in a custom attribute extension:

```go {.good #example1} package awesome ```

Would result in a code element such as: <code class="language-go good" id="example1">

```go {.bad #example2} package util ```

Would result in a code element such as: <code class="language-go bad" id="example2">

These can be used to provide different styles for different languages, as well as different styles (for example, background color) for code blocks. The IDs can be used to select (or point to) specific code blocks in the rendered HTML.

Index ¶

Constants ¶

This section is empty.

Variables ¶

This section is empty.

Functions ¶

func NewCustomCodeHighlight ¶

func NewCustomCodeHighlight() goldmark.Extender

NewCustomCodeHighlight returns a wrapped Chroma highlight extension.

func NewInfoBlockParser ¶

func NewInfoBlockParser() parser.BlockParser

NewInfoBlockParser returns a BlockParser that recognizes a "Info:" start, which it then ensures that the class attribute of the resulting HTML element has a "note" class added to aid in styling.

func NewNoteBlockParser ¶

func NewNoteBlockParser() parser.BlockParser

NewNoteBlockParser returns a BlockParser that recognizes a "Note:" start, which it then ensures that the class attribute of the resulting HTML element has a "note" class added to aid in styling.

func NewWarningBlockParser ¶

func NewWarningBlockParser() parser.BlockParser

NewWarningBlockParser returns a BlockParser that recognizes a "Warning:" start, which it then ensures that the class attribute of the resulting HTML element has a "note" class added to aid in styling.

Types ¶

type CustomCodeHighlight ¶

type CustomCodeHighlight struct {
	goldmark.Extender
}

CustomCodeHighlight implements a custom fenced code highlighter that uses Chroma under the hood, but also implements class and general HTML attribute handling.

type InfoBlockParser ¶

type InfoBlockParser struct {
	parser.BlockParser
}

InfoBlockParser implements a paragraph block parser that recognizes a paragraph starting with "Info:".

func (*InfoBlockParser) Open ¶

func (b *InfoBlockParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State)

func (*InfoBlockParser) Trigger ¶

func (b *InfoBlockParser) Trigger() []byte

Trigger will be triggered for lines starting with "Info:"

type Markdown ¶

type Markdown []byte

func (Markdown) Render ¶

func (m Markdown) Render(ctx context.Context, w io.Writer) error

Render Markdown into HTML.

TODO: use github.com/abhinav/goldmark-frontmatter to parse the frontmatter and pass that back to the callee, so they can use it to run an appropriate template with the frontmatter variables as input.

type NoteBlockParser ¶

type NoteBlockParser struct {
	parser.BlockParser
}

NoteBlockParser implements a paragraph block parser that recognizes a paragraph starting with "Note:".

func (*NoteBlockParser) Open ¶

func (b *NoteBlockParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State)

func (*NoteBlockParser) Trigger ¶

func (b *NoteBlockParser) Trigger() []byte

Trigger will be triggered for lines starting with "Note:"

type Page ¶

type Page struct {
	Title    string
	Metadata map[string]string
	Contents []Renderer

	// text.Template as we only use it to embed the Markdown rendered HTML
	// within `<< .Markdown >>`. The resulting document is also a template
	// and will be rendered using `package "html/template"` as a final pass
	// with the supplied meatadata.
	Template *txt.Template
}

Page represents a single Web page. It contains everything necessary to let the page's render function produce an HTML representation of the page and all its contents.

func (*Page) Render ¶

func (p *Page) Render(ctx context.Context, w io.Writer) error

Render produces the HTML representing this page and all its contents.

TODO: Use frontmatter style to create a template to evaluate with the frontmatter as input to the template. Find the template files by evaluating the provided, and parsed, configuration file.

type Renderer ¶

type Renderer interface {
	Render(context.Context, io.Writer) error
}

Renderer implements the Render functionality of any components.

type WarningBlockParser ¶

type WarningBlockParser struct {
	parser.BlockParser
}

WarningBlockParser implements a paragraph block parser that recognizes a paragraph starting with "Warning:".

func (*WarningBlockParser) Open ¶

func (b *WarningBlockParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State)

func (*WarningBlockParser) Trigger ¶

func (b *WarningBlockParser) Trigger() []byte

Trigger will be triggered for lines starting with "Warning:"

Directories ¶

Path Synopsis
cmd
web

Jump to

Keyboard shortcuts

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