# Copyright (c) 2020 Jerome Arbez-Gindre # frozen_string_literal: true require('asciidoctor/extensions') unless RUBY_ENGINE == 'opal' # An extension that allow to define applicable definitions # # Usage # :tag-mylabel-color: yellow # :tag-otherlabel-color: red # # # [define, requirement, TOTO-0001, [mylabel, otherlabel]] # -- # The system shall allow to do lots of things. # -- # # or # # [define, requirement, TOTO-0001] # This shall be nice. # require('asciidoctor/defmastership/regexp_dispatcher') require('defmastership/constants') require('defmastership/parsing_state') module Asciidoctor module DefMastership # Preprocessor to replace adoc statements class Preprocessor < Asciidoctor::Extensions::Preprocessor EREF_CONFIG_REGEXP = ::DefMastership::DMRegexp::EREF_CONFIG DEFINITION_REGEXP = ::DefMastership::DMRegexp::DEFINITION EREF_DEF_REGEXP = ::DefMastership::DMRegexp::EREF_DEF IREF_DEF_REGEXP = ::DefMastership::DMRegexp::IREF_DEF ATTR_SET_REGEXP = ::DefMastership::DMRegexp::ATTR_SET VARIABLE_DEF_REGEXP = ::DefMastership::DMRegexp::VARIABLE_DEF def initialize(config = {}) super(config) @has_url = {} @variables = {} @parsing_state = ::DefMastership::ParsingState.new end # process the document def process(_document, reader) return reader if reader.eof? reader.unshift_lines(parse_and_replace(reader.read_lines)) reader end private def build_subs subs = RegexpDispatcher.new(self) subs .add_rule(EREF_CONFIG_REGEXP, :set_eref_url_if_any) .add_rule(DEFINITION_REGEXP, :build_definition) .add_rule(EREF_DEF_REGEXP, :build_external_ref) .add_rule(IREF_DEF_REGEXP, :build_internal_ref) .add_rule(ATTR_SET_REGEXP, :attribute_setting) .add_rule(VARIABLE_DEF_REGEXP, :variable_set) end def parse_and_replace(lines) subs = build_subs lines.reduce([]) do |new_lines, line| next new_lines + [line] unless @parsing_state.enabled?(line) next new_lines + subs.replace(line) end end def set_eref_url_if_any(line, matches) @has_url[matches[:refname]] = true if matches[:symb] == 'url' && matches[:value] != 'none' [line] end def show_explicit_checksum(matches) matches[:explicit_checksum] && @variables['show-explicit-checksum'] != 'disable' && @variables["show-#{matches[:type]}-explicit-checksum"] != 'disable' end def build_definition(_line, matches) definition_lines = [] explicit_checksum_str = " [.checksum]#(#{matches[:explicit_checksum]})#" if show_explicit_checksum(matches) explicit_version_str = " [.version]#(#{matches[:explicit_version]})#" if matches[:explicit_version] labels_str = " #{labels_strings(matches[:labels]).join(' ')}" if matches[:labels] definition_lines << ".#{matches[:reference]}#{explicit_version_str}#{explicit_checksum_str}#{labels_str}" definition_lines << "[##{matches[:reference]}.define.#{matches[:type]}]" end def labels_strings(labels) labels_strs = [] labels.split(/\s*,\s*/).reject(&:empty?).each do |label| labels_strs << "[.tag.{tag-#{label}-color}]##{label}#" end labels_strs end def build_link(ref, matches) if @has_url[matches[:refname]] "link:{eref-#{matches[:refname]}-url}##{ref}[#{ref}]" else ref end end def show_ext_ref(matches) @variables['show-ext-ref'] != 'disable' && @variables["show-#{matches[:refname]}-ext-ref"] != 'disable' end def build_external_ref(_line, matches) return [] unless show_ext_ref(matches) extrefs = matches[:extrefs].split(/\s*,\s*/) new_line = "[.external_reference]\#{eref-#{matches[:refname]}-prefix} " extref_line = extrefs.map { |ref| build_link(ref, matches) } @has_url[matches[:refname]] ["#{new_line}#{extref_line.join(', ')}.#"] end def build_internal_ref(line, _matches) [ line.gsub(IREF_DEF_REGEXP) do "<<#{Regexp.last_match[:intref]},#{Regexp.last_match[:intref]}>>" end ] end def attribute_setting(_line, matches) [ '[.attribute]', "{attr-#{matches[:attr]}-prefix} #{matches[:value]}." ] end def variable_set(line, matches) @variables[matches[:varname]] = matches[:value] [line] end end end end