rewrite in progress

This commit is contained in:
Yessiest 2023-08-29 22:41:50 +04:00
parent 161689bec0
commit 3af7a372da
38 changed files with 4861 additions and 257 deletions

View File

@ -0,0 +1,5 @@
lib/hyde.rb 6b22abff461426484b51291071193f02c2cf7850
lib/hyde/pattern_matching.rb 84399fe8cc7f55b1da9a9348759a75ba1e6374e6
lib/hyde/pattern_matching/glob.rb c8dab66857e6da3770f94ab26134ec27d262f240
lib/hyde/pattern_matching/util.rb 188dc7d5d9a9a6538a01943a83eb132c385dc092
lib/hyde/pattern_matching/rematch.rb 54a4f94791e68d85c38034d954e4c3174e01511b

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +1,8 @@
# The strange case of Dr. WEBrick and Mr. Hyde
# The strange case of Dr. Rack and Mr. Hyde
Hyde is a library that provides a DSL for creating HTTP servers. It wraps around WEBrick (this decision is subject to change), and allows for creating complex HTTP path pattern matching scenarios.
Hyde is a library that provides a DSL for creating HTTP servers. As of now it is using Rack as the webserver adapter, but ideally it shouldn't take much work to make it run on top of any webserver.
Hyde was initially designed to try the DSL features Ruby offered. When the potential of Ruby's DSL tools was realized, Hyde became an experiment in an attempt to create a backend API tool that would speed up the process of creating HTTP paths by grouping them together into `PathSpec` objects.
Since then, the goal of the project has remained largely the same - to create a tool that could be used to speed up the process of API development.
Hyde was made mostly for fun. Ideally it will become something more, but as of yet it's just an experiment revolving around Ruby Metaprogramming and its DSL capabilities.
# Examples

View File

@ -1,8 +1,12 @@
# frozen_string_literal: true
require 'rack'
require_relative 'test_app'
app = Rack::Builder.new do
use Rack::Lint
run TestApp::App.new
app = Rack::Builder.new do |builder|
builder.use Rack::Lint
builder.run (proc do |env|
pp env
[200, {"content-type" => "text/html"}, ["p","i","s","s"]]
end)
end
run app

130
doc/Hyde.html Normal file
View File

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Module: Hyde
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde";
relpath = '';
</script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="_index.html">Index (H)</a> &raquo;
<span class="title">Hyde</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Module: Hyde
</h1>
<div class="box_info">
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde.rb<span class="defines">,<br />
lib/hyde/pattern_matching.rb,<br /> lib/hyde/pattern_matching/glob.rb,<br /> lib/hyde/pattern_matching/util.rb,<br /> lib/hyde/pattern_matching/rematch.rb</span>
</dd>
</dl>
</div>
<h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>Hyde is a hideously simple ruby web framework</p>
</div>
</div>
<div class="tags">
</div><h2>Defined Under Namespace</h2>
<p class="children">
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Hyde/PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span>
<strong class="classes">Classes:</strong> <span class='object_link'><a href="Hyde/Path.html" title="Hyde::Path (class)">Path</a></span>, <span class='object_link'><a href="Hyde/PathBinding.html" title="Hyde::PathBinding (class)">PathBinding</a></span>, <span class='object_link'><a href="Hyde/Pattern.html" title="Hyde::Pattern (class)">Pattern</a></span>
</p>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

121
doc/Hyde/Path.html Normal file
View File

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Class: Hyde::Path
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../css/style.css" type="text/css" />
<link rel="stylesheet" href="../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::Path";
relpath = '../';
</script>
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../_index.html">Index (P)</a> &raquo;
<span class='title'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span>
&raquo;
<span class="title">Path</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Class: Hyde::Path
</h1>
<div class="box_info">
<dl>
<dt>Inherits:</dt>
<dd>
<span class="inheritName">Object</span>
<ul class="fullTree">
<li>Object</li>
<li class="next">Hyde::Path</li>
</ul>
<a href="#" class="inheritanceTree">show all</a>
</dd>
</dl>
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde.rb</dd>
</dl>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

121
doc/Hyde/PathBinding.html Normal file
View File

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Class: Hyde::PathBinding
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../css/style.css" type="text/css" />
<link rel="stylesheet" href="../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::PathBinding";
relpath = '../';
</script>
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../_index.html">Index (P)</a> &raquo;
<span class='title'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span>
&raquo;
<span class="title">PathBinding</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Class: Hyde::PathBinding
</h1>
<div class="box_info">
<dl>
<dt>Inherits:</dt>
<dd>
<span class="inheritName">Object</span>
<ul class="fullTree">
<li>Object</li>
<li class="next">Hyde::PathBinding</li>
</ul>
<a href="#" class="inheritanceTree">show all</a>
</dd>
</dl>
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde.rb</dd>
</dl>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

563
doc/Hyde/Pattern.html Normal file
View File

@ -0,0 +1,563 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Class: Hyde::Pattern
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../css/style.css" type="text/css" />
<link rel="stylesheet" href="../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::Pattern";
relpath = '../';
</script>
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../_index.html">Index (P)</a> &raquo;
<span class='title'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span>
&raquo;
<span class="title">Pattern</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Class: Hyde::Pattern
</h1>
<div class="box_info">
<dl>
<dt>Inherits:</dt>
<dd>
<span class="inheritName">Object</span>
<ul class="fullTree">
<li>Object</li>
<li class="next">Hyde::Pattern</li>
</ul>
<a href="#" class="inheritanceTree">show all</a>
</dd>
</dl>
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde/pattern_matching.rb</dd>
</dl>
</div>
<h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>Delegate class for all available patterns. Picks appropriate pattern based on contents.</p>
</div>
</div>
<div class="tags">
</div>
<h2>
Instance Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#initialize-instance_method" title="#initialize (instance method)">#<strong>initialize</strong>(pattern) &#x21d2; Pattern </a>
</span>
<span class="note title constructor">constructor</span>
<span class="summary_desc"><div class='inline'>
<p>A new instance of Pattern.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match-instance_method" title="#match (instance method)">#<strong>match</strong>(input) &#x21d2; Array(String,Array,Hash), FalseClass </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Match the string and assign matches to parameters.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match%3F-instance_method" title="#match? (instance method)">#<strong>match?</strong>(input) &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Test if a string can be matched.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#static%3F-instance_method" title="#static? (instance method)">#<strong>static?</strong> &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Checks if pattern object is static (is a simple String pattern).</p>
</div></span>
</li>
</ul>
<div id="constructor_details" class="method_details_list">
<h2>Constructor Details</h2>
<div class="method_details first">
<h3 class="signature first" id="initialize-instance_method">
#<strong>initialize</strong>(pattern) &#x21d2; <tt><span class='object_link'><a href="" title="Hyde::Pattern (class)">Pattern</a></span></tt>
</h3><div class="docstring">
<div class="discussion">
<p>Returns a new instance of Pattern.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>pattern</span>
<span class='type'>(<tt>Object</tt>)</span>
&mdash;
<div class='inline'>
<p>object to generate pattern from</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
17
18
19
20</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching.rb', line 17</span>
<span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span><span class='lparen'>(</span><span class='id identifier rubyid_pattern'>pattern</span><span class='rparen'>)</span>
<span class='ivar'>@pattern</span> <span class='op'>=</span> <span class='id identifier rubyid_patternify'>patternify</span><span class='lparen'>(</span><span class='id identifier rubyid_pattern'>pattern</span><span class='rparen'>)</span>
<span class='ivar'>@static</span> <span class='op'>=</span> <span class='ivar'>@pattern</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span> <span class='const'>String</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
<div id="instance_method_details" class="method_details_list">
<h2>Instance Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="match-instance_method">
#<strong>match</strong>(input) &#x21d2; <tt>Array(String,Array,Hash)</tt>, <tt>FalseClass</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Match the string and assign matches to parameters. Returns:</p>
<ul><li>
<p>Unmatched part of a string</p>
</li><li>
<p>Unnamed parameters</p>
</li><li>
<p>Named parameters</p>
</li></ul>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Array(String,Array,Hash)</tt>)</span>
</li>
<li>
<span class='type'>(<tt>FalseClass</tt>)</span>
&mdash;
<div class='inline'>
<p>if input doesnt match pattern</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
36
37
38
39
40
41
42
43
44
45
46
47</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching.rb', line 36</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='kw'>if</span> <span class='ivar'>@pattern</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span> <span class='const'>String</span>
<span class='id identifier rubyid_input'>input</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='kw'>if</span> <span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_start_with?'>start_with?</span><span class='lparen'>(</span><span class='ivar'>@pattern</span><span class='rparen'>)</span>
<span class='lbracket'>[</span><span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_delete_prefix'>delete_prefix</span><span class='lparen'>(</span><span class='ivar'>@pattern</span><span class='rparen'>)</span><span class='comma'>,</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rbracket'>]</span>
<span class='kw'>else</span>
<span class='kw'>false</span>
<span class='kw'>end</span>
<span class='kw'>else</span>
<span class='ivar'>@pattern</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='kw'>end</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
<div class="method_details ">
<h3 class="signature " id="match?-instance_method">
#<strong>match?</strong>(input) &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Test if a string can be matched. Lighter version of match that doesnt assign any variables.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
53
54
55
56
57
58
59</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching.rb', line 53</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match?'>match?</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='kw'>if</span> <span class='ivar'>@pattern</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span> <span class='const'>String</span>
<span class='const'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_start_with?'>start_with?</span> <span class='id identifier rubyid_pattern'>pattern</span>
<span class='kw'>else</span>
<span class='ivar'>@pattern</span><span class='period'>.</span><span class='id identifier rubyid_match?'>match?</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='kw'>end</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
<div class="method_details ">
<h3 class="signature " id="static?-instance_method">
#<strong>static?</strong> &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Checks if pattern object is static (is a simple String pattern).</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
23
24
25</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching.rb', line 23</span>
<span class='kw'>def</span> <span class='id identifier rubyid_static?'>static?</span>
<span class='ivar'>@static</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,242 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Module: Hyde::PatternMatching
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../css/style.css" type="text/css" />
<link rel="stylesheet" href="../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::PatternMatching";
relpath = '../';
</script>
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../_index.html">Index (P)</a> &raquo;
<span class='title'><span class='object_link'><a href="../Hyde.html" title="Hyde (module)">Hyde</a></span></span>
&raquo;
<span class="title">PatternMatching</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Module: Hyde::PatternMatching
</h1>
<div class="box_info">
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde/pattern_matching.rb<span class="defines">,<br />
lib/hyde/pattern_matching/glob.rb,<br /> lib/hyde/pattern_matching/util.rb,<br /> lib/hyde/pattern_matching/rematch.rb</span>
</dd>
</dl>
</div>
<h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>Utility functions and pattern-generator classes. Used primarily to create patterns for path definitions.</p>
</div>
</div>
<div class="tags">
</div><h2>Defined Under Namespace</h2>
<p class="children">
<strong class="classes">Classes:</strong> <span class='object_link'><a href="PatternMatching/Glob.html" title="Hyde::PatternMatching::Glob (class)">Glob</a></span>, <span class='object_link'><a href="PatternMatching/ReMatch.html" title="Hyde::PatternMatching::ReMatch (class)">ReMatch</a></span>
</p>
<h2>
Class Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#canonicalize-class_method" title="canonicalize (class method)">.<strong>canonicalize</strong>(string) &#x21d2; String </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Strips extra slashes from a string.</p>
</div></span>
</li>
</ul>
<div id="class_method_details" class="method_details_list">
<h2>Class Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="canonicalize-class_method">
.<strong>canonicalize</strong>(string) &#x21d2; <tt>String</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Strips extra slashes from a string. (including slashes at the start and end of the string)</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>string</span>
<span class='type'>(<tt>String</tt>)</span>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>String</tt>)</span>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
9
10
11
12
13</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/util.rb', line 9</span>
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'>canonicalize</span><span class='lparen'>(</span><span class='id identifier rubyid_string'>string</span><span class='rparen'>)</span>
<span class='id identifier rubyid_string'>string</span><span class='period'>.</span><span class='id identifier rubyid_gsub'>gsub</span><span class='lparen'>(</span><span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>\/+</span><span class='regexp_end'>/</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>/</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
<span class='period'>.</span><span class='id identifier rubyid_delete_prefix'>delete_prefix</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>/</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
<span class='period'>.</span><span class='id identifier rubyid_delete_suffix'>delete_suffix</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>/</span><span class='tstring_end'>&quot;</span></span><span class='rparen'>)</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,651 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Class: Hyde::PatternMatching::Glob
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../../css/style.css" type="text/css" />
<link rel="stylesheet" href="../../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::PatternMatching::Glob";
relpath = '../../';
</script>
<script type="text/javascript" charset="utf-8" src="../../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../../_index.html">Index (G)</a> &raquo;
<span class='title'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span> &raquo; <span class='title'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span>
&raquo;
<span class="title">Glob</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Class: Hyde::PatternMatching::Glob
</h1>
<div class="box_info">
<dl>
<dt>Inherits:</dt>
<dd>
<span class="inheritName">Object</span>
<ul class="fullTree">
<li>Object</li>
<li class="next">Hyde::PatternMatching::Glob</li>
</ul>
<a href="#" class="inheritanceTree">show all</a>
</dd>
</dl>
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde/pattern_matching/glob.rb</dd>
</dl>
</div>
<h2>Overview</h2><div class="docstring">
<div class="discussion">
<p>Implements glob-like pattern matching. Exact specifications for globbing rules:</p>
<p>“/”</p>
<pre class="code ruby"><code class="ruby">- act as directory separators
- multiple slashes (i.e. &quot;///&quot;) are the same as one slash (&quot;/&quot;)
- slashes are stripped at start and end of an expression or path
- slashes are not matched by anything but the globstar (&quot;**&quot;)
</code></pre>
<p>“*” ( regexp: /([^/]*)/ )</p>
<pre class="code ruby"><code class="ruby">- matches from 0 to any number of characters
- does not match nothing if placed between two slashes (i.e &quot;/*/&quot;)
- result is captured in an array
- stops at slashes
- greedy (matches as much as possible)
</code></pre>
<p>“**” ( regexp: /(.*)/ )</p>
<pre class="code ruby"><code class="ruby">- matches any number of characters
- matches slashes (&quot;/&quot;)
- result is captured in an array
- does not stop at slashes
- greedy (matches as much as possible)
</code></pre>
<p>“[…]+” ( regexp: itself, ! and ^ at the start are interchangeable )</p>
<pre class="code ruby"><code class="ruby">- acts like a regexp range
- matches any characters, including slashes if specified
- matches any number of characters
- valid ways to specify a range: [A-z], [a-z], [9-z] (ascii order)
- ! or ^ at the start invert meaning (any character not in range)
- result is captured in an array
</code></pre>
<p>“:name” ( regexp: acts like a named group for /[^/]*/ )</p>
<pre class="code ruby"><code class="ruby">- acts like * as defined above
- result is captured in a hash with &quot;name&quot; as key
- name allows alphanumeric characters and underscores
- ignored unless placed between two slashes
</code></pre>
<p>“(name|name2|…)” ( regexp: itself )</p>
<pre class="code ruby"><code class="ruby">- matches any of (full keywords) name, name2, ...
- result is captured in an array
- each name may include only these groups of characters:
- alphanumeric
- slashes
- underscores
- dashes
</code></pre>
</div>
</div>
<div class="tags">
</div>
<h2>
Class Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#can_convert%3F-class_method" title="can_convert? (class method)">.<strong>can_convert?</strong>(input) &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Test if input is convertible to a Glob and if it should be converted.</p>
</div></span>
</li>
</ul>
<h2>
Instance Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#initialize-instance_method" title="#initialize (instance method)">#<strong>initialize</strong>(pattern) &#x21d2; Glob </a>
</span>
<span class="note title constructor">constructor</span>
<span class="summary_desc"><div class='inline'>
<p>A new instance of Glob.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match-instance_method" title="#match (instance method)">#<strong>match</strong>(input) &#x21d2; Array(String,Array,Hash), FalseClass </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Match the string and assign matches to parameters.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match%3F-instance_method" title="#match? (instance method)">#<strong>match?</strong>(input) &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Test if a string can be matched.</p>
</div></span>
</li>
</ul>
<div id="constructor_details" class="method_details_list">
<h2>Constructor Details</h2>
<div class="method_details first">
<h3 class="signature first" id="initialize-instance_method">
#<strong>initialize</strong>(pattern) &#x21d2; <tt><span class='object_link'><a href="" title="Hyde::PatternMatching::Glob (class)">Glob</a></span></tt>
</h3><div class="docstring">
<div class="discussion">
<p>Returns a new instance of Glob.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>Glob pattern</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
56
57
58
59
60
61
62
63</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/glob.rb', line 56</span>
<span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span><span class='lparen'>(</span><span class='id identifier rubyid_pattern'>pattern</span><span class='rparen'>)</span>
<span class='id identifier rubyid_pattern'>pattern</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="../PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_pattern'>pattern</span><span class='rparen'>)</span>
<span class='id identifier rubyid_pieces'>pieces</span> <span class='op'>=</span> <span class='id identifier rubyid_pattern'>pattern</span><span class='period'>.</span><span class='id identifier rubyid_split'>split</span><span class='lparen'>(</span><span class='const'>TOKENS</span><span class='rparen'>)</span>
<span class='comment'># @type [Array&lt;String,Integer&gt;]
</span> <span class='ivar'>@index</span> <span class='op'>=</span> <span class='id identifier rubyid_build_index'>build_index</span><span class='lparen'>(</span><span class='id identifier rubyid_pieces'>pieces</span><span class='rparen'>)</span>
<span class='comment'># @type [Regexp]
</span> <span class='ivar'>@glob</span> <span class='op'>=</span> <span class='id identifier rubyid_build_regexp'>build_regexp</span><span class='lparen'>(</span><span class='id identifier rubyid_pieces'>pieces</span><span class='rparen'>)</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
<div id="class_method_details" class="method_details_list">
<h2>Class Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="can_convert?-class_method">
.<strong>can_convert?</strong>(input) &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Test if input is convertible to a Glob and if it should be converted</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'></span>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
&mdash;
<div class='inline'>
<p>Input can be safely converted to Glob</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
96
97
98
99</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/glob.rb', line 96</span>
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_can_convert?'>can_convert?</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span> <span class='const'>String</span> <span class='kw'>and</span>
<span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_match?'>match?</span><span class='lparen'>(</span><span class='const'>TOKENS</span><span class='rparen'>)</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
<div id="instance_method_details" class="method_details_list">
<h2>Instance Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="match-instance_method">
#<strong>match</strong>(input) &#x21d2; <tt>Array(String,Array,Hash)</tt>, <tt>FalseClass</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Match the string and assign matches to parameters. Returns:</p>
<ul><li>
<p>Unmatched part of a string</p>
</li><li>
<p>Unnamed parameters</p>
</li><li>
<p>Named parameters</p>
</li></ul>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Array(String,Array,Hash)</tt>)</span>
</li>
<li>
<span class='type'>(<tt>FalseClass</tt>)</span>
&mdash;
<div class='inline'>
<p>if input doesnt match glob</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
74
75
76
77
78
79
80
81
82</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/glob.rb', line 74</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_input'>input</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="../PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='ivar'>@glob</span><span class='rparen'>)</span>
<span class='kw'>return</span> <span class='kw'>false</span> <span class='kw'>unless</span> <span class='id identifier rubyid_result'>result</span>
<span class='id identifier rubyid_input'>input</span> <span class='op'>=</span> <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_post_match'>post_match</span>
<span class='id identifier rubyid_named_params'>named_params</span><span class='comma'>,</span> <span class='id identifier rubyid_params'>params</span> <span class='op'>=</span> <span class='id identifier rubyid_assign_by_index'>assign_by_index</span><span class='lparen'>(</span><span class='ivar'>@index</span><span class='comma'>,</span> <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_captures'>captures</span><span class='rparen'>)</span>
<span class='lbracket'>[</span><span class='id identifier rubyid_input'>input</span><span class='comma'>,</span> <span class='id identifier rubyid_params'>params</span><span class='comma'>,</span> <span class='id identifier rubyid_named_params'>named_params</span><span class='rbracket'>]</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
<div class="method_details ">
<h3 class="signature " id="match?-instance_method">
#<strong>match?</strong>(input) &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Test if a string can be matched. Lighter version of match that doesnt assign any variables.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
88
89
90
91</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/glob.rb', line 88</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match?'>match?</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_input'>input</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="../PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_match?'>match?</span> <span class='ivar'>@glob</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,569 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Class: Hyde::PatternMatching::ReMatch
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="../../css/style.css" type="text/css" />
<link rel="stylesheet" href="../../css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "Hyde::PatternMatching::ReMatch";
relpath = '../../';
</script>
<script type="text/javascript" charset="utf-8" src="../../js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="../../js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="../../class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="../../_index.html">Index (R)</a> &raquo;
<span class='title'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span> &raquo; <span class='title'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span>
&raquo;
<span class="title">ReMatch</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="../../class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Class: Hyde::PatternMatching::ReMatch
</h1>
<div class="box_info">
<dl>
<dt>Inherits:</dt>
<dd>
<span class="inheritName">Object</span>
<ul class="fullTree">
<li>Object</li>
<li class="next">Hyde::PatternMatching::ReMatch</li>
</ul>
<a href="#" class="inheritanceTree">show all</a>
</dd>
</dl>
<dl>
<dt>Defined in:</dt>
<dd>lib/hyde/pattern_matching/rematch.rb</dd>
</dl>
</div>
<h2>Overview</h2><div class="docstring">
<div class="discussion">
<div class="note notetag">
<strong>Note:</strong>
<div class='inline'>
<p>If you are planning to write your own pattern, this is the easiest one to read.</p>
</div>
</div>
<p>Regexp pattern matching wrapper. Following principles apply to the wrapper:</p>
<ul><li>
<p>Regexp input is canonicalized using Hyde::PatternMatching.canonicalize</p>
</li><li>
<p>Matched content and anything before it is consumed in #match output</p>
</li></ul>
</div>
</div>
<div class="tags">
</div>
<h2>
Class Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#can_convert%3F-class_method" title="can_convert? (class method)">.<strong>can_convert?</strong>(string) &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Test if input is convertible and if it should be converted.</p>
</div></span>
</li>
</ul>
<h2>
Instance Method Summary
<small><a href="#" class="summary_toggle">collapse</a></small>
</h2>
<ul class="summary">
<li class="public ">
<span class="summary_signature">
<a href="#initialize-instance_method" title="#initialize (instance method)">#<strong>initialize</strong>(pattern) &#x21d2; ReMatch </a>
</span>
<span class="note title constructor">constructor</span>
<span class="summary_desc"><div class='inline'>
<p>A new instance of ReMatch.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match-instance_method" title="#match (instance method)">#<strong>match</strong>(input) &#x21d2; Array(String,Array,Hash), FalseClass </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Match the string and assign matches to parameters.</p>
</div></span>
</li>
<li class="public ">
<span class="summary_signature">
<a href="#match%3F-instance_method" title="#match? (instance method)">#<strong>match?</strong>(input) &#x21d2; Boolean </a>
</span>
<span class="summary_desc"><div class='inline'>
<p>Test if a string can be matched.</p>
</div></span>
</li>
</ul>
<div id="constructor_details" class="method_details_list">
<h2>Constructor Details</h2>
<div class="method_details first">
<h3 class="signature first" id="initialize-instance_method">
#<strong>initialize</strong>(pattern) &#x21d2; <tt><span class='object_link'><a href="" title="Hyde::PatternMatching::ReMatch (class)">ReMatch</a></span></tt>
</h3><div class="docstring">
<div class="discussion">
<p>Returns a new instance of ReMatch.</p>
</div>
</div>
<div class="tags">
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
13
14
15</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/rematch.rb', line 13</span>
<span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span><span class='lparen'>(</span><span class='id identifier rubyid_pattern'>pattern</span><span class='rparen'>)</span>
<span class='ivar'>@glob</span> <span class='op'>=</span> <span class='id identifier rubyid_pattern'>pattern</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
<div id="class_method_details" class="method_details_list">
<h2>Class Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="can_convert?-class_method">
.<strong>can_convert?</strong>(string) &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Test if input is convertible and if it should be converted.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'></span>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
&mdash;
<div class='inline'>
<p>Input can be safely converted to Glob</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
44
45
46</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/rematch.rb', line 44</span>
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_can_convert?'>can_convert?</span><span class='lparen'>(</span><span class='id identifier rubyid_string'>string</span><span class='rparen'>)</span>
<span class='id identifier rubyid_string'>string</span><span class='period'>.</span><span class='id identifier rubyid_is_a?'>is_a?</span> <span class='const'>Regexp</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
<div id="instance_method_details" class="method_details_list">
<h2>Instance Method Details</h2>
<div class="method_details first">
<h3 class="signature first" id="match-instance_method">
#<strong>match</strong>(input) &#x21d2; <tt>Array(String,Array,Hash)</tt>, <tt>FalseClass</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Match the string and assign matches to parameters. Returns:</p>
<ul><li>
<p>Unmatched part of a string</p>
</li><li>
<p>Unnamed parameters</p>
</li><li>
<p>Named parameters</p>
</li></ul>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Array(String,Array,Hash)</tt>)</span>
</li>
<li>
<span class='type'>(<tt>FalseClass</tt>)</span>
&mdash;
<div class='inline'>
<p>if input doesnt match regexp</p>
</div>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
26
27
28
29
30
31</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/rematch.rb', line 26</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="../PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span><span class='lparen'>(</span><span class='ivar'>@glob</span><span class='rparen'>)</span>
<span class='kw'>return</span> <span class='kw'>false</span> <span class='kw'>unless</span> <span class='id identifier rubyid_result'>result</span>
<span class='lbracket'>[</span><span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_post_match'>post_match</span><span class='comma'>,</span> <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_captures'>captures</span><span class='comma'>,</span> <span class='id identifier rubyid_result'>result</span><span class='period'>.</span><span class='id identifier rubyid_named_captures'>named_captures</span><span class='rbracket'>]</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
<div class="method_details ">
<h3 class="signature " id="match?-instance_method">
#<strong>match?</strong>(input) &#x21d2; <tt>Boolean</tt>
</h3><div class="docstring">
<div class="discussion">
<p>Test if a string can be matched. Lighter version of match that doesnt assign any variables.</p>
</div>
</div>
<div class="tags">
<p class="tag_title">Parameters:</p>
<ul class="param">
<li>
<span class='name'>input</span>
<span class='type'>(<tt>String</tt>)</span>
&mdash;
<div class='inline'>
<p>String to match</p>
</div>
</li>
</ul>
<p class="tag_title">Returns:</p>
<ul class="return">
<li>
<span class='type'>(<tt>Boolean</tt>)</span>
</li>
</ul>
</div><table class="source_code">
<tr>
<td>
<pre class="lines">
37
38
39</pre>
</td>
<td>
<pre class="code"><span class="info file"># File 'lib/hyde/pattern_matching/rematch.rb', line 37</span>
<span class='kw'>def</span> <span class='id identifier rubyid_match?'>match?</span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span>
<span class='const'><span class='object_link'><a href="../../Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="../PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span></span><span class='period'>.</span><span class='id identifier rubyid_canonicalize'><span class='object_link'><a href="../PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_input'>input</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_match?'>match?</span> <span class='ivar'>@glob</span>
<span class='kw'>end</span></pre>
</td>
</tr>
</table>
</div>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:24 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

173
doc/_index.html Normal file
View File

@ -0,0 +1,173 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/common.css" type="text/css" />
<script type="text/javascript">
pathId = null;
relpath = '';
</script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1 class="noborder title">Documentation by YARD 0.9.34</h1>
<div id="listing">
<h1 class="alphaindex">Alphabetic Index</h1>
<h2>File Listing</h2>
<ul id="files" class="index_inline_list">
<li class="r1"><a href="index.html" title="README">README</a></li>
</ul>
<div class="clear"></div>
<h2>Namespace Listing A-Z</h2>
<table>
<tr>
<td valign='top' width="33%">
<ul id="alpha_G" class="alpha">
<li class="letter">G</li>
<ul>
<li>
<span class='object_link'><a href="Hyde/PatternMatching/Glob.html" title="Hyde::PatternMatching::Glob (class)">Glob</a></span>
<small>(Hyde::PatternMatching)</small>
</li>
</ul>
</ul>
<ul id="alpha_H" class="alpha">
<li class="letter">H</li>
<ul>
<li>
<span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span>
</li>
</ul>
</ul>
<ul id="alpha_P" class="alpha">
<li class="letter">P</li>
<ul>
<li>
<span class='object_link'><a href="Hyde/Path.html" title="Hyde::Path (class)">Path</a></span>
<small>(Hyde)</small>
</li>
<li>
<span class='object_link'><a href="Hyde/PathBinding.html" title="Hyde::PathBinding (class)">PathBinding</a></span>
<small>(Hyde)</small>
</li>
<li>
<span class='object_link'><a href="Hyde/Pattern.html" title="Hyde::Pattern (class)">Pattern</a></span>
<small>(Hyde)</small>
</li>
<li>
<span class='object_link'><a href="Hyde/PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span>
<small>(Hyde)</small>
</li>
</ul>
</ul>
<ul id="alpha_R" class="alpha">
<li class="letter">R</li>
<ul>
<li>
<span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html" title="Hyde::PatternMatching::ReMatch (class)">ReMatch</a></span>
<small>(Hyde::PatternMatching)</small>
</li>
</ul>
</ul>
</td>
</tr>
</table>
</div>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:23 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

51
doc/class_list.html Normal file
View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
<title>Class List</title>
<base id="base_target" target="_parent" />
</head>
<body>
<div id="content">
<div class="fixed_header">
<h1 id="full_list_header">Class List</h1>
<div id="full_list_nav">
<span><a target="_self" href="class_list.html">
Classes
</a></span>
<span><a target="_self" href="method_list.html">
Methods
</a></span>
<span><a target="_self" href="file_list.html">
Files
</a></span>
</div>
<div id="search">Search: <input type="text" /></div>
</div>
<ul id="full_list" class="class">
<li id="object_" class="odd"><div class="item" style="padding-left:30px"><span class='object_link'><a href="top-level-namespace.html" title="Top Level Namespace (root)">Top Level Namespace</a></span></div></li>
<li id='object_Hyde' class='even'><div class='item' style='padding-left:30px'><a class='toggle'></a> <span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span><small class='search_info'>Top Level Namespace</small></div><ul><li id='object_Hyde::Path' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Hyde/Path.html" title="Hyde::Path (class)">Path</a></span> &lt; Object<small class='search_info'>Hyde</small></div></li><li id='object_Hyde::PathBinding' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Hyde/PathBinding.html" title="Hyde::PathBinding (class)">PathBinding</a></span> &lt; Object<small class='search_info'>Hyde</small></div></li><li id='object_Hyde::Pattern' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Hyde/Pattern.html" title="Hyde::Pattern (class)">Pattern</a></span> &lt; Object<small class='search_info'>Hyde</small></div></li><li id='object_Hyde::PatternMatching' class='collapsed even'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Hyde/PatternMatching.html" title="Hyde::PatternMatching (module)">PatternMatching</a></span><small class='search_info'>Hyde</small></div><ul><li id='object_Hyde::PatternMatching::Glob' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Hyde/PatternMatching/Glob.html" title="Hyde::PatternMatching::Glob (class)">Glob</a></span> &lt; Object<small class='search_info'>Hyde::PatternMatching</small></div></li><li id='object_Hyde::PatternMatching::ReMatch' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html" title="Hyde::PatternMatching::ReMatch (class)">ReMatch</a></span> &lt; Object<small class='search_info'>Hyde::PatternMatching</small></div></li></ul></li></ul></li>
</ul>
</div>
</body>
</html>

1
doc/css/common.css Normal file
View File

@ -0,0 +1 @@
/* Override this file with custom rules */

58
doc/css/full_list.css Normal file
View File

@ -0,0 +1,58 @@
body {
margin: 0;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-size: 13px;
height: 101%;
overflow-x: hidden;
background: #fafafa;
}
h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; }
.clear { clear: both; }
.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; }
#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; }
#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; }
#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; }
#full_list ul { padding: 0; }
#full_list li { padding: 0; margin: 0; list-style: none; }
#full_list li .item { padding: 5px 5px 5px 12px; }
#noresults { padding: 7px 12px; background: #fff; }
#content.insearch #noresults { margin-left: 7px; }
li.collapsed ul { display: none; }
li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; }
li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; }
li { color: #888; cursor: pointer; }
li.deprecated { text-decoration: line-through; font-style: italic; }
li.odd { background: #f0f0f0; }
li.even { background: #fafafa; }
.item:hover { background: #ddd; }
li small:before { content: "("; }
li small:after { content: ")"; }
li small.search_info { display: none; }
a, a:visited { text-decoration: none; color: #05a; }
li.clicked > .item { background: #05a; color: #ccc; }
li.clicked > .item a, li.clicked > .item a:visited { color: #eee; }
li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; }
li.collapsed.clicked a.toggle { background-position: top right; }
#search input { border: 1px solid #bbb; border-radius: 3px; }
#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; }
#full_list_nav a, #nav a:visited { color: #358; }
#full_list_nav a:hover { background: transparent; color: #5af; }
#full_list_nav span:after { content: ' | '; }
#full_list_nav span:last-child:after { content: ''; }
#content h1 { margin-top: 0; }
li { white-space: nowrap; cursor: normal; }
li small { display: block; font-size: 0.8em; }
li small:before { content: ""; }
li small:after { content: ""; }
li small.search_info { display: none; }
#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; }
#content.insearch #search { background-position: center right; }
#search input { width: 110px; }
#full_list.insearch ul { display: block; }
#full_list.insearch .item { display: none; }
#full_list.insearch .found { display: block; padding-left: 11px !important; }
#full_list.insearch li a.toggle { display: none; }
#full_list.insearch li small.search_info { display: block; }

497
doc/css/style.css Normal file
View File

@ -0,0 +1,497 @@
html {
width: 100%;
height: 100%;
}
body {
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-size: 13px;
width: 100%;
margin: 0;
padding: 0;
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
}
#nav {
position: relative;
width: 100%;
height: 100%;
border: 0;
border-right: 1px dotted #eee;
overflow: auto;
}
.nav_wrap {
margin: 0;
padding: 0;
width: 20%;
height: 100%;
position: relative;
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
flex-shrink: 0;
-webkit-flex-shrink: 0;
-ms-flex: 1 0;
}
#resizer {
position: absolute;
right: -5px;
top: 0;
width: 10px;
height: 100%;
cursor: col-resize;
z-index: 9999;
}
#main {
flex: 5 1;
-webkit-flex: 5 1;
-ms-flex: 5 1;
outline: none;
position: relative;
background: #fff;
padding: 1.2em;
padding-top: 0.2em;
box-sizing: border-box;
}
@media (max-width: 920px) {
.nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; }
#resizer { display: none; }
#nav {
z-index: 9999;
background: #fff;
display: none;
position: absolute;
top: 40px;
right: 12px;
width: 500px;
max-width: 80%;
height: 80%;
overflow-y: scroll;
border: 1px solid #999;
border-collapse: collapse;
box-shadow: -7px 5px 25px #aaa;
border-radius: 2px;
}
}
@media (min-width: 920px) {
body { height: 100%; overflow: hidden; }
#main { height: 100%; overflow: auto; }
#search { display: none; }
}
#main img { max-width: 100%; }
h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; }
h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; }
h1.title { margin-bottom: 10px; }
h1.alphaindex { margin-top: 0; font-size: 22px; }
h2 {
padding: 0;
padding-bottom: 3px;
border-bottom: 1px #aaa solid;
font-size: 1.4em;
margin: 1.8em 0 0.5em;
position: relative;
}
h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; }
h2 small a {
display: block;
height: 20px;
border: 1px solid #aaa;
border-bottom: 0;
border-top-left-radius: 5px;
background: #f8f8f8;
position: relative;
padding: 2px 7px;
}
.clear { clear: both; }
.inline { display: inline; }
.inline p:first-child { display: inline; }
.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; }
.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt {
color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em;
border-radius: 4px;
}
.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; }
.docstring h1 { font-size: 1.2em; }
.docstring h2 { font-size: 1.1em; }
.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; }
.summary_desc .object_link a, .docstring .object_link a {
font-family: monospace; font-size: 1.05em;
color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em;
border-radius: 4px;
}
.rdoc-term { padding-right: 25px; font-weight: bold; }
.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; }
.summary_desc pre.code .object_link a, .docstring pre.code .object_link a {
padding: 0px; background: inherit; color: inherit; border-radius: inherit;
}
/* style for <table> */
#filecontents table, .docstring table { border-collapse: collapse; }
#filecontents table th, #filecontents table td,
.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; }
#filecontents table tr:nth-child(odd),
.docstring table tr:nth-child(odd) { background: #eee; }
#filecontents table tr:nth-child(even),
.docstring table tr:nth-child(even) { background: #fff; }
#filecontents table th, .docstring table th { background: #fff; }
/* style for <ul> */
#filecontents li > p, .docstring li > p { margin: 0px; }
#filecontents ul, .docstring ul { padding-left: 20px; }
/* style for <dl> */
#filecontents dl, .docstring dl { border: 1px solid #ccc; }
#filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; }
#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; }
#filecontents dd > p, .docstring dd > p { margin: 0px; }
.note {
color: #222;
margin: 20px 0;
padding: 10px;
border: 1px solid #eee;
border-radius: 3px;
display: block;
}
.docstring .note {
border-left-color: #ccc;
border-left-width: 5px;
}
.note.todo { background: #ffffc5; border-color: #ececaa; }
.note.returns_void { background: #efefef; }
.note.deprecated { background: #ffe5e5; border-color: #e9dada; }
.note.title.deprecated { background: #ffe5e5; border-color: #e9dada; }
.note.private { background: #ffffc5; border-color: #ececaa; }
.note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; }
.summary_signature + .note.title { margin-left: 7px; }
h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; }
.note.title { background: #efefef; }
.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; }
.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.private { background: #d5d5d5; border-color: #c5c5c5; }
.note.title.not_defined_here { background: transparent; border: none; font-style: italic; }
.discussion .note { margin-top: 6px; }
.discussion .note:first-child { margin-top: 0; }
h3.inherited {
font-style: italic;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-weight: normal;
padding: 0;
margin: 0;
margin-top: 12px;
margin-bottom: 3px;
font-size: 13px;
}
p.inherited {
padding: 0;
margin: 0;
margin-left: 25px;
}
.box_info dl {
margin: 0;
border: 0;
width: 100%;
font-size: 1em;
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
}
.box_info dl dt {
flex-shrink: 0;
-webkit-flex-shrink: 1;
-ms-flex-shrink: 1;
width: 100px;
text-align: right;
font-weight: bold;
border: 1px solid #aaa;
border-width: 1px 0px 0px 1px;
padding: 6px 0;
padding-right: 10px;
}
.box_info dl dd {
flex-grow: 1;
-webkit-flex-grow: 1;
-ms-flex: 1;
max-width: 420px;
padding: 6px 0;
padding-right: 20px;
border: 1px solid #aaa;
border-width: 1px 1px 0 0;
overflow: hidden;
position: relative;
}
.box_info dl:last-child > * {
border-bottom: 1px solid #aaa;
}
.box_info dl:nth-child(odd) > * { background: #eee; }
.box_info dl:nth-child(even) > * { background: #fff; }
.box_info dl > * { margin: 0; }
ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; }
.index_inline_list { padding-left: 0; font-size: 1.1em; }
.index_inline_list li {
list-style: none;
display: inline-block;
padding: 0 12px;
line-height: 30px;
margin-bottom: 5px;
}
dl.constants { margin-left: 10px; }
dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; }
dl.constants.compact dt { display: inline-block; font-weight: normal }
dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; }
dl.constants .docstring .note:first-child { margin-top: 5px; }
.summary_desc {
margin-left: 32px;
display: block;
font-family: sans-serif;
font-size: 1.1em;
margin-top: 8px;
line-height: 1.5145em;
margin-bottom: 0.8em;
}
.summary_desc tt { font-size: 0.9em; }
dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; }
dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; }
dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; }
dl.constants .discussion *:first-child { margin-top: 0; }
dl.constants .discussion *:last-child { margin-bottom: 0; }
.method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; }
.method_details.first { border: 0; margin-top: 5px; }
.method_details.first h3.signature { margin-top: 1em; }
p.signature, h3.signature {
font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace;
padding: 6px 10px; margin-top: 1em;
background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px;
}
p.signature tt,
h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; }
p.signature .overload,
h3.signature .overload { display: block; }
p.signature .extras,
h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; }
p.signature .not_defined_here,
h3.signature .not_defined_here,
p.signature .aliases,
h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; }
p.signature .aliases .names,
h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; }
.tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; }
.tags .tag_title tt { color: initial; padding: initial; background: initial; }
.tags ul { margin-top: 5px; padding-left: 30px; list-style: square; }
.tags ul li { margin-bottom: 3px; }
.tags ul .name { font-family: monospace; font-weight: bold; }
.tags ul .note { padding: 3px 6px; }
.tags { margin-bottom: 12px; }
.tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; }
.tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; }
.tags .examples .inline p:before { content: "▸"; font-size: 1em; margin-right: 5px; }
.tags .overload .overload_item { list-style: none; margin-bottom: 25px; }
.tags .overload .overload_item .signature {
padding: 2px 8px;
background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px;
}
.tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; }
.tags .overload .docstring { margin-top: 15px; }
.defines { display: none; }
#method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; }
.showSource { font-size: 0.9em; }
.showSource a, .showSource a:visited { text-decoration: none; color: #666; }
#content a, #content a:visited { text-decoration: none; color: #05a; }
#content a:hover { background: #ffffa5; }
ul.summary {
list-style: none;
font-family: monospace;
font-size: 1em;
line-height: 1.5em;
padding-left: 0px;
}
ul.summary a, ul.summary a:visited {
text-decoration: none; font-size: 1.1em;
}
ul.summary li { margin-bottom: 5px; }
.summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; }
.summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; }
.summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; }
ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;}
ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; }
#content .summary_signature:hover a,
#content .summary_signature:hover a:visited {
background: transparent;
color: #049;
}
p.inherited a { font-family: monospace; font-size: 0.9em; }
p.inherited { word-spacing: 5px; font-size: 1.2em; }
p.children { font-size: 1.2em; }
p.children a { font-size: 0.9em; }
p.children strong { font-size: 0.8em; }
p.children strong.modules { padding-left: 5px; }
ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; }
ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; }
ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAHtJREFUeNqMzrEJAkEURdGzuhgZbSoYWcAWoBVsB4JgZAGmphsZCZYzTQgWNCYrDN9RvMmHx+X916SUBFbo8CzD1idXrLErw1mQttgXtyrOcQ/Ny5p4Qh+2XqLYYazsPWNTiuMkRxa4vcV+evuNAUOLIx5+c2hyzv7hNQC67Q+/HHmlEwAAAABJRU5ErkJggg==) no-repeat top center; }
ul.fullTree li:first-child { padding-top: 0; background: transparent; }
ul.fullTree li:last-child { padding-bottom: 0; }
.showAll ul.fullTree { display: block; }
.showAll .inheritName { display: none; }
#search { position: absolute; right: 12px; top: 0px; z-index: 9000; }
#search a {
display: block; float: left;
padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a;
border: 1px solid #d8d8e5;
border-bottom-left-radius: 3px; border-bottom-right-radius: 3px;
background: #F1F8FF;
box-shadow: -1px 1px 3px #ddd;
}
#search a:hover { background: #f5faff; color: #06b; fill: #06b; }
#search a.active {
background: #568; padding-bottom: 20px; color: #fff; fill: #fff;
border: 1px solid #457;
border-top-left-radius: 5px; border-top-right-radius: 5px;
}
#search a.inactive { color: #999; fill: #999; }
.inheritanceTree, .toggleDefines {
float: right;
border-left: 1px solid #aaa;
position: absolute; top: 0; right: 0;
height: 100%;
background: #f6f6f6;
padding: 5px;
min-width: 55px;
text-align: center;
}
#menu { font-size: 1.3em; color: #bbb; }
#menu .title, #menu a { font-size: 0.7em; }
#menu .title a { font-size: 1em; }
#menu .title { color: #555; }
#menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; }
#menu a:hover { color: #05a; }
#footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; }
#footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; }
#footer a:hover { color: #05a; }
#listing ul.alpha { font-size: 1.1em; }
#listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; }
#listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; }
#listing ul.alpha ul { margin: 0; padding-left: 15px; }
#listing ul small { color: #666; font-size: 0.7em; }
li.r1 { background: #f0f0f0; }
li.r2 { background: #fafafa; }
#content ul.summary li.deprecated .summary_signature a,
#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; }
#toc {
position: relative;
float: right;
overflow-x: auto;
right: -3px;
margin-left: 20px;
margin-bottom: 20px;
padding: 20px; padding-right: 30px;
max-width: 300px;
z-index: 5000;
background: #fefefe;
border: 1px solid #ddd;
box-shadow: -2px 2px 6px #bbb;
}
#toc .title { margin: 0; }
#toc ol { padding-left: 1.8em; }
#toc li { font-size: 1.1em; line-height: 1.7em; }
#toc > ol > li { font-size: 1.1em; font-weight: bold; }
#toc ol > li > ol { font-size: 0.9em; }
#toc ol ol > li > ol { padding-left: 2.3em; }
#toc ol + li { margin-top: 0.3em; }
#toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; }
#toc.hidden:hover { background: #fafafa; }
#filecontents h1 + #toc.nofloat { margin-top: 0; }
@media (max-width: 560px) {
#toc {
margin-left: 0;
margin-top: 16px;
float: none;
max-width: none;
}
}
/* syntax highlighting */
.source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; }
#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; }
#filecontents pre.code, .docstring pre.code { display: block; }
.source_code .lines { padding-right: 12px; color: #555; text-align: right; }
#filecontents pre.code, .docstring pre.code,
.tags pre.example {
padding: 9px 14px;
margin-top: 4px;
border: 1px solid #e1e1e8;
background: #f7f7f9;
border-radius: 4px;
font-size: 1em;
overflow-x: auto;
line-height: 1.2em;
}
pre.code { color: #000; tab-size: 2; }
pre.code .info.file { color: #555; }
pre.code .val { color: #036A07; }
pre.code .tstring_content,
pre.code .heredoc_beg, pre.code .heredoc_end,
pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep,
pre.code .words_beg, pre.code .words_end, pre.code .words_sep,
pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep,
pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep,
pre.code .tstring, pre.code .dstring { color: #036A07; }
pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s,
pre.code .rubyid_to_sym, pre.code .rubyid_to_f,
pre.code .dot + pre.code .id,
pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; }
pre.code .comment { color: #0066FF; }
pre.code .const, pre.code .constant { color: #585CF6; }
pre.code .label,
pre.code .symbol { color: #C5060B; }
pre.code .kw,
pre.code .rubyid_require,
pre.code .rubyid_extend,
pre.code .rubyid_include { color: #0000FF; }
pre.code .ivar { color: #318495; }
pre.code .gvar,
pre.code .rubyid_backref,
pre.code .rubyid_nth_ref { color: #6D79DE; }
pre.code .regexp, .dregexp { color: #036A07; }
pre.code a { border-bottom: 1px dotted #bbf; }
/* inline code */
*:not(pre) > code {
padding: 1px 3px 1px 3px;
border: 1px solid #E1E1E8;
background: #F7F7F9;
border-radius: 4px;
}
/* Color fix for links */
#content .summary_desc pre.code .id > .object_link a, /* identifier */
#content .docstring pre.code .id > .object_link a { color: #0085FF; }
#content .summary_desc pre.code .const > .object_link a, /* constant */
#content .docstring pre.code .const > .object_link a { color: #585CF6; }

205
doc/file.README.html Normal file
View File

@ -0,0 +1,205 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
File: README
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "README";
relpath = '';
</script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="file_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="_index.html">Index</a> &raquo;
<span class="title">File: README</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><div id='filecontents'><h1 id="the-strange-case-of-dr-rack-and-mr-hyde">The strange case of Dr. Rack and Mr. Hyde</h1>
<p>Hyde is a library that provides a DSL for creating HTTP servers. As of now it is using Rack as the webserver adapter, but ideally it shouldn&#39;t take much work to make it run on top of any webserver.</p>
<p>Hyde was made mostly for fun. Ideally it will become something more, but as of yet it&#39;s just an experiment revolving around Ruby Metaprogramming and its DSL capabilities.</p>
<h1 id="examples">Examples</h1>
<p>A simple &quot;Hello, World!&quot; HTTP API using Hyde</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>/hello</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Hello, World!</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>A push/pull stack as an HTTP API</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='const'>Stack</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>pull</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='const'>Stack</span><span class='period'>.</span><span class='id identifier rubyid_pop'>pop</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_post'>post</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>push</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='const'>Stack</span><span class='period'>.</span><span class='id identifier rubyid_push'>push</span> <span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>Several push/pull buckets</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='const'>Stack</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_1</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_2</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_3</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='rbrace'>}</span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_path'>path</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_1</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_2</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_3</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>pull</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_bucket_name'>bucket_name</span> <span class='op'>=</span> <span class='lparen'>(</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_filepath'>filepath</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>bucket_[^\/]*</span><span class='regexp_end'>/</span></span><span class='rparen'>)</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='const'>Stack</span><span class='lbracket'>[</span><span class='id identifier rubyid_bucket_name'>bucket_name</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_pop'>pop</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_post'>post</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>push</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_bucket_name'>bucket_name</span> <span class='op'>=</span> <span class='lparen'>(</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_filepath'>filepath</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>bucket_[^\/]*</span><span class='regexp_end'>/</span></span><span class='rparen'>)</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span>
<span class='const'>Stack</span><span class='lbracket'>[</span><span class='id identifier rubyid_bucket_name'>bucket_name</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_push'>push</span> <span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>Static file serving
(Note: index applies <em>only</em> to /var/www (to the path its defined in))</p>
<pre class="code ruby"><code class="ruby">require &#39;hyde&#39;
server = Hyde::Server.new Port:8000 do
path &quot;static&quot; do
root &quot;/var/www&quot;
index [&quot;index.html&quot;,&quot;index.htm&quot;]
serve &quot;*/*.html&quot; safe_regexp: false
serve &quot;*.html&quot;
end
end
server.start
</code></pre>
<p>Logging on a particular path</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span><span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_path'>path</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>unimportant</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>version</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>{&quot;version&quot;: &quot;the good one&quot;}</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>application/json</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_path'>path</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>important</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span>
<span class='id identifier rubyid_preprocess'>preprocess</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='comment'># Implement logging logic here
</span> <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Client at </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_remote_ip'>remote_ip</span><span class='embexpr_end'>}</span><span class='tstring_content'> wanted to access something /important!</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>answer</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>{&quot;answer&quot;:42}</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>application/json</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>And a lot more to come (hopefully)</p>
<h1 id="documentation">Documentation</h1>
<p>Someday it&#39;s gonna be there somewhere</p>
<h1 id="license">License</h1>
<pre class="code ruby"><code class="ruby"> Hyde - an HTTP request pattern matching system
Copyright (C) 2022 yessiest (yessiest@memeware.net)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see &lt;https://www.gnu.org/licenses/&gt;.
</code></pre>
</div></div>
<div id="footer">
Generated on Mon Aug 28 22:29:23 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

56
doc/file_list.html Normal file
View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
<title>File List</title>
<base id="base_target" target="_parent" />
</head>
<body>
<div id="content">
<div class="fixed_header">
<h1 id="full_list_header">File List</h1>
<div id="full_list_nav">
<span><a target="_self" href="class_list.html">
Classes
</a></span>
<span><a target="_self" href="method_list.html">
Methods
</a></span>
<span><a target="_self" href="file_list.html">
Files
</a></span>
</div>
<div id="search">Search: <input type="text" /></div>
</div>
<ul id="full_list" class="file">
<li id="object_README" class="odd">
<div class="item"><span class="object_link"><a href="index.html" title="README">README</a></span></div>
</li>
</ul>
</div>
</body>
</html>

17
doc/frames.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Documentation by YARD 0.9.34</title>
</head>
<script type="text/javascript">
var match = unescape(window.location.hash).match(/^#!(.+)/);
var name = match ? match[1] : 'index.html';
name = name.replace(/^(\w+):\/\//, '').replace(/^\/\//, '');
window.top.location = name;
</script>
<noscript>
<h1>Oops!</h1>
<h2>YARD requires JavaScript!</h2>
</noscript>
</html>

205
doc/index.html Normal file
View File

@ -0,0 +1,205 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
File: README
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "README";
relpath = '';
</script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="_index.html">Index</a> &raquo;
<span class="title">File: README</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><div id='filecontents'><h1 id="the-strange-case-of-dr-rack-and-mr-hyde">The strange case of Dr. Rack and Mr. Hyde</h1>
<p>Hyde is a library that provides a DSL for creating HTTP servers. As of now it is using Rack as the webserver adapter, but ideally it shouldn&#39;t take much work to make it run on top of any webserver.</p>
<p>Hyde was made mostly for fun. Ideally it will become something more, but as of yet it&#39;s just an experiment revolving around Ruby Metaprogramming and its DSL capabilities.</p>
<h1 id="examples">Examples</h1>
<p>A simple &quot;Hello, World!&quot; HTTP API using Hyde</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>/hello</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Hello, World!</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>A push/pull stack as an HTTP API</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='const'>Stack</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>pull</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='const'>Stack</span><span class='period'>.</span><span class='id identifier rubyid_pop'>pop</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_post'>post</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>push</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='const'>Stack</span><span class='period'>.</span><span class='id identifier rubyid_push'>push</span> <span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>Several push/pull buckets</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='const'>Stack</span> <span class='op'>=</span> <span class='lbrace'>{</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_1</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_2</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_3</span><span class='tstring_end'>&quot;</span></span> <span class='op'>=&gt;</span> <span class='lbracket'>[</span><span class='rbracket'>]</span><span class='rbrace'>}</span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span> <span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_path'>path</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_1</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_2</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>bucket_3</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>pull</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_bucket_name'>bucket_name</span> <span class='op'>=</span> <span class='lparen'>(</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_filepath'>filepath</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>bucket_[^\/]*</span><span class='regexp_end'>/</span></span><span class='rparen'>)</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='const'>Stack</span><span class='lbracket'>[</span><span class='id identifier rubyid_bucket_name'>bucket_name</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_pop'>pop</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_post'>post</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>push</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_bucket_name'>bucket_name</span> <span class='op'>=</span> <span class='lparen'>(</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_filepath'>filepath</span><span class='period'>.</span><span class='id identifier rubyid_match'>match</span> <span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>bucket_[^\/]*</span><span class='regexp_end'>/</span></span><span class='rparen'>)</span><span class='lbracket'>[</span><span class='int'>0</span><span class='rbracket'>]</span>
<span class='const'>Stack</span><span class='lbracket'>[</span><span class='id identifier rubyid_bucket_name'>bucket_name</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_push'>push</span> <span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&quot;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>text/plain</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>Static file serving
(Note: index applies <em>only</em> to /var/www (to the path its defined in))</p>
<pre class="code ruby"><code class="ruby">require &#39;hyde&#39;
server = Hyde::Server.new Port:8000 do
path &quot;static&quot; do
root &quot;/var/www&quot;
index [&quot;index.html&quot;,&quot;index.htm&quot;]
serve &quot;*/*.html&quot; safe_regexp: false
serve &quot;*.html&quot;
end
end
server.start
</code></pre>
<p>Logging on a particular path</p>
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>hyde</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span></span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>Port:</span><span class='int'>8000</span> <span class='kw'>do</span>
<span class='id identifier rubyid_path'>path</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>unimportant</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>version</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>{&quot;version&quot;: &quot;the good one&quot;}</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>application/json</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_path'>path</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>important</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span>
<span class='id identifier rubyid_preprocess'>preprocess</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='comment'># Implement logging logic here
</span> <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Client at </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span><span class='period'>.</span><span class='id identifier rubyid_remote_ip'>remote_ip</span><span class='embexpr_end'>}</span><span class='tstring_content'> wanted to access something /important!</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='id identifier rubyid_get'>get</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>answer</span><span class='tstring_end'>&quot;</span></span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_ctx'>ctx</span><span class='op'>|</span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='period'>.</span><span class='id identifier rubyid_body'>body</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>{&quot;answer&quot;:42}</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_ctx'>ctx</span><span class='period'>.</span><span class='id identifier rubyid_response'>response</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Content-Type</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>application/json</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='kw'>end</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_start'>start</span>
</code></pre>
<p>And a lot more to come (hopefully)</p>
<h1 id="documentation">Documentation</h1>
<p>Someday it&#39;s gonna be there somewhere</p>
<h1 id="license">License</h1>
<pre class="code ruby"><code class="ruby"> Hyde - an HTTP request pattern matching system
Copyright (C) 2022 yessiest (yessiest@memeware.net)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see &lt;https://www.gnu.org/licenses/&gt;.
</code></pre>
</div></div>
<div id="footer">
Generated on Mon Aug 28 22:29:23 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

314
doc/js/app.js Normal file
View File

@ -0,0 +1,314 @@
(function() {
var localStorage = {}, sessionStorage = {};
try { localStorage = window.localStorage; } catch (e) { }
try { sessionStorage = window.sessionStorage; } catch (e) { }
function createSourceLinks() {
$('.method_details_list .source_code').
before("<span class='showSource'>[<a href='#' class='toggleSource'>View source</a>]</span>");
$('.toggleSource').toggle(function() {
$(this).parent().nextAll('.source_code').slideDown(100);
$(this).text("Hide source");
},
function() {
$(this).parent().nextAll('.source_code').slideUp(100);
$(this).text("View source");
});
}
function createDefineLinks() {
var tHeight = 0;
$('.defines').after(" <a href='#' class='toggleDefines'>more...</a>");
$('.toggleDefines').toggle(function() {
tHeight = $(this).parent().prev().height();
$(this).prev().css('display', 'inline');
$(this).parent().prev().height($(this).parent().height());
$(this).text("(less)");
},
function() {
$(this).prev().hide();
$(this).parent().prev().height(tHeight);
$(this).text("more...");
});
}
function createFullTreeLinks() {
var tHeight = 0;
$('.inheritanceTree').toggle(function() {
tHeight = $(this).parent().prev().height();
$(this).parent().toggleClass('showAll');
$(this).text("(hide)");
$(this).parent().prev().height($(this).parent().height());
},
function() {
$(this).parent().toggleClass('showAll');
$(this).parent().prev().height(tHeight);
$(this).text("show all");
});
}
function searchFrameButtons() {
$('.full_list_link').click(function() {
toggleSearchFrame(this, $(this).attr('href'));
return false;
});
window.addEventListener('message', function(e) {
if (e.data === 'navEscape') {
$('#nav').slideUp(100);
$('#search a').removeClass('active inactive');
$(window).focus();
}
});
$(window).resize(function() {
if ($('#search:visible').length === 0) {
$('#nav').removeAttr('style');
$('#search a').removeClass('active inactive');
$(window).focus();
}
});
}
function toggleSearchFrame(id, link) {
var frame = $('#nav');
$('#search a').removeClass('active').addClass('inactive');
if (frame.attr('src') === link && frame.css('display') !== "none") {
frame.slideUp(100);
$('#search a').removeClass('active inactive');
}
else {
$(id).addClass('active').removeClass('inactive');
if (frame.attr('src') !== link) frame.attr('src', link);
frame.slideDown(100);
}
}
function linkSummaries() {
$('.summary_signature').click(function() {
document.location = $(this).find('a').attr('href');
});
}
function summaryToggle() {
$('.summary_toggle').click(function(e) {
e.preventDefault();
localStorage.summaryCollapsed = $(this).text();
$('.summary_toggle').each(function() {
$(this).text($(this).text() == "collapse" ? "expand" : "collapse");
var next = $(this).parent().parent().nextAll('ul.summary').first();
if (next.hasClass('compact')) {
next.toggle();
next.nextAll('ul.summary').first().toggle();
}
else if (next.hasClass('summary')) {
var list = $('<ul class="summary compact" />');
list.html(next.html());
list.find('.summary_desc, .note').remove();
list.find('a').each(function() {
$(this).html($(this).find('strong').html());
$(this).parent().html($(this)[0].outerHTML);
});
next.before(list);
next.toggle();
}
});
return false;
});
if (localStorage.summaryCollapsed == "collapse") {
$('.summary_toggle').first().click();
} else { localStorage.summaryCollapsed = "expand"; }
}
function constantSummaryToggle() {
$('.constants_summary_toggle').click(function(e) {
e.preventDefault();
localStorage.summaryCollapsed = $(this).text();
$('.constants_summary_toggle').each(function() {
$(this).text($(this).text() == "collapse" ? "expand" : "collapse");
var next = $(this).parent().parent().nextAll('dl.constants').first();
if (next.hasClass('compact')) {
next.toggle();
next.nextAll('dl.constants').first().toggle();
}
else if (next.hasClass('constants')) {
var list = $('<dl class="constants compact" />');
list.html(next.html());
list.find('dt').each(function() {
$(this).addClass('summary_signature');
$(this).text( $(this).text().split('=')[0]);
if ($(this).has(".deprecated").length) {
$(this).addClass('deprecated');
};
});
// Add the value of the constant as "Tooltip" to the summary object
list.find('pre.code').each(function() {
console.log($(this).parent());
var dt_element = $(this).parent().prev();
var tooltip = $(this).text();
if (dt_element.hasClass("deprecated")) {
tooltip = 'Deprecated. ' + tooltip;
};
dt_element.attr('title', tooltip);
});
list.find('.docstring, .tags, dd').remove();
next.before(list);
next.toggle();
}
});
return false;
});
if (localStorage.summaryCollapsed == "collapse") {
$('.constants_summary_toggle').first().click();
} else { localStorage.summaryCollapsed = "expand"; }
}
function generateTOC() {
if ($('#filecontents').length === 0) return;
var _toc = $('<ol class="top"></ol>');
var show = false;
var toc = _toc;
var counter = 0;
var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];
var i;
var curli;
if ($('#filecontents h1').length > 1) tags.unshift('h1');
for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; }
var lastTag = parseInt(tags[0][1], 10);
$(tags.join(', ')).each(function() {
if ($(this).parents('.method_details .docstring').length != 0) return;
if (this.id == "filecontents") return;
show = true;
var thisTag = parseInt(this.tagName[1], 10);
if (this.id.length === 0) {
var proposedId = $(this).attr('toc-id');
if (typeof(proposedId) != "undefined") this.id = proposedId;
else {
var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_');
if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; }
this.id = proposedId;
}
}
if (thisTag > lastTag) {
for (i = 0; i < thisTag - lastTag; i++) {
if ( typeof(curli) == "undefined" ) {
curli = $('<li/>');
toc.append(curli);
}
toc = $('<ol/>');
curli.append(toc);
curli = undefined;
}
}
if (thisTag < lastTag) {
for (i = 0; i < lastTag - thisTag; i++) {
toc = toc.parent();
toc = toc.parent();
}
}
var title = $(this).attr('toc-title');
if (typeof(title) == "undefined") title = $(this).text();
curli =$('<li><a href="#' + this.id + '">' + title + '</a></li>');
toc.append(curli);
lastTag = thisTag;
});
if (!show) return;
html = '<div id="toc"><p class="title hide_toc"><a href="#"><strong>Table of Contents</strong></a></p></div>';
$('#content').prepend(html);
$('#toc').append(_toc);
$('#toc .hide_toc').toggle(function() {
$('#toc .top').slideUp('fast');
$('#toc').toggleClass('hidden');
$('#toc .title small').toggle();
}, function() {
$('#toc .top').slideDown('fast');
$('#toc').toggleClass('hidden');
$('#toc .title small').toggle();
});
}
function navResizeFn(e) {
if (e.which !== 1) {
navResizeFnStop();
return;
}
sessionStorage.navWidth = e.pageX.toString();
$('.nav_wrap').css('width', e.pageX);
$('.nav_wrap').css('-ms-flex', 'inherit');
}
function navResizeFnStop() {
$(window).unbind('mousemove', navResizeFn);
window.removeEventListener('message', navMessageFn, false);
}
function navMessageFn(e) {
if (e.data.action === 'mousemove') navResizeFn(e.data.event);
if (e.data.action === 'mouseup') navResizeFnStop();
}
function navResizer() {
$('#resizer').mousedown(function(e) {
e.preventDefault();
$(window).mousemove(navResizeFn);
window.addEventListener('message', navMessageFn, false);
});
$(window).mouseup(navResizeFnStop);
if (sessionStorage.navWidth) {
navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)});
}
}
function navExpander() {
var done = false, timer = setTimeout(postMessage, 500);
function postMessage() {
if (done) return;
clearTimeout(timer);
var opts = { action: 'expand', path: pathId };
document.getElementById('nav').contentWindow.postMessage(opts, '*');
done = true;
}
window.addEventListener('message', function(event) {
if (event.data === 'navReady') postMessage();
return false;
}, false);
}
function mainFocus() {
var hash = window.location.hash;
if (hash !== '' && $(hash)[0]) {
$(hash)[0].scrollIntoView();
}
setTimeout(function() { $('#main').focus(); }, 10);
}
function navigationChange() {
// This works around the broken anchor navigation with the YARD template.
window.onpopstate = function() {
var hash = window.location.hash;
if (hash !== '' && $(hash)[0]) {
$(hash)[0].scrollIntoView();
}
};
}
$(document).ready(function() {
navResizer();
navExpander();
createSourceLinks();
createDefineLinks();
createFullTreeLinks();
searchFrameButtons();
linkSummaries();
summaryToggle();
constantSummaryToggle();
generateTOC();
mainFocus();
navigationChange();
});
})();

216
doc/js/full_list.js Normal file
View File

@ -0,0 +1,216 @@
(function() {
var $clicked = $(null);
var searchTimeout = null;
var searchCache = [];
var caseSensitiveMatch = false;
var ignoreKeyCodeMin = 8;
var ignoreKeyCodeMax = 46;
var commandKey = 91;
RegExp.escape = function(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
function escapeShortcut() {
$(document).keydown(function(evt) {
if (evt.which == 27) {
window.parent.postMessage('navEscape', '*');
}
});
}
function navResizer() {
$(window).mousemove(function(e) {
window.parent.postMessage({
action: 'mousemove', event: {pageX: e.pageX, which: e.which}
}, '*');
}).mouseup(function(e) {
window.parent.postMessage({action: 'mouseup'}, '*');
});
window.parent.postMessage("navReady", "*");
}
function clearSearchTimeout() {
clearTimeout(searchTimeout);
searchTimeout = null;
}
function enableLinks() {
// load the target page in the parent window
$('#full_list li').on('click', function(evt) {
$('#full_list li').removeClass('clicked');
$clicked = $(this);
$clicked.addClass('clicked');
evt.stopPropagation();
if (evt.target.tagName === 'A') return true;
var elem = $clicked.find('> .item .object_link a')[0];
var e = evt.originalEvent;
var newEvent = new MouseEvent(evt.originalEvent.type);
newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
elem.dispatchEvent(newEvent);
evt.preventDefault();
return false;
});
}
function enableToggles() {
// show/hide nested classes on toggle click
$('#full_list a.toggle').on('click', function(evt) {
evt.stopPropagation();
evt.preventDefault();
$(this).parent().parent().toggleClass('collapsed');
highlight();
});
}
function populateSearchCache() {
$('#full_list li .item').each(function() {
var $node = $(this);
var $link = $node.find('.object_link a');
if ($link.length > 0) {
searchCache.push({
node: $node,
link: $link,
name: $link.text(),
fullName: $link.attr('title').split(' ')[0]
});
}
});
}
function enableSearch() {
$('#search input').keyup(function(event) {
if (ignoredKeyPress(event)) return;
if (this.value === "") {
clearSearch();
} else {
performSearch(this.value);
}
});
$('#full_list').after("<div id='noresults' style='display:none'></div>");
}
function ignoredKeyPress(event) {
if (
(event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) ||
(event.keyCode == commandKey)
) {
return true;
} else {
return false;
}
}
function clearSearch() {
clearSearchTimeout();
$('#full_list .found').removeClass('found').each(function() {
var $link = $(this).find('.object_link a');
$link.text($link.text());
});
$('#full_list, #content').removeClass('insearch');
$clicked.parents().removeClass('collapsed');
highlight();
}
function performSearch(searchString) {
clearSearchTimeout();
$('#full_list, #content').addClass('insearch');
$('#noresults').text('').hide();
partialSearch(searchString, 0);
}
function partialSearch(searchString, offset) {
var lastRowClass = '';
var i = null;
for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) {
var item = searchCache[i];
var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name);
var matchString = buildMatchString(searchString);
var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i");
if (searchName.match(matchRegexp) == null) {
item.node.removeClass('found');
item.link.text(item.link.text());
}
else {
item.node.addClass('found');
item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1');
lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2';
item.link.html(item.name.replace(matchRegexp, "<strong>$&</strong>"));
}
}
if(i == searchCache.length) {
searchDone();
} else {
searchTimeout = setTimeout(function() {
partialSearch(searchString, i);
}, 0);
}
}
function searchDone() {
searchTimeout = null;
highlight();
if ($('#full_list li:visible').size() === 0) {
$('#noresults').text('No results were found.').hide().fadeIn();
} else {
$('#noresults').text('').hide();
}
$('#content').removeClass('insearch');
}
function buildMatchString(searchString, event) {
caseSensitiveMatch = searchString.match(/[A-Z]/) != null;
var regexSearchString = RegExp.escape(searchString);
if (caseSensitiveMatch) {
regexSearchString += "|" +
$.map(searchString.split(''), function(e) { return RegExp.escape(e); }).
join('.+?');
}
return regexSearchString;
}
function highlight() {
$('#full_list li:visible').each(function(n) {
$(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even');
});
}
/**
* Expands the tree to the target element and its immediate
* children.
*/
function expandTo(path) {
var $target = $(document.getElementById('object_' + path));
$target.addClass('clicked');
$target.removeClass('collapsed');
$target.parentsUntil('#full_list', 'li').removeClass('collapsed');
if($target[0]) {
window.scrollTo(window.scrollX, $target.offset().top - 250);
highlight();
}
}
function windowEvents(event) {
var msg = event.data;
if (msg.action === "expand") {
expandTo(msg.path);
}
return false;
}
window.addEventListener("message", windowEvents, false);
$(document).ready(function() {
escapeShortcut();
navResizer();
enableLinks();
enableToggles();
populateSearchCache();
enableSearch();
});
})();

4
doc/js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

155
doc/method_list.html Normal file
View File

@ -0,0 +1,155 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
<title>Method List</title>
<base id="base_target" target="_parent" />
</head>
<body>
<div id="content">
<div class="fixed_header">
<h1 id="full_list_header">Method List</h1>
<div id="full_list_nav">
<span><a target="_self" href="class_list.html">
Classes
</a></span>
<span><a target="_self" href="method_list.html">
Methods
</a></span>
<span><a target="_self" href="file_list.html">
Files
</a></span>
</div>
<div id="search">Search: <input type="text" /></div>
</div>
<ul id="full_list" class="method">
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/Glob.html#can_convert%3F-class_method" title="Hyde::PatternMatching::Glob.can_convert? (method)">can_convert?</a></span>
<small>Hyde::PatternMatching::Glob</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html#can_convert%3F-class_method" title="Hyde::PatternMatching::ReMatch.can_convert? (method)">can_convert?</a></span>
<small>Hyde::PatternMatching::ReMatch</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching.html#canonicalize-class_method" title="Hyde::PatternMatching.canonicalize (method)">canonicalize</a></span>
<small>Hyde::PatternMatching</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/Pattern.html#initialize-instance_method" title="Hyde::Pattern#initialize (method)">#initialize</a></span>
<small>Hyde::Pattern</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/Glob.html#initialize-instance_method" title="Hyde::PatternMatching::Glob#initialize (method)">#initialize</a></span>
<small>Hyde::PatternMatching::Glob</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html#initialize-instance_method" title="Hyde::PatternMatching::ReMatch#initialize (method)">#initialize</a></span>
<small>Hyde::PatternMatching::ReMatch</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/Pattern.html#match-instance_method" title="Hyde::Pattern#match (method)">#match</a></span>
<small>Hyde::Pattern</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/Glob.html#match-instance_method" title="Hyde::PatternMatching::Glob#match (method)">#match</a></span>
<small>Hyde::PatternMatching::Glob</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html#match-instance_method" title="Hyde::PatternMatching::ReMatch#match (method)">#match</a></span>
<small>Hyde::PatternMatching::ReMatch</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/Pattern.html#match%3F-instance_method" title="Hyde::Pattern#match? (method)">#match?</a></span>
<small>Hyde::Pattern</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/Glob.html#match%3F-instance_method" title="Hyde::PatternMatching::Glob#match? (method)">#match?</a></span>
<small>Hyde::PatternMatching::Glob</small>
</div>
</li>
<li class="even ">
<div class="item">
<span class='object_link'><a href="Hyde/PatternMatching/ReMatch.html#match%3F-instance_method" title="Hyde::PatternMatching::ReMatch#match? (method)">#match?</a></span>
<small>Hyde::PatternMatching::ReMatch</small>
</div>
</li>
<li class="odd ">
<div class="item">
<span class='object_link'><a href="Hyde/Pattern.html#static%3F-instance_method" title="Hyde::Pattern#static? (method)">#static?</a></span>
<small>Hyde::Pattern</small>
</div>
</li>
</ul>
</div>
</body>
</html>

View File

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Top Level Namespace
&mdash; Documentation by YARD 0.9.34
</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/common.css" type="text/css" />
<script type="text/javascript">
pathId = "";
relpath = '';
</script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
</head>
<body>
<div class="nav_wrap">
<iframe id="nav" src="class_list.html?1"></iframe>
<div id="resizer"></div>
</div>
<div id="main" tabindex="-1">
<div id="header">
<div id="menu">
<a href="_index.html">Index</a> &raquo;
<span class="title">Top Level Namespace</span>
</div>
<div id="search">
<a class="full_list_link" id="class_list_link"
href="class_list.html">
<svg width="24" height="24">
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
</svg>
</a>
</div>
<div class="clear"></div>
</div>
<div id="content"><h1>Top Level Namespace
</h1>
<div class="box_info">
</div>
<h2>Defined Under Namespace</h2>
<p class="children">
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Hyde.html" title="Hyde (module)">Hyde</a></span>
</p>
</div>
<div id="footer">
Generated on Mon Aug 28 22:29:23 2023 by
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
0.9.34 (ruby-3.0.6).
</div>
</div>
</body>
</html>

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'mime-types'
require 'webrick'
require 'uri'

View File

@ -1,10 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title> Unforseen consequences </title>
</head>
<body>
<p> Cleverly done, mister Freeman, but you are not supposed to be here </p>
<p> <b> Get back where you <a href="/index.html">belong</a> </b> </p>
</body>
</html>

View File

@ -1,189 +1,17 @@
# frozen_string_literal: true
require_relative 'pattern_matching'
# Hyde is a hideously simple ruby web framework
#
module Hyde
# String and path processing utilities
module PatternMatching
# Strips extra slashes from a string
# (including slashes at the start and end of the string)
# @param string [String]
# @return [String]
def self.canonicalize(string)
string.gsub(/\/+/, "/")
.delete_prefix("/")
.delete_suffix("/")
end
# Hyde version
# @type [String]
VERSION = '0.8 (beta/rewrite)'
# Implements glob-like pattern matching
# Exact specifications for globbing rules:
# "/"
# - act as directory separators
# - multiple slashes (i.e. "///") are the same as one slash ("/")
# - slashes are stripped at start and end of an expression or path
# - slashes are not matched by anything but the globstar ("**")
#
# "*" ( regexp: /([^/]*)/ )
# - matches from 0 to any number of characters
# - does not match nothing if placed between two slashes (i.e "/*/")
# - result is captured in an array
# - stops at slashes
# - greedy (matches as much as possible)
#
# "**" ( regexp: /(.*)/ )
# - matches any number of characters
# - matches slashes ("/")
# - result is captured in an array
# - does not stop at slashes
# - greedy (matches as much as possible)
#
# "?" ( regexp: /[^/]/ )
# - matches exactly one character
# - result is not captured
# - cannot match slashes
#
# "[...]" ( regexp: itself, ! and ^ at the start are interchangeable )
# - acts like a regexp range
# - matches any characters, including slashes if specified
# - valid ways to specify a range: [A-z], [a-z], [9-z] (ascii order)
# - ! or ^ at the start invert meaning (any character not in range)
# - result is not captured
#
# ":<name>" ( regexp: acts like a named group for /[^/]*/ )
# - acts like * as defined above
# - result is captured in a hash with <name> as key
# - <name> allows alphanumeric characters and underscores
class Glob
# @param input [String] Glob pattern
def initialize(pattern)
pattern = Hyde::PatternMatching.canonicalize(pattern)
pieces = pattern.split(/(\/\*\*\/|\*\*|\*|\?|\[!?\w-\w\]|:[^\/]+)/)
# @type [Array<String,Integer>]
@index = build_index(pieces)
# @type [Regexp]
@glob = Regexp.new(pieces.map do |filter|
case filter
when "/**/" then "/(.*/|)"
when "**" then "(.*)"
when "*" then "([^/]*)"
when "?" then "[^/]"
when /^\[!?\w-\w\]$/ then filter.sub('!', '^')
when /:[\w_]+/ then "[^/]*"
else filter.gsub(/[\^$.|+(){}]/, '\\\\\\0')
end
end.join("").prepend("^/?"))
puts @glob
end
# Hyde branding and version
VLINE = "Hyde/#{Hyde::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n"
# Match the string and assign matches to parameters
# Returns:
# - Unmatched part of a string
# - Unnamed parameters
# - Named parameters
# @param input [String] String to match
# @return [Array(String,Array,Hash)]
def match(input)
input = Hyde::PatternMatching.canonicalize(input)
result = input.match(@glob)
input = result.post_match
named_params, params = assign_by_index(@index, result.captures)
[input, params, named_params]
end
# Test if a string can be matched
# Lighter version of match that doesn't assign any variables
# @param input [String] String to match
# @return [Boolean]
def match?(input)
input = Hyde::PatternMatching.canonicalize(input)
input.match? @glob
end
# Test if input is convertible to a Glob and if there is any reason to
# @param input
# @return [Boolean] Input can be safely converted to Glob
def self.can_convert?(input)
input.kinf_of? String and
input.match?(/(?<!^\\)(?:\*\*|\*|\?|\[!?\w-\w\]|:[^\/]+)/)
end
private
# Build an index for separating normal matches from named matches
# @param pieces [Array(String)] Glob pattern after being splitted
# @return [Array(String,Integer)] Index array to use with assign_to_index
def build_index(pieces)
count = -1
index = []
pieces.each do |x|
if x.match?(/(\*\*|\*)/)
index.append(count += 1)
elsif (name = x.match(/:[^\/]+/))
index.append(name)
end
end
index
end
# Assign values from match.captures to named and numbered groups
# @param index [Array(String,Integer)] Index array generated by build_index
# @param params [Array] Unnamed captures from a String.match
def assign_by_index(index, params)
named_params = {}
new_params = []
params.each_with_index do |x, k|
if index[k].is_a? String
named_params[index[k]] = x
else
new_params[index[k]] = x
end
end
[named_params, new_params]
end
end
# Implements regexp pattern matching
class ReMatch
def initialize(pattern)
@glob = pattern
end
def match
end
def self.can_convert?(string)
string.is_a? Regexp
end
end
# Umbrella class that picks a suitable pattern to be a middle man for
class Pattern
def initialize(pattern, **options)
@pattern = patternify(pattern)
@static = @pattern.is_a? String
@options = options
end
def static?
@static
end
def match
end
private
# Try and convert the string to a pattern, if possible
def patternify(pattern)
Glob.new(pattern, **@options) if Glob.can_convert?(pattern)
ReMatch.new(pattern, **@options) if Glob.can_convert?(pattern)
end
end
end
class PathBinding
end
class Path
end
# Hyde copyright
COPYRIGHT = "Copyright 2023 Yessiest"
end

27
lib/hyde/path.rb Normal file
View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
require_relative 'pattern_matching'
module Hyde
# Primary building block of request navigation.
class Path
def initialize(path, &setup)
@pattern = Pattern.new(path).freeze
@children = []
binding = PathBinding.new(self)
binding.instance_exec setup
end
end
# Protected interface that provides DSL context for setup block
class PathBinding
def initialize(path)
@origin = path
end
def params
@origin.params.freeze
end
end
end

View File

@ -1,2 +1,74 @@
# frozen_string_literal: true
require_relative 'pattern_matching/util'
require_relative 'pattern_matching/glob'
require_relative 'pattern_matching/rematch'
module Hyde
# Utility functions and pattern-generator classes.
# Used primarily to create patterns for path definitions.
module PatternMatching end
# Delegate class for all available patterns.
# Picks appropriate pattern based on contents.
class Pattern
# @param pattern [Object] object to generate pattern from
def initialize(pattern)
@pattern = patternify(pattern)
@static = @pattern.is_a? String
end
# Checks if pattern object is static (is a simple String pattern).
def static?
@static
end
# Match the string and assign matches to parameters.
# Returns:
#
# - Unmatched part of a string
# - Unnamed parameters
# - Named parameters
# @param input [String] String to match
# @return [Array(String,Array,Hash)]
# @return [FalseClass] if input doesn't match pattern
def match(input)
if @pattern.is_a? String
input = Hyde::PatternMatching.canonicalize(input)
if input.start_with?(@pattern)
[input.delete_prefix(@pattern), [], {}]
else
false
end
else
@pattern.match(input)
end
end
# Test if a string can be matched.
# Lighter version of match that doesn't assign any variables.
# @param input [String] String to match
# @return [Boolean]
def match?(input)
if @pattern.is_a? String
Hyde::PatternMatching.canonicalize(input).start_with? pattern
else
@pattern.match?(input)
end
end
private
def patternify(pattern)
classdomain = Hyde::PatternMatching
classdomain.constants
.filter { |x| classdomain.const_get(x).is_a? Class }
.map { |x| classdomain.const_get(x) }
.each do |pattern_generator|
return pattern_generator.new(pattern) if pattern_generator.can_convert? pattern
end
Hyde::PatternMatching.canonicalize(pattern)
end
end
end

View File

@ -1,7 +1,14 @@
# frozen_string_literal: true
module Hyde
module PatternMatching
# Implements glob-like pattern matching
# someday i've heard this quote:
# "if you love regexp so much why don't you marry the damn thing?"
# and so i did, as you can see here.
# Implements glob-like pattern matching.
# Exact specifications for globbing rules:
#
# "/"
# - act as directory separators
# - multiple slashes (i.e. "///") are the same as one slash ("/")
@ -22,60 +29,60 @@ module Hyde
# - does not stop at slashes
# - greedy (matches as much as possible)
#
# "?" ( regexp: /[^/]/ )
# - matches exactly one character
# - result is captured
# - cannot match slashes
#
# "[...]" ( regexp: itself, ! and ^ at the start are interchangeable )
# "[...]+" ( regexp: itself, ! and ^ at the start are interchangeable )
# - acts like a regexp range
# - matches any characters, including slashes if specified
# - matches any number of characters
# - valid ways to specify a range: [A-z], [a-z], [9-z] (ascii order)
# - ! or ^ at the start invert meaning (any character not in range)
# - result is captured
# - result is captured in an array
#
# ":<name>" ( regexp: acts like a named group for /[^/]*/ )
# ":name" ( regexp: acts like a named group for /[^/]*/ )
# - acts like * as defined above
# - result is captured in a hash with <name> as key
# - <name> allows alphanumeric characters and underscores
# - result is captured in a hash with "name" as key
# - name allows alphanumeric characters and underscores
# - ignored unless placed between two slashes
#
# "(name|name2|...)" ( regexp: itself )
# - matches any of (full keywords) name, name2, ...
# - result is captured in an array
# - each name may include only these groups of characters:
# - alphanumeric
# - slashes
# - underscores
# - dashes
class Glob
# @param input [String] Glob pattern
def initialize(pattern)
pattern = Hyde::PatternMatching.canonicalize(pattern)
pieces = pattern.split(/(\/\*\*\/|\*\*|\*|\?|\[!?\w-\w\]|:[^\/]+)/)
pieces = pattern.split(TOKENS)
# @type [Array<String,Integer>]
@index = build_index(pieces)
# @type [Regexp]
@glob = Regexp.new(pieces.map do |filter|
case filter
when "/**/" then "/(.*/|)"
when "**" then "(.*)"
when "*" then "([^/]*)"
when "?" then "([^/])"
when /^\[!?\w-\w\]$/ then "(#{filter.sub('!', '^')})"
when /:[\w_]+/ then "([^/]*)"
else filter.gsub(/[\^$.|+(){}]/, '\\\\\\0')
end
end.join("").prepend("^/?"))
@glob = build_regexp(pieces)
end
# Match the string and assign matches to parameters
# Match the string and assign matches to parameters.
# Returns:
#
# - Unmatched part of a string
# - Unnamed parameters
# - Named parameters
# @param input [String] String to match
# @return [Array(String,Array,Hash)]
# @return [FalseClass] if input doesn't match glob
def match(input)
input = Hyde::PatternMatching.canonicalize(input)
result = input.match(@glob)
return false unless result
input = result.post_match
named_params, params = assign_by_index(@index, result.captures)
[input, params, named_params]
end
# Test if a string can be matched
# Lighter version of match that doesn't assign any variables
# Test if a string can be matched.
# Lighter version of match that doesn't assign any variables.
# @param input [String] String to match
# @return [Boolean]
def match?(input)
@ -83,48 +90,79 @@ module Hyde
input.match? @glob
end
# Test if input is convertible to a Glob and if there is any reason to
# Test if input is convertible to a Glob and if it should be converted
# @param input
# @return [Boolean] Input can be safely converted to Glob
def self.can_convert?(input)
input.kinf_of? String and
input.match?(/(?<!^\\)(?:\*\*|\*|\?|\[!?\w-\w\]|:[^\/]+)/)
input.is_a? String and
input.match?(TOKENS)
end
private
# Regexp pattern to match glob tokens
TOKENS = /
( # Glob-specific tokens
\/\*\*\/ | # Freestanding globstar
\*\* | # Attached globstar
\* | # Regular glob
\[!?\w-\w\]\+ | # Character group
(?<=\/):[\w_]+(?=\/) | # Named glob
\([\w\/|_-]+\) # Alternator group
)
/x.freeze
# Build an index for separating normal matches from named matches
# @param pieces [Array(String)] Glob pattern after being splitted
# @return [Array(String,Integer)] Index array to use with assign_to_index
# @return [Array(String,Integer)] Index array for assign_by_index
def build_index(pieces)
count = -1
index = []
pieces.each do |x|
if x.match?(/(\/\*\*\/|\*\*|\*|\?|\[!?\w-\w\])/)
if (name = x.match(/^:([\w_]+)$/))
index.append(name[1])
elsif x.match?(TOKENS)
index.append(count += 1)
elsif (name = x.match(/(?<=:)[^\/]+/))
index.append(name[0])
end
end
index
end
# Assign values from match.captures to named and numbered groups
# @param index [Array(String,Integer)] Index array generated by build_index
# @param index [Array(String,Integer)] Index array
# @param params [Array] Unnamed captures from a String.match
# @return [Array(Hash,Array)]
def assign_by_index(index, params)
named_params = {}
new_params = []
puts index.inspect
params.each_with_index do |x, k|
# FIXME: this is a hack for globstar implementation at line 152
x = (x.nil? ? "" : x)
if index[k].is_a? String
named_params[index[k]] = x
named_params[index[k].to_sym] = x
else
new_params[index[k]] = x
end
end
[named_params, new_params]
end
# Create a Regexp from a glob pattern according to defined syntax
# @param tokens [Array(String)] Split array of glob tokens
# @return [Regexp]
def build_regexp(tokens)
Regexp.new(tokens.map do |filter|
case filter
when "/**/" then "/(?:(.*)\/|)" # FIXME: this may return nil
when "**" then "(.*)"
when "*" then "([^/]*)"
when /^\([\w\/|_-]+\)$/ then filter.sub('-', '\\-')
when /^\[!?\w-\w\]\+$/ then filter.sub('!', '^')
when /^:[\w_]+$/ then "([^/]*)"
else filter.gsub(/[\^$.|+(){}]/, '\\\\\\0')
end
end.join("").prepend("^/?"))
end
end
end
end

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
module Hyde
module PatternMatching
# Regexp pattern matching wrapper.
# Following principles apply to the wrapper:
#
# - Regexp input is canonicalized using Hyde::PatternMatching.canonicalize
# - Matched content and anything before it is consumed in #match output
#
# @note If you are planning to write your own pattern, this is the easiest one to read.
class ReMatch
def initialize(pattern)
@glob = pattern
end
# Match the string and assign matches to parameters.
# Returns:
#
# - Unmatched part of a string
# - Unnamed parameters
# - Named parameters
# @param input [String] String to match
# @return [Array(String,Array,Hash)]
# @return [FalseClass] if input doesn't match regexp
def match(input)
result = Hyde::PatternMatching.canonicalize(input).match(@glob)
return false unless result
[result.post_match, result.captures, result.named_captures]
end
# Test if a string can be matched.
# Lighter version of match that doesn't assign any variables.
# @param input [String] String to match
# @return [Boolean]
def match?(input)
Hyde::PatternMatching.canonicalize(input).match? @glob
end
# Test if input is convertible and if it should be converted.
# @param input
# @return [Boolean] Input can be safely converted to Glob
def self.can_convert?(string)
string.is_a? Regexp
end
end
end
end

View File

@ -1,6 +1,8 @@
# frozen_string_literal: true
module Hyde
module PatternMatching
# Strips extra slashes from a string
# Strips extra slashes from a string.
# (including slashes at the start and end of the string)
# @param string [String]
# @return [String]

21
lib/hyde/request.rb Normal file
View File

@ -0,0 +1,21 @@
require 'uri'
module Hyde
class Request
def initialize(env)
@env = env
@method = env["REQUEST_METHOD"]
@path = env["PATH_INFO"]
@script_name = env["SCRIPT_NAME"]
@query_string = env["QUERY_STRING"]
@host = env["SERVER_NAME"]
@port = env["SERVER_PORT"]
@virtual_host = env["HTTP_HOST"]
@headers = env.filter { |k, _| k.start_with? "HTTP_" }
end
attr_reader @host
attr_reader @port
end
end

15
test/Hyde_Pattern.rb Normal file
View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require_relative "../lib/hyde/pattern_matching"
require "test/unit"
class TestPattern < Test::Unit::TestCase
include Hyde
# match? test
def test_matchq
assert_equal(true, Pattern.new("/static/path").freeze.static?)
assert_equal(["", [], {}], Pattern.new("/static/path").freeze.match("/static/path"))
assert_equal(["", ["wonm"], {}], Pattern.new("/static/*/glob").freeze.match("/static/wonm/glob"))
assert_equal(["", ["pong/ping"], {}], Pattern.new(/static\/(.*)\/glob/).freeze.match("/static/pong/ping/glob"))
end
end

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
require_relative "../lib/hyde/pattern_matching"
require "test/unit"
@ -5,7 +7,7 @@ class TestGlob < Test::Unit::TestCase
include Hyde::PatternMatching
# match? test
def test_matchq
# testing "*"
puts "Test group: *"
unit = Glob.new("/test/*")
[
"est/anything", false,
@ -30,7 +32,7 @@ class TestGlob < Test::Unit::TestCase
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
# testing "**"
puts "Test group: **"
unit = Glob.new("/test/**/something")
[
"/test/s/something", true,
@ -67,29 +69,18 @@ class TestGlob < Test::Unit::TestCase
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
# testing ?
unit = Glob.new("/test/?hit")
[
"/test/thing", false,
"/test/chit", true,
"/test//hit", false,
"/testhit", false
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
# testing char ranges
puts "Test group: char ranges"
unit = Glob.new("/test/[9-z]+")
[
"/test/t+", true,
"/test/$+", false,
"/test/aosidujqwi", false,
"/test/aosidujqwi", true,
"/test/9+", true
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
# testing named captures
puts "Test group: named captures"
unit = Glob.new("/test/:name/something")
[
"/test/something/something", true,
@ -101,6 +92,85 @@ class TestGlob < Test::Unit::TestCase
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
puts "Test group: alternator groups"
unit = Glob.new("/test/(one|another-thing)/something")
[
"/test/one/something", true,
"/test/another-thing/something", true,
"/test/one/something/more", true,
"test/another-thing/something/even/more", true,
"/test/two/something", false,
"test//something", false,
"/test/something", false
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
end
def test_match
puts "Test group: *"
unit = Glob.new("/test/*/something")
[
"/test/include/something", ["", ["include"], {}],
"/test//something", false,
"/test/include/something/extra", ["/extra", ["include"], {}],
"/test/shlurpglurp/asdsdsad/something", false
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match(test))
end
puts "Test group: **"
unit = Glob.new("/test/**/something")
[
"/test/include/something", ["", ["include"], {}],
"/test/something", ["", [""], {}],
"/testsomething", false,
"/test/dir/subdir/something", ["", ["dir/subdir"], {}],
"/test/dir/subdir/something/extra", ["/extra", ["dir/subdir"], {}]
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match(test))
end
puts "Test group: **/*.ext"
unit = Glob.new("/test/**/*.ext")
[
"/test/file.ext", ["", ["", "file"], {}],
"/test/path/file.ext", ["", ["path", "file"], {}],
"/test/path/file.php", false,
"/test/path/.ext", ["", ["path", ""], {}],
"/test/dir/subdir/file.ext", ["", ["dir/subdir", "file"], {}]
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match(test))
end
puts "Test group: named captures"
assert_equal(false, Glob.can_convert?("/test/as:something/thing"))
assert_equal(false, Glob.can_convert?("/test/:&(&(@42/thing"))
unit = Glob.new("/test/:name/thing")
[
"/test/thing", false,
"/test//thing", false,
"/test/path/thing", ["", [], { name: "path" }],
"/test/peepee*(^*&^*&68123/thing", ["", [], { name: "peepee*(^*&^*&68123" }],
"/test/dum/file.ext", false
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match(test))
end
puts "Test group: alternator groups"
unit = Glob.new("/test/(this|that|anything_like-this)/thing")
[
"/test/thing", false,
"/test//thing", false,
"/test/this/thing", ["", ["this"], {}],
"/test/that/thing", ["", ["that"], {}],
"/test/anything_likeeeeethis/thing", false,
"/test/anything_like-this/thing", ["", ["anything_like-this"], {}]
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match(test))
end
#i hate writing unit tests
end
end

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
require_relative "../lib/hyde/pattern_matching"
require "test/unit"
class TestReMatch < Test::Unit::TestCase
include Hyde::PatternMatching
# match? test
def test_matchq
a = ReMatch.new(/^test\/path_[^\/]+/)
assert_equal(true, a.match?("/test/path_1"))
assert_equal(false, a.match?("/test/path"))
assert_equal(false, a.match?("test/path/anything"))
assert_equal(true, a.match?("/test/path_1/extra"))
end
def test_match
a = ReMatch.new(/^test\/path_([^\/]+)/)
assert_equal(["", ["1"], {}], a.match("/test/path_1"))
assert_equal(false, a.match("/test/path"))
assert_equal(false, a.match("test/path/anything"))
assert_equal(["/extra", ["1"], {}], a.match("/test/path_1/extra"))
end
end