mindwords 0.3.1 → 0.5.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mindwords.rb +118 -111
- metadata +22 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cecbfa6443266445084268c94ccedf12ca1f1c4a8e601a510ad49d375c54e910
|
4
|
+
data.tar.gz: 184f031666fbc23c62ca1fb7b61bbfbce99a1bd88c75072fc9645153f4e1f502
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fd523b6544be615a5a1112deca758af2cc5f6053f03e48c4382acecd413f32db9ed440d572171be342fd64141c0f34debd18f7bd6ebc615cf125029e86ce3f4
|
7
|
+
data.tar.gz: 047f68b8746aa20cda1bff2e9c09472fee21f70d4f36cee1599576b71f6243b5107e45f632eedf2ab2e953e9df00867dda4b9a94ec13f896f6d38a136cda9ed9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mindwords.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# file: mindwords.rb
|
4
4
|
|
5
5
|
require 'rexle'
|
6
|
+
require 'rxfhelper'
|
6
7
|
require 'line-tree'
|
7
8
|
|
8
9
|
module HashCopy
|
@@ -19,97 +20,15 @@ class MindWords
|
|
19
20
|
using ColouredText
|
20
21
|
using HashCopy
|
21
22
|
|
23
|
+
attr_accessor :lines
|
22
24
|
|
23
|
-
def initialize(
|
25
|
+
def initialize(raws, parent: nil, debug: false)
|
24
26
|
|
25
|
-
@debug = debug
|
26
|
-
@a = s.strip.gsub(/^\n/,'').lines
|
27
|
-
@a.shift if @a.first =~ /<\?mindwords\?>/
|
27
|
+
@parent, @debug = parent, debug
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
h = {}
|
36
|
-
@hashtags = {}
|
37
|
-
|
38
|
-
lines.each do |title, rawtags|
|
39
|
-
|
40
|
-
rawtags.scan(/#(\w+)/).flatten(1).each do |rawtag|
|
41
|
-
tag = rawtag.gsub(/ +/, '_')
|
42
|
-
h[tag] ||= []
|
43
|
-
h[tag] << title
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
@hashtags = h.deep_clone.sort.map {|tag, fields| [tag, fields.sort]}.to_h
|
49
|
-
|
50
|
-
# does the key exist as a field? Nesting of hash object is performed here.
|
51
|
-
|
52
|
-
h.keys.each do |key|
|
53
|
-
|
54
|
-
r = h.detect {|_, value| value.include? key}
|
55
|
-
next unless r
|
56
|
-
h[r.first].delete key
|
57
|
-
h[r.first] << {key => h[key]}
|
58
|
-
#puts r.inspect
|
59
|
-
h.delete key
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
@h = h
|
64
|
-
|
65
|
-
a = rexlize(h)
|
66
|
-
doc = Rexle.new(['root', {}, '', *a])
|
67
|
-
|
68
|
-
|
69
|
-
# remove duplicates which appear in the same branch above the nested node
|
70
|
-
rm_duplicates(doc)
|
71
|
-
|
72
|
-
# remove redundant nodes (outsiders)
|
73
|
-
# a redundant node is where all children exist in existing nested nodes
|
74
|
-
|
75
|
-
redundants = doc.root.elements.map do |e|
|
76
|
-
|
77
|
-
r = e.elements.all? {|x| !x.has_elements?}
|
78
|
-
puts "%s %s" % [e.name, r] if @debug
|
79
|
-
dups = e.elements.all? {|x| doc.root.xpath('//' + x.name).length > 1}
|
80
|
-
puts 'dups: ' + dups.inspect if @debug
|
81
|
-
e.backtrack.to_s if dups
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
redundants.compact.each {|x| doc.element(x).delete }
|
86
|
-
rm_duplicates(doc)
|
87
|
-
|
88
|
-
node = if parent then
|
89
|
-
found = doc.root.element('//' + parent)
|
90
|
-
found ? found : doc.root
|
91
|
-
else
|
92
|
-
doc.root
|
93
|
-
end
|
94
|
-
|
95
|
-
@outline = treeize node
|
96
|
-
|
97
|
-
node.root.each_recursive do |e|
|
98
|
-
|
99
|
-
e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
|
100
|
-
|
101
|
-
s = e.parent.attributes[:breadcrumb] ? \
|
102
|
-
e.parent.attributes[:breadcrumb].to_s + ' / ' : ''
|
103
|
-
e.attributes[:breadcrumb] = s + e.value.strip
|
104
|
-
|
105
|
-
r = @a.grep(/^#{e.attributes[:title]} #/i)
|
106
|
-
next unless r.any?
|
107
|
-
e.attributes[:hashtags] = r[0].scan(/(?<=#)\w+/).join(' ')
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
@xml = node.xml pretty: true
|
29
|
+
s, _ = RXFHelper.read raws
|
30
|
+
@lines = s.strip.gsub(/^\n/,'').lines
|
31
|
+
@lines.shift if @lines.first =~ /<\?mindwords\?>/
|
113
32
|
|
114
33
|
end
|
115
34
|
|
@@ -119,11 +38,12 @@ class MindWords
|
|
119
38
|
e = doc.root.element("//*[@id='#{id}']")
|
120
39
|
#e.attributes[:breadcrumb].to_s if e
|
121
40
|
|
122
|
-
end
|
41
|
+
end
|
42
|
+
|
123
43
|
|
124
44
|
def search(keyword)
|
125
45
|
|
126
|
-
a = @
|
46
|
+
a = @lines.grep(/#{keyword}/i).map do |line|
|
127
47
|
|
128
48
|
puts 'line: ' + line.inspect if @debug
|
129
49
|
|
@@ -145,7 +65,7 @@ class MindWords
|
|
145
65
|
end
|
146
66
|
|
147
67
|
def sort()
|
148
|
-
s = @
|
68
|
+
s = @lines.sort.join
|
149
69
|
|
150
70
|
def s.to_s()
|
151
71
|
self.lines.map do |x|
|
@@ -158,13 +78,13 @@ class MindWords
|
|
158
78
|
end
|
159
79
|
|
160
80
|
def sort!()
|
161
|
-
@
|
81
|
+
@lines = sort().lines
|
162
82
|
self
|
163
83
|
end
|
164
84
|
|
165
85
|
def tag_sort()
|
166
86
|
|
167
|
-
h = @
|
87
|
+
h = @lines.group_by {|x| x[/#\w+/]}
|
168
88
|
s = h.sort.map {|key, value| value.sort }.join
|
169
89
|
|
170
90
|
def s.to_s()
|
@@ -179,7 +99,7 @@ class MindWords
|
|
179
99
|
end
|
180
100
|
|
181
101
|
def tag_sort!()
|
182
|
-
@
|
102
|
+
@lines = tag_sort().lines
|
183
103
|
self
|
184
104
|
end
|
185
105
|
|
@@ -192,15 +112,16 @@ class MindWords
|
|
192
112
|
end
|
193
113
|
|
194
114
|
def to_outline(sort: true)
|
115
|
+
build()
|
195
116
|
sort ? a2tree(tree_sort(LineTree.new(@outline).to_a)) : @outline
|
196
117
|
end
|
197
118
|
|
198
119
|
def to_s(colour: false)
|
199
120
|
|
200
121
|
header = "<?mindwords?>\n\n"
|
201
|
-
return header + @
|
122
|
+
return header + @lines.join unless colour
|
202
123
|
|
203
|
-
body = @
|
124
|
+
body = @lines.map do |x|
|
204
125
|
title, hashtags = x.split(/(?=#)/,2)
|
205
126
|
title + hashtags.chomp.brown
|
206
127
|
end.join("\n")
|
@@ -210,7 +131,7 @@ class MindWords
|
|
210
131
|
end
|
211
132
|
|
212
133
|
def to_words()
|
213
|
-
to_outline.lines.map {|x| x[/\w[\w ]+/] }
|
134
|
+
to_outline.lines.map {|x| x[/\w[\w ]+/] }.uniq
|
214
135
|
end
|
215
136
|
|
216
137
|
def to_xml()
|
@@ -219,6 +140,91 @@ class MindWords
|
|
219
140
|
|
220
141
|
private
|
221
142
|
|
143
|
+
def build()
|
144
|
+
|
145
|
+
h = {}
|
146
|
+
|
147
|
+
@lines.each do |line|
|
148
|
+
|
149
|
+
title, rawtags = line.split(/ (?=#)/,2)
|
150
|
+
|
151
|
+
rawtags.scan(/#(\w+)/).flatten(1).each do |rawtag|
|
152
|
+
tag = rawtag.gsub(/ +/, '_')
|
153
|
+
h[tag] ||= []
|
154
|
+
h[tag] << title
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
@hashtags = h.deep_clone.sort.map {|tag, fields| [tag, fields.sort]}.to_h
|
160
|
+
|
161
|
+
|
162
|
+
a = rexlize(h)
|
163
|
+
doc = Rexle.new(['root', {}, '', *a])
|
164
|
+
|
165
|
+
# apply node nesting
|
166
|
+
|
167
|
+
doc.root.elements.each do |e|
|
168
|
+
|
169
|
+
doc.root.xpath('//' + e.name).each do |e2|
|
170
|
+
|
171
|
+
next if e2 === e
|
172
|
+
|
173
|
+
e2.parent.add e
|
174
|
+
e2.delete
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
# remove duplicates which appear in the same branch above the nested node
|
182
|
+
rm_duplicates(doc)
|
183
|
+
|
184
|
+
# remove redundant nodes (outsiders)
|
185
|
+
# a redundant node is where all children exist in existing nested nodes
|
186
|
+
|
187
|
+
redundants = doc.root.elements.map do |e|
|
188
|
+
|
189
|
+
r = e.elements.all? {|x| !x.has_elements?}
|
190
|
+
puts "%s %s" % [e.name, r] if @debug
|
191
|
+
dups = e.elements.all? {|x| doc.root.xpath('//' + x.name).length > 1}
|
192
|
+
puts 'dups: ' + dups.inspect if @debug
|
193
|
+
e.backtrack.to_s if dups
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
redundants.compact.each {|x| doc.element(x).delete }
|
198
|
+
|
199
|
+
|
200
|
+
node = if @parent then
|
201
|
+
found = doc.root.element('//' + @parent)
|
202
|
+
found ? found : doc.root
|
203
|
+
else
|
204
|
+
doc.root
|
205
|
+
end
|
206
|
+
|
207
|
+
@outline = treeize node
|
208
|
+
|
209
|
+
node.root.each_recursive do |e|
|
210
|
+
|
211
|
+
e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
|
212
|
+
|
213
|
+
s = e.parent.attributes[:breadcrumb] ? \
|
214
|
+
e.parent.attributes[:breadcrumb].to_s + ' / ' : ''
|
215
|
+
e.attributes[:breadcrumb] = s + e.value.strip
|
216
|
+
|
217
|
+
r = @lines.grep(/^#{e.attributes[:title]} #/i)
|
218
|
+
next unless r.any?
|
219
|
+
e.attributes[:hashtags] = r[0].scan(/(?<=#)\w+/).join(' ')
|
220
|
+
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
@xml = node.xml pretty: true
|
225
|
+
|
226
|
+
end
|
227
|
+
|
222
228
|
def rexlize(a)
|
223
229
|
|
224
230
|
a.map do |x|
|
@@ -227,16 +233,19 @@ class MindWords
|
|
227
233
|
|
228
234
|
case x
|
229
235
|
when String
|
230
|
-
[x.gsub(/ +/,'
|
236
|
+
[x.downcase.gsub(/ +/,''), {title: x}, x]
|
231
237
|
when Hash
|
232
238
|
[
|
233
|
-
x.keys.first.gsub(/_/,' '),
|
239
|
+
x.keys.first.downcase.gsub(/_/,' '),
|
234
240
|
{title: x.keys.first},
|
235
241
|
x.keys.first,
|
236
242
|
*rexlize(x.values.first)
|
237
243
|
]
|
238
244
|
when Array
|
239
|
-
[
|
245
|
+
[
|
246
|
+
x.first.downcase.gsub(/_/,' '),
|
247
|
+
{title: x.first}, x.first, *rexlize(x.last)
|
248
|
+
]
|
240
249
|
end
|
241
250
|
end
|
242
251
|
|
@@ -245,24 +254,22 @@ class MindWords
|
|
245
254
|
def rm_duplicates(doc)
|
246
255
|
|
247
256
|
duplicates = []
|
257
|
+
|
248
258
|
doc.root.each_recursive do |e|
|
249
259
|
|
250
|
-
puts 'e: ' + e.name.inspect if @debug
|
251
260
|
rows = e.parent.xpath('//' + e.name)
|
252
261
|
next if rows.length < 2
|
253
262
|
|
254
|
-
rows[
|
255
|
-
|
256
|
-
duplicates << [e.backtrack.to_s, e2.backtrack.to_s]
|
257
|
-
end
|
263
|
+
rows[0..-2].each {|e2| duplicates << e.backtrack.to_s }
|
264
|
+
|
258
265
|
end
|
259
266
|
|
260
|
-
duplicates.each do |path
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
267
|
+
duplicates.each do |path|
|
268
|
+
|
269
|
+
puts 'path: ' + path.inspect if @debug
|
270
|
+
e = doc.element(path)
|
271
|
+
e.delete if e
|
272
|
+
|
266
273
|
end
|
267
274
|
|
268
275
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mindwords
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
aWH7D2AmhOpqNwWnPHzWR/yzpigAVTrvpHfRxZleQj6Z/090nIH2KR0RdioMmPFq
|
36
36
|
3+574KQzs/gR9Y5a+iMcvHRN
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2021-01-
|
38
|
+
date: 2021-01-25 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: line-tree
|
@@ -57,6 +57,26 @@ dependencies:
|
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: 0.9.1
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rxfhelper
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '1.1'
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.1.3
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.1'
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.1.3
|
60
80
|
description:
|
61
81
|
email: digital.robertson@gmail.com
|
62
82
|
executables: []
|
metadata.gz.sig
CHANGED
Binary file
|