# File lib/asciidoctor/substituters.rb, line 24
  def apply_subs(lines, subs = COMPOSITE_SUBS[:normal])
    if subs.nil?
      subs = []
    elsif subs.is_a? Symbol
      subs = [subs]
    end

    if !subs.empty?
      # QUESTION is this most efficient operation?
      subs = subs.map {|key|
        COMPOSITE_SUBS.has_key?(key) ? COMPOSITE_SUBS[key] : key
      }.flatten
    end

    return lines if subs.empty?

    multiline = lines.is_a?(Array)
    text = multiline ? lines.join : lines

    if (has_passthroughs = subs.include?(:macros))
      text = extract_passthroughs(text)
    end
    
    subs.each {|type|
      case type
      when :specialcharacters
        text = sub_specialcharacters(text)
      when :quotes
        text = sub_quotes(text)
      when :attributes
        text = sub_attributes(text.lines.entries).join
      when :replacements
        text = sub_replacements(text)
      when :macros
        text = sub_macros(text)
      when :callouts
        text = sub_callouts(text)
      when :post_replacements
        text = sub_post_replacements(text)
      else
        puts "asciidoctor: WARNING: unknown substitution type #{type}"
      end
    }
    text = restore_passthroughs(text) if has_passthroughs

    multiline ? text.lines.entries : text
  end