Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/bug(renderer): Support chroma, fix source paragraph #720

Merged
merged 1 commit into from
Jul 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions LIMITATIONS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ See https://github.com/bytesparadise/libasciidoc/issues/679[Issue #679].
The `favicon` document attribute is not recognized.
See https://github.com/bytesparadise/libasciidoc/issues/681[Issue #681].

== Syntax Highlighters
== Syntax Highlighting

Only the `pygments` highlighter is recognized.
Libasciidoc highlights source code using https://github.com/alecthomas/chroma[Chroma].
To use it, specify `chroma` for the `source-highlighter` attribute. The value of `pygments`
is treated as an alias. Chroma supports all the standard pygments styles, as well as the vast
majority of the same source code languages. However some more esoteric languages might not be supported.
See https://github.com/alecthomas/chroma#supported-languages[Chroma's documentation] for details.

== Math

Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Although it does not support the full Asciidoc/Asciidoctor syntax, Libasciidoc a
* Attribute declaration and substitution
* Paragraphs and admonition paragraphs
* Delimited Blocks (fenced blocks, listing blocks, example blocks, comment blocks, quoted blocks, sidebar blocks, verse blocks)
* Source code highlighting of delimited blocks
* Source code highlighting of delimited blocks (use either `chroma` or `pygments` as the `source-highlighter`)
* Literal blocks (paragraph starting with a space, with the `+++....+++` delimiter or with the `[literal]` attribute)
* Quoted text (bold, italic, monospace, marked, superscript and subscript) and substitution prevention using the backslash (`\`) character
* Single and double quoted typographic quotes (e.g. '`single`' and "`double`")
Expand Down
10 changes: 7 additions & 3 deletions pkg/renderer/sgml/delimited_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,17 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite

highlighter, _ := ctx.Attributes.GetAsString(types.AttrSyntaxHighlighter)
language, found := b.Attributes.GetAsString(types.AttrLanguage)
if found && highlighter == "pygments" {
if found && (highlighter == "chroma" || highlighter == "pygments") {
// using github.com/alecthomas/chroma to highlight the content
contentBuf := &strings.Builder{}
lexer := lexers.Get(language)
if lexer == nil {
lexer = lexers.Fallback
}
lexer = chroma.Coalesce(lexer)
style := styles.Fallback
if s, found := ctx.Attributes.GetAsString("pygments-style"); found {

if s, found := ctx.Attributes.GetAsString(highlighter + "-style"); found {
style = styles.Get(s)
}
iterator, err := lexer.Tokenise(nil, content)
Expand All @@ -145,7 +149,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite
html.PreventSurroundingPre(true),
}
// extra option: inline CSS instead of classes
if ctx.Attributes.GetAsStringWithDefault("pygments-css", "classes") == "style" {
if ctx.Attributes.GetAsStringWithDefault(highlighter+"-css", "classes") == "style" {
options = append(options, html.WithClasses(false))
} else {
options = append(options, html.WithClasses(true))
Expand Down
16 changes: 16 additions & 0 deletions pkg/renderer/sgml/html5/delimited_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,22 @@ end</code></pre>
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("with title, source and unknown languages attributes", func() {
source := `[source,brainfart]
.Source block title
----
int main(int argc, char **argv);
----`
expected := `<div class="listingblock">
<div class="title">Source block title</div>
<div class="content">
<pre class="highlight"><code class="language-brainfart" data-lang="brainfart">int main(int argc, char **argv);</code></pre>
</div>
</div>
`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("with id, title, source and languages attributes", func() {
source := `[#id-for-source-block]
[source,ruby]
Expand Down
9 changes: 0 additions & 9 deletions pkg/renderer/sgml/html5/paragraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ const (

delimitedBlockParagraphTmpl = "<p>{{ .CheckStyle }}{{ .Content }}</p>\n"

sourceParagraphTmpl = "<div class=\"listingblock\">\n" +
"<div class=\"content\">\n" +
"<pre class=\"highlight\">" +
`<code{{ if .Language }} class="language-{{ .Language }}" data-lang="{{ .Language }}"{{ end }}>` +
"{{ .Content }}" +
"</code></pre>\n" +
"</div>\n" +
"</div>\n"

verseParagraphTmpl = "<div {{ if .ID }}id=\"{{ .ID }}\" {{ end }}class=\"verseblock\">\n" +
"{{ if .Title }}<div class=\"title\">{{ .Title }}</div>\n{{ end }}" +
"<pre class=\"content\">{{ .Content }}</pre>\n" +
Expand Down
17 changes: 17 additions & 0 deletions pkg/renderer/sgml/html5/paragraph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,21 @@ image::foo.png[]`
})
})

Context("source paragraphs", func() {

It("with source and languages attributes", func() {
source := `:source-highlighter: chroma

[source,c]
int main(int argc, char **argv);
`
expected := `<div class="listingblock">
<div class="content">
<pre class="chroma highlight"><code data-lang="c"><span class="tok-kt">int</span> <span class="tok-nf">main</span><span class="tok-p">(</span><span class="tok-kt">int</span> <span class="tok-n">argc</span><span class="tok-p">,</span> <span class="tok-kt">char</span> <span class="tok-o">**</span><span class="tok-n">argv</span><span class="tok-p">);</span></code></pre>
</div>
</div>
`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})
})
})
1 change: 0 additions & 1 deletion pkg/renderer/sgml/html5/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ var templates = sgml.Templates{
SectionHeader: sectionHeaderTmpl,
SidebarBlock: sidebarBlockTmpl,
SourceBlock: sourceBlockTmpl,
SourceParagraph: sourceParagraphTmpl,
StringElement: stringTmpl,
SubscriptText: subscriptTextTmpl,
SuperscriptText: superscriptTextTmpl,
Expand Down
27 changes: 4 additions & 23 deletions pkg/renderer/sgml/paragraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,11 @@ func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p types.
}

func (r *sgmlRenderer) renderSourceParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) {
log.Debug("rendering source paragraph...")
result := &strings.Builder{}

content, err := r.renderLines(ctx, p.Lines)
if err != nil {
return "", errors.Wrap(err, "unable to render source paragraph lines")
}
err = r.sourceParagraph.Execute(result, struct {
Context *renderer.Context
ID sanitized
Title sanitized
Language string
Content sanitized
Lines []interface{}
}{

Context: ctx,
ID: r.renderElementID(p.Attributes),
Title: r.renderElementTitle(p.Attributes),
Language: p.Attributes.GetAsStringWithDefault(types.AttrLanguage, ""),
Content: sanitized(content),
Lines: p.Lines,
return r.renderSourceBlock(ctx, types.DelimitedBlock{
Kind: types.Source,
Attributes: p.Attributes,
Elements: p.Lines,
})
return result.String(), err
}

func (r *sgmlRenderer) renderVerseParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) {
Expand Down
2 changes: 0 additions & 2 deletions pkg/renderer/sgml/sgml_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ type sgmlRenderer struct {
sectionHeader *textTemplate
sidebarBlock *textTemplate
sourceBlock *textTemplate
sourceParagraph *textTemplate
stringElement *textTemplate
subscriptText *textTemplate
superscriptText *textTemplate
Expand Down Expand Up @@ -144,7 +143,6 @@ func (r *sgmlRenderer) prepareTemplates() error {
r.stringElement, err = r.newTemplate("string-element", tmpls.StringElement, err)
r.sidebarBlock, err = r.newTemplate("sidebar-block", tmpls.SidebarBlock, err)
r.sourceBlock, err = r.newTemplate("source-block", tmpls.SourceBlock, err)
r.sourceParagraph, err = r.newTemplate("source-paragraph", tmpls.SourceParagraph, err)
r.subscriptText, err = r.newTemplate("subscript", tmpls.SubscriptText, err)
r.superscriptText, err = r.newTemplate("superscript", tmpls.SuperscriptText, err)
r.table, err = r.newTemplate("table", tmpls.Table, err)
Expand Down
1 change: 0 additions & 1 deletion pkg/renderer/sgml/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ type Templates struct {
SectionHeader string
SidebarBlock string
SourceBlock string
SourceParagraph string
StringElement string
SubscriptText string
SuperscriptText string
Expand Down
16 changes: 16 additions & 0 deletions pkg/renderer/sgml/xhtml5/delimited_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,22 @@ end</code></pre>
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})

It("with title, source and unknown languages attributes", func() {
source := `[source,brainfart]
.Source block title
----
int main(int argc, char **argv);
----`
expected := `<div class="listingblock">
<div class="title">Source block title</div>
<div class="content">
<pre class="highlight"><code class="language-brainfart" data-lang="brainfart">int main(int argc, char **argv);</code></pre>
</div>
</div>
`
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})

It("with html content", func() {
source := `[source]
----
Expand Down
18 changes: 18 additions & 0 deletions pkg/renderer/sgml/xhtml5/paragraph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,24 @@ image::foo.png[]`
<img src="foo.png" alt="quote" width="john doe" height="quote title"/>
</div>
</div>
`
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})
})

Context("source paragraphs", func() {

It("with source and languages attributes", func() {
source := `:source-highlighter: chroma

[source,c]
int main(int argc, char **argv);
`
expected := `<div class="listingblock">
<div class="content">
<pre class="chroma highlight"><code data-lang="c"><span class="tok-kt">int</span> <span class="tok-nf">main</span><span class="tok-p">(</span><span class="tok-kt">int</span> <span class="tok-n">argc</span><span class="tok-p">,</span> <span class="tok-kt">char</span> <span class="tok-o">**</span><span class="tok-n">argv</span><span class="tok-p">);</span></code></pre>
</div>
</div>
`
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})
Expand Down