charmbracelet / glamour

Stylesheet-based markdown rendering for your CLI apps 💇🏻‍♀️
MIT License
2.49k stars 183 forks source link

Reference-style links above document add line break #304

Open cactysman opened 5 months ago

cactysman commented 5 months ago

Reference-style links placed on top of the document add a leading line break to the document.

Setup

To Reproduce

  1. Run attached source code
  2. Look at output

Source Code

package main

import "github.com/charmbracelet/glamour"
import "fmt"

var md = "# Hello World\n\nThis is a [link][url]."

var linkAbove = "[url]: https://example.com\n" + md
var linkBelow = md + "\n\n[url]: https://example.com\n"

func main() {
    print("no link", md)
    print("link below", linkBelow)
    print("link above", linkAbove)
}

func print(title string, in string) {
    out, _ := glamour.Render(in, "dark")
    fmt.Print(title + ": <start>" + out + "<end>\n\n")
}

Expected behavior The actual output of the markdown document should probably be trimmed, or at least not include that extra line break on top.

Screenshots image

cactysman commented 5 months ago

I also confirmed that it's not goldmark's fault with the following code (using a simple goldmark setup that should probably suffice) producing identical results no matter where the refs are placed.

package main

import (
    "bytes"
    "fmt"
    "github.com/yuin/goldmark"
    "github.com/yuin/goldmark/extension"
    "github.com/yuin/goldmark/parser"
)

func main() {
    md := goldmark.New(
        goldmark.WithExtensions(
            extension.GFM,
            extension.DefinitionList,
        ),
        goldmark.WithParserOptions(
            parser.WithAutoHeadingID(),
        ),
    )

    var bufA bytes.Buffer
    var bufB bytes.Buffer
    sourceA := []byte("[a]: https://example.com\n\n# hi\n\n[link][a]")
    sourceB := []byte("# hi\n\n[link][a]\n\n[a]: https://example.com")

    if err := md.Convert(sourceA, &bufA); err != nil {
        panic(err)
    }
    fmt.Println("START1" + bufA.String() + "END1\n")

    if err := md.Convert(sourceB, &bufB); err != nil {
        panic(err)
    }
    fmt.Println("START2" + bufB.String() + "END2")
}
START1<h1 id="hi">hi</h1>
<p><a href="https://example.com">link</a></p>
END1

START2<h1 id="hi">hi</h1>
<p><a href="https://example.com">link</a></p>
END2