class Giblish::DocidCollector
Parse all adoc files for :docid: attributes
Constants
- ID_MAX_LENGTH
The maximum number of characters required for a valid doc id
- ID_MIN_LENGTH
The minimum number of characters required for a valid doc id
Attributes
Public Class Methods
# File lib/giblish/docid.rb, line 20 def clear_cache @docid_cache = {} end
# File lib/giblish/docid.rb, line 24 def clear_deps @docid_deps = {} end
Public Instance Methods
add a new source document to the docid_deps
# File lib/giblish/docid.rb, line 59 def add_source_dep(src_path) return if docid_deps.key? src_path docid_deps[src_path] = [] end
Check if a :docid: <id> entry exists in the header. According to www.methods.co.nz/asciidoc/userguide.html#X95 the header is optional, but if it exists it:
-
must start with a titel (=+ <My Title>)
-
ends with one or more blank lines
-
does not contain any blank line
# File lib/giblish/docid.rb, line 47 def parse_file(path) Giblog.logger.debug { "parsing file #{path} for docid..." } Giblish.process_header_lines_from_file(path) do |line| m = /^:docid: +(.*)$/.match(line) if m # There is a docid defined, cache the path and doc id validate_and_add m[1], path end end end
This hook is called by Asciidoctor once for each document before Asciidoctor processes the adoc content.
It replaces references of the format <<:docid: ID-1234,Hello >> with references to a resolved relative path.
# File lib/giblish/docid.rb, line 70 def process(document, reader) # Add doc as a source dependency for doc ids src_path = document.attributes["docfile"] # Note: the nil check is there to prevent us adding generated # asciidoc docs that does not exist in the file system (e.g. the # generated index pages). This is a bit hackish and should maybe be # done differently return if src_path.nil? add_source_dep src_path # Convert all docid refs to valid relative refs reader.lines.each do |line| line.gsub!(/<<\s*:docid:\s*(.*?)>>/) do |_m| # parse the ref target_id, section, display_str = parse_doc_id_ref Regexp.last_match(1) # The result is a valid ref in the form # <<target_doc.adoc#[section][,display_str]>> Giblog.logger.debug { "Replace docid ref in doc #{src_path}..." } if docid_cache.key? target_id # add the referenced doc id as a target dependency of this document docid_deps[src_path] << target_id docid_deps[src_path] = docid_deps[src_path].uniq # resolve the doc id ref to a valid relative path "<<#{get_rel_path(src_path, target_id)}##{section}#{display_str}>>" else "<<UNKNOWN_DOC, Could not resolve doc id reference !!!>>" end end end reader end
Private Instance Methods
make sure the id is within the designated length and does not contain a '#' symbol
# File lib/giblish/docid.rb, line 149 def doc_id_ok?(doc_id) (doc_id.length.between?(ID_MIN_LENGTH, ID_MAX_LENGTH) && !doc_id.include?("#")) end
Helper method to shorten calls to docid_cache
from instance methods
# File lib/giblish/docid.rb, line 110 def docid_cache self.class.docid_cache end
# File lib/giblish/docid.rb, line 114 def docid_deps self.class.docid_deps end
Get the relative path from the src doc to the doc with the given doc id
# File lib/giblish/docid.rb, line 120 def get_rel_path(src_path, doc_id) raise ArgumentError("unknown doc id: #{doc_id}") unless docid_cache.key? doc_id rel_path = docid_cache[doc_id] .dirname .relative_path_from(Pathname.new(src_path).dirname) + docid_cache[doc_id].basename rel_path.to_s end
input_str shall be the expression between <<:docid:<input_str>>> where the <input_str> is in the form <id>[,display_str]
returns an array with [id, section, display_str]
# File lib/giblish/docid.rb, line 135 def parse_doc_id_ref(input_str) ref, display_str = input_str.split(",").each(&:strip) id, section = ref.split "#" display_str = id.dup if display_str.nil? display_str.prepend "," section = "" if section.nil? [id, section, display_str] end
# File lib/giblish/docid.rb, line 154 def validate_and_add(doc_id, path) id = doc_id.strip Giblog.logger.debug { "found possible docid: #{id}" } unless doc_id_ok? doc_id Giblog.logger.error { "Invalid docid: #{id} in file #{path}, this will be ignored!" } return end if docid_cache.key? id Giblog.logger.warn { "Found same doc id twice (#{id})." } Giblog.logger.warn { "Assigning this id to the file #{path}." } Giblog.logger.warn { "Discarding this id from the file #{docid_cache[id]}." } end docid_cache[id] = Pathname(path) end