Skip to content

Commit

Permalink
Support internal linking to source blocks by their block names
Browse files Browse the repository at this point in the history
  • Loading branch information
kaushalmodi committed Nov 8, 2017
1 parent a04b632 commit 48de866
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 59 deletions.
127 changes: 68 additions & 59 deletions ox-hugo.el
Expand Up @@ -1258,69 +1258,78 @@ channel."
(parameters (org-babel-parse-header-arguments parameters-str))
(hl-lines (cdr (assoc :hl_lines parameters)))
(hl-lines (when hl-lines
(replace-regexp-in-string "," " " hl-lines)))) ;"1,3-4" -> "1 3-4"
(replace-regexp-in-string "," " " hl-lines))) ;"1,3-4" -> "1 3-4"
(label (let ((lbl (and (org-element-property :name src-block)
(org-export-get-reference src-block info))))
(if lbl
(format "<a id=\"%s\"></a>\n" lbl)
"")))
ret)
;; (message "ox-hugo src [dbg] number-lines: %S" number-lines)
;; (message "ox-hugo src [dbg] parameters: %S" parameters)
(cond
;; 1. If number-lines is nil AND :hugo-code-fence is non-nil
((and (null number-lines)
(null hl-lines)
(org-hugo--plist-get-true-p info :hugo-code-fence))
(let ((ret (org-blackfriday-src-block src-block nil info)))
(when (and org-hugo-langs-no-descr-in-code-fences
(member (intern lang) org-hugo-langs-no-descr-in-code-fences))
;; When using Pygments, with the pygmentsCodeFences
;; options enabled in Hugo, `org' is not recognized as a
;; "language", because Pygments does not have a lexer for
;; Org.
;; Issue on Pygments repo:
;; https://bitbucket.org/birkenfeld/pygments-main/issues/719/wishlist-support-org
;; So attempt to do below:
;; ```org
;; # org comment
;; ```
;; will not result in a <code> tag wrapped block in HTML.
;;
;; So override the language to be an empty string in such cases.
;;
;; *Note* that this issue does NOT exist if using Chroma,
;; which is the default syntax highlighter after Hugo
;; v0.28.
(setq ret (replace-regexp-in-string (concat "\\`\\(```+\\)" lang) "\\1" ret)))
ret))
;; 2. If number-lines is non-nil, or
;; 3. If hl-lines is non-nil, or
;; 4. If :hugo-code-fence is nil
(t
(let ((code (org-export-format-code-default src-block info))
(linenos-str "")
(hllines-str "")
;; 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)
(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)))
;; 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 code (replace-regexp-in-string "^\\s-*[0-9]+\\s-\\{2\\}" "" code)))
(when hl-lines
(setq hllines-str (concat "hl_lines=" hl-lines))
(when number-lines
(setq hllines-str (concat ", " hllines-str))))
(format "{{< highlight %s%s>}}\n%s{{< /highlight >}}\n"
lang
(format highlight-args-str linenos-str hllines-str)
code))))))
(setq ret
(cond
;; 1. If number-lines is nil AND :hugo-code-fence is non-nil
((and (null number-lines)
(null hl-lines)
(org-hugo--plist-get-true-p info :hugo-code-fence))
(let ((ret1 (org-blackfriday-src-block src-block nil info)))
(when (and org-hugo-langs-no-descr-in-code-fences
(member (intern lang) org-hugo-langs-no-descr-in-code-fences))
;; When using Pygments, with the pygmentsCodeFences
;; options enabled in Hugo, `org' is not recognized as a
;; "language", because Pygments does not have a lexer for
;; Org.
;; Issue on Pygments repo:
;; https://bitbucket.org/birkenfeld/pygments-main/issues/719/wishlist-support-org
;; So attempt to do below:
;; ```org
;; # org comment
;; ```
;; will not result in a <code> tag wrapped block in HTML.
;;
;; So override the language to be an empty string in such cases.
;;
;; *Note* that this issue does NOT exist if using Chroma,
;; which is the default syntax highlighter after Hugo
;; v0.28.
(setq ret1 (replace-regexp-in-string (concat "\\`\\(```+\\)" lang) "\\1" ret1)))
ret1))
;; 2. If number-lines is non-nil, or
;; 3. If hl-lines is non-nil, or
;; 4. If :hugo-code-fence is nil
(t
(let ((code (org-export-format-code-default src-block info))
(linenos-str "")
(hllines-str "")
;; 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)
(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)))
;; 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 code (replace-regexp-in-string "^\\s-*[0-9]+\\s-\\{2\\}" "" code)))
(when hl-lines
(setq hllines-str (concat "hl_lines=" hl-lines))
(when number-lines
(setq hllines-str (concat ", " hllines-str))))
(format "{{< highlight %s%s>}}\n%s{{< /highlight >}}\n"
lang
(format highlight-args-str linenos-str hllines-str)
code)))))
(concat label ret)))



;;; Filter Functions

;;;; Body Filter
Expand Down
50 changes: 50 additions & 0 deletions test/site/content-org/all-posts.org
Expand Up @@ -1519,6 +1519,56 @@ link./
#+INCLUDE: "./all-posts.org::#lorem-ipsum" :only-contents t

*Here we refer to item [[target]].*
*** Links to source blocks :noexport:
:PROPERTIES:
:EXPORT_FILE_NAME: links-to-source-blocks
:END:
*Note*: This test is marked as =noexport= because the Org generated
link IDs are random and thus would fail the tests. So let this test
serve just as an example and not as a part of the automated test
suite.

To export this test, you'll need to temporarily remove the =noexport=
tag.
-----
From [[http://orgmode.org/manual/Internal-links.html][(org) Internal links]],

#+BEGIN_QUOTE
If no dedicated target exists, the link will then try to match the
exact name of an element within the buffer. Naming is done with the
‘#+NAME’ keyword, which has to be put in the line before the element it
refers to, as in the following example
#+BEGIN_EXAMPLE
,#+NAME: My Target
| a | table |
|----+------------|
| of | four cells |
#+END_EXAMPLE
#+END_QUOTE

So the below code block:
#+BEGIN_SRC org
,#+NAME: code__hello
,#+BEGIN_SRC emacs-lisp
(message "Hello")
,#+END_SRC
Here we refer to code snippet [[code__hello]].
#+END_SRC

will output below (/lorem-ipsum/ added to increase page content so
that the link jump is evident):

#+NAME: code__hello
#+BEGIN_SRC emacs-lisp
(message "Hello")
#+END_SRC

/Scroll to the end of the below 'lorem-ipsum' block to find the test
link./

#+INCLUDE: "./all-posts.org::#lorem-ipsum" :only-contents t

*Here we refer to code snippet [[code__hello]].*
* Equations :equations:
** Inline equations
:PROPERTIES:
Expand Down
104 changes: 104 additions & 0 deletions test/site/content/posts/links-to-source-blocks.md
@@ -0,0 +1,104 @@
+++
title = "Links to source blocks"
tags = ["links", "internal-links"]
draft = false
+++

**Note**: This test is marked as `noexport` because the Org generated
link IDs are random and thus would fail the tests. So let this test
serve just as an example and not as a part of the automated test
suite.

To export this test, you'll need to temporarily remove the `noexport`
tag.

---

From [(org) Internal links](http://orgmode.org/manual/Internal-links.html),

> If no dedicated target exists, the link will then try to match the
> exact name of an element within the buffer. Naming is done with the
> ‘#+NAME’ keyword, which has to be put in the line before the element it
> refers to, as in the following example
>
> ```text
> #+NAME: My Target
> | a | table |
> |----+------------|
> | of | four cells |
> ```
So the below code block:

````org
#+NAME: code__hello
#+BEGIN_SRC emacs-lisp
(message "Hello")
#+END_SRC
Here we refer to code snippet [[code__hello]].
````

will output below (_lorem-ipsum_ added to increase page content so
that the link jump is evident):

<a id="orgd4c64be"></a>
````emacs-lisp
(message "Hello")
````

_Scroll to the end of the below 'lorem-ipsum' block to find the test
link._

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et
quam metus. Etiam in iaculis mi, sit amet pretium magna. Donec ut dui
mi. Maecenas pharetra sapien nunc, ut mollis enim aliquam quis. Nam at
ultricies metus. Nulla tempor augue in vestibulum tristique. Phasellus
volutpat pharetra metus quis suscipit. Morbi maximus sem dolor, id
accumsan ipsum commodo non.

Fusce quam ligula, gravida ac dui venenatis, bibendum commodo
lorem. Duis id elit turpis. Integer sed diam nibh. Donec tempus
lacinia odio, a laoreet velit dictum id. Suspendisse efficitur euismod
purus et porttitor. Aliquam sit amet tellus mauris. Mauris semper
dignissim nibh, faucibus vestibulum purus varius quis. Suspendisse
potenti. Cras at ligula sit amet nunc vehicula condimentum quis nec
est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae; Donec iaculis, neque sit amet maximus rhoncus,
nisl tortor convallis ante, ut mollis purus augue ut justo. Praesent
felis urna, volutpat sit amet posuere dictum, luctus quis nibh. Proin
et tristique ipsum, in aliquam ante.

Aenean eget ex mauris. Cras ut tempor quam. Curabitur eget nulla
laoreet, bibendum neque porta, tempus nulla. Ut tellus nisi, semper eu
ligula pretium, aliquam accumsan dolor. Nunc fermentum cursus arcu eu
suscipit. Nam dolor tellus, efficitur sed condimentum at, fringilla
eget nisi. Nulla luctus metus felis. Suspendisse potenti. Cras lacinia
orci nec dui sodales commodo. Donec tellus arcu, congue porta ultrices
non, pretium et sapien. Proin mattis risus dignissim feugiat
tristique. Donec nibh lorem, facilisis id posuere ut, varius ac
urna. Etiam ultrices dignissim mauris, quis venenatis ex semper ut.

Curabitur id fermentum erat, rhoncus scelerisque est. Sed pulvinar,
nulla sed sollicitudin scelerisque, ipsum erat sollicitudin dolor, ut
commodo arcu justo vel libero. Curabitur turpis dolor, fermentum ut
elit a, vehicula commodo nunc. Sed sit amet blandit nulla, quis
sodales massa. Donec lobortis, urna vel volutpat ullamcorper, mauris
est efficitur nulla, et suscipit velit dui at metus. Aliquam id sem
sed metus tristique scelerisque nec vitae odio. Phasellus a
pellentesque libero, vel convallis metus. Sed nec fringilla magna, non
varius ex. Sed interdum eleifend ligula, quis porta enim ultrices
a. Donec hendrerit diam ac elementum tincidunt.

Pellentesque eget nisl rhoncus, malesuada justo nec, suscipit
quam. Nam sodales mauris eu bibendum suscipit. Vivamus sodales dui
lorem, scelerisque pellentesque diam fermentum sed. Etiam fermentum
nisl id nisl blandit, sit amet semper erat ultricies. Nulla tincidunt
nulla metus, eu imperdiet lorem malesuada sagittis. Maecenas accumsan
risus sed ante eleifend, vitae pretium leo porta. Suspendisse vitae
eros vitae dui ornare condimentum id sit amet mauris. Etiam tincidunt
consequat risus, eu posuere mi. Donec ut nunc eu massa porttitor
suscipit nec nec neque. Suspendisse vitae tincidunt justo, sed
molestie velit. Nullam pellentesque convallis ante, vel posuere libero
blandit in.

**Here we refer to code snippet [2](#orgd4c64be).**

0 comments on commit 48de866

Please sign in to comment.