1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Whole-element anchoring: reference lines and their resolved anchors.
//!
//! A *reference line* is a line whose only content (after indentation) is a
//! single bracketed reference, e.g. a line that is exactly `[./readme.txt]`.
//! Per `specs/.../references-general.lex` §2.3.2–§2.3.4 such a line anchors the
//! *entire head line of the element directly above it* (a session title, a list
//! item's own line, a definition's subject term, a verbatim subject, or a
//! paragraph line). It never attaches downward, and when there is no content
//! line directly above it (first line of its container, or preceded by a blank
//! line) it *self-links* — it stands alone and links its own text, exactly like
//! a lone inline reference.
//!
//! Reference lines are removed from the line stream *before* structural parsing
//! (see [`crate::lex::anchoring`]), so they are transparent to the
//! definition-vs-session decision. The removal pass also resolves each line's
//! anchor here, against the original (pre-removal) source, so every range below
//! is in original-source coordinates — which is what editors and serializers
//! need, since the document the user sees still contains the reference lines.
use Range;
use crateReferenceInline;
/// A reference line and its resolved anchor.
///
/// Collected on [`crate::lex::ast::Document`] as a queryable, document-level
/// list (`Document::reference_lines()`), so downstream consumers — the babel
/// serializers and the LSP `documentLink` provider — can read the anchor
/// without re-deriving the line-adjacency rules.
/// The resolved anchor of a reference line.
/// The head-line shape a reference line anchored.
///
/// The anchor is resolved against the original source line directly above the
/// reference line, so the classification reflects what that line *looks like*,
/// which is also exactly what determines how much of it the anchor covers:
///
/// - [`AnchoredElement::ListItem`] — the line opens with a list marker (`- `,
/// `1. `, `a) `, …); the marker is excluded from the anchor.
/// - [`AnchoredElement::Subject`] — the line ends with a `:` subject marker (a
/// definition term, a colon-style session title, or a verbatim subject); the
/// trailing colon is excluded from the anchor.
/// - [`AnchoredElement::WholeLine`] — any other head line (a plain paragraph
/// line, or a session title written without a colon); the whole line is the
/// anchor.
///
/// Session title vs. paragraph vs. verbatim subject are *not* distinguished
/// here because they are indistinguishable from the head line alone and, more
/// importantly, anchor identically (the whole line, modulo the colon rule). The
/// behaviorally-meaningful distinctions — marker stripping and colon stripping
/// — are the ones captured.