wikisys 0.4.0 → 0.4.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/lib/wikisys.rb +436 -0
- data/stylesheet/pg.xsl +52 -0
- data.tar.gz.sig +1 -1
- metadata +3 -1
- 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: 968d63c44160b867a30d0102d61998755fe7e6ac1f1d77b517aa5c057dc6fd61
|
4
|
+
data.tar.gz: 2ede5cdd04ca85944cdcd228081283e91c546ac450246fce7f11923fe55eeba2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 234190cfca855775c8e1218ae5f64d94e6b673dabdf6a98609f8db35cfa5207483c82ead6688509fb76effc8969ee073b93dc0f55373b3abca47da411b7461e1
|
7
|
+
data.tar.gz: 3bd627fab82a7cc57b90d4085dc77aa357fe782c68c6d1b060d7e9830be2491825d754f853b27360ab9befd06e3363fedbefa8320d4459ceedfd4513e3ade997
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/wikisys.rb
ADDED
@@ -0,0 +1,436 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# file: wikisys.rb
|
4
|
+
|
5
|
+
require 'dxlite'
|
6
|
+
require 'dir-to-xml'
|
7
|
+
require 'mindwords'
|
8
|
+
require 'martile'
|
9
|
+
|
10
|
+
module FileFetch
|
11
|
+
|
12
|
+
def fetch_filepath(filename)
|
13
|
+
|
14
|
+
lib = File.dirname(__FILE__)
|
15
|
+
File.join(lib,'..','stylesheet',filename)
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_file(filename)
|
20
|
+
|
21
|
+
filepath = fetch_filepath filename
|
22
|
+
read filepath
|
23
|
+
end
|
24
|
+
|
25
|
+
def read(s)
|
26
|
+
RXFHelper.read(s).first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Wikisys
|
31
|
+
|
32
|
+
class Wiki
|
33
|
+
include FileFetch
|
34
|
+
using ColouredText
|
35
|
+
|
36
|
+
attr_accessor :title, :content, :tags
|
37
|
+
attr_reader :to_xml
|
38
|
+
|
39
|
+
def initialize(filepath='.', entries: 'entries.json', debug: false)
|
40
|
+
|
41
|
+
@filepath = filepath
|
42
|
+
@page = ''
|
43
|
+
@debug = debug
|
44
|
+
|
45
|
+
@hc = HashCache.new(size:30)
|
46
|
+
|
47
|
+
@entries = if entries.is_a? DxLite then
|
48
|
+
|
49
|
+
entries
|
50
|
+
|
51
|
+
elsif File.exists?(entries) then
|
52
|
+
|
53
|
+
DxLite.new(entries)
|
54
|
+
|
55
|
+
else
|
56
|
+
|
57
|
+
DxLite.new('entries/entry(title, tags)')
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_breadcrumb(filepath, links)
|
64
|
+
|
65
|
+
doc = Rexle.new(read_file(filepath))
|
66
|
+
heading = doc.root.element('heading')
|
67
|
+
|
68
|
+
menu = Rexle.new(HtmlCom::Menu.new(:breadcrumb, links).to_html)
|
69
|
+
|
70
|
+
heading.insert_before menu.root
|
71
|
+
write_file filepath, doc.root.xml
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def page(title)
|
76
|
+
|
77
|
+
r = @entries.find_by_title title
|
78
|
+
@page = r ? read_md(title) : make_page(title)
|
79
|
+
@to_xml = build_xml @page
|
80
|
+
@entries.save
|
81
|
+
|
82
|
+
return @page
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def page=(raw_content)
|
87
|
+
|
88
|
+
title = raw_content.lines.first.chomp
|
89
|
+
|
90
|
+
r = @entries.find_by_title title
|
91
|
+
make_page(title, raw_content.lines.last.chomp[/(?<=\+ )/]) unless r
|
92
|
+
|
93
|
+
write_md title, raw_content
|
94
|
+
title, content, tags = read_md()
|
95
|
+
@to_xml = build_xml title, content, tags
|
96
|
+
write_xml title, @to_xml
|
97
|
+
|
98
|
+
|
99
|
+
@entries.save
|
100
|
+
@page = raw_content
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def modify_build(filename)
|
105
|
+
|
106
|
+
@title, @content, @tags = read_md(filename)
|
107
|
+
|
108
|
+
# find the entry
|
109
|
+
# modify the tags if necessary
|
110
|
+
|
111
|
+
r = @entries.find_by_title @title
|
112
|
+
puts 'r: ' + r.inspect if @debug
|
113
|
+
return unless r
|
114
|
+
|
115
|
+
write_xml(@title, build_xml(@title, @content, @tags))
|
116
|
+
|
117
|
+
r.tags = @tags.join(' ') if r.tags != @tags
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
def new_build(filename)
|
122
|
+
|
123
|
+
@title, @content, @tags = read_md(filename)
|
124
|
+
@entries.create title: @title, tags: @tags.join(' ')
|
125
|
+
|
126
|
+
puts 'md contents: ' + [@title, @content, @tags].inspect if @debug
|
127
|
+
write_xml(@title, build_xml(@title, @content, @tags))
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
def read_file(file='index.html')
|
132
|
+
@hc.read(file) { File.read(file) }
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_css()
|
136
|
+
fetch_file 'pg.css'
|
137
|
+
end
|
138
|
+
|
139
|
+
def write_html(filename)
|
140
|
+
|
141
|
+
FileUtils.mkdir_p File.join(@filepath, 'html')
|
142
|
+
|
143
|
+
xml = read_file File.join(@filepath, 'xml', filename)
|
144
|
+
puts 'about to fetch_file' if @debug
|
145
|
+
xsl = fetch_file 'pg.xsl'
|
146
|
+
puts 'xsl: ' + xsl.inspect if @debug
|
147
|
+
|
148
|
+
html_file = File.join(@filepath, 'html', filename.sub(/\.xml$/,'.html'))
|
149
|
+
write_file(html_file, transform(xsl, xml))
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def read_md(filename)
|
156
|
+
|
157
|
+
filepath = File.join(@filepath, 'md', filename)
|
158
|
+
return unless File.exists? filepath
|
159
|
+
|
160
|
+
s = read_file(filepath).strip
|
161
|
+
|
162
|
+
# read the title
|
163
|
+
title = s.lines.first.chomp.sub(/^# +/,'')
|
164
|
+
|
165
|
+
# read the hashtags if there is any
|
166
|
+
tagsline = s.lines.last[/^ *\+ +(.*)/,1]
|
167
|
+
|
168
|
+
if tagsline then
|
169
|
+
|
170
|
+
[title, s.lines[1..-2].join, tagsline.split]
|
171
|
+
|
172
|
+
else
|
173
|
+
|
174
|
+
[title, s.lines[1..--1].join, []]
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
def build_xml(title, content, tags)
|
181
|
+
|
182
|
+
puts 'content: ' + content.inspect if @debug
|
183
|
+
s = content.gsub(/\[\[[^\]]+\]\]/) do |raw_link|
|
184
|
+
|
185
|
+
r = @entries.find_by_title title
|
186
|
+
|
187
|
+
e = Rexle::Element.new('a').add_text title
|
188
|
+
e.attributes[:href] = title.gsub(/ +/, '_')
|
189
|
+
|
190
|
+
if r then
|
191
|
+
|
192
|
+
e.attributes[:title] = title.capitalize
|
193
|
+
|
194
|
+
else
|
195
|
+
|
196
|
+
make_page(title.capitalize)
|
197
|
+
e.attributes[:class] = 'new'
|
198
|
+
e.attributes[:title] = title.capitalize + ' (page does not exist)'
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
e.xml
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
heading = "<heading>%s</heading>" % title
|
208
|
+
|
209
|
+
if tags.any? then
|
210
|
+
|
211
|
+
list = tags.map {|tag| " <tag>%s</tag>" % tag}
|
212
|
+
tags = "<tags>\n%s\n </tags>" % list.join("\n")
|
213
|
+
|
214
|
+
body = "<body>\n %s </body>" % \
|
215
|
+
Martile.new(s.lines[1..-2].join.strip).to_html
|
216
|
+
|
217
|
+
else
|
218
|
+
|
219
|
+
body = "<body>%s</body>" % Martile.new(s.lines[1..-1].join.strip).to_html
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
"<article id='%s'>\n %s\n %s\n %s\n</article>" % \
|
224
|
+
[title.downcase.gsub(/ +/,'-'), heading, body, tags]
|
225
|
+
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
def transform(xsl, xml)
|
231
|
+
|
232
|
+
doc = Nokogiri::XML(xml)
|
233
|
+
xslt = Nokogiri::XSLT(xsl)
|
234
|
+
|
235
|
+
xslt.transform(doc)
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
def write_xml(title, content)
|
240
|
+
|
241
|
+
filepath = File.join(File.absolute_path(@filepath), 'xml',
|
242
|
+
title.downcase.gsub(/ +/,'_') + '.xml')
|
243
|
+
FileUtils.mkdir_p File.dirname(filepath)
|
244
|
+
#File.write filepath, content
|
245
|
+
write_file filepath, content
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
def write_file(filepath, content)
|
250
|
+
|
251
|
+
puts 'writing file: ' + filepath.inspect if @debug
|
252
|
+
File.write filepath, content
|
253
|
+
@hc.write(filepath) { content }
|
254
|
+
end
|
255
|
+
|
256
|
+
def make_page(title, raw_tags=title.downcase.gsub(/['\.\(\)]/,''))
|
257
|
+
|
258
|
+
tags = raw_tags.split.join(' ')
|
259
|
+
s = "#{title}\n\n\n+ " + tags
|
260
|
+
write_md title, s
|
261
|
+
write_xml title, build_xml(s)
|
262
|
+
|
263
|
+
@entries.create title: title, tags: tags
|
264
|
+
|
265
|
+
return s
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
def read_md_file(filename)
|
270
|
+
|
271
|
+
filepath = File.join(@filepath, 'md', filename)
|
272
|
+
File.read(filepath)
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
def write_md(title, content)
|
277
|
+
|
278
|
+
filepath = File.join(File.absolute_path(@filepath), 'md',
|
279
|
+
title.gsub(/ +/,'_') + '.md')
|
280
|
+
FileUtils.mkdir_p File.dirname(filepath)
|
281
|
+
File.write filepath, content
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
class Pages
|
288
|
+
|
289
|
+
attr_accessor :mw, :entries
|
290
|
+
|
291
|
+
def initialize(filepath='.', debug: false)
|
292
|
+
|
293
|
+
@filepath, @debug = filepath, debug
|
294
|
+
|
295
|
+
entries_file = File.join(@filepath, 'entries.txt')
|
296
|
+
|
297
|
+
if File.exists?(entries_file) then
|
298
|
+
@entries = DxLite.new(entries_file)
|
299
|
+
else
|
300
|
+
@entries = DxLite.new('entries/entry(title, tags)')
|
301
|
+
@entries.save entries_file
|
302
|
+
end
|
303
|
+
|
304
|
+
# check for the mindwords raw document file
|
305
|
+
mindwords_file = File.join(@filepath, 'mindwords.txt')
|
306
|
+
|
307
|
+
if File.exists?(mindwords_file) then
|
308
|
+
@mw = MindWords.new(mindwords_file)
|
309
|
+
else
|
310
|
+
@mw = MindWords.new
|
311
|
+
@mw.filepath = mindwords_file
|
312
|
+
end
|
313
|
+
|
314
|
+
scan_md_files()
|
315
|
+
|
316
|
+
end
|
317
|
+
|
318
|
+
private
|
319
|
+
|
320
|
+
|
321
|
+
# Check if any of the md files have been modified or newly created
|
322
|
+
#
|
323
|
+
def scan_md_files()
|
324
|
+
|
325
|
+
filepath = File.join(@filepath, 'md')
|
326
|
+
puts 'about to scan ' + filepath.inspect if @debug
|
327
|
+
dir = DirToXML.new(filepath, index: 'dir.json', debug: @debug)
|
328
|
+
h = dir.activity
|
329
|
+
puts 'h: ' + h.inspect if @debug
|
330
|
+
|
331
|
+
pg = Wiki.new @filepath, entries: @entries, debug: @debug
|
332
|
+
|
333
|
+
|
334
|
+
h[:new].each do |filename|
|
335
|
+
|
336
|
+
pg.new_build(filename)
|
337
|
+
update_mw(pg.title, pg.tags)
|
338
|
+
|
339
|
+
end
|
340
|
+
|
341
|
+
h[:modified].each do |filename|
|
342
|
+
|
343
|
+
pg.modify_build(filename)
|
344
|
+
update_mw(pg.title, pg.tags)
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
@mw.save if @mw.lines.any?
|
349
|
+
outline_filepath = File.join(@filepath, 'myoutline.txt')
|
350
|
+
|
351
|
+
File.write outline_filepath, @mw.to_outline
|
352
|
+
|
353
|
+
(h[:new] + h[:modified]).each do |filename|
|
354
|
+
|
355
|
+
xml_file = filename.sub(/\.md$/,'.xml')
|
356
|
+
filepath = File.join(@filepath, 'xml', xml_file)
|
357
|
+
s = pg.read_file filepath
|
358
|
+
title = Rexle.new(s).root.text('heading')
|
359
|
+
puts 'about to search title: ' + title.inspect if @debug
|
360
|
+
found = @mw.search(title)
|
361
|
+
|
362
|
+
if found then
|
363
|
+
|
364
|
+
links = found.breadcrumb.map do |x|
|
365
|
+
[x, x.downcase.gsub(/ +/,'-') + '.html']
|
366
|
+
end
|
367
|
+
|
368
|
+
pg.create_breadcrumb(filepath, links)
|
369
|
+
|
370
|
+
end
|
371
|
+
|
372
|
+
pg.write_html xml_file
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
@entries.save
|
377
|
+
|
378
|
+
|
379
|
+
end # /scan_md_files
|
380
|
+
|
381
|
+
def update_mw(title, line_tags)
|
382
|
+
|
383
|
+
# read the file
|
384
|
+
|
385
|
+
tags = line_tags.reject {|x| x =~ /#{title.strip}/i}
|
386
|
+
puts 'tags: ' + tags.inspect if @debug
|
387
|
+
puts 'title: ' + title.inspect if @debug
|
388
|
+
|
389
|
+
return if tags.empty?
|
390
|
+
|
391
|
+
line = title + ' ' + tags.map {|x| "#" + x }.join(' ') + "\n"
|
392
|
+
puts 'line: ' + line.inspect if @debug
|
393
|
+
|
394
|
+
# does the tagsline contain the topic hashtag?
|
395
|
+
|
396
|
+
#if tagsline =~ /#/ # not yet implemented
|
397
|
+
|
398
|
+
|
399
|
+
|
400
|
+
# check if the title already exists
|
401
|
+
found = @mw.lines.grep(/^#{title} +(?=#)/i)
|
402
|
+
|
403
|
+
if found.any? then
|
404
|
+
|
405
|
+
found_tags = found.first.scan(/(?<=#)\w+/)
|
406
|
+
|
407
|
+
if @debug then
|
408
|
+
|
409
|
+
puts 'tags: ' + tags.inspect
|
410
|
+
puts 'found_tags: ' + found_tags.inspect
|
411
|
+
|
412
|
+
end
|
413
|
+
|
414
|
+
new_tags = tags - found_tags
|
415
|
+
|
416
|
+
# add the new tags to the mindwords line
|
417
|
+
|
418
|
+
hashtags = (found_tags + new_tags).map {|x| '#' + x }.join(' ')
|
419
|
+
|
420
|
+
i = @mw.lines.index(found.first)
|
421
|
+
@mw.lines[i] = line
|
422
|
+
|
423
|
+
else
|
424
|
+
|
425
|
+
@mw.lines << line
|
426
|
+
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
|
431
|
+
def view_file(file='index.html')
|
432
|
+
@hc.read(file) { File.read(file) }
|
433
|
+
end
|
434
|
+
|
435
|
+
end
|
436
|
+
end
|
data/stylesheet/pg.xsl
ADDED
@@ -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>
|
data.tar.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
WM.������%�%H���:�f�LxF �CA��F��;g��V��F�h����(h���1�$��)�b�2�`�G+����=�%|�L!
|
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.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -123,7 +123,9 @@ executables: []
|
|
123
123
|
extensions: []
|
124
124
|
extra_rdoc_files: []
|
125
125
|
files:
|
126
|
+
- lib/wikisys.rb
|
126
127
|
- stylesheet/pg.css
|
128
|
+
- stylesheet/pg.xsl
|
127
129
|
homepage: https://github.com/jrobertson/wikisys
|
128
130
|
licenses:
|
129
131
|
- MIT
|
metadata.gz.sig
CHANGED
Binary file
|