Code Monkey home page Code Monkey logo

goldmark-highlighting's Introduction

goldmark-highlighting

goldmark-highlighting is an extension for the goldmark that adds syntax-highlighting to the fenced code blocks.

goldmark-highlighting uses chroma as a syntax highlighter.

Installation

go get github.com/yuin/goldmark-highlighting/v2

Usage

package main

import (
	"bytes"
	"fmt"

	"github.com/yuin/goldmark"

	chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
	highlighting "github.com/yuin/goldmark-highlighting/v2"
)

func main() {
	mdsrc := `
		Title
		=======
		` + "```" + `
		func main() {
		    fmt.Println("ok")
		}
		` + "```" + `
	`

	// Simple usage
	markdown := goldmark.New(
		goldmark.WithExtensions(
			highlighting.Highlighting,
		),
	)
	var buf bytes.Buffer
	if err := markdown.Convert([]byte(mdsrc), &buf); err != nil {
		panic(err)
	}
	title := buf.String()
	fmt.Print(title)

	// Custom configuration
	markdown2 := goldmark.New(
		goldmark.WithExtensions(
			highlighting.NewHighlighting(
				highlighting.WithStyle("monokai"),
				highlighting.WithFormatOptions(
					chromahtml.WithLineNumbers(true),
				),
			),
		),
	)
	var buf2 bytes.Buffer
	if err := markdown2.Convert([]byte(mdsrc), &buf2); err != nil {
		panic(err)
	}
	title2 := buf2.String()
	fmt.Print(title2)
}

License

MIT

Author

Yusuke Inuzuka

goldmark-highlighting's People

Contributors

bep avatar jolheiser avatar litao-byted avatar satotake avatar stephenafamo avatar wkoszek avatar yuin avatar zeripath avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

goldmark-highlighting's Issues

[feature request] Support for linkable line numbers as supported by Chroma

Hello,

Can you please enable the support of LinkableLineNumbers() as supported by Chroma?

https://github.com/alecthomas/chroma#the-html-formatter

Hugo supported enabling the generation of linkable line numbers by passing the anchorlinenos=true attribute to the Hugo highlight shortcode. That shortcode internally uses the same Chroma library to do the code syntax highlighting.

Right now, the highlight shortcode inherits this anchorlinenos=true feature from Chroma. But if I try to use code fences with that attribute, I do not get anchorized line numbers because this library doesn't support that.

Thanks!


References

Tests fail with chroma 0.7.1

Hugo currently has chroma at 0.7.1 in its go.mod, but this repo has 0.7.0. If you get 0.7.1, then tests will fail here:

--- FAIL: TestHighlighting (0.00s)
    highlighting_test.go:136: failed to render CSS

Seems to do with alecthomas/chroma#317 changing the comments in the CSS slightly.

Add linenostart

As a way to start line numbers at something other than 1; useful for code samples from real world programs.

Proposal - Allow mixed case attribute names

Currently, this does not do anything:

```text {LineNos=true LineNoStart=42}
foo
```

You must do this instead:

```text {linenos=true linenostart=42}
foo
```

Users are accustomed to case-insensitive HTML attribute names. I understand this is markdown, not HTML, but there is a similar expectation from non-developer users.

Allow a custom HTML wrapper

Note that I'm not saying that the current behavior is wrong, but coming from experience, I know that many people will shout if I introduce changes in Hugo that breaks their layout/CSS structure too much.

Looking at Hugo's output below I admit it looks a little bit odd, so fixing that would be a bonus. But what I suggest is to

  • add an option to add a wrapper around Chroma's output (e.g. <div class="highlight">CHROMA OUTPUT</div>), which would make most Hugo sites look good without any changes.
  • it would be good if that option could get the lang value.
package main

import (
	"bytes"
	"fmt"
	"log"
	"strings"

	"github.com/alecthomas/chroma/formatters/html"
	highlighting "github.com/yuin/goldmark-highlighting"

	"github.com/yuin/goldmark"
)

func main() {
	content := `

$$$go
fmt.Println("Hello")
$$$

$$$moo
Moo
$$$
`
	content = strings.Replace(content, "$$$", "```", -1)

	markdown := goldmark.New(
		goldmark.WithExtensions(
			highlighting.NewHighlighting(
				highlighting.WithStyle("monokai"),
				highlighting.WithFormatOptions(
					html.WithClasses(),
				),
			),
		),
	)

	var buf bytes.Buffer
	err := markdown.Convert([]byte(content), &buf)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(buf.String())
}

The above prints:

<pre class="chroma"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello&#34;</span><span class="p">)</span>
</pre>
<pre><code class="language-moo">Moo
</code></pre>

A similar block in Hugo would today look like this:

<div class="highlight"><pre class="chroma"><code class="language-go hljs" data-lang="go"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">)</span></code></pre></div>

<div class="highlight"><pre class="chroma"><code class="language-moo" data-lang="moo">Moo</code></pre></div>

Fuzz crash on ```0{class=0#.

Please answer the following before submitting your issue:

  1. What version of goldmark are you using? : v1.3.5
  2. What version of Go are you using? : go1.16
  3. What operating system and processor architecture are you using? : linux/amd64
  4. What did you do? : ran go-fuzz on my own project that uses the goldmark parser
  5. What did you expect to see? : no crashes by goldmark
  6. What did you see instead? :
panic: interface conversion: interface {} is float64, not []uint8

goroutine 1 [running]:
github.com/yuin/goldmark/parser.ParseAttributes.func1(0x7bede0, 0xdcfe00, 0x5, 0x5af701)
        ./.go/pkg/mod/github.com/yuin/[email protected]/parser/attribute.go:68 +0x2bf
github.com/yuin/goldmark/parser.Attributes.findUpdate(0xc00062d130, 0x2, 0x2, 0xdc2074, 0x5, 0x5, 0xc00047f8b0, 0x1)
        ./.go/pkg/mod/github.com/yuin/[email protected]/parser/attribute.go:37 +0xb7
github.com/yuin/goldmark/parser.ParseAttributes(0xc14930, 0xc00060a310, 0xc0bb64, 0x0, 0x412e82, 0xc00047f998)
        ./.go/pkg/mod/github.com/yuin/[email protected]/parser/attribute.go:67 +0x449
github.com/yuin/goldmark-highlighting.getAttributes(0xc000692000, 0xc0005876d3, 0xb, 0xd, 0xc0005876d3, 0xb)
        ./.go/pkg/mod/github.com/yuin/[email protected]/highlighting.go:368 +0x148
github.com/yuin/goldmark-highlighting.(*HTMLRenderer).renderFencedCodeBlock(0xc00060a1c0, 0xc14188, 0xc00059d880, 0xc0005876d0, 0xe, 0x10, 0xc1bf80, 0xc000692000, 0x1, 0xdc98e0, ...)
        ./.go/pkg/mod/github.com/yuin/[email protected]/highlighting.go:395 +0x1b7
github.com/yuin/goldmark/renderer.(*renderer).Render.func2(0xc1bf80, 0xc000692000, 0x1, 0x0, 0xc14188, 0xc00059d880)
        ./.go/pkg/mod/github.com/yuin/[email protected]/renderer/renderer.go:166 +0x108
github.com/yuin/goldmark/ast.walkHelper(0xc1bf80, 0xc000692000, 0xc00047fe48, 0x3, 0x0, 0x0)
        ./.go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:492 +0x43
github.com/yuin/goldmark/ast.walkHelper(0xc1bd40, 0xc0005a18c0, 0xc00047fe48, 0xc000681000, 0x0, 0xc000587600)
        ./.go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:498 +0x16b
github.com/yuin/goldmark/ast.Walk(...)
        ./.go/pkg/mod/github.com/yuin/[email protected]/ast/ast.go:487
github.com/yuin/goldmark/renderer.(*renderer).Render(0xc00062d0e0, 0xc12068, 0xc000638f30, 0xc0005876d0, 0xe, 0x10, 0xc1bd40, 0xc0005a18c0, 0x10, 0xe)
        ./.go/pkg/mod/github.com/yuin/[email protected]/renderer/renderer.go:161 +0x13c
github.com/yuin/goldmark.(*markdown).Convert(0xc00059d500, 0xc0005876d0, 0xe, 0x10, 0xc12068, 0xc000638f30, 0x0, 0x0, 0x0, 0x406185, ...)
        ./.go/pkg/mod/github.com/yuin/[email protected]/markdown.go:117 +0x12c
main.main()
        ./goldmark_crash.go:21 +0xcb
exit status 2
package main

import (
        "bytes"
        "fmt"

        "github.com/yuin/goldmark" // Version v1.3.5
        highlighting "github.com/yuin/goldmark-highlighting" // Version v0.0.0-20210428103930-3a9678dbb86c
)

var gm = goldmark.New(
        goldmark.WithExtensions(
                highlighting.NewHighlighting(),
        ),
)

// This input will crash the parser
var input string = "```0{class=0#."

func main() {
        var buf bytes.Buffer
        err := gm.Convert([]byte(input), &buf)
        fmt.Println("Error:", err)
}

Copy from yuin/goldmark#219

Use fallback lexer when no language is specified

(Initially posted in gohugoio/hugo#8913)

Currently, when using code fences without language specified (and GuessLanguage is disabled), no CSS class or style is added to pre/code. I think it would be more useful to use the fallback lexer instead -- like it happens when GuessLanguage is used and the language isn't identified -- as it would use a consistent fore/background color without special CSS handling by the user.

Concurrent use of goldmark-highlighting ?

Apparently, according to this goldmark issue, the goldmark instance created with New can be used concurrently with multiple go routines rendering different Mardown text.

I may have misunderstood it's usage, but it seam that this property is not preserved by the use of WithCSSWriter as the same writer is shared by different concurrent Rendering operations.

It's correct or intended usage may need a clarification.

If we want to inline the css as a style in the head of the web page, we would need to support concurrent css writing. To do that it seam the the CSS writer should be passed as a context variable.

Will this option ensure that the css is written only once ?

Panic when linenostart is a string

markdown

~~~text {linenostart="1"}
foo
~~~
code
package main

import (
	"bytes"
	"fmt"

	"github.com/yuin/goldmark"
	highlighting "github.com/yuin/goldmark-highlighting"
)

func main() {
	md := goldmark.New(
		goldmark.WithExtensions(
			highlighting.Highlighting,
		),
	)

	input := `
~~~text {linenostart="1"}
foo
~~~
`

	var buf bytes.Buffer
	if err := md.Convert([]byte(input), &buf); err != nil {
		panic(err)
	}

	fmt.Println(buf.String())

}

Some adjustments

Note that I would be happy to do the work below, if you agree that this is OK

  • Assuming alecthomas/chroma#300 gets merged, I suggest we add a callback ala WithCodeBlockOptions func(CodeBlockContext)[]chromahtml.Option
  • To allow for toggling table/inline line numbers and to make the API compatible with Pygments, I suggest making linenos optionally be a string, ref:
linenos
If set to 'table', output line numbers as a table with two cells, one containing the line numbers, the other the whole code. This is copy-and-paste-friendly, but may cause alignment problems with some browsers or fonts. If set to 'inline', the line numbers will be integrated in the <pre> tag that contains the code (that setting is new in Pygments 0.8).
For compatibility with Pygments 0.7 and earlier, every true value except 'inline' means the same as 'table' (in particular, that means also True).

The default value is False, which means no line numbers at all.
  • E.g linenos=true, linenos=table, linenos=inline, linenos=false

  • And finally WithLineNumbersInTable, WithLineNumbers options, which would allow for default values for the above.

IRC text log support

Hi! I was wondering if you would consider IRC text log syntaxic coloration to be something in the scope for this library?

The only issue I find that would make its implementation tedious is the fact that there is no "keyword classes", so the color classes should be attributed based on the nickname's content.

Example, the following chatlog would have three different colors for the three different nicknames (having multiple different nicknames with the same color is okay, to me).

<Arte> This is a test -- Color 1
<Stux> Another test -- Color 2
<Test> A third message -- Color 3 (or any other color, if conflict)

The colors could be computed with a trivial hash algorithm.

Panic on simple but broken commonmark

goldmark has https://github.com/yuin/goldmark/discussions in github.
You should post only issues here. Feature requests and questions should be posted at discussions.

  • goldmark is fully compliant with the CommonMark. Before submitting issue, you must read CommonMark spec and confirm your output is different from CommonMark online demo.
    • Extensions(Autolink without < >, Table, etc) are not part of CommonMark spec. You should confirm your output is different from other official renderers correspond with an extension.
  • goldmark is not dedicated for Hugo. If you are Hugo user and your issue was raised by your experience in Hugo, you should consider create issue at Hugo repository at first .

Please answer the following before submitting your issue:

  1. What version of goldmark are you using? : v1.3.2
  2. What version of Go are you using? : 16.1
  3. What operating system and processor architecture are you using? : linux amd64
  4. What did you do? : passed the following through goldmakr
a
:	```
		a
  1. What did you expect to see? : not a panic
  2. What did you see instead? :
runtime error: slice bounds out of range [14:13]
	/usr/local/go/src/runtime/panic.go:116 (0x43de84)
		goPanicSliceB: panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/text/segment.go:48 (0xf0ecf2)
		(*Segment).Value: return append(result, buffer[t.Start:t.Stop]...)
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark-highlighting/highlighting.go:516 (0x119ce6e)
		(*HTMLRenderer).renderFencedCodeBlock: r.Writer.RawWrite(w, line.Value(source))
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/renderer/renderer.go:166 (0xf34c47)
		(*renderer).Render.func2: s, err = f(writer, source, n, entering)
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/ast/ast.go:492 (0xf11c62)
		walkHelper: status, err := walker(n, true)
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/ast/ast.go:498 (0xf11d7b)
		walkHelper: if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/ast/ast.go:498 (0xf11d7b)
		walkHelper: if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/ast/ast.go:498 (0xf11d7b)
		walkHelper: if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/ast/ast.go:487 (0xf345fb)
		Walk: _, err := walkHelper(n, walker)
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/renderer/renderer.go:161 (0xf3455c)
		(*renderer).Render: err := ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
	/home/andrew/src/go/gitea/vendor/github.com/yuin/goldmark/markdown.go:117 (0xf3d024)
  1. Did you confirm your output is different from CommonMark online demo or other official renderer correspond with an extension?: yes

line highlighting in codefences

    ```js {highlight:[1,'5-7',8]}
    export function solution(str) {
        let i = 0;
        let count = 0;
        while(i<str.length){
            if(str.charAt(i)=='-'){
                i++;
                continue;
            }
            if(i!=str.length-1 && str.charAt(i+1)=='-'){
                i+=3;
            }else if(i!=0 && str.charAt(i-1)=='-'){
                i+=1;
            }else{
                return -1;
            }
            count++;
        }
        return count;
    }
    ```

Is it possible to support this. I saw chroma has HighlightLines

Add a way to toggle line numbers

A request I heard a lot, and I agree that it would be useful, is a way to toggle line numbers. This is typically used in combination with hl_lines; you may want it to default set to off, but want to show them in code samples when you highlight ranges.

Proposal - Improve attribute parsing

Users are accustomed to quoting HTML attributes, regardless of type, because many have no concept of type. And the browser doesn't care. I understand this is markdown, not HTML, but there is a similar expectation from non-developer users.

With this module, quoting or not quoting an attribute makes a big difference.

Example Notes
{linenostart="1"} Panic (see #27)
{linenos="false"} Effectively setting it to true
{hl_lines="[2]"} Ignored

Highlighting extension not preserving whitespace in <pre> tag

I am using gold mark highlighting extension in my go code like this.

highlighting.NewHighlighting(
    highlighting.WithStyle("monokai"),
),

and i define code in markdown this way

```json
{
  "site_title":"test",
  "email":"[email protected]",
  "twitter_username":"@test",
  "github_username":"test",
  "minify_css": true,
  "minify_html": true,
  "list": [
    "1",
    "2",
    "3"
  ],
  "map": {
    "a": 1,
    "b": 2
  }
}
```

After the rendering my formatted code block does not take whitespace or newlines into account and displays HTML like this.
Screenshot 2021-07-08 at 6 30 34 PM

Not sure, if this is a bug or I am missing some config option!

My full gold mark instantiation looks like this.

md := goldmark.New(
		goldmark.WithExtensions(meta.Meta,
			highlighting.NewHighlighting(
				highlighting.WithStyle("monokai"),
			),
			extension.Footnote,
			extension.GFM,
			emoji.Emoji,
			mathjax.MathJax,
		),
		goldmark.WithRendererOptions(
			html.WithHardWraps(),
		),
		goldmark.WithParserOptions(
			parser.WithBlockParsers(),
			parser.WithAttribute(),
		),
	)

[Feature request] Use `class` instead `style`

Why should we use class, not hard code style:

  • Dark themes are more popular now, people doesn't only like light theme. class can ensure people are using their perfect theme.
  • Free Configuration. We can customize many fun themes in our css file either.
  • Security. Style is more easier to get XSS attack, so things like bluemonday will clear the style and none highlighted codes will be send to the client

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.