qipowl 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile +0 -1
- data/bin/bowler +1 -9
- data/config/bowlers/html.yaml +8 -6
- data/config/bowlers/ispru.yaml +16 -0
- data/extras/demo/main.rb +7 -6
- data/extras/demo/public/html.html +22 -15
- data/extras/demo/public/index.html +6 -6
- data/features/html.feature +10 -2
- data/features/ispru.feature +15 -0
- data/features/monkey.feature +8 -0
- data/features/step_definitions/bowler_steps.rb +2 -0
- data/features/step_definitions/html_steps.rb +6 -0
- data/features/step_definitions/ispru_steps.rb +2 -0
- data/features/step_definitions/monkey_steps.rb +9 -0
- data/lib/qipowl/bowlers/html.rb +11 -6
- data/lib/qipowl/bowlers/i_sp_ru.rb +96 -0
- data/lib/qipowl/core/bowler.rb +20 -16
- data/lib/qipowl/core/mapper.rb +4 -6
- data/lib/qipowl/core/monkeypatches.rb +3 -2
- data/lib/qipowl/core/ruler.rb +6 -2
- data/lib/qipowl/utils/unicode_strings.rb +26 -0
- data/lib/qipowl/version.rb +1 -1
- data/lib/qipowl.rb +9 -9
- data/qipowl.gemspec +2 -2
- metadata +10 -4
- data/lib/qipowl/bowlers/htmldoc.rb +0 -268
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c656b2aa5f88eb634e30f0ae4c9f8a1dae18237d
|
4
|
+
data.tar.gz: 26b1185aedc158f4fcb660b807bf5691fea97570
|
5
5
|
!binary "U0hBNTEy":
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78be05dbfaf7720127cb2da7db32c4b204f8f7146d69fc3749f330e0e95ec2ce5fa3d99451fc38aa38b3e041c3a41e10f3c99ea37238c4bc5c5180943bfcf4e6
|
7
|
+
data.tar.gz: 50e3187848e51d7aca086f5410ed23cf0f472bd40844e2b83101cf67c574c6267c483e53e31db4ac3ae6d37a82616cf3b6005cc9a13f9bdacd20d22e6534a89c
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,7 +3,6 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in typogrowl.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'htmlbeautifier', :git => 'https://github.com/threedaymonk/htmlbeautifier'
|
7
6
|
gem 'aquarium', '~> 0.6', :git => 'git://github.com/deanwampler/Aquarium.git'
|
8
7
|
gem "crochets", :git => 'git://github.com/mudasobwa/crochets.git'
|
9
8
|
|
data/bin/bowler
CHANGED
@@ -12,7 +12,7 @@ OptionParser.new do |opts|
|
|
12
12
|
|
13
13
|
# Bowl result?
|
14
14
|
opts.on("-a", "--action ACTION", [:bowl, :ruby, :cmd, :yaml, :html],
|
15
|
-
"Action to apply on input (bowl,
|
15
|
+
"Action to apply on input (bowl, html); default: html") do |action|
|
16
16
|
options[:action] = action || :bowl
|
17
17
|
end
|
18
18
|
|
@@ -31,14 +31,6 @@ file_or_string = File.read(file_or_string) if File.exist?(file_or_string)
|
|
31
31
|
case options[:action]
|
32
32
|
when :bowl
|
33
33
|
puts file_or_string.bowl
|
34
|
-
when :ruby
|
35
|
-
puts Qipowl::Mapping.new(nil, file_or_string).to_ruby
|
36
|
-
when :html
|
37
|
-
puts Qipowl::Html.parse file_or_string
|
38
|
-
when :cmd
|
39
|
-
puts Qipowl::Cmd.execute file_or_string
|
40
|
-
when :yaml
|
41
|
-
puts Qipowl::Yaml.parse file_or_string
|
42
34
|
else
|
43
35
|
puts Qipowl::Html.parse file_or_string
|
44
36
|
end
|
data/config/bowlers/html.yaml
CHANGED
@@ -74,18 +74,20 @@
|
|
74
74
|
:tag : :p
|
75
75
|
:class : :lead
|
76
76
|
:☆ :
|
77
|
-
:tag : :
|
78
|
-
:class : :
|
79
|
-
:★ :
|
77
|
+
:tag : :span
|
78
|
+
:class : :'text-warning'
|
79
|
+
:★ :
|
80
|
+
:tag : :span
|
81
|
+
:class : :'label label-info'
|
80
82
|
:☛ :
|
81
83
|
:tag : :p
|
82
|
-
:class : :
|
84
|
+
:class : :'text-success'
|
83
85
|
:☞ :
|
84
86
|
:tag : :p
|
85
|
-
:class : :
|
87
|
+
:class : :'text-info'
|
86
88
|
:☣ :
|
87
89
|
:tag : :p
|
88
|
-
:class : :
|
90
|
+
:class : :'text-warning'
|
89
91
|
:☢ :
|
90
92
|
:tag : :p
|
91
93
|
:class : :text_danger
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
:entities :
|
4
|
+
:regular :
|
5
|
+
'.' : :dot
|
6
|
+
',' : :comma
|
7
|
+
':' : :colon
|
8
|
+
';' : :semicolon
|
9
|
+
'¡' : :exclm_start
|
10
|
+
'!' : :exclm_end
|
11
|
+
'¿' : :quest_start
|
12
|
+
'?' : :quest_end
|
13
|
+
|
14
|
+
:custom :
|
15
|
+
'([.,:;?!])(?=\s|\Z)' : ' \1 '
|
16
|
+
'(?<=\s|\A)([¿¡])' : ' \1 '
|
data/extras/demo/main.rb
CHANGED
@@ -4,31 +4,32 @@ require 'cgi'
|
|
4
4
|
require 'json'
|
5
5
|
require 'sinatra'
|
6
6
|
|
7
|
-
require_relative '
|
7
|
+
require_relative '../../lib/qipowl'
|
8
8
|
|
9
9
|
use Rack::Session::Pool, :expire_after => 2592000
|
10
10
|
|
11
11
|
before do
|
12
|
-
session[:typo] ||= Qipowl.
|
12
|
+
session[:typo] ||= Qipowl::Ruler.new_bowler "html"
|
13
|
+
session[:mapping] ||= session[:typo].class::ENTITIES.rmerge({:custom => session[:typo].class::CUSTOM_TAGS}).to_json
|
13
14
|
end
|
14
15
|
|
15
16
|
get '/html/mapping' do
|
16
17
|
content_type :json
|
17
|
-
session[:
|
18
|
+
session[:mapping]
|
18
19
|
end
|
19
20
|
|
20
21
|
delete '/html/mapping/:key' do |key|
|
21
22
|
content_type :json
|
22
|
-
session[:typo].
|
23
|
+
session[:typo].remove_entity(key.to_sym).to_json
|
23
24
|
end
|
24
25
|
|
25
26
|
put '/html/mapping/:section/:key/:value/?:enclosure?' do |section, key, value, enclosure|
|
26
27
|
content_type :json
|
27
|
-
session[:typo].
|
28
|
+
session[:typo].add_entity(section.to_sym, key.to_sym, value.to_sym, enclosure ? enclosure.to_sym : nil).to_json
|
28
29
|
end
|
29
30
|
|
30
31
|
get '/html/parse' do
|
31
32
|
str = CGI::parse(request.query_string)['text'].first
|
32
33
|
content_type :html
|
33
|
-
session[:typo].
|
34
|
+
session[:typo].execute str
|
34
35
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<head>
|
7
7
|
<meta charset="utf-8">
|
8
8
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
9
|
-
<title>
|
9
|
+
<title>Qipowl for HTML</title>
|
10
10
|
<meta name="description" content="">
|
11
11
|
<meta name="viewport" content="width=device-width">
|
12
12
|
|
@@ -17,7 +17,7 @@
|
|
17
17
|
padding-bottom: 20px;
|
18
18
|
}
|
19
19
|
table.mapping {
|
20
|
-
font:
|
20
|
+
font: 10px monospace;
|
21
21
|
}
|
22
22
|
table.mapping thead {
|
23
23
|
font-size: 12px;
|
@@ -87,13 +87,12 @@
|
|
87
87
|
' <input class="form-control" id="mapping-new-enclosure" name="enclosure" placeholder="Enclosure">' +
|
88
88
|
' </div>' +
|
89
89
|
' <div class="form-group">' +
|
90
|
-
' <select class="form-control" id="mapping-new-section" name="section">' +
|
91
|
-
' <option>' + 'flush' + '</option>' +
|
90
|
+
' <select class="form-control" id="mapping-new-section" name="section">' +
|
92
91
|
' <option>' + 'block' + '</option>' +
|
92
|
+
' <option>' + 'alone' + '</option>' +
|
93
93
|
' <option>' + 'magnet' + '</option>' +
|
94
|
-
' <option>' + '
|
95
|
-
' <option>' + '
|
96
|
-
' <option>' + 'custom' + '</option>' +
|
94
|
+
' <option>' + 'grip' + '</option>' +
|
95
|
+
' <option>' + 'regular' + '</option>' +
|
97
96
|
' </select>' +
|
98
97
|
' </div>' +
|
99
98
|
' <div class="form-group">' +
|
@@ -153,11 +152,11 @@
|
|
153
152
|
<span class="icon-bar"></span>
|
154
153
|
<span class="icon-bar"></span>
|
155
154
|
</button>
|
156
|
-
<a class="navbar-brand" href="index.html">
|
155
|
+
<a class="navbar-brand" href="index.html">Qipowl Demo</a>
|
157
156
|
</div>
|
158
157
|
<div class="navbar-collapse collapse">
|
159
158
|
<ul class="nav navbar-nav">
|
160
|
-
<li><a href="http://github.com/mudasobwa/
|
159
|
+
<li><a href="http://github.com/mudasobwa/qipowl">Source</a></li>
|
161
160
|
<li class="active"><a href="#">HTML</a></li>
|
162
161
|
<!--li class="dropdown">
|
163
162
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
@@ -197,9 +196,10 @@
|
|
197
196
|
<textarea style="margin-bottom:0.2em;" type="text" rows="21" id="text" name="text" class="form-control">
|
198
197
|
§1 Welcome!
|
199
198
|
|
200
|
-
|
199
|
+
¶ Qipowl ≈helps≈ you to ≡format rich≡ using plain text. This para is, for instance,
|
200
|
+
has “leading para” bootstrap class ( `class='lead'`).
|
201
201
|
|
202
|
-
|
202
|
+
This is a plain para with slight ≡qipowl≡ markup.
|
203
203
|
|
204
204
|
• unbulleted lists:
|
205
205
|
• nice
|
@@ -208,8 +208,8 @@ Typogrowl ≈helps≈ you to ≡format rich≡ using plain text. This para is, f
|
|
208
208
|
|
209
209
|
★ Feel free to test:
|
210
210
|
▷ bulleted lists — with “•” symbol
|
211
|
-
▷ data lists —
|
212
|
-
▷ blockquotes —
|
211
|
+
▷ data lists — with “▶”
|
212
|
+
▷ blockquotes — with “〉” and nesteds
|
213
213
|
▷ links — with “ ¹” and other human readables
|
214
214
|
|
215
215
|
§3 Even bootstrap classes are available:
|
@@ -221,9 +221,16 @@ Typogrowl ≈helps≈ you to ≡format rich≡ using plain text. This para is, f
|
|
221
221
|
• “☣” for “warning” text
|
222
222
|
• “☢” for “danger” text
|
223
223
|
|
224
|
-
|
224
|
+
✍
|
225
225
|
Comments are visible in HTML source only
|
226
|
-
|
226
|
+
✍
|
227
|
+
|
228
|
+
Λ ruby
|
229
|
+
# Source code snippet
|
230
|
+
void main() {
|
231
|
+
exit("Hello, World!");
|
232
|
+
}
|
233
|
+
Λ
|
227
234
|
|
228
235
|
Hope you’ll enjoy!
|
229
236
|
</textarea>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<head>
|
7
7
|
<meta charset="utf-8">
|
8
8
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
9
|
-
<title>
|
9
|
+
<title>Qipowl Demo</title>
|
10
10
|
<meta name="description" content="">
|
11
11
|
<meta name="viewport" content="width=device-width">
|
12
12
|
|
@@ -34,11 +34,11 @@
|
|
34
34
|
<span class="icon-bar"></span>
|
35
35
|
<span class="icon-bar"></span>
|
36
36
|
</button>
|
37
|
-
<a class="navbar-brand" href="index.html">
|
37
|
+
<a class="navbar-brand" href="index.html">Qipowl Demo</a>
|
38
38
|
</div>
|
39
39
|
<nav class="navbar-collapse collapse">
|
40
40
|
<ul class="nav navbar-nav">
|
41
|
-
<li><a href="http://github.com/mudasobwa/
|
41
|
+
<li><a href="http://github.com/mudasobwa/qipowl">Source</a></li>
|
42
42
|
<li><a href="html.html">HTML</a></li>
|
43
43
|
<!--li class="dropdown">
|
44
44
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
|
@@ -69,12 +69,12 @@
|
|
69
69
|
<!-- Main jumbotron for a primary marketing message or call to action -->
|
70
70
|
<div class="jumbotron">
|
71
71
|
<div class="container">
|
72
|
-
<h1>
|
73
|
-
<p><em>
|
72
|
+
<h1>Qipowl rules</h1>
|
73
|
+
<p><em>Qipowl</em> is the next generation markup environment. It’s not the
|
74
74
|
markup language only, since it provides the very efficient and straightforward
|
75
75
|
library to produce custom markups. It′s not the markup library either,
|
76
76
|
since it comes with ready-to-use markdown-like markup and 2HTML converter.</p>
|
77
|
-
<p><a class="btn btn-primary btn-lg" href="https://github.com/mudasobwa/
|
77
|
+
<p><a class="btn btn-primary btn-lg" href="https://github.com/mudasobwa/qipowl#usage">Learn more »</a></p>
|
78
78
|
</div>
|
79
79
|
</div>
|
80
80
|
|
data/features/html.feature
CHANGED
@@ -23,6 +23,15 @@ Feature: All the possibilities of HTML parser
|
|
23
23
|
| "here λ≡code bold≡λ goes" | "<p>here <code><strong>code bold</strong></code> goes</p>" |
|
24
24
|
| "Hello, ≈World≈!" | "<p>Hello, <em>World</em>!</p>" |
|
25
25
|
|
26
|
+
Scenario Outline: Inplace tags nested
|
27
|
+
Given we use "html" bowler
|
28
|
+
When the input string is <input>
|
29
|
+
And the execute method is called on bowler
|
30
|
+
Then the result should NOT equal to <output>
|
31
|
+
|
32
|
+
Examples:
|
33
|
+
| input | output |
|
34
|
+
| "here ≡nested ≡bold≡ tags≡ go" | "<p>here <strong>nested <strong>bold</strong> tags</strong> goes</p>" |
|
26
35
|
|
27
36
|
Scenario Outline: Alone tags
|
28
37
|
Given we use "html" bowler
|
@@ -42,7 +51,7 @@ Feature: All the possibilities of HTML parser
|
|
42
51
|
Then the result should equal to
|
43
52
|
"""
|
44
53
|
|
45
|
-
<pre class='ruby'>@mapping[:block] = ≡bold
|
54
|
+
<pre class='ruby'>@mapping[:block] = ≡bold≡</pre>
|
46
55
|
"""
|
47
56
|
|
48
57
|
Scenario: Block tag ✍
|
@@ -189,7 +198,6 @@ Feature: All the possibilities of HTML parser
|
|
189
198
|
Then the result should equal to
|
190
199
|
"""
|
191
200
|
|
192
|
-
|
193
201
|
<p>Nice?</p>
|
194
202
|
"""
|
195
203
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Feature: Text must be properly translated with Ispru
|
4
|
+
|
5
|
+
Scenario Outline: Russian language
|
6
|
+
Given we use "ispru" bowler
|
7
|
+
When the input string is <input>
|
8
|
+
And the execute method is called on bowler
|
9
|
+
Then the result should equal to <output>
|
10
|
+
|
11
|
+
Examples:
|
12
|
+
| input | output |
|
13
|
+
| "Он сказал: 'Поехали!'." | "Он сказал: «Поехали!»." |
|
14
|
+
| "Ссылка: http://wikipedia.org не покорежена." | "Ссылка: http://wikipedia.org не покорежена." |
|
15
|
+
| "Mamá lavados marco." | "Мама моет раму." |
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
Then(/^the result should equal to "(.*?)"$/) do |result|
|
2
4
|
expect(@result.carriage).to eq(result)
|
3
5
|
end
|
@@ -9,3 +11,7 @@ end
|
|
9
11
|
Then(/^the result should match "(.*?)"$/) do |result|
|
10
12
|
expect(@result).to match(result)
|
11
13
|
end
|
14
|
+
|
15
|
+
Then(/^the result should NOT equal to "(.*?)"$/) do |result|
|
16
|
+
expect(@result.carriage).not_to eq(result)
|
17
|
+
end
|
data/lib/qipowl/bowlers/html.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'net/http'
|
4
|
-
require 'htmlbeautifier'
|
5
4
|
|
6
5
|
require_relative '../core/bowler'
|
7
|
-
require_relative '../bowlers/htmldoc'
|
8
6
|
|
9
7
|
module Qipowl
|
8
|
+
module Mappers
|
9
|
+
class HtmlBowlerMapper < BowlerMapper
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
10
14
|
# Module placeholder for dynamically created bowlers
|
11
15
|
module Bowlers
|
12
16
|
class Html < Bowler
|
@@ -18,8 +22,7 @@ module Qipowl
|
|
18
22
|
# @param [Array] args the words, gained since last call to {#harvest}
|
19
23
|
# @return [Array] the array of words with trimmed `grip` tag
|
20
24
|
def ∀_grip *args
|
21
|
-
|
22
|
-
mine, rest = text.split("#{__callee__}∎", 2)
|
25
|
+
mine, rest = [*args].join(SEPARATOR).split("#{__callee__}∎", 2)
|
23
26
|
[tagify(∃_grip_tag(__callee__), {:class => ∃_grip(__callee__)[:class]}, mine), rest]
|
24
27
|
end
|
25
28
|
|
@@ -35,12 +38,14 @@ module Qipowl
|
|
35
38
|
# @param [String] param the text to be places on the same string as
|
36
39
|
# opening tag
|
37
40
|
# @return [Nil] nil
|
38
|
-
def ∀_block
|
41
|
+
def ∀_block *args
|
42
|
+
param, *args = args.flatten
|
43
|
+
param = param.to_s
|
39
44
|
harvest __callee__,
|
40
45
|
tagify(
|
41
46
|
∃_block_tag(__callee__),
|
42
47
|
{:class => (param.strip.empty? ? ∃_block(__callee__)[:class] : param.strip)},
|
43
|
-
args.hsub(String::HTML_ENTITIES)
|
48
|
+
args.join(SEPARATOR).hsub(String::HTML_ENTITIES)
|
44
49
|
)
|
45
50
|
end
|
46
51
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# КТО ЧТО_ДЕЛАЕТ КОМУ ЧТО
|
4
|
+
# ☺ ⚙ ♿ ☕
|
5
|
+
|
6
|
+
# КАКОЙ КАК КАКОЙ КАКОЙ
|
7
|
+
# ☼ ☂ ☼ ☼
|
8
|
+
|
9
|
+
# ПОКА НЕ ОПРЕДЕЛЕНА ЧАСТЬ РЕЧИ (найти термин для)
|
10
|
+
# ∈
|
11
|
+
|
12
|
+
# МАРКЕРЫ ДЛЯ ПАДЕЖЕЙ, ВРЕМЕН, [ДЕЕ]ПРИЧАСТИЙ ИТД.
|
13
|
+
# например: глагол_наст.вр_деепричастие — «сетуя»
|
14
|
+
|
15
|
+
require 'typogrowth'
|
16
|
+
|
17
|
+
require_relative '../core/bowler'
|
18
|
+
|
19
|
+
module Qipowl
|
20
|
+
module Mappers
|
21
|
+
class IspruBowlerMapper < BowlerMapper
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Bowlers
|
27
|
+
class Ispru < Bowler
|
28
|
+
|
29
|
+
attr_reader :dict
|
30
|
+
|
31
|
+
LANG_FROM = 'es' # FIXME UGLY
|
32
|
+
LANG_TO = 'ru' # FIXME UGLY
|
33
|
+
|
34
|
+
##############################################################################
|
35
|
+
### Default handlers for all the types of markup ###
|
36
|
+
##############################################################################
|
37
|
+
|
38
|
+
# `:regular` default handler
|
39
|
+
# @param [Array] args the words, gained since last call to {#harvest}
|
40
|
+
def ∀_regular *args
|
41
|
+
["#{__callee__}", [*args].flatten]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Drum-roll!! The main handler for words
|
45
|
+
def ∀_word method, *args, &block
|
46
|
+
[(@dict[method.to_s.unbowl] || method).bowl, args]
|
47
|
+
end
|
48
|
+
|
49
|
+
=begin
|
50
|
+
def . *args
|
51
|
+
end
|
52
|
+
def , *args
|
53
|
+
end
|
54
|
+
def ; *args
|
55
|
+
end
|
56
|
+
def ! *args
|
57
|
+
end
|
58
|
+
def ? *args
|
59
|
+
end
|
60
|
+
def ! *args
|
61
|
+
[__callee__, args]
|
62
|
+
end
|
63
|
+
def : *args
|
64
|
+
[__callee__, args]
|
65
|
+
end
|
66
|
+
=end
|
67
|
+
protected
|
68
|
+
def defreeze str
|
69
|
+
@dict = {'Mamá' => 'Мама', 'lavados' => 'моет', 'marco' => 'раму'}
|
70
|
+
(super str) # .typo(LANG_FROM)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @see {Qipowl::Bowler#serveup}
|
74
|
+
#
|
75
|
+
# Additionally it beatifies the output HTML
|
76
|
+
#
|
77
|
+
# @param [String] str to be roasted
|
78
|
+
def serveup str
|
79
|
+
(super str).typo(LANG_TO).strip
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
# Hence we cannot simply declare the DSL for it, we need to handle
|
84
|
+
# calls to all the _methods_, starting with those symbols.
|
85
|
+
#
|
86
|
+
# @param [Symbol] method as specified by caller (`method_missing`.)
|
87
|
+
# @param [Array] args as specified by caller (`method_missing`.)
|
88
|
+
# @param [Proc] block as specified by caller (`method_missing`.)
|
89
|
+
#
|
90
|
+
# @return [Array] the array of words
|
91
|
+
def special_handler method, *args, &block
|
92
|
+
∀_word method, args, block
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/qipowl/core/bowler.rb
CHANGED
@@ -46,7 +46,7 @@ module Qipowl::Bowlers
|
|
46
46
|
# Everything is a DSL, remember?
|
47
47
|
#
|
48
48
|
# @return true
|
49
|
-
def respond_to?
|
49
|
+
def respond_to? method, incl_priv = false
|
50
50
|
true
|
51
51
|
end
|
52
52
|
|
@@ -68,7 +68,7 @@ module Qipowl::Bowlers
|
|
68
68
|
if self.private_methods.include?(:special_handler)
|
69
69
|
[method, args].flatten
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Adds new +entity+ in the section specified.
|
73
73
|
# E. g., call to
|
74
74
|
#
|
@@ -125,7 +125,7 @@ module Qipowl::Bowlers
|
|
125
125
|
%w(block alone magnet grip regular).each { |section|
|
126
126
|
define_method "∀_#{section}".to_sym, ->(*args) {
|
127
127
|
raise "Default method for #{section} (“#{self.class.name.gsub(/_\d+\Z/, '')}#∀_#{section}”) MUST be defined"
|
128
|
-
}
|
128
|
+
} unless Bowler.instance_methods(true).include?("∀_#{section}".to_sym)
|
129
129
|
}
|
130
130
|
|
131
131
|
def defreeze str
|
@@ -133,14 +133,14 @@ module Qipowl::Bowlers
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def roast str
|
136
|
-
(split str).
|
136
|
+
(split str).map { |dish|
|
137
137
|
@yielded = []
|
138
138
|
rest = begin
|
139
|
-
eval(dish.
|
139
|
+
eval(dish.bowl.carriage)
|
140
140
|
rescue Exception => e
|
141
141
|
msg = e.message.dup
|
142
142
|
logger.error '='*78
|
143
|
-
logger.error "Could not roast dish [#{msg.force_encoding(Encoding::UTF_8)}].\nWill return as is… Dish follows
|
143
|
+
logger.error "Could not roast dish [#{msg.force_encoding(Encoding::UTF_8)}].\nWill return as is… Dish follows:\n\n"
|
144
144
|
logger.error '-'*78
|
145
145
|
logger.error dish
|
146
146
|
logger.error '='*78
|
@@ -148,7 +148,7 @@ module Qipowl::Bowlers
|
|
148
148
|
end
|
149
149
|
harvest(nil, orphan([*rest].join(SEPARATOR))) # FIXME Check if this is correct in all the cases
|
150
150
|
@yielded.pop(@yielded.size).reverse.join(SEPARATOR)
|
151
|
-
}.
|
151
|
+
}.join($/).uncarriage.un␚ify.unspacefy.unbowl
|
152
152
|
end
|
153
153
|
|
154
154
|
def serveup str
|
@@ -204,12 +204,13 @@ module Qipowl::Bowlers
|
|
204
204
|
private
|
205
205
|
# Prepares blocks in the input for the execution
|
206
206
|
def block str
|
207
|
+
return str unless self.class.const_defined?(:BLOCK_TAGS)
|
207
208
|
result = str.dup
|
208
209
|
self.class::BLOCK_TAGS.each { |tag, value|
|
209
|
-
result.gsub!(/(#{tag})\s*(\S*\s
|
210
|
+
result.gsub!(/(#{tag})\s*(\S*\s?|$)(.*?)(#{tag}|\Z)/m) {
|
210
211
|
%Q{
|
211
212
|
|
212
|
-
#{$1}
|
213
|
+
#{$1} #{$2.strip.bowl} #{$3.bowl.carriage}
|
213
214
|
|
214
215
|
}
|
215
216
|
}
|
@@ -219,17 +220,19 @@ module Qipowl::Bowlers
|
|
219
220
|
|
220
221
|
# Prepares customs in the input for the execution
|
221
222
|
def custom str
|
222
|
-
|
223
|
+
return str unless self.class.const_defined?(:CUSTOM_TAGS)
|
224
|
+
result = str.dup
|
223
225
|
self.class::CUSTOM_TAGS.each { |tag, value|
|
224
|
-
result.gsub!(/#{tag}
|
226
|
+
result.gsub!(/#{tag}/m, value)
|
225
227
|
}
|
226
|
-
result
|
228
|
+
result
|
227
229
|
end
|
228
230
|
|
229
231
|
# Prepares grips in the input for the execution
|
230
232
|
# FIX<E There is a problem: we append a trailing space, need to remove it later!!
|
231
233
|
def grip str
|
232
|
-
|
234
|
+
return str unless self.class.const_defined?(:GRIP_TAGS)
|
235
|
+
result = str.bowl
|
233
236
|
self.class::GRIP_TAGS.each { |tag, value|
|
234
237
|
result.gsub!(/(?:#{tag})(.*?)(?:#{tag})/m) {
|
235
238
|
next if (args = $1).vacant?
|
@@ -237,12 +240,13 @@ module Qipowl::Bowlers
|
|
237
240
|
"⌦ #{tag} #{args}#{tag}∎⌫"
|
238
241
|
}
|
239
242
|
}
|
240
|
-
result
|
243
|
+
result.unbowl
|
241
244
|
end
|
242
245
|
|
243
246
|
def split str
|
244
|
-
(block str
|
245
|
-
|
247
|
+
(block str).split(/\R{2,}/).map { |para|
|
248
|
+
self.class.const_defined?(:BLOCK_TAGS) &&
|
249
|
+
(para =~ /\A(#{self.class::BLOCK_TAGS.keys.join('|')})\s+/) ?
|
246
250
|
para : (grip custom para)
|
247
251
|
}
|
248
252
|
end
|
data/lib/qipowl/core/mapper.rb
CHANGED
@@ -37,7 +37,7 @@ module Qipowl::Mappers
|
|
37
37
|
@hash.rmerge!(input.to_hash)
|
38
38
|
incs.each { |inc|
|
39
39
|
merge! inc
|
40
|
-
} rescue NoMethodError
|
40
|
+
} rescue NoMethodError # FIXME WTF rescueing here?
|
41
41
|
end
|
42
42
|
private
|
43
43
|
# FIXME Make file search more flexible!!!
|
@@ -49,6 +49,8 @@ module Qipowl::Mappers
|
|
49
49
|
end
|
50
50
|
|
51
51
|
class BowlerMapper < Mapper
|
52
|
+
include TypoLogging
|
53
|
+
|
52
54
|
def initialize input = nil
|
53
55
|
input = self.class.name.split('::').last.downcase.gsub(/bowlermapper\Z/, '') if input.nil?
|
54
56
|
super input
|
@@ -57,7 +59,7 @@ module Qipowl::Mappers
|
|
57
59
|
@entities_dirty = true
|
58
60
|
|
59
61
|
def entities
|
60
|
-
return @entities unless @entities_dirty
|
62
|
+
return @entities unless @entities_dirty && @hash[:entities]
|
61
63
|
@entities = {}
|
62
64
|
@hash[:entities].each { |key, value| # :block. :alone etc
|
63
65
|
@entities[key] ||= {}
|
@@ -78,10 +80,6 @@ module Qipowl::Mappers
|
|
78
80
|
@entities
|
79
81
|
end
|
80
82
|
end
|
81
|
-
|
82
|
-
class HtmlBowlerMapper < BowlerMapper
|
83
|
-
|
84
|
-
end
|
85
83
|
end
|
86
84
|
|
87
85
|
if __FILE__ == $0
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require_relative '../utils/unicode_strings'
|
3
4
|
require_relative '../utils/hash_recursive_merge'
|
4
5
|
|
5
6
|
module Qipowl
|
@@ -114,11 +115,11 @@ module Qipowl
|
|
114
115
|
self.gsub!(/\R/, " #{CARRIAGE_RETURN} ")
|
115
116
|
end
|
116
117
|
def uncarriage
|
117
|
-
self.gsub(
|
118
|
+
self.gsub(/\s?#{CARRIAGE_RETURN}\s?/, %Q(
|
118
119
|
))
|
119
120
|
end
|
120
121
|
def uncarriage!
|
121
|
-
self.gsub!(
|
122
|
+
self.gsub!(/\s?#{CARRIAGE_RETURN}\s?/, %Q(
|
122
123
|
))
|
123
124
|
end
|
124
125
|
|
data/lib/qipowl/core/ruler.rb
CHANGED
@@ -57,9 +57,12 @@ module Qipowl
|
|
57
57
|
|
58
58
|
@@yamls[yaml] = clazz.new
|
59
59
|
end
|
60
|
+
|
61
|
+
# FIXME Make contants PER-EIGENCLASS
|
60
62
|
def teach_class clazz, mapper
|
61
63
|
clazz.const_set("CUSTOM_TAGS", mapper.to_hash[:custom])
|
62
64
|
clazz.const_set("ENCLOSURES_TAGS", mapper.to_hash[:enclosures])
|
65
|
+
clazz.const_set("ENTITIES", mapper.entities)
|
63
66
|
clazz.const_set("TAGS", {})
|
64
67
|
clazz.class_eval %Q{
|
65
68
|
def ∃_enclosures entity
|
@@ -73,9 +76,10 @@ module Qipowl
|
|
73
76
|
end
|
74
77
|
}
|
75
78
|
%w(block alone magnet grip regular).each { |section|
|
79
|
+
next unless mapper.entities && mapper.entities[section.to_sym]
|
76
80
|
clazz.const_set("#{section.upcase}_TAGS", mapper.entities[section.to_sym])
|
77
81
|
clazz.class_eval %Q{
|
78
|
-
|
82
|
+
self::TAGS.rmerge! self::#{section.upcase}_TAGS
|
79
83
|
def ∃_#{section} entity
|
80
84
|
self.class::#{section.upcase}_TAGS.each { |k, v|
|
81
85
|
next unless k == entity
|
@@ -93,7 +97,7 @@ module Qipowl
|
|
93
97
|
tag = Hash === value && value[:marker] ? value[:marker] : "∀_#{section}"
|
94
98
|
clazz.class_eval %Q{
|
95
99
|
alias_method :#{key}, :#{tag}
|
96
|
-
} unless clazz.instance_methods.include?(key)
|
100
|
+
} unless clazz.instance_methods.include?(key.to_sym)
|
97
101
|
}
|
98
102
|
}
|
99
103
|
clazz.class_eval %Q{
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
if 'мама'.upcase != 'МАМА'
|
4
|
+
require 'unicode'
|
5
|
+
class ::String
|
6
|
+
def downcase
|
7
|
+
Unicode::downcase(self)
|
8
|
+
end
|
9
|
+
def downcase!
|
10
|
+
self.replace downcase
|
11
|
+
end
|
12
|
+
def upcase
|
13
|
+
Unicode::upcase(self)
|
14
|
+
end
|
15
|
+
def upcase!
|
16
|
+
self.replace upcase
|
17
|
+
end
|
18
|
+
def capitalize
|
19
|
+
Unicode::capitalize(self)
|
20
|
+
end
|
21
|
+
def capitalize!
|
22
|
+
self.replace capitalize
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
data/lib/qipowl/version.rb
CHANGED
data/lib/qipowl.rb
CHANGED
@@ -4,7 +4,9 @@ require_relative "qipowl/version"
|
|
4
4
|
require_relative "qipowl/core/mapper"
|
5
5
|
require_relative "qipowl/core/ruler"
|
6
6
|
require_relative "qipowl/core/bowler"
|
7
|
+
|
7
8
|
require_relative "qipowl/bowlers/html"
|
9
|
+
require_relative "qipowl/bowlers/i_sp_ru"
|
8
10
|
#require_relative "qipowl/bowlers/cmd"
|
9
11
|
#require_relative "qipowl/bowlers/yaml"
|
10
12
|
|
@@ -33,18 +35,16 @@ module Qipowl
|
|
33
35
|
instance_eval(&block)
|
34
36
|
end
|
35
37
|
|
36
|
-
def self.tg__html
|
37
|
-
Html.new
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.tg_md__html
|
41
|
-
result = tg__html
|
42
|
-
result.merge_rules "#{File.dirname(__FILE__)}/tagmaps/markdown2html.yaml"
|
43
|
-
result
|
44
|
-
end
|
45
38
|
end
|
46
39
|
|
47
40
|
Qipowl::config do
|
48
41
|
params :bowlers_dir
|
49
42
|
bowlers_dir File.expand_path(File.join(__dir__, '..', 'config', 'bowlers'))
|
43
|
+
end
|
44
|
+
|
45
|
+
class Qipowl::Html
|
46
|
+
attr_reader :bowler
|
47
|
+
def self.parse s
|
48
|
+
(@bowler ||= Qipowl::Ruler.new_bowler "html").execute s
|
49
|
+
end
|
50
50
|
end
|
data/qipowl.gemspec
CHANGED
@@ -34,8 +34,8 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_development_dependency 'yard-cucumber'
|
35
35
|
|
36
36
|
s.add_dependency 'psych'
|
37
|
-
s.add_dependency '
|
38
|
-
s.add_dependency '
|
37
|
+
s.add_dependency 'unicode'
|
38
|
+
s.add_dependency 'typogrowth'
|
39
39
|
s.add_dependency 'aquarium'
|
40
40
|
s.add_dependency 'crochets'
|
41
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qipowl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexei Matyushkin
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: unicode
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ! '>='
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: typogrowth
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ! '>='
|
@@ -172,6 +172,7 @@ files:
|
|
172
172
|
- config/bowlers/cmd.yaml
|
173
173
|
- config/bowlers/html.yaml
|
174
174
|
- config/bowlers/html_supplemental.yaml
|
175
|
+
- config/bowlers/ispru.yaml
|
175
176
|
- config/bowlers/markdown2html.yaml
|
176
177
|
- extras/demo/main.rb
|
177
178
|
- extras/demo/public/apple-touch-icon-114x114-precomposed.png
|
@@ -201,8 +202,12 @@ files:
|
|
201
202
|
- extras/support/typo
|
202
203
|
- features/bowler.feature
|
203
204
|
- features/html.feature
|
205
|
+
- features/ispru.feature
|
206
|
+
- features/monkey.feature
|
204
207
|
- features/step_definitions/bowler_steps.rb
|
205
208
|
- features/step_definitions/html_steps.rb
|
209
|
+
- features/step_definitions/ispru_steps.rb
|
210
|
+
- features/step_definitions/monkey_steps.rb
|
206
211
|
- features/support/env.rb
|
207
212
|
- images/owl-old.png
|
208
213
|
- images/owl-old.xcf
|
@@ -211,7 +216,7 @@ files:
|
|
211
216
|
- lib/qipowl.rb
|
212
217
|
- lib/qipowl/bowlers/cmd.rb
|
213
218
|
- lib/qipowl/bowlers/html.rb
|
214
|
-
- lib/qipowl/bowlers/
|
219
|
+
- lib/qipowl/bowlers/i_sp_ru.rb
|
215
220
|
- lib/qipowl/bowlers/yaml.rb
|
216
221
|
- lib/qipowl/core/bowler.rb
|
217
222
|
- lib/qipowl/core/mapper.rb
|
@@ -219,6 +224,7 @@ files:
|
|
219
224
|
- lib/qipowl/core/ruler.rb
|
220
225
|
- lib/qipowl/utils/hash_recursive_merge.rb
|
221
226
|
- lib/qipowl/utils/logging.rb
|
227
|
+
- lib/qipowl/utils/unicode_strings.rb
|
222
228
|
- lib/qipowl/version.rb
|
223
229
|
- qipowl.gemspec
|
224
230
|
- qipowl.komodoproject
|
@@ -1,268 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'fileutils'
|
5
|
-
require 'yaml'
|
6
|
-
require_relative '../core/monkeypatches.rb'
|
7
|
-
require_relative '../utils/hash_recursive_merge.rb'
|
8
|
-
|
9
|
-
module Qipowl
|
10
|
-
|
11
|
-
class HtmlDoc < Nokogiri::XML::SAX::Document
|
12
|
-
attr_reader :qp, :tags
|
13
|
-
def initialize mapping
|
14
|
-
@mapping = mapping
|
15
|
-
@inside = nil
|
16
|
-
@collector = {}
|
17
|
-
@tags = {:inplace => {}, :linewide => {}}
|
18
|
-
@qp = ''
|
19
|
-
@level = 0
|
20
|
-
end
|
21
|
-
|
22
|
-
def start_element name, attributes = []
|
23
|
-
current_attrs = Hash[attributes]
|
24
|
-
|
25
|
-
@qp += case name.to_sym
|
26
|
-
when :p, :div
|
27
|
-
if current_attrs['class']
|
28
|
-
@collector[name.to_sym] = "✿_#{name.to_sym}_#{current_attrs['class'].gsub(/\s+/, '_')}".to_sym
|
29
|
-
@tags[:linewide][@collector[name.to_sym]] = "#{name.to_sym}†#{current_attrs['class'].gsub(/\s+/, '†')}".to_sym
|
30
|
-
"\n\n#{@collector[name.to_sym]} "
|
31
|
-
else
|
32
|
-
"\n\n"
|
33
|
-
end
|
34
|
-
when :ul, :ol, :table, :dl
|
35
|
-
@inside = name.to_sym
|
36
|
-
"\n"
|
37
|
-
when :pre then "\n\nΛ\n"
|
38
|
-
when :tr then " ┇ "
|
39
|
-
when :td then " ┆ "
|
40
|
-
when :a
|
41
|
-
@inside = :a
|
42
|
-
@collector[:href] = current_attrs['href']
|
43
|
-
@collector[:name] = current_attrs['name']
|
44
|
-
''
|
45
|
-
when :li then (@inside == :ol) ? "◦ " : "• "
|
46
|
-
when :b, :strong then "≡"
|
47
|
-
when :i, :em, :nobr then "≈"
|
48
|
-
when :strike, :del, :s then "─"
|
49
|
-
when :small then "↓"
|
50
|
-
when :u then "▁"
|
51
|
-
when :code, :tt then "λ"
|
52
|
-
when :dfn, :abbr, :cite
|
53
|
-
@inside = name.to_sym
|
54
|
-
@collector[:title] = current_attrs['title']
|
55
|
-
when :hr then "\n\n——\n\n"
|
56
|
-
when :br then " ⏎\n"
|
57
|
-
when :center then "\n— "
|
58
|
-
when :dt then "▷ "
|
59
|
-
when :dd then " — "
|
60
|
-
when :h1 then "§1 "
|
61
|
-
when :h2 then "§2 "
|
62
|
-
when :h3 then "§3 "
|
63
|
-
when :h4 then "§4 "
|
64
|
-
when :h5 then "§5 "
|
65
|
-
when :h6 then "§6 "
|
66
|
-
when :blockquote then "\n\n〉 "
|
67
|
-
when :figure
|
68
|
-
@inside = :figure
|
69
|
-
"\n\n"
|
70
|
-
when :figcaption then " "
|
71
|
-
when :img then fix_href(current_attrs['src'])
|
72
|
-
when :span, :sup
|
73
|
-
if current_attrs['class'].nil?
|
74
|
-
''
|
75
|
-
else
|
76
|
-
@collector[name.to_sym] = "✿_span_#{current_attrs['class'].gsub(/\s+/, '_')}".to_sym
|
77
|
-
@tags[:inplace][@collector[name.to_sym]] = "span†#{current_attrs['class'].gsub(/\s+/, '†')}".to_sym
|
78
|
-
" #{@collector[name.to_sym]}"
|
79
|
-
end
|
80
|
-
when :embed, :iframe then "\n\n#{current_attrs['src']}\n\n"
|
81
|
-
when :html, :body, :object, :param, :thead, :tbody, :font, :'lj-embed', :'lj-cut'
|
82
|
-
''
|
83
|
-
else
|
84
|
-
raise "=== Unhandled: #{name} with attrs: [#{current_attrs}]"
|
85
|
-
''
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def characters str
|
90
|
-
case @inside
|
91
|
-
when :a, :dfn, :abbr
|
92
|
-
@collector[:text] = str
|
93
|
-
else
|
94
|
-
@qp += str
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def end_element name
|
99
|
-
@qp += case name.to_sym
|
100
|
-
when :p, :div
|
101
|
-
@collector.delete(name.to_sym)
|
102
|
-
"\n\n"
|
103
|
-
when :a
|
104
|
-
@inside = nil
|
105
|
-
(href= @collector.delete(:href)) ?
|
106
|
-
" #{(@collector.delete(:text) || '').gsub(/\s+/, "\u{00A0}")}¹#{fix_href href} " :
|
107
|
-
"☇ #{@collector.delete(:name)} #{@collector.delete(:text)}"
|
108
|
-
when :dfn, :abbr, :cite
|
109
|
-
@inside = nil
|
110
|
-
result = " #{@collector.delete(:text).gsub(/\s+/, "\u{00A0}")}†#{@collector.delete(:title)}† " rescue ''
|
111
|
-
result
|
112
|
-
when :ul, :ol, :table, :dl
|
113
|
-
@inside = nil
|
114
|
-
"\n"
|
115
|
-
when :li then "\n"
|
116
|
-
when :pre then "\nΛ\n\n"
|
117
|
-
when :b, :strong then "≡"
|
118
|
-
when :i, :em, :nobr then "≈"
|
119
|
-
when :u then "▁"
|
120
|
-
when :dd then "\n"
|
121
|
-
when :strike, :del, :s then "─"
|
122
|
-
when :small then "↓"
|
123
|
-
when :code, :tt then "λ"
|
124
|
-
when :span, :sup
|
125
|
-
"#{@collector.delete(name.to_sym)} "
|
126
|
-
when :h1, :h2, :h3, :h4, :h5, :h6 then "\n\n"
|
127
|
-
when :blockquote then "\n\n"
|
128
|
-
when :figure
|
129
|
-
@inside = nil
|
130
|
-
"\n\n"
|
131
|
-
else
|
132
|
-
''
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
def fix_href href, site = 'http://mudasobwa.ru/'
|
138
|
-
href.start_with?('http') ? href : href.gsub(/\A\/+/, '').prepend(site)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
if __FILE__ == $0
|
145
|
-
|
146
|
-
def prepare str
|
147
|
-
str.gsub(/&[nm]dash;/, '—') # dashes
|
148
|
-
.gsub(/ /, ' ') # dashes
|
149
|
-
.gsub(/\s+--\s+/, ' — ') # dashes
|
150
|
-
.gsub(/^\s*/, '') # leading spaces
|
151
|
-
.gsub(/<img src="\/i\/>/, '')
|
152
|
-
.gsub(/™/, '™') # other entities
|
153
|
-
.gsub(/©/, '©') # other entities
|
154
|
-
.gsub(/(1st@1stone.ru|am@secondiary.ru)/, 'am@mudasobwa.ru')
|
155
|
-
.gsub(/http:\/\/(www\.)?(secondiary|1stone|matiouchkine.net)\.ru/, 'http://mudasobwa.ru') # obsolete site name
|
156
|
-
.gsub(/\[(http[^\]]*)\]/, '\1') # obsolete markdown pics
|
157
|
-
.gsub(/<span>\s*<\/span>/, 'λ\1λ') # obsolete markdown pics
|
158
|
-
.gsub(/<lj (?:comm|user)="(.*?)">/, '✎ \1') # obsolete markdown pics
|
159
|
-
.gsub(/<([^<>]*?@[^<>]*?)>/, '\1') # obsolete markdown pics
|
160
|
-
.gsub(/<imgsrc=/, '<img src=') # obsolete markdown pics
|
161
|
-
.gsub(/<ahref=/, '<a href=') # obsolete markdown pics
|
162
|
-
.gsub(/<\/p>\s*<p>\s*—/, " ⏎\n—") # direct speech
|
163
|
-
.gsub(/<br(?:\s*\/?\s*)>\s*<br(?:\s*\/?\s*)>/, "\n\n") # old-fashioned carriage
|
164
|
-
.gsub(/<[!]--[^<>]*?-->/, '') # comments
|
165
|
-
# .gsub(/([\.,:;!?])(?=\S)/, '\1 ') # fix punctuation
|
166
|
-
end
|
167
|
-
|
168
|
-
def postpare str
|
169
|
-
str.gsub(/\R{2,}/, "\n\n")
|
170
|
-
.gsub(/\A(\s|⏎)*/, '')
|
171
|
-
.gsub(/(\s|⏎)*\Z/, '')
|
172
|
-
end
|
173
|
-
|
174
|
-
tags = {
|
175
|
-
:magnet => {:✎ => :lj, :☇ => :a},
|
176
|
-
:inplace => {:▁ => :u, :─ => :del},
|
177
|
-
:linewide => {:☛ => :twit},
|
178
|
-
:block => {:✁ => :cut}
|
179
|
-
}
|
180
|
-
file = "#{File.dirname(__FILE__)}/../../../data/internals/posts.csv"
|
181
|
-
file_errors = "#{File.dirname(__FILE__)}/../../../data/internals/errors.txt"
|
182
|
-
FileUtils.rm file_errors if File.exist? file_errors
|
183
|
-
|
184
|
-
FileUtils.mkdir("#{File.dirname(__FILE__)}/../../../data/site")
|
185
|
-
# %w{txt pic ref twt}.each {|d| FileUtils.mkdir("#{File.dirname(__FILE__)}/../../../data/site/#{d}")}
|
186
|
-
|
187
|
-
puts "Reading #{file} …"
|
188
|
-
File.readlines(file).each { |l|
|
189
|
-
data = l.split('☢')
|
190
|
-
puts "Processing record #{data[0]}"
|
191
|
-
begin
|
192
|
-
html_doc = Qipowl::HtmlDoc.new nil
|
193
|
-
parser = Nokogiri::HTML::SAX::Parser.new(html_doc)
|
194
|
-
parser.parse(prepare data[2])
|
195
|
-
tags.rmerge! html_doc.tags
|
196
|
-
body = postpare(html_doc.qp)
|
197
|
-
|
198
|
-
body = body.strip if body
|
199
|
-
|
200
|
-
id = data[0]
|
201
|
-
title = data[1].gsub(/'/, "’")
|
202
|
-
date = data[3]
|
203
|
-
img = data[4]
|
204
|
-
|
205
|
-
if img && !img.empty? && !img.start_with?('http://')
|
206
|
-
img = "http://mudasobwa.ru/i/#{img.gsub(/\A\/+/, '')}"
|
207
|
-
end
|
208
|
-
|
209
|
-
q_doc = Qipowl::HtmlDoc.new nil
|
210
|
-
q_parser = Nokogiri::HTML::SAX::Parser.new(q_doc)
|
211
|
-
q_parser.parse(prepare data[5])
|
212
|
-
tags.rmerge! q_doc.tags
|
213
|
-
quote = postpare(q_doc.qp)
|
214
|
-
|
215
|
-
q_url = data[6]
|
216
|
-
type = data[7].to_i # 1 => text, 2 => image, 3 => quote, 4 => twit
|
217
|
-
stype = case type
|
218
|
-
when 1 then :txt
|
219
|
-
when 2 then :pic
|
220
|
-
when 3 then :ref
|
221
|
-
when 4 then :twt
|
222
|
-
else :txt
|
223
|
-
end
|
224
|
-
|
225
|
-
owl_text = %Q(---
|
226
|
-
title: '#{title}'
|
227
|
-
id: #{id}
|
228
|
-
date: '#{date}'
|
229
|
-
categories: [#{stype}]
|
230
|
-
---
|
231
|
-
|
232
|
-
)
|
233
|
-
# owl_text << (type == 4 ? "☛ " : "§1 ")
|
234
|
-
# owl_text << title
|
235
|
-
# owl_text << "\n\n"
|
236
|
-
|
237
|
-
owl_text << case type
|
238
|
-
when 2
|
239
|
-
"#{img} #{body.gsub(/\R/, ' ⏎ ')}"
|
240
|
-
when 3
|
241
|
-
q_ref = q_url[/http:\/\/(.*?)\/|\Z/, 1].split('.').last(2).join('.') rescue nil
|
242
|
-
"\n〉 #{quote.strip}\n‒ #{q_ref ? q_ref : q_url}, #{q_url}\n\n#{body}"
|
243
|
-
else body
|
244
|
-
end
|
245
|
-
|
246
|
-
fname = "#{date.split.first}-#{title.to_filename}.owl"
|
247
|
-
fname = (1..100).each {|i|
|
248
|
-
break "#{date.split.first}-#{title.to_filename}-#{i}.owl" \
|
249
|
-
unless File.exist?("#{File.dirname(__FILE__)}/../../../data/site/#{date.split.first}-#{title.to_filename}-#{i}.owl")
|
250
|
-
} if File.exist?("#{File.dirname(__FILE__)}/../../../data/site/#{fname}")
|
251
|
-
File.open("#{File.dirname(__FILE__)}/../../../data/site/#{fname}", 'a') { |f| f.write(owl_text) }
|
252
|
-
|
253
|
-
rescue Exception => e
|
254
|
-
puts '—'*40
|
255
|
-
puts 'Error occured'
|
256
|
-
puts prepare(data[2])
|
257
|
-
puts '—'*40
|
258
|
-
puts prepare(data[5])
|
259
|
-
puts '—'*40
|
260
|
-
raise e
|
261
|
-
end
|
262
|
-
}
|
263
|
-
|
264
|
-
File.open("#{File.dirname(__FILE__)}/../../../data/site/rules.yaml", 'a') { |f|
|
265
|
-
f.write(tags.to_yaml)
|
266
|
-
}
|
267
|
-
|
268
|
-
end
|