js-regex-3.1.1/0000755000175100017510000000000013372265131012271 5ustar pravipravijs-regex-3.1.1/lib/0000755000175100017510000000000013372265131013037 5ustar pravipravijs-regex-3.1.1/lib/js_regex/0000755000175100017510000000000013372265131014645 5ustar pravipravijs-regex-3.1.1/lib/js_regex/node.rb0000644000175100017510000000336313372265131016124 0ustar pravipravi# frozen_string_literal: true class JsRegex # # Converter#convert result. Represents a branch or leaf node with an optional # quantifier as well as type and reference annotations for SecondPass. # class Node attr_reader :children, :quantifier, :reference, :type TYPES = %i[ backref_num captured_group conditional dropped plain subexp_call ] def initialize(*children, quantifier: nil, reference: nil, type: :plain) raise ArgumentError, "bad type #{type}" unless TYPES.include?(type) self.children = children self.quantifier = quantifier self.reference = reference self.type = type end def initialize_copy(orig) super self.children = orig.children.map(&:clone) self.quantifier = orig.quantifier && orig.quantifier.clone end def map(&block) clone.tap { |node| node.children.replace(children.map(&block)) } end def <<(node) children << node self end def dropped? # keep everything else, including empty or depleted capturing groups # so as not to not mess with reference numbers (e.g. backrefs) type.equal?(:dropped) end def to_s case type when :dropped '' when :backref_num, :captured_group, :plain children.join << quantifier.to_s else raise TypeError, "#{type} must be substituted before stringification" end end def update(attrs) self.children = attrs[:children] if attrs.key?(:children) self.quantifier = attrs[:quantifier] if attrs.key?(:quantifier) self.type = attrs[:type] if attrs.key?(:type) end private attr_writer :children, :reference, :quantifier, :type end end js-regex-3.1.1/lib/js_regex/converter/0000755000175100017510000000000013372265131016654 5ustar pravipravijs-regex-3.1.1/lib/js_regex/converter/subexpression_converter.rb0000644000175100017510000000044713372265131024206 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class SubexpressionConverter < JsRegex::Converter::Base private def convert_data convert_subexpressions end end end end js-regex-3.1.1/lib/js_regex/converter/unsupported_token_converter.rb0000644000175100017510000000045713372265131025066 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class UnsupportedTokenConverter < JsRegex::Converter::Base private def convert_data warn_of_unsupported_feature end end end end js-regex-3.1.1/lib/js_regex/converter/group_converter.rb0000644000175100017510000000436113372265131022430 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class GroupConverter < JsRegex::Converter::Base private def convert_data case subtype when :atomic then emulate_atomic_group when :capture then build_group when :comment then drop_without_warning when :named then build_named_group when :options, :options_switch then build_options_group when :passive then build_passive_group when :absence then warn_of_unsupported_feature else build_unsupported_group end end def emulate_atomic_group if context.in_atomic_group build_unsupported_group('nested atomic group') else context.start_atomic_group result = wrap_in_backrefed_lookahead(convert_subexpressions) context.end_atomic_group result end end def build_named_group # remember position, then drop name part without warning context.store_named_group_position(expression.name) build_group(head: '(', reference: expression.name) end def build_options_group unless (encoding_options = data.scan(/[adu]/)).empty? warn_of_unsupported_feature("encoding options #{encoding_options}") end if subtype.equal?(:options_switch) # can be ignored since #options on subsequent Expressions are correct drop_without_warning else build_passive_group end end def build_passive_group build_group(head: '(?:', capturing: false) end def build_unsupported_group(description = nil) warn_of_unsupported_feature(description) build_passive_group end def build_group(opts = {}) head = opts[:head] || pass_through if opts[:capturing].equal?(false) return Node.new(*group_with_head(head)) end context.capture_group ref = opts[:reference] || expression.number Node.new(*group_with_head(head), reference: ref, type: :captured_group) end def group_with_head(head) [head, *convert_subexpressions, ')'] end end end end js-regex-3.1.1/lib/js_regex/converter/meta_converter.rb0000644000175100017510000000143413372265131022220 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class MetaConverter < JsRegex::Converter::Base private def convert_data case subtype when :alternation convert_alternatives when :dot expression.multiline? ? '(?:.|\n)' : '.' else warn_of_unsupported_feature end end def convert_alternatives kept_any = false convert_subexpressions.map do |node| dropped = !node.children.empty? && node.children.all?(&:dropped?) node.children.unshift('|') if kept_any.equal?(true) && !dropped kept_any = true unless dropped node end end end end end js-regex-3.1.1/lib/js_regex/converter/property_converter.rb0000644000175100017510000000245413372265131023161 0ustar pravipravi# frozen_string_literal: true require_relative 'base' require 'character_set' class JsRegex module Converter # # Template class implementation. # # Uses the `character_set` and `regexp_property_values` gems to get the # codepoints matched by the property and build a set string from them. # class PropertyConverter < JsRegex::Converter::Base private def convert_data content = CharacterSet.of_property(subtype) if expression.case_insensitive? && !context.case_insensitive_root content = content.case_insensitive end if expression.negative? if content.astral_part.empty? return "[^#{content.to_s(format: :js)}]" else warn_of_unsupported_feature('astral plane negation by property') end elsif Converter.surrogate_pair_limit.nil? || Converter.surrogate_pair_limit >= content.astral_part.size return content.to_s_with_surrogate_alternation else warn_of_unsupported_feature('large astral plane match of property') end bmp_part = content.bmp_part return drop if bmp_part.empty? string = bmp_part.to_s(format: :js) expression.negative? ? "[^#{string}]" : "[#{string}]" end end end end js-regex-3.1.1/lib/js_regex/converter/backreference_converter.rb0000644000175100017510000000370213372265131024051 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class BackreferenceConverter < JsRegex::Converter::Base private def convert_data case subtype when :name_ref then convert_name_ref when :number, :number_ref then convert_number_ref when :number_rel_ref then convert_number_rel_ref when :name_call then mark_name_call when :number_call then mark_number_call when :number_rel_call then mark_number_rel_call else # name_recursion_ref, number_recursion_ref, ... warn_of_unsupported_feature end end def convert_name_ref convert_ref(context.named_group_positions.fetch(expression.name)) end def convert_number_ref convert_ref(context.new_capturing_group_position(expression.number)) end def convert_number_rel_ref convert_ref(context.new_capturing_group_position(absolute_position)) end def convert_ref(position) Node.new('\\', Node.new(position.to_s, type: :backref_num)) end def absolute_position expression.number + context.original_capturing_group_count + 1 end def mark_name_call mark_call(expression.name) end def mark_number_call if expression.number.equal?(0) return warn_of_unsupported_feature('whole-pattern recursion') end mark_call(expression.number) end def mark_number_rel_call is_forward_referring = data.include?('+') # e.g. \g<+2> mark_call(absolute_position - (is_forward_referring ? 1 : 0)) end def mark_call(reference) # increment group count as calls will be substituted with groups context.increment_local_capturing_group_count Node.new(reference: reference, type: :subexp_call) end end end end js-regex-3.1.1/lib/js_regex/converter/anchor_converter.rb0000644000175100017510000000150713372265131022545 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class AnchorConverter < JsRegex::Converter::Base private def convert_data case subtype when :bol, :bos then '^' when :eol, :eos then '$' when :eos_ob_eol then '(?=\n?$)' when :word_boundary then pass_boundary_with_warning('\b') when :nonword_boundary then pass_boundary_with_warning('\B') else warn_of_unsupported_feature end end def pass_boundary_with_warning(boundary) warn("The boundary '#{boundary}' at index #{expression.ts} "\ 'is not unicode-aware in JavaScript, '\ 'so it might act differently than in Ruby.') boundary end end end end js-regex-3.1.1/lib/js_regex/converter/escape_converter.rb0000644000175100017510000000305413372265131022532 0ustar pravipravi# frozen_string_literal: true require_relative 'base' require_relative 'literal_converter' class JsRegex module Converter # # Template class implementation. # class EscapeConverter < JsRegex::Converter::Base ESCAPES_SHARED_BY_RUBY_AND_JS = %i[ alternation backslash backspace bol carriage codepoint dot eol form_feed group_close group_open hex interval_close interval_open newline octal one_or_more set_close set_open tab vertical_tab zero_or_more zero_or_one ].freeze private def convert_data case subtype when :codepoint_list convert_codepoint_list when :control, :meta_sequence unicode_escape_codepoint when :literal LiteralConverter.convert_data(data) when *ESCAPES_SHARED_BY_RUBY_AND_JS pass_through when :bell, :escape hex_escape_codepoint else warn_of_unsupported_feature end end def convert_codepoint_list expression.chars.each_with_object(Node.new) do |char, node| node << LiteralConverter.convert_data(Regexp.escape(char)) end end def unicode_escape_codepoint "\\u#{expression.codepoint.to_s(16).upcase.rjust(4, '0')}" end def hex_escape_codepoint "\\x#{expression.codepoint.to_s(16).upcase.rjust(2, '0')}" end end end end js-regex-3.1.1/lib/js_regex/converter/conditional_converter.rb0000644000175100017510000000135013372265131023572 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class ConditionalConverter < JsRegex::Converter::Base private def convert_data case subtype when :open then mark_conditional when :condition then drop_without_warning else warn_of_unsupported_feature end end def mark_conditional reference = expression.reference node = Node.new('(?:', reference: reference, type: :conditional) expression.branches.each do |branch| node << Node.new('(?:', convert_expression(branch), ')') end node << ')' end end end end js-regex-3.1.1/lib/js_regex/converter/assertion_converter.rb0000644000175100017510000000117013372265131023276 0ustar pravipravi# frozen_string_literal: true require_relative 'base' require_relative 'group_converter' class JsRegex module Converter # # Template class implementation. # # Note the inheritance from GroupConverter. # class AssertionConverter < JsRegex::Converter::GroupConverter private def convert_data case subtype when :lookahead, :nlookahead build_group(capturing: false) when :nlookbehind warn_of_unsupported_feature('negative lookbehind assertion') else # :lookbehind, ... build_unsupported_group end end end end end js-regex-3.1.1/lib/js_regex/converter/base.rb0000644000175100017510000000405713372265131020121 0ustar pravipravi# frozen_string_literal: true class JsRegex module Converter # # Template class. Implement #convert_data in subclasses and return # instance of String or Node from it. # class Base # returns instance of Node with #quantifier attached. def convert(expression, context) self.context = context self.expression = expression node = convert_data node = Node.new(node) if node.instance_of?(String) apply_quantifier(node) end private attr_accessor :context, :expression def subtype expression.token end def data expression.text end alias pass_through data def apply_quantifier(node) return node if node.dropped? || (qtf = expression.quantifier).nil? if qtf.possessive? node.update(quantifier: qtf.text[0..-2]) return wrap_in_backrefed_lookahead([node]) else node.update(quantifier: qtf) end node end def convert_subexpressions Node.new(*expression.expressions.map { |exp| convert_expression(exp) }) end def convert_expression(expression) Converter.convert(expression, context) end def warn_of_unsupported_feature(description = nil) description ||= "#{subtype} #{expression.type}".tr('_', ' ') full_desc = "#{description} '#{expression}'" warn("Dropped unsupported #{full_desc} at index #{expression.ts}") drop end def warn(text) context.warnings << text end def drop Node.new(type: :dropped) end alias drop_without_warning drop def wrap_in_backrefed_lookahead(content) backref_num = context.capturing_group_count + 1 backref_num_node = Node.new(backref_num.to_s, type: :backref_num) context.increment_local_capturing_group_count # an empty passive group (?:) is appended as literal digits may follow Node.new('(?=(', *content, '))\\', backref_num_node, '(?:)') end end end end js-regex-3.1.1/lib/js_regex/converter/freespace_converter.rb0000644000175100017510000000044113372265131023224 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class FreespaceConverter < JsRegex::Converter::Base private def convert_data drop_without_warning end end end end js-regex-3.1.1/lib/js_regex/converter/literal_converter.rb0000644000175100017510000000423013372265131022723 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class LiteralConverter < JsRegex::Converter::Base class << self ASTRAL_PLANE_CODEPOINT_PATTERN = /[\u{10000}-\u{FFFFF}]/ def convert_data(data) if data =~ ASTRAL_PLANE_CODEPOINT_PATTERN data.each_char.each_with_object(Node.new) do |chr, node| if chr =~ ASTRAL_PLANE_CODEPOINT_PATTERN node << surrogate_pair_for(chr) else node << convert_bmp_data(chr) end end else convert_bmp_data(data) end end def convert_bmp_data(data) ensure_json_compatibility( ensure_forward_slashes_are_escaped(data) ) end private def surrogate_pair_for(astral_char) base = astral_char.codepoints.first - 65_536 high = ((base / 1024).floor + 55_296).to_s(16) low = (base % 1024 + 56_320).to_s(16) "(?:\\u#{high}\\u#{low})" end def ensure_forward_slashes_are_escaped(data) # literal slashes would signify the pattern end in JsRegex#to_s data.gsub(%r{\\?/}, '\\/') end def ensure_json_compatibility(data) data.gsub(%r{\\?([\f\n\r\t])}) { Regexp.escape($1) } end end private def convert_data result = self.class.convert_data(data) if context.case_insensitive_root && !expression.case_insensitive? warn_of_unsupported_feature('nested case-sensitive literal') elsif !context.case_insensitive_root && expression.case_insensitive? return handle_locally_case_insensitive_literal(result) end result end HAS_CASE_PATTERN = /[\p{lower}\p{upper}]/ def handle_locally_case_insensitive_literal(literal) return literal unless literal =~ HAS_CASE_PATTERN literal.each_char.each_with_object(Node.new) do |chr, node| node << (chr =~ HAS_CASE_PATTERN ? "[#{chr}#{chr.swapcase}]" : chr) end end end end end js-regex-3.1.1/lib/js_regex/converter/set_converter.rb0000644000175100017510000000456713372265131022077 0ustar pravipravi# frozen_string_literal: true require_relative 'base' require_relative 'escape_converter' require_relative 'type_converter' require 'character_set' class JsRegex module Converter # # Template class implementation. # # Unlike other converters, this one does not recurse on subexpressions, # since many are unsupported by JavaScript. If it detects incompatible # children, it uses the `character_set` gem to establish the codepoints # matched by the whole set and build a completely new set string. # class SetConverter < JsRegex::Converter::Base private def convert_data if directly_compatible? return expression.to_s(:base) .gsub(%r{\\?([\f\n\r\t])}) { Regexp.escape($1) } end content = CharacterSet.of_expression(expression) if expression.case_insensitive? && !context.case_insensitive_root content = content.case_insensitive elsif !expression.case_insensitive? && context.case_insensitive_root warn_of_unsupported_feature('nested case-sensitive set') end if Converter.surrogate_pair_limit.nil? || Converter.surrogate_pair_limit >= content.astral_part.size content.to_s_with_surrogate_alternation else warn_of_unsupported_feature('large astral plane match of set') bmp_part = content.bmp_part bmp_part.empty? ? drop : bmp_part.to_s(format: :js, in_brackets: true) end end def directly_compatible? if expression.case_insensitive? && !context.case_insensitive_root # casefolding needed return false end # check for children needing conversion (#each_expression is recursive) expression.each_expression do |node| case node.type when :literal # surrogate pair substitution needed if astral next if node.text.force_encoding('utf-8').ord <= 0xFFFF when :set # conversion needed for nested sets, intersections next if node.token.equal?(:range) when :type next if TypeConverter::TYPES_SHARED_BY_RUBY_AND_JS.include?(node.token) when :escape next if EscapeConverter::ESCAPES_SHARED_BY_RUBY_AND_JS.include?(node.token) end return false end true end end end end js-regex-3.1.1/lib/js_regex/converter/context.rb0000644000175100017510000000414313372265131020667 0ustar pravipravi# frozen_string_literal: true class JsRegex module Converter # # Passed among Converters to globalize basic status data. # # The Converters themselves are stateless. # class Context attr_reader :capturing_group_count, :case_insensitive_root, :in_atomic_group, :named_group_positions, :warnings def initialize(case_insensitive_root: false) self.added_capturing_groups_after_group = Hash.new(0) self.capturing_group_count = 0 self.named_group_positions = {} self.warnings = [] self.case_insensitive_root = case_insensitive_root end # group context def capture_group self.capturing_group_count = capturing_group_count + 1 end def start_atomic_group self.in_atomic_group = true end def end_atomic_group self.in_atomic_group = false end def increment_local_capturing_group_count added_capturing_groups_after_group[original_capturing_group_count] += 1 capture_group end # takes and returns 1-indexed group positions. # new is different from old if capturing groups were added in between. def new_capturing_group_position(old_position) increment = 0 added_capturing_groups_after_group.each do |after_n_groups, count| increment += count if after_n_groups < old_position end old_position + increment end def original_capturing_group_count capturing_group_count - total_added_capturing_groups end def store_named_group_position(name) named_group_positions[name] = capturing_group_count + 1 end private attr_accessor :added_capturing_groups_after_group attr_writer :capturing_group_count, :case_insensitive_root, :in_atomic_group, :named_group_positions, :warnings def total_added_capturing_groups added_capturing_groups_after_group.values.inject(0, &:+) end end end end js-regex-3.1.1/lib/js_regex/converter/type_converter.rb0000644000175100017510000000145313372265131022254 0ustar pravipravi# frozen_string_literal: true require_relative 'base' class JsRegex module Converter # # Template class implementation. # class TypeConverter < JsRegex::Converter::Base TYPES_SHARED_BY_RUBY_AND_JS = %i[ digit nondigit word nonword space nonspace ].freeze HEX_EXPANSION = '[0-9A-Fa-f]' NONHEX_EXPANSION = '[^0-9A-Fa-f]' LINEBREAK_EXPANSION = '(?:\r\n|\r|\n)' private def convert_data case subtype when :hex then HEX_EXPANSION when :nonhex then NONHEX_EXPANSION when :linebreak then LINEBREAK_EXPANSION when *TYPES_SHARED_BY_RUBY_AND_JS pass_through else warn_of_unsupported_feature end end end end end js-regex-3.1.1/lib/js_regex/version.rb0000644000175100017510000000010513372265131016653 0ustar pravipravi# frozen_string_literal: true class JsRegex VERSION = '3.1.1' end js-regex-3.1.1/lib/js_regex/converter.rb0000644000175100017510000000266513372265131017212 0ustar pravipravi# frozen_string_literal: true class JsRegex module Converter Dir[File.join(File.dirname(__FILE__), 'converter', '*.rb')].each do |file| require file end MAP = Hash.new(UnsupportedTokenConverter).merge( anchor: AnchorConverter, assertion: AssertionConverter, backref: BackreferenceConverter, conditional: ConditionalConverter, escape: EscapeConverter, expression: SubexpressionConverter, free_space: FreespaceConverter, group: GroupConverter, literal: LiteralConverter, meta: MetaConverter, nonproperty: PropertyConverter, property: PropertyConverter, set: SetConverter, type: TypeConverter ).freeze class << self def convert(exp, context = nil) self.for(exp).convert(exp, context || Context.new) end def for(expression) MAP[expression.type].new end # Limit the number of generated surrogate pairs, else the output might # get to large for certain applications. The chosen number is somewhat # arbitrary. 100 pairs make for about 1 KB, uncompressed. The median char # count of all properties supported by Ruby is 92. 75% are below 300 chars. # # Set this to nil if you need full unicode matches and size doesn't matter. attr_accessor :surrogate_pair_limit end self.surrogate_pair_limit = 300 end end js-regex-3.1.1/lib/js_regex/conversion.rb0000644000175100017510000000217713372265131017366 0ustar pravipravi# frozen_string_literal: true class JsRegex # # This class acts as a facade, passing a regex to the converters. # # ::of returns a source String, options String, and warnings Array. # class Conversion require 'regexp_parser' require_relative 'converter' require_relative 'node' require_relative 'second_pass' class << self def of(ruby_regex, options: nil) source, warnings = convert_source(ruby_regex) options_string = convert_options(ruby_regex, options) [source, options_string, warnings] end private def convert_source(ruby_regex) tree = Regexp::Parser.parse(ruby_regex) context = Converter::Context.new(case_insensitive_root: tree.i?) converted_tree = Converter.convert(tree, context) final_tree = SecondPass.call(converted_tree) [final_tree.to_s, context.warnings] end def convert_options(ruby_regex, custom_options) options = custom_options.to_s.scan(/[gimuy]/) options << 'i' if (ruby_regex.options & Regexp::IGNORECASE).nonzero? options.uniq.sort.join end end end end js-regex-3.1.1/lib/js_regex/second_pass.rb0000644000175100017510000000711013372265131017472 0ustar pravipravi# frozen_string_literal: true class JsRegex # # After conversion of a full Regexp::Expression tree, this class # checks for Node instances that need further processing. # # E.g. subexpression calls (such as \g<1>) can be look-ahead, # so the full Regexp must have been processed first, and only then can # they be substituted with the conversion result of their targeted group. # module SecondPass module_function def call(tree) substitute_subexp_calls(tree) alternate_conditional_permutations(tree) tree end def substitute_subexp_calls(tree) crawl(tree) do |node| if node.type == :subexp_call called_group = find_group_by_reference(node.reference, in_node: tree) node.update(children: called_group.children, type: :captured_group) end end end def crawl(node, &block) return if node.instance_of?(String) yield(node) node.children.each { |child| crawl(child, &block) } end def alternate_conditional_permutations(tree) permutations = conditional_tree_permutations(tree) return tree if permutations.empty? alternatives = permutations.map.with_index do |variant, i| Node.new((i.zero? ? '(?:' : '|(?:'), variant, ')') end tree.update(children: alternatives) end def find_group_by_reference(ref, in_node: nil) crawl(in_node) do |node| return node if node.type == :captured_group && node.reference == ref end Node.new('()') end def conditional_tree_permutations(tree) all_conditions = conditions(tree) return [] if all_conditions.empty? captured_groups_per_branch = captured_group_count(tree) condition_permutations(all_conditions).map.with_index do |truthy_conds, i| tree_permutation = tree.clone # find referenced groups and conditionals and make one-sided crawl(tree_permutation) do |node| truthy = truthy_conds.include?(node.reference) if node.type.equal?(:captured_group) && all_conditions.include?(node.reference) truthy ? min_quantify(node) : null_quantify(node) elsif node.type.equal?(:conditional) branches = node.children[1...-1] if branches.count == 1 truthy || null_quantify(branches.first) else null_quantify(truthy ? branches.last : branches.first) end node.update(type: :plain) elsif node.type.equal?(:backref_num) new_num = node.children[0].to_i + captured_groups_per_branch * i node.update(children: [new_num.to_s]) end end end end def conditions(tree) conditions = [] crawl(tree) do |node| conditions << node.reference if node.type.equal?(:conditional) end conditions end def captured_group_count(tree) count = 0 crawl(tree) { |node| count += 1 if node.type.equal?(:captured_group)} count end def condition_permutations(conditions) return [] if conditions.empty? condition_permutations = (0..(conditions.length)).inject([]) do |arr, n| arr += conditions.combination(n).to_a end end def min_quantify(node) return if (qtf = node.quantifier).nil? || qtf.min > 0 if qtf.max.equal?(1) # any zero_or_one quantifier (?, ??, ?+) node.update(quantifier: nil) else node.update(quantifier: "{1,#{qtf.max}}#{'?' if qtf.reluctant?}") end end def null_quantify(node) node.update(quantifier: '{0}') end end end js-regex-3.1.1/lib/js_regex.rb0000644000175100017510000000132113372265131015167 0ustar pravipravi# frozen_string_literal: true # JsRegex converts ::Regexp instances to JavaScript. # # Usage: # # js_regex = JsRegex.new(my_ruby_regex) # js_regex.to_h # for use in 'new RegExp()' # js_regex.to_s # for direct injection into JavaScript # class JsRegex require_relative File.join('js_regex', 'conversion') require_relative File.join('js_regex', 'version') require 'json' attr_reader :source, :options, :warnings def initialize(ruby_regex, options: nil) @source, @options, @warnings = Conversion.of(ruby_regex, options: options) end def to_h { source: source, options: options } end def to_json(options = {}) to_h.to_json(options) end def to_s "/#{source}/#{options}" end end js-regex-3.1.1/js_regex.gemspec0000644000175100017510000000735613372265131015457 0ustar pravipravi######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: js_regex 3.1.1 ruby lib Gem::Specification.new do |s| s.name = "js_regex".freeze s.version = "3.1.1" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Janosch M\u00FCller".freeze] s.date = "2018-09-24" s.description = "JsRegex converts Ruby's native regular expressions for JavaScript, taking care of various incompatibilities and returning warnings for unsolvable differences.".freeze s.email = ["janosch84@gmail.com".freeze] s.files = ["lib/js_regex.rb".freeze, "lib/js_regex/conversion.rb".freeze, "lib/js_regex/converter.rb".freeze, "lib/js_regex/converter/anchor_converter.rb".freeze, "lib/js_regex/converter/assertion_converter.rb".freeze, "lib/js_regex/converter/backreference_converter.rb".freeze, "lib/js_regex/converter/base.rb".freeze, "lib/js_regex/converter/conditional_converter.rb".freeze, "lib/js_regex/converter/context.rb".freeze, "lib/js_regex/converter/escape_converter.rb".freeze, "lib/js_regex/converter/freespace_converter.rb".freeze, "lib/js_regex/converter/group_converter.rb".freeze, "lib/js_regex/converter/literal_converter.rb".freeze, "lib/js_regex/converter/meta_converter.rb".freeze, "lib/js_regex/converter/property_converter.rb".freeze, "lib/js_regex/converter/set_converter.rb".freeze, "lib/js_regex/converter/subexpression_converter.rb".freeze, "lib/js_regex/converter/type_converter.rb".freeze, "lib/js_regex/converter/unsupported_token_converter.rb".freeze, "lib/js_regex/node.rb".freeze, "lib/js_regex/second_pass.rb".freeze, "lib/js_regex/version.rb".freeze] s.homepage = "https://github.com/janosch-x/js_regex".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.1.0".freeze) s.rubygems_version = "2.7.6".freeze s.summary = "Converts Ruby regexes to JavaScript regexes.".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q.freeze, ["~> 1.1"]) s.add_development_dependency(%q.freeze, ["~> 12.3"]) s.add_runtime_dependency(%q.freeze, ["~> 1.1"]) s.add_runtime_dependency(%q.freeze, ["~> 0.3"]) s.add_development_dependency(%q.freeze, ["~> 3.8"]) s.add_development_dependency(%q.freeze, ["~> 3.8"]) s.add_development_dependency(%q.freeze, ["~> 3.8"]) s.add_development_dependency(%q.freeze, ["~> 0.12"]) else s.add_dependency(%q.freeze, ["~> 1.1"]) s.add_dependency(%q.freeze, ["~> 12.3"]) s.add_dependency(%q.freeze, ["~> 1.1"]) s.add_dependency(%q.freeze, ["~> 0.3"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 0.12"]) end else s.add_dependency(%q.freeze, ["~> 1.1"]) s.add_dependency(%q.freeze, ["~> 12.3"]) s.add_dependency(%q.freeze, ["~> 1.1"]) s.add_dependency(%q.freeze, ["~> 0.3"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 3.8"]) s.add_dependency(%q.freeze, ["~> 0.12"]) end end