-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Research checkpoint commit: markdown processing.
This has... mixed success. I've got three different irons in the fire here: 1. The plain markdown text coming out (to sanity check my templates) 2. A library called Glamour used to process it 3. A brief prototype of going straight to Goldmark and using that system's renderers directly on the AST. I've posted a bunch of notes on this in the dev chat on Matrix already, as well as some screenshots, so I'll keep this commit note briefer. In short, controlling the line spacing and indentation is turning out remarkably hard with option 2. In fact, I think it's outright impossible without some invasive changes tantamount to forking. So that's a bummer. It got good rapid results and was very exciting! But "indent the contents under an h4 deeper than under an h2" is just not a feature I can get there. And there are a few other weird cliffs to customizability (links can only be handled one way, except for a special case around fragment-only links? tables or other attempts to pack info densely are limited. etc) that are unfortunate. Getting isomorphic html output, if I wanted to include spacing and all, and have it rendered in html identically to how it would be in plain ANSI terminal text, is also looking pretty hard with Option 2. I think we'd end up literally storing the ANSI and all in testmark codeblocks, and then writing code in the site generator to re-render that into html. Possible, and well within the range of things I was considering doing anyway at the begining of this exploration, but... also maybe not totally ideal, considering how much control we _could_ have of this, by going with Option 3. Now, Option 3... well, the big question there is simply "how much work is that going to be?", and the answer is "I don't know". But the prototype of using goldmark directly with my own renderer went off pretty much without a hitch, and it seems like it reaches a very maximal level of control. And for reference, the size of goldmark's own html renderer is about 1000 lines of (very understandable) code. That's... about a 990 lines more than I'd _like_ to own, but on the other hand, if it's self contained and doesn't need much tweaking after the first pass, maybe it's acceptable. In exchange for that code, we'd get utterly total control of rendering, so we could fearlessly use all sorts of stuff (say, even codeblocks within text within headings that describe flags, and get all of it aligned correctly)... and it would become also totally in reach to write branches for emitting html color annotations vs ANSI, with full correctness as the action of both would be driven by the same AST walk. Jury's still out a bit. This checkpoint is just that: a checkpoint. Some of this code will disappear again, for certain. Which, exactly, is not yet certain.
- Loading branch information
Showing
5 changed files
with
178 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package doctests_cli | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"os" | ||
"testing" | ||
|
||
"github.com/charmbracelet/glamour" | ||
"github.com/yuin/goldmark" | ||
"github.com/yuin/goldmark/ast" | ||
"github.com/yuin/goldmark/extension" | ||
"github.com/yuin/goldmark/parser" | ||
"github.com/yuin/goldmark/renderer" | ||
"github.com/yuin/goldmark/util" | ||
|
||
wfapp "github.com/warptools/warpforge/app" | ||
) | ||
|
||
func TestRegenerate(t *testing.T) { | ||
wfapp.App.Description = "A longer, multi-line and multi-paragraph description may go here." | ||
//"> This is a blockquote\n> with multiple lines\n>> >> > > now indented\n> back again\n> ```\n> codeblocks??\n> ```\n" | ||
|
||
wfapp.App.Writer = os.Stdout | ||
wfapp.App.ErrWriter = os.Stderr | ||
_ = wfapp.App.Run([]string{"-h"}) | ||
|
||
fmt.Println("--------") | ||
|
||
// style := glamour.ASCIIStyleConfig // a lot of things seem ignored when using glamour.DarkStyleConfig ? namely codeblock prefix and suffix | ||
style := glamour.DarkStyleConfig | ||
stringPtr := func(s string) *string { return &s } | ||
uintPtr := func(u uint) *uint { return &u } | ||
style.Document.Margin = uintPtr(2) | ||
style.Paragraph.Margin = uintPtr(2) | ||
style.Code.Prefix = "`" | ||
style.Code.Suffix = "`" | ||
style.CodeBlock.Margin = uintPtr(6) | ||
style.CodeBlock.Prefix = "```\n" | ||
style.CodeBlock.Suffix = "```\n" | ||
//style.CodeBlock.Chroma = nil // Presence of chroma oversides codeblock prefix and suffix...? Seems like something I'd consider a bug? Report upstream? | ||
style.H4.BlockSuffix = " " | ||
style.H4.Margin = uintPtr(4) | ||
style.H4.Color = stringPtr("139") | ||
style.Table.CenterSeparator = stringPtr("x") | ||
|
||
//style = glamour.ASCIIStyleConfig | ||
|
||
r, _ := glamour.NewTermRenderer( | ||
//glamour.WithAutoStyle(), | ||
glamour.WithStyles(style), | ||
glamour.WithWordWrap(80), // this does things that are wrong? setting it to a large number produces insanity and many excessive lines. // ... okay maybe only for code blocks? // ... nope not even just code blocks. // OKAY NO, it's something weird to vscode's terminal. investigation aborting, not critical. | ||
) | ||
|
||
wfapp.App.Writer = r | ||
wfapp.App.ErrWriter = r | ||
_ = wfapp.App.Run([]string{"-h"}) | ||
|
||
r.Close() | ||
io.Copy(os.Stdout, r) | ||
|
||
fmt.Println("--------") | ||
|
||
md := goldmark.New( | ||
goldmark.WithExtensions(extension.GFM), | ||
goldmark.WithParserOptions( | ||
parser.WithAutoHeadingID(), | ||
), | ||
goldmark.WithRenderer(goldmarkRendererToANSI()), | ||
) | ||
var buf bytes.Buffer | ||
wfapp.App.Writer = &buf | ||
wfapp.App.ErrWriter = &buf | ||
_ = wfapp.App.Run([]string{"-h"}) | ||
if err := md.Convert(buf.Bytes(), os.Stdout); err != nil { | ||
panic(err) | ||
} | ||
|
||
} | ||
|
||
func goldmarkRendererToANSI() renderer.Renderer { | ||
return renderer.NewRenderer( | ||
renderer.WithNodeRenderers(util.PrioritizedValue{Value: &gmRenderer{}, Priority: 1}), | ||
) | ||
} | ||
|
||
type gmRenderer struct { | ||
} | ||
|
||
// RegisterFuncs is to meet `goldmark/renderer.NodeRenderer`, and goldmark calls it to get further configuration done. | ||
func (r *gmRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { | ||
reg.Register(ast.KindHeading, r.renderHeading) | ||
} | ||
|
||
// RegisterFuncs is to meet `goldmark/renderer.NodeRenderer`. We don't really use it. | ||
func (r *gmRenderer) AddOptions(...renderer.Option) {} | ||
|
||
func (r *gmRenderer) renderHeading(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { | ||
n := node.(*ast.Heading) | ||
if entering { | ||
_, _ = w.WriteString("<h") | ||
_ = w.WriteByte("0123456"[n.Level]) | ||
_ = w.WriteByte('>') | ||
} else { | ||
_, _ = w.WriteString("</h") | ||
_ = w.WriteByte("0123456"[n.Level]) | ||
_, _ = w.WriteString(">\n") | ||
} | ||
return ast.WalkContinue, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters