runeblog 0.2.41 → 0.2.46

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/bin/blog +4 -7
  3. data/empty_view/themes/standard/blog/post_entry.lt3 +11 -10
  4. data/empty_view/themes/standard/etc/blog.css.lt3 +18 -1
  5. data/empty_view/themes/standard/navbar/faq.lt3 +1 -0
  6. data/empty_view/themes/standard/navbar/navbar.lt3 +1 -0
  7. data/empty_view/themes/standard/post/generate.lt3 +9 -4
  8. data/empty_view/themes/standard/widgets/ad/ad.lt3 +8 -1
  9. data/empty_view/themes/standard/widgets/ad/ad1.png +0 -0
  10. data/empty_view/themes/standard/widgets/ad/ad2.png +0 -0
  11. data/empty_view/themes/standard/widgets/ad/ad3.png +0 -0
  12. data/empty_view/themes/standard/widgets/ad/ad4.png +0 -0
  13. data/empty_view/themes/standard/widgets/bydates/bydates.rb +7 -3
  14. data/empty_view/themes/standard/widgets/links/links.rb +28 -3
  15. data/empty_view/themes/standard/widgets/news/news.rb +7 -3
  16. data/empty_view/themes/standard/widgets/pages/pages.rb +10 -3
  17. data/empty_view/themes/standard/widgets/pinned/pinned.rb +7 -3
  18. data/empty_view/themes/standard/widgets/search/search.rb +7 -3
  19. data/empty_view/themes/standard/widgets/sitemap/sitemap.rb +7 -3
  20. data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.rb +7 -3
  21. data/lib/default.rb +1 -4
  22. data/lib/global.rb +8 -7
  23. data/lib/helpers-blog.rb +15 -15
  24. data/lib/liveblog.rb +94 -57
  25. data/lib/logging.rb +17 -8
  26. data/lib/post.rb +6 -6
  27. data/lib/publish.rb +4 -4
  28. data/lib/repl.rb +1 -0
  29. data/lib/runeblog.rb +77 -47
  30. data/lib/runeblog_version.rb +1 -1
  31. data/lib/view.rb +2 -8
  32. data/lib/xlate.rb +2 -2
  33. data/test/austin.rb +159 -0
  34. metadata +8 -5
  35. data/empty_view/remote/widgets/links/list.data +0 -3
  36. data/empty_view/remote/widgets/news/list.data +0 -4
  37. data/empty_view/remote/widgets/pages/list.data +0 -4
@@ -6,14 +6,14 @@ require 'xlate'
6
6
  module RuneBlog::Helpers
7
7
 
8
8
  def copy(src, dst)
9
- log!(enter: __method__, args: [src, dst])
9
+ log!(enter: __method__, args: [src, dst], level: 2)
10
10
  cmd = "cp #{src} #{dst} 2>/dev/null"
11
11
  rc = system!(cmd)
12
12
  puts " Failed: #{cmd} - from #{caller[0]}" unless rc
13
13
  end
14
14
 
15
15
  def copy!(src, dst)
16
- log!(enter: __method__, args: [src, dst])
16
+ log!(enter: __method__, args: [src, dst], level: 2)
17
17
  cmd = "cp -r #{src} #{dst} 2>/dev/null"
18
18
  rc = system!(cmd)
19
19
  puts " Failed: #{cmd} - from #{caller[0]}" unless rc
@@ -36,7 +36,7 @@ module RuneBlog::Helpers
36
36
  # end
37
37
 
38
38
  def read_config(file, *syms)
39
- log!(enter: __method__, args: [file, *syms])
39
+ log!(enter: __method__, args: [file, *syms], level: 3)
40
40
  lines = File.readlines(file).map(&:chomp)
41
41
  obj = ::OpenStruct.new
42
42
  lines.each do |line|
@@ -61,7 +61,7 @@ module RuneBlog::Helpers
61
61
  end
62
62
 
63
63
  def try_read_config(file, hash)
64
- log!(enter: __method__, args: [file, hash])
64
+ log!(enter: __method__, args: [file, hash], level: 3)
65
65
  return hash.values unless File.exist?(file)
66
66
  vals = read_config(file, *hash.keys)
67
67
  vals
@@ -80,7 +80,7 @@ module RuneBlog::Helpers
80
80
  # end
81
81
 
82
82
  def write_config(obj, file)
83
- log!(enter: __method__, args: [obj, file])
83
+ log!(enter: __method__, args: [obj, file], level: 2)
84
84
  hash = obj.to_h
85
85
  File.open(file, "w") do |out|
86
86
  hash.each_pair {|key, val| out.puts "#{key}: #{val}" }
@@ -88,13 +88,13 @@ module RuneBlog::Helpers
88
88
  end
89
89
 
90
90
  def get_views # read from filesystem
91
- log!(enter: __method__)
91
+ log!(enter: __method__, level: 3)
92
92
  dirs = subdirs("#@root/views/").sort
93
93
  dirs.map {|name| RuneBlog::View.new(name) }
94
94
  end
95
95
 
96
96
  def new_dotfile(root: ".blogs", current_view: "test_view", editor: "vi")
97
- log!(enter: __method__, args: [root, current_view, editor])
97
+ log!(enter: __method__, args: [root, current_view, editor], level: 3)
98
98
  root = Dir.pwd/root
99
99
  x = OpenStruct.new
100
100
  x.root, x.current_view, x.editor = root, current_view, editor
@@ -102,21 +102,21 @@ module RuneBlog::Helpers
102
102
  end
103
103
 
104
104
  def new_sequence
105
- log!(enter: __method__)
105
+ log!(enter: __method__, level: 3)
106
106
  dump(0, "sequence")
107
107
  version_info = "#{RuneBlog::VERSION}\nBlog created: #{Time.now.to_s}"
108
108
  dump(version_info, "VERSION")
109
109
  end
110
110
 
111
111
  def subdirs(dir)
112
- log!(enter: __method__, args: [dir])
112
+ log!(enter: __method__, args: [dir], level: 3)
113
113
  dirs = Dir.entries(dir) - %w[. ..]
114
114
  dirs.reject! {|x| ! File.directory?("#@root/views/#{x}") }
115
115
  dirs
116
116
  end
117
117
 
118
118
  def find_draft_slugs
119
- log!(enter: __method__)
119
+ log!(enter: __method__, level: 3)
120
120
  files = Dir["#@root/drafts/**"].grep /\d{4}.*.lt3$/
121
121
  flagfile = "#@root/drafts/last_rebuild"
122
122
  last = File.exist?(flagfile) ? File.mtime(flagfile) : (Time.now - 86_400)
@@ -128,7 +128,7 @@ module RuneBlog::Helpers
128
128
  end
129
129
 
130
130
  def create_dirs(*dirs)
131
- log!(enter: __method__, args: [*dirs])
131
+ log!(enter: __method__, args: [*dirs], level: 3)
132
132
  dirs.each do |dir|
133
133
  dir = dir.to_s # symbols allowed
134
134
  next if Dir.exist?(dir)
@@ -139,27 +139,27 @@ module RuneBlog::Helpers
139
139
  end
140
140
 
141
141
  def interpolate(str, bind)
142
- log!(enter: __method__, args: [str, bind])
142
+ log!(enter: __method__, args: [str, bind], level: 3)
143
143
  wrap = "<<-EOS\n#{str}\nEOS"
144
144
  eval wrap, bind
145
145
  end
146
146
 
147
147
  def error(err) # Hmm, this is duplicated
148
- log!(str: "duplicated method", enter: __method__, args: [err])
148
+ log!(str: "duplicated method", enter: __method__, args: [err], level: 2)
149
149
  str = "\n Error: #{err}"
150
150
  puts str
151
151
  puts err.backtrace.join("\n")
152
152
  end
153
153
 
154
154
  def dump(obj, name)
155
- log!(enter: __method__, args: [obj, name])
155
+ log!(enter: __method__, args: [obj, name], level: 3)
156
156
  File.write(name, obj)
157
157
  end
158
158
 
159
159
  end
160
160
 
161
161
  def dump(obj, name) # FIXME scope
162
- log!(str: "scope problem", enter: __method__, args: [obj, name])
162
+ log!(str: "scope problem", enter: __method__, args: [obj, name], level: 3)
163
163
  File.write(name, obj)
164
164
  end
165
165
 
@@ -17,7 +17,7 @@ def init_liveblog # FIXME - a lot of this logic sucks
17
17
  @blog = RuneBlog.new(dir)
18
18
  @root = @blog.root
19
19
  @view = @blog.view
20
- @view_name = @blog.view.name
20
+ @view_name = @blog.view.name unless @view.nil?
21
21
  @vdir = @blog.view.dir
22
22
  @version = RuneBlog::VERSION
23
23
  @theme = @vdir/:themes/:standard
@@ -27,35 +27,45 @@ end
27
27
  # "dot" commands
28
28
  ##################
29
29
 
30
+
31
+
32
+ def dropcap
33
+ # Bad form: adds another HEAD
34
+ text = _data
35
+ _out " "
36
+ letter = text[0]
37
+ remain = text[1..-1]
38
+ _out %[<div class='mydrop'>#{letter}</div>]
39
+ _out %[<div style="padding-top: 1px">#{remain}]
40
+ end
41
+
30
42
  def post
31
43
  @meta = OpenStruct.new
32
44
  @meta.num = _args[0]
33
45
  _out " <!-- Post number #{@meta.num} -->\n "
34
46
  end
35
47
 
36
- def backlink
37
- _out %[<br><a href="javascript:history.go(-1)">[Back]</a>]
48
+ def post_trailer
49
+ perma = _var("publish.proto") + "://" + _var("publish.server") +
50
+ "/" + _var("publish.path") + "/permalink/" + _var("post.aslug") +
51
+ ".html"
52
+ tags = _var("post.tags")
53
+ if tags.empty?
54
+ taglist = ""
55
+ else
56
+ taglist = "Tags: #{tags}"
57
+ end
58
+ _out <<~HTML
59
+ <table width=100%><tr>
60
+ <td width=10%><a style="text-decoration: none" href="javascript:history.go(-1)">[Back]</a></td>
61
+ <td width=10%><a style="text-decoration: none" href="#{perma}"> [permalink] </a></td>
62
+ <td width=80% align=right><font size=-3>#{taglist}</font></td></tr></table>
63
+ HTML
64
+ # damned syntax highlighting
38
65
  end
39
66
 
40
- def dropcap
41
- # Bad form: adds another HEAD
42
- _out <<-HTML
43
- <head>
44
- <style>
45
- p:first-child:first-letter {
46
- color: #0000ff;
47
- float: left;
48
- font-family: Verdana;
49
- font-size: 75px;
50
- line-height: 60px;
51
- padding-top: 4px;
52
- padding-right: 8px;
53
- padding-left: 3px;
54
- }
55
- </style>
56
- </head>
57
- HTML
58
- _out " "
67
+ def backlink
68
+ _out %[<br><a href="javascript:history.go(-1)">[Back]</a>]
59
69
  end
60
70
 
61
71
  def quote
@@ -109,17 +119,17 @@ end
109
119
 
110
120
 
111
121
  def make_main_links
112
- log!(enter: __method__)
122
+ log!(enter: __method__, level: 1)
113
123
  # FIXME remember strings may not be safe
114
124
  line = _data.chomp
115
125
  tag, card_title = *line.split(" ", 2)
116
126
  cardfile, mainfile = "#{tag}-card", "#{tag}-main"
117
127
  input = "list.data"
118
- log!(str: "Reading #{input}", pwd: true)
128
+ log!(str: "Reading #{input}", pwd: true, level: 3)
119
129
  pairs = File.readlines(input).map {|line| line.chomp.split(/, */, 2) }
120
130
  _write_main(mainfile, pairs, card_title, tag)
121
131
  _write_card(cardfile, mainfile, pairs, card_title, tag)
122
- log!(str: "...returning from method", pwd: true)
132
+ log!(str: "...returning from method", pwd: true, level: 3)
123
133
  end
124
134
 
125
135
  ### inset
@@ -127,25 +137,36 @@ end
127
137
  def inset
128
138
  lines = _body
129
139
  box = ""
140
+ output = []
130
141
  lines.each do |line|
131
- line = line.dup
132
- if line[0] == "/" # Only into inset
133
- line[0] = ' '
134
- box << line.dup + " "
135
- line.replace(" ")
142
+ line = line
143
+ case line[0]
144
+ when "/" # Only into inset
145
+ line[0] = ' '
146
+ box << line
147
+ line.replace(" ")
148
+ when "|" # Into inset and body
149
+ line[0] = ' '
150
+ box << line
151
+ output << line
152
+ else # Only into body
153
+ output << line
136
154
  end
137
- if line[0] == "|" # Into inset and body
138
- line[0] = ' '
139
- box << line.dup + " "
140
- end
141
- _passthru(line)
155
+ # _passthru(line)
142
156
  end
143
157
  lr = _args.first
144
158
  wide = _args[1] || "25"
145
- _passthru "<div style='float:#{lr}; width: #{wide}%; padding:8px; padding-right:12px'>" # ; font-family:verdana'>"
146
- _passthru '<b><i>'
147
- _passthru box
148
- _passthru_noline '</i></b></div>'
159
+ stuff = "<div style='float:#{lr}; width: #{wide}%; padding:8px; padding-right:12px'>"
160
+ stuff << '<b><i>' + box + '</i></b></div>'
161
+ _out "</p>" # kludge!! nopara
162
+ 0.upto(2) {|i| _passthru output[i] }
163
+ _passthru stuff
164
+ # _passthru "<div style='float:#{lr}; width: #{wide}%; padding:8px; padding-right:12px'>" # ; font-family:verdana'>"
165
+ # _passthru '<b><i>'
166
+ # _passthru box
167
+ # _passthru_noline '</i></b></div>'
168
+ 3.upto(output.length-1) {|i| _passthru output[i] }
169
+ _out "<p>" # kludge!! para
149
170
  _optional_blank_line
150
171
  end
151
172
 
@@ -154,7 +175,8 @@ def title
154
175
  title = @_data.chomp
155
176
  @meta.title = title
156
177
  setvar :title, title
157
- _out %[<h1 class="post-title">#{title}</h1><br>]
178
+ # FIXME refactor -- just output variables for a template
179
+ # _out %[<h1 class="post-title">#{title}</h1><br>]
158
180
  _optional_blank_line
159
181
  end
160
182
 
@@ -212,10 +234,16 @@ end
212
234
 
213
235
  def teaser
214
236
  raise "'post' was not called" unless @meta
215
- @meta.teaser = _body_text
237
+ text = _body_text
238
+ @meta.teaser = text
216
239
  setvar :teaser, @meta.teaser
217
- _out @meta.teaser + "\n"
218
- # FIXME
240
+ if _args[0] == "dropcap" # FIXME doesn't work yet!
241
+ letter, remain = text[0], text[1..-1]
242
+ _out %[<div class='mydrop'>#{letter}</div>]
243
+ _out %[<div style="padding-top: 1px">#{remain}] + "\n"
244
+ else
245
+ _out @meta.teaser + "\n"
246
+ end
219
247
  end
220
248
 
221
249
  def finalize
@@ -285,7 +313,6 @@ def head # Does NOT output tags
285
313
  hash = defaults.dup.update(result) # FIXME collisions?
286
314
 
287
315
  hash.each_value {|x| _out " " + x }
288
- _out "<body>"
289
316
  end
290
317
 
291
318
  ########## newer stuff...
@@ -356,16 +383,26 @@ def sidebar
356
383
  tcard = "#{tag}-card.html"
357
384
 
358
385
  code = _load_local(tag)
359
- code && Dir.chdir(wtag) { code.build }
360
-
361
- # if File.exist?(wtag/"SUBFILES")
362
- # children = Dir[wtag/"*.lt3"] - [wtag/tag+".lt3"]
363
- # children.each do |child|
364
- # dest = child.sub(/.lt3$/, ".html")
365
- # xlate src: child, dst: dest # , debug: true
366
- # end
367
- # end
368
- xlate cwd: wtag, src: tag, dst: tcard # , debug: true
386
+ if code
387
+ if ["pages", "links"].include? tag
388
+ Dir.chdir(wtag) do
389
+ widget = code.new(@blog)
390
+ widget.build
391
+ end
392
+ end
393
+ end
394
+
395
+ if tag == "ad"
396
+ num = rand(1..4)
397
+ img = "widgets/ad/ad#{num}.png"
398
+ src, dst = img, @root/:views/@view_name/"remote/widgets/ad/"
399
+ system!("cp #{src} #{dst}") # , show: true)
400
+ File.open(wtag/"vars.lt3", "w") do |f|
401
+ f.puts ".set ad.image = #{img}"
402
+ end
403
+ end
404
+
405
+ xlate cwd: wtag, src: tag, dst: tcard # , debug: (tag == "ad")
369
406
  _include_file wtag/tcard
370
407
  end
371
408
  _out %[</div>]
@@ -574,7 +611,7 @@ def _html_body(file, css = nil)
574
611
  end
575
612
 
576
613
  def _write_card(cardfile, mainfile, pairs, card_title, tag)
577
- log!(str: "Creating #{cardfile}.html", pwd: true)
614
+ log!(str: "Creating #{cardfile}.html", pwd: true, level: 2)
578
615
  url = mainfile
579
616
  url = :widgets/tag/mainfile + ".html"
580
617
  File.open("#{cardfile}.html", "w") do |f|
@@ -589,7 +626,7 @@ def _write_card(cardfile, mainfile, pairs, card_title, tag)
589
626
  </h5>
590
627
  <div class="collapse" id="#{tag}">
591
628
  EOS
592
- log!(str: "Writing data pairs to #{cardfile}.html", pwd: true)
629
+ log!(str: "Writing data pairs to #{cardfile}.html", pwd: true, level: 2)
593
630
  local = _local_tag?(tag)
594
631
  pairs.each do |file, title|
595
632
  url = file
@@ -662,7 +699,7 @@ def _write_main_pages(mainfile, pairs, card_title, tag)
662
699
  end
663
700
 
664
701
  def _write_main(mainfile, pairs, card_title, tag)
665
- log!(str: "Creating #{mainfile}.html", pwd: true)
702
+ log!(str: "Creating #{mainfile}.html", pwd: true, level: 2)
666
703
 
667
704
  if tag == "pages" # temporary experiment
668
705
  _write_main_pages(mainfile, pairs, card_title, tag)
@@ -2,8 +2,17 @@ unless self.respond_to?("log!")
2
2
  $logging = true
3
3
  $log = File.new("/tmp/runeblog.log","w")
4
4
 
5
- def log!(str: "", enter: nil, args: [], pwd: false, dir: false)
5
+ def outlog(str = "", stderr: false)
6
+ $log.puts str
7
+ STDERR.puts str if stderr
8
+ end
9
+
10
+ def log!(str: "", enter: nil, args: [], pwd: false, dir: false, level: 0, stderr: false)
6
11
  return unless $logging
12
+ @err_level ||= ENV['RUNEBLOG_ERROR_LEVEL']
13
+ @err_level ||= 0
14
+ return if level < @err_level
15
+
7
16
  time = Time.now.strftime("%H:%M:%S")
8
17
 
9
18
  meth = ""
@@ -17,16 +26,16 @@ unless self.respond_to?("log!")
17
26
  str = " ... #{str}" unless str.empty?
18
27
  indent = " "*12
19
28
 
20
- $log.puts "#{time} #{meth}#{para}"
21
- $log.puts "#{indent} #{str} " unless str.empty?
22
- $log.puts "#{indent} #{source}"
23
- $log.puts "#{indent} pwd = #{Dir.pwd} " if pwd
29
+ outlog "#{time} #{meth}#{para}"
30
+ outlog "#{indent} #{str} " unless str.empty?
31
+ outlog "#{indent} #{source}"
32
+ outlog "#{indent} pwd = #{Dir.pwd} " if pwd
24
33
  if dir
25
34
  files = (Dir.entries('.') - %w[. ..]).join(" ")
26
- $log.puts "#{indent} dir/* = #{files}"
35
+ outlog "#{indent} dir/* = #{files}"
27
36
  end
28
- # $log.puts "#{indent} livetext params = #{livedata.inpect} " unless livedata.nil?
29
- $log.puts
37
+ # outlog "#{indent} livetext params = #{livedata.inpect} " unless livedata.nil?
38
+ outlog
30
39
  $log.close
31
40
  $log = File.new("/tmp/runeblog.log","a")
32
41
  end
@@ -10,14 +10,14 @@ class RuneBlog::Post
10
10
  include RuneBlog::Helpers
11
11
 
12
12
  def self.files(num, root)
13
- log!(enter: __method__, args: [num, root])
13
+ log!(enter: __method__, args: [num, root], level: 3)
14
14
  files = Find.find(root).to_a
15
15
  result = files.grep(/#{prefix(num)}-/)
16
16
  result
17
17
  end
18
18
 
19
19
  def self.load(post)
20
- log!(enter: __method__, args: [post])
20
+ log!(enter: __method__, args: [post], level: 3)
21
21
  raise "Doesn't work right now"
22
22
  raise NoBlogAccessor if RuneBlog.blog.nil?
23
23
  # "post" is a slug
@@ -36,7 +36,7 @@ class RuneBlog::Post
36
36
  end
37
37
 
38
38
  def write_metadata(meta) # FIXME ???
39
- log!(enter: __method__, args: [meta])
39
+ log!(enter: __method__, args: [meta], level: 3)
40
40
  debug "=== write_metadata:"
41
41
  debug "-----\n#{meta.inspect}\n-----"
42
42
  fname2 = "metadata.txt"
@@ -57,7 +57,7 @@ class RuneBlog::Post
57
57
  end
58
58
 
59
59
  def initialize
60
- log!(enter: __method__)
60
+ log!(enter: __method__, level: 3)
61
61
  @blog = RuneBlog.blog || raise(NoBlogAccessor)
62
62
  @meta = OpenStruct.new
63
63
  end
@@ -115,7 +115,7 @@ class RuneBlog::ViewPost
115
115
  :teaser_text
116
116
 
117
117
  def initialize(view, postdir)
118
- log!(enter: __method__, args: [view, postdir])
118
+ log!(enter: __method__, args: [view, postdir], level: 3)
119
119
  # Assumes already parsed/processed
120
120
  @blog = RuneBlog.blog || raise(NoBlogAccessor)
121
121
  @path = postdir.dup
@@ -131,7 +131,7 @@ class RuneBlog::ViewPost
131
131
  end
132
132
 
133
133
  def get_dirs
134
- log!(enter: __method__, args: [view, postdir])
134
+ log!(enter: __method__, args: [view, postdir], level: 3)
135
135
  fname = File.basename(draft)
136
136
  noext = fname.sub(/.lt3$/, "")
137
137
  vdir = @root/:views/view