highlight: support highlighting lines in the default writer

The hl_lines key is specifically the same as Hugo's key.
This commit is contained in:
Kisaragi Hiu 2022-07-18 03:56:15 +09:00
parent 9b56fc914c
commit ab8d3bc16a
No known key found for this signature in database
GPG key ID: 40ECBEAEA8775FC2
6 changed files with 97 additions and 2 deletions

View file

@ -63,7 +63,14 @@ func highlightCodeBlock(source, lang string, inline bool, params map[string]stri
}
l = chroma.Coalesce(l)
it, _ := l.Tokenise(nil, source)
_ = html.New().Format(&w, styles.Get("github"), it)
options := []html.Option{}
if params[":hl_lines"] != "" {
ranges := org.ParseRanges(params[":hl_lines"])
if ranges != nil {
options = append(options, html.HighlightLines(ranges))
}
}
_ = html.New(options...).Format(&w, styles.Get("github"), it)
if inline {
return `<div class="highlight-inline">` + "\n" + w.String() + "\n" + `</div>`
}

View file

@ -127,7 +127,14 @@ func highlightCodeBlock(source, lang string, inline bool, params map[string]stri
}
l = chroma.Coalesce(l)
it, _ := l.Tokenise(nil, source)
_ = html.New().Format(&w, styles.Get("friendly"), it)
options := []html.Option{}
if params[":hl_lines"] != "" {
ranges := org.ParseRanges(params[":hl_lines"])
if ranges != nil {
options = append(options, html.HighlightLines(ranges))
}
}
_ = html.New(options...).Format(&w, styles.Get("friendly"), it)
if inline {
return `<div class="highlight-inline">` + "\n" + w.String() + "\n" + `</div>`
}

12
org/testdata/hl-lines.html vendored Normal file
View file

@ -0,0 +1,12 @@
<p>Lines in a source block can be highlighted with <code class="verbatim">:hl_lines</code>.</p>
<div class="src src-emacs-lisp">
<div class="highlight">
<pre>
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
</pre>
</div>
</div>

9
org/testdata/hl-lines.org vendored Normal file
View file

@ -0,0 +1,9 @@
Lines in a source block can be highlighted with =:hl_lines=.
#+begin_src emacs-lisp :hl_lines 3-4
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
#+end_src

9
org/testdata/hl-lines.pretty_org vendored Normal file
View file

@ -0,0 +1,9 @@
Lines in a source block can be highlighted with =:hl_lines=.
#+BEGIN_SRC emacs-lisp :hl_lines 3-4
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
(+ 1 2)
#+END_SRC

View file

@ -1,5 +1,10 @@
package org
import (
"strconv"
"strings"
)
func isSecondBlankLine(d *Document, i int) bool {
if i-1 <= 0 {
return false
@ -17,3 +22,49 @@ func isImageOrVideoLink(n Node) bool {
}
return false
}
// Parse ranges like this:
// "3-5" -> [[3, 5]]
// "3 8-10" -> [[3, 3], [8, 10]]
// "3 5 6" -> [[3, 3], [5, 5], [6, 6]]
//
// This is Hugo's hlLinesToRanges with "startLine" removed and errors
// ignored.
func ParseRanges(s string) [][2]int {
var ranges [][2]int
s = strings.TrimSpace(s)
if s == "" {
return ranges
}
fields := strings.Split(s, " ")
for _, field := range fields {
field = strings.TrimSpace(field)
if field == "" {
continue
}
numbers := strings.Split(field, "-")
var r [2]int
if len(numbers) > 1 {
first, err := strconv.Atoi(numbers[0])
if err != nil {
return ranges
}
second, err := strconv.Atoi(numbers[1])
if err != nil {
return ranges
}
r[0] = first
r[1] = second
} else {
first, err := strconv.Atoi(numbers[0])
if err != nil {
return ranges
}
r[0] = first
r[1] = first
}
ranges = append(ranges, r)
}
return ranges
}