def sub_attributes data, opts = {}
return data if data.nil_or_empty?
if (string_data = ::String === data)
data = [data]
end
doc_attrs = @document.attributes
attribute_missing = nil
result = []
data.each do |line|
reject = false
reject_if_empty = false
line = line.gsub(AttributeReferenceRx) {
m = $~
if m[1] == '\\' || m[4] == '\\'
%({#{m[2]}})
elsif !m[3].nil_or_empty?
offset = (directive = m[3]).length + 1
expr = m[2][offset..-1]
case directive
when 'set'
args = expr.split(':')
_, value = Parser.store_attribute(args[0], args[1] || '', @document)
unless value
if doc_attrs.fetch('attribute-undefined', Compliance.attribute_undefined) == 'drop-line'
reject = true
break ''
end
end
reject_if_empty = true
''
when 'counter', 'counter2'
args = expr.split(':')
val = @document.counter(args[0], args[1])
if directive == 'counter2'
reject_if_empty = true
''
else
val
end
else
warn %(asciidoctor: WARNING: illegal attribute directive: #{m[3]})
m[0]
end
elsif doc_attrs.key?(key = m[2].downcase)
doc_attrs[key]
elsif INTRINSIC_ATTRIBUTES.key? key
INTRINSIC_ATTRIBUTES[key]
else
case (attribute_missing ||= (opts[:attribute_missing] || doc_attrs.fetch('attribute-missing', Compliance.attribute_missing)))
when 'skip'
m[0]
when 'drop-line'
warn %(asciidoctor: WARNING: dropping line containing reference to missing attribute: #{key})
reject = true
break ''
when 'warn'
warn %(asciidoctor: WARNING: skipping reference to missing attribute: #{key})
m[0]
else
reject_if_empty = true
''
end
end
} if line.include? '{'
result << line unless reject || (reject_if_empty && line.empty?)
end
string_data ? result * EOL : result
end