Skip to content

Commit

Permalink
Support ":linenos <val>" for src and example blocks
Browse files Browse the repository at this point in the history
Fixes #326 and
#489.
  • Loading branch information
kaushalmodi committed Dec 31, 2021
1 parent cd313dc commit 9408d8c
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 24 deletions.
32 changes: 31 additions & 1 deletion doc/ox-hugo-manual.org
Expand Up @@ -1339,7 +1339,9 @@ fences (even with this property at a non-nil value) if:
- Line numbers are enabled using the Org =-n= / =+n= syntax (see
below), or
- Line highlighting is enabled using the =:hl_lines= parameter in the
source block header (see below).
source block header (see below), or
- =:linenos= parameter is specified in the source block header (see
below).

Set the =HUGO_CODE_FENCE= property to =nil= if you want to *always*
use the Hugo =highlight= shortcode.
Expand Down Expand Up @@ -1382,6 +1384,34 @@ The Org source for the below is similar to the above, except that the
=-n= switch is also added to enable the line numbers.

#+include: "../test/site/content-org/all-posts.org::#source-blocks-with-highlighting-with-linenums-not-starting-from-1" :only-contents t
**** Line number Style (*linenos*)
When line numbers are enabled, by default the "table" style is used
for line numbers. This is specified using the [[https://gohugo.io/content-management/syntax-highlighting/#highlight-shortcode][=linenos= argument to
the =highlight= shortcode]].

This default can be overridden using the =:linenos= parameter in the
source block header.

*Example usage*: If a user has enabled the line numbers by default by
using something like this in the site's =config.toml=:

#+begin_src toml
[markup]
[markup.highlight]
lineNos = true
#+end_src

, they can disable printing of line numbers for selected source blocks
by adding =:linenos false= to their headers.

#+begin_src org
,#+begin_src emacs-lisp :linenos false
(message "hello")
(message "bye")
,#+end_src
#+end_src

/The same =:linenos= header arg works for example blocks too./
*** Equations
:PROPERTIES:
:EXPORT_FILE_NAME: equations
Expand Down
60 changes: 37 additions & 23 deletions ox-hugo.el
Expand Up @@ -943,14 +943,14 @@ ORIG-FUN is the original function `org-babel-exp-code' that this
function is designed to advice using `:around'. ARGS are the
arguments of the ORIG-FUN.
This advice retains the `:hl_lines' and `:front_matter_extra'
parameters, if added to any source block. This parameter is used
in `org-hugo-src-block'.
This advice retains the `:hl_lines', `linenos' and
`:front_matter_extra' parameters, if added to any source block.
This parameter is used in `org-hugo-src-block'.
This advice is added to the ORIG-FUN only while an ox-hugo export
is in progress. See `org-hugo--before-export-function' and
`org-hugo--after-export-function'."
(let* ((param-keys-to-be-retained '(:hl_lines :front_matter_extra))
(let* ((param-keys-to-be-retained '(:hl_lines :linenos :front_matter_extra))
(info (car args))
(parameters (nth 2 info))
(ox-hugo-params-str (let ((str ""))
Expand Down Expand Up @@ -1747,21 +1747,29 @@ created.
CONTENTS is nil. INFO is a plist holding contextual
information."
(let (;; See `org-element-example-block-parser' for all EXAMPLE-BLOCK properties.
(number-lines (org-element-property :number-lines example-block)) ;Non-nil if -n or +n switch is used
ret)
(if number-lines
(let* ((text (org-export-format-code-default example-block info))
(linenostart-str (progn
;; Extract the start line number of the example block.
(let* (;; See `org-element-example-block-parser' for all EXAMPLE-BLOCK properties.
(number-lines (org-element-property :number-lines example-block)) ;Non-nil if -n or +n switch is used
(switches-str (org-element-property :switches example-block))
(linenos-style (and (org-string-nw-p switches-str)
(string-match ":linenos\\s-+\\([^ ]+\\)\\b" switches-str)
(match-string-no-properties 1 switches-str)))
linenos-str
ret)
(if (or number-lines linenos-style)
(let ((linenos-style (or linenos-style "table"))
(text (org-export-format-code-default example-block info)))
(setq linenos-str (format "linenos=%s" linenos-style))
(let ((linenostart-str (and ;Extract the start line number of the example block.
(string-match "\\`\\([0-9]+\\)\\s-\\{2\\}" text)
(match-string-no-properties 1 text)))
(linenos-str (format "\"linenos=table, linenostart=%s\"" linenostart-str)))
(match-string-no-properties 1 text))))
(when linenostart-str
(setq linenos-str (format "%s, linenostart=%s" linenos-str linenostart-str))))

;; Remove Org-inserted numbers from the beginning of each
;; line as the Hugo highlight shortcode will be used instead
;; of literally inserting the line numbers.
(setq text (replace-regexp-in-string "^[0-9]+\\s-\\{2\\}" "" text))
(setq text (format "{{< highlight text %s>}}\n%s{{< /highlight >}}\n" linenos-str text))
(setq text (format "{{< highlight text \"%s\">}}\n%s{{< /highlight >}}\n" linenos-str text))
(setq ret (org-blackfriday--div-wrap-maybe example-block text)))
(setq ret (org-blackfriday-example-block example-block nil info)))
ret))
Expand Down Expand Up @@ -2641,6 +2649,8 @@ Hugo \"highlight\" shortcode features:
- Code blocks with line numbers (if the -n or +n switch is used)
- Highlight certains lines in the code block (if the :hl_lines
parameter is used)
- Set the `linenos' argument to the value passed by :linenos
(defaults to `table')
CONTENTS is nil. INFO is a plist used as a communication
channel."
Expand All @@ -2667,6 +2677,7 @@ channel."
(let* (;; See `org-element-src-block-parser' for all SRC-BLOCK properties.
(number-lines (org-element-property :number-lines src-block)) ;Non-nil if -n or +n switch is used
(hl-lines (cdr (assoc :hl_lines parameters)))
(linenos-style (cdr (assoc :linenos parameters)))
(hl-lines (cond
((stringp hl-lines)
(replace-regexp-in-string "," " " hl-lines)) ;"1,3-4" -> "1 3-4"
Expand Down Expand Up @@ -2702,10 +2713,11 @@ channel."
;; (message "ox-hugo src [dbg] parameters: %S" parameters)
(setq content
(cond
;; If both number-lines and hl-lines are nil
;; If all: number-lines, hl-lines and linenos-style are nil
;; , AND if :hugo-code-fence is non-nil (which is, by default).
((and (null number-lines)
(null hl-lines)
(null linenos-style)
(org-hugo--plist-get-true-p info :hugo-code-fence))
(let ((content1 (org-blackfriday-src-block src-block nil info)))
(when (and org-hugo-langs-no-descr-in-code-fences
Expand All @@ -2732,6 +2744,7 @@ channel."
content1))
;; If number-lines is non-nil
;; , or if hl-lines is non-nil
;; , or if linenos-style is non-nil
;; , or if :hugo-code-fence is nil
(t
(let ((code (org-export-format-code-default src-block info))
Expand All @@ -2740,15 +2753,16 @@ channel."
;; Formatter string where the first arg si linenos-str and
;; second is hllines-str.
(highlight-args-str "%s%s"))
(when (or number-lines
hl-lines)
(when (or number-lines hl-lines linenos-style)
(setq highlight-args-str " \"%s%s\""))
(when number-lines
(let ((linenostart-str (progn
;; Extract the start line number of the code block
(string-match "\\`\\s-*\\([0-9]+\\)\\s-\\{2\\}" code)
(match-string-no-properties 1 code))))
(setq linenos-str (format "linenos=table, linenostart=%s" linenostart-str)))
(when (or number-lines linenos-style)
(let ((linenos-style (or linenos-style "table")))
(setq linenos-str (format "linenos=%s" linenos-style))
(let ((linenostart-str (and ;Extract the start line number of the code block
(string-match "\\`\\s-*\\([0-9]+\\)\\s-\\{2\\}" code)
(match-string-no-properties 1 code))))
(when linenostart-str
(setq linenos-str (format "%s, linenostart=%s" linenos-str linenostart-str)))))
;; Remove Org-inserted numbers from the beginning of each
;; line as the Hugo highlight shortcode will be used instead
;; of literally inserting the line numbers.
Expand Down
18 changes: 18 additions & 0 deletions test/site/content-org/all-posts.org
Expand Up @@ -1373,6 +1373,18 @@ property needs to be left *empty* instead of setting to =nil=!
#+begin_src org :noweb yes :exports results :results output replace :eval yes
<<src-block-n-custom-continue>>
#+end_src
**** Specifying ~linenos~ parameter
#+begin_src emacs-lisp :linenos false
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
#+end_src

#+begin_src emacs-lisp -n 30 :linenos inline
(message "This is line 30")
(message "This is line 31")
(message "This is line 32")
#+end_src
*** Source blocks with highlighting
:PROPERTIES:
:EXPORT_FILE_NAME: source-block-with-highlighting
Expand Down Expand Up @@ -1937,6 +1949,12 @@ line 23
line 33
line 34
#+end_example
*** Specifying ~linenos~ parameter
#+begin_example :linenos false
This is line 1
This is line 2
This is line 3
#+end_example
** Example blocks with ATTR_HTML :attr___html:attr___css:
:PROPERTIES:
:EXPORT_FILE_NAME: example-blocks-with-attr-html
Expand Down
9 changes: 9 additions & 0 deletions test/site/content/posts/example-block-with-line-numbers.md
Expand Up @@ -38,3 +38,12 @@ line 23
line 33
line 34
{{< /highlight >}}


## Specifying `linenos` parameter {#specifying-linenos-parameter}

{{< highlight text "linenos=false">}}
This is line 1
This is line 2
This is line 3
{{< /highlight >}}
15 changes: 15 additions & 0 deletions test/site/content/posts/source-block-with-line-numbers.md
Expand Up @@ -93,3 +93,18 @@ draft = false
;; This will be listed as line 33
(message "This is line 34")
{{< /highlight >}}


## Specifying `linenos` parameter {#specifying-linenos-parameter}

{{< highlight emacs-lisp "linenos=false" >}}
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
{{< /highlight >}}

{{< highlight emacs-lisp "linenos=inline, linenostart=30" >}}
(message "This is line 30")
(message "This is line 31")
(message "This is line 32")
{{< /highlight >}}

0 comments on commit 9408d8c

Please sign in to comment.