runeblog 0.3.27 → 0.3.28

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 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