Module: Coradoc::Reference::Address::Path
- Defined in:
- lib/coradoc/reference/address/path.rb
Overview
Inter-document path — a document identifier plus optional fragment. Matches document-ID-shaped barewords (uppercase + dash + digit, e.g. "ELF-5005-1") and relative/absolute file paths ("images/foo.png", "../shared/common.adoc"). Locality is carried in fragment.
"ELF-5005-1" => path target "ELF-5005-1"
"ELF-5005-1#sec-3" => path target "ELF-5005-1", fragment "sec-3"
"images/foo.png" => path target "images/foo.png"
Constant Summary collapse
- DOC_ID_PATTERN =
Doc-ID pattern: uppercase-led bareword ("ELF-5005-1"). Used together with a separate digit scan — two linear passes, no ambiguous adjacent quantifiers (polynomial-ReDoS-safe).
/\A[A-Z][A-Z0-9_\-]*\z/- LOOSE_PATTERN =
Loose pattern used by
parsewhen the scheme is already chosen (via hint). Accepts any non-empty target plus optional fragment. /\A([^#]+)(?:#(.*))?\z/
Class Method Summary collapse
- .matches?(raw) ⇒ Boolean
- .normalize_fragment(fragment) ⇒ Object
- .parse(raw) ⇒ Object
- .scheme_name ⇒ Object
- .serialize(address) ⇒ Object
Class Method Details
.matches?(raw) ⇒ Boolean
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/coradoc/reference/address/path.rb', line 30 def matches?(raw) return false if raw.nil? || raw.empty? value = raw.to_s return true if value.include?('/') # Document IDs are uppercase-led and contain at least one digit # (what distinguishes them from anchors like "SECTION"). id_part = value.split('#', 2).first DOC_ID_PATTERN.match?(id_part) && id_part.match?(/\d/) end |
.normalize_fragment(fragment) ⇒ Object
60 61 62 |
# File 'lib/coradoc/reference/address/path.rb', line 60 def normalize_fragment(fragment) fragment&.empty? ? nil : fragment end |
.parse(raw) ⇒ Object
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/coradoc/reference/address/path.rb', line 42 def parse(raw) match = LOOSE_PATTERN.match(raw.to_s) raise Address::ParseError, "Invalid path: #{raw.inspect}" unless match Address.new( scheme: 'path', target: match[1], fragment: normalize_fragment(match[2]) ) end |
.scheme_name ⇒ Object
26 27 28 |
# File 'lib/coradoc/reference/address/path.rb', line 26 def scheme_name :path end |
.serialize(address) ⇒ Object
53 54 55 56 57 58 |
# File 'lib/coradoc/reference/address/path.rb', line 53 def serialize(address) base = address.target.to_s return base unless address.fragment && !address.fragment.empty? "#{base}##{address.fragment}" end |