repper 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0889e10cd309dbdd42315e1049c2f7e10a9ab46b949b08c390614965aa2c1483'
4
- data.tar.gz: 8ef2f61c38c6e23abcd933c1e3e462602c19d153824c7632114673b57b291ad5
3
+ metadata.gz: dc27c0c06fc2947ca6485a0cbf9a904e83b959f5e05e5ae98d9441600d24c988
4
+ data.tar.gz: 0a597629326934ec23073f9729fa19eaa9e7f56e8ec11cd4573911039d36f908
5
5
  SHA512:
6
- metadata.gz: a78030f011bb7d74c0263b2e6353114bdd94c9bdd5ee05f36ec7712dd5ad719f23050cea5627fb51cfc8ebe8bdf8b7813ec2094ea163c0253c58996e1fa5997c
7
- data.tar.gz: 28b9f8a9243497e1be1ae2243c81817e2dc566532b314b03b9aa3410a947a9eb50f16b79b9b33a8e76e189c63efbc98b173acf160f814ca9bff2e91deb1d839f
6
+ metadata.gz: 2041d9d7fc5f71e536c123f2274fe1353ba14d6c8b6fc01e63a1f45165618a94bd9268a9dd221eb8348f2c96a4ead548a383940ce986d5c8330ace7860c5f87b
7
+ data.tar.gz: bf2029e67d73116b47484304e20565c150179576d0645982c8433d3608cb8365e6f06860c9e820414c9d71d0abe9f239fb0b7ea97bd77a04b599ecfdac982d50
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [1.0.0] - 2022-04-30
3
+ ## [1.1.1] - 2026-10-23
4
+
5
+ ### Fixed
6
+
7
+ - correct indentation when using newer `regexp_parser` versions
8
+
9
+ ## [1.1.0] - 2022-05-29
10
+
11
+ ### Added
12
+
13
+ - codemod capability and corresponding `exe/repper` executable
14
+ - new format `Repper::Format::Extended`
15
+ - `Regexp#original_inspect` when using `Regexp#inspect` override
16
+
17
+ ### Fixed
18
+
19
+ - use the more appropriate `:inline` format when passing `format: nil | false`
20
+
21
+ ## [1.0.0] - 2022-05-09
4
22
 
5
23
  - Initial release
data/Gemfile CHANGED
@@ -5,6 +5,8 @@ gemspec
5
5
 
6
6
  # gem 'regexp_parser', path: '../regexp_parser'
7
7
 
8
+ gem "irb"
9
+ gem "pry"
8
10
  gem "rake", "~> 13.0"
9
-
10
11
  gem "rspec", "~> 3.0"
12
+ gem "simplecov-cobertura"
data/README.md CHANGED
@@ -1,9 +1,12 @@
1
- <h1>
2
- Repper
3
- <img alt='Rapper necklace with dollar pendant' src='https://user-images.githubusercontent.com/10758879/167485870-5c49284d-a783-453e-8be0-a3597c2ef97c.png' height='46' align='right' />
4
- </h1>
1
+ <img alt='Rapper necklace with dollar pendant' src='https://user-images.githubusercontent.com/10758879/167485870-5c49284d-a783-453e-8be0-a3597c2ef97c.png' height='64' align='right' />
5
2
 
6
- Repper is a regular expression pretty printer for Ruby.
3
+ # Repper
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/repper.svg)](http://badge.fury.io/rb/repper)
6
+ [![Build Status](https://github.com/jaynetics/repper/actions/workflows/main.yml/badge.svg)](https://github.com/jaynetics/repper/actions)
7
+ [![Coverage](https://codecov.io/gh/jaynetics/repper/branch/main/graph/badge.svg?token=4C6EKINE4B)](https://codecov.io/gh/jaynetics/repper)
8
+
9
+ Repper is a regular expression pretty printer and formatter for Ruby.
7
10
 
8
11
  ## Installation
9
12
 
@@ -11,20 +14,28 @@ Repper is a regular expression pretty printer for Ruby.
11
14
 
12
15
  ## Usage
13
16
 
14
- `repper` can be integrated into the REPL (e.g. IRB) through core extensions or used manually.
17
+ `repper` can be integrated into the REPL (e.g. IRB) through core extensions for Regexp pretty-printing, integrated into editors to format Regexps, or called manually.
15
18
 
16
19
  There are also a few customization options.
17
20
 
18
- ### Full REPL integration (recommended)
21
+ ### REPL integration
22
+
23
+ #### Via Regexp#inspect (recommended)
19
24
 
20
25
  `require 'repper/core_ext/regexp'` in your `~/.irbrc` or `~/.pryrc` to override `Regexp#inspect` and automatically use `repper` to display Regexps:
21
26
 
22
- <img width="313" alt="screenshot1" src="https://user-images.githubusercontent.com/10758879/167497359-e5bb94db-1382-465b-903a-3e114721b7a6.png">
27
+ <img width="475" alt="screenshot1" src="https://user-images.githubusercontent.com/10758879/167719748-60f4013a-c8d4-4a62-843a-d9f27057bcd3.png">
23
28
 
24
- ### Extending Kernel#pp
29
+ #### Via Kernel#pp
25
30
 
26
31
  Alternatively, `require 'repper/core_ext/kernel'` to make the `pp` command give nicer output for Regexps (which will look like above by default).
27
32
 
33
+ ### Editor integration
34
+
35
+ Use [vscode-repper](https://github.com/jaynetics/vscode-repper) to format Regexps in VSCode.
36
+
37
+ ![vscode-repper](https://user-images.githubusercontent.com/10758879/170892739-e2f408f2-e239-4b13-8d28-c14fb7a9dbb9.gif)
38
+
28
39
  ### Using Repper manually
29
40
 
30
41
  ```ruby
@@ -36,11 +47,13 @@ Repper.render(/foo/) # returns the pretty print String
36
47
 
37
48
  #### Customizing the format
38
49
 
39
- The default format is the annotated, indented format shown above.
50
+ Multiple formats are available out of the box:
40
51
 
41
- If you want to see the indented structure without annotations, use the `:structured` format.
42
-
43
- If you only want colorization you can use the `:inline` format.
52
+ - `:annotated` is the default, verbose format, shown above
53
+ - `:inline` adds only colorization and does not restructure the Regexp
54
+ - `:structured` is like `:annotated`, just without annotations
55
+ - `:x` (or `:extended`) returns a lightly formatted but equivalent Regexp
56
+ - this format is used for the repper executable and [vscode-repper](https://github.com/jaynetics/vscode-repper)
44
57
 
45
58
  You can change the format globally:
46
59
 
@@ -50,14 +63,14 @@ Repper.format = :structured
50
63
 
51
64
  Or pick a format on a case-by-case basis:
52
65
 
53
- <img width="445" alt="screenshot2" src="https://user-images.githubusercontent.com/10758879/167497599-105f39c7-91e0-4954-bce3-d04ad7266695.png">
66
+ <img width="711" alt="screenshot2" src="https://user-images.githubusercontent.com/10758879/167719567-ae8ee42f-839e-4ce4-af56-a139044d3436.png">
54
67
 
55
68
  Or create your own format:
56
69
 
57
70
  ```ruby
58
71
  require 'csv'
59
72
 
60
- csv_format = ->(elements, _theme) { elements.map(&:text).to_csv }
73
+ csv_format = ->(tokens, _theme) { tokens.map(&:text).to_csv }
61
74
  Repper.render(/re[\p{pe}\r]$/, format: csv_format)
62
75
  => "/,re,[,\\p{pe},\\r,],$,/\n"
63
76
  ```
@@ -69,7 +82,8 @@ The color theme can also be set globally or passed on call:
69
82
  ```ruby
70
83
  Repper.theme = :monokai # a nicer theme, if the terminal supports it
71
84
  ```
72
- <img width="316" alt="screenshot3" src="https://user-images.githubusercontent.com/10758879/167497895-0cdc017f-5c77-4b15-afaa-207f7eb887cc.png">
85
+
86
+ <img width="478" alt="screenshot3" src="https://user-images.githubusercontent.com/10758879/167719807-9170ba92-48d1-4669-a05d-a72f962b961d.png">
73
87
 
74
88
  ```ruby
75
89
  Repper.call(/foo/, theme: nil) # render without colors
data/exe/repper ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/repper"
4
+
5
+ Repper::Command.call(ARGV)
@@ -0,0 +1,70 @@
1
+ module Repper
2
+ # Formatter for Ruby code containing Regexp literals.
3
+ # Takes Ruby code, finds included Regexps (both // and %r style),
4
+ # formats them, and returns the updated Ruby code.
5
+ module Codemod
6
+ module_function
7
+
8
+ def call(code)
9
+ formatted_code = code.dup
10
+
11
+ regexp_locations(code).reverse.each do |loc|
12
+ beg_idx = code[/\A(.*\n){#{loc.beg_line}}/].size + loc.beg_char
13
+ end_idx = code[/\A(.*\n){#{loc.end_line}}/].size + loc.end_char
14
+ range = beg_idx..end_idx
15
+
16
+ /\A(?<start>\/|%r.)(?<source>.*)(?<stop>[^a-z])(?<flags>[a-z]*)\z/m =~
17
+ code[range]
18
+
19
+ tokens = Tokenizer.call(source, delimiters: [start, stop], flags: flags)
20
+ formatted_regexp = Format::Extended.call(tokens, Theme::Plain)
21
+
22
+ # indent consistently by applying leading line indentation to all lines
23
+ lead_indentation = code.lines[loc.beg_line][/^ */]
24
+ formatted_regexp.gsub!("\n", "\n#{lead_indentation}")
25
+
26
+ formatted_code[range] = formatted_regexp
27
+ end
28
+
29
+ formatted_code
30
+ end
31
+
32
+ require 'ripper'
33
+
34
+ def regexp_locations(code)
35
+ embed_level = 0
36
+ beg_tokens = {}
37
+
38
+ Ripper.lex(code).each.with_object([]) do |token, acc|
39
+ case token[1]
40
+ when :on_regexp_beg
41
+ beg_tokens[embed_level] = token
42
+ # nested regexp literals are not supported a.t.m., so if we're
43
+ # in an embed, discard the location of the surrounding regexp.
44
+ beg_tokens[embed_level - 1] = nil
45
+ when :on_regexp_end
46
+ next unless beg_token = beg_tokens[embed_level]
47
+
48
+ acc << Location.new(
49
+ beg_line: beg_token[0][0] - 1, # note: using 0-indexed line values
50
+ beg_char: beg_token[0][1],
51
+ end_line: token[0][0] - 1,
52
+ end_char: token[0][1] + (token[2].length - 1), # lex includes flags
53
+ )
54
+ when :on_embexpr_beg # embedded expression a.k.a. interpolation (#{...})
55
+ embed_level += 1
56
+ when :on_embexpr_end
57
+ embed_level -= 1
58
+ when :on_const, :on_ident
59
+ # OK when embedded - Regexp::Parser will treat them as literals
60
+ else
61
+ # other embedded expressions are not supported
62
+ beg_tokens[embed_level - 1] = nil
63
+ end
64
+ end
65
+ end
66
+
67
+ Location = Struct.new(:beg_line, :beg_char, :end_line, :end_char,
68
+ keyword_init: true)
69
+ end
70
+ end
@@ -0,0 +1,39 @@
1
+ module Repper
2
+ # Service object for exe/repper. Formats Ruby code with Repper::Codemod.
3
+ module Command
4
+ module_function
5
+
6
+ PARSE_ERROR_EXIT_STATUS = 1
7
+
8
+ def call(argv)
9
+ if argv.count == 0
10
+ format_stdio
11
+ else
12
+ format_files(argv)
13
+ end
14
+ end
15
+
16
+ def format_stdio
17
+ input = STDIN.read
18
+ output = format(input)
19
+ print output
20
+ end
21
+
22
+ def format(string)
23
+ Codemod.call(string)
24
+ rescue Repper::Error => e
25
+ warn "Parsing failed: #{e.class} - #{e.message}"
26
+ exit PARSE_ERROR_EXIT_STATUS
27
+ end
28
+
29
+ def format_files(paths)
30
+ paths.grep(/\.rb\z/).each { |path| format_file(path) }
31
+ end
32
+
33
+ def format_file(path)
34
+ code = File.read(path)
35
+ formatted_code = format(code)
36
+ File.write(path, formatted_code)
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,6 @@
1
1
  require 'repper'
2
2
  require_relative 'regexp_ext'
3
3
 
4
+ Regexp.alias_method :original_inspect, :inspect
5
+
4
6
  ::Regexp.prepend(Repper::RegexpExt)
@@ -1,4 +1,4 @@
1
- # This extension does not include itself automatically,
1
+ # This extension does not enable itself automatically,
2
2
  # require 'repper/core_ext/regexp' to do so.
3
3
  module Repper
4
4
  ALREADY_COLORED_MARK = :@__already_colored__
@@ -1,7 +1,8 @@
1
1
  module Repper
2
2
  module Format
3
- Annotated = ->(elements, theme) do
4
- table = Tabulo::Table.new(elements.reject(&:whitespace?), **TABULO_STYLE)
3
+ # A structured and colorized format with annotations about token types.
4
+ Annotated = ->(tokens, theme) do
5
+ table = Tabulo::Table.new(tokens.reject(&:whitespace?), **TABULO_STYLE)
5
6
  table.add_column(
6
7
  :indented_text,
7
8
  styler: ->(_, string, cell) { theme.colorize(string, cell.source.type) }
@@ -0,0 +1,41 @@
1
+ module Repper
2
+ module Format
3
+ # A lightly structured format that retains parsability
4
+ # and functional equivalence, for use in code.
5
+ Extended = ->(tokens, theme) do
6
+ run_types = %i[escape literal nonposixclass nonproperty
7
+ posixclass property set type]
8
+ forms_run = ->(el){ run_types.include?(el.type) || el.subtype == :dot }
9
+ prev = nil
10
+
11
+ tokens.each.with_object(''.dup) do |tok, acc|
12
+ # drop existing x-mode whitespace, if any
13
+ if tok.whitespace?
14
+ next
15
+ # keep some tokens in line:
16
+ # - option switches and conditions for syntactic correctness
17
+ # - quantifiers and codepoint runs for conciseness
18
+ elsif tok.type == :quantifier ||
19
+ tok.subtype == :options_switch && tok.text == ')' ||
20
+ tok.subtype == :condition ||
21
+ prev && forms_run.call(prev) && forms_run.call(tok)
22
+ acc << theme.colorize(tok.inlined_text, tok.type)
23
+ # keep comments in line, too, but with padding
24
+ elsif tok.comment?
25
+ acc << " #{theme.colorize(tok.inlined_text, tok.type)}"
26
+ # render root start, as well as end of empty root, without linebreak
27
+ elsif tok.root? && (prev.nil? || prev.root?)
28
+ acc << theme.colorize(tok.text, tok.type)
29
+ # else, if root is not empty, ensure x-flag is present at end
30
+ elsif tok.root?
31
+ acc << "\n#{theme.colorize(tok.text.sub(/x?\z/, 'x'), tok.type)}"
32
+ # render other tokens on their own lines for an indented structure,
33
+ # e.g. groups, alternations, anchors, assertions, ...
34
+ else
35
+ acc << "\n#{theme.colorize(tok.indented_text, tok.type)}"
36
+ end
37
+ prev = tok
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,7 +1,8 @@
1
1
  module Repper
2
2
  module Format
3
- Inline = ->(elements, theme) do
4
- elements.map { |el| theme.colorize(el.text, el.type) }.join
3
+ # A format that only adds color but does not change structure.
4
+ Inline = ->(tokens, theme) do
5
+ tokens.map { |tok| theme.colorize(tok.text, tok.type) }.join
5
6
  end
6
7
  end
7
8
  end
@@ -1,7 +1,8 @@
1
1
  module Repper
2
2
  module Format
3
- Plain = ->(elements, *) do
4
- elements.map(&:text).join
3
+ # A no-op format, equivalent to the original Regexp#inspect.
4
+ Plain = ->(tokens, *) do
5
+ tokens.map(&:text).join
5
6
  end
6
7
  end
7
8
  end
@@ -1,7 +1,8 @@
1
1
  module Repper
2
2
  module Format
3
- Structured = ->(elements, theme) do
4
- table = Tabulo::Table.new(elements.reject(&:whitespace?), **TABULO_STYLE)
3
+ # A structured format with colorization.
4
+ Structured = ->(tokens, theme) do
5
+ table = Tabulo::Table.new(tokens.reject(&:whitespace?), **TABULO_STYLE)
5
6
  table.add_column(
6
7
  :indented_text,
7
8
  styler: ->(_, string, cell) { theme.colorize(string, cell.source.type) }
@@ -3,8 +3,8 @@ require 'tabulo'
3
3
  module Repper
4
4
  module Format
5
5
  TABULO_STYLE = {
6
- border: :blank,
7
- header_frequency: nil,
6
+ border: :blank, # i.e. don't draw borders
7
+ header_frequency: nil, # i.e. omit column headers
8
8
  truncation_indicator: '…',
9
9
  wrap_body_cells_to: 1,
10
10
  }
data/lib/repper/format.rb CHANGED
@@ -3,8 +3,9 @@ module Repper
3
3
  def self.cast(arg)
4
4
  case arg
5
5
  when ::Proc then arg
6
+ when :x then Format::Extended
6
7
  when ::Symbol, ::String then Format.const_get(arg.capitalize) rescue nil
7
- when false, nil then Format::Plain
8
+ when false, nil then Format::Inline
8
9
  end || raise(Repper::ArgumentError, "unknown format #{arg.inspect}")
9
10
  end
10
11
  end
@@ -0,0 +1,43 @@
1
+ module Repper
2
+ # A part of a Regexp. Generated by Repper::Tokenizer.
3
+ # `expression:` must be a Regexp::Expression::Base from regexp_parser.
4
+ Token = Struct.new(:expression, :text) do
5
+ def indented_text
6
+ "#{' ' * expression.nesting_level}#{inlined_text}"
7
+ end
8
+
9
+ def inlined_text
10
+ if comment?
11
+ text.strip
12
+ else
13
+ text
14
+ .gsub(/(?<!\\) /, '\\ ')
15
+ .gsub(/[\n\r\t\v]/) { |ws| ws.inspect.delete(?") }
16
+ end
17
+ end
18
+
19
+ def comment?
20
+ subtype == :comment
21
+ end
22
+
23
+ def root?
24
+ subtype == :root
25
+ end
26
+
27
+ def whitespace?
28
+ subtype == :whitespace
29
+ end
30
+
31
+ def type
32
+ expression.type
33
+ end
34
+
35
+ def subtype
36
+ expression.token
37
+ end
38
+
39
+ def annotation
40
+ expression.human_name unless root?
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,44 @@
1
+ require 'regexp_parser'
2
+
3
+ module Repper
4
+ # Uses Regexp::Parser to get the AST of a Regexp, and turns that AST
5
+ # into a flat Array of visual elements that match the Regexp notation.
6
+ module Tokenizer
7
+ module_function
8
+
9
+ def call(regexp, delimiters: ['/', '/'], flags: nil)
10
+ tree = Regexp::Parser.parse(regexp, options: flags =~ /x/ && Regexp::EXTENDED)
11
+ flatten(tree, delimiters: delimiters, flags: flags)
12
+ rescue ::Regexp::Parser::Error => e
13
+ raise e.extend(Repper::Error)
14
+ end
15
+
16
+ def flatten(exp, acc = [], delimiters: nil, flags: nil)
17
+ # Add opening entry.
18
+ exp.is?(:root) && acc << Token.new(exp, delimiters[0])
19
+
20
+ # Ignore nesting of invisible intermediate branches for better visuals.
21
+ if exp.is?(:sequence)
22
+ exp.each_expression(true) { |child| child.nesting_level -= 1 }
23
+ end
24
+
25
+ exp.parts.each do |part|
26
+ if part.instance_of?(::String)
27
+ acc << Token.new(exp, part)
28
+ else # part.is_a?(Regexp::Expression::Base)
29
+ flatten(part, acc)
30
+ end
31
+ end
32
+
33
+ exp.quantified? && flatten(exp.quantifier, acc)
34
+
35
+ # Add closing entry.
36
+ exp.is?(:root) && begin
37
+ flags ||= exp.options.keys.join
38
+ acc << Token.new(exp, "#{delimiters[1]}#{flags.chars.uniq.sort.join}")
39
+ end
40
+
41
+ acc
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module Repper
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.1"
3
3
  end
data/lib/repper.rb CHANGED
@@ -1,7 +1,9 @@
1
- require_relative "repper/element"
1
+ require_relative "repper/codemod"
2
+ require_relative "repper/command"
2
3
  require_relative "repper/errors"
3
4
  require_relative "repper/format"
4
- require_relative "repper/parser"
5
+ require_relative "repper/token"
6
+ require_relative "repper/tokenizer"
5
7
  require_relative "repper/theme"
6
8
  require_relative "repper/version"
7
9
 
@@ -14,18 +16,18 @@ module Repper
14
16
  end
15
17
 
16
18
  def render(regexp, format: self.format, theme: self.theme)
17
- elements = Parser.call(regexp)
18
- format = Format.cast(format)
19
- theme = Theme.cast(theme)
20
- format.call(elements, theme)
19
+ tokens = Tokenizer.call(regexp)
20
+ format = Format.cast(format)
21
+ theme = Theme.cast(theme)
22
+ format.call(tokens, theme)
21
23
  end
22
24
 
23
- def theme=(theme)
24
- @theme = Theme.cast(theme)
25
+ def format=(arg)
26
+ @format = Format.cast(arg)
25
27
  end
26
28
 
27
- def format=(format)
28
- @format = Format.cast(format)
29
+ def theme=(arg)
30
+ @theme = Theme.cast(arg)
29
31
  end
30
32
  end
31
33
 
data/repper.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Janosch Müller"]
7
7
  spec.email = ["janosch84@gmail.com"]
8
8
 
9
- spec.summary = "Regexp pretty printer for Ruby"
9
+ spec.summary = "Regexp pretty printer and formatter for Ruby"
10
10
  spec.homepage = "https://github.com/jaynetics/repper"
11
11
  spec.license = "MIT"
12
12
  spec.required_ruby_version = ">= 2.7.0"
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_dependency "rainbow", "~> 3.1"
28
- spec.add_dependency "regexp_parser", "~> 2.4"
28
+ spec.add_dependency "regexp_parser", "~> 2.6"
29
29
  spec.add_dependency "tabulo", "~> 2.8"
30
30
  end
data/repper.svg CHANGED
@@ -9,6 +9,8 @@
9
9
  id="svg5"
10
10
  inkscape:version="1.1.2 (b8e25be8, 2022-02-05)"
11
11
  sodipodi:docname="repper.svg"
12
+ inkscape:export-xdpi="32.537697"
13
+ inkscape:export-ydpi="32.537697"
12
14
  xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13
15
  xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
14
16
  xmlns="http://www.w3.org/2000/svg"
@@ -24,16 +26,78 @@
24
26
  inkscape:document-units="mm"
25
27
  showgrid="false"
26
28
  inkscape:zoom="0.3"
27
- inkscape:cx="395"
29
+ inkscape:cx="178.33333"
28
30
  inkscape:cy="400"
29
31
  inkscape:window-width="1383"
30
32
  inkscape:window-height="916"
31
- inkscape:window-x="0"
32
- inkscape:window-y="38"
33
+ inkscape:window-x="1512"
34
+ inkscape:window-y="496"
33
35
  inkscape:window-maximized="0"
34
36
  inkscape:current-layer="layer1" />
35
37
  <defs
36
38
  id="defs2">
39
+ <inkscape:path-effect
40
+ effect="skeletal"
41
+ id="path-effect92594"
42
+ is_visible="true"
43
+ lpeversion="1"
44
+ pattern="m 218.50956,-4.9822433 c -1.39261,-1.458531 -5.24307,-0.392108 -8.59476,2.3804213 -3.3517,2.77251917 -4.94168,6.2064186 -3.54907,7.6649479 1.39261,1.4585306 5.24306,0.3921075 8.59476,-2.3804211 3.35169,-2.77251913 4.94168,-6.206419 3.54907,-7.6649481 z"
45
+ copytype="single_stretched"
46
+ prop_scale="1"
47
+ scale_y_rel="false"
48
+ spacing="0"
49
+ normal_offset="0"
50
+ tang_offset="0"
51
+ prop_units="false"
52
+ vertical_pattern="false"
53
+ hide_knot="false"
54
+ fuse_tolerance="0" />
55
+ <inkscape:path-effect
56
+ effect="simplify"
57
+ id="path-effect92590"
58
+ is_visible="true"
59
+ lpeversion="1"
60
+ steps="1"
61
+ threshold="0.00221557"
62
+ smooth_angles="360"
63
+ helper_size="0"
64
+ simplify_individual_paths="false"
65
+ simplify_just_coalesce="false" />
66
+ <inkscape:path-effect
67
+ effect="skeletal"
68
+ id="path-effect92556"
69
+ is_visible="true"
70
+ lpeversion="1"
71
+ pattern="m -6.5579804,-4.9666732 c 1.392609,-1.4585305 5.243064,-0.3921075 8.59476,2.3804215 3.351699,2.77251918 4.941681,6.2064186 3.54907,7.6649479 -1.39261,1.4585306 -5.24306404,0.3921075 -8.594759,-2.3804211 -3.351699,-2.77251912 -4.941682,-6.206419 -3.549071,-7.6649483 z"
72
+ copytype="single_stretched"
73
+ prop_scale="1"
74
+ scale_y_rel="false"
75
+ spacing="0"
76
+ normal_offset="0"
77
+ tang_offset="0"
78
+ prop_units="false"
79
+ vertical_pattern="false"
80
+ hide_knot="false"
81
+ fuse_tolerance="0" />
82
+ <inkscape:path-effect
83
+ effect="simplify"
84
+ id="path-effect92552"
85
+ is_visible="true"
86
+ lpeversion="1"
87
+ steps="1"
88
+ threshold="0.00221557"
89
+ smooth_angles="360"
90
+ helper_size="0"
91
+ simplify_individual_paths="false"
92
+ simplify_just_coalesce="false" />
93
+ <linearGradient
94
+ id="linearGradient91990"
95
+ inkscape:swatch="solid">
96
+ <stop
97
+ style="stop-color:#e3cf00;stop-opacity:1;"
98
+ offset="0"
99
+ id="stop91988" />
100
+ </linearGradient>
37
101
  <inkscape:path-effect
38
102
  effect="skeletal"
39
103
  id="path-effect43053"
@@ -304,6 +368,60 @@
304
368
  vertical_pattern="false"
305
369
  hide_knot="false"
306
370
  fuse_tolerance="0" />
371
+ <inkscape:path-effect
372
+ effect="simplify"
373
+ id="path-effect29027-15"
374
+ is_visible="true"
375
+ lpeversion="1"
376
+ steps="1"
377
+ threshold="0.00221557"
378
+ smooth_angles="360"
379
+ helper_size="0"
380
+ simplify_individual_paths="false"
381
+ simplify_just_coalesce="false" />
382
+ <inkscape:path-effect
383
+ effect="skeletal"
384
+ id="path-effect29029-2"
385
+ is_visible="true"
386
+ lpeversion="1"
387
+ pattern="m 20.669672,46.003934 c 0.621589,-1.918412 4.553331,-2.628809 8.77621,-1.585706 4.222877,1.043101 7.145659,3.446649 6.524067,5.365061 -0.62159,1.918412 -4.553331,2.628807 -8.776209,1.585705 -4.222877,-1.043101 -7.14566,-3.446649 -6.524068,-5.36506 z"
388
+ copytype="single_stretched"
389
+ prop_scale="1"
390
+ scale_y_rel="false"
391
+ spacing="0"
392
+ normal_offset="0"
393
+ tang_offset="0"
394
+ prop_units="false"
395
+ vertical_pattern="false"
396
+ hide_knot="false"
397
+ fuse_tolerance="0" />
398
+ <inkscape:path-effect
399
+ effect="simplify"
400
+ id="path-effect92552-3"
401
+ is_visible="true"
402
+ lpeversion="1"
403
+ steps="1"
404
+ threshold="0.00221557"
405
+ smooth_angles="360"
406
+ helper_size="0"
407
+ simplify_individual_paths="false"
408
+ simplify_just_coalesce="false" />
409
+ <inkscape:path-effect
410
+ effect="skeletal"
411
+ id="path-effect92556-9"
412
+ is_visible="true"
413
+ lpeversion="1"
414
+ pattern="m -6.5579804,-4.9666732 c 1.392609,-1.4585305 5.243064,-0.3921075 8.59476,2.3804215 3.351699,2.77251918 4.941681,6.2064186 3.54907,7.6649479 -1.39261,1.4585306 -5.24306404,0.3921075 -8.594759,-2.3804211 -3.351699,-2.77251912 -4.941682,-6.206419 -3.549071,-7.6649483 z"
415
+ copytype="single_stretched"
416
+ prop_scale="1"
417
+ scale_y_rel="false"
418
+ spacing="0"
419
+ normal_offset="0"
420
+ tang_offset="0"
421
+ prop_units="false"
422
+ vertical_pattern="false"
423
+ hide_knot="false"
424
+ fuse_tolerance="0" />
307
425
  </defs>
308
426
  <g
309
427
  inkscape:label="Ebene 1"
@@ -311,136 +429,154 @@
311
429
  id="layer1">
312
430
  <text
313
431
  xml:space="preserve"
314
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.264583"
432
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
315
433
  x="88.609558"
316
434
  y="142.00261"
317
- id="text473"><tspan
435
+ id="text473"
436
+ inkscape:export-xdpi="32.30674"
437
+ inkscape:export-ydpi="32.30674"><tspan
318
438
  sodipodi:role="line"
319
439
  id="tspan471"
320
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.264583"
440
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
321
441
  x="88.609558"
322
442
  y="142.00261">$</tspan></text>
323
443
  <text
324
444
  xml:space="preserve"
325
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.264583"
445
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
326
446
  x="26.48514"
327
447
  y="147.63461"
328
448
  id="text473-4"
329
449
  inkscape:transform-center-x="2.9956772"
330
450
  inkscape:transform-center-y="-2.5677233"><tspan
331
451
  id="tspan471-3"
332
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.264583"
452
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50.8px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
333
453
  x="26.48514"
334
454
  y="147.63461"
335
455
  sodipodi:role="line" /></text>
336
456
  <text
337
457
  xml:space="preserve"
338
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.7622px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.222719"
458
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.7622px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
339
459
  x="84.480263"
340
460
  y="-73.830437"
341
461
  id="text473-1"
342
- transform="matrix(-0.01039371,0.84174345,-1.1879195,-0.00736484,0,0)"><tspan
462
+ transform="matrix(-0.01039371,0.84174345,-1.1879195,-0.00736484,0,0)"
463
+ inkscape:export-xdpi="32.30674"
464
+ inkscape:export-ydpi="32.30674"><tspan
343
465
  sodipodi:role="line"
344
466
  id="tspan471-8"
345
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.7622px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.222719"
467
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.7622px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
346
468
  x="84.480263"
347
469
  y="-73.830437">0</tspan></text>
348
470
  <text
349
471
  xml:space="preserve"
350
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:44.4055px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';white-space:pre;inline-size:40.7295;stroke-width:0.231278"
472
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:44.4055px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';white-space:pre;inline-size:40.7295;fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.53487;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
351
473
  x="18.91221"
352
474
  y="-47.323662"
353
475
  id="text473-1-5"
354
- transform="matrix(-0.45969555,0.66650243,-0.97588205,-0.53512053,4.2333335,10.289189)"><tspan
476
+ transform="matrix(-0.45969555,0.66650243,-0.97588205,-0.53512053,4.2333335,10.289189)"
477
+ inkscape:export-xdpi="32.30674"
478
+ inkscape:export-ydpi="32.30674"><tspan
355
479
  x="18.91221"
356
480
  y="-47.323662"
357
- id="tspan84688">0</tspan></text>
481
+ id="tspan93379">0</tspan></text>
358
482
  <text
359
483
  xml:space="preserve"
360
- style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';stroke-width:0.264583"
484
+ style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
361
485
  x="47.930836"
362
486
  y="84.734871"
363
487
  id="text18132"><tspan
364
488
  sodipodi:role="line"
365
489
  id="tspan18130"
366
- style="stroke-width:0.264583"
490
+ style="fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
367
491
  x="47.930836"
368
492
  y="84.734871" /></text>
369
493
  <text
370
494
  xml:space="preserve"
371
- style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';stroke-width:0.264583"
495
+ style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
372
496
  x="35.948128"
373
497
  y="33.380402"
374
498
  id="text23204"><tspan
375
499
  sodipodi:role="line"
376
500
  id="tspan23202"
377
- style="stroke-width:0.264583"
501
+ style="fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
378
502
  x="35.948128"
379
503
  y="33.380402" /></text>
380
504
  <path
381
- style="fill:#000000;stroke:none;stroke-width:0.284007px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
382
- d="m 59.099047,70.776083 c 2.120975,-1.078377 10.77195,1.950654 20.22924,5.094731 -0.147517,-0.0492 1.418427,0.473496 1.27091,0.424299 9.989745,3.340154 17.614113,6.281378 15.582927,8.125798 -1.600508,1.453348 -9.549486,1.32287 -18.585399,-1.349413 0,0 -1e-6,0 -1e-6,0 C 76.147903,82.64138 74.690387,82.144385 73.237982,81.580972 62.456459,77.398636 57.08906,71.798024 59.099047,70.776083 Z"
505
+ style="fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
506
+ d="m 59.099139,70.776137 c 2.12787,-1.081793 10.854698,1.976966 20.364006,5.139528 -0.108589,-0.03622 1.244719,0.415606 1.13613,0.379383 9.989564,3.340372 17.61416,6.281333 15.582842,8.12586 -1.591933,1.445551 -9.462126,1.32328 -18.440304,-1.306619 0,-10e-7 -10e-7,-10e-7 -10e-7,-10e-7 C 76.245556,82.674336 74.739206,82.162967 73.238054,81.580609 62.45744,77.398376 57.087976,71.798591 59.099139,70.776137 Z"
383
507
  id="path29025"
384
508
  inkscape:path-effect="#path-effect29027;#path-effect29029"
385
509
  inkscape:original-d="m 58.148912,72.423541 c 13.62864,5.908708 23.245218,8.103634 38.499876,10.153486"
386
- sodipodi:nodetypes="cc" />
510
+ sodipodi:nodetypes="cc"
511
+ inkscape:export-xdpi="32.30674"
512
+ inkscape:export-ydpi="32.30674" />
387
513
  <text
388
514
  xml:space="preserve"
389
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.0429px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.218973"
515
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.0429px;line-height:1;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
390
516
  x="146.16597"
391
517
  y="96.452888"
392
518
  id="text473-1-5-0"
393
- transform="matrix(0.4855282,0.70395662,1.0307219,-0.5651917,0,0)"><tspan
519
+ transform="matrix(0.4855282,0.70395662,1.0307219,-0.5651917,0,0)"
520
+ inkscape:export-xdpi="32.30674"
521
+ inkscape:export-ydpi="32.30674"><tspan
394
522
  sodipodi:role="line"
395
523
  id="tspan471-8-6-1"
396
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.0429px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';stroke-width:0.218973"
524
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.0429px;font-family:Thonburi;-inkscape-font-specification:'Thonburi Bold';fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
397
525
  x="146.16597"
398
526
  y="96.452888">0</tspan></text>
399
527
  <path
400
- style="fill:#000000;stroke:none;stroke-width:0.28963px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
401
- d="m 115.94486,85.097149 c 1.62878,1.516174 9.67995,1.368939 18.78066,-1.453697 0,0 0,-10e-7 0,-10e-7 1.41436,-0.440526 2.83487,-0.946725 4.24854,-1.517955 10.78635,-4.358484 16.03105,-10.152634 13.97777,-11.206085 -2.16623,-1.111417 -10.64635,1.973884 -20.10584,5.251398 0.20166,-0.07012 -1.57428,0.547897 -1.37261,0.477773 -9.95865,3.471655 -17.58664,6.532745 -15.52852,8.448567 z"
528
+ style="fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
529
+ d="m 115.94486,85.097146 c 1.62012,1.508092 9.59184,1.369553 18.63551,-1.408796 0,0 0,0 0,0 1.46199,-0.451029 2.93133,-0.972313 4.39362,-1.563218 10.78546,-4.358378 16.03219,-10.151702 13.97774,-11.205664 -2.17642,-1.116557 -10.72491,1.99989 -20.23992,5.297849 0.14949,-0.05199 -1.38801,0.483186 -1.23853,0.431194 -9.95842,3.471909 -17.58669,6.532679 -15.52842,8.448635 z"
402
530
  id="path29025-0"
403
531
  sodipodi:nodetypes="cc"
404
532
  inkscape:original-d="m 153.95732,72.621585 c -13.62872,6.144952 -23.24535,8.427629 -38.50001,10.55943"
405
- inkscape:path-effect="#path-effect43049;#path-effect43053" />
533
+ inkscape:path-effect="#path-effect43049;#path-effect43053"
534
+ inkscape:export-xdpi="32.30674"
535
+ inkscape:export-ydpi="32.30674" />
406
536
  <text
407
537
  xml:space="preserve"
408
- style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';stroke-width:0.264583"
538
+ style="font-size:10.5833px;line-height:1.25;font-family:'System Font';-inkscape-font-specification:'System Font';fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
409
539
  x="67.616714"
410
540
  y="123.67867"
411
541
  id="text30077"><tspan
412
542
  sodipodi:role="line"
413
543
  id="tspan30075"
414
- style="stroke-width:0.264583"
544
+ style="fill:#e9c915;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
415
545
  x="67.616714"
416
546
  y="123.67867" /></text>
417
547
  <rect
418
548
  id="rect66881"
419
- width="6.5312495"
420
- height="16.90856"
421
- x="102.88905"
422
- y="91.982559"
423
- style="stroke-width:0.274066" />
549
+ width="7.2900386"
550
+ height="11.079004"
551
+ x="102.50966"
552
+ y="87.608177"
553
+ style="fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.05246;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
554
+ inkscape:export-xdpi="32.30674"
555
+ inkscape:export-ydpi="32.30674" />
424
556
  <text
425
557
  xml:space="preserve"
426
- style="font-size:31.75px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:0.264583;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
558
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
427
559
  x="72.62812"
428
560
  y="153.12755"
429
- id="text75927"><tspan
561
+ id="text75927"
562
+ inkscape:export-xdpi="32.30674"
563
+ inkscape:export-ydpi="32.30674"><tspan
430
564
  sodipodi:role="line"
431
565
  id="tspan75925"
432
- style="font-size:31.75px;stroke-width:0.264583;-inkscape-font-specification:Arial;font-family:Arial;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
566
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;font-family:Arial;-inkscape-font-specification:Arial;fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
433
567
  x="72.62812"
434
568
  y="153.12755">*</tspan></text>
435
569
  <text
436
570
  xml:space="preserve"
437
- style="font-size:31.75px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:0.264583;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
571
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
438
572
  x="124.74483"
439
573
  y="125.85077"
440
- id="text75927-8"><tspan
574
+ id="text75927-8"
575
+ inkscape:export-xdpi="32.30674"
576
+ inkscape:export-ydpi="32.30674"><tspan
441
577
  sodipodi:role="line"
442
578
  id="tspan75925-9"
443
- style="font-size:31.75px;stroke-width:0.264583;-inkscape-font-specification:Arial;font-family:Arial;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"
579
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;font-family:Arial;-inkscape-font-specification:Arial;fill:#efc30f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
444
580
  x="124.74483"
445
581
  y="125.85077">*</tspan></text>
446
582
  </g>
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: repper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janosch Müller
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rainbow
@@ -30,14 +29,14 @@ dependencies:
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '2.4'
32
+ version: '2.6'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '2.4'
39
+ version: '2.6'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: tabulo
43
42
  requirement: !ruby/object:Gem::Requirement
@@ -52,10 +51,10 @@ dependencies:
52
51
  - - "~>"
53
52
  - !ruby/object:Gem::Version
54
53
  version: '2.8'
55
- description:
56
54
  email:
57
55
  - janosch84@gmail.com
58
- executables: []
56
+ executables:
57
+ - repper
59
58
  extensions: []
60
59
  extra_rdoc_files: []
61
60
  files:
@@ -65,24 +64,28 @@ files:
65
64
  - LICENSE.txt
66
65
  - README.md
67
66
  - Rakefile
67
+ - exe/repper
68
68
  - lib/repper.rb
69
+ - lib/repper/codemod.rb
70
+ - lib/repper/command.rb
69
71
  - lib/repper/core_ext/kernel.rb
70
72
  - lib/repper/core_ext/kernel_ext.rb
71
73
  - lib/repper/core_ext/regexp.rb
72
74
  - lib/repper/core_ext/regexp_ext.rb
73
- - lib/repper/element.rb
74
75
  - lib/repper/errors.rb
75
76
  - lib/repper/format.rb
76
77
  - lib/repper/format/annotated.rb
78
+ - lib/repper/format/extended.rb
77
79
  - lib/repper/format/inline.rb
78
80
  - lib/repper/format/plain.rb
79
81
  - lib/repper/format/structured.rb
80
82
  - lib/repper/format/tabulo_style.rb
81
- - lib/repper/parser.rb
82
83
  - lib/repper/theme.rb
83
84
  - lib/repper/theme/default.rb
84
85
  - lib/repper/theme/monokai.rb
85
86
  - lib/repper/theme/plain.rb
87
+ - lib/repper/token.rb
88
+ - lib/repper/tokenizer.rb
86
89
  - lib/repper/version.rb
87
90
  - repper.gemspec
88
91
  - repper.svg
@@ -94,7 +97,6 @@ metadata:
94
97
  homepage_uri: https://github.com/jaynetics/repper
95
98
  source_code_uri: https://github.com/jaynetics/repper
96
99
  changelog_uri: https://github.com/jaynetics/repper/tree/main/CHANGELOG.md
97
- post_install_message:
98
100
  rdoc_options: []
99
101
  require_paths:
100
102
  - lib
@@ -109,8 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
111
  - !ruby/object:Gem::Version
110
112
  version: '0'
111
113
  requirements: []
112
- rubygems_version: 3.4.0.dev
113
- signing_key:
114
+ rubygems_version: 4.0.23
114
115
  specification_version: 4
115
- summary: Regexp pretty printer for Ruby
116
+ summary: Regexp pretty printer and formatter for Ruby
116
117
  test_files: []
@@ -1,31 +0,0 @@
1
- module Repper
2
- Element = Struct.new(:type, :subtype, :level, :text, :id, keyword_init: true) do
3
- def indented_text
4
- inlined_text = text.gsub(/[\n\r\t\v]/) { |ws| ws.inspect.delete(?") }
5
- "#{' ' * level}#{inlined_text}"
6
- end
7
-
8
- def whitespace?
9
- subtype == :whitespace
10
- end
11
-
12
- def annotation
13
- case [type, subtype]
14
- in [_, :root]
15
- nil
16
- in [_, :alternation | :comment | :condition | :intersection | :range => subtype]
17
- subtype
18
- in [:conditional | :free_space => type, _]
19
- type
20
- in [:group, :capture | :named]
21
- "capture group #{id}"
22
- in [:meta, :dot]
23
- 'match-all'
24
- in [:keep, :mark]
25
- 'keep-mark lookbehind'
26
- in [type, subtype]
27
- [subtype, type].uniq.join(' ')
28
- end.to_s.tr('_', ' ')
29
- end
30
- end
31
- end
data/lib/repper/parser.rb DELETED
@@ -1,49 +0,0 @@
1
- require 'regexp_parser'
2
-
3
- module Repper
4
- module Parser
5
- module_function
6
-
7
- def call(regexp)
8
- tree = ::Regexp::Parser.parse(regexp)
9
- flatten(tree)
10
- rescue ::Regexp::Parser::Error => e
11
- raise e.extend(Repper::Error)
12
- end
13
-
14
- # Turn Regexp::Parser AST back into a flat Array of visual elements
15
- # that match the Regexp notation.
16
- def flatten(exp, acc = [])
17
- # Add opening entry.
18
- exp.is?(:root) && acc << make_element(exp, '/')
19
-
20
- # Ignore nesting of invisible intermediate branches for better visuals.
21
- exp.is?(:sequence) && exp.nesting_level -= 1
22
-
23
- exp.parts.each do |part|
24
- if part.instance_of?(::String)
25
- acc << make_element(exp, part)
26
- else # part.is_a?(Regexp::Expression::Base)
27
- flatten(part, acc)
28
- end
29
- end
30
-
31
- exp.quantified? && flatten(exp.quantifier, acc)
32
-
33
- # Add closing entry.
34
- exp.is?(:root) && acc << make_element(exp, "/#{exp.options.keys.join}")
35
-
36
- acc
37
- end
38
-
39
- def make_element(exp, text)
40
- Element.new(
41
- type: exp.type,
42
- subtype: exp.token,
43
- level: exp.nesting_level,
44
- text: text,
45
- id: exp.respond_to?(:identifier) && exp.identifier,
46
- )
47
- end
48
- end
49
- end