module Asciidoctor::Substitutors

def resolve_subs subs, type = :block, defaults = nil, subject = nil

Returns An Array of Symbols representing the substitution operation or nothing if no subs are found.

subject - The String to use in log messages to communicate the subject for which subs are being resolved (default: nil)
defaults - An Array of substitutions to start with when computing incremental substitutions (default: nil).
type - A Symbol representing the context for which the subs are being resolved (default: :block).
subs - The comma-delimited String of substitution names or aliases.

Public: Resolve the list of comma-delimited subs against the possible options.
def resolve_subs subs, type = :block, defaults = nil, subject = nil
  return if subs.nil_or_empty?
  # QUESTION should we store candidates as a Set instead of an Array?
  candidates = nil
  subs = subs.delete ' ' if subs.include? ' '
  modifiers_present = SubModifierSniffRx.match? subs
  subs.split(',').each do |key|
    modifier_operation = nil
    if modifiers_present
      if (first = key.chr) == '+'
        modifier_operation = :append
        key = key.slice 1, key.length
      elsif first == '-'
        modifier_operation = :remove
        key = key.slice 1, key.length
      elsif key.end_with? '+'
        modifier_operation = :prepend
        key = key.chop
      end
    end
    key = key.to_sym
    # special case to disable callouts for inline subs
    if type == :inline && (key == :verbatim || key == :v)
      resolved_keys = BASIC_SUBS
    elsif SUB_GROUPS.key? key
      resolved_keys = SUB_GROUPS[key]
    elsif type == :inline && key.length == 1 && (SUB_HINTS.key? key)
      resolved_key = SUB_HINTS[key]
      if (candidate = SUB_GROUPS[resolved_key])
        resolved_keys = candidate
      else
        resolved_keys = [resolved_key]
      end
    else
      resolved_keys = [key]
    end
    if modifier_operation
      candidates ||= (defaults ? (defaults.drop 0) : [])
      case modifier_operation
      when :append
        candidates += resolved_keys
      when :prepend
        candidates = resolved_keys + candidates
      when :remove
        candidates -= resolved_keys
      end
    else
      candidates ||= []
      candidates += resolved_keys
    end
  end
  return unless candidates
  # weed out invalid options and remove duplicates (order is preserved; first occurrence wins)
  resolved = candidates & SUB_OPTIONS[type]
  unless (candidates - resolved).empty?
    invalid = candidates - resolved
    logger.warn %(invalid substitution type#{invalid.size > 1 ? 's' : ''}#{subject ? ' for ' : ''}#{subject}: #{invalid.join ', '})
  end
  resolved
end