Chris@909: module CodeRay Chris@909: module Encoders Chris@909: Chris@909: load :filter Chris@909: Chris@909: # A Filter that selects tokens based on their token kind. Chris@909: # Chris@909: # == Options Chris@909: # Chris@909: # === :exclude Chris@909: # Chris@909: # One or many symbols (in an Array) which shall be excluded. Chris@909: # Chris@909: # Default: [] Chris@909: # Chris@909: # === :include Chris@909: # Chris@909: # One or many symbols (in an array) which shall be included. Chris@909: # Chris@909: # Default: :all, which means all tokens are included. Chris@909: # Chris@909: # Exclusion wins over inclusion. Chris@909: # Chris@909: # See also: CommentFilter Chris@909: class TokenKindFilter < Filter Chris@909: Chris@909: register_for :token_kind_filter Chris@909: Chris@909: DEFAULT_OPTIONS = { Chris@909: :exclude => [], Chris@909: :include => :all Chris@909: } Chris@909: Chris@909: protected Chris@909: def setup options Chris@909: super Chris@909: Chris@909: @group_excluded = false Chris@909: @exclude = options[:exclude] Chris@909: @exclude = Array(@exclude) unless @exclude == :all Chris@909: @include = options[:include] Chris@909: @include = Array(@include) unless @include == :all Chris@909: end Chris@909: Chris@909: def include_text_token? text, kind Chris@909: include_group? kind Chris@909: end Chris@909: Chris@909: def include_group? kind Chris@909: (@include == :all || @include.include?(kind)) && Chris@909: !(@exclude == :all || @exclude.include?(kind)) Chris@909: end Chris@909: Chris@909: public Chris@909: Chris@909: # Add the token to the output stream if +kind+ matches the conditions. Chris@909: def text_token text, kind Chris@909: super if !@group_excluded && include_text_token?(text, kind) Chris@909: end Chris@909: Chris@909: # Add the token group to the output stream if +kind+ matches the Chris@909: # conditions. Chris@909: # Chris@909: # If it does not, all tokens inside the group are excluded from the Chris@909: # stream, even if their kinds match. Chris@909: def begin_group kind Chris@909: if @group_excluded Chris@909: @group_excluded += 1 Chris@909: elsif include_group? kind Chris@909: super Chris@909: else Chris@909: @group_excluded = 1 Chris@909: end Chris@909: end Chris@909: Chris@909: # See +begin_group+. Chris@909: def begin_line kind Chris@909: if @group_excluded Chris@909: @group_excluded += 1 Chris@909: elsif include_group? kind Chris@909: super Chris@909: else Chris@909: @group_excluded = 1 Chris@909: end Chris@909: end Chris@909: Chris@909: # Take care of re-enabling the delegation of tokens to the output stream Chris@909: # if an exluded group has ended. Chris@909: def end_group kind Chris@909: if @group_excluded Chris@909: @group_excluded -= 1 Chris@909: @group_excluded = false if @group_excluded.zero? Chris@909: else Chris@909: super Chris@909: end Chris@909: end Chris@909: Chris@909: # See +end_group+. Chris@909: def end_line kind Chris@909: if @group_excluded Chris@909: @group_excluded -= 1 Chris@909: @group_excluded = false if @group_excluded.zero? Chris@909: else Chris@909: super Chris@909: end Chris@909: end Chris@909: Chris@909: end Chris@909: Chris@909: end Chris@909: end