diff --git a/blorg/util.go b/blorg/util.go
index e24ea9a..ef588db 100644
--- a/blorg/util.go
+++ b/blorg/util.go
@@ -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 `
` + "\n" + w.String() + "\n" + `
`
}
diff --git a/main.go b/main.go
index c400d56..62a22f3 100644
--- a/main.go
+++ b/main.go
@@ -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 `` + "\n" + w.String() + "\n" + `
`
}
diff --git a/org/testdata/hl-lines.html b/org/testdata/hl-lines.html
new file mode 100644
index 0000000..c458903
--- /dev/null
+++ b/org/testdata/hl-lines.html
@@ -0,0 +1,12 @@
+Lines in a source block can be highlighted with :hl_lines
.
+
+
+
+(+ 1 2)
+(+ 1 2)
+(+ 1 2)
+(+ 1 2)
+(+ 1 2)
+
+
+
diff --git a/org/testdata/hl-lines.org b/org/testdata/hl-lines.org
new file mode 100644
index 0000000..17851b8
--- /dev/null
+++ b/org/testdata/hl-lines.org
@@ -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
diff --git a/org/testdata/hl-lines.pretty_org b/org/testdata/hl-lines.pretty_org
new file mode 100644
index 0000000..5d7ba70
--- /dev/null
+++ b/org/testdata/hl-lines.pretty_org
@@ -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
diff --git a/org/util.go b/org/util.go
index c25bf27..b83b6f4 100644
--- a/org/util.go
+++ b/org/util.go
@@ -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
+}