diff --git a/lib/haml/parser.rb b/lib/haml/parser.rb index 6912f8d7..0a674cec 100644 --- a/lib/haml/parser.rb +++ b/lib/haml/parser.rb @@ -5,9 +5,6 @@ require 'strscan' require 'haml/haml_error' require 'haml/util' -# haml/parser/haml_* are a copy of Haml 5. Most of them should be removed. -require 'haml/parser/haml_options' - module Haml class Parser include Haml::Util @@ -99,24 +96,8 @@ module Haml # Used for scanning old attributes, substituting the first '{' METHOD_CALL_PREFIX = 'a(' - # A list of options that are actually used in this parser - AVAILABLE_OPTIONS = %i[ - autoclose - escape_html - filename - line - mime_type - preserve - remove_whitespace - ] - def initialize(options) - @options = HamlOptions.defaults.dup - AVAILABLE_OPTIONS.each do |key| - @options[key] = options[key] - end - @options = HamlOptions.new(@options) - + @options = ParserOptions.new(options) # Record the indent levels of "if" statements to validate the subsequent # elsif and else statements are indented at the appropriate level. @script_level_stack = [] @@ -962,5 +943,44 @@ module Haml end end private_constant :AttributeMerger + + class ParserOptions + # A list of options that are actually used in the parser + AVAILABLE_OPTIONS = %i[ + autoclose + escape_html + filename + line + mime_type + preserve + remove_whitespace + suppress_eval + ].each do |option| + attr_reader option + end + + DEFAULTS = { + autoclose: %w(area base basefont br col command embed frame + hr img input isindex keygen link menuitem meta + param source track wbr), + escape_html: false, + filename: '(haml)', + line: 1, + mime_type: 'text/html', + preserve: %w(textarea pre code), + remove_whitespace: false, + suppress_eval: false, + } + + def initialize(values = {}) + DEFAULTS.each {|k, v| instance_variable_set :"@#{k}", v} + AVAILABLE_OPTIONS.each do |key| + if values.key?(key) + instance_variable_set :"@#{key}", values[key] + end + end + end + end + private_constant :ParserOptions end end diff --git a/lib/haml/parser/haml_options.rb b/lib/haml/parser/haml_options.rb deleted file mode 100644 index 440f9446..00000000 --- a/lib/haml/parser/haml_options.rb +++ /dev/null @@ -1,290 +0,0 @@ -# frozen_string_literal: true - -module Haml - # This class encapsulates all of the configuration options that Haml - # understands. Please see the {file:REFERENCE.md#options Haml Reference} to - # learn how to set the options. - class HamlOptions - @valid_formats = [:html4, :html5, :xhtml] - @buffer_option_keys = [:autoclose, :preserve, :attr_wrapper, :format, - :encoding, :escape_html, :escape_filter_interpolations, :escape_attrs, :hyphenate_data_attrs, :cdata] - - DEFAULTS = { - attr_wrapper: "'", - autoclose: %w(area base basefont br col command embed frame - hr img input isindex keygen link menuitem meta - param source track wbr), - encoding: nil, - escape_attrs: true, - escape_html: false, - escape_filter_interpolations: nil, - filename: '(haml)', - format: :html5, - hyphenate_data_attrs: true, - line: 1, - mime_type: 'text/html', - preserve: %w(textarea pre code), - remove_whitespace: false, - suppress_eval: false, - cdata: false, - trace: false, - filters: {}, - } - private_constant :DEFAULTS - - class << self - # The default option values. - # @return Hash - def defaults - @defaults ||= DEFAULTS.merge(encoding: 'UTF-8') - end - - # An array of valid values for the `:format` option. - # @return Array - attr_reader :valid_formats - - # An array of keys that will be used to provide a hash of options to - # {Haml::HamlBuffer}. - # @return Hash - attr_reader :buffer_option_keys - - # Returns a subset of defaults: those that {Haml::HamlBuffer} cares about. - # @return [{Symbol => Object}] The options hash - def buffer_defaults - @buffer_defaults ||= buffer_option_keys.inject({}) do |hash, key| - hash.merge(key => defaults[key]) - end - end - - def wrap(options) - if options.is_a?(HamlOptions) - options - else - HamlOptions.new(options) - end - end - end - - # The character that should wrap element attributes. This defaults to `'` - # (an apostrophe). Characters of this type within the attributes will be - # escaped (e.g. by replacing them with `'`) if the character is an - # apostrophe or a quotation mark. - attr_reader :attr_wrapper - - # A list of tag names that should be automatically self-closed if they have - # no content. This can also contain regular expressions that match tag names - # (or any object which responds to `#===`). Defaults to `['meta', 'img', - # 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base']`. - attr_accessor :autoclose - - # The encoding to use for the HTML output. - # This can be a string or an `Encoding` Object. Note that Haml **does not** - # automatically re-encode Ruby values; any strings coming from outside the - # application should be converted before being passed into the Haml - # template. Defaults to `Encoding.default_internal`; if that's not set, - # defaults to the encoding of the Haml template; if that's `US-ASCII`, - # defaults to `"UTF-8"`. - attr_reader :encoding - - # Sets whether or not to escape HTML-sensitive characters in attributes. If - # this is true, all HTML-sensitive characters in attributes are escaped. If - # it's set to false, no HTML-sensitive characters in attributes are escaped. - # If it's set to `:once`, existing HTML escape sequences are preserved, but - # other HTML-sensitive characters are escaped. - # - # Defaults to `true`. - attr_accessor :escape_attrs - - # Sets whether or not to escape HTML-sensitive characters in script. If this - # is true, `=` behaves like {file:REFERENCE.md#escaping_html `&=`}; - # otherwise, it behaves like {file:REFERENCE.md#unescaping_html `!=`}. Note - # that if this is set, `!=` should be used for yielding to subtemplates and - # rendering partials. See also {file:REFERENCE.md#escaping_html Escaping HTML} and - # {file:REFERENCE.md#unescaping_html Unescaping HTML}. - # - # Defaults to false. - attr_accessor :escape_html - - # Sets whether or not to escape HTML-sensitive characters in interpolated strings. - # See also {file:REFERENCE.md#escaping_html Escaping HTML} and - # {file:REFERENCE.md#unescaping_html Unescaping HTML}. - # - # Defaults to the current value of `escape_html`. - attr_accessor :escape_filter_interpolations - - # The name of the Haml file being parsed. - # This is only used as information when exceptions are raised. This is - # automatically assigned when working through ActionView, so it's really - # only useful for the user to assign when dealing with Haml programatically. - attr_accessor :filename - - # If set to `true`, Haml will convert underscores to hyphens in all - # {file:REFERENCE.md#html5_custom_data_attributes Custom Data Attributes} As - # of Haml 4.0, this defaults to `true`. - attr_accessor :hyphenate_data_attrs - - # The line offset of the Haml template being parsed. This is useful for - # inline templates, similar to the last argument to `Kernel#eval`. - attr_accessor :line - - # Determines the output format. The default is `:html5`. The other options - # are `:html4` and `:xhtml`. If the output is set to XHTML, then Haml - # automatically generates self-closing tags and wraps the output of the - # Javascript and CSS-like filters inside CDATA. When the output is set to - # `:html5` or `:html4`, XML prologs are ignored. In all cases, an appropriate - # doctype is generated from `!!!`. - # - # If the mime_type of the template being rendered is `text/xml` then a - # format of `:xhtml` will be used even if the global output format is set to - # `:html4` or `:html5`. - attr :format - - # The mime type that the rendered document will be served with. If this is - # set to `text/xml` then the format will be overridden to `:xhtml` even if - # it has set to `:html4` or `:html5`. - attr_accessor :mime_type - - # A list of tag names that should automatically have their newlines - # preserved using the {Haml::HamlHelpers#preserve} helper. This means that any - # content given on the same line as the tag will be preserved. For example, - # `%textarea= "Foo\nBar"` compiles to ``. - # Defaults to `['textarea', 'pre']`. See also - # {file:REFERENCE.md#whitespace_preservation Whitespace Preservation}. - attr_accessor :preserve - - # If set to `true`, all tags are treated as if both - # {file:REFERENCE.md#whitespace_removal__and_ whitespace removal} options - # were present. Use with caution as this may cause whitespace-related - # formatting errors. - # - # Defaults to `false`. - attr_accessor :remove_whitespace - - # Whether or not attribute hashes and Ruby scripts designated by `=` or `~` - # should be evaluated. If this is `true`, said scripts are rendered as empty - # strings. - # - # Defaults to `false`. - attr_accessor :suppress_eval - - # Whether to include CDATA sections around javascript and css blocks when - # using the `:javascript` or `:css` filters. - # - # This option also affects the `:sass`, `:scss`, `:less` and `:coffeescript` - # filters. - # - # Defaults to `false` for html, `true` for xhtml. Cannot be changed when using - # xhtml. - attr_accessor :cdata - - # Enable template tracing. If true, it will add a 'data-trace' attribute to - # each tag generated by Haml. The value of the attribute will be the - # source template name and the line number from which the tag was generated, - # separated by a colon. On Rails applications, the path given will be a - # relative path as from the views directory. On non-Rails applications, - # the path will be the full path. - attr_accessor :trace - - # Key is filter name in String and value is Class to use. Defaults to {}. - attr_accessor :filters - - def initialize(values = {}) - defaults.each {|k, v| instance_variable_set :"@#{k}", v} - values.each {|k, v| send("#{k}=", v) if defaults.has_key?(k) && !v.nil?} - yield if block_given? - end - - # Retrieve an option value. - # @param key The value to retrieve. - def [](key) - send key - end - - # Set an option value. - # @param key The key to set. - # @param value The value to set for the key. - def []=(key, value) - send "#{key}=", value - end - - [:escape_attrs, :hyphenate_data_attrs, :remove_whitespace, :suppress_eval].each do |method| - class_eval(<<-END) - def #{method}? - !! @#{method} - end - END - end - - # @return [Boolean] Whether or not the format is XHTML. - def xhtml? - not html? - end - - # @return [Boolean] Whether or not the format is any flavor of HTML. - def html? - html4? or html5? - end - - # @return [Boolean] Whether or not the format is HTML4. - def html4? - format == :html4 - end - - # @return [Boolean] Whether or not the format is HTML5. - def html5? - format == :html5 - end - - def attr_wrapper=(value) - @attr_wrapper = value || self.class.defaults[:attr_wrapper] - end - - # Undef :format to suppress warning. It's defined above with the `:attr` - # macro in order to make it appear in Yard's list of instance attributes. - undef :format - def format - mime_type == "text/xml" ? :xhtml : @format - end - - def format=(value) - unless self.class.valid_formats.include?(value) - raise Haml::HamlError, "Invalid output format #{value.inspect}" - end - @format = value - end - - undef :cdata - def cdata - xhtml? || @cdata - end - - def encoding=(value) - return unless value - @encoding = value.is_a?(Encoding) ? value.name : value.to_s - @encoding = "UTF-8" if @encoding.upcase == "US-ASCII" - end - - # Returns a non-default subset of options: those that {Haml::HamlBuffer} cares about. - # All of the values here are such that when `#inspect` is called on the hash, - # it can be `Kernel#eval`ed to get the same result back. - # - # See {file:REFERENCE.md#options the Haml options documentation}. - # - # @return [{Symbol => Object}] The options hash - def for_buffer - self.class.buffer_option_keys.inject({}) do |hash, key| - value = public_send(key) - if self.class.buffer_defaults[key] != value - hash[key] = value - end - hash - end - end - - private - - def defaults - self.class.defaults - end - end -end