wikisys 0.2.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bffc9856824a5b8afe8648ea585e3fbe2400ff94e7d0c0fbb0f622b138b8f7e6
4
- data.tar.gz: c2acad35e8fe2361cadabe919004a2f203bf687a1efdc43e061351a3fda11678
3
+ metadata.gz: 7df49481e6dd9b98d651456392c9dc2bdc74ccd65565a7a5a73818415c3ebb24
4
+ data.tar.gz: 615021b76e6869b19f2b0885970778da4885b459bdc9d90adca8b159c5a756a7
5
5
  SHA512:
6
- metadata.gz: 0fc14b79eb6eca3034f904be493787d8058e8d85699f612d0c1749e2bc4536c20fa7c08b36e81b04f0ac7c8ae8955884f86565a3a027348c218acd181898bc3e
7
- data.tar.gz: 9f499b325c14ed3dc204d21c928756a5b27cae725c824f718056cdece85c1729b44f62734d1723a1282585ad5b7bf5fc71c035647851b88bcdf09b0430b9b71b
6
+ metadata.gz: e6b9139472aa18dc3c7d76eed52a5d5f0ee5956f7ba061fde200989c605f7238d2c51779550f3f0f47da718694230e11c197853dd9a2949f38c4ed475249c536
7
+ data.tar.gz: 5a7532e004d33a95f6802fe912cc6d791dccf0c7fe9f815330e59b91488a33067897af8d41d2332633705c9e6f6b82b42dae8ba4c3bad0beab074114dc8b2c52
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -3,12 +3,38 @@
3
3
  # file: wikisys.rb
4
4
 
5
5
  require 'dxlite'
6
+ require 'dir-to-xml'
7
+ require 'mindwords'
6
8
  require 'martile'
9
+ require 'hashcache'
10
+
11
+ module FileFetch
12
+
13
+ def fetch_filepath(filename)
14
+
15
+ lib = File.dirname(__FILE__)
16
+ File.join(lib,'..','stylesheet',filename)
17
+
18
+ end
19
+
20
+ def fetch_file(filename)
21
+
22
+ filepath = fetch_filepath filename
23
+ read filepath
24
+ end
25
+
26
+ def read(s)
27
+ RXFHelper.read(s).first
28
+ end
29
+ end
7
30
 
8
31
  module Wikisys
9
32
 
10
- class Wiki
33
+ class Wiki
34
+ include FileFetch
35
+ using ColouredText
11
36
 
37
+ attr_accessor :title, :content, :tags
12
38
  attr_reader :to_xml
13
39
 
14
40
  def initialize(filepath='.', entries: 'entries.json', debug: false)
@@ -16,18 +42,36 @@ module Wikisys
16
42
  @filepath = filepath
17
43
  @page = ''
18
44
  @debug = debug
45
+
46
+ @hc = HashCache.new(size:30)
19
47
 
20
- @entries = if File.exists?(entries) then
48
+ @entries = if entries.is_a? DxLite then
49
+
50
+ entries
51
+
52
+ elsif File.exists?(entries) then
21
53
 
22
54
  DxLite.new(entries)
23
55
 
24
56
  else
25
57
 
26
- DxLite.new('entries/entry(title, tags)', filepath: entries)
58
+ DxLite.new('entries/entry(title, tags)')
27
59
 
28
60
  end
29
61
 
30
62
  end
63
+
64
+ def create_breadcrumb(filepath, links)
65
+
66
+ doc = Rexle.new(read_file(filepath))
67
+ heading = doc.root.element('heading')
68
+
69
+ menu = Rexle.new(HtmlCom::Menu.new(:breadcrumb, links).to_html)
70
+
71
+ heading.insert_before menu.root
72
+ write_file filepath, doc.root.xml
73
+
74
+ end
31
75
 
32
76
  def page(title)
33
77
 
@@ -48,8 +92,8 @@ module Wikisys
48
92
  make_page(title, raw_content.lines.last.chomp[/(?<=\+ )/]) unless r
49
93
 
50
94
  write_md title, raw_content
51
-
52
- @to_xml = build_xml raw_content
95
+ title, content, tags = read_md()
96
+ @to_xml = build_xml title, content, tags
53
97
  write_xml title, @to_xml
54
98
 
55
99
 
@@ -58,13 +102,86 @@ module Wikisys
58
102
 
59
103
  end
60
104
 
105
+ def modify_build(filename)
106
+
107
+ @title, @content, @tags = read_md(filename)
108
+
109
+ # find the entry
110
+ # modify the tags if necessary
111
+
112
+ r = @entries.find_by_title @title
113
+ puts 'r: ' + r.inspect if @debug
114
+ return unless r
115
+
116
+ write_xml(@title, build_xml(@title, @content, @tags))
117
+
118
+ r.tags = @tags.join(' ') if r.tags != @tags
119
+
120
+ end
121
+
122
+ def new_build(filename)
123
+
124
+ @title, @content, @tags = read_md(filename)
125
+ @entries.create title: @title, tags: @tags.join(' ')
126
+
127
+ puts 'md contents: ' + [@title, @content, @tags].inspect if @debug
128
+ write_xml(@title, build_xml(@title, @content, @tags))
129
+
130
+ end
131
+
132
+ def read_file(file='index.html')
133
+ @hc.read(file) { File.read(file) }
134
+ end
135
+
136
+ def to_css()
137
+ fetch_file 'pg.css'
138
+ end
139
+
140
+ def write_html(filename)
141
+
142
+ FileUtils.mkdir_p File.join(@filepath, 'html')
143
+
144
+ xml = read_file File.join(@filepath, 'xml', filename)
145
+ puts 'about to fetch_file' if @debug
146
+ xsl = fetch_file 'pg.xsl'
147
+ puts 'xsl: ' + xsl.inspect if @debug
148
+
149
+ html_file = File.join(@filepath, 'html', filename.sub(/\.xml$/,'.html'))
150
+ write_file(html_file, transform(xsl, xml))
151
+
152
+ end
153
+
61
154
  private
62
155
 
63
- def build_xml(content)
156
+ def read_md(filename)
157
+
158
+ filepath = File.join(@filepath, 'md', filename)
159
+ return unless File.exists? filepath
160
+
161
+ s = read_file(filepath).strip
162
+
163
+ # read the title
164
+ title = s.lines.first.chomp.sub(/^# +/,'')
64
165
 
166
+ # read the hashtags if there is any
167
+ tagsline = s.lines.last[/^ *\+ +(.*)/,1]
168
+
169
+ if tagsline then
170
+
171
+ [title, s.lines[1..-2].join, tagsline.split]
172
+
173
+ else
174
+
175
+ [title, s.lines[1..--1].join, []]
176
+
177
+ end
178
+
179
+ end
180
+
181
+ def build_xml(title, content, tags)
182
+
183
+ puts 'content: ' + content.inspect if @debug
65
184
  s = content.gsub(/\[\[[^\]]+\]\]/) do |raw_link|
66
-
67
- title = raw_link[2..-3].strip
68
185
 
69
186
  r = @entries.find_by_title title
70
187
 
@@ -88,12 +205,11 @@ module Wikisys
88
205
  end
89
206
 
90
207
 
91
- heading = "<heading>%s</heading>" % s.lines.first.chomp
92
- tags = ''
208
+ heading = "<heading>%s</heading>" % title
93
209
 
94
- if s.lines.last[0] = '+' then
210
+ if tags.any? then
95
211
 
96
- list = s.lines.last[2..-1].split.map {|tag| " <tag>%s</tag>" % tag}
212
+ list = tags.map {|tag| " <tag>%s</tag>" % tag}
97
213
  tags = "<tags>\n%s\n </tags>" % list.join("\n")
98
214
 
99
215
  body = "<body>\n %s </body>" % \
@@ -105,11 +221,39 @@ module Wikisys
105
221
 
106
222
  end
107
223
 
108
- "<article>\n %s\n %s\n %s\n</article>" % [heading, body, tags]
224
+ "<article id='%s'>\n %s\n %s\n %s\n</article>" % \
225
+ [title.downcase.gsub(/ +/,'-'), heading, body, tags]
109
226
 
110
227
 
111
228
  end
112
229
 
230
+
231
+ def transform(xsl, xml)
232
+
233
+ doc = Nokogiri::XML(xml)
234
+ xslt = Nokogiri::XSLT(xsl)
235
+
236
+ xslt.transform(doc)
237
+
238
+ end
239
+
240
+ def write_xml(title, content)
241
+
242
+ filepath = File.join(File.absolute_path(@filepath), 'xml',
243
+ title.downcase.gsub(/ +/,'_') + '.xml')
244
+ FileUtils.mkdir_p File.dirname(filepath)
245
+ #File.write filepath, content
246
+ write_file filepath, content
247
+
248
+ end
249
+
250
+ def write_file(filepath, content)
251
+
252
+ puts 'writing file: ' + filepath.inspect if @debug
253
+ File.write filepath, content
254
+ @hc.write(filepath) { content }
255
+ end
256
+
113
257
  def make_page(title, raw_tags=title.downcase.gsub(/['\.\(\)]/,''))
114
258
 
115
259
  tags = raw_tags.split.join(' ')
@@ -121,13 +265,12 @@ module Wikisys
121
265
 
122
266
  return s
123
267
 
124
- end
268
+ end
125
269
 
126
- def read_md(title)
127
-
128
- filepath = File.join(File.absolute_path(@filepath), 'md',
129
- title.gsub(/ +/,'_') + '.md')
130
- File.read(title.gsub(/ +/,'_') + '.md')
270
+ def read_md_file(filename)
271
+
272
+ filepath = File.join(@filepath, 'md', filename)
273
+ File.read(filepath)
131
274
 
132
275
  end
133
276
 
@@ -138,17 +281,159 @@ module Wikisys
138
281
  FileUtils.mkdir_p File.dirname(filepath)
139
282
  File.write filepath, content
140
283
 
284
+ end
285
+
286
+ end
287
+
288
+ class Pages
289
+
290
+ attr_accessor :mw, :entries
291
+
292
+ def initialize(filepath='.', debug: false)
293
+
294
+ @filepath, @debug = filepath, debug
295
+
296
+ entries_file = File.join(@filepath, 'entries.txt')
297
+
298
+ if File.exists?(entries_file) then
299
+ @entries = DxLite.new(entries_file)
300
+ else
301
+ @entries = DxLite.new('entries/entry(title, tags)')
302
+ @entries.save entries_file
303
+ end
304
+
305
+ # check for the mindwords raw document file
306
+ mindwords_file = File.join(@filepath, 'mindwords.txt')
307
+
308
+ if File.exists?(mindwords_file) then
309
+ @mw = MindWords.new(mindwords_file)
310
+ else
311
+ @mw = MindWords.new
312
+ @mw.filepath = mindwords_file
313
+ end
314
+
315
+ scan_md_files()
316
+
141
317
  end
142
318
 
143
- def write_xml(title, content)
319
+ private
320
+
321
+
322
+ # Check if any of the md files have been modified or newly created
323
+ #
324
+ def scan_md_files()
144
325
 
145
- filepath = File.join(File.absolute_path(@filepath), 'xml',
146
- title.gsub(/ +/,'_') + '.xml')
147
- FileUtils.mkdir_p File.dirname(filepath)
148
- File.write filepath, content
326
+ filepath = File.join(@filepath, 'md')
327
+ puts 'about to scan ' + filepath.inspect if @debug
328
+ dir = DirToXML.new(filepath, index: 'dir.json', debug: @debug)
329
+ h = dir.activity
330
+ puts 'h: ' + h.inspect if @debug
149
331
 
150
- end
332
+ return if (h[:new] + h[:modified]).empty?
333
+
334
+ pg = Wiki.new @filepath, entries: @entries, debug: @debug
335
+
336
+
337
+ h[:new].each do |filename|
338
+
339
+ pg.new_build(filename)
340
+ update_mw(pg.title, pg.tags)
341
+
342
+ end
343
+
344
+ h[:modified].each do |filename|
345
+
346
+ pg.modify_build(filename)
347
+ update_mw(pg.title, pg.tags)
348
+
349
+ end
350
+
351
+ @mw.save if @mw.lines.any?
352
+ outline_filepath = File.join(@filepath, 'myoutline.txt')
353
+
354
+ File.write outline_filepath, @mw.to_outline
355
+
356
+ (h[:new] + h[:modified]).each do |filename|
357
+
358
+ xml_file = filename.sub(/\.md$/,'.xml')
359
+ filepath = File.join(@filepath, 'xml', xml_file)
360
+ s = pg.read_file filepath
361
+ title = Rexle.new(s).root.text('heading')
362
+ puts 'about to search title: ' + title.inspect if @debug
363
+ found = @mw.search(title)
364
+
365
+ if found then
366
+
367
+ links = found.breadcrumb.map do |x|
368
+ [x, x.downcase.gsub(/ +/,'-') + '.html']
369
+ end
370
+
371
+ pg.create_breadcrumb(filepath, links)
372
+
373
+ end
374
+
375
+ pg.write_html xml_file
376
+
377
+ end
378
+
379
+ @entries.save
380
+
381
+
382
+ end # /scan_md_files
151
383
 
152
- end
384
+ def update_mw(title, line_tags)
385
+
386
+ # read the file
387
+
388
+ tags = line_tags.reject {|x| x =~ /#{title.strip}/i}
389
+ puts 'tags: ' + tags.inspect if @debug
390
+ puts 'title: ' + title.inspect if @debug
391
+
392
+ return if tags.empty?
393
+
394
+ line = title + ' ' + tags.map {|x| "#" + x }.join(' ') + "\n"
395
+ puts 'line: ' + line.inspect if @debug
396
+
397
+ # does the tagsline contain the topic hashtag?
398
+
399
+ #if tagsline =~ /#/ # not yet implemented
400
+
401
+
402
+
403
+ # check if the title already exists
404
+ found = @mw.lines.grep(/^#{title} +(?=#)/i)
405
+
406
+ if found.any? then
407
+
408
+ found_tags = found.first.scan(/(?<=#)\w+/)
409
+
410
+ if @debug then
411
+
412
+ puts 'tags: ' + tags.inspect
413
+ puts 'found_tags: ' + found_tags.inspect
414
+
415
+ end
416
+
417
+ new_tags = tags - found_tags
418
+
419
+ # add the new tags to the mindwords line
420
+
421
+ hashtags = (found_tags + new_tags).map {|x| '#' + x }.join(' ')
422
+
423
+ i = @mw.lines.index(found.first)
424
+ @mw.lines[i] = line
425
+
426
+ else
427
+
428
+ @mw.lines << line
429
+
430
+ end
431
+
432
+ end
433
+
434
+ def view_file(file='index.html')
435
+ @hc.read(file) { File.read(file) }
436
+ end
153
437
 
438
+ end
154
439
  end
@@ -0,0 +1,75 @@
1
+
2
+
3
+ /* begin breadcrumb.css */
4
+
5
+ body {font-family: Arial;}
6
+
7
+ /* Style the list */
8
+ ul.breadcrumb {
9
+ padding: 10px 16px;
10
+ list-style: none;
11
+ background-color: #eee;
12
+ }
13
+
14
+ /* Display list items side by side */
15
+ ul.breadcrumb li {
16
+ display: inline;
17
+ font-size: 18px;
18
+ }
19
+
20
+ /* Add a slash symbol (/) before/behind each list item */
21
+ ul.breadcrumb li+li:before {
22
+ padding: 8px;
23
+ color: black;
24
+ content: "/\00a0";
25
+ }
26
+
27
+ /* Add a color to all links inside the list */
28
+ ul.breadcrumb li a {
29
+ color: #0275d8;
30
+ text-decoration: none;
31
+ }
32
+
33
+ /* Add a color on mouse-over */
34
+ ul.breadcrumb li a:hover {
35
+ color: #01447e;
36
+ text-decoration: underline;
37
+ }
38
+
39
+ /* end breadcrumb */
40
+
41
+ article {
42
+ background-color: rgba(255,255,255,0.5);
43
+ padding: 1.1em;
44
+ margin: 0.4em;
45
+ }
46
+
47
+ header div {text-align: right}
48
+ #tags {
49
+ background-color: transparent;
50
+ padding: 2.5em 1.0em;
51
+ margin: 1.0em 0em;
52
+ list-style-type: none
53
+ }
54
+ #tags li {
55
+ background-color: transparent;
56
+ display: inline;
57
+ padding: 0.1em;
58
+ margin: 1.3em 0.1em;
59
+ color: #fff;
60
+ }
61
+
62
+ #tags li a {
63
+ background-color: #eee;
64
+ color: #a95;
65
+ text-decoration: none;
66
+ font-family: "Courier";
67
+ font-weight: 600;
68
+ font-size: 0.9em;
69
+ padding: 0.4em 0.6em;
70
+ margin: 0.3em;
71
+
72
+ }
73
+
74
+ #tags li:hover {background-color: transparent; }
75
+ #tags li a:hover { background-color: #ededed; color: #66e; }
@@ -0,0 +1,52 @@
1
+ <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
2
+
3
+ <xsl:template match='article'>
4
+
5
+ <html>
6
+ <head>
7
+ <link rel="stylesheet" type="text/css" href=pg.css"/>
8
+ </head>
9
+ <body>
10
+ <xsl:variable name='id' select='@id'/>
11
+ <header><div><a href='../edit?id={$id}'>edit</a></div></header>
12
+ <div>
13
+ <xsl:copy-of select='ul[@class="breadcrumb"]' />
14
+ </div>
15
+ <article>
16
+ <xsl:apply-templates select='heading' />
17
+ <xsl:copy-of select='body/*' />
18
+ </article>
19
+ <xsl:apply-templates select='tags' />
20
+ </body>
21
+ </html>
22
+
23
+ </xsl:template>
24
+
25
+ <xsl:template match='heading'>
26
+
27
+ <h1><xsl:value-of select='.' /></h1>
28
+
29
+ </xsl:template>
30
+
31
+ <xsl:template match='tags'>
32
+
33
+ <ul id='tags'>
34
+ <xsl:apply-templates select='tag' />
35
+ </ul>
36
+
37
+ </xsl:template>
38
+
39
+ <xsl:template match='tag'>
40
+
41
+ <li>
42
+ <xsl:element name='a'>
43
+ <xsl:attribute name='href'>
44
+ ../hashtags.html#<xsl:value-of select='.' />
45
+ </xsl:attribute>
46
+ <xsl:value-of select='.' />
47
+ </xsl:element>
48
+ </li>
49
+
50
+ </xsl:template>
51
+
52
+ </xsl:stylesheet>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wikisys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -35,28 +35,48 @@ cert_chain:
35
35
  O3SRDzvvWXrwDFGyRDmGqdEw51FKHPw/6pk4ci0QPIvQEgOyPKfdSesPWmNmtxpf
36
36
  KX/89ohIpftt89vtcCI21R5u
37
37
  -----END CERTIFICATE-----
38
- date: 2020-06-22 00:00:00.000000000 Z
38
+ date: 2021-01-30 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
- name: dxlite
41
+ name: dir-to-xml
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0.2'
46
+ version: '1.0'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.2.2
49
+ version: 1.0.4
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: '0.2'
56
+ version: '1.0'
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.0.4
60
+ - !ruby/object:Gem::Dependency
61
+ name: mindwords
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0.5'
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 0.5.4
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.5'
57
77
  - - ">="
58
78
  - !ruby/object:Gem::Version
59
- version: 0.2.2
79
+ version: 0.5.4
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: martile
62
82
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +86,7 @@ dependencies:
66
86
  version: '1.4'
67
87
  - - ">="
68
88
  - !ruby/object:Gem::Version
69
- version: 1.4.3
89
+ version: 1.4.6
70
90
  type: :runtime
71
91
  prerelease: false
72
92
  version_requirements: !ruby/object:Gem::Requirement
@@ -76,7 +96,27 @@ dependencies:
76
96
  version: '1.4'
77
97
  - - ">="
78
98
  - !ruby/object:Gem::Version
79
- version: 1.4.3
99
+ version: 1.4.6
100
+ - !ruby/object:Gem::Dependency
101
+ name: hashcache
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - "~>"
105
+ - !ruby/object:Gem::Version
106
+ version: '0.2'
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 0.2.10
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.2'
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 0.2.10
80
120
  description:
81
121
  email: james@jamesrobertson.eu
82
122
  executables: []
@@ -84,6 +124,8 @@ extensions: []
84
124
  extra_rdoc_files: []
85
125
  files:
86
126
  - lib/wikisys.rb
127
+ - stylesheet/pg.css
128
+ - stylesheet/pg.xsl
87
129
  homepage: https://github.com/jrobertson/wikisys
88
130
  licenses:
89
131
  - MIT
@@ -103,7 +145,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
145
  - !ruby/object:Gem::Version
104
146
  version: '0'
105
147
  requirements: []
106
- rubygems_version: 3.0.3
148
+ rubyforge_project:
149
+ rubygems_version: 2.7.10
107
150
  signing_key:
108
151
  specification_version: 4
109
152
  summary: A poor man's wiki.
metadata.gz.sig CHANGED
Binary file