mindwords 0.1.1 → 0.4.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mindwords.rb +209 -39
- metadata +7 -7
- 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: 85426d79852d7306a24090b6c4fca89929b8004d4c084e60e2a19e6cd684d43d
|
4
|
+
data.tar.gz: ae8b9179bc0d486a75c12ccc5a241e52ed58e82cd32919957925f26a68d91527
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf8ef8f8031725781221f97f0779e9660f03a193354d62e5206302b2cfe54cb4296d5360d093e70b6e5835164d3e9dbcf18d486b33dcb85b084f7872db5e0280
|
7
|
+
data.tar.gz: 507bf3d566e2f3d8377efe32ff559e2d8fcc832ade715bbb33aa305c7a20e0d4355da90eed7513066159aa821864e38ee5f959ddb9bb4a85ce38a2e896f94022
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mindwords.rb
CHANGED
@@ -3,47 +3,69 @@
|
|
3
3
|
# file: mindwords.rb
|
4
4
|
|
5
5
|
require 'rexle'
|
6
|
+
require 'line-tree'
|
6
7
|
|
7
|
-
|
8
|
+
module HashCopy
|
9
|
+
refine Hash do
|
10
|
+
|
11
|
+
def deep_clone()
|
12
|
+
Marshal.load(Marshal.dump(self))
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
8
17
|
|
9
|
-
|
18
|
+
class MindWords
|
19
|
+
using ColouredText
|
20
|
+
using HashCopy
|
21
|
+
|
22
|
+
|
23
|
+
def initialize(s, parent: nil, debug: false)
|
10
24
|
|
11
25
|
@debug = debug
|
12
|
-
|
13
|
-
|
26
|
+
@a = s.strip.gsub(/^\n/,'').lines
|
27
|
+
@a.shift if @a.first =~ /<\?mindwords\?>/
|
28
|
+
|
29
|
+
lines = @a.map do |line|
|
14
30
|
|
15
31
|
word = line.split(/ (?=#)/,2)
|
16
32
|
|
17
33
|
end
|
18
|
-
|
34
|
+
|
19
35
|
h = {}
|
36
|
+
@hashtags = {}
|
20
37
|
|
21
|
-
lines.each do |
|
38
|
+
lines.each do |title, rawtags|
|
22
39
|
|
23
|
-
|
40
|
+
rawtags.scan(/#(\w+)/).flatten(1).each do |rawtag|
|
24
41
|
tag = rawtag.gsub(/ +/, '_')
|
25
42
|
h[tag] ||= []
|
26
|
-
h[tag] <<
|
43
|
+
h[tag] << title
|
27
44
|
end
|
28
45
|
|
29
46
|
end
|
47
|
+
|
48
|
+
@hashtags = h.deep_clone.sort.map {|tag, fields| [tag, fields.sort]}.to_h
|
30
49
|
|
31
|
-
|
32
|
-
|
33
|
-
h.keys.each do |key|
|
34
|
-
|
35
|
-
r = h.detect {|_, value| value.include? key}
|
36
|
-
next unless r
|
37
|
-
h[r.first].delete key
|
38
|
-
h[r.first] << {key => h[key]}
|
39
|
-
#puts r.inspect
|
40
|
-
h.delete key
|
41
|
-
|
42
|
-
end
|
43
|
-
|
50
|
+
|
44
51
|
a = rexlize(h)
|
45
52
|
doc = Rexle.new(['root', {}, '', *a])
|
46
53
|
|
54
|
+
# apply node nesting
|
55
|
+
|
56
|
+
doc.root.elements.each do |e|
|
57
|
+
|
58
|
+
doc.root.xpath('//' + e.name).each do |e2|
|
59
|
+
|
60
|
+
next if e2 === e
|
61
|
+
|
62
|
+
e2.parent.add e
|
63
|
+
e2.delete
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
47
69
|
|
48
70
|
# remove duplicates which appear in the same branch above the nested node
|
49
71
|
rm_duplicates(doc)
|
@@ -62,14 +84,138 @@ class MindWords
|
|
62
84
|
end
|
63
85
|
|
64
86
|
redundants.compact.each {|x| doc.element(x).delete }
|
65
|
-
|
87
|
+
|
88
|
+
|
89
|
+
node = if parent then
|
90
|
+
found = doc.root.element('//' + parent)
|
91
|
+
found ? found : doc.root
|
92
|
+
else
|
93
|
+
doc.root
|
94
|
+
end
|
95
|
+
|
96
|
+
@outline = treeize node
|
97
|
+
|
98
|
+
node.root.each_recursive do |e|
|
99
|
+
|
100
|
+
e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
|
101
|
+
|
102
|
+
s = e.parent.attributes[:breadcrumb] ? \
|
103
|
+
e.parent.attributes[:breadcrumb].to_s + ' / ' : ''
|
104
|
+
e.attributes[:breadcrumb] = s + e.value.strip
|
105
|
+
|
106
|
+
r = @a.grep(/^#{e.attributes[:title]} #/i)
|
107
|
+
next unless r.any?
|
108
|
+
e.attributes[:hashtags] = r[0].scan(/(?<=#)\w+/).join(' ')
|
109
|
+
|
110
|
+
|
111
|
+
end
|
66
112
|
|
67
|
-
@
|
113
|
+
@xml = node.xml pretty: true
|
68
114
|
|
69
115
|
end
|
116
|
+
|
117
|
+
def element(id)
|
118
|
+
|
119
|
+
doc = Rexle.new(@xml)
|
120
|
+
e = doc.root.element("//*[@id='#{id}']")
|
121
|
+
#e.attributes[:breadcrumb].to_s if e
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
def search(keyword)
|
126
|
+
|
127
|
+
a = @a.grep(/#{keyword}/i).map do |line|
|
128
|
+
|
129
|
+
puts 'line: ' + line.inspect if @debug
|
130
|
+
|
131
|
+
words = line.split
|
132
|
+
r = words.grep /#{keyword}/i
|
133
|
+
i = words.index r[0]
|
134
|
+
|
135
|
+
[line, i]
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
return nil if a.empty?
|
140
|
+
#return a[0][0] if a.length < 2
|
70
141
|
|
71
|
-
|
72
|
-
@
|
142
|
+
a2 = a.sort_by(&:last).map(&:first)
|
143
|
+
puts 'a2: ' + a2.inspect if @debug
|
144
|
+
MindWords.new(a2.join, parent: keyword, debug: @debug)
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
def sort()
|
149
|
+
s = @a.sort.join
|
150
|
+
|
151
|
+
def s.to_s()
|
152
|
+
self.lines.map do |x|
|
153
|
+
title, hashtags = x.split(/(?=#)/,2)
|
154
|
+
title + hashtags.chomp.brown
|
155
|
+
end.join("\n")
|
156
|
+
end
|
157
|
+
|
158
|
+
return s
|
159
|
+
end
|
160
|
+
|
161
|
+
def sort!()
|
162
|
+
@a = sort().lines
|
163
|
+
self
|
164
|
+
end
|
165
|
+
|
166
|
+
def tag_sort()
|
167
|
+
|
168
|
+
h = @a.group_by {|x| x[/#\w+/]}
|
169
|
+
s = h.sort.map {|key, value| value.sort }.join
|
170
|
+
|
171
|
+
def s.to_s()
|
172
|
+
self.lines.map do |x|
|
173
|
+
title, hashtags = x.split(/(?=#)/,2)
|
174
|
+
title + hashtags.chomp.brown
|
175
|
+
end.join("\n")
|
176
|
+
end
|
177
|
+
|
178
|
+
return s
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
def tag_sort!()
|
183
|
+
@a = tag_sort().lines
|
184
|
+
self
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_h()
|
188
|
+
@h
|
189
|
+
end
|
190
|
+
|
191
|
+
def to_hashtags()
|
192
|
+
@hashtags
|
193
|
+
end
|
194
|
+
|
195
|
+
def to_outline(sort: true)
|
196
|
+
sort ? a2tree(tree_sort(LineTree.new(@outline).to_a)) : @outline
|
197
|
+
end
|
198
|
+
|
199
|
+
def to_s(colour: false)
|
200
|
+
|
201
|
+
header = "<?mindwords?>\n\n"
|
202
|
+
return header + @a.join unless colour
|
203
|
+
|
204
|
+
body = @a.map do |x|
|
205
|
+
title, hashtags = x.split(/(?=#)/,2)
|
206
|
+
title + hashtags.chomp.brown
|
207
|
+
end.join("\n")
|
208
|
+
|
209
|
+
header + body
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
def to_words()
|
214
|
+
to_outline.lines.map {|x| x[/\w[\w ]+/] }
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_xml()
|
218
|
+
@xml
|
73
219
|
end
|
74
220
|
|
75
221
|
private
|
@@ -82,11 +228,16 @@ class MindWords
|
|
82
228
|
|
83
229
|
case x
|
84
230
|
when String
|
85
|
-
[x.gsub(/ +/,'_'), {}, x]
|
231
|
+
[x.gsub(/ +/,'_'), {title: x}, x]
|
86
232
|
when Hash
|
87
|
-
[
|
233
|
+
[
|
234
|
+
x.keys.first.gsub(/_/,' '),
|
235
|
+
{title: x.keys.first},
|
236
|
+
x.keys.first,
|
237
|
+
*rexlize(x.values.first)
|
238
|
+
]
|
88
239
|
when Array
|
89
|
-
[x.first
|
240
|
+
[x.first.gsub(/_/,' '), {title: x.first}, x.first, *rexlize(x.last)]
|
90
241
|
end
|
91
242
|
end
|
92
243
|
|
@@ -95,23 +246,22 @@ class MindWords
|
|
95
246
|
def rm_duplicates(doc)
|
96
247
|
|
97
248
|
duplicates = []
|
249
|
+
|
98
250
|
doc.root.each_recursive do |e|
|
99
251
|
|
100
|
-
puts 'e: ' + e.name.inspect if @debug
|
101
252
|
rows = e.parent.xpath('//' + e.name)
|
102
253
|
next if rows.length < 2
|
103
254
|
|
104
|
-
rows[
|
105
|
-
|
106
|
-
duplicates << [e.backtrack.to_s, e2.backtrack.to_s]
|
107
|
-
end
|
255
|
+
rows[0..-2].each {|e2| duplicates << e.backtrack.to_s }
|
256
|
+
|
108
257
|
end
|
109
258
|
|
110
|
-
duplicates.each do |path
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
259
|
+
duplicates.each do |path|
|
260
|
+
|
261
|
+
puts 'path: ' + path.inspect if @debug
|
262
|
+
e = doc.element(path)
|
263
|
+
e.delete if e
|
264
|
+
|
115
265
|
end
|
116
266
|
|
117
267
|
end
|
@@ -130,6 +280,26 @@ class MindWords
|
|
130
280
|
|
131
281
|
lines.join
|
132
282
|
end
|
283
|
+
|
284
|
+
def tree_sort(a)
|
285
|
+
|
286
|
+
if a.first.is_a? Array then
|
287
|
+
a.sort_by(&:first).map {|x| tree_sort(x) }
|
288
|
+
elsif a.any?
|
289
|
+
[a.first] + tree_sort(a[1..-1])
|
290
|
+
else
|
291
|
+
[]
|
292
|
+
end
|
293
|
+
end
|
133
294
|
|
134
|
-
|
295
|
+
def a2tree(a, indent=0)
|
296
|
+
|
297
|
+
a.map do |row|
|
298
|
+
title, *remaining = row
|
299
|
+
children = remaining ? a2tree(remaining, indent+1) : ''
|
300
|
+
(' ' * indent) + title + "\n" + children
|
301
|
+
end.join
|
135
302
|
|
303
|
+
end
|
304
|
+
|
305
|
+
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.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,28 +35,28 @@ 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-22 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: line-tree
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '0.9'
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 0.9.1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '0.9'
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
59
|
+
version: 0.9.1
|
60
60
|
description:
|
61
61
|
email: digital.robertson@gmail.com
|
62
62
|
executables: []
|
metadata.gz.sig
CHANGED
Binary file
|