### Install mustermann-contrib Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Install the mustermann-contrib gem using the gem command. ```console $ gem install mustermann-contrib Successfully installed mustermann-1.0.0 Successfully installed mustermann-contrib-1.0.0 ... ``` -------------------------------- ### Benchmarking Mustermann::Set Performance Source: https://github.com/sinatra/mustermann/blob/main/docs/performance.md Provides command-line examples for benchmarking the performance of `Mustermann::Set` with different configurations and route counts. ```sh bundle exec ruby bench/set.rb bundle exec ruby bench/set.rb --trie true bundle exec ruby bench/set.rb --no-trie bundle exec ruby bench/set.rb --routes 10,50,100,500 --nesting 2 --trie 20 ``` -------------------------------- ### Initialize Set with Initial Mappings Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Provide an initial hash of patterns and values directly to the `Mustermann::Set` constructor for a concise setup. ```ruby set = Mustermann::Set.new( '/users/:id' => :users_show, '/posts/:id' => :posts_show ) ``` -------------------------------- ### Mustermann Simple Pattern Examples Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/simple.md Demonstrates the creation and usage of simple patterns for matching and extracting parameters from URLs. This type is suitable for porting applications to newer Sinatra versions without performance degradation. ```ruby require 'mustermann' pattern = Mustermann.new('/:example', type: :simple) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => false pattern.params("/foo.bar") # => { "example" => "foo.bar" } pattern.params("/foo/bar") # => nil ``` ```ruby pattern = Mustermann.new('/:example/?:optional?', type: :simple) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => true pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil } pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" } ``` ```ruby pattern = Mustermann.new('/*', type: :simple) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => true pattern.params("/foo.bar") # => { "splat" => ["foo.bar"] } pattern.params("/foo/bar") # => { "splat" => ["foo/bar"] } ``` -------------------------------- ### Initialize Set with a Block Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use a block with the `Mustermann::Set.new` constructor for imperative setup of patterns and values. ```ruby set = Mustermann::Set.new do |s| s.add('/users/:id', :users_show) s.add('/posts/:id', :posts_show) end ``` -------------------------------- ### S-expression String Example Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md An example of an s-expression like string format for representing patterns. ```text (root (separator /) (capture : (name page))) ``` -------------------------------- ### Custom Brace Pattern Implementation Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md A comprehensive example of a custom pattern type using brace syntax, including named captures, optional segments, constraints, groups, and alternations. ```ruby require 'mustermann/ast/pattern' class BracePattern < Mustermann::AST::Pattern register :brace class Parser < Mustermann::AST::Parser # Disallow unmatched closing braces on(?}) { |char| unexpected(char) } # {name} for a capture, {+name} for a named splat on(?{) do |char| if scan(?+) name = expect(/\w+/) expect(?}) node(:named_splat, name) else name = expect(/\w+/) constraint = scan(/:\w+/) expect(?}) n = node(:capture, name) n.constraint = '\d+' if constraint == ':int' n.constraint = '\w+' if constraint == ':word' n end end # Groups with (...) on(?() { |char| node(:group) { read unless scan(?)) } } # Alternation with | on(?|) { |char| node(:or) } # Make captures and groups optional with ? suffix(??, after: :capture) { |m, e| node(:optional, e) } suffix(??, after: :group) { |m, e| node(:optional, e) } end end ``` -------------------------------- ### Hansi Template String Example Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md An example of a Hansi template string format, which uses XML-like tags for pattern elements. ```xml /:page ``` -------------------------------- ### Angle-Bracket Captures Example Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md A complete custom pattern type using '' syntax for captures. This example defines how to parse angle-bracketed names and greedy splats. ```ruby require 'mustermann/ast/pattern' class AnglePattern < Mustermann::AST::Pattern register :angle class Parser < Mustermann::AST::Parser # Disallow unmatched > at the top level on(?>) { |char| unexpected(char) } on(?<) do |char| name = expect(/\w+/) expect(?>) node(:capture, name) end # "**" becomes a greedy splat on(?*) do |char| if scan(?*) node(:named_splat, 'path') else name = scan(/\w+/) name ? node(:named_splat, name) : node(:splat) end end end end ``` ```ruby pattern = Mustermann.new('/users//posts/', type: :angle) pattern === '/users/42/posts/hello-world' # => true pattern.params('/users/42/posts/hello-world') # => {"id" => "42", "slug" => "hello-world"} pattern = Mustermann.new('/files/**', type: :angle) pattern.params('/files/img/logo.png') # => {"path" => ["img/logo.png"]} ``` ```ruby on(?<) do |char| match = expect(/(?\w+)> node(:capture, match[:name]) end ``` -------------------------------- ### Node Types Reference Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md A quick reference for built-in node types used in Mustermann patterns, including their purpose and example usage. ```markdown | Node | Purpose | Example use | |------|---------|-------------| | `:char` | A literal character | `node(:char, 'x')` | | `:separator` | A path separator (`/`) | `node(:separator, '/')` | | `:capture` | A named parameter capture | `node(:capture) { scan(/\w+/) }` | | `:splat` | An unnamed wildcard (`splat` key in params) | `node(:splat)` | | `:named_splat` | A named wildcard | `node(:named_splat, 'rest')` | | `:group` | A grouped sequence | `node(:group) { ... }` | | `:optional` | A group that may be absent | `node(:optional, inner_node)` | | `:union` | Two or more alternatives | `node(:union, [a, b])` | | `:or` | Separator between union arms | `node(:or)` | ``` -------------------------------- ### Create and Use Identity Pattern Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/identity.md Demonstrates how to create an identity pattern and test string matches. No special options are required for basic usage. ```ruby require 'mustermann' pattern = Mustermann.new('/foo/bar', type: :identity) pattern === '/foo/bar' # => true pattern === '/foo/baz' # => false pattern.params('/foo/bar') # => {} ``` -------------------------------- ### Create symbolic links with Mustermann::FileUtils Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Create symbolic links using Mustermann::FileUtils.ln_s, mapping source patterns to target paths. ```ruby require 'mustermann/file_utils' # creates a symbolic link from bin/example to lib/example.rb Mustermann::FileUtils.ln_s('lib/:name.rb' => 'bin/:name') ``` -------------------------------- ### Sinatra Pattern Type Source: https://context7.com/sinatra/mustermann/llms.txt This snippet shows the basic setup for using the default Sinatra pattern type in Mustermann. ```ruby require 'mustermann' ``` -------------------------------- ### Convert Pattern to Proc Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Patterns implement `to_proc`, allowing them to be used like Ruby Procs, for example, with methods like `detect`. ```ruby require 'mustermann' pattern = Mustermann.new('/foo') callback = pattern.to_proc # => # callback.call('/foo') # => true callback.call('/bar') # => false ``` -------------------------------- ### Basic Flask Pattern Usage Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/flask.md Demonstrates basic usage of the Flask pattern type for parameter extraction and expansion. Requires the 'mustermann/flask' gem. ```ruby require 'mustermann/flask' Mustermann.new('//', type: :flask).params('/a/b/c') # => { prefix: 'a', page: 'b/c' } pattern = Mustermann.new('/', type: :flask) pattern.respond_to? :expand # => true pattern.expand(name: 'foo') # => '/foo' pattern.respond_to? :to_templates # => true pattern.to_templates # => ['/{name}'] ``` -------------------------------- ### Copy files with Mustermann::FileUtils Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Copy files using Mustermann::FileUtils.cp and recursively copy directories with Mustermann::FileUtils.cp_r, based on pattern mappings. ```ruby require 'mustermann/file_utils' # copies example.txt to example.bak.txt Mustermann::FileUtils.cp(':base.:ext' => ':base.bak.:ext') # copies Foo.app/example.txt to Foo.back.app/example.txt Mustermann::FileUtils.cp_r(':base.:ext' => ':base.bak.:ext') ``` -------------------------------- ### Basic Express Pattern Usage Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/express.md Demonstrates creating an Express pattern, parsing parameters from a URL, and expanding a pattern into a URL. Requires the mustermann/express gem. ```ruby require 'mustermann/express' Mustermann.new('/:name/:rest+', type: :express).params('/a/b/c') # => { name: 'a', rest: 'b/c' } pattern = Mustermann.new('/:name', type: :express) pattern.respond_to? :expand # => true pattern.expand(name: 'foo') # => '/foo' pattern.respond_to? :to_templates # => true pattern.to_templates # => ['/{name}'] ``` -------------------------------- ### Visualizing Patterns with HTML Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Demonstrates generating HTML-based syntax highlighting for Mustermann patterns using `to_html`. This is useful for displaying patterns in web interfaces. ```ruby require 'mustermann/visualizer' puts Mustermann.new('/:name').to_html ``` -------------------------------- ### Peek at String Beginning Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use `peek`, `peek_size`, `peek_match`, and `peek_params` to match a pattern against the beginning of a string without consuming the entire string. Returns nil if no match. ```ruby require 'mustermann' pattern = Mustermann.new('/:prefix') pattern.peek('/foo/bar') # => '/foo' pattern.peek_size('/foo/bar') # => 4 path_info = '/foo/bar' params, size = patter.peek_params(path_info) # params == { "prefix" => "foo" } rest = path_info[size..-1] # => "/bar" ``` -------------------------------- ### Basic Rails Pattern Matching Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/rails.md Demonstrates basic usage of the Rails pattern for matching URLs and extracting parameters. Use this for standard Rails-style routing. ```ruby require 'mustermann' pattern = Mustermann.new('/:example', type: :rails) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => false pattern.params("/foo.bar") # => { "example" => "foo.bar" } pattern.params("/foo/bar") # => nil ``` ```ruby pattern = Mustermann.new('/:example(/:optional)', type: :rails) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => true pattern.params("/foo.bar") # => { "example" => "foo.bar", "optional" => nil } pattern.params("/foo/bar") # => { "example" => "foo", "optional" => "bar" } ``` ```ruby pattern = Mustermann.new('/*example', type: :rails) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => true pattern.params("/foo.bar") # => { "example" => "foo.bar" } pattern.params("/foo/bar") # => { "example" => "foo/bar" } ``` -------------------------------- ### Implement Custom BracePattern with AST::Pattern Source: https://context7.com/sinatra/mustermann/llms.txt Define a custom pattern type 'brace' by subclassing Mustermann::AST::Pattern. This example shows how to parse named captures with optional constraints and splats. ```ruby require 'mustermann/ast/pattern' class BracePattern < Mustermann::AST::Pattern register :brace class Parser < Mustermann::AST::Parser on(?}) { |c| unexpected(c) } # {name} → named capture; {+name} → named splat on(?{) do |c| if scan(?+) node(:named_splat, expect(/W+/).tap { expect(?}) }) else name = expect(/W+/) constraint = scan(/:W+/) expect(?}) n = node(:capture, name) n.constraint = '\d+' if constraint == ':int' n end end on(?() { |c| node(:group) { read unless scan(?)) } } on(?|) { |c| node(:or) } suffix(??, after: :capture) { |m, e| node(:optional, e) } suffix(??, after: :group) { |m, e| node(:optional, e) } end end p = Mustermann.new('/users/{id:int}/posts/{slug}?', type: :brace) p === '/users/42/posts/hello' # => true p === '/users/42/posts' # => true p === '/users/foo/posts' # => false p.params('/users/42/posts/hello') # => {"id" => "42", "slug" => "hello"} p.params('/users/42/posts') # => {"id" => "42", "slug" => nil} # Full expand and to_templates support inherited automatically p.expand(id: '42', slug: 'hello') # => "/users/42/posts/hello" ``` -------------------------------- ### Basic String Matching with Mustermann Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Demonstrates basic string matching using Mustermann patterns with the =~ operator and a case statement. Useful for simple pattern checks. ```ruby if '/foo/bar' =~ Mustermann.new('/foo/*') puts 'it works!' end ``` ```ruby case 'something.png' when Mustermann.new('foo/*') then puts "prefixed with foo" when Mustermann.new('*.pdf') then puts "it's a PDF" when Mustermann.new('*.png') then puts "it's an image" end ``` -------------------------------- ### Generate HTML and Stylesheet from Highlight Object Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Demonstrates how to obtain the stylesheet and HTML output from a highlight object created by Mustermann::Visualizer.highlight. ```erb <% highlight = Mustermann::Visualizer.highlight("/:name") %> <%= highlight.to_html(css: false) %> ``` -------------------------------- ### Cake Pattern Expand and To Templates Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/cake.md Shows how to expand a Cake pattern to a URL and convert it to templates for routing. Requires the 'mustermann/cake' gem. ```ruby pattern = Mustermann.new('/:name') pattern.respond_to? :expand # => true pattern.expand(name: 'foo') # => '/foo' pattern.respond_to? :to_templates # => true pattern.to_templates # => ['/{name}'] ``` -------------------------------- ### Use Pattern as Proc with Detect Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Demonstrates using a Mustermann pattern converted to a Proc with the `detect` method to find a matching element in a list. ```ruby require 'mustermann' list = ["foo", "example@email.com", "bar"] pattern = Mustermann.new(":name@:domain.:tld") email = list.detect(&pattern) # => "example@email.com" ``` -------------------------------- ### Basic Regex Pattern Matching Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/regexp.md Demonstrates creating a regex pattern and testing string matches. Ensure the pattern does not contain anchors unless check_anchors is explicitly set to false. ```ruby require 'mustermann' pattern = Mustermann.new('/\d+', type: :regexp) pattern === '/123' # => true pattern === '/abc' # => false ``` -------------------------------- ### Basic Sinatra Pattern Usage Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/sinatra.md Demonstrates how to create and use Sinatra patterns for matching and extracting parameters. The `Mustermann.new` method initializes a pattern, and the `===` operator checks for a match, while `pattern.params` extracts captured values. ```ruby require 'mustermann' pattern = Mustermann.new('/:name') pattern === '/alice' # => true pattern === '/alice/bob' # => false pattern.params('/alice') # => { "name" => "alice" } pattern = Mustermann.new('/:foo/:bar') pattern.params('/hello/world') # => { "foo" => "hello", "bar" => "world" } pattern = Mustermann.new('/*') pattern.params('/a/b/c') # => { "splat" => ["a/b/c"] } ``` -------------------------------- ### Fine-grained Pattern Highlighting Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Illustrates using `Mustermann::Visualizer.highlight` for more control over pattern visualization, including generating ANSI color codes. ```ruby require 'mustermann/visualizer' pattern = Mustermann.new('/:name') highlight = Mustermann::Visualizer.highlight(pattern) puts highlight.to_ansi ``` -------------------------------- ### Glob files using Mustermann::FileUtils Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Use Mustermann::FileUtils to glob files based on Mustermann patterns. Requires 'mustermann/file_utils'. ```ruby require 'mustermann/file_utils' Mustermann::FileUtils[':base.:ext'] # => ['example.txt'] Mustermann::FileUtils.glob(':base.:ext') do |file, params| file # => "example.txt" params # => {"base"=>"example", "ext"=>"txt"} end ``` -------------------------------- ### Basic StringScanner Usage Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Demonstrates basic scanning operations like `scan`, `getch`, and accessing captured groups. Use this for sequential matching and extraction from a string. ```ruby require 'mustermann/string_scanner' scanner = Mustermann::StringScanner.new("here is our example string") scanner.scan("here") # => "here" scanner.getch # => " " if scanner.scan(":verb our") scanner.scan(:noun, capture: :word) scanner[:verb] # => "is" scanner[:nound] # => "example" end scanner.rest # => "string" ``` -------------------------------- ### StringScanner with Default Options Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Demonstrates initializing `StringScanner` with default options, such as `type: :shell`. This sets a default pattern type for all subsequent operations on the scanner. ```ruby scanner = Mustermann::StringScanner.new(input, type: :shell) ``` -------------------------------- ### Map files using Mustermann::FileUtils Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Map file paths using Mustermann::FileUtils.glob_map, optionally providing a block for custom transformations. ```ruby require 'mustermann/file_utils' Mustermann::FileUtils.glob_map(':base.:ext' => ':base.bak.:ext') # => {'example.txt' => 'example.bak.txt'} Mustermann::FileUtils.glob_map(':base.:ext' => :base) { |file, mapped| mapped } # => ['example'] ``` -------------------------------- ### Basic Shell Pattern Matching Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/shell.md Demonstrates the basic usage of the shell pattern type for matching strings. The `*` matches anything but a slash, while `**` matches anything. ```ruby require 'mustermann' pattern = Mustermann.new('/*', type: :shell) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => false pattern = Mustermann.new('/**/*', type: :shell) pattern === "/foo.bar" # => true pattern === "/foo/bar" # => true ``` -------------------------------- ### Using Mustermann::Set with Hybrid Patterns and Capture Options Source: https://github.com/sinatra/mustermann/blob/main/CHANGELOG.md Demonstrates creating a Mustermann::Set with hybrid pattern syntax, defining capture options with type conversions, and matching/expanding paths. The `capture` option allows specifying expected types for captured parameters. ```ruby require "mustermann/set" set = Mustermann::Set.new(type: :hybrid, capture: { id: Integer, user_id: Integer, slug: :slug }) # adding values is optional set.add "/users", "users.index" set.add "/users/:id", "users.show" set.add "/posts", "posts.index" set.add "/users/:user_id/posts", "posts.index" set.add "/posts/:id(-:slug)", "posts.show" # slug is optional match = set.match("/posts/42-awesome-post") # id is automatically converted to an Integer, and slug is available as a string match.params # => { id: 42, slug: "awesome-post" } # You can access the pattern and value that matched match.value # => "posts.show" match.pattern # => # # Generate a path from a set value and params set.expand("posts.index") # => "/posts" set.expand("posts.index", user_id: 42) # => "/users/42/posts" ``` -------------------------------- ### Instantiating Shell Pattern Directly Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Demonstrates direct instantiation of a specific Mustermann pattern type, the Shell pattern. This approach is useful when you want to be explicit about the pattern type being used. ```ruby require 'mustermann/shell' pattern = Mustermann::Shell.new('/*/**') ``` -------------------------------- ### Render Pattern as Tree Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Loading 'mustermann/visualizer' adds the 'to_tree' method to pattern objects for rendering an AST-based pattern as a tree. ```ruby require 'mustermann/visualizer' puts Mustermann.new("/:page(.:ext)?/*action").to_tree ``` -------------------------------- ### Peek Match All for Multiple Prefix Matches Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use `peek_match_all` to retrieve all patterns that match a prefix of the input string. Results include the matched string and the post-match remainder. ```ruby results = set.peek_match_all('/users/42/posts') results.map(&:value) # => [:users] results.map(&:post_match) # => ['/posts'] ``` -------------------------------- ### Creating Shell-Type Patterns Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Illustrates how to create a Mustermann pattern of a specific type, in this case, the shell type. This is useful when you need to enforce a particular pattern syntax. ```ruby require 'mustermann' pattern = Mustermann.new('/*/**', type: :shell) ``` -------------------------------- ### Visualizing Patterns with ANSI Colors Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Shows how to use `mustermann/visualizer` to generate ANSI color-coded representations of Mustermann patterns. This is helpful for debugging and understanding pattern structures in the terminal. ```ruby require 'mustermann/visualizer' puts Mustermann.new('/:name').to_ansi ``` -------------------------------- ### Generate HTML with Stylesheet Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Generates an HTML string for a Mustermann pattern, including a CSS stylesheet for styling the syntax elements. ```ruby Mustermann.new('/:name').to_html(css: true) ``` -------------------------------- ### Instantiate and Test a Custom Pattern Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md Use `Mustermann.new` with the `type` option to create an instance of your custom pattern. Test its matching behavior. ```ruby pattern = Mustermann.new('hello world', type: :wiki) pattern === 'hello_world' # => true pattern === 'hello world' # => true pattern === 'hello-world' # => false ``` -------------------------------- ### Convert Custom Object to Pattern Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Demonstrates how Mustermann can create patterns from any object that implements the `to_pattern` method, allowing for custom pattern definitions. ```ruby require 'mustermann' class MyObject def to_pattern(**options) Mustermann.new("/foo", **options) end end object = MyObject.new Mustermann.new(object, type: :rails) # => # ``` -------------------------------- ### Shell Pattern with Alternation Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/shell.md Shows how to use the alternation syntax `{foo,bar}` within a shell pattern to match one of the specified alternatives. ```ruby require 'mustermann' pattern = Mustermann.new('/{foo,bar}', type: :shell) pattern === "/foo" # => true pattern === "/bar" # => true pattern === "/baz" # => false ``` -------------------------------- ### Inspect Mode Highlighting Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Explains how to generate highlighted pattern strings based on their `inspect` representation rather than `to_s`, using either the pattern object directly or the `Visualizer.highlight` method. ```ruby require 'mustermann/visualizer' pattern = Mustermann.new('/:name') # directly from the pattern puts pattern.to_ansi(inspect: true) # via the highlighter highlight = Mustermann::Visualizer.highlight(pattern, inspect: true) puts highlight.to_ansi ``` -------------------------------- ### Using the `node` Helper Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md The `node` helper creates an AST node and records its position. It accepts a type, arguments, and an optional block for parsing nested content. ```ruby node(type, *args, &block) ``` ```ruby on(?:) { |char| node(:capture) { scan(/\w+/) } } ``` ```ruby on(?() { |char| node(:group) { read unless scan(?)) } } ``` -------------------------------- ### Generate HTML with Custom Classes and Tags Output Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Shows the resulting HTML when custom class prefixes and tags are applied to a Mustermann pattern. ```html /:name ``` -------------------------------- ### URL Expansion with Mustermann Patterns Source: https://context7.com/sinatra/mustermann/llms.txt Use the `expand` method to generate strings from parameter hashes. You can control how extra parameters are handled using `:append` or `:ignore` options. `Mustermann::Expander` can manage multiple patterns. ```ruby require 'mustermann' pattern = Mustermann.new('/:file(.:ext)?') pattern.expand(file: 'pony') # => "/pony" pattern.expand(file: 'pony', ext: 'jpg') # => "/pony.jpg" # Handling extra parameters pattern = Mustermann.new('/:slug') pattern.expand(:append, slug: 'foo', page: '2') # => "/foo?page=2" pattern.expand(:ignore, slug: 'foo', page: '2') # => "/foo" # Expander objects for multiple patterns require 'mustermann/expander' expander = Mustermann::Expander.new expander << '/users/:user_id' expander << '/pages/:page_id' expander.expand(user_id: 15) # => "/users/15" expander.expand(page_id: 58) # => "/pages/58" # Raise on missing required keys begin pattern.expand(ext: 'jpg') rescue Mustermann::ExpandError => e e.message # => "... required segment ..." end ``` -------------------------------- ### Mustermann::FileUtils for File Operations Source: https://context7.com/sinatra/mustermann/llms.txt Provides file system operations driven by Mustermann patterns, including globbing with parameter extraction, generating shell glob patterns, and performing copy/symlink operations based on mapped paths. ```ruby require 'mustermann/file_utils' # Glob with param extraction Mustermann::FileUtils.glob(':base.:ext') do |file, params| file # => "example.txt" params # => {"base"=>"example", "ext"=>"txt"} end # Generate an equivalent shell glob pattern Mustermann::FileUtils.glob_pattern('src/:path/:file.(js|rb)') # => 'src/**/*/*.{js,rb}' # Copy, rename, symlink using pattern-mapped paths Mustermann::FileUtils.cp(':base.:ext' => ':base.bak.:ext') Mustermann::FileUtils.ln_s('lib/:name.rb' => 'bin/:name') ``` -------------------------------- ### Check for Template Generation Support Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use `respond_to?` to safely check if a pattern supports template generation before calling `to_templates`. ```ruby if pattern.respond_to? :to_templates pattern.to_templates else warn "does not support template generation" end ``` -------------------------------- ### Expand Parameters to Strings Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Generate strings from parameter hashes using the `expand` method. It uses the same interface as individual pattern expansion. ```ruby set = Mustermann::Set.new set.add('/users/:id', :users) set.add('/posts/:id', :posts) set.expand(id: '5') # => '/users/5' (first applicable pattern) set.expand(:posts, id: '5') # => '/posts/5' (patterns for a specific value) ``` -------------------------------- ### Create and Add Patterns to a Set Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Initialize a Mustermann::Set and add patterns with associated values. Use `match` to find the first matching pattern and its captured parameters. ```ruby require 'mustermann/set' set = Mustermann::Set.new set.add('/users/:id', :users_show) set.add('/posts/:id', :posts_show) set.add('/posts', :posts_index) m = set.match('/users/42') m.value # => :users_show m.params['id'] # => '42' set.match('/unknown') # => nil ``` -------------------------------- ### Hybrid Pattern: Named Captures and Splats Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/hybrid.md Demonstrates the use of named captures and splats within hybrid patterns, similar to Sinatra. Use for dynamic URL segments. ```ruby # Named captures, splats and URI template placeholders work as in sinatra pattern = Mustermann.new('/:controller(/:action(/:id))', type: :hybrid) pattern.params('/posts') # => { "controller" => "posts" } pattern.params('/posts/show') # => { "controller" => "posts", "action" => "show" } ``` ```ruby pattern = Mustermann.new('/*prefix/:name', type: :hybrid) pattern.params('/a/b/c') # => { "prefix" => "a/b", "name" => "c" } ``` -------------------------------- ### Mustermann::Visualizer for Pattern AST Rendering Source: https://context7.com/sinatra/mustermann/llms.txt Renders the internal Abstract Syntax Tree (AST) of a Mustermann pattern as syntax-highlighted HTML or ANSI output, or as a tree diagram. Useful for debugging and understanding pattern structure. ```ruby require 'mustermann/visualizer' pattern = Mustermann.new('/:name(.:ext)?') # ANSI color output for terminals puts pattern.to_ansi # HTML with inline styles (default) pattern.to_html # => '...' # HTML with CSS classes pattern.to_html(css: false) # => '...' # Full stylesheet in a separate block highlight = Mustermann::Visualizer.highlight(pattern) puts highlight.stylesheet # => CSS string puts highlight.to_html(css: false) # AST tree rendering puts pattern.to_tree # root # separator / ``` -------------------------------- ### Peeking at String Prefixes with Mustermann Source: https://context7.com/sinatra/mustermann/llms.txt Use `peek` and `peek_size` to match a prefix of a string instead of the whole string. `peek_params` returns the matched parameters and the number of characters consumed, while `peek_match` returns a match object with position information. ```ruby require 'mustermann' pattern = Mustermann.new('/:prefix') pattern.peek('/foo/bar') # => '/foo' pattern.peek_size('/foo/bar') # => 4 # peek_params returns [params_hash, chars_consumed] params, size = pattern.peek_params('/foo/bar') params # => {"prefix" => "foo"} size # => 4 rest = '/foo/bar'[size..] # => "/bar" # peek_match returns a Mustermann::Match with position info m = pattern.peek_match('/foo/bar') m[:prefix] # => "foo" m.post_match # => "/bar" ``` -------------------------------- ### Test Brace Pattern with Optional Segments and Constraints Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md Demonstrates matching and parameter extraction for a custom brace-style pattern that supports optional segments and type constraints. ```ruby p = Mustermann.new('/users/{id:int}/posts/{slug}?', type: :brace) p === '/users/42/posts/hello' # => true p === '/users/42/posts' # => true p === '/users/foo/posts' # => false p.params('/users/42/posts/hello') # => {"id" => "42", "slug" => "hello"} p.params('/users/42/posts') # => {"id" => "42", "slug" => nil} p = Mustermann.new('/files/{+rest}', type: :brace) p.params('/files/img/logo.png') # => {"rest" => ["img/logo.png"]} ``` -------------------------------- ### Create a Mustermann::Mapper with hash argument Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Initialize Mustermann::Mapper with a hash of input patterns to output patterns. Mappings are applied in insertion order. ```ruby require 'mustermann/mapper' mapper = Mustermann::Mapper.new("/:page(.:format)?" => ["/:page/view.:format", "/:page/view.html"]) mapper['/foo'] # => "/foo/view.html" mapper['/foo.xml'] # => "/foo/view.xml" mapper['/foo/bar'] # => "/foo/bar" ``` -------------------------------- ### Set Patterns with Global Options Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Apply pattern options, such as `type:`, to all patterns within a set by passing them as keyword arguments during initialization. ```ruby set = Mustermann::Set.new(type: :rails) set.add('/:controller(/:action(/:id))', :route) ``` -------------------------------- ### Configuring Mustermann::Set Matching Strategy Source: https://github.com/sinatra/mustermann/blob/main/docs/performance.md Shows how to explicitly configure the matching strategy (linear or trie) for `Mustermann::Set` using the `use_trie:` option. ```ruby # Force trie from the first pattern set = Mustermann::Set.new(use_trie: true) # Keep linear always (e.g. for a tiny router) set = Mustermann::Set.new(use_trie: false) # Switch after 20 patterns instead of the default 50 set = Mustermann::Set.new(use_trie: 20) ``` -------------------------------- ### Converting Regexp and Pattern Objects to Patterns Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Demonstrates converting `Regexp` objects and existing Mustermann patterns to new pattern objects using `to_pattern`. This allows for type conversion or re-application of pattern logic. ```ruby %r{/foo}.to_pattern # => # "/foo".to_pattern.to_pattern # => # ``` -------------------------------- ### Converting Strings and Symbols to Patterns Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Shows how to use the `to_pattern` method on strings and symbols to convert them into Mustermann pattern objects. You can specify the pattern type, like `:rails`. ```ruby require 'mustermann/to_pattern' "/foo".to_pattern # => # "/foo".to_pattern(type: :rails) # => # ``` -------------------------------- ### Cake Pattern Usage with Captures and Splats Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/cake.md Demonstrates how to use the Cake pattern for parsing URL parameters, including named captures and single/double splats. Requires the 'mustermann/cake' gem. ```ruby require 'mustermann/cake' Mustermann.new('/:name/*', type: :cake).params('/a/b/c') # => { name: 'a', splat: ['b', 'c'] } Mustermann.new('/:name/**', type: :cake).params('/a/b/c') # => { name: 'a', splat: 'b/c' } ``` -------------------------------- ### Mustermann Pyramid Pattern Usage Source: https://github.com/sinatra/mustermann/blob/main/docs/patterns/pyramid.md Demonstrates basic usage of the Mustermann Pyramid pattern for parsing URL parameters and expanding routes. Requires the 'mustermann-contrib' gem. ```ruby require 'mustermann/pyramid' Mustermann.new('/{prefix}/*suffix', type: :pyramid).params('/a/b/c') # => { prefix: 'a', suffix: ['b', 'c'] } ``` ```ruby pattern = Mustermann.new('/{name}', type: :pyramid) pattern.respond_to? :expand # => true pattern.expand(name: 'foo') # => '/foo' pattern.respond_to? :to_templates # => true pattern.to_templates # => ['/{name}'] ``` -------------------------------- ### Peek Match for Prefix Matching Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use `peek_match` to match a prefix of the input string. The remaining unmatched part of the string is available via the `post_match` attribute. ```ruby set = Mustermann::Set.new set.add('/users/:id', :users) m = set.peek_match('/users/42/posts') m.to_s # => '/users/42' m.post_match # => '/posts' m.value # => :users ``` -------------------------------- ### Generate Hansi and S-expression Strings Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Use Mustermann::Visualizer.highlight to create a highlight object and then convert it to Hansi template strings or s-expression like strings. ```ruby require 'mustermann/visualizer' highlight = Mustermann::Visualizer.highlight("/:page") puts highlight.to_hansi_template puts highlight.to_sexp ``` -------------------------------- ### Basic Mustermann Patterns Source: https://context7.com/sinatra/mustermann/llms.txt Demonstrates named segments, optional groups, splats, and alternations in Mustermann patterns. Use for basic URL routing and parameter extraction. ```ruby Mustermann.new('/:name').params('/alice') # => {"name"=>"alice"} ``` ```ruby Mustermann.new('/:foo(/:bar)').params('/x') # => {"foo"=>"x", "bar"=>nil} ``` ```ruby Mustermann.new('/:foo(/:bar)').params('/x/y') # => {"foo"=>"x", "bar"=>"y"} ``` ```ruby Mustermann.new('/*').params('/a/b/c') # => {"splat"=>["a/b/c"]} ``` ```ruby Mustermann.new('/a|/b') === '/a' # => true ``` -------------------------------- ### Test Optional Capture Pattern Source: https://github.com/sinatra/mustermann/blob/main/docs/custom-patterns.md Demonstrates matching URLs with optional capture groups using an angle-bracket pattern. ```ruby pattern = Mustermann.new('/posts//?', type: :angle) pattern.params('/posts/2024/hello') # => {"year" => "2024", "slug" => "hello"} pattern.params('/posts/2024') # => {"year" => "2024", "slug" => nil} ``` -------------------------------- ### Enable and Disable Caching in Mustermann::Set Source: https://github.com/sinatra/mustermann/blob/main/docs/performance.md Demonstrates how to initialize a Mustermann::Set with caching enabled (default) or disabled. Caching is most effective in long-running processes where the same path strings are frequently matched. ```ruby set = Mustermann::Set.new(use_cache: true) # default ``` ```ruby set = Mustermann::Set.new(use_cache: false) # disable ``` -------------------------------- ### Generate URI Templates from Pattern Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Convert a Mustermann pattern into a list of URI templates. This is useful for generating hypermedia links. ```ruby require 'mustermann' Mustermann.new("/:name").to_templates # => ["/{name}"] Mustermann.new("/:foo(@:bar)?/*baz").to_templates # => ["/{foo}@{bar}/{+baz}", "/{foo}/{+baz}"] Mustermann.new("/{name}", type: :template).to_templates # => ["/{name}"] ``` -------------------------------- ### Check Pattern Feature Support Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Use `respond_to?` to determine if a pattern object supports specific methods like `expand` or `to_templates`. Alternatively, catch `NotImplementedError` for methods that might not be supported. ```ruby require 'mustermann' pattern = Mustermann.new("/") puts "supports expanding" if pattern.respond_to? :expand puts "supports generating templates" if pattern.respond_to? :to_templates ``` ```ruby require 'mustermann' pattern = Mustermann.new("/") begin p pattern.to_templates rescue NotImplementedError puts "does not support generating templates" end ``` -------------------------------- ### StringScanner with Pattern Objects Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Shows how to use Mustermann pattern objects directly with `scan` or `check`. This is useful when patterns are pre-defined or dynamically created. ```ruby pattern = Mustermann.new(':name') scanner.check(pattern) ``` -------------------------------- ### Custom Theme with Highlight Object Source: https://github.com/sinatra/mustermann/blob/main/mustermann-contrib/README.md Applies a custom theme to a pattern using the Mustermann::Visualizer.highlight method and outputs the result as ANSI escape codes. ```ruby highlight = Mustermann::Visualizer.highlight(pattern, special: "#08f") puts highlight.to_ansi ``` -------------------------------- ### Include Git Versions with Bundler Source: https://github.com/sinatra/mustermann/blob/main/README.md Use this snippet to include the latest development versions of Mustermann and mustermann-contrib from GitHub using Bundler. This is useful for testing or using the latest features before they are released. ```ruby github 'sinatra/mustermann' do gem 'mustermann' gem 'mustermann-contrib' end ``` -------------------------------- ### Match Order With Trie (Loose) Source: https://github.com/sinatra/mustermann/blob/main/mustermann/README.md Illustrates match order when `use_trie` is true. Static segments are prioritized over dynamic segments when they overlap. ```ruby set = Mustermann::Set.new(use_trie: true) set.add("/:path", :first) set.add("/static", :second) set.add("/:path", :third) set.match("/static").value # => :second set.match_all("/static").map(&:value) # => [:second, :first, :third] ``` -------------------------------- ### Non-greedy Splat Compilation Source: https://github.com/sinatra/mustermann/blob/main/docs/performance.md Demonstrates how splat captures in Mustermann patterns compile to non-greedy regular expressions to ensure minimal consumption of characters. ```ruby Mustermann.new("/*path/:name").to_regexp # => /\A(?-mix:\/(?.*?)\/(?[^\/\?#]+))\Z/ ``` -------------------------------- ### Mustermann::Router for Rack Applications Source: https://context7.com/sinatra/mustermann/llms.txt A lightweight, Rack-compatible router built on `Mustermann::Set`. It allows defining routes with associated blocks for handling requests and can generate paths for named routes. ```ruby require 'mustermann/router' router = Mustermann::Router.new do on('/') { [200, {}, ['root']] } on('/users/:id') { |params| [200, {}, ["user #{params['id']}"]] } end # Use as a Rack app # run router # Generate paths router.path_for('users/:id', id: 42) # => "/users/42" ``` -------------------------------- ### Object Identity for Mustermann Patterns Source: https://github.com/sinatra/mustermann/blob/main/docs/performance.md Demonstrates that Mustermann.new may return the same instance for identical arguments to avoid redundant compilation. Do not rely on object identity; reuse is a performance optimization, not a guarantee. ```ruby Mustermann.new("/:name").equal? Mustermann.new("/:name") # may be true ```