branch: elpa/adoc-mode
commit 27912a8d382ab81977293e42a2bf29bd4c92a848
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
Recognise the block ID shorthand [#id]
Modern AsciiDoc assigns a block ID with the shorthand [#id] (optionally
[#id.role%opt] or [style#id]) rather than only the legacy [[id]] anchor.
Add a block-id-shorthand anchor type so adoc-goto-ref-label and M-. follow
xrefs to [#id] (and [style#id]) blocks, and a font-lock keyword that
highlights the id in a pure [#id...] line with adoc-anchor-face.
---
CHANGELOG.md | 1 +
adoc-mode.el | 19 ++++++++++++++++++-
doc/spec-compliance.adoc | 27 ++++++++++++++++-----------
test/adoc-mode-test.el | 24 ++++++++++++++++++++++++
4 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a8a12ae80..03dcc0ec18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### New features
+- Recognise the modern block ID shorthand `[#id]`. The id in a `[#id]` /
`[#id.role%opt]` block-attribute line is now highlighted like an anchor
(`adoc-anchor-face`), and cross-reference following (`adoc-goto-ref-label`,
`M-.`) jumps to `[#id]` block IDs - including the `[style#id]` form, e.g.
`[source#id]` - not just `[[id]]` anchors.
- Highlight checklist items. An unordered list item whose text begins with `[
]` (unchecked), `[x]`/`[X]`, or `[*]` (checked) now fontifies the checkbox with
the new `adoc-checkbox-face` (inherits `font-lock-constant-face`).
- Honour backslash escapes in inline formatting: a backslash before a
formatting delimiter (e.g. `\*not bold*`, `\**nor this**`, `` \`nor code` ``)
now de-emphasises the backslash and leaves the escaped span as literal text
instead of fontifying it as markup. Previously the unconstrained forms still
leaked an inner constrained match (`\**x**` highlighted `x`).
- `fill-paragraph` (and auto-fill) now preserve AsciiDoc hard line breaks: a
line ending in a space and a `+` is no longer merged with the following line.
Filling still joins ordinary soft-wrapped lines and indents list-item
continuations.
diff --git a/adoc-mode.el b/adoc-mode.el
index f1b6427bc3..49b34110e2 100644
--- a/adoc-mode.el
+++ b/adoc-mode.el
@@ -1366,10 +1366,19 @@ this id. If ID is nil, the regexp matches any anchor."
((eq type 'inline-general)
(adoc-re-inline-macro "anchor" id))
+ ((eq type 'block-id-shorthand)
+ ;; Modern block ID shorthand on a block attribute line, e.g. [#id],
+ ;; [#id.role%opt] or [style#id]. Group 1 is the id; anything before the
+ ;; `#' is a positional style and anything after is a role/option/attr.
+ (concat "^\\[\\(?:[^][#\n]*\\)#"
+ "\\(" (if id (regexp-quote id) (adoc-re-id)) "\\)"
+ "\\(?:[.%,][^]\n]*\\)?"
+ "\\][ \t]*$"))
+
((null type)
(mapconcat
(lambda (x) (adoc-re-anchor x id))
- '(block-id inline-special biblio inline-general)
+ '(block-id block-id-shorthand inline-special biblio inline-general)
"\\|"))
(t
@@ -2598,6 +2607,14 @@ for multiline constructs to be matched."
'(0 '(face adoc-meta-face adoc-reserved block-del))
'(1 '(face adoc-anchor-face adoc-flyspell-ignore t) t) ;; BLOCK-ID
'(2 'adoc-secondary-text-face t t)) ;; SECONDARY-TEXT
+ ;; block id shorthand on its own line: [#id], [#id.role], [#id.role%opt]
+ (list `(lambda (end)
+ (adoc-kwf-std
+ end
+ "^\\(\\[#\\)\\([-a-zA-Z0-9_]+\\)\\(?:[.%][^]\n]*\\)?\\(\\]\\)[
\t]*$"
+ '(0)))
+ '(0 '(face adoc-meta-face adoc-reserved block-del))
+ '(2 '(face adoc-anchor-face adoc-flyspell-ignore t) t)) ;; BLOCK-ID
;; --- general attribute list block element
;; ^\[(?P<attrlist>.*)\]$
diff --git a/doc/spec-compliance.adoc b/doc/spec-compliance.adoc
index f9b24177d8..ae1e4357f4 100644
--- a/doc/spec-compliance.adoc
+++ b/doc/spec-compliance.adoc
@@ -58,8 +58,10 @@ Findings are graded:
| Medium
| blocks / sections / attributes
-| The modern block-attribute *ID shorthand* `[#id]` (and `[#id.role]`)
- is not recognised; only the legacy block anchor `[[id]]` is.
+| [.line-through]#The modern block-attribute *ID shorthand* `[#id]` is not
+ recognised.# *FIXED* - `[#id]` is highlighted as an anchor and is
+ navigable; the `.role`/`%opt` shorthands inside an arbitrary attribute
+ list are still not individually faced.
| Medium
| text
@@ -157,8 +159,8 @@ Findings are graded:
| -
| Block ID shorthand `[#id]` / `[#id.role]`
-| Not recognised (only `[[id]]`); this is the preferred modern form
-| Medium
+| *Fixed* - highlighted as an anchor and navigable (see `block-id-shorthand`)
+| -
| Hard line breaks (line ending in ` +`)
| Preserved when filling; `[%hardbreaks]` option not specially handled
@@ -230,8 +232,8 @@ Findings are graded:
| -
| Custom section ID via `[#id]` shorthand
-| Not recognised (see blocks / attributes)
-| Medium
+| Fixed (see blocks / attributes)
+| -
| Discrete heading, special sections (appendix, bibliography, glossary)
| Styles are generic attribute lines; titles highlight normally
@@ -315,8 +317,9 @@ Findings are graded:
| -
| ID/role/option shorthand `[#id.role%opt]`
-| Partial - the attribute list highlights, but `#id` / `.role` / `%opt`
- shorthands inside it are not individually recognised
+| Partial - a pure `[#id]` line highlights the id as an anchor and is
+ navigable; the `.role` / `%opt` shorthands inside an arbitrary attribute
+ list are still not individually faced
| Medium
| Counters `{counter:name}`, character-replacement refs
@@ -377,9 +380,11 @@ implements.
. [x] *Recognise checklist items* (`* [ ]`, `* [x]`, `* [*]`) with a
dedicated face for the checkbox. Done - `adoc-kw-checkbox` /
`adoc-checkbox-face`.
-. [ ] *Recognise the block-attribute ID/role/option shorthand* `[#id]`,
- `[#id.role]`, `[%opt]` on block attribute lines, and treat `[#id]` as a
- block anchor for `adoc-goto-ref-label` / xref following.
+. [x] *Recognise the block-attribute ID shorthand* `[#id]`. Done -
+ `[#id]` / `[#id.role%opt]` lines highlight the id as an anchor
+ (`block-id-shorthand`) and `adoc-goto-ref-label` follows `[#id]` (and
+ `[style#id]`) targets. Faceting `.role` / `%opt` inside arbitrary
+ attribute lists is left as a smaller follow-up.
. [ ] *Add modern curved-quote highlighting* `+"`text`"+` and ``'`text`'``.
. [ ] *Drop or de-emphasise the deprecated `` `text' `` / ``\`\`text''``
templates* in the menu (and the `+...+` / `++...++` "Monospaced"
diff --git a/test/adoc-mode-test.el b/test/adoc-mode-test.el
index 837040f27f..0d8e8c9e46 100644
--- a/test/adoc-mode-test.el
+++ b/test/adoc-mode-test.el
@@ -1383,6 +1383,30 @@ on top of the `<mark>' default)."
(should (equal (line-number-at-pos) 3)))
(kill-buffer "adoc-test")))
+(ert-deftest adoctest-test-block-id-shorthand-faces ()
+ ;; the id in a [#id] block-attribute line is highlighted like an anchor
+ (adoctest-faces "block-id-shorthand"
+ "[#" 'adoc-meta-face "myid" 'adoc-anchor-face "]"
'adoc-meta-face)
+ (adoctest-faces "block-id-shorthand-role"
+ "[#" 'adoc-meta-face "myid" 'adoc-anchor-face ".role%open]"
'adoc-meta-face))
+
+(ert-deftest adoctest-test-goto-block-id-shorthand ()
+ (with-temp-buffer
+ (adoc-mode)
+ (insert "[#sect2]\n" ;1
+ "== Two\n" ;2
+ "\n" ;3
+ "[source#sid]\n" ;4
+ "----\n" ;5
+ "code\n" ;6
+ "----\n") ;7
+ ;; the pure shorthand form
+ (adoc-goto-ref-label "sect2")
+ (should (equal (line-number-at-pos) 1))
+ ;; the style+id form is navigable too
+ (adoc-goto-ref-label "sid")
+ (should (equal (line-number-at-pos) 4))))
+
(defun adoctest-template (template expected)
"Todo document adoctest-template TEMPLATE EXPECTED."
(let ((buf-name (concat "adoctest-" (symbol-name template))))