Compare commits

...

2 Commits

Author SHA1 Message Date
Yessiest 3af7a372da rewrite in progress 2023-08-29 22:41:50 +04:00
Yessiest 161689bec0 commencing full rewrite of hyde 2023-08-28 04:15:09 +04:00
50 changed files with 5224 additions and 413 deletions

5
.yardoc/checksums Normal file
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

0
.yardoc/complete Normal file
View File

BIN
.yardoc/object_types Normal file

Binary file not shown.

BIN
.yardoc/objects/root.dat Normal file

Binary file not shown.

BIN
.yardoc/proxy_types Normal file

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

12
config.ru Normal file
View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
require 'rack'
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,17 +1,27 @@
# frozen_string_literal: true
require 'mime-types'
require 'webrick'
require 'uri'
require 'pp'
# Primary module
module Hyde
# Branding and version
VERSION = "0.5 (alpha)"
# Hyde version
# @type [String]
VERSION = '0.5 (alpha)'
attr_reader :VERSION
# Hyde branding and version (for error templates)
# @type [String]
VLINE = "Hyde/#{Hyde::VERSION} on WEBrick/#{WEBrick::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n"
attr_reader :VLINE
# Generate HTML error template
# @param errortext [String] Error explanation
# @param backtrace [String] Ruby backtrace
def error_template(errortext, backtrace)
<<HTMLEOF
<<~HTMLEOF
<!DOCTYPE HTML>
<html>
<head>
@ -30,7 +40,7 @@ module Hyde
#{WEBrick::HTMLUtils.escape(backtrace) or "\n\n\n"}
</code></pre>
<hr/>
<p class="small">#{WEBrick::HTMLUtils.escape(VLINE)}</p>
<p class="small">#{WEBrick::HTMLUtils.escape(Hyde::VLINE)}</p>
</div>
</body>
</html>
@ -39,58 +49,29 @@ HTMLEOF
module_function :error_template
WEBrick::HTTPResponse.class_exec do
attr_accessor :recent_backtrace
public
def set_backtrace(backtrace)
@recent_backtrace = backtrace
end
attr_accessor :recent_backtrace
def create_error_page
@body = Hyde.error_template(@reason_phrase, @recent_backtrace)
end
end
class Server < WEBrick::HTTPServer
def initialize(config={},&setup)
super(config)
@hyde_pathspec = Hyde::Pathspec.new "/", &setup
self.mount_proc '/' do |req,res|
context = Hyde::Context.new(req.path, req, res)
begin
while context and (not context.exit_loop) do
context.exit_loop = true
context = catch :controlled_exit do
@hyde_pathspec._match(context)
context
end
while postprocessor = context.queue_postprocess.shift do
postprocessor.call(context)
end
end
while finalizer = context.queue_finalize.shift do
finalizer.call(context)
end
rescue Exception => e
puts e.message
puts e.backtrace
res.set_backtrace "#{e.message} (#{e.class})\n#{e.backtrace.join "\n"}"
res.status = 500
end
end
end
end
# Interchangeable glob/regex/string pattern matching
module PatternMatching
def _prep_path(path, safe_regexp: true)
@safe_regexp = safe_regexp
@path = _normalize(path) if path.kind_of? String
@path = path if path.kind_of? Regexp
@path = _normalize(path) if path.is_a? String
@path = path if path.is_a? Regexp
end
def _match?(path, ctx)
# @return [Boolean]
def _match?(path, _ctx)
# behvaiour used by "index" method
return true if @path == ""
split_path = path.split("/").filter { |x| x != "" }
if @path.kind_of? Regexp then
return true if @path == ''
split_path = path.split('/').filter { |x| x != '' }
if @path.is_a? Regexp
# this chunk of fuck is needed to force regexp into 3 rules:
# 1) unsafe regexp means match the whole (remaining) line.
# 3) safe regexp means match only the part before the next slash
@ -98,38 +79,40 @@ HTMLEOF
# this forces the matching to work somewhat consistently
test = @path.match _normalize_input(path) unless @safe_regexp
test = @path.match split_path[0] if @safe_regexp
if test and (test.pre_match == "") and (test.post_match == "") then
return true
if test and (test.pre_match == '') and (test.post_match == '')
true
else
return false
false
end
else
# algorithm to match path segments until no more left in @path
@path.split("/").filter { |x| x != "" }
.each_with_index { |x,i|
@path.split('/').filter { |x| x != '' }
.each_with_index do |x, i|
return false if x != split_path[i]
}
return true
end
true
end
end
def _normalize_input(path)
# remove duplicate slashes and trim edge slashes
(path.split "/").filter { |x| x != "" }.join("/")
(path.split '/').filter { |x| x != '' }.join('/')
end
def _normalize(path)
# remove duplicate slashe s and trim edge slashes
path = _normalize_input(path)
# globbing behaviour simulated with regexp
if path.match /(?<!\\)[\*\?\[]/ then
if path.match /(?<!\\)[\*\?\[]/
path = Regexp.new(path
.gsub(/[\^\$\.\|\+\(\)\{\}]/,"\\\\\\0")
.gsub(/(?<!\\)\*\*/,".*")
.gsub(/(?<![.\\])\*/,"[^/]*")
.gsub(/(?<!\\)\?/,".")
.gsub(/(?<!\\)\[\!/,"[^")
.gsub(/[\^\$\.\|\+\(\)\{\}]/, '\\\\\\0')
.gsub(/(?<!\\)\*\*/, '.*')
.gsub(/(?<![.\\])\*/, '[^/]*')
.gsub(/(?<!\\)\?/, '.')
.gsub(/(?<!\\)\[\!/, '[^')
)
end
return path
path
end
end
@ -142,18 +125,18 @@ HTMLEOF
res.header['location'] = URI(url).to_s
throw :controlled_exit, @current_context
end
def rewrite(url)
new_context = Context::rewrite(@current_context,url)
new_context = Context.rewrite(@current_context, url)
new_context.exit_loop = false
throw :controlled_exit, new_context
end
def die(code, message=nil, backtrace="")
def die(code, message = nil, backtrace = '')
@current_context.response.status = code
@current_context.response.set_backtrace(backtrace)
if not message then
message = WEBrick::HTTPStatus::StatusMessage[code]
end
if @current_context.codehandlers[code] then
@current_context.response.backtrace = backtrace
message ||= WEBrick::HTTPStatus::StatusMessage[code]
if @current_context.codehandlers[code]
@current_context.codehandlers[code].call(@current_context, message, backtrace)
else
@current_context.response.body = Hyde.error_template(message, backtrace)
@ -166,7 +149,7 @@ HTMLEOF
class Context
def initialize(path, request, response)
@path = path
@filepath = ""
@filepath = ''
@request = request
@response = response
@indexlist = []
@ -176,24 +159,22 @@ HTMLEOF
@queue_finalize = []
@exit_loop = false
end
def self.rewrite(pctx, newpath)
newctx = Context.new(newpath, pctx.request, pctx.response)
newctx.vars = pctx.vars
newctx.queue_finalize = pctx.queue_finalize.clone
newctx.queue_postprocess = pctx.queue_postprocess.clone
return newctx
newctx
end
def enqueue_finalizer(dup: false, &block)
if block_given? then
if dup or not @queue_finalize.include? block then
@queue_finalize.append(block)
end
end
return unless block_given?
@queue_finalize.append(block) if dup or !@queue_finalize.include? block
end
def enqueue_postprocessor(&block)
if block_given? then
@queue_postprocess.append(block)
end
@queue_postprocess.append(block) if block_given?
end
attr_reader :request
attr_reader :response
@ -236,91 +217,90 @@ HTMLEOF
_prep_path path, safe_regexp: safe_regexp
@block = block_optional
end
def _match(request)
if @block and (_match? request.path, request) then
return unless @block and (_match? request.path, request)
@current_context = Hyde::ProtectedContext.new(request)
return_later = self.instance_exec @current_context, &@block
return return_later
end
return_later = instance_exec @current_context, &@block
return_later
end
# @sg-ignore
def _match?(path, request)
# End node - nothing must be after it
if super(path,request) then
return unless super(path, request)
match_path = _normalize_input(path).match(@path)
return (match_path.post_match == "")
end
match_path.post_match == ''
end
end
class Serve < Hyde::Probe
def _match(request)
return super if @block
if _match? request.path, request then
return unless _match? request.path, request
@current_context = request
match_path = _normalize_input(request.path).match(@path)[0]
filepath = request.filepath + match_path
begin
mimetype = MIME::Types.type_for(filepath)
file = File.new filepath, "r"
data = file.read()
file = File.new filepath, 'r'
data = file.read
request.response.body = data
request.response["Content-Type"] = mimetype
request.response['Content-Type'] = mimetype
rescue Errno::ENOENT
die(404)
end
end
end
end
class GetMatch < Hyde::Probe
@match_method = "get"
@match_method = 'get'
def initialize(*a, **b, &block)
@match_method = (self.class.instance_variable_get :@match_method)
raise Exception, "block required!" if not block
raise Exception, 'block required!' unless block
super(*a, **b, &block)
end
def _match?(path, ctx)
if ctx.request.request_method == @match_method.upcase then
return super(path, ctx)
if ctx.request.request_method == @match_method.upcase
super(path, ctx)
else
return false
false
end
end
end
class PostMatch < GetMatch
@match_method = "post"
@match_method = 'post'
end
class PutMatch < GetMatch
@match_method = "put"
@match_method = 'put'
end
class PatchMatch < GetMatch
@match_method = "patch"
@match_method = 'patch'
end
class DeleteMatch < GetMatch
@match_method = "delete"
@match_method = 'delete'
end
class OptionsMatch < GetMatch
@match_method = "options"
@match_method = 'options'
end
class LinkMatch < GetMatch
@match_method = "link"
@match_method = 'link'
end
class UnlinkMatch < GetMatch
@match_method = "unlink"
@match_method = 'unlink'
end
class PrintProbe < Hyde::Probe
def _match(request)
if _match? request.path, request then
puts "#{request.path} matched!"
end
puts "#{request.path} matched!" if _match? request.path, request
end
end
@ -338,9 +318,9 @@ HTMLEOF
options: Hyde::OptionsMatch,
link: Hyde::LinkMatch,
unlink: Hyde::UnlinkMatch
}.each_pair { |name, newclass|
}.each_pair do |name, newclass|
define_method name do |path, *a, **b, &block|
if path.kind_of? Array then
if path.is_a? Array
path.each do |x|
@chain.append newclass.new x, *a, **b, &block
end
@ -348,7 +328,7 @@ HTMLEOF
@chain.append newclass.new path, *a, **b, &block
end
end
}
end
end
class Pathspec
@ -360,10 +340,11 @@ HTMLEOF
@chain = []
@root_override = root_path
@remap = false
self.instance_exec &block
instance_exec(&block)
end
def path(path, *a, **b, &block)
if path.kind_of? Array then
if path.is_a? Array
path.each do |x|
@chain.append Hyde::Pathspec.new x, *a, **b, &block
end
@ -371,51 +352,58 @@ HTMLEOF
@chain.append Hyde::Pathspec.new path, *a, **b, &block
end
end
def root(path)
@root_override = "/"+_normalize_input(path)
@root_override = '/' + _normalize_input(path)
end
def remap(path)
@root_override = "/"+_normalize_input(path)
@root_override = '/' + _normalize_input(path)
@remap = true
end
def index(list)
@indexlist = list if list.kind_of? Array
@indexlist = [list] if list.kind_of? String
@indexlist = list if list.is_a? Array
@indexlist = [list] if list.is_a? String
end
def preprocess(&block)
@preprocessor = block
end
def postprocess(&block)
@postprocessor = block
end
def finalize(dup: false, &block)
@finalizer = block
@finalizer_dup = dup
end
def _match(request)
@current_context = request
self.instance_exec request, &@preprocessor if @preprocessor
request.enqueue_postprocessor &@postprocessor if @preprocessor
instance_exec request, &@preprocessor if @preprocessor
request.enqueue_postprocessor(&@postprocessor) if @preprocessor
request.enqueue_finalizer dup: @finalizer_dup, &@finalizer if @finalizer
if _match? request.path, request then
if _match? request.path, request
match_path = _normalize_input(request.path).match(@path)
next_path = match_path[0]
request.path = cut_path = match_path.post_match
# remap/root method handling
if @root_override then
request.filepath = if @remap then
@root_override+"/"
else @root_override+"/"+next_path+"/" end
if @root_override
request.filepath = if @remap
@root_override + '/'
else @root_override + '/' + next_path + '/' end
else
request.filepath = request.filepath+next_path+"/"
request.filepath = request.filepath + next_path + '/'
end
# redefine indexing parameters if they are defined for a pathspec
request.indexlist = @indexlist if @indexlist
# do directory indexing
if cut_path.match /^\/?$/ then
if cut_path.match %r{^/?$}
request.indexlist.each do |x|
try_index = @chain.find { |y| y._match? x, request }
if try_index then
if try_index
request.path = x
return try_index._match request
end
@ -424,7 +412,7 @@ HTMLEOF
# passthrough to the next path object
next_pathspec = @chain.find { |x| x._match? cut_path, request }
next_pathspec._match request if next_pathspec
unless next_pathspec then
unless next_pathspec
# die and throw up if nowhere to go
die(404)
end

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>

17
lib/hyde.rb Normal file
View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
require_relative 'pattern_matching'
# Hyde is a hideously simple ruby web framework
#
module Hyde
# Hyde version
# @type [String]
VERSION = '0.8 (beta/rewrite)'
# Hyde branding and version
VLINE = "Hyde/#{Hyde::VERSION} (Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\n"
# 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

@ -0,0 +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

@ -0,0 +1,168 @@
# frozen_string_literal: true
module Hyde
module PatternMatching
# 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 ("/")
# - 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: 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 in an array
#
# ":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
# - 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(TOKENS)
# @type [Array<String,Integer>]
@index = build_index(pieces)
# @type [Regexp]
@glob = build_regexp(pieces)
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 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.
# @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 it should be converted
# @param input
# @return [Boolean] Input can be safely converted to Glob
def self.can_convert?(input)
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 for assign_by_index
def build_index(pieces)
count = -1
index = []
pieces.each do |x|
if (name = x.match(/^:([\w_]+)$/))
index.append(name[1])
elsif x.match?(TOKENS)
index.append(count += 1)
end
end
index
end
# Assign values from match.captures to named and numbered groups
# @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 = []
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].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

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Hyde
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
end
end

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

@ -0,0 +1,176 @@
# frozen_string_literal: true
require_relative "../lib/hyde/pattern_matching"
require "test/unit"
class TestGlob < Test::Unit::TestCase
include Hyde::PatternMatching
# match? test
def test_matchq
puts "Test group: *"
unit = Glob.new("/test/*")
[
"est/anything", false,
"/test", false,
"/test/anything", true,
"/test//as", true,
"/test/", false,
"/test/as/whatever", true,
"test/as", true
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
unit = Glob.new("/test/*/something")
[
"/test/s/something", true,
"/test//something", false,
"/test/something", false,
"test/b/something", true,
"/test/b/someth", 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/s/something", true,
"/test/dir/something", true,
"/test/something", true,
"test/b/something", true,
"/test/b/someth", false,
"/test/a/b/c/something", true,
"/test/a/b/csomething", false,
"/testsomething", false,
"/something", false
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
unit = Glob.new("/test/**/*.php")
[
"/test/archive.php", true,
"/test/assets/thing.js", false,
"/test/assetsthing.js", false,
"/test/parts/thing.php", true,
"/test/partsthing.php", true,
"/test/.php", true,
"/test/parts/extra/test.php", true,
"test/archive.php", true,
"test/assets/thing.js", false,
"test/assetsthing.js", false,
"test/parts/thing.php", true,
"test/partsthing.php", true,
"test/.php", true,
"test/parts/extra/test.php", true,
"/test/parts/extra/test.php/literally/anything/here", true
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
puts "Test group: char ranges"
unit = Glob.new("/test/[9-z]+")
[
"/test/t+", true,
"/test/$+", false,
"/test/aosidujqwi", true,
"/test/9+", true
].each_slice(2) do |test, result|
puts("Testing: #{test}")
assert_equal(result, unit.match?(test))
end
puts "Test group: named captures"
unit = Glob.new("/test/:name/something")
[
"/test/something/something", true,
"/test/asd/something/extra", true,
"/test//something/what", false,
"/test/something/what", false,
"/test/asd/asd/something/what", 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/(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

View File

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> Welcome to Hyde </title>
</head>
<body>
<h1> Welcome to <a href="https://adastra7.net/git/Yessiest/hyde">Hyde</a> </h1>
<p> Hyde is the horrible side of Jekyll, and, consequently, this particular project.</p>
<ul>
<li> <a href="/uploads/">Uploads</a> </li>
<li> <a href="/about/webrick">WEBrick</a> </li>
<li> <a href="/about/hyde">Hyde</a> </li>
</ul>
<hr />
<p> Created by Yessiest </p>
</body>
</html>

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> test </title>
</head>
<body>
<h1> This is a test </h1>
<hr>
<address> yes </address>
</body>
</html>

View File

@ -1,7 +0,0 @@
# Welcome to the INFINITE HYPERNET
---
- THE HYPE IS REAL
- SCENE IS DEAD
- BLOOD OF LAMERS IS FUEL

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title> very test </title>
</head>
<body>
<h1> This is a very test </h1>
<hr>
<address> yes 2 </address>
</body>
</html>

View File

@ -1 +0,0 @@
# YES

View File

@ -1,15 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD><TITLE>File listing</TITLE></HEAD>
<BODY>
<H1>File listing:</H1>
<ul>
<li><a href="/uploads/01-blog/test.md">this</a></li>
<li><a href="/uploads/02-rules/megafuck.md">that</a></li>
</ul>
<HR>
<ADDRESS>
welcum to this crap
</ADDRESS>
</BODY>
</HTML>

View File

@ -1,32 +0,0 @@
require_relative "hyde"
server = Hyde::Server.new Port: 8000 do
{"add" => -> (a,b) { a + b },
"sub" => -> (a,b) { a - b },
"mul" => -> (a,b) { a * b },
"div" => -> (a,b) {
begin
return a/b
rescue ZeroDivisionError
return "Divided by zero"
end
}
}.each_pair do |k,v|
serve k do |ctx|
req,res = ctx.request,ctx.response
a,b = req.query["a"],req.query["b"]
result = (a and b) ? v.call(a.to_f,b.to_f) : "Invalid parameters"
res.body = "
<!DOCTYPE html>
<html>
<head>
<title> Calculator API test </title>
</head>
<body>
<h> Result: #{result} </h>
</body>
</html>"
res['Content-Type'] = "text/html"
end
end
end
server.start

View File

@ -1,46 +0,0 @@
require_relative 'hyde'
server = Hyde::Server.new Port: 8000 do
root "/home/yessiest/Projects/hyde/test/"
serve "index.html"
index ["index.html"]
path "about" do
preprocess do |ctx|
puts "#{ctx} entered fully virtual directory!"
end
postprocess do |ctx|
puts "#{ctx} reached endpoint!"
end
finalize do |ctx|
puts "#{ctx} finished processing!"
end
get "portal" do |ctx|
ctx.vars[:ass] = true
rewrite "/about/hyde"
end
get "webrick" do |ctx|
ctx.response.body = "WEBrick is a modular http server stack"
ctx.response['Content-Type'] = "text/plain"
end
get "en_passant" do |ctx|
puts "holy hell!"
redirect "https://google.com/search?q=en+passant"
end
get "hyde" do |ctx|
puts ctx.vars[:ass]
ctx.response.body = "Hyde is the disgusting side of Jekyll, and, by extension, the thing that makes WEBrick usable."
ctx.response['Content-Type'] = "text/plain"
end
post "hyde" do |ctx|
ctx.response.body = "Your message: #{ctx.request.body}"
ctx.response['Content-Type'] = "text/plain"
end
end
path "uploads" do
index ["index.html"]
serve "**/*.md", safe_regexp: false
serve ["*.html","**/*.html"], safe_regexp: false
end
end
server.start

View File

@ -1,72 +0,0 @@
require_relative "hyde"
path = Hyde::Pathspec.new "/" do
root "/var/www"
path "about" do
printProbe "test"
printProbe "test_*"
end
path "docs" do
remap "/var/www/markdown_compiled/"
printProbe "test"
printProbe "test_*"
probe "speen" do |request|
puts "maurice spinning"
redirect "https://www.youtube.com/watch?v=KeNyN_rVL_c"
pp request
end
end
path "cell_1337" do
root "/var/www/cells"
path "control" do
probe "close" do |request|
puts "Permissions level 4 required to control this cell"
pp request
end
probe "open" do |request|
puts "Permissions level 4 required to control this cell"
pp request
end
end
printProbe "info"
end
path (/cell_[^\/]*/) do
root "/var/www/cells"
path "control" do
probe "close" do |request|
puts "Closing cell #{request.filepath.match /cell_[^\/]*/}"
pp request
end
probe "open" do |request|
puts "Opening cell #{request.filepath.match /cell_[^\/]*/}"
pp request
end
end
printProbe "dura"
printProbe "info"
end
path "bad_?" do
printProbe "path"
end
probe ["info","hyde"] do
puts "this is the most disgusting and visceral thing i've written yet, and i love it"
end
end
[
Hyde::Request.new("/about/speen",nil,nil),
Hyde::Request.new("/about/test",nil,nil),
Hyde::Request.new("/about/test_2",nil,nil),
Hyde::Request.new("/docs/speen",nil,nil),
Hyde::Request.new("/docs/test",nil,nil),
Hyde::Request.new("/docs/test_3",nil,nil),
Hyde::Request.new("/cell_41/control/open",nil,nil),
Hyde::Request.new("/cell_21/control/close",nil,nil),
Hyde::Request.new("/cell_19283/info",nil,nil),
Hyde::Request.new("/cell_1337/control/close",nil,nil),
Hyde::Request.new("/duracell_129/control/open",nil,nil),
Hyde::Request.new("/duracell_1447/control/close",nil,nil),
Hyde::Request.new("/bad_2path",nil,nil),
Hyde::Request.new("/info",nil,nil),
Hyde::Request.new("/hyde",nil,nil)
].each { |x| path.match(x) }
# what a load of fuck this is

View File

@ -1,14 +0,0 @@
require 'webrick'
server = WEBrick::HTTPServer.new :Port => 8000
trap 'INT' do server.shutdown end
server.mount_proc '/' do |req, res|
pp res
pp req
res['Content-Type'] = "text/plain"
res.body = 'A'*65536+"Hello world"
end
server.start