runeblog 0.2.42 → 0.2.47

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/bin/blog +4 -7
  3. data/empty_view/assets/austin-pano.jpg +0 -0
  4. data/empty_view/themes/standard/blog/generate.lt3 +5 -3
  5. data/empty_view/themes/standard/blog/post_entry.lt3 +11 -10
  6. data/empty_view/themes/standard/etc/blog.css.lt3 +18 -0
  7. data/empty_view/themes/standard/navbar/faq.lt3 +1 -0
  8. data/empty_view/themes/standard/navbar/navbar.lt3 +1 -0
  9. data/empty_view/themes/standard/post/generate.lt3 +5 -4
  10. data/empty_view/themes/standard/widgets/ad/ad.lt3 +8 -1
  11. data/empty_view/themes/standard/widgets/ad/ad1.png +0 -0
  12. data/empty_view/themes/standard/widgets/ad/ad2.png +0 -0
  13. data/empty_view/themes/standard/widgets/ad/ad3.png +0 -0
  14. data/empty_view/themes/standard/widgets/ad/ad4.png +0 -0
  15. data/empty_view/themes/standard/widgets/bydates/bydates.rb +7 -3
  16. data/empty_view/themes/standard/widgets/links/links.rb +28 -3
  17. data/empty_view/themes/standard/widgets/news/news.rb +7 -3
  18. data/empty_view/themes/standard/widgets/pages/pages.rb +10 -3
  19. data/empty_view/themes/standard/widgets/pinned/pinned.rb +7 -3
  20. data/empty_view/themes/standard/widgets/search/search.rb +7 -3
  21. data/empty_view/themes/standard/widgets/sitemap/sitemap.rb +7 -3
  22. data/empty_view/themes/standard/widgets/tag-cloud/tag-cloud.rb +7 -3
  23. data/lib/default.rb +1 -1
  24. data/lib/global.rb +15 -40
  25. data/lib/helpers-blog.rb +15 -44
  26. data/lib/liveblog.rb +92 -56
  27. data/lib/logging.rb +17 -8
  28. data/lib/post.rb +7 -10
  29. data/lib/publish.rb +4 -5
  30. data/lib/repl.rb +2 -6
  31. data/lib/runeblog.rb +58 -71
  32. data/lib/runeblog_version.rb +1 -1
  33. data/lib/view.rb +2 -9
  34. data/lib/xlate.rb +35 -35
  35. data/test/austin.rb +29 -20
  36. metadata +8 -5
  37. data/empty_view/remote/widgets/links/list.data +0 -3
  38. data/empty_view/remote/widgets/news/list.data +0 -4
  39. data/empty_view/remote/widgets/pages/list.data +0 -4
@@ -6,37 +6,21 @@ 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
20
20
  end
21
21
 
22
- # def get_root
23
- # log!(enter: __method__)
24
- # if $_blog
25
- # if $_blog.root
26
- # puts "0. Returned: #{$_blog.root}/"
27
- # return $_blog.root + "/"
28
- # else
29
- # puts "1. Returned: ./"
30
- # return "./"
31
- # end
32
- # else
33
- # puts "2. Returned: ./"
34
- # return "./"
35
- # end
36
- # end
37
-
38
22
  def read_config(file, *syms)
39
- log!(enter: __method__, args: [file, *syms])
23
+ log!(enter: __method__, args: [file, *syms], level: 3)
40
24
  lines = File.readlines(file).map(&:chomp)
41
25
  obj = ::OpenStruct.new
42
26
  lines.each do |line|
@@ -61,26 +45,14 @@ module RuneBlog::Helpers
61
45
  end
62
46
 
63
47
  def try_read_config(file, hash)
64
- log!(enter: __method__, args: [file, hash])
48
+ log!(enter: __method__, args: [file, hash], level: 3)
65
49
  return hash.values unless File.exist?(file)
66
50
  vals = read_config(file, *hash.keys)
67
51
  vals
68
52
  end
69
53
 
70
- # def put_config(root:, view:"test_view", editor: "/usr/local/bin/vim")
71
- # log!(enter: __method__, args: [root, view, editor])
72
- # Dir.mkdir(root) unless Dir.exist?(root)
73
- # Dir.chdir(root) do
74
- # File.open("config", "w") do |cfg|
75
- # cfg.puts "root: #{root}"
76
- # cfg.puts "current_view: #{view}"
77
- # cfg.puts "editor: #{editor}"
78
- # end
79
- # end
80
- # end
81
-
82
54
  def write_config(obj, file)
83
- log!(enter: __method__, args: [obj, file])
55
+ log!(enter: __method__, args: [obj, file], level: 2)
84
56
  hash = obj.to_h
85
57
  File.open(file, "w") do |out|
86
58
  hash.each_pair {|key, val| out.puts "#{key}: #{val}" }
@@ -88,13 +60,13 @@ module RuneBlog::Helpers
88
60
  end
89
61
 
90
62
  def get_views # read from filesystem
91
- log!(enter: __method__)
63
+ log!(enter: __method__, level: 3)
92
64
  dirs = subdirs("#@root/views/").sort
93
65
  dirs.map {|name| RuneBlog::View.new(name) }
94
66
  end
95
67
 
96
68
  def new_dotfile(root: ".blogs", current_view: "test_view", editor: "vi")
97
- log!(enter: __method__, args: [root, current_view, editor])
69
+ log!(enter: __method__, args: [root, current_view, editor], level: 3)
98
70
  root = Dir.pwd/root
99
71
  x = OpenStruct.new
100
72
  x.root, x.current_view, x.editor = root, current_view, editor
@@ -102,21 +74,21 @@ module RuneBlog::Helpers
102
74
  end
103
75
 
104
76
  def new_sequence
105
- log!(enter: __method__)
77
+ log!(enter: __method__, level: 3)
106
78
  dump(0, "sequence")
107
79
  version_info = "#{RuneBlog::VERSION}\nBlog created: #{Time.now.to_s}"
108
80
  dump(version_info, "VERSION")
109
81
  end
110
82
 
111
83
  def subdirs(dir)
112
- log!(enter: __method__, args: [dir])
84
+ log!(enter: __method__, args: [dir], level: 3)
113
85
  dirs = Dir.entries(dir) - %w[. ..]
114
86
  dirs.reject! {|x| ! File.directory?("#@root/views/#{x}") }
115
87
  dirs
116
88
  end
117
89
 
118
90
  def find_draft_slugs
119
- log!(enter: __method__)
91
+ log!(enter: __method__, level: 3)
120
92
  files = Dir["#@root/drafts/**"].grep /\d{4}.*.lt3$/
121
93
  flagfile = "#@root/drafts/last_rebuild"
122
94
  last = File.exist?(flagfile) ? File.mtime(flagfile) : (Time.now - 86_400)
@@ -128,7 +100,7 @@ module RuneBlog::Helpers
128
100
  end
129
101
 
130
102
  def create_dirs(*dirs)
131
- log!(enter: __method__, args: [*dirs])
103
+ log!(enter: __method__, args: [*dirs], level: 3)
132
104
  dirs.each do |dir|
133
105
  dir = dir.to_s # symbols allowed
134
106
  next if Dir.exist?(dir)
@@ -139,27 +111,26 @@ module RuneBlog::Helpers
139
111
  end
140
112
 
141
113
  def interpolate(str, bind)
142
- log!(enter: __method__, args: [str, bind])
114
+ log!(enter: __method__, args: [str, bind], level: 3)
143
115
  wrap = "<<-EOS\n#{str}\nEOS"
144
116
  eval wrap, bind
145
117
  end
146
118
 
147
119
  def error(err) # Hmm, this is duplicated
148
- log!(str: "duplicated method", enter: __method__, args: [err])
120
+ log!(str: "duplicated method", enter: __method__, args: [err], level: 2)
149
121
  str = "\n Error: #{err}"
150
122
  puts str
151
123
  puts err.backtrace.join("\n")
152
124
  end
153
125
 
154
126
  def dump(obj, name)
155
- log!(enter: __method__, args: [obj, name])
127
+ log!(enter: __method__, args: [obj, name], level: 3)
156
128
  File.write(name, obj)
157
129
  end
158
-
159
130
  end
160
131
 
161
132
  def dump(obj, name) # FIXME scope
162
- log!(str: "scope problem", enter: __method__, args: [obj, name])
133
+ log!(str: "scope problem", enter: __method__, args: [obj, name], level: 3)
163
134
  File.write(name, obj)
164
135
  end
165
136
 
@@ -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
 
@@ -213,10 +234,16 @@ end
213
234
 
214
235
  def teaser
215
236
  raise "'post' was not called" unless @meta
216
- @meta.teaser = _body_text
237
+ text = _body_text
238
+ @meta.teaser = text
217
239
  setvar :teaser, @meta.teaser
218
- _out @meta.teaser + "\n"
219
- # 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
220
247
  end
221
248
 
222
249
  def finalize
@@ -286,7 +313,6 @@ def head # Does NOT output tags
286
313
  hash = defaults.dup.update(result) # FIXME collisions?
287
314
 
288
315
  hash.each_value {|x| _out " " + x }
289
- _out "<body>"
290
316
  end
291
317
 
292
318
  ########## newer stuff...
@@ -357,16 +383,26 @@ def sidebar
357
383
  tcard = "#{tag}-card.html"
358
384
 
359
385
  code = _load_local(tag)
360
- code && Dir.chdir(wtag) { code.build }
361
-
362
- # if File.exist?(wtag/"SUBFILES")
363
- # children = Dir[wtag/"*.lt3"] - [wtag/tag+".lt3"]
364
- # children.each do |child|
365
- # dest = child.sub(/.lt3$/, ".html")
366
- # xlate src: child, dst: dest # , debug: true
367
- # end
368
- # end
369
- 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")
370
406
  _include_file wtag/tcard
371
407
  end
372
408
  _out %[</div>]
@@ -575,7 +611,7 @@ def _html_body(file, css = nil)
575
611
  end
576
612
 
577
613
  def _write_card(cardfile, mainfile, pairs, card_title, tag)
578
- log!(str: "Creating #{cardfile}.html", pwd: true)
614
+ log!(str: "Creating #{cardfile}.html", pwd: true, level: 2)
579
615
  url = mainfile
580
616
  url = :widgets/tag/mainfile + ".html"
581
617
  File.open("#{cardfile}.html", "w") do |f|
@@ -590,7 +626,7 @@ def _write_card(cardfile, mainfile, pairs, card_title, tag)
590
626
  </h5>
591
627
  <div class="collapse" id="#{tag}">
592
628
  EOS
593
- log!(str: "Writing data pairs to #{cardfile}.html", pwd: true)
629
+ log!(str: "Writing data pairs to #{cardfile}.html", pwd: true, level: 2)
594
630
  local = _local_tag?(tag)
595
631
  pairs.each do |file, title|
596
632
  url = file
@@ -663,7 +699,7 @@ def _write_main_pages(mainfile, pairs, card_title, tag)
663
699
  end
664
700
 
665
701
  def _write_main(mainfile, pairs, card_title, tag)
666
- log!(str: "Creating #{mainfile}.html", pwd: true)
702
+ log!(str: "Creating #{mainfile}.html", pwd: true, level: 2)
667
703
 
668
704
  if tag == "pages" # temporary experiment
669
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,19 +10,18 @@ class RuneBlog::Post
10
10
  include RuneBlog::Helpers
11
11
 
12
12
  def self.files(num, root)
13
- log!(enter: __method__, args: [num, root])
14
- files = Find.find(root).to_a
13
+ log!(enter: __method__, args: [num, root], level: 3)
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
24
24
  pdir = RuneBlog.blog.view.dir/post
25
- verify(Dir.exist?(pdir) => "Directory #{pdir} not found")
26
25
  meta = nil
27
26
  Dir.chdir(pdir) do
28
27
  meta = read_config("metadata.txt")
@@ -36,7 +35,7 @@ class RuneBlog::Post
36
35
  end
37
36
 
38
37
  def write_metadata(meta) # FIXME ???
39
- log!(enter: __method__, args: [meta])
38
+ log!(enter: __method__, args: [meta], level: 3)
40
39
  debug "=== write_metadata:"
41
40
  debug "-----\n#{meta.inspect}\n-----"
42
41
  fname2 = "metadata.txt"
@@ -57,7 +56,7 @@ class RuneBlog::Post
57
56
  end
58
57
 
59
58
  def initialize
60
- log!(enter: __method__)
59
+ log!(enter: __method__, level: 3)
61
60
  @blog = RuneBlog.blog || raise(NoBlogAccessor)
62
61
  @meta = OpenStruct.new
63
62
  end
@@ -73,7 +72,6 @@ class RuneBlog::Post
73
72
  post.meta.title, post.meta.teaser, post.meta.body, post.meta.pubdate =
74
73
  title, teaser, body, pubdate
75
74
  post.meta.views = [post.blog.view.to_s] + views
76
- # STDERR.puts "Post.create: views = #{views.inspect}"
77
75
  post.meta.tags = []
78
76
  post.blog.make_slug(post.meta) # adds to meta
79
77
 
@@ -93,7 +91,6 @@ class RuneBlog::Post
93
91
 
94
92
  def edit
95
93
  log!(enter: __method__)
96
- verify(File.exist?(@draft) => "File #{@draft} not found")
97
94
  result = system!("vi #@draft +8") # TODO improve this
98
95
  raise EditorProblem(draft) unless result
99
96
  nil
@@ -115,7 +112,7 @@ class RuneBlog::ViewPost
115
112
  :teaser_text
116
113
 
117
114
  def initialize(view, postdir)
118
- log!(enter: __method__, args: [view, postdir])
115
+ log!(enter: __method__, args: [view, postdir], level: 3)
119
116
  # Assumes already parsed/processed
120
117
  @blog = RuneBlog.blog || raise(NoBlogAccessor)
121
118
  @path = postdir.dup
@@ -131,7 +128,7 @@ class RuneBlog::ViewPost
131
128
  end
132
129
 
133
130
  def get_dirs
134
- log!(enter: __method__, args: [view, postdir])
131
+ log!(enter: __method__, args: [view, postdir], level: 3)
135
132
  fname = File.basename(draft)
136
133
  noext = fname.sub(/.lt3$/, "")
137
134
  vdir = @root/:views/view