Skip to content

Commit

Permalink
Merge pull request #566 from kaushalmodi/target-link-improvements
Browse files Browse the repository at this point in the history
Target link improvements

- Handle target anchor string like non alphanumeric chars like spaces. Now `<<some target>>` works.
- Prefixing a target name with `.` now prevents the auto-prefixing of `org-target--` string to the anchor name. So `<<.abc>>` will be same as adding `<span id="abc"></span>` in HTML.
  • Loading branch information
kaushalmodi committed Feb 17, 2022
2 parents 58a685c + a7cb6b9 commit f7838b7
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 18 deletions.
20 changes: 20 additions & 0 deletions doc/ox-hugo-manual.org
Expand Up @@ -3980,6 +3980,7 @@ might appreciate the power of [[https://orgmode.org/manual/Macro-Replacement.htm

This is best shown using the same ~relref~ shortcode example ..

<<.relref-org-macro>>
Instead of always typing ~@@hugo:[Org Special Blocks]({​{< relref
"org-special-blocks" >}})@@~, you can define an Org macro called
~relref~ like so:
Expand Down Expand Up @@ -4084,6 +4085,25 @@ org-hugo-get-heading-slug org-hugo-get-md5)~.
#+begin_src md
### Heading in a post {#74283e7c-a20b-1c22-af88-e41ff8055d17}
#+end_src
**** Target Links
Org mode specifies the ~<<target>>~ syntax in the [[https://orgmode.org/manual/Internal-Links.html][Internal Links]]
section of the Org manual.

By default, a target named "foo" <<foo>>(~<<foo>>~) will create an
HTML anchor with a prefix (like ~org-target--~). See [[foo][this link]] to that
"foo" target.

But if the target name is prefixed with a ".", like ".bar"
<<.bar>>(~<<.bar>>~), the HTML anchor with
#+begin_mark
not have that prefix
#+end_mark
. See [[.bar][this link]] to that ".bar" target.

This special feature allows you to create an HTML anchor anywhere in
your document which you might then refer from a different post by
using something like the {{{relref(~relref~ Org
macro,shortcodes#relref-org-macro)}}}.
** Meta
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "7.meta"
Expand Down
45 changes: 36 additions & 9 deletions ox-blackfriday.el
Expand Up @@ -660,9 +660,14 @@ Else return an empty string."
;;;; Convert string to a valid anchor name
(defun org-blackfriday--valid-html-anchor-name (str)
"Turn STR into a valid HTML anchor name.
Replaces invalid characters with \"-\"."
Replaces invalid characters with \"-\". The returned anchor name
will also never begin or end with \"-\".
"
(or (and (stringp str)
(replace-regexp-in-string "[^a-zA-Z0-9_-.]" "-" str))
(string-trim
(replace-regexp-in-string "[^a-zA-Z0-9_-.]" "-" str)
"-"))
""))

;; Return HTML span tags for link targets.
Expand Down Expand Up @@ -1441,16 +1446,38 @@ contextual information."
blank-line-before-table tbl table-post))))

;;;; Target
(defun org-blackfriday--get-target-anchor (target)
"Get HTML anchor for TARGET element.
By default, the returned anchor string is the HTML sanitized
target name (`:value' property of TARGET element) with a prefix
returned by `org-blackfriday--get-ref-prefix'.
If the anchor string begins with \".\", the returned anchor
string is just the HTML sanitized target name without that \".\".
TARGET NAME ANCHOR
abc org-target--abc
abc def org-target--abc-def
.abc abc"
(let ((target-name (org-element-property :value target))
(verbatim-target-prefix ".") ;This needs to be non-alpha-numeric, and not an Org-recognized link prefix like "#"
(prefix ""))
(unless (string-prefix-p verbatim-target-prefix target-name)
(setq prefix (org-blackfriday--get-ref-prefix 'target)))
;; Below function will auto-remove the `verbatim-target-prefix' if
;; present.
(setq target-name (org-blackfriday--valid-html-anchor-name target-name))
(format "%s%s" prefix target-name)))

(defun org-blackfriday-target (target _contents _info)
"Transcode a TARGET object from Org to HTML.
CONTENTS is nil."
(let* ((prefix (org-blackfriday--get-ref-prefix 'target))
(ref (format "%s%s"
prefix
(org-element-property :value target)))
(attr (format " class=\"%s\" id=\"%s\""
(string-remove-suffix "--" prefix)
ref)))
(let* ((class (string-remove-suffix "--"
(org-blackfriday--get-ref-prefix 'target)))
(anchor (org-blackfriday--get-target-anchor target))
(attr (format " class=\"%s\" id=\"%s\"" class anchor)))
(org-blackfriday--link-target attr)))

;;;; Verse Block
Expand Down
4 changes: 1 addition & 3 deletions ox-hugo.el
Expand Up @@ -2198,9 +2198,7 @@ and rewrite link paths to make blogging more seamless."
(org-export-get-reference destination info))))
;; Ref to a <<target>>.
((eq (org-element-type destination) 'target)
(format "%s%s"
(org-blackfriday--get-ref-prefix (org-element-type destination))
raw-path)) ;If the target is <<xyz>>, `raw-path' will be "xyz"
(org-blackfriday--get-target-anchor destination))
;; Ref to all other link destinations.
(t
(org-export-get-reference destination info)))))
Expand Down
13 changes: 10 additions & 3 deletions test/site/content-org/all-posts.org
Expand Up @@ -3536,7 +3536,7 @@ Once that is evaluated, links like these will export fine i.e. no
:CUSTOM_ID: link-heading-2
:END:
- Link to [[#link-heading-1][Heading 1]]
*** Links to Org targets
*** Links to Org Targets
:PROPERTIES:
:EXPORT_FILE_NAME: links-to-org-targets
:END:
Expand All @@ -3560,6 +3560,13 @@ link./
#+include: "./misc/common.org::#lorem-ipsum" :only-contents t

*Here we refer to item [[target]].*
**** Using Org targets as verbatim anchors
paragraph 1

<<.paragraph-2>>
paragraph 2

[[.paragraph-2][Link to paragraph 2]]
*** Links to source blocks :src_block:
:PROPERTIES:
:EXPORT_FILE_NAME: links-to-source-blocks
Expand Down Expand Up @@ -3655,7 +3662,7 @@ init file.
- [[#internal-target][Link to CUSTOM_ID within the same post]]
- [[id:8e65ff86-3f9a-48ef-9b43-751a2e8a9372][Link to ID within the same post]]
- [[*Internal target][Link to heading within the same post]]
- [[internal-target][Link to target within the same post]]
- Links to target links within the same post like [[internal target link][this]].
*** Cross-post links :crosspost_links:
Cross-post links are internal links pointing to targets in a different
subtree that will be exported to another Hugo post than the link
Expand Down Expand Up @@ -3685,7 +3692,7 @@ resolved to the containing post.
:CUSTOM_ID: internal-target
:ID: 8e65ff86-3f9a-48ef-9b43-751a2e8a9372
:END:
<<internal-target>>
<<internal target link>>
*** Link destination
:PROPERTIES:
:CUSTOM_ID: link-destination
Expand Down
4 changes: 2 additions & 2 deletions test/site/content/posts/links-outside-the-same-post.md
Expand Up @@ -30,7 +30,7 @@ init file.
- [Link to CUSTOM_ID within the same post](#internal-target)
- [Link to ID within the same post](#internal-target)
- [Link to heading within the same post](#internal-target)
- [Link to target within the same post](#org-target--internal-target)
- Links to target links within the same post like [this](#org-target--internal-target-link).


## Cross-post links <span class="tag"><span class="crosspost_links">crosspost-links</span></span> {#cross-post-links}
Expand Down Expand Up @@ -68,7 +68,7 @@ resolved to the containing post.

## Internal target {#internal-target}

<span class="org-target" id="org-target--internal-target"></span>
<span class="org-target" id="org-target--internal-target-link"></span>


## Link destination {#link-destination}
Expand Down
12 changes: 11 additions & 1 deletion test/site/content/posts/links-to-org-targets.md
@@ -1,5 +1,5 @@
+++
title = "Links to Org targets"
title = "Links to Org Targets"
tags = ["links", "internal-links"]
draft = false
+++
Expand Down Expand Up @@ -74,3 +74,13 @@ molestie velit. Nullam pellentesque convallis ante, vel posuere libero
blandit in.

**Here we refer to item [2](#org-target--target).**


## Using Org targets as verbatim anchors {#using-org-targets-as-verbatim-anchors}

paragraph 1

<span class="org-target" id="paragraph-2"></span>
paragraph 2

[Link to paragraph 2](#paragraph-2)

0 comments on commit f7838b7

Please sign in to comment.