runeblog 0.3.27 → 0.3.28

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: a5338170556c8520e1d03e284f43a1f0b33833dbedf3d6e33991b06086dc655b
4
- data.tar.gz: a0e4c476dd214cd0ca3460597e6b1a07415b2223101c2eb1a1eed1966380c41f
3
+ metadata.gz: c0f9a3b31f1adc96704b1781f04e2eb4227ca341ebc3f118a0ead49c3be65859
4
+ data.tar.gz: 573d4f8ba2778d476b9b327e1c994863745f1d643f6b633cc771d3d4b2872af6
5
5
  SHA512:
6
- metadata.gz: 3cd616193a36e21dc6a9ffe56cf2a16c7abc1e3b50bfe339ba0b2b3446c4fd3d7fdcb63c3f569d2a2044d59c0cdbf05a38bc15aa5a1bb70d6482e276a1eb9b91
7
- data.tar.gz: aef8ad80e260ecc9805a13ea24b8ca22d9bb9fb8fbf719dd6d7f5fbb9e28032f9313335df8b96ab6993db68a60b16bbab6ccc6cba9261add841aba002dcc1930
6
+ metadata.gz: acaaf9714332878e5f60b26576c86286672f221717b8c66901749cf9e9e4a257baee45ec5a2fe42d1eea3c64746cd959d10bbba1b08828cb15075ca9af85ae40
7
+ data.tar.gz: 43b9c4d21d1c5d82f6c7e1b1ce291f304e1dd52f12b46b36200f4aebe2db127603b15ab1dcaca43cc8ea607a515263019abf20c4b88d8e0da620a41187639a9a
data/bin/blog CHANGED
@@ -87,7 +87,7 @@ def get_started
87
87
  end
88
88
 
89
89
  def mainloop
90
- info = @blog.view || "no view"
90
+ info = @blog.view.name rescue "No view"
91
91
  print fx("[#{info}] ", Red, :bold)
92
92
  cmd = STDSCR.gets(history: @cmdhist, tab: @tabcom, capture: [" "])
93
93
  case cmd
@@ -107,6 +107,8 @@ def mainloop
107
107
  puts "Don't understand '#{cmd.inspect}'\n "
108
108
  end
109
109
  rescue => err
110
+ # puts "----- ML_RESCUE err = #{err.inspect} VIEW = #{@blog.view.inspect}"
111
+ puts "----- ML_RESCUE err = #{err.inspect} "
110
112
  log!(str: err.to_s)
111
113
  log!(str: err.backtrace.join("\n")) if err.respond_to?(:backtrace)
112
114
  puts "Current dir = #{Dir.pwd}"
@@ -148,7 +150,7 @@ end
148
150
 
149
151
  def handle_cmdline
150
152
  cmd = ARGV[0]
151
- @blog = RuneBlog.new
153
+ @blog = RuneBlog.read # was .new
152
154
  abort "No blog found" if @blog.nil?
153
155
 
154
156
  case cmd
@@ -197,7 +199,7 @@ def create_new_repo?
197
199
  new_repo = true
198
200
  end
199
201
 
200
- @blog = RuneBlog.new
202
+ @blog = RuneBlog.read # was .new
201
203
  get_started if new_repo
202
204
  rescue => err
203
205
  STDERR.puts "Error - #{err.to_s}"
data/bin/blog.rb ADDED
@@ -0,0 +1,237 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $LOAD_PATH << "./lib"
4
+
5
+ require 'runeblog'
6
+ require 'rubytext'
7
+
8
+ require 'menus'
9
+
10
+ require 'repl'
11
+
12
+ include RuneBlog::REPL
13
+
14
+ def yesno(question, noskip=false)
15
+ puts fx("\n #{question}", :bold)
16
+ puts unless noskip
17
+ STDSCR.yesno
18
+ end
19
+
20
+ def pick_editor
21
+ choices = %w[vim emacs vi nano]
22
+ r, c = STDSCR.rc
23
+ num, name = STDSCR.menu(r: r, c: c+6, title: "Default editor", items: choices)
24
+ file = `which #{name}`.chomp
25
+ end
26
+
27
+ def get_universal
28
+ univ = "#{@blog.root}/data/universal.lt3"
29
+ if yesno("Faster initial setup? (no: edit universal.lt3)")
30
+ # author = ask!(" Author name: ")
31
+ # site = ask!(" Site/domain: ")
32
+ # Temporarily, for speed:
33
+ author, site = "Hal Fulton", "somedomain.com"
34
+ puts " Author name: #{author}"
35
+ puts " Site/domain: #{site}"
36
+ # Now stash it...
37
+ str = File.read(univ)
38
+ str = str.gsub(/AUTHOR/, author)
39
+ str = str.gsub(/SITE_DOMAIN/, site)
40
+ File.write(univ, str)
41
+ else
42
+ vim_params = '-c ":set hlsearch" -c ":hi Search ctermfg=2 ctermbg=6" +/"\(AUTHOR.*\|SITE.*\)"'
43
+ edit_file(univ, vim: vim_params)
44
+ end
45
+ end
46
+
47
+ def get_global
48
+ view_name = ask!(" Filename: ")
49
+ @blog.create_view(view_name) # call change_view??
50
+ if yesno("Faster view setup? (no: edit global.lt3)")
51
+ title = ask!(" View title: ")
52
+ subtitle = ask!(" Subtitle : ")
53
+ domain = ask!(" Domain : ")
54
+ modify_view_global(view_name)
55
+ modify_view_settings(name: view_name, title: title, subtitle: subtitle,
56
+ domain: domain)
57
+ else
58
+ vim_params = '-c ":set hlsearch" -c ":hi Search ctermfg=2 ctermbg=6" +/"\(VIEW_.*\|SITE.*\)"'
59
+ edit_file(@blog.view.dir/"themes/standard/global.lt3", vim: vim_params)
60
+ end
61
+ end
62
+
63
+ def get_started
64
+ if yesno("Do you want to qo a quick setup?")
65
+ puts " First choose your editor."
66
+ @blog.editor = pick_editor
67
+ File.write("#{@blog.root}/data/EDITOR", @blog.editor)
68
+ print " Default editor is "
69
+ puts fx(@blog.editor, :bold)
70
+
71
+ get_universal
72
+ # Now create a custom global.lt3
73
+ @blog._generate_global
74
+ puts fx("\n Quick setup complete!", :bold)
75
+ if yesno("Create your first view now?")
76
+ get_global
77
+ puts fx("\n View #{@blog.view} created!\n ", :bold)
78
+ end
79
+ end
80
+
81
+ print fx(" For help", :bold); puts " type h or help."
82
+ print fx(" Create a view", :bold); puts " with: new view"
83
+ print fx(" Create a post", :bold); puts " (within current view): new post"
84
+ end
85
+
86
+ def mainloop
87
+ info = @blog.view || "no view"
88
+ print fx("[#{info}] ", Red, :bold)
89
+ cmd = STDSCR.gets(history: @cmdhist, tab: @tabcom, capture: [" "]).chomp
90
+ case cmd
91
+ when " ", RubyText::Keys::Escape
92
+ Dir.chdir(@blog.view.dir)
93
+ show_top_menu
94
+ puts
95
+ return
96
+ when RubyText::Keys::CtlD # ^D
97
+ cmd_quit
98
+ when String
99
+ return if cmd.empty? # CR does nothing
100
+ invoking = RuneBlog::REPL.choose_method(cmd)
101
+ ret = send(*invoking)
102
+ else
103
+ puts "Don't understand '#{cmd.inspect}'\n "
104
+ end
105
+ rescue => err
106
+ log!(str: err.to_s)
107
+ log!(str: err.backtrace.join("\n")) if err.respond_to?(:backtrace)
108
+ puts "Current dir = #{Dir.pwd}"
109
+ puts err
110
+ puts err.backtrace.join("\n")
111
+ puts "Pausing..."; gets
112
+ end
113
+
114
+ def cmdline_preview
115
+ _need_view
116
+ local = @blog.view.local_index
117
+ result = system("open #{local}")
118
+ end
119
+
120
+ def cmdline_publish
121
+ abort "Not implemented yet"
122
+ _need_view
123
+ end
124
+
125
+ def cmdline_browse
126
+ abort "Not implemented yet"
127
+ _need_view
128
+ end
129
+
130
+ def _need_view
131
+ @view = ARGV[1]
132
+ abort "Need 'view' parameter" if @view.nil?
133
+ abort "No such view '#{view}'" unless @blog.view?(@view)
134
+ end
135
+
136
+ def cmdline_rebuild
137
+ _need_view
138
+ print "Generating view... "
139
+ @blog.generate_view(@view)
140
+ print "Generating index... "
141
+ num = @blog.generate_index(@view)
142
+ puts "#{num} posts\n "
143
+ end
144
+
145
+ def handle_cmdline
146
+ cmd = ARGV[0]
147
+ @blog = RuneBlog.new
148
+ abort "No blog found" if @blog.nil?
149
+
150
+ case cmd
151
+ when "rebuild"; cmdline_rebuild
152
+ when "publish"; cmdline_publish
153
+ when "preview"; cmdline_preview
154
+ when "browse"; cmdline_browse
155
+ else
156
+ puts "Command '#{cmd}' is unknown"
157
+ end
158
+ exit
159
+ end
160
+
161
+ def check_ruby_version
162
+ major, minor = RUBY_VERSION.split(".").values_at(0,1)
163
+ ver = major.to_i*10 + minor.to_i
164
+ unless ver >= 24
165
+ RubyText.stop
166
+ sleep 0.2
167
+ puts "Needs Ruby 2.4 or greater"
168
+ exit
169
+ end
170
+ end
171
+
172
+ def reopen_stderr
173
+ errfile = File.new("stderr.out", "w")
174
+ STDERR.reopen(errfile)
175
+ end
176
+
177
+ def set_fgbg
178
+ # read a .rubytext file here?? Call it something else?
179
+ home = ENV['HOME']
180
+ @fg, @bg = Blue, White ## FIXME!! try_read_config("#{home}/.rubytext", fg: Blue, bg: White)
181
+ @fg = @fg.downcase.to_sym
182
+ @bg = @bg.downcase.to_sym
183
+
184
+ RubyText.start(:_echo, :keypad, scroll: true, log: "binblog.txt", fg: @fg, bg: @bg)
185
+ end
186
+
187
+ def create_new_repo?
188
+ new_repo = false
189
+ if ! RuneBlog.exist?
190
+ exit unless yesno("No blog repo found. Create new one?")
191
+ RuneBlog.create_new_blog_repo
192
+ puts fx(" Blog repo successfully created.", :bold)
193
+ new_repo = true
194
+ end
195
+
196
+ @blog = RuneBlog.new
197
+ get_started if new_repo
198
+ rescue => err
199
+ STDERR.puts "Error - #{err.to_s}"
200
+ STDERR.puts err.backtrace if err.respond_to?(:backtrace)
201
+ end
202
+
203
+ def print_intro
204
+ print fx(" For help", :bold)
205
+ puts " type h or help.\n "
206
+
207
+ puts fx("\n RuneBlog", :bold), fx(" v #{RuneBlog::VERSION}\n", Red)
208
+ end
209
+
210
+ def cmd_history_etc
211
+ @cmdhist = []
212
+ @tabcom = RuneBlog::REPL::Patterns.keys.uniq - RuneBlog::REPL::Abbr.keys
213
+ @tabcom.map! {|x| x.sub(/ [\$\>].*/, "") + " " }
214
+ @tabcom.sort!
215
+ end
216
+
217
+ def exit_repl
218
+ # RubyText.stop
219
+ sleep 0.2
220
+ puts
221
+ end
222
+
223
+ ### Main
224
+
225
+ include RuneBlog::Helpers # for try_read_config
226
+
227
+ reopen_stderr
228
+ check_ruby_version
229
+
230
+ handle_cmdline unless ARGV.empty?
231
+ set_fgbg
232
+ print_intro
233
+ create_new_repo?
234
+
235
+ cmd_history_etc
236
+ loop { mainloop }
237
+ exit_repl
data/data/global.lt3 CHANGED
@@ -15,6 +15,6 @@ charset utf-8
15
15
  url http://SITE
16
16
  locale en_US
17
17
 
18
- font.family verdana
18
+ font.family verdana
19
19
  .end
20
20
 
data/lib/helpers-blog.rb CHANGED
@@ -24,7 +24,6 @@ module RuneBlog::Helpers
24
24
  dir = root/:views/view/:settings
25
25
  end
26
26
  file = dir/"features.txt"
27
- # puts "-- in #{Dir.pwd} trying to read #{file}"
28
27
  pairs = read_pairs(file)
29
28
  enabled = {}
30
29
  pairs.each {|k,v| enabled[k] = (v == "1") }
@@ -108,12 +107,6 @@ module RuneBlog::Helpers
108
107
  stop_RubyText rescue nil
109
108
  end
110
109
 
111
- def retrieve_views # read from filesystem
112
- log!(enter: __method__, level: 3)
113
- dirs = subdirs("#@root/views/").sort
114
- dirs.map {|name| RuneBlog::View.new(name) }
115
- end
116
-
117
110
  def write_repo_config(root: "#{Dir.pwd}/.blogs", view: nil, editor: "/usr/local/bin/vim")
118
111
  view ||= File.read("#{root}/data/VIEW").chomp rescue "[no view]"
119
112
  File.write(root + "/data/ROOT", root + "\n")
data/lib/liveblog.rb CHANGED
@@ -49,20 +49,20 @@ end
49
49
  def dropcap
50
50
  log!(enter: __method__)
51
51
  # Bad form: adds another HEAD
52
- text = _data
53
- _out " "
52
+ text = api.data
53
+ api.out " "
54
54
  letter = text[0]
55
55
  remain = text[1..-1]
56
- _out %[<div class='mydrop'>#{letter}</div>]
57
- _out %[<div style="padding-top: 1px">#{remain}]
56
+ api.out %[<div class='mydrop'>#{letter}</div>]
57
+ api.out %[<div style="padding-top: 1px">#{remain}]
58
58
  end
59
59
 
60
60
  def post
61
61
  log!(enter: __method__)
62
62
  @meta = OpenStruct.new
63
- @meta.num = _args[0]
63
+ @meta.num = api.args[0]
64
64
  setvar("post.num", @meta.num.to_i)
65
- _out " <!-- Post number #{@meta.num} -->\n "
65
+ api.out " <!-- Post number #{@meta.num} -->\n "
66
66
  end
67
67
 
68
68
  def _got_python?
@@ -91,7 +91,7 @@ def post_toolbar
91
91
  log!(enter: __method__)
92
92
  back_icon = %[<img src="assets/back-icon.png" width=24 height=24 alt="Go back"></img>]
93
93
  back = %[<a style="text-decoration: none" href="javascript:history.go(-1)">#{back_icon}</a>]
94
- _out <<~HTML
94
+ api.out <<~HTML
95
95
  <div align='right'>#{back} #@reddit_comments</div>
96
96
  HTML
97
97
  end
@@ -138,7 +138,7 @@ log! str: " -- dir = #{dir}"
138
138
  # damned syntax highlighting </>
139
139
  end
140
140
  # STDERR.print "Pausing... "; getch
141
- _out <<~HTML
141
+ api.out <<~HTML
142
142
  #{reddit_txt}
143
143
  <hr>
144
144
  <table width=100%><tr>
@@ -151,27 +151,27 @@ end
151
151
  def faq
152
152
  log!(enter: __method__)
153
153
  @faq_count ||= 0
154
- _out "<br>" if @faq_count == 0
154
+ api.out "<br>" if @faq_count == 0
155
155
  @faq_count += 1
156
- ques = _data.chomp
157
- ans = _body.join("\n")
156
+ ques = api.data.chomp
157
+ ans = api.body.join("\n")
158
158
  id = "faq#@faq_count"
159
- _out %[&nbsp;<a data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample"><font size=+3>&#8964;</font></a>]
160
- _out %[&nbsp;<b>#{ques}</b>]
161
- _out %[<div class="collapse" id="#{id}"><br><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{ans}</font></div>\n]
162
- _out "<br>" # unless @faq_count == 1
163
- _optional_blank_line
159
+ api.out %[&nbsp;<a data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample"><font size=+3>&#8964;</font></a>]
160
+ api.out %[&nbsp;<b>#{ques}</b>]
161
+ api.out %[<div class="collapse" id="#{id}"><br><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{ans}</font></div>\n]
162
+ api.out "<br>" # unless @faq_count == 1
163
+ api.optional_blank_line
164
164
  end
165
165
 
166
166
  def backlink
167
167
  log!(enter: __method__)
168
- _out %[<br><a href="javascript:history.go(-1)">[Back]</a>]
168
+ api.out %[<br><a href="javascript:history.go(-1)">[Back]</a>]
169
169
  end
170
170
 
171
171
  def code
172
172
  log!(enter: __method__)
173
- lines = _body # _text
174
- _out "<font size=+1><pre>\n#{lines}\n</pre></font>"
173
+ lines = api.body # _text
174
+ api.out "<font size=+1><pre>\n#{lines}\n</pre></font>"
175
175
  end
176
176
 
177
177
  def _read_navbar_data
@@ -191,7 +191,7 @@ def banner
191
191
  str2 = ""
192
192
  navbar = nil
193
193
  vdir = @blog.root/:views/@blog.view
194
- lines = _body.to_a
194
+ lines = api.body.to_a
195
195
 
196
196
  lines.each do |line|
197
197
  count += 1
@@ -234,14 +234,14 @@ def banner
234
234
  str2 << " '#{tag}' isn't known" + "\n"
235
235
  end
236
236
  end
237
- _out <<~HTML
237
+ api.out <<~HTML
238
238
  <table width=100% bgcolor=#{bg}>
239
239
  <tr>
240
240
  #{str2}
241
241
  </tr>
242
242
  </table>
243
243
  HTML
244
- _out navbar if navbar
244
+ api.out navbar if navbar
245
245
  rescue => err
246
246
  STDERR.puts "err = #{err}"
247
247
  STDERR.puts err.backtrace.join("\n") if err.respond_to?(:backtrace)
@@ -306,7 +306,7 @@ end
306
306
  def quote
307
307
  log!(enter: __method__)
308
308
  _passthru "<blockquote>"
309
- _passthru _body.join(" ")
309
+ _passthru api.body.join(" ")
310
310
  _passthru "</blockquote>"
311
311
  _optional_blank_line
312
312
  end
@@ -317,7 +317,7 @@ end
317
317
 
318
318
  def style
319
319
  log!(enter: __method__)
320
- fname = _args[0]
320
+ fname = api.args[0]
321
321
  _passthru %[<link rel="stylesheet" href="???/etc/#{fname}')">]
322
322
  end
323
323
 
@@ -333,43 +333,43 @@ def h6; _passthru "<h6>#{@_data}</h6>"; end
333
333
  def hr; _passthru "<hr>"; end
334
334
 
335
335
  def nlist
336
- log!(enter: __method__)
337
- _out "<ol>"
338
- _body {|line| _out "<li>#{line}</li>" }
339
- _out "</ol>"
340
- _optional_blank_line
336
+ log!(enter: api._method__)
337
+ api.out "<ol>"
338
+ api.body {|line| api.out "<li>#{line}</li>" }
339
+ api.out "</ol>"
340
+ api.optional_blank_line
341
341
  end
342
342
 
343
343
  def list
344
344
  log!(enter: __method__)
345
- _out "<ul>"
346
- _body {|line| _out "<li>#{line}</li>" }
347
- _out "</ul>"
348
- _optional_blank_line
345
+ api.out "<ul>"
346
+ api.body {|line| api.out "<li>#{line}</li>" }
347
+ api.out "</ul>"
348
+ api.optional_blank_line
349
349
  end
350
350
 
351
351
  def list!
352
352
  log!(enter: __method__)
353
- _out "<ul>"
354
- lines = _body.each
353
+ api.out "<ul>"
354
+ lines = api.body.each
355
355
  loop do
356
356
  line = lines.next
357
- line = _format(line)
357
+ line = api.format(line)
358
358
  if line[0] == " "
359
- _out line
359
+ api.out line
360
360
  else
361
- _out "<li>#{line}</li>"
361
+ api.out "<li>#{line}</li>"
362
362
  end
363
363
  end
364
- _out "</ul>"
365
- _optional_blank_line
364
+ api.out "</ul>"
365
+ api.optional_blank_line
366
366
  end
367
367
 
368
368
  ### inset
369
369
 
370
370
  def inset
371
371
  log!(enter: __method__)
372
- lines = _body
372
+ lines = api.body
373
373
  box = ""
374
374
  output = []
375
375
  lines.each do |line|
@@ -387,16 +387,16 @@ def inset
387
387
  output << line
388
388
  end
389
389
  end
390
- lr = _args.first
391
- wide = _args[1] || "25"
390
+ lr = api.args.first
391
+ wide = api.args[1] || "25"
392
392
  stuff = "<div style='float:#{lr}; width: #{wide}%; padding:8px; padding-right:12px'>"
393
393
  stuff << '<b><i>' + box + '</i></b></div>'
394
- _out "</p>" # kludge!! nopara
394
+ api.out "</p>" # kludge!! nopara
395
395
  0.upto(2) {|i| _passthru output[i] }
396
396
  _passthru stuff
397
397
  3.upto(output.length-1) {|i| _passthru output[i] }
398
- _out "<p>" # kludge!! para
399
- _optional_blank_line
398
+ api.out "<p>" # kludge!! para
399
+ api.optional_blank_line
400
400
  end
401
401
 
402
402
  def title
@@ -406,42 +406,42 @@ def title
406
406
  @meta.title = title
407
407
  setvar :title, title
408
408
  # FIXME refactor -- just output variables for a template
409
- _optional_blank_line
409
+ api.optional_blank_line
410
410
  end
411
411
 
412
412
  def pubdate
413
413
  log!(enter: __method__)
414
414
  raise NoPostCall unless @meta
415
- _debug "data = #@_data"
415
+ api.debug "data = #@_data"
416
416
  # Check for discrepancy?
417
417
  match = /(\d{4}).(\d{2}).(\d{2})/.match @_data
418
418
  junk, y, m, d = match.to_a
419
419
  y, m, d = y.to_i, m.to_i, d.to_i
420
420
  @meta.date = ::Date.new(y, m, d)
421
421
  @meta.pubdate = "%04d-%02d-%02d" % [y, m, d]
422
- _optional_blank_line
422
+ api.optional_blank_line
423
423
  end
424
424
 
425
425
  def tags
426
426
  log!(enter: __method__)
427
427
  raise NoPostCall unless @meta
428
- _debug "args = #{_args}"
429
- @meta.tags = _args.dup || []
430
- _optional_blank_line
428
+ api.debug "args = #{_args}"
429
+ @meta.tags = api.args.dup || []
430
+ api.optional_blank_line
431
431
  end
432
432
 
433
433
  def views
434
434
  log!(enter: __method__)
435
435
  raise NoPostCall unless @meta
436
- _debug "data = #{_args}"
437
- @meta.views = _args.dup
438
- _optional_blank_line
436
+ api.debug "data = #{_args}"
437
+ @meta.views = api.args.dup
438
+ api.optional_blank_line
439
439
  end
440
440
 
441
441
  def pin
442
442
  log!(enter: __method__)
443
443
  raise NoPostCall unless @meta
444
- _debug "data = #{_args}" # verify only valid views?
444
+ api.debug "data = #{_args}" # verify only valid views?
445
445
  pinned = @_args
446
446
  @meta.pinned = pinned
447
447
  pinned.each do |pinview|
@@ -452,7 +452,7 @@ def pin
452
452
  pins.uniq!
453
453
  File.open(datafile, "w") {|out| pins.each {|pin| out.puts pin } }
454
454
  end
455
- _optional_blank_line
455
+ api.optional_blank_line
456
456
  rescue => err
457
457
  STDERR.puts "err = #{err}"
458
458
  STDERR.puts err.backtrace.join("\n") if err.respond_to?(:backtrace)
@@ -472,15 +472,15 @@ end
472
472
  def teaser
473
473
  log!(enter: __method__)
474
474
  raise NoPostCall unless @meta
475
- text = _body.join("\n")
475
+ text = api.body.join("\n")
476
476
  @meta.teaser = text
477
477
  setvar :teaser, @meta.teaser
478
- if _args[0] == "dropcap" # FIXME doesn't work yet!
478
+ if api.args[0] == "dropcap" # FIXME doesn't work yet!
479
479
  letter, remain = text[0], text[1..-1]
480
- _out %[<div class='mydrop'>#{letter}</div>]
481
- _out %[<div style="padding-top: 1px">#{remain}] + "\n"
480
+ api.out %[<div class='mydrop'>#{letter}</div>]
481
+ api.out %[<div style="padding-top: 1px">#{remain}] + "\n"
482
482
  else
483
- _out @meta.teaser + "\n"
483
+ api.out @meta.teaser + "\n"
484
484
  end
485
485
  end
486
486
 
@@ -498,10 +498,10 @@ end
498
498
 
499
499
  def head # Does NOT output <head> tags
500
500
  log!(enter: __method__)
501
- args = _args
501
+ args = api.args
502
502
  args.each do |inc|
503
503
  self.data = inc
504
- _include
504
+ dot_include
505
505
  end
506
506
  # Depends on vars: title, desc, host
507
507
  defaults = {}
@@ -522,7 +522,7 @@ def head # Does NOT output <head> tags
522
522
  "favicon" => %[<link rel="shortcut icon" type="image/x-icon" href="etc/favicon.ico">\n <link rel="apple-touch-icon" href="etc/favicon.ico">]
523
523
  }
524
524
  result = {}
525
- lines = _body
525
+ lines = api.body
526
526
  lines.each do |line|
527
527
  line.chomp
528
528
  word, remain = line.split(" ", 2)
@@ -547,14 +547,14 @@ def head # Does NOT output <head> tags
547
547
  end
548
548
  hash = defaults.dup.update(result) # FIXME collisions?
549
549
 
550
- hash.each_value {|x| _out " " + x }
550
+ hash.each_value {|x| api.out " " + x }
551
551
  end
552
552
 
553
553
  ########## newer stuff...
554
554
 
555
555
  def meta
556
556
  log!(enter: __method__)
557
- args = _args
557
+ args = api.args
558
558
  enum = args.each
559
559
  str = "<meta"
560
560
  arg = enum.next
@@ -569,12 +569,12 @@ def meta
569
569
  arg = enum.next
570
570
  end
571
571
  str << ">"
572
- _out str
572
+ api.out str
573
573
  end
574
574
 
575
575
  def recent_posts # side-effect
576
576
  log!(enter: __method__)
577
- _out <<-HTML
577
+ api.out <<-HTML
578
578
  <div class="col-lg-9 col-md-9 col-sm-9 col-xs-12">
579
579
  <iframe id="main" style="width: 70vw; height: 100vh; position: relative;"
580
580
  src='recent.html' width=100% frameborder="0" allowfullscreen>
@@ -623,17 +623,18 @@ end
623
623
 
624
624
  def sidebar
625
625
  log!(enter: __method__)
626
- _debug "--- handling sidebar\r"
627
- if _args.include? "off"
628
- _body { } # iterate, do nothing
626
+ api.debug "--- handling sidebar\r"
627
+ if api.args.include? "off"
628
+ api.body { } # iterate, do nothing
629
629
  return
630
630
  end
631
631
 
632
- _out %[<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12">]
632
+ api.out %[<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12">]
633
633
 
634
634
  standard = %w[pinned pages links news]
635
635
 
636
- _body do |token|
636
+ lines = api.body.to_a
637
+ lines.each do |token|
637
638
  tag = token.chomp.strip.downcase
638
639
  wtag = "../../widgets"/tag
639
640
  raise CantFindWidgetDir(wtag) unless Dir.exist?(wtag)
@@ -645,9 +646,9 @@ def sidebar
645
646
  raise "Nonstandard widget?"
646
647
  end
647
648
 
648
- _include_file wtag/tcard
649
+ api.include_file wtag/tcard
649
650
  end
650
- _out %[</div>]
651
+ api.out %[</div>]
651
652
  rescue => err
652
653
  puts "err = #{err}"
653
654
  puts err.backtrace.join("\n") if err.respond_to?(:backtrace)
@@ -657,20 +658,20 @@ end
657
658
 
658
659
  def stylesheet
659
660
  log!(enter: __method__)
660
- lines = _body
661
+ lines = api.body
661
662
  url = lines[0]
662
663
  integ = lines[1]
663
664
  cross = lines[2] || "anonymous"
664
- _out %[<link rel="stylesheet" href="#{url}" integrity="#{integ}" crossorigin="#{cross}"></link>]
665
+ api.out %[<link rel="stylesheet" href="#{url}" integrity="#{integ}" crossorigin="#{cross}"></link>]
665
666
  end
666
667
 
667
668
  def script
668
669
  log!(enter: __method__)
669
- lines = _body
670
+ lines = api.body
670
671
  url = lines[0]
671
672
  integ = lines[1]
672
673
  cross = lines[2] || "anonymous"
673
- _out %[<script src="#{url}" integrity="#{integ}" crossorigin="#{cross}"></script>]
674
+ api.out %[<script src="#{url}" integrity="#{integ}" crossorigin="#{cross}"></script>]
674
675
  end
675
676
 
676
677
  $Dot = self # Clunky! for dot commands called from Functions class
@@ -716,7 +717,7 @@ end
716
717
 
717
718
  def tag_cloud
718
719
  log!(enter: __method__)
719
- title = _data
720
+ title = api.data
720
721
  title = "Tag Cloud" if title.empty?
721
722
  open = <<-HTML
722
723
  <div class="card mb-3">
@@ -727,15 +728,15 @@ def tag_cloud
727
728
  </h5>
728
729
  <div class="collapse" id="tag-cloud">
729
730
  HTML
730
- _out open
731
- _body do |line|
731
+ api.out open
732
+ api.body do |line|
732
733
  line.chomp!
733
734
  url, classname, cdata = line.split(",", 3)
734
735
  main = _main(url)
735
- _out %[<a #{main} class="#{classname}">#{cdata}</a>]
736
+ api.out %[<a #{main} class="#{classname}">#{cdata}</a>]
736
737
  end
737
738
  close = %[ </div>\n </div>\n </div>]
738
- _out close
739
+ api.out close
739
740
  end
740
741
 
741
742
  def vnavbar
@@ -785,7 +786,7 @@ def _make_navbar(orient = :horiz)
785
786
  output = File.new(html_file, "w")
786
787
  output.puts start
787
788
  lines = _read_navbar_data
788
- lines = ["index Home"] + lines unless _args.include?("nohome")
789
+ lines = ["index Home"] + lines unless api.args.include?("nohome")
789
790
  lines.each do |line|
790
791
  basename, cdata = line.chomp.strip.split(" ", 2)
791
792
  full = :banner/:navbar/basename+".html"
@@ -831,16 +832,16 @@ def _passthru(line)
831
832
  log!(enter: __method__)
832
833
  return if line.nil?
833
834
  line = _format(line)
834
- _out line + "\n"
835
- _out "<p>" if line.empty? && ! @_nopara
835
+ api.out line + "\n"
836
+ api.out "<p>" if line.empty? && ! @_nopara
836
837
  end
837
838
 
838
839
  def _passthru_noline(line)
839
840
  log!(enter: __method__)
840
841
  return if line.nil?
841
842
  line = _format(line)
842
- _out line
843
- _out "<p>" if line.empty? && ! @_nopara
843
+ api.out line
844
+ api.out "<p>" if line.empty? && ! @_nopara
844
845
  end
845
846
 
846
847
  def _write_metadata
@@ -891,7 +892,7 @@ def _card_generic(card_title:, middle:, extra: "")
891
892
  </div>
892
893
  HTML
893
894
  text = front + middle + tail
894
- _out text + "\n "
895
+ api.out text + "\n "
895
896
  end
896
897
 
897
898
  def _var(name) # FIXME scope issue!
data/lib/lowlevel.rb CHANGED
@@ -23,13 +23,14 @@
23
23
  File.open(file, "a") {|f| f.puts "#{Time.now} #{line}" }
24
24
  end
25
25
 
26
- def system!(str, show: false)
27
- log!(enter: __method__, args: [str], level: 2)
28
- STDERR.puts str if show
29
- rc = system(str)
26
+ def system!(os_cmd, show: false)
27
+ log!(enter: __method__, args: [os_cmd], level: 2)
28
+ caller.each {|x| print "::: "; p x }
29
+ STDERR.puts os_cmd if show
30
+ rc = system(os_cmd)
30
31
  STDERR.puts " rc = #{rc.inspect}" if show
31
32
  return rc if rc
32
- STDERR.puts "FAILED: #{str.inspect}"
33
+ STDERR.puts "FAILED: #{os_cmd.inspect}"
33
34
  STDERR.puts "\ncaller = \n#{caller.join("\n ")}\n"
34
35
  if defined?(RubyText)
35
36
  sleep 6
data/lib/processing.rb CHANGED
@@ -77,11 +77,14 @@ rescue => err
77
77
  end
78
78
 
79
79
  def get_live_vars(src)
80
+ dir, base = File.dirname(src), File.basename(src)
80
81
  live = Livetext.customize(call: [".nopara"])
81
- # puts "glv: src = #{src.inspect}"
82
- # STDERR.puts "glv: src = #{src.inspect}"
83
- live.xform_file(src)
82
+ Dir.chdir(dir) { live.xform_file(base) }
84
83
  live
84
+ rescue => e
85
+ puts e
86
+ puts $!
87
+ gets
85
88
  end
86
89
 
87
90
  end
data/lib/repl.rb CHANGED
@@ -39,7 +39,7 @@ module RuneBlog::REPL
39
39
 
40
40
  def cmd_config
41
41
  hash = {"Variables (general)" => "global.lt3",
42
- " View-specific" => "../../settings/view.txt",
42
+ " View-specific" => "../settings/view.txt",
43
43
  " Recent posts" => "../../settings/recent.txt",
44
44
  " Publishing" => "../../settings/publish.txt",
45
45
  "Configuration: enable/disable" => "../../settings/features.txt",
@@ -253,7 +253,6 @@ log! str: "=== ...finished!"
253
253
  name = @blog.view.name
254
254
  k, name = STDSCR.menu(title: "Views", items: viewnames, curr: n, wrap: true)
255
255
  return if name.nil?
256
- log! str: "cv Setting to #{name.inspect}"
257
256
  @blog.view = name
258
257
  # puts "\n ", fx(name, :bold), "\n"
259
258
  return
@@ -371,7 +370,8 @@ log! str: "cv Setting to #{name.inspect}"
371
370
 
372
371
  def cmd_list_views
373
372
  puts
374
- @blog.views.each do |v|
373
+ list = @blog.views
374
+ list.each do |v|
375
375
  v = v.to_s
376
376
  title = view2title(v)
377
377
  v = fx(v, :bold) if v == @blog.view.name
@@ -412,22 +412,16 @@ log! str: "cv Setting to #{name.inspect}"
412
412
  if curr_drafts.empty?
413
413
  puts "\n No drafts\n "
414
414
  return
415
- else
416
- puts
417
- curr_drafts.each do |draft|
418
- base = draft.sub(/.lt3$/, "")
419
- dir = @blog.root/:posts/base
420
- meta = nil
421
- Dir.chdir(dir) { meta = @blog.read_metadata }
422
- num, title = meta.num, meta.title
423
- num = '%4d' % num.to_s
424
- puts " ", fx(num, Red), " ", fx(title, Black)
425
- other = @blog._get_views(@blog.root/:drafts/draft) - [@blog.view.to_s]
426
- unless other.empty?
427
- print fx(" "*9 + "also in: ", :bold)
428
- puts other.join(", ")
429
- end
430
- end
415
+ end
416
+ puts
417
+ curr_drafts.each do |draft|
418
+ base = draft.sub(/.lt3$/, "")
419
+ dir = @blog.root/:posts/base
420
+ meta = nil
421
+ Dir.chdir(dir) { meta = @blog.read_metadata }
422
+ num, title = meta.num, meta.title
423
+ num = '%4d' % num.to_s
424
+ puts " ", fx(num, Red), " ", fx(title, Black)
431
425
  end
432
426
  puts
433
427
  end
@@ -438,12 +432,11 @@ log! str: "cv Setting to #{name.inspect}"
438
432
  if assets.empty?
439
433
  puts " No assets"
440
434
  return
441
- else
442
- puts
443
- assets.each do |name|
444
- asset = File.basename(name)
445
- puts " ", fx(asset, Blue)
446
- end
435
+ end
436
+ puts
437
+ assets.each do |name|
438
+ asset = File.basename(name)
439
+ puts " ", fx(asset, Blue)
447
440
  end
448
441
  puts
449
442
  end
data/lib/runeblog.rb CHANGED
@@ -58,9 +58,9 @@ class RuneBlog
58
58
  include ErrorChecks
59
59
  end
60
60
 
61
- attr_reader :views, :sequence
62
- attr_accessor :root, :editor, :features
63
- attr_accessor :view # overridden
61
+ attr_reader :views, :sequence
62
+ attr_accessor :root, :editor, :features
63
+ attr_accessor :view # overridden
64
64
  attr_accessor :post
65
65
 
66
66
  attr_accessor :post_views, :post_tags, :dirty_views
@@ -74,7 +74,7 @@ class RuneBlog
74
74
  teaser: "No teaser", body: "No body", tags: ["untagged"],
75
75
  views: [], back: "javascript:history.go(-1)", home: "no url")
76
76
  log!(enter: __method__, args: [num, title, date, view, teaser, body, tags, views, back, home], level: 3)
77
- viewlist = (views + [view.to_s]).join(" ")
77
+ viewlist = (views + [view.to_s]).join(" ").uniq
78
78
  taglist = ".tags " + tags.join(" ")
79
79
 
80
80
  <<~TEXT
@@ -96,9 +96,9 @@ class RuneBlog
96
96
 
97
97
  def self.create_new_blog_repo(root_rel = ".blogs")
98
98
  log!(enter: __method__, args: [root_rel])
99
+ check_error(BlogRepoAlreadyExists) { Dir.exist?(repo_root) }
99
100
  check_nonempty_string(root_rel)
100
101
  repo_root = Dir.pwd/root_rel
101
- check_error(BlogRepoAlreadyExists) { Dir.exist?(repo_root) }
102
102
 
103
103
  create_dirs(repo_root)
104
104
  Dir.chdir(repo_root) do
@@ -110,7 +110,6 @@ class RuneBlog
110
110
  unless File.exist?(repo_root/"data/VIEW")
111
111
  copy_data(repo_root/:data)
112
112
  end
113
- # copy_data(:extra, repo_root/:config)
114
113
  write_repo_config(root: repo_root)
115
114
  # Weird. Like a singleton - dumbass circular dependency?
116
115
  self.blog = blog = self.new
@@ -128,32 +127,35 @@ class RuneBlog
128
127
  _tmp_error(err)
129
128
  end
130
129
 
131
- def initialize(root_rel = ".blogs") # always assumes existing blog
132
- log!(enter: "initialize", args: [root_rel])
133
- # Weird. Like a singleton - dumbass circular dependency?
134
- self.class.blog = self
135
-
136
- @root = Dir.pwd/root_rel
137
- # write_repo_config(root: @root) # ?? FIXME
138
- get_repo_config
139
- read_features # top level
140
- @views = retrieve_views
141
- self.view = File.read(@root/"data/VIEW").chomp
142
- md = Dir.pwd.match(%r[.*/views/(.*?)/])
143
- if md
144
- @view_name = md[1]
145
- @view = str2view(@view_name)
130
+ ################
131
+
132
+ def self.read(root_rel = ".blogs") # always assumes existing blog
133
+ log!(enter: "RuneBlog.read", args: [root_rel])
134
+ instance = RuneBlog.allocate
135
+ instance.instance_eval do
136
+ @blog = instance # Duhhh
137
+ @root = Dir.pwd/root_rel
138
+ # _init_get_view ##########??????
139
+ # self.class.blog = self # Weird, like singleton. Dumbass circular dependency?
140
+ RuneBlog.blog = instance
141
+ dirs = subdirs("#@root/views/").sort
142
+ @views = dirs.map {|name| RuneBlog::View.new(name) }
143
+ @curr = str2view(File.read(@root/"data/VIEW").chomp)
144
+ @view = @curr
145
+ # ...was init_get_view
146
+ @sequence, @post_views, @post_tags = get_sequence, [], []
146
147
  end
147
- @sequence = get_sequence
148
- @post_views = []
149
- @post_tags = []
148
+ return instance
150
149
  rescue => err
151
- puts "Error - see stdout.txt"
152
- STDERR.puts err.inspect
153
- STDERR.puts err&.backtrace
150
+ puts "ERROR - #{err.inspect}"
151
+ # puts "Error - see stderr.out"
152
+ puts err.inspect + "\n" + err&.backtrace
154
153
  sleep 3
155
154
  end
156
155
 
156
+ def initialize ##### FIXME ??
157
+ end
158
+
157
159
  def complete_file(name, vars, hash)
158
160
  debugging = vars.nil?
159
161
  return if hash.empty?
@@ -270,14 +272,6 @@ class RuneBlog
270
272
  views.any? {|x| x.name == name }
271
273
  end
272
274
 
273
- # def view(name = nil)
274
- # log!(enter: __method__, args: [name], level: 3)
275
- # return @view if name.nil?
276
- #
277
- # check_nonempty_string(name)
278
- # return str2view(name)
279
- # end
280
-
281
275
  def str2view(str)
282
276
  log!(enter: __method__, args: [str], level: 3)
283
277
  check_nonempty_string(str) # redundant?
@@ -297,15 +291,12 @@ class RuneBlog
297
291
  @view = nil
298
292
  return
299
293
  end
300
- # STDERR.puts "view= #{arg.inspect}"
301
-
302
294
  case arg
303
295
  when RuneBlog::View
304
296
  @view = arg
305
297
  @view.get_globals(true)
306
298
  when String
307
299
  new_view = str2view(arg)
308
- # STDERR.puts "view= new view #{new_view.inspect}"
309
300
  check_error(NoSuchView, arg) { new_view.nil? }
310
301
  @view = new_view
311
302
  else
@@ -541,11 +532,10 @@ class RuneBlog
541
532
  next unless Dir.exist?(postdir)
542
533
  meta = nil
543
534
  Dir.chdir(postdir) { meta = read_metadata }
544
- # puts [draft, meta.views].inspect
545
535
  list << draft if meta.views.include?(self.view.to_s)
546
536
  end
547
- # list.sort
548
- curr_drafts
537
+ # curr_drafts
538
+ list.sort
549
539
  end
550
540
 
551
541
  def all_drafts
@@ -739,8 +729,7 @@ args = {cwd: pdraft, src: draft, debug: true, dst: "guts.html",
739
729
 
740
730
  def remove_post(num)
741
731
  log!(enter: __method__, args: [num], level: 1)
742
- check_integer(num)
743
- # FIXME update original draft .views
732
+ check_integer(num) # FIXME update original draft .views
744
733
  tag = prefix(num)
745
734
  files = Find.find(self.view.dir).to_a
746
735
  list = files.select {|x| File.directory?(x) and x =~ /#{tag}/ }
@@ -1,7 +1,7 @@
1
1
  if !defined?(RuneBlog::Path)
2
2
 
3
3
  class RuneBlog
4
- VERSION = "0.3.27"
4
+ VERSION = "0.3.28"
5
5
 
6
6
  path = Gem.find_files("runeblog").grep(/runeblog-/).first
7
7
  Path = File.dirname(path)
data/runeblog.gemspec CHANGED
@@ -21,7 +21,7 @@ spec = Gem::Specification.new do |s|
21
21
  s.authors = ["Hal Fulton"]
22
22
  s.email = 'rubyhacker@gmail.com'
23
23
  s.executables << "blog"
24
- s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.10'
24
+ s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.33'
25
25
  s.add_runtime_dependency 'rubytext', '~> 0.1', '>= 0.1.23'
26
26
  s.add_runtime_dependency 'rouge', '~> 3.25', '>= 3.25.0'
27
27
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runeblog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.27
4
+ version: 0.3.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hal Fulton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-17 00:00:00.000000000 Z
11
+ date: 2024-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: livetext
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '0.9'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.9.10
22
+ version: 0.9.33
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '0.9'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.9.10
32
+ version: 0.9.33
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rubytext
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +101,7 @@ files:
101
101
  - "./README.md"
102
102
  - "./runeblog.gemspec"
103
103
  - bin/blog
104
+ - bin/blog.rb
104
105
  - bin/mkwidget
105
106
  - data/EDITOR
106
107
  - data/ROOT
@@ -256,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
257
  - !ruby/object:Gem::Version
257
258
  version: '0'
258
259
  requirements: []
259
- rubygems_version: 3.1.2
260
+ rubygems_version: 3.2.3
260
261
  signing_key:
261
262
  specification_version: 4
262
263
  summary: A command-line blogging system