js_regex-3.7.0/0000755000004100000410000000000014030277010013351 5ustar www-datawww-datajs_regex-3.7.0/lib/0000755000004100000410000000000014030277010014117 5ustar www-datawww-datajs_regex-3.7.0/lib/js_regex.rb0000644000004100000410000000210214030277010016245 0ustar www-datawww-data# 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', 'error') 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.empty? ? '(?:)' : source}/#{options}" end def self.new!(ruby_regex, options: nil) js_regex = new(ruby_regex, options: options) if js_regex.warnings.any? raise StandardError.new( "Could not fully convert the given regex #{ruby_regex.inspect}:\n" + js_regex.warnings.join("\n") ).extend(JsRegex::Error) end js_regex end end js_regex-3.7.0/lib/js_regex/0000755000004100000410000000000014030277010015725 5ustar www-datawww-datajs_regex-3.7.0/lib/js_regex/second_pass.rb0000644000004100000410000000703614030277010020561 0ustar www-datawww-dataclass JsRegex # # After conversion of a full Regexp::Expression tree, this # checks for Node instances that need further processing. # module SecondPass class << self def call(tree) alternate_conditional_permutations(tree) tree end private def alternate_conditional_permutations(tree) permutations = conditional_tree_permutations(tree) return if permutations.empty? alternatives = permutations.map.with_index do |variant, i| Node.new((i.zero? ? '(?:' : '|(?:'), variant, ')') end tree.update(children: alternatives) end def conditional_tree_permutations(tree) all_conds = conditions(tree) return [] if all_conds.empty? caps_per_branch = captured_group_count(tree) condition_permutations(all_conds).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| build_permutation(node, all_conds, truthy_conds, caps_per_branch, i) end end end def crawl(node, &block) return if node.instance_of?(String) yield(node) node.children.each { |child| crawl(child, &block) } 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) (0..(conditions.length)).inject([]) do |arr, n| arr + conditions.combination(n).to_a end end def build_permutation(node, all_conds, truthy_conds, caps_per_branch, i) truthy = truthy_conds.include?(node.reference) if node.type.equal?(:captured_group) && all_conds.include?(node.reference) adapt_referenced_group_to_permutation(node, truthy) elsif node.type.equal?(:conditional) adapt_conditional_to_permutation(node, truthy) elsif node.type.equal?(:backref_num) adapt_backref_to_permutation(node, caps_per_branch, i) end end def adapt_referenced_group_to_permutation(group_node, truthy) truthy ? min_quantify(group_node) : null_quantify(group_node) end def adapt_conditional_to_permutation(conditional_node, truthy) branches = conditional_node.children[1...-1] if branches.count == 1 truthy || null_quantify(branches.first) else null_quantify(truthy ? branches.last : branches.first) end conditional_node.update(type: :plain) end def adapt_backref_to_permutation(backref_node, caps_per_branch, i) new_num = backref_node.children[0].to_i + caps_per_branch * i backref_node.update(children: [new_num.to_s]) end def min_quantify(node) return if guarantees_at_least_one_match?(qtf = node.quantifier) 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 guarantees_at_least_one_match?(quantifier) quantifier.nil? || quantifier.min > 0 end def null_quantify(node) node.update(quantifier: '{0}') end end end end js_regex-3.7.0/lib/js_regex/version.rb0000644000004100000410000000004614030277010017737 0ustar www-datawww-dataclass JsRegex VERSION = '3.7.0' end js_regex-3.7.0/lib/js_regex/conversion.rb0000644000004100000410000000232614030277010020442 0ustar www-datawww-dataclass 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 'error' require_relative 'node' require_relative 'second_pass' class << self def of(input, options: nil) source, warnings = convert_source(input) options_string = convert_options(input, options) [source, options_string, warnings] end private def convert_source(input) tree = Regexp::Parser.parse(input) 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] rescue Regexp::Parser::Error => e raise e.extend(JsRegex::Error) end def convert_options(input, custom_options) options = custom_options.to_s.scan(/[gimuy]/) if input.is_a?(Regexp) && (input.options & Regexp::IGNORECASE).nonzero? options << 'i' end options.uniq.sort.join end end end end js_regex-3.7.0/lib/js_regex/converter/0000755000004100000410000000000014030277010017734 5ustar www-datawww-datajs_regex-3.7.0/lib/js_regex/converter/unsupported_token_converter.rb0000644000004100000410000000042014030277010026134 0ustar www-datawww-datarequire_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.7.0/lib/js_regex/converter/escape_converter.rb0000644000004100000410000000303014030277010023604 0ustar www-datawww-datarequire_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(expression.char) 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.7.0/lib/js_regex/converter/property_converter.rb0000644000004100000410000000142714030277010024240 0ustar www-datawww-datarequire_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_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 property') end content.to_s_with_surrogate_ranges end end end end js_regex-3.7.0/lib/js_regex/converter/group_converter.rb0000644000004100000410000000465214030277010023513 0ustar www-datawww-datarequire_relative 'base' class JsRegex module Converter # # Template class implementation. # class GroupConverter < JsRegex::Converter::Base private def convert_data case subtype when :capture, :named then build_group when :atomic then emulate_atomic_group when :comment then drop_without_warning when :options, :options_switch then build_options_group when :passive then build_passive_group when :absence then build_absence_group_if_simple 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_options_group 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_absence_group_if_simple if unmatchable_absence_group? unmatchable_substitution elsif expression.inner_match_length.fixed? build_absence_group else warn_of_unsupported_feature('variable-length absence group content') end end def unmatchable_absence_group? expression.empty? end def unmatchable_substitution '(?!)' end def build_absence_group head = "(?:(?:.|\\n){,#{expression.inner_match_length.min - 1}}|(?:(?!" tail = ')(?:.|\n))*)' build_group(head: head, tail: tail, 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] || '(' tail = opts[:tail] || ')' return Node.new(*wrap(head, tail)) if opts[:capturing].equal?(false) context.capture_group ref = expression.number Node.new(*wrap(head, tail), reference: ref, type: :captured_group) end def wrap(head, tail) [head, convert_subexpressions, tail] end end end end js_regex-3.7.0/lib/js_regex/converter/assertion_converter.rb0000644000004100000410000000115514030277010024361 0ustar www-datawww-datarequire_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(head: pass_through, capturing: false) when :nlookbehind warn_of_unsupported_feature('negative lookbehind assertion') else # :lookbehind, ... build_unsupported_group end end end end end js_regex-3.7.0/lib/js_regex/converter/meta_converter.rb0000644000004100000410000000204414030277010023276 0ustar www-datawww-datarequire_relative 'base' class JsRegex module Converter # # Template class implementation. # class MetaConverter < JsRegex::Converter::Base DOT_EXPANSION = '(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\n\uD800-\uDFFF])' ML_DOT_EXPANSION = '(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF])' private def convert_data case subtype when :alternation convert_alternatives when :dot expression.multiline? ? ML_DOT_EXPANSION : DOT_EXPANSION else warn_of_unsupported_feature end end def convert_alternatives kept_any_previous_branch = nil convert_subexpressions.transform do |node| unless dropped_branch?(node) node.children.unshift('|') if kept_any_previous_branch kept_any_previous_branch = true end node end end def dropped_branch?(branch_node) branch_node.children.any? && branch_node.children.all?(&:dropped?) end end end end js_regex-3.7.0/lib/js_regex/converter/conditional_converter.rb0000644000004100000410000000122514030277010024653 0ustar www-datawww-datarequire_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 else warn_of_unsupported_feature end end def mark_conditional reference = expression.referenced_expression.number 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.7.0/lib/js_regex/converter/base.rb0000644000004100000410000000401614030277010021174 0ustar www-datawww-dataclass 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.map { |subexp| convert_expression(subexp) }) 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_of("Dropped unsupported #{full_desc} at index #{expression.ts}") drop end def warn_of(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.7.0/lib/js_regex/converter/subexpression_converter.rb0000644000004100000410000000041014030277010025254 0ustar www-datawww-datarequire_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.7.0/lib/js_regex/converter/context.rb0000644000004100000410000000352214030277010021747 0ustar www-datawww-dataclass 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, :warnings def initialize(case_insensitive_root: false) self.added_capturing_groups_after_group = Hash.new(0) self.capturing_group_count = 0 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 private attr_accessor :added_capturing_groups_after_group attr_writer :capturing_group_count, :case_insensitive_root, :in_atomic_group, :warnings def total_added_capturing_groups added_capturing_groups_after_group.values.inject(0, &:+) end end end end js_regex-3.7.0/lib/js_regex/converter/anchor_converter.rb0000644000004100000410000000140014030277010023615 0ustar www-datawww-datarequire_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_of("The anchor '#{boundary}' at index #{expression.ts} "\ 'only works at ASCII word boundaries in JavaScript.') boundary end end end end js_regex-3.7.0/lib/js_regex/converter/freespace_converter.rb0000644000004100000410000000040214030277010024301 0ustar www-datawww-datarequire_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.7.0/lib/js_regex/converter/type_converter.rb0000644000004100000410000000303514030277010023332 0ustar www-datawww-datarequire_relative 'base' class JsRegex module Converter # # Template class implementation. # class TypeConverter < JsRegex::Converter::Base HEX_EXPANSION = '[0-9A-Fa-f]' NONHEX_EXPANSION = '[^0-9A-Fa-f]' LINEBREAK_EXPANSION = '(?:\r\n|[\n\v\f\r\u0085\u2028\u2029])' def self.directly_compatible?(expression) case expression.token when :space, :nonspace !expression.ascii_classes? when :digit, :nondigit, :word, :nonword !expression.unicode_classes? end end private def convert_data case subtype when :hex then HEX_EXPANSION when :nonhex then NONHEX_EXPANSION when :linebreak then LINEBREAK_EXPANSION when :digit, :space, :word return pass_through if self.class.directly_compatible?(expression) set_substitution when :nondigit, :nonspace, :nonword return pass_through if self.class.directly_compatible?(expression) negative_set_substitution else warn_of_unsupported_feature end end def negative_set_substitution # ::of_expression returns an inverted set for negative expressions, # so we need to un-invert before wrapping in [^ and ]. Kinda lame. "[^#{character_set.inversion.bmp_part}]" end def set_substitution character_set.bmp_part.to_s(in_brackets: true) end def character_set CharacterSet.of_expression(expression) end end end end js_regex-3.7.0/lib/js_regex/converter/backreference_converter.rb0000644000004100000410000000212514030277010025127 0ustar www-datawww-datarequire_relative 'base' class JsRegex module Converter # # Template class implementation. # class BackreferenceConverter < JsRegex::Converter::Base private def convert_data case subtype when :name_ref, :number, :number_ref, :number_rel_ref then convert_ref when :name_call, :number_call, :number_rel_call then convert_call else # name_recursion_ref, number_recursion_ref, ... warn_of_unsupported_feature end end def convert_ref position = context.new_capturing_group_position(target_position) Node.new('\\', Node.new(position.to_s, type: :backref_num)) end def target_position expression.referenced_expression.number end def convert_call if expression.respond_to?(:number) && expression.number.equal?(0) return warn_of_unsupported_feature('whole-pattern recursion') end context.increment_local_capturing_group_count convert_expression(expression.referenced_expression.unquantified_clone) end end end end js_regex-3.7.0/lib/js_regex/converter/literal_converter.rb0000644000004100000410000000361414030277010024010 0ustar www-datawww-datarequire_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 convert_astral_data(data) else escape_incompatible_bmp_literals(data) end end def convert_astral_data(data) data.each_char.each_with_object(Node.new) do |char, node| if char =~ ASTRAL_PLANE_CODEPOINT_PATTERN node << surrogate_substitution_for(char) else node << escape_incompatible_bmp_literals(char) end end end def escape_incompatible_bmp_literals(data) data.gsub('/', '\\/').gsub(/[\f\n\r\t]/) { |lit| Regexp.escape(lit) } end private def surrogate_substitution_for(char) CharacterSet::Writer.write_surrogate_ranges([], [char.codepoints]) 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) literal =~ HAS_CASE_PATTERN ? case_insensitivize(literal) : literal end def case_insensitivize(literal) 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.7.0/lib/js_regex/converter/set_converter.rb0000644000004100000410000000406414030277010023147 0ustar www-datawww-datarequire_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 return pass_through_with_escaping if directly_compatible? 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 content.to_s_with_surrogate_ranges end def directly_compatible? all_children_directly_compatible? && !casefolding_needed? end def all_children_directly_compatible? # note that #each_expression is recursive expression.each_expression.all? { |ch| child_directly_compatible?(ch) } end def child_directly_compatible?(exp) case exp.type when :literal # surrogate pair substitution needed if astral exp.text.ord <= 0xFFFF when :set # conversion needed for nested sets, intersections exp.token.equal?(:range) when :type TypeConverter.directly_compatible?(exp) when :escape EscapeConverter::ESCAPES_SHARED_BY_RUBY_AND_JS.include?(exp.token) end end def casefolding_needed? expression.case_insensitive? ^ context.case_insensitive_root end def pass_through_with_escaping string = expression.to_s(:base) LiteralConverter.escape_incompatible_bmp_literals(string) end end end end js_regex-3.7.0/lib/js_regex/error.rb0000644000004100000410000000021714030277010017403 0ustar www-datawww-dataclass JsRegex # This is mixed into errors, e.g. those thrown by the parser, # allowing to `rescue JsRegex::Error`. module Error; end end js_regex-3.7.0/lib/js_regex/node.rb0000644000004100000410000000307314030277010017202 0ustar www-datawww-dataclass 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 require_relative 'error' attr_reader :children, :quantifier, :reference, :type TYPES = %i[ backref_num captured_group conditional dropped plain ].freeze def initialize(*children, reference: nil, type: :plain) self.children = children self.reference = reference self.type = type end def initialize_copy(*) self.children = children.map(&:clone) end def transform(&block) children.map!(&block) self 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.new( "#{type} must be substituted before stringification" ).extend(JsRegex::Error) end end def update(attrs) self.children = attrs.fetch(:children) if attrs.key?(:children) self.quantifier = attrs.fetch(:quantifier) if attrs.key?(:quantifier) self.type = attrs.fetch(:type) if attrs.key?(:type) end private attr_writer :children, :reference, :quantifier, :type end end js_regex-3.7.0/lib/js_regex/converter.rb0000644000004100000410000000212014030277010020254 0ustar www-datawww-dataclass JsRegex module Converter Dir[File.join(__dir__, 'converter', '*.rb')].sort.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 # Legacy method. Remove in v4.0.0. def surrogate_pair_limit=(_arg) warn '#surrogate_pair_limit= is deprecated and has no effect anymore.' end end end end js_regex-3.7.0/js_regex.gemspec0000644000004100000410000000760614030277010016535 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: js_regex 3.7.0 ruby lib Gem::Specification.new do |s| s.name = "js_regex".freeze s.version = "3.7.0" 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 = "2021-03-03" 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/error.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/jaynetics/js_regex".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.1.0".freeze) s.rubygems_version = "2.7.6.2".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.4"]) s.add_development_dependency(%q.freeze, ["~> 0.2.12"]) s.add_development_dependency(%q.freeze, ["~> 1.0"]) s.add_development_dependency(%q.freeze, ["~> 0.3"]) s.add_development_dependency(%q.freeze, ["~> 13.0"]) s.add_runtime_dependency(%q.freeze, ["~> 2.1"]) s.add_runtime_dependency(%q.freeze, ["~> 1.0"]) s.add_development_dependency(%q.freeze, ["~> 3.10"]) s.add_development_dependency(%q.freeze, ["~> 1.8"]) else s.add_dependency(%q.freeze, ["~> 1.4"]) s.add_dependency(%q.freeze, ["~> 0.2.12"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, ["~> 0.3"]) s.add_dependency(%q.freeze, ["~> 13.0"]) s.add_dependency(%q.freeze, ["~> 2.1"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, ["~> 3.10"]) s.add_dependency(%q.freeze, ["~> 1.8"]) end else s.add_dependency(%q.freeze, ["~> 1.4"]) s.add_dependency(%q.freeze, ["~> 0.2.12"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, ["~> 0.3"]) s.add_dependency(%q.freeze, ["~> 13.0"]) s.add_dependency(%q.freeze, ["~> 2.1"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, ["~> 3.10"]) s.add_dependency(%q.freeze, ["~> 1.8"]) end end