mindwords 0.6.4 → 0.6.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57efb3e9e699846f0886274e3d976cbad5707b3c9b5497cc175f15a5a1bfcfe6
4
- data.tar.gz: 67fd42d36fe854b72c4336ed1ef185925d40fee6ecdb1e54c729fa3ee601869d
3
+ metadata.gz: 7510e9608c67e4af590bf024b9910a592c28c6f949d66d37499f940265b5e9d0
4
+ data.tar.gz: f982e7b27d1cd9d230d2f2783bf89a75d296ae0bcf6c32324aeb2d089fab113a
5
5
  SHA512:
6
- metadata.gz: ee70b813f79e3a41149b583fe5bebde65c6fb7ef47bb0cb3683f060b1e5bc523f69af796391a1a9b3ed79ed18ce52a26c75949144d7ba1995fc96ad332bd9112
7
- data.tar.gz: 28a891931b0b589c8519fe05286a440a200bbdea028eba0dc629b79349b472491ed8a1a2b46e4ee64444ce177f9c28b42c595f273859bd209b97797a1a445956
6
+ metadata.gz: eb7c8532b2a5a46edace11d960f568b306b01ef3edd8c45557176451d158b42ae57e1ee3818c1df9ac202bdd17aefde8bbd2e036d913b40d57caed7d365749d1
7
+ data.tar.gz: d50c913670f4a5c567b5a9c81c0f1c3ef3c9293957a91128befb76196dc672e075b4f2db925a4e1156f269ab1963cbdf774192b739c9e8a4eb7b634640e969d8
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/mindwords.rb CHANGED
@@ -8,44 +8,44 @@ require 'line-tree'
8
8
 
9
9
  module HashCopy
10
10
  refine Hash do
11
-
11
+
12
12
  def deep_clone()
13
13
  Marshal.load(Marshal.dump(self))
14
14
  end
15
-
15
+
16
16
  end
17
17
  end
18
18
 
19
19
  class MindWords
20
20
  using ColouredText
21
21
  using HashCopy
22
-
22
+
23
23
  attr_accessor :lines, :filepath
24
-
24
+
25
25
  def initialize(raws='', parent: nil, debug: false)
26
26
 
27
27
  @parent, @debug = parent, debug
28
-
28
+
29
29
  s, type = RXFHelper.read raws
30
-
30
+
31
31
  @filepath = raws if type == :file or type == :dfs
32
- lines = s.strip.gsub(/^\n/,'').lines.uniq
33
- lines.shift if lines.first =~ /<\?mindwords\?>/
34
-
32
+ lines = (s.strip.gsub(/(^\n|\r)/,'') + "\n").lines.uniq
33
+ lines.shift if lines.first =~ /<\?mindwords\?>/
34
+
35
35
  @lines = lines.inject([]) do |r,line|
36
-
36
+
37
37
  # the following does 2 things:
38
38
  # 1. splits words separated by a bar (|) onto their own line
39
- # 2. prefixes a word with an underscore if the word is the
40
- # same as the hashtag. That way it's not removed by the
39
+ # 2. prefixes a word with an underscore if the word is the
40
+ # same as the hashtag. That way it's not removed by the
41
41
  # redundancy checker
42
42
 
43
43
  raw_words, raw_hashtags = line.split(/(?= #)/,2)
44
44
  words = raw_words.split(/ *\| */)
45
45
  hashtags = raw_hashtags.scan(/(?<=#)\w+/)
46
-
47
- words.each do |word|
48
-
46
+
47
+ words.each do |word|
48
+
49
49
  linex = (word + raw_hashtags)
50
50
  r << (hashtags.include?(word) ? linex.sub!(/\b#{word}\b/, '_\0') \
51
51
  : linex)
@@ -53,75 +53,87 @@ class MindWords
53
53
 
54
54
  r
55
55
  end
56
-
56
+
57
57
  end
58
-
58
+
59
59
  def add(s)
60
-
60
+
61
61
  @lines.concat s.strip.lines
62
-
62
+
63
63
  end
64
-
64
+
65
65
  def breadcrumb()
66
66
  @parent.attributes[:breadcrumb].split(/ +\/ +/) if @parent
67
67
  end
68
-
68
+
69
69
  def headings()
70
70
  breadcrumb[0..-2]
71
71
  end
72
-
73
-
72
+
73
+
74
74
  def element(id)
75
-
75
+
76
76
  doc = Rexle.new(to_xml())
77
77
  e = doc.root.element("//*[@id='#{id}']")
78
78
  #e.attributes[:breadcrumb].to_s if e
79
-
79
+
80
80
  end
81
-
82
- def hashtags()
83
- @parent.attributes[:hashtags].split if @parent
81
+
82
+ # If title supplied, searches for a requested title and returns the
83
+ # associated hashtags
84
+ # When no title is supplied, it will return the hashtags for the
85
+ # parent element of a search result object
86
+ #
87
+ def hashtags(title=nil)
88
+
89
+ if title then
90
+ found = search(title)
91
+ found.hashtags() if found
92
+ else
93
+ @parent.attributes[:hashtags].split if @parent
94
+ end
95
+
84
96
  end
85
-
97
+
86
98
  # helpful when searching for a word itself using autosuggest
87
99
  #
88
100
  def lookup(s)
89
101
  self.to_words.keys.sort.grep /^#{s}/i
90
- end
91
-
92
- # same as #lines but inludes the breadcrumb path; Helpful to identify
102
+ end
103
+
104
+ # same as #lines but inludes the breadcrumb path; Helpful to identify
93
105
  # which words don't have a breadcrumb path.
94
106
  #
95
107
  def linesplus()
96
-
108
+
97
109
  to_a.map do |word, _|
98
110
  r = search word
99
111
  r ? [word, r.breadcrumb] : [r, nil]
100
112
  end
101
-
113
+
102
114
  end
103
115
 
104
116
  def save(file=@filepath)
105
-
117
+
106
118
  return if @lines.empty?
107
-
119
+
108
120
  puts 'before save' if @debug
109
-
121
+
110
122
  File.write file, to_s()
111
-
123
+
112
124
  end
113
125
 
114
- # Accepts a list of words with the aim of returning a MindWords document
126
+ # Accepts a list of words with the aim of returning a MindWords document
115
127
  # using matched words with hashtags from the existing MindWords document.
116
128
  #
117
129
  def reflect(raws)
118
-
130
+
119
131
  h = to_h
120
-
132
+
121
133
  missing_words = []
122
-
134
+
123
135
  # add the tags from the main list
124
- a = raws.strip.lines.map do |x|
136
+ a = raws.strip.lines.map do |x|
125
137
  if h[x.chomp] then
126
138
  [x.chomp, h[x.chomp]]
127
139
  else
@@ -143,162 +155,162 @@ class MindWords
143
155
  raws3 = a.uniq.map {|s,tags| [s, tags.map {|x| '#' + x }.join(' ')].join(' ') }.join("\n")
144
156
 
145
157
  [MindWords.new(raws3), missing_words]
146
-
158
+
147
159
  end
148
-
160
+
149
161
  def search(keyword, succinct: true)
150
-
162
+
151
163
  a = @lines.grep(/#{keyword}/i).map do |line|
152
-
164
+
153
165
  puts 'line: ' + line.inspect if @debug
154
-
166
+
155
167
  words = line.split
156
168
  r = words.grep /#{keyword}/i
157
169
  i = words.index r[0]
158
-
170
+
159
171
  [line, i]
160
-
172
+
161
173
  end
162
-
174
+
163
175
  return nil if a.empty?
164
176
  #return a[0][0] if a.length < 2
165
177
 
166
178
  a2 = a.sort_by(&:last).map(&:first)
167
179
  puts 'a2: ' + a2.inspect if @debug
168
180
  e = element(keyword.downcase.gsub(/ +/,'-'))
169
-
181
+
170
182
  return MindWords.new(a2.uniq.join, debug: @debug) if e.nil?
171
183
 
172
184
  # find and add any linkage support lines
173
185
  #
174
-
186
+
175
187
  a3 = []
176
188
 
177
189
  a2.each do |line|
178
-
190
+
179
191
  line.chomp.scan(/#[^ ]+/).each do |hashtag|
180
-
192
+
181
193
  puts 'hashtag: ' + hashtag.inspect if @debug
182
194
  r2 = @lines.grep(/^#{hashtag[1..-1]} #/)
183
- a3 << r2.first if r2
184
-
195
+ a3 << r2.first if r2
196
+
185
197
  end
186
198
  end
187
199
 
188
200
  puts 'a2: ' + a2.inspect if @debug
189
201
  a2.concat a3
190
-
202
+
191
203
  if succinct then
192
204
  MindWords.new(a2.uniq.join, parent: e, debug: @debug)
193
205
  else
194
206
  MindWords.new(a2.uniq.join, debug: @debug)
195
207
  end
196
-
208
+
197
209
  end
198
-
210
+
199
211
  def sort()
200
212
  s = @lines.sort.join
201
-
213
+
202
214
  def s.to_s()
203
215
  self.lines.map do |x|
204
216
  title, hashtags = x.split(/(?=#)/,2)
205
217
  title + hashtags.chomp.brown
206
218
  end.join("\n")
207
- end
208
-
219
+ end
220
+
209
221
  return s
210
222
  end
211
-
223
+
212
224
  def sort!()
213
225
  @lines = sort().lines
214
226
  self
215
227
  end
216
-
228
+
217
229
  def tag_sort()
218
-
219
- h = @lines.group_by {|x| x[/#\w+/]}
230
+
231
+ h = @lines.group_by {|x| x[/#\w+/]}
220
232
  s = h.sort.map {|key, value| value.sort }.join
221
-
233
+
222
234
  def s.to_s()
223
235
  self.lines.map do |x|
224
236
  title, hashtags = x.split(/(?=#)/,2)
225
237
  title + hashtags.chomp.brown
226
238
  end.join("\n")
227
239
  end
228
-
240
+
229
241
  return s
230
-
242
+
231
243
  end
232
-
244
+
233
245
  def tag_sort!()
234
246
  @lines = tag_sort().lines
235
247
  self
236
248
  end
237
249
 
238
250
  def to_a()
239
-
240
- @lines.map do |x|
251
+
252
+ @lines.map do |x|
241
253
  s, rawtags = x.split(/(?= #)/,2)
242
254
  [s, rawtags.scan(/(?<=#)\w+/)]
243
255
  end
244
-
256
+
245
257
  end
246
-
258
+
247
259
  def to_h()
248
260
  to_a.to_h
249
261
  end
250
-
262
+
251
263
  def to_hashtags()
252
264
  @hashtags
253
265
  end
254
266
 
255
267
  def to_outline(sort: true)
256
-
268
+
257
269
  build()
258
-
270
+
259
271
  if sort then
260
272
  a = LineTree.new(@outline).to_a
261
- puts ('a: ' + a.inspect).debug if @debug
273
+ puts ('a: ' + a.inspect).debug if @debug
262
274
  a2tree(tree_sort(a))
263
275
  else
264
276
  @outline
265
277
  end
266
-
278
+
267
279
  end
268
-
280
+
269
281
  alias to_tree to_outline
270
-
282
+
271
283
  def to_s(colour: false)
272
-
284
+
273
285
  header = "<?mindwords?>\n\n"
274
286
  return header + @lines.map(&:chomp).join("\n") unless colour
275
-
287
+
276
288
  body = @lines.map do |x|
277
289
  title, hashtags = x.split(/(?=#)/,2)
278
290
  title + hashtags.chomp.brown
279
291
  end.join("\n")
280
-
292
+
281
293
  header + body
282
-
283
- end
284
-
294
+
295
+ end
296
+
285
297
  def to_words()
286
-
298
+
287
299
  h = {}
288
-
300
+
289
301
  Rexle.new(to_xml).root.each_recursive do |e|
290
-
302
+
291
303
  h[e.attributes[:title]] = {
292
- breadcrumb: e.attributes[:breadcrumb],
304
+ breadcrumb: e.attributes[:breadcrumb],
293
305
  hashtags: e.attributes[:hashtags]
294
306
  }
295
-
307
+
296
308
  end
297
-
309
+
298
310
  h
299
-
300
- end
301
-
311
+
312
+ end
313
+
302
314
  def to_xml()
303
315
  build() unless @xml
304
316
  @xml
@@ -307,13 +319,13 @@ class MindWords
307
319
  private
308
320
 
309
321
  def build()
310
-
322
+
311
323
  h = {}
312
324
 
313
325
  @lines.each do |line|
314
326
 
315
327
  title, rawtags = line.split(/(?= #)/,2)
316
-
328
+
317
329
  rawtags.scan(/#(\w+)/).flatten(1).each do |rawtag|
318
330
  tag = rawtag.gsub(/ +/, '_')
319
331
  h[tag] ||= []
@@ -321,32 +333,32 @@ class MindWords
321
333
  end
322
334
 
323
335
  end
324
-
336
+
325
337
  @hashtags = h.deep_clone.sort.map {|tag, fields| [tag, fields.sort]}.to_h
326
338
 
327
-
339
+
328
340
  a = rexlize(h)
329
341
  doc = Rexle.new(['root', {}, '', *a])
330
342
 
331
343
  # apply node nesting
332
344
 
333
345
  doc.root.elements.each do |e|
334
-
346
+
335
347
  doc.root.xpath('//' + e.name).each do |e2|
336
-
348
+
337
349
  next if e2 === e
338
-
350
+
339
351
  e2.parent.add e
340
352
  e2.delete
341
-
353
+
342
354
  end
343
-
355
+
344
356
  end
345
357
 
346
-
358
+
347
359
  # remove duplicates which appear in the same branch above the nested node
348
360
  rm_duplicates(doc)
349
-
361
+
350
362
  # remove redundant nodes (outsiders)
351
363
  # a redundant node is where all children exist in existing nested nodes
352
364
 
@@ -359,60 +371,60 @@ class MindWords
359
371
  e.backtrack.to_s if dups
360
372
 
361
373
  end
362
-
374
+
363
375
  puts 'redundants: ' + redundants.inspect if @debug
364
376
 
365
377
  redundants.compact.each {|x| doc.element(x).delete }
366
-
378
+
367
379
  node = if @parent then
368
380
  found = doc.root.element('//' + @parent.name)
369
381
  found ? found.parent : doc.root
370
382
  else
371
383
  doc.root
372
384
  end
373
-
374
- # the following removes any undescore prefix from words which were the
385
+
386
+ # the following removes any undescore prefix from words which were the
375
387
  # same as the hashtag
376
-
388
+
377
389
  node.root.each_recursive do |e|
378
390
 
379
391
  next unless e
380
392
  puts 'e: ' + e.inspect if @debug
381
-
393
+
382
394
  e.attributes[:id] = e.attributes[:id].sub(/^_/,'') if e.attributes[:id]
383
395
  e.attributes[:title] = e.attributes[:title].sub(/^_/,'') if e.attributes[:title]
384
396
  e.value = e.value.sub(/^_/,'')
385
397
  e.name = e.name.sub(/^_/,'')
386
-
387
- end
388
-
398
+
399
+ end
400
+
389
401
  # ----
390
-
402
+
391
403
  @outline = treeize node
392
-
404
+
393
405
  node.root.each_recursive do |e|
394
-
395
- e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
396
-
406
+
407
+ e.attributes[:id] = e.attributes[:title].downcase.gsub(/ +/,'-')
408
+
397
409
  s = e.parent.attributes[:breadcrumb] ? \
398
410
  e.parent.attributes[:breadcrumb].to_s + ' / ' : ''
399
411
  e.attributes[:breadcrumb] = s + e.value.strip
400
-
412
+
401
413
  r = @lines.grep(/^#{e.attributes[:title]} #/i)
402
414
  next unless r.any?
403
415
  e.attributes[:hashtags] = r[0].scan(/(?<=#)\w+/).join(' ')
404
416
 
405
-
417
+
406
418
  end
407
-
419
+
408
420
  @xml = node.xml pretty: true
409
421
 
410
422
  end
411
-
423
+
412
424
  def rexlize(a)
413
-
425
+
414
426
  a.map do |x|
415
-
427
+
416
428
  puts 'x: ' + x.inspect if @debug
417
429
 
418
430
  case x
@@ -420,41 +432,41 @@ class MindWords
420
432
  [x.downcase.gsub(/ +/,''), {title: x}, x]
421
433
  when Hash
422
434
  [
423
- x.keys.first.downcase.gsub(/_/,' '),
424
- {title: x.keys.first},
435
+ x.keys.first.downcase.gsub(/_/,' '),
436
+ {title: x.keys.first},
425
437
  x.keys.first,
426
438
  *rexlize(x.values.first)
427
439
  ]
428
440
  when Array
429
441
  [
430
- x.first.downcase.gsub(/_/,' '),
442
+ x.first.downcase.gsub(/_/,' '),
431
443
  {title: x.first}, x.first, *rexlize(x.last)
432
444
  ]
433
445
  end
434
446
  end
435
447
 
436
448
  end
437
-
449
+
438
450
  def rm_duplicates(doc)
439
-
451
+
440
452
  duplicates = []
441
-
453
+
442
454
  doc.root.each_recursive do |e|
443
455
 
444
456
  rows = e.parent.xpath('//' + e.name)
445
457
  next if rows.length < 2
446
458
 
447
459
  rows[0..-2].each {|e2| duplicates << e.backtrack.to_s }
448
-
460
+
449
461
  end
450
462
 
451
463
  duplicates.each do |path|
452
-
464
+
453
465
  puts 'pathx: ' + path.inspect if @debug
454
466
  e = doc.element(path)
455
467
  e.delete if e
456
-
457
- end
468
+
469
+ end
458
470
 
459
471
  end
460
472
 
@@ -466,13 +478,13 @@ class MindWords
466
478
 
467
479
  puts 'e: ' + e.inspect if @debug
468
480
  if e.is_a? Rexle::Element then
469
- (' ' * indent) + e.value.to_s + "\n" + treeize(e,indent+1)
481
+ (' ' * indent) + e.value.to_s + "\n" + treeize(e,indent+1)
470
482
  end
471
483
  end
472
484
 
473
485
  lines.join
474
486
  end
475
-
487
+
476
488
  def tree_sort(a)
477
489
 
478
490
  if a.first.is_a? Array then
@@ -492,7 +504,7 @@ class MindWords
492
504
  (' ' * indent) + title + "\n" + children
493
505
  end.join
494
506
 
495
- end
507
+ end
496
508
 
497
509
  end
498
510
 
@@ -502,7 +514,7 @@ class MindWordsWidget
502
514
 
503
515
  end
504
516
 
505
-
517
+
506
518
  # can be used for main entries or a words list
507
519
  #
508
520
  def input(content: '', action: 'mwupdate', target: 'icontent')
data.tar.gz.sig CHANGED
Binary file
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.6.4
4
+ version: 0.6.5
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-06-30 00:00:00.000000000 Z
38
+ date: 2022-01-01 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: line-tree
@@ -46,7 +46,7 @@ dependencies:
46
46
  version: '0.9'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.9.2
49
+ version: 0.9.3
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,7 +56,7 @@ dependencies:
56
56
  version: '0.9'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.9.2
59
+ version: 0.9.3
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rxfhelper
62
62
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  requirements: []
106
- rubygems_version: 3.1.2
106
+ rubyforge_project:
107
+ rubygems_version: 2.7.10
107
108
  signing_key:
108
109
  specification_version: 4
109
110
  summary: Helps get what's in your mind into a structure using words and hashtags.
metadata.gz.sig CHANGED
Binary file