rubulex 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.sass-cache/585bcb933d47ad9fc0e0c198b6c88f057e68fc16/default.sassc +0 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/rubulex +11 -0
- data/config.ru +10 -0
- data/data/rubulex/public/javascripts/rubulex.js +165 -0
- data/data/rubulex/views/index.slim +154 -0
- data/data/rubulex/views/stylesheets/default.sass +145 -0
- data/lib/rubulex.rb +13 -0
- data/lib/rubulex/app.rb +33 -0
- data/lib/rubulex/regexp_parser.rb +65 -0
- data/lib/rubulex/version.rb +3 -0
- data/rubulex.gemspec +27 -0
- metadata +158 -0
data/.gitignore
ADDED
Binary file
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Oliver Feldt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rubulex
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rubulex'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rubulex
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/rubulex
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
ENV['BUNDLE_GEMFILE'] ||= File.join(File.dirname(__FILE__), "..", "Gemfile")
|
6
|
+
ENV['RACK_ENV'] ||= "testing"
|
7
|
+
Bundler.require(:default, ENV['RACK_ENV'])
|
8
|
+
|
9
|
+
require 'rubulex'
|
10
|
+
|
11
|
+
Rubulex::App.run!
|
data/config.ru
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
/*
|
2
|
+
jQuery's document.ready/$(function(){}) should
|
3
|
+
you wish to use a cross-browser DOMReady solution
|
4
|
+
without opting for a library.
|
5
|
+
|
6
|
+
usage:
|
7
|
+
$(function(){
|
8
|
+
// your code
|
9
|
+
})
|
10
|
+
|
11
|
+
Parts: jQuery project, Diego Perini, Lucent M.
|
12
|
+
This version: Addy Osmani
|
13
|
+
*/
|
14
|
+
(function(window) {
|
15
|
+
"use strict"
|
16
|
+
|
17
|
+
// Define a local copy of $
|
18
|
+
var $ = function(callback) {
|
19
|
+
readyBound = false
|
20
|
+
$.isReady = false
|
21
|
+
if (typeof callback === "function") {
|
22
|
+
DOMReadyCallback = callback
|
23
|
+
}
|
24
|
+
bindReady()
|
25
|
+
},
|
26
|
+
|
27
|
+
// Use the correct document accordingly with window argument (sandbox)
|
28
|
+
document = window.document,
|
29
|
+
readyBound = false,
|
30
|
+
DOMReadyCallback = function() {},
|
31
|
+
|
32
|
+
// The ready event handler
|
33
|
+
DOMContentLoaded = function() {
|
34
|
+
if (document.addEventListener) {
|
35
|
+
document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false)
|
36
|
+
} else {
|
37
|
+
// we're here because readyState !== "loading" in oldIE
|
38
|
+
// which is good enough for us to call the dom ready!
|
39
|
+
document.detachEvent("onreadystatechange", DOMContentLoaded)
|
40
|
+
}
|
41
|
+
DOMReady()
|
42
|
+
},
|
43
|
+
|
44
|
+
// Handle when the DOM is ready
|
45
|
+
DOMReady = function() {
|
46
|
+
// Make sure that the DOM is not already loaded
|
47
|
+
if (!$.isReady) {
|
48
|
+
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
49
|
+
if (!document.body) { return setTimeout(DOMReady, 1) }
|
50
|
+
// Remember that the DOM is ready
|
51
|
+
$.isReady = true
|
52
|
+
// If there are functions bound, to execute
|
53
|
+
DOMReadyCallback()
|
54
|
+
// Execute all of them
|
55
|
+
}
|
56
|
+
}, // /ready()
|
57
|
+
|
58
|
+
bindReady = function() {
|
59
|
+
var toplevel = false
|
60
|
+
|
61
|
+
if (readyBound) { return }
|
62
|
+
readyBound = true
|
63
|
+
|
64
|
+
// Catch cases where $ is called after the
|
65
|
+
// browser event has already occurred.
|
66
|
+
if (document.readyState !== "loading") {
|
67
|
+
DOMReady()
|
68
|
+
}
|
69
|
+
|
70
|
+
// Mozilla, Opera and webkit nightlies currently support this event
|
71
|
+
if (document.addEventListener) {
|
72
|
+
// Use the handy event callback
|
73
|
+
document.addEventListener("DOMContentLoaded", DOMContentLoaded, false)
|
74
|
+
// A fallback to window.onload, that will always work
|
75
|
+
window.addEventListener("load", DOMContentLoaded, false)
|
76
|
+
// If IE event model is used
|
77
|
+
} else if (document.attachEvent) {
|
78
|
+
// ensure firing before onload,
|
79
|
+
// maybe late but safe also for iframes
|
80
|
+
document.attachEvent("onreadystatechange", DOMContentLoaded)
|
81
|
+
// A fallback to window.onload, that will always work
|
82
|
+
window.attachEvent("onload", DOMContentLoaded)
|
83
|
+
// If IE and not a frame
|
84
|
+
// continually check to see if the document is ready
|
85
|
+
try {
|
86
|
+
toplevel = window.frameElement == null
|
87
|
+
} catch (e) { }
|
88
|
+
if (document.documentElement.doScroll && toplevel) {
|
89
|
+
doScrollCheck()
|
90
|
+
}
|
91
|
+
}
|
92
|
+
},
|
93
|
+
|
94
|
+
// The DOM ready check for Internet Explorer
|
95
|
+
doScrollCheck = function() {
|
96
|
+
if ($.isReady) { return }
|
97
|
+
try {
|
98
|
+
// If IE is used, use the trick by Diego Perini
|
99
|
+
// http://javascript.nwbox.com/IEContentLoaded/
|
100
|
+
document.documentElement.doScroll("left")
|
101
|
+
} catch (error) {
|
102
|
+
setTimeout(doScrollCheck, 1)
|
103
|
+
return
|
104
|
+
}
|
105
|
+
// and execute any waiting functions
|
106
|
+
DOMReady()
|
107
|
+
}
|
108
|
+
|
109
|
+
// Is the DOM ready to be used? Set to true once it occurs.
|
110
|
+
$.isReady = false
|
111
|
+
|
112
|
+
// Expose $ to the global object
|
113
|
+
window.$ = $
|
114
|
+
|
115
|
+
})(window)
|
116
|
+
|
117
|
+
Rubulex = {
|
118
|
+
|
119
|
+
}
|
120
|
+
|
121
|
+
Rubulex.queryRegex = function(e) {
|
122
|
+
if (this.inputTimeout) {
|
123
|
+
window.clearTimeout(this.inputTimeout)
|
124
|
+
this.inputTimeout = null
|
125
|
+
}
|
126
|
+
if (Rubulex.regexInput.value !== "" && Rubulex.testData.value !== "") {
|
127
|
+
this.inputTimeout = window.setTimeout(function() {
|
128
|
+
var form = document.getElementById("editor_form")
|
129
|
+
var formData = new FormData(form)
|
130
|
+
var xhr = new XMLHttpRequest()
|
131
|
+
xhr.open('POST', form.action, true)
|
132
|
+
xhr.onload = function(e) {
|
133
|
+
var json_response = JSON.parse(xhr.responseText)
|
134
|
+
Rubulex.result.innerHTML = json_response.match_result
|
135
|
+
if (json_response.match_groups !== null) {
|
136
|
+
Rubulex.result_group_container.style.display = "block"
|
137
|
+
Rubulex.result_groups.innerHTML = json_response.match_groups
|
138
|
+
} else {
|
139
|
+
Rubulex.result_group_container.style.display = "none"
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
xhr.send(formData)
|
144
|
+
return false // Prevent page from submitting.
|
145
|
+
}, 750)
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
$(function() {
|
150
|
+
Rubulex.regexInput = document.getElementById("regex")
|
151
|
+
Rubulex.regexOptionsInput = document.getElementById("regex_options")
|
152
|
+
Rubulex.testData = document.getElementById("test_data")
|
153
|
+
Rubulex.result = document.getElementById("result")
|
154
|
+
Rubulex.result_group_container = document.getElementsByClassName("result_groups")[0]
|
155
|
+
Rubulex.result_groups = document.getElementById("result_groups")
|
156
|
+
var elements = [
|
157
|
+
Rubulex.regexInput,
|
158
|
+
Rubulex.regexOptionsInput,
|
159
|
+
Rubulex.testData
|
160
|
+
]
|
161
|
+
|
162
|
+
for (var i = 0; i < elements.length; i++) {
|
163
|
+
elements[i].addEventListener('input', Rubulex.queryRegex, false)
|
164
|
+
}
|
165
|
+
})
|
@@ -0,0 +1,154 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title Rubulex - A Ruby Regular Expression Editor
|
5
|
+
meta name="keywords" content="regexp regex ruby language"
|
6
|
+
meta name="author" content="Oliver Feldt"
|
7
|
+
link rel="stylesheet" media="screen" type="text/css" href="stylesheets/default.css"
|
8
|
+
script src="javascripts/rubulex.js" type="text/javascript"
|
9
|
+
|
10
|
+
body
|
11
|
+
.page
|
12
|
+
.header
|
13
|
+
h1 Rubulex
|
14
|
+
h2 a Ruby Regular Expression Editor
|
15
|
+
|
16
|
+
.content
|
17
|
+
.editor
|
18
|
+
form#editor_form method="post" action="regex/test" accept-charset="UTF-8"
|
19
|
+
.regexp_entry
|
20
|
+
label Your regular expression:
|
21
|
+
br
|
22
|
+
span= "/"
|
23
|
+
input id="regex" type="text" tabindex="1" size="60" name="regex"
|
24
|
+
span= "/"
|
25
|
+
input id="regex_options" type="text" tabindex="1" size="6" name="options"
|
26
|
+
span= "/"
|
27
|
+
.test
|
28
|
+
.data_pane
|
29
|
+
label Your test data:
|
30
|
+
textarea id="test_data" tabindex="3" rows="10" name="test_data" cols="56"
|
31
|
+
.match_pane
|
32
|
+
.results
|
33
|
+
label Your result:
|
34
|
+
#result
|
35
|
+
.result_groups{ style="display: none;" }
|
36
|
+
label Your result groups:
|
37
|
+
#result_groups
|
38
|
+
.help
|
39
|
+
div style="float:left"
|
40
|
+
table
|
41
|
+
tr
|
42
|
+
td
|
43
|
+
code [abc]
|
44
|
+
td A single character of: a, b or c
|
45
|
+
tr
|
46
|
+
td
|
47
|
+
code [^abc]
|
48
|
+
td Any single character except: a, b, or c
|
49
|
+
tr
|
50
|
+
td
|
51
|
+
code [a-z]
|
52
|
+
td Any single character in the range a-z
|
53
|
+
tr
|
54
|
+
td
|
55
|
+
code [a-zA-Z]
|
56
|
+
td Any single character in the range a-z or A-Z
|
57
|
+
tr
|
58
|
+
td
|
59
|
+
code ^
|
60
|
+
td Start of line
|
61
|
+
tr
|
62
|
+
td
|
63
|
+
code $
|
64
|
+
td End of line
|
65
|
+
tr
|
66
|
+
td
|
67
|
+
code \A
|
68
|
+
td Start of string
|
69
|
+
tr
|
70
|
+
td
|
71
|
+
code \z
|
72
|
+
td End of string
|
73
|
+
|
74
|
+
div style="float:left"
|
75
|
+
table
|
76
|
+
tr
|
77
|
+
td
|
78
|
+
code .
|
79
|
+
td Any single character
|
80
|
+
tr
|
81
|
+
td
|
82
|
+
code \s
|
83
|
+
td Any whitespace character
|
84
|
+
tr
|
85
|
+
td
|
86
|
+
code \S
|
87
|
+
td Any non-whitespace character
|
88
|
+
tr
|
89
|
+
td
|
90
|
+
code \d
|
91
|
+
td Any digit
|
92
|
+
tr
|
93
|
+
td
|
94
|
+
code \D
|
95
|
+
td Any non-digit
|
96
|
+
tr
|
97
|
+
td
|
98
|
+
code \w
|
99
|
+
td Any word character (letter, number, underscore)
|
100
|
+
tr
|
101
|
+
td
|
102
|
+
code \W
|
103
|
+
td Any non-word character
|
104
|
+
tr
|
105
|
+
td
|
106
|
+
code \b
|
107
|
+
td Any word boundary
|
108
|
+
table
|
109
|
+
tr
|
110
|
+
td
|
111
|
+
code (...)
|
112
|
+
td Capture everything enclosed
|
113
|
+
tr
|
114
|
+
td
|
115
|
+
code (a|b)
|
116
|
+
td a or b
|
117
|
+
tr
|
118
|
+
td
|
119
|
+
code a?
|
120
|
+
td Zero or one of a
|
121
|
+
tr
|
122
|
+
td
|
123
|
+
code a*
|
124
|
+
td Zero or more of a
|
125
|
+
tr
|
126
|
+
td
|
127
|
+
code a+
|
128
|
+
td One or more of a
|
129
|
+
tr
|
130
|
+
td
|
131
|
+
code a{3}
|
132
|
+
td Exactly 3 of a
|
133
|
+
tr
|
134
|
+
td
|
135
|
+
code a{3,}
|
136
|
+
td 3 or more of a
|
137
|
+
tr
|
138
|
+
td
|
139
|
+
code a{3,6}
|
140
|
+
td Between 3 and 6 of a
|
141
|
+
|
142
|
+
.regex_options
|
143
|
+
p
|
144
|
+
| options:
|
145
|
+
code i
|
146
|
+
| case insensitive
|
147
|
+
code m
|
148
|
+
| make dot match newlines
|
149
|
+
code x
|
150
|
+
| ignore whitespace in regex
|
151
|
+
code o
|
152
|
+
| perform {...} substitutions only once
|
153
|
+
.footer
|
154
|
+
| Copyright © #{Rubulex::VERSION} Expression
|
@@ -0,0 +1,145 @@
|
|
1
|
+
*
|
2
|
+
margin: 0
|
3
|
+
padding: 0
|
4
|
+
|
5
|
+
@mixin rounded
|
6
|
+
$radius: 6px
|
7
|
+
|
8
|
+
border-radius: $radius
|
9
|
+
-moz-border-radius: $radius
|
10
|
+
-webkit-border-radius: $radius
|
11
|
+
|
12
|
+
@mixin shadow
|
13
|
+
box-shadow: 2px 2px 2px gray
|
14
|
+
|
15
|
+
h1
|
16
|
+
font-size: 48pt
|
17
|
+
|
18
|
+
h2
|
19
|
+
font-size: 16pt
|
20
|
+
|
21
|
+
form
|
22
|
+
input, textarea
|
23
|
+
font-size: 13pt
|
24
|
+
margin: 4pt
|
25
|
+
padding: 6pt
|
26
|
+
border: 1px solid #D0D0D0
|
27
|
+
|
28
|
+
&:focus
|
29
|
+
border: 1px solid #A0F0A0
|
30
|
+
|
31
|
+
span.red
|
32
|
+
background-color: red
|
33
|
+
color: white
|
34
|
+
span.green
|
35
|
+
background-color: green
|
36
|
+
color: white
|
37
|
+
span.yellow
|
38
|
+
background-color: yellow
|
39
|
+
color: white
|
40
|
+
span.darkorange
|
41
|
+
background-color: darkorange
|
42
|
+
color: white
|
43
|
+
span.blue
|
44
|
+
background-color: blue
|
45
|
+
color: white
|
46
|
+
|
47
|
+
html
|
48
|
+
head
|
49
|
+
body
|
50
|
+
width: 100%
|
51
|
+
height: 100%
|
52
|
+
|
53
|
+
background-color: white
|
54
|
+
|
55
|
+
.page
|
56
|
+
margin-top: 20px
|
57
|
+
margin-left: auto
|
58
|
+
margin-right: auto
|
59
|
+
min-width: 960px
|
60
|
+
min-height: 100%
|
61
|
+
width: 960px
|
62
|
+
|
63
|
+
.header
|
64
|
+
color: #454545
|
65
|
+
height: 120px
|
66
|
+
text-align: center
|
67
|
+
text-shadow: 2px 2px 2px gray
|
68
|
+
|
69
|
+
.content
|
70
|
+
height: 640px
|
71
|
+
|
72
|
+
.editor
|
73
|
+
@include rounded
|
74
|
+
@include shadow
|
75
|
+
|
76
|
+
background-color: #FEFEFE
|
77
|
+
border: 1px solid #D0D0D0
|
78
|
+
padding: 18px
|
79
|
+
|
80
|
+
.regexp_entry
|
81
|
+
padding: 8px
|
82
|
+
|
83
|
+
input, span
|
84
|
+
display: inline-block
|
85
|
+
margin: 4px
|
86
|
+
|
87
|
+
span
|
88
|
+
color: gray
|
89
|
+
font-size: 24pt
|
90
|
+
vertical-align: middle
|
91
|
+
|
92
|
+
.test
|
93
|
+
|
94
|
+
.data_pane
|
95
|
+
padding: 8px
|
96
|
+
float: left
|
97
|
+
width: 420px
|
98
|
+
|
99
|
+
textarea
|
100
|
+
font-family: monaco, courier
|
101
|
+
font-size: 13pt
|
102
|
+
font-weight: bold
|
103
|
+
padding: 6pt
|
104
|
+
width: 100%
|
105
|
+
|
106
|
+
.match_pane
|
107
|
+
padding: 8px
|
108
|
+
margin-left: 50%
|
109
|
+
width: 440px
|
110
|
+
|
111
|
+
#result, #result_groups
|
112
|
+
font-family: monaco, courier
|
113
|
+
font-size: 13pt
|
114
|
+
font-weight: bold
|
115
|
+
padding: 6pt
|
116
|
+
margin: 4px
|
117
|
+
min-height: 200px
|
118
|
+
border: 1px solid #D0D0D0
|
119
|
+
|
120
|
+
.help
|
121
|
+
@include rounded
|
122
|
+
@include shadow
|
123
|
+
border: 1px solid #D0D0D0
|
124
|
+
margin-top: 32px
|
125
|
+
padding: 8px
|
126
|
+
font-size: 8pt
|
127
|
+
|
128
|
+
code
|
129
|
+
font-weight: bold
|
130
|
+
|
131
|
+
table
|
132
|
+
tr
|
133
|
+
td
|
134
|
+
padding-right: 12px
|
135
|
+
|
136
|
+
.regex_options
|
137
|
+
text-align: center
|
138
|
+
border-top: 1px solid #D0D0D0
|
139
|
+
padding-top: 16px
|
140
|
+
margin-top: 16px
|
141
|
+
|
142
|
+
code
|
143
|
+
padding-right: 12px
|
144
|
+
padding-left: 12px
|
145
|
+
|
data/lib/rubulex.rb
ADDED
data/lib/rubulex/app.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rubulex
|
2
|
+
class App < Sinatra::Base
|
3
|
+
helpers Sinatra::JSON
|
4
|
+
set :json_encoder, :to_json
|
5
|
+
set :static, true
|
6
|
+
set :public_folder, File.join(Gem.datadir("rubulex"), "public")
|
7
|
+
set :views, File.join(Gem.datadir("rubulex"), "views")
|
8
|
+
set :slim, { format: :html5 }
|
9
|
+
|
10
|
+
get '/' do
|
11
|
+
slim :index
|
12
|
+
end
|
13
|
+
|
14
|
+
get '/stylesheets/:name.css' do
|
15
|
+
content_type 'text/css', charset: 'utf-8'
|
16
|
+
|
17
|
+
sass :"/stylesheets/#{params[:name]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
post '/regex/test' do
|
21
|
+
content_type 'text/html', charset: 'utf-8'
|
22
|
+
|
23
|
+
parser = Rubulex::RegexpParser.new(
|
24
|
+
params[:regex].to_s,
|
25
|
+
params[:options].to_s,
|
26
|
+
params[:test_data].to_s
|
27
|
+
)
|
28
|
+
|
29
|
+
json parser.result
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Rubulex
|
2
|
+
class RegexpParser
|
3
|
+
def initialize(regex, options, data)
|
4
|
+
self.options = options
|
5
|
+
self.regex = regex
|
6
|
+
self.data = data
|
7
|
+
@match_result = nil
|
8
|
+
@match_groups = nil
|
9
|
+
|
10
|
+
parse
|
11
|
+
end
|
12
|
+
|
13
|
+
def data=(data)
|
14
|
+
@data = data[0..4095] || ""
|
15
|
+
end
|
16
|
+
|
17
|
+
def regex=(regex)
|
18
|
+
@regex = Regexp.new(/#{regex}/, @options)
|
19
|
+
rescue RegexpError => error
|
20
|
+
@regex = //
|
21
|
+
end
|
22
|
+
|
23
|
+
def options=(options)
|
24
|
+
options = options.match(/(?<options>(?<option>[imxo]){,4})/)[:options].split(//)
|
25
|
+
|
26
|
+
options_lookup_table = Hash.new(0)
|
27
|
+
options_lookup_table["i"] = Regexp::IGNORECASE
|
28
|
+
options_lookup_table["m"] = Regexp::MULTILINE
|
29
|
+
options_lookup_table["x"] = Regexp::EXTENDED
|
30
|
+
|
31
|
+
@options = options.inject(0) do |result, option|
|
32
|
+
result | options_lookup_table[option]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse
|
37
|
+
@data.match(@regex) do |match|
|
38
|
+
colors = ->() do
|
39
|
+
(@colors ||= [:red, :green, :darkorange, :blue].cycle).next
|
40
|
+
end
|
41
|
+
@match_result = @data.dup
|
42
|
+
@match_result.gsub!(@regex) do |match|
|
43
|
+
"<span class='#{colors.call}'>#{match}</span>"
|
44
|
+
end
|
45
|
+
@match_result.gsub!(/\n/,"<br />")
|
46
|
+
|
47
|
+
@match_groups = if match.names.length > 0
|
48
|
+
match.names.each_with_object([]) { |match_name, memo|
|
49
|
+
memo << { match_name.to_sym => match[match_name] }
|
50
|
+
}
|
51
|
+
elsif match.length > 0
|
52
|
+
match.to_a[1..-1].map.with_index { |match, index| { index => match } }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def result
|
58
|
+
{
|
59
|
+
match_result: @match_result,
|
60
|
+
match_groups: @match_groups.join("<br />")
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/rubulex.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rubulex/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "rubulex"
|
8
|
+
gem.version = Rubulex::VERSION
|
9
|
+
gem.authors = ["Oliver Feldt"]
|
10
|
+
gem.email = ["oliver.feldt@googlemail.com"]
|
11
|
+
gem.description = "A simple self-hosted Rubular Clone"
|
12
|
+
gem.summary = "Rubulex is a simple web application for developing/testing Regular Expression"
|
13
|
+
gem.homepage = "https://github.com/ofeldt/rubulex"
|
14
|
+
|
15
|
+
gem.add_runtime_dependency "sinatra", "~> 1.4.3"
|
16
|
+
gem.add_runtime_dependency "sinatra-contrib", "~> 1.4.0"
|
17
|
+
gem.add_runtime_dependency "slim", "~> 1.3.6"
|
18
|
+
gem.add_runtime_dependency "sass", "~> 3.2.7"
|
19
|
+
gem.add_runtime_dependency "bundler", "~> 1.3.5"
|
20
|
+
|
21
|
+
gem.add_development_dependency "rspec", "~> 2.13.0"
|
22
|
+
|
23
|
+
gem.files = `git ls-files`.split($/)
|
24
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
25
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
26
|
+
gem.require_paths = ["lib"]
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubulex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Oliver Feldt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sinatra
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.4.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra-contrib
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.4.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.4.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: slim
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.3.6
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.3.6
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sass
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 3.2.7
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 3.2.7
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.3.5
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.3.5
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 2.13.0
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.13.0
|
110
|
+
description: A simple self-hosted Rubular Clone
|
111
|
+
email:
|
112
|
+
- oliver.feldt@googlemail.com
|
113
|
+
executables:
|
114
|
+
- rubulex
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .gitignore
|
119
|
+
- .sass-cache/585bcb933d47ad9fc0e0c198b6c88f057e68fc16/default.sassc
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- bin/rubulex
|
125
|
+
- config.ru
|
126
|
+
- data/rubulex/public/javascripts/rubulex.js
|
127
|
+
- data/rubulex/views/index.slim
|
128
|
+
- data/rubulex/views/stylesheets/default.sass
|
129
|
+
- lib/rubulex.rb
|
130
|
+
- lib/rubulex/app.rb
|
131
|
+
- lib/rubulex/regexp_parser.rb
|
132
|
+
- lib/rubulex/version.rb
|
133
|
+
- rubulex.gemspec
|
134
|
+
homepage: https://github.com/ofeldt/rubulex
|
135
|
+
licenses: []
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.25
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: Rubulex is a simple web application for developing/testing Regular Expression
|
158
|
+
test_files: []
|