runeblog 0.2.49 → 0.2.54

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: 148dacf82516a20ba94f7ddf83e3160d717aacf156a88b23187bc5e891a80542
4
- data.tar.gz: 296c90e497e7efb780fb73c91caff732626bfbeb8f3400c866bdf156688ed059
3
+ metadata.gz: 6fe89e19a4aca1e7fe6d3ae97f9df2099a2b5fa71f859cf857cc7804eaf50ff2
4
+ data.tar.gz: 7a1df9174ea7d4c66c7cab14bdef90f0bcfa25ac942a8cabb7e55626a802cc90
5
5
  SHA512:
6
- metadata.gz: 58fca96171e5fd86d3c6fd207a481c6e957dcd6b777dbec7f7b9f588bed9a6a71c5ceee01ba78bffec3b4acb722df8f597dc397f1153f0517f7d5f9b205e154d
7
- data.tar.gz: 3d46a5f3720342d13e8b9d4665a40f92fb4f70418449dccbd71efdc3e2f96dc64785a6ae1b6d82adbe4022492eb23678c5aea15a4d88de900ef18cce0a9da737
6
+ metadata.gz: ab9912b9aa341458f348265ec533221945d928f4a4dc1528812e56c44eaaefc2387d82010613461b85476c81daca15bd2e12c95f650d2c140f95b8f563cc94fc
7
+ data.tar.gz: 40b9030124447ef0c6a3799bd046590d199b57130ffc8006f648685c8d90d2f986335fec2b81b44f9cb5e4bce760ad50579a8873cbea3d7d80ef6aa88c0e55d3
@@ -10,7 +10,8 @@
10
10
  .sidebar
11
11
  ad
12
12
  links
13
- news
13
+ pinned
14
14
  pages
15
+ news
15
16
  .end
16
17
 
@@ -9,7 +9,6 @@
9
9
  . --------------------------------------------------
10
10
 
11
11
  .navbar
12
- index Home
13
12
  about About
14
13
  contact Contact
15
14
  faq FAQ
@@ -12,22 +12,59 @@ class ::RuneBlog::Widget
12
12
 
13
13
  def build
14
14
  input = "list.data"
15
- lines = File.readlines(input)
16
- data = lines.map! {|x| x.chomp.split(/, */, 3) }
15
+ @lines = File.readlines(input)
16
+ write_main
17
+ write_card
18
+ end
19
+
20
+ def write_main
21
+ @data = @lines.map! {|x| x.chomp.split(/, */, 3) }
17
22
  css = "* { font-family: verdana }"
18
23
  card_title = "External Links" # FIXME
19
24
  File.open("#{Type}-main.html", "w") do |f|
20
25
  _html_body(f, css) do
21
26
  f.puts "<h1>#{card_title}</h1><br><hr>"
22
27
  url_ref = nil
23
- data.each do |url, frameable, title|
28
+ @data.each do |url, frameable, title|
24
29
  url_ref = (frameable == "yes") ? "href = '#{url}'" : _blank(url)
25
30
  css = "color: #8888FF; text-decoration: none; font-size: 21px" # ; font-family: verdana"
26
31
  f.puts %[<a style="#{css}" #{url_ref}>#{title}</a> <br>]
27
32
  end
28
33
  end
29
34
  end
30
- # remember -card also
35
+ end
36
+
37
+ def write_card
38
+ tag = "links"
39
+ url = :widgets/tag/tag+"-main.html"
40
+ card_title = "External links" # FIXME
41
+ cardfile = "#@self-card"
42
+ File.open("#{cardfile}.html", "w") do |f|
43
+ f.puts <<-EOS
44
+ <div class="card mb-3">
45
+ <div class="card-body">
46
+ <h5 class="card-title">
47
+ <button type="button" class="btn btn-primary" data-toggle="collapse" data-target="##{tag}">+</button>
48
+ <a href="javascript: void(0)"
49
+ onclick="javascript:open_main('#{url}')"
50
+ style="text-decoration: none; color: black"> #{card_title}</a>
51
+ </h5>
52
+ <div class="collapse" id="#{tag}">
53
+ EOS
54
+ @data.each do |url2, frameable, title|
55
+ main_ref = %[href="javascript: void(0)" onclick="javascript:open_main('#{url2}')"]
56
+ tab_ref = %[href="#{url2}"]
57
+ url_ref = (frameable == "yes") ? main_ref : tab_ref
58
+ anchor = %[<a #{url_ref}>#{title}</a>]
59
+ wrapper = %[<li class="list-group-item">#{anchor}</li>]
60
+ f.puts wrapper
61
+ end
62
+ f.puts <<-EOS
63
+ </div>
64
+ </div>
65
+ </div>
66
+ EOS
67
+ end
31
68
  end
32
69
 
33
70
  def edit_menu
@@ -1,9 +1,40 @@
1
1
  .mixin liveblog
2
2
 
3
+ <html>
4
+ <head>
5
+
6
+ <style>
7
+ * { font-family: verdana }
8
+ </style>
9
+
10
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
11
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"></link>
12
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap-theme.min.css"></link>
13
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
14
+
15
+ </head>
16
+
17
+ <body>
18
+
3
19
  <h2>Frequently Asked Questions</h2>
4
20
 
5
- This is
6
- just a
7
- FAAAAAQ....
21
+ .faq Are you a rabbit?
22
+ Yes, I am.
23
+ .end
24
+
25
+ .faq Are you a frog?
26
+ Don't be stupid. I just told you I was a rabbit.
27
+ .end
28
+
29
+ .faq Why do you answer a question with a question?
30
+ *Do I in fact answer a question with a question?
31
+ .end
32
+
33
+ .faq Are you serious?
34
+ No, I'm a rabbit.
35
+ .end
8
36
 
9
37
  .backlink
38
+
39
+ </body>
40
+ </html>
@@ -4,9 +4,89 @@ class ::RuneBlog::Widget
4
4
  class Pinned
5
5
  def initialize(repo)
6
6
  @blog = repo
7
+ @self = "pinned"
7
8
  end
8
9
 
10
+ def _html_body(file, css = nil) # FIXME
11
+ file.puts "<html>"
12
+ if css
13
+ file.puts " <head>"
14
+ file.puts " <style>\n#{css}\n </style>"
15
+ file.puts " </head>"
16
+ end
17
+ file.puts " <body>"
18
+ yield
19
+ file.puts " </body>\n</html>"
20
+ end
21
+
9
22
  def build
23
+ @tmp = File.new("/tmp/debug-out", "w")
24
+ posts = nil
25
+ Dir.chdir(@blog.root/:posts) { posts = Dir["*"] }
26
+ lines = File.readlines("list.data")
27
+ hash = {}
28
+ @links = []
29
+ lines.each do |x|
30
+ num, title = x.chomp.split(" ", 2)
31
+ hash[num] = title
32
+ pre = '%04d' % num
33
+ nslug = posts.grep(/#{pre}-/).first
34
+ name = nslug[5..-1]
35
+ link = name+".html"
36
+ @links << [title, link]
37
+ end
38
+ write_main
39
+ write_card
40
+ end
41
+
42
+ def write_main
43
+ tag = "pinned"
44
+ card_title = "Pinned posts" # FIXME
45
+ # setvar "card.title", card_title
46
+ css = "* { font-family: verdana }"
47
+ mainfile = "#@self-main"
48
+ File.open("#{mainfile}.html", "w") do |f|
49
+ _html_body(f, css) do
50
+ f.puts "<h1>#{card_title}</h1><br><hr>"
51
+ @links.each do |title, file|
52
+ title = title.gsub(/\\/, "") # kludge
53
+ css = "color: #8888FF; text-decoration: none; font-size: 21px"
54
+ f.puts %[<a style="#{css}" href="../../#{file}">#{title}</a> <br>]
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def write_card
61
+ tag = "pinned"
62
+ url = :widgets/tag/tag+"-main.html"
63
+ card_title = "Pinned posts" # FIXME
64
+ cardfile = "#@self-card"
65
+ File.open("#{cardfile}.html", "w") do |f|
66
+ f.puts <<-EOS
67
+ <div class="card mb-3">
68
+ <div class="card-body">
69
+ <h5 class="card-title">
70
+ <button type="button" class="btn btn-primary" data-toggle="collapse" data-target="##{tag}">+</button>
71
+ <a href="javascript: void(0)"
72
+ onclick="javascript:open_main('#{url}')"
73
+ style="text-decoration: none; color: black"> #{card_title}</a>
74
+ </h5>
75
+ <div class="collapse" id="#{tag}">
76
+ EOS
77
+ @links.each do |title, file|
78
+ url2 = file
79
+ url_ref = %[href="javascript: void(0)" onclick="javascript:open_main('#{url2}')"]
80
+ anchor = %[<a #{url_ref}>#{title}</a>]
81
+ wrapper = %[<li class="list-group-item">#{anchor}</li>]
82
+ f.puts wrapper
83
+ end
84
+ f.puts <<-EOS
85
+ </div>
86
+ </div>
87
+ </div>
88
+ EOS
89
+ end
10
90
  end
11
91
 
12
92
  def edit_menu
@@ -15,6 +15,7 @@ module RuneBlog::REPL
15
15
  "v" => :cmd_version,
16
16
  "list views" => :cmd_list_views,
17
17
  "lsv" => :cmd_list_views,
18
+ "clear" => :cmd_clear,
18
19
 
19
20
  "new view $name" => :cmd_new_view,
20
21
 
@@ -30,7 +31,9 @@ module RuneBlog::REPL
30
31
  "cv" => :cmd_change_view, # 0-arity must come second
31
32
 
32
33
  "config" => :cmd_config,
33
- "manage" => :cmd_manage,
34
+ "manage $widget" => :cmd_manage,
35
+
36
+ "legacy" => :cmd_legacy,
34
37
 
35
38
  "list posts" => :cmd_list_posts,
36
39
  "lsp" => :cmd_list_posts,
@@ -187,25 +190,6 @@ module RuneBlog::REPL
187
190
  slug[0..3] + slug[4..-1]
188
191
  end
189
192
 
190
- def import(arg = nil)
191
- raise "Not implemented at present..."
192
- arg = nil if arg == ""
193
- arg ||= ask("Filename: ") # check validity later
194
- name = arg
195
- grep = `grep ^.title #{name}`
196
- @title = grep.sub(/^.title /, "")
197
- @slug = @blog.make_slug(@title) # import (not impl)
198
- @fname = @slug + ".lt3"
199
- result = system!("cp #{name} #@root/drafts/#@fname")
200
- raise CantCopy(name, "#@root/drafts/#@fname") unless result
201
-
202
- edit_initial_post(@fname)
203
- process_post(@fname)
204
- link_post_all_views(@meta)
205
- rescue => err
206
- error(err)
207
- end
208
-
209
193
  def tags_for_view(vname = @blog.view)
210
194
  Dir.chdir(vname) do
211
195
  fname = "tagpool"
@@ -1,6 +1,7 @@
1
1
  require 'ostruct'
2
2
  require 'pp'
3
3
  require 'date'
4
+ require 'find'
4
5
 
5
6
  require 'runeblog'
6
7
  require 'pathmagic'
@@ -18,7 +19,7 @@ def init_liveblog # FIXME - a lot of this logic sucks
18
19
  @root = @blog.root
19
20
  @view = @blog.view
20
21
  @view_name = @blog.view.name unless @view.nil?
21
- @vdir = @blog.view.dir
22
+ @vdir = @blog.view.dir rescue "NONAME"
22
23
  @version = RuneBlog::VERSION
23
24
  @theme = @vdir/:themes/:standard
24
25
  end
@@ -66,13 +67,18 @@ end
66
67
 
67
68
  def faq
68
69
  @faq_count ||= 0
70
+ _out "<br>" if @faq_count == 0
69
71
  @faq_count += 1
70
72
  ques = _data.chomp
71
73
  ans = _body_text
72
74
  id = "faq#@faq_count"
73
- _out %[&nbsp;<a class="btn btn-default btn-xs" data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample">+</a>]
75
+ # _out %[&nbsp;<a class="btn btn-default btn-xs" data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample">+</a>]
76
+ _out %[&nbsp;<a data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample"><font size=+3>&#8964;</font></a>]
74
77
  _out %[&nbsp;<b>#{ques}</b>]
75
- _out %[<div class="collapse" id="#{id}"><br><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{ans}</font></div><br><br>\n]
78
+ # _out "<font size=-2><br></font>" if @faq_count == 1
79
+ # _out "<br>" unless @faq_count == 1
80
+ _out %[<div class="collapse" id="#{id}"><br><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{ans}</font></div>\n]
81
+ _out "<br>" unless @faq_count == 1
76
82
  _optional_blank_line
77
83
  end
78
84
 
@@ -90,16 +96,17 @@ def banner # still experimental
90
96
  pieces.each do |piece|
91
97
  _out " <td colspan=#{span}>"
92
98
  case
93
- when piece.start_with?("hnav")
94
- _out "<center>hnav1 hnav2 hnav3 hnav4</center>"
95
- when piece.start_with?("vnav")
96
- _out "vnav1<br>vnav2<br>vnav3<br>vnav4<br>"
99
+ when piece.start_with?("navbar")
100
+ file = "navbar/navbar.html"
101
+ _out File.read(file)
97
102
  when piece.start_with?("text")
98
103
  file = piece.split(":")[1]
104
+ file ||= "banner/text.html"
99
105
  _out File.read(file)
100
106
  when piece.start_with?("image")
101
- file = piece.split(":")[1]
102
- _out " <img src=#{file} height=100></img>"
107
+ image = piece.split(":")[1]
108
+ image ||= "banner/banner.jpg"
109
+ _out " <img src=#{image} height=100></img>"
103
110
  else
104
111
  _out " '#{piece}' isn't known"
105
112
  end
@@ -258,10 +265,30 @@ end
258
265
 
259
266
  def pin
260
267
  raise "'post' was not called" unless @meta
261
- _debug "data = #{_args}"
262
- # verify only already-specified views?
263
- @meta.pinned = _args.dup
268
+ _debug "data = #{_args}" # verify only valid views?
269
+ pinned = @_args
270
+ @meta.pinned = pinned
271
+ pinned.each do |pinview|
272
+ dir = @blog.root/:views/pinview/"themes/standard/widgets/pinned/"
273
+ datafile = dir/"list.data"
274
+ if File.exist?(datafile)
275
+ pins = File.readlines(datafile)
276
+ else
277
+ pins = []
278
+ end
279
+ pins << "#{@meta.num} #{@meta.title}\n"
280
+ pins.uniq!
281
+ outfile = File.new(datafile, "w")
282
+ pins.each do |pin|
283
+ outfile.puts pin
284
+ end
285
+ outfile.close
286
+ end
264
287
  _optional_blank_line
288
+ rescue => err
289
+ puts "err = #{err}"
290
+ puts err.backtrace.join("\n")
291
+ gets
265
292
  end
266
293
 
267
294
  def write_post
@@ -412,12 +439,16 @@ rescue => err
412
439
  end
413
440
 
414
441
  def sidebar
442
+ _debug "--- handling sidebar\r"
415
443
  if _args.include? "off"
416
444
  _body { } # iterate, do nothing
417
445
  return
418
446
  end
419
447
 
420
448
  _out %[<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12">]
449
+
450
+ standard = %w[pinned pages links]
451
+
421
452
  _body do |token|
422
453
  tag = token.chomp.strip.downcase
423
454
  wtag = :widgets/tag
@@ -426,12 +457,14 @@ def sidebar
426
457
 
427
458
  code = _load_local(tag)
428
459
  if code
429
- if ["pages", "links"].include? tag
460
+ if ["pages", "links", "pinned"].include? tag
430
461
  Dir.chdir(wtag) do
431
462
  widget = code.new(@blog)
432
463
  widget.build
433
464
  end
434
465
  end
466
+ _include_file wtag/tcard
467
+ next
435
468
  end
436
469
 
437
470
  if tag == "ad"
@@ -444,7 +477,13 @@ def sidebar
444
477
  end
445
478
  end
446
479
 
447
- xlate cwd: wtag, src: tag, dst: tcard # , debug: (tag == "ad")
480
+ depend = %w[card.css main.css custom.rb local.rb]
481
+ depend += ["#{wtag}.lt3", "#{wtag}.rb"]
482
+ depend += %w[pieces/card-head.lt3 pieces/card-tail.lt3]
483
+ depend += %w[pieces/main-head.lt3 pieces/main-tail.lt3]
484
+ depend.map! {|x| @blog.view.dir/"themes/standard/widgets"/wtag/x }
485
+ _debug "--- call xlate #{tag} src = #{tag} dst = #{tcard}\r"
486
+ xlate cwd: wtag, src: tag, dst: tcard, force: true, deps: depend # , debug: true
448
487
  _include_file wtag/tcard
449
488
  end
450
489
  _out %[</div>]
@@ -599,42 +638,53 @@ def tag_cloud
599
638
  end
600
639
 
601
640
  def vnavbar
641
+ _custom_navbar(:vert)
602
642
  end
603
643
 
604
- def navbar2
644
+ def hnavbar
645
+ _custom_navbar # horiz is default
646
+ end
647
+
648
+ def navbar
649
+ _custom_navbar # horiz is default
650
+ end
651
+
652
+ def _custom_navbar(orient = :horiz)
605
653
  vdir = @blog.view.dir
606
654
  title = _var(:blog)
607
655
 
656
+ extra = ""
657
+ extra = "navbar-expand-lg" if orient == :horiz
658
+
608
659
  open = <<-HTML
609
- <nav class="navbar navbar-light bg-light">
610
- <a class="navbar-brand" href="index.html">#{title}</a>
611
- <ul class="navbar-nav mr-auto">
660
+ <nav class="navbar #{extra} navbar-light bg-light">
661
+ <ul class="navbar-nav mr-auto">
612
662
  HTML
613
663
  close = <<-HTML
614
- </ul>
615
- </div>
664
+ </ul>
616
665
  </nav>
617
666
  HTML
618
667
 
619
- first = true
620
- _out open
668
+ html_file = @blog.root/:views/@blog.view/:themes/:standard/:navbar/"navbar.html"
669
+ output = File.new(@blog.root/:views/@blog.view/:themes/:standard/:navbar/"navbar.html", "w")
670
+ output.puts open
621
671
  lines = _body
672
+ lines = [" index Home"] + lines unless _args.include?("nohome")
622
673
  lines.each do |line|
623
674
  basename, cdata = line.chomp.strip.split(" ", 2)
624
675
  full = :navbar/basename+".html"
625
676
  href_main = _main(full)
626
- if first
627
- first = false # hardcode this part??
628
- _out %[<li class="nav-item active"> <a class="nav-link" href="index.html">#{cdata}<span class="sr-only">(current)</span></a> </li>]
677
+ if basename == "index" # special case
678
+ output.puts %[<li class="nav-item active"> <a class="nav-link" href="index.html">#{cdata}<span class="sr-only">(current)</span></a> </li>]
629
679
  else
630
680
  xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html" # , debug: true
631
- _out %[<li class="nav-item"> <a class="nav-link" #{href_main}>#{cdata}</a> </li>]
681
+ output.puts %[<li class="nav-item"> <a class="nav-link" #{href_main}>#{cdata}</a> </li>]
632
682
  end
633
683
  end
634
- _out close
684
+ output.puts close
635
685
  end
636
686
 
637
- def navbar
687
+ def _old_navbar
638
688
  vdir = @blog.view.dir
639
689
  title = _var(:blog)
640
690
 
@@ -671,7 +721,8 @@ def navbar
671
721
  first = false # hardcode this part??
672
722
  _out %[<li class="nav-item active"> <a class="nav-link" href="index.html">#{cdata}<span class="sr-only">(current)</span></a> </li>]
673
723
  else
674
- xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html" # , debug: true
724
+ depend = Find.find(@blog.root/:views/@blog.view.to_s/"themes/standard/navbar/").to_a
725
+ xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html", deps: depend # , debug: true
675
726
  _out %[<li class="nav-item"> <a class="nav-link" #{href_main}>#{cdata}</a> </li>]
676
727
  end
677
728
  end
@@ -724,7 +775,7 @@ def _write_card(cardfile, mainfile, pairs, card_title, tag)
724
775
  wrapper = %[<li class="list-group-item">#{anchor}</li>]
725
776
  f.puts wrapper
726
777
  end
727
- _include_file cardfile+".html"
778
+ _include_file cardfile+".html"
728
779
  f.puts <<-EOS
729
780
  </div>
730
781
  </div>
@@ -831,7 +882,7 @@ end
831
882
 
832
883
  def _write_metadata
833
884
  File.write("teaser.txt", @meta.teaser)
834
- fields = [:num, :title, :date, :pubdate, :views, :tags]
885
+ fields = [:num, :title, :date, :pubdate, :views, :tags, :pinned]
835
886
  fname2 = "metadata.txt"
836
887
  f2 = File.open(fname2, "w") do |f2|
837
888
  fields.each {|fld| f2.puts "#{fld}: #{@meta.send(fld)}" }
@@ -21,7 +21,8 @@ class RuneBlog::Post
21
21
  raise "Doesn't work right now"
22
22
  raise NoBlogAccessor if RuneBlog.blog.nil?
23
23
  # "post" is a slug
24
- pdir = RuneBlog.blog.view.dir/post
24
+ pdir = RuneBlog.blog.root/:drafts/post
25
+ puts "-- load: opening #{pdir}"
25
26
  meta = nil
26
27
  Dir.chdir(pdir) do
27
28
  meta = read_config("metadata.txt")
@@ -112,9 +113,76 @@ class RuneBlog::Post
112
113
  end
113
114
 
114
115
  class RuneBlog::ViewPost
115
- attr_reader :path, :nslug, :aslug, :title, :date,
116
- :teaser_text
116
+ attr_accessor :nslug, :aslug, :num, :view, :blog
117
+ attr_accessor :path, :title, :date, :teaser_text
118
+
119
+ def self.make(blog:, view:, nslug:)
120
+ raise "No numeric prefix on #{nslug}" unless nslug =~ /^\d{4}-/
121
+ raise "Not expecting an extension" if nslug.end_with?(".lt3") || nslug.end_with?(".html")
122
+ view = view.to_s
123
+ view.define_singleton_method :path do |subdir = ""|
124
+ str = blog.root/:views/view
125
+ str << "/#{subdir}" unless subdir.empty?
126
+ str
127
+ end
128
+ view.define_singleton_method :standard do |subdir = ""|
129
+ str = blog.root/:views/view/:themes/:standard
130
+ str << "/#{subdir}" unless subdir.empty?
131
+ str
132
+ end
133
+ view.define_singleton_method :postdir do |file = ""|
134
+ file = file.to_s
135
+ str = blog.root/:views/view/:posts/nslug
136
+ str = str/file unless file.empty?
137
+ str
138
+ end
139
+ view.define_singleton_method :remote do |dir: "", file: ""|
140
+ subdir = subdir.to_s
141
+ file = file.to_s
142
+ str = blog.root/:views/view/:remote
143
+ str = str/subdir unless subdir.empty?
144
+ str = str/file unless file.empty?
145
+ str
146
+ end
147
+ obj = RuneBlog::ViewPost.new(view, nslug)
148
+ obj.blog = blog
149
+ obj.view = view
150
+ obj.nslug = nslug
151
+ obj.aslug = nslug[5..-1]
152
+ obj.num = nslug[0..3]
153
+ obj
154
+ end
155
+
156
+ def repo(subdir = "")
157
+ subdir = subdir.to_s
158
+ unless subdir.empty?
159
+ raise "Expected 'posts' or 'drafts'" unless %w[posts drafts].include?(subdir)
160
+ end
161
+ str = blog.root
162
+ str = str/subdir unless subdir.empty?
163
+ str
164
+ end
165
+
166
+ alias root repo
167
+
168
+ def slug(num = true, ext = "")
169
+ ext = ext.to_s
170
+ str = ""
171
+ str << @num << "-" if num
172
+ str << @aslug
173
+ str << ext
174
+ str
175
+ end
117
176
 
177
+ =begin
178
+ aslug this-is-a-post
179
+ aslug_live this-is-a-post.lt3
180
+ aslug_html this-is-a-post.lt3
181
+ nslug 0001-this-is-a-post
182
+
183
+ slug(:num, ext = "")
184
+ =end
185
+
118
186
  def initialize(view, postdir)
119
187
  log!(enter: __method__, args: [view, postdir], level: 3)
120
188
  # Assumes already parsed/processed
@@ -122,7 +190,7 @@ class RuneBlog::ViewPost
122
190
  @path = postdir.dup
123
191
  @nslug = @path.split("/").last
124
192
  @aslug = @nslug[5..-1]
125
- fname = "#{postdir}/teaser.txt"
193
+ fname = "#{postdir}/teaser.txt" # ???
126
194
  @teaser_text = File.read(fname).chomp
127
195
  # FIXME dumb hacks...
128
196
  mdfile = postdir/"metadata.txt"
@@ -38,10 +38,10 @@ module RuneBlog::REPL
38
38
  end
39
39
 
40
40
  def cmd_config(arg, testing = false)
41
- list = ["global.lt3", "blog/generate.lt3", " head.lt3", " index.lt3",
42
- " post_entry.lt3", "etc/blog.css.lt3", " externals.lt3",
43
- "post/generate.lt3", " head.lt3", " index.lt3",
44
- " permalink.lt3"]
41
+ list = ["global.lt3", "blog/generate.lt3", ".... head.lt3", ".... index.lt3",
42
+ ".... post_entry.lt3", "etc/blog.css.lt3", "... externals.lt3",
43
+ "post/generate.lt3", ".... head.lt3", ".... index.lt3",
44
+ ".... permalink.lt3"]
45
45
  name = ["global.lt3", "blog/generate.lt3", "blog/head.lt3", "blog/index.lt3",
46
46
  "blog/post_entry.lt3", "etc/blog.css.lt3", "blog/externals.lt3",
47
47
  "post/generate.lt3", "post/head.lt3", "post/index.lt3",
@@ -53,12 +53,11 @@ module RuneBlog::REPL
53
53
  end
54
54
 
55
55
  def cmd_manage(arg, testing = false)
56
- puts "Arg = #{arg.inspect}"
57
56
  case arg
58
- when "pages"; _manage_pages(arg, testing = false)
59
- when "links"; _manage_links(arg, testing = false)
60
- when "navbar"; _manage_navbar(arg, testing = false)
61
- # when "pinned"; _manage_pinned(arg, testing = false) # ditch this??
57
+ when "pages"; _manage_pages(nil, testing = false)
58
+ when "links"; _manage_links(nil, testing = false)
59
+ when "navbar"; _manage_navbar(nil, testing = false)
60
+ # when "pinned"; _manage_pinned(nil, testing = false) # ditch this??
62
61
  else
63
62
  puts "#{arg} is unknown"
64
63
  end
@@ -72,7 +71,6 @@ puts "Arg = #{arg.inspect}"
72
71
  end
73
72
 
74
73
  def _manage_navbar(arg, testing = false) # cloned from manage_pages
75
- puts "Got to #{__method__}"
76
74
  check_empty(arg)
77
75
  dir = @blog.view.dir/"themes/standard/navbar"
78
76
  files = Dir.entries(dir) - %w[. .. navbar.lt3]
@@ -266,6 +264,10 @@ puts "Got to #{__method__}"
266
264
 
267
265
  def cmd_new_view(arg, testing = false)
268
266
  reset_output
267
+ if arg.nil?
268
+ arg = ask("\nFilename: ")
269
+ puts
270
+ end
269
271
  @blog.create_view(arg)
270
272
  edit_file(@blog.view.dir/"themes/standard/global.lt3")
271
273
  @blog.change_view(arg)
@@ -284,6 +286,10 @@ puts "Got to #{__method__}"
284
286
  def cmd_new_post(arg, testing = false)
285
287
  reset_output
286
288
  check_empty(arg)
289
+ if @blog.views.empty?
290
+ puts "\n Create a view before creating the first post!\n "
291
+ return
292
+ end
287
293
  title = ask("\nTitle: ")
288
294
  puts
289
295
  @blog.create_new_post(title)
@@ -321,7 +327,7 @@ puts "Got to #{__method__}"
321
327
  id = get_integer(arg)
322
328
  # Simplify this
323
329
  tag = "#{'%04d' % id}"
324
- files = ::Find.find(@blog.root+"/drafts").to_a
330
+ files = ::Find.find(@blog.root/:drafts).to_a
325
331
  files = files.grep(/#{tag}-.*lt3/)
326
332
  files = files.map {|f| File.basename(f) }
327
333
  if files.size > 1
@@ -338,7 +344,7 @@ puts "Got to #{__method__}"
338
344
  end
339
345
 
340
346
  file = files.first
341
- draft = "#{@blog.root}/drafts/#{file}"
347
+ draft = @blog.root/:drafts/file
342
348
  result = edit_file(draft)
343
349
  @blog.generate_post(draft)
344
350
  rescue => err
@@ -445,54 +451,91 @@ puts "Got to #{__method__}"
445
451
  @out
446
452
  end
447
453
 
454
+ def cmd_legacy(arg = nil)
455
+ # dir = ask("Dir = ")
456
+ dir = "sources/computing"
457
+ puts "Importing from: #{dir}"
458
+ files = Dir[dir/"**"]
459
+ files.each do |fname|
460
+ name = fname
461
+ cmd = "grep ^.title #{name}"
462
+ grep = `#{cmd}` # find .title
463
+ @title = grep.sub(/^.title /, "")
464
+ num = `grep ^.post #{name}`.sub(/^.post /, "").to_i
465
+ seq = @blog.get_sequence
466
+ tnum = File.basename(fname).to_i
467
+
468
+ raise "num != seq + 1" if num != seq + 1
469
+ raise "num != tnum" if num != tnum
470
+ seq = @blog.next_sequence
471
+ raise "num != seq" if num != seq
472
+
473
+ label = '%04d' % num
474
+ slug0 = @title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
475
+ @slug = "#{label}-#{slug0}"
476
+ @fname = @slug + ".lt3"
477
+ cmd = "cp #{name} #{@blog.root}/drafts/#@fname"
478
+ result = system!(cmd)
479
+ raise CantCopy(name, "#{@blog.root}/drafts/#@fname") unless result
480
+ # post = Post.load(@slug)
481
+ draft = "#{@blog.root}/drafts/#@fname"
482
+ @meta = @blog.generate_post(draft)
483
+ puts
484
+ sleep 2
485
+ end
486
+ rescue => err
487
+ error(err)
488
+ end
489
+
490
+ Help = <<-EOS
491
+
492
+ {Basics:} {Views:}
493
+ ------------------------------------------- -------------------------------------------
494
+ {h, help} This message {change view VIEW} Change current view
495
+ {q, quit} Exit the program {cv VIEW} Change current view
496
+ {v, version} Print version information {new view} Create a new view
497
+ {clear} Clear screen {list views} List all views available
498
+ {lsv} Same as: list views
499
+
500
+
501
+ {Posts:} {Advanced:}
502
+ ------------------------------------------- -------------------------------------------
503
+ {p, post} Create a new post {config} Edit various system files
504
+ {new post} Same as p, post {customize} (BUGGY) Change set of tags, extra views
505
+ {lsp, list posts} List posts in current view {preview} Look at current (local) view in browser
506
+ {lsd, list drafts} List all drafts (all views) {browse} Look at current (published) view in browser
507
+ {delete ID [ID...]} Remove multiple posts {rebuild} Regenerate all posts and relink
508
+ {undelete ID} Undelete a post {publish} Publish (current view)
509
+ {edit ID} Edit a post {ssh} Login to remote server
510
+ {import ASSETS} Import assets (images, etc.) {manage WIDGET} Manage content/layout of a widget
511
+ EOS
512
+
448
513
  def cmd_help(arg, testing = false)
449
514
  reset_output
450
515
  check_empty(arg)
451
- msg = <<-EOS
452
-
453
- Commands:
454
-
455
- h, help This message
456
- q, quit Exit the program
457
- v, version Print version information
458
-
459
- change view VIEW Change current view
460
- cv VIEW Change current view
461
-
462
- new view Create a new view
463
-
464
- list views List all views available
465
- lsv Same as: list views
466
-
467
- config Edit various system files
468
- * customize (BUGGY) Change set of tags, extra views
469
-
470
- p, post Create a new post
471
- new post Same as post (create a post)
472
-
473
- * import ASSETS Import assets (images, etc.)
474
-
475
- lsp, list posts List posts in current view
476
-
477
- lsd, list drafts List all posts regardless of view
478
-
479
- delete ID [ID...] Remove multiple posts
480
- undelete ID Undelete a post
481
- edit ID Edit a post
482
-
483
- preview Look at current (local) view in browser
484
- browse Look at current (published) view in browser
485
- rebuild Regenerate all posts and relink
486
- publish Publish (current view)
487
- ssh Login to remote server
488
- EOS
516
+ msg = Help
489
517
  output msg
490
518
  msg.each_line do |line|
491
- next if testing
492
- line.chomp!
493
- s1, s2 = line[0..22], line[23..-1]
494
- print fx(s1, :bold)
495
- puts s2
519
+ e = line.each_char
520
+ first = true
521
+ loop do
522
+ s1 = ""
523
+ c = e.next
524
+ if c == "{"
525
+ s2 = first ? "" : " "
526
+ first = false
527
+ loop do
528
+ c = e.next
529
+ break if c == "}"
530
+ s2 << c
531
+ end
532
+ print fx(s2, :bold)
533
+ s2 = ""
534
+ else
535
+ s1 << c
536
+ end
537
+ print s1
538
+ end
496
539
  end
497
540
  puts unless testing
498
541
  @out
@@ -1,5 +1,6 @@
1
1
  require 'date'
2
2
  require 'find'
3
+ require 'ostruct'
3
4
 
4
5
  require 'logging'
5
6
 
@@ -116,7 +117,13 @@ class RuneBlog
116
117
  log!(enter: __method__, args: [dir], level: 1)
117
118
  Dir.chdir(dir) do
118
119
  views = _retrieve_metadata(:views)
119
- views.each {|v| system!("cp *html #@root/views/#{v}/remote") }
120
+ views.each do |v|
121
+ unless self.view?(v)
122
+ puts "#{fx("Warning:", :red)} #{fx(v, :bold)} is not a view"
123
+ next
124
+ end
125
+ system!("cp *html #@root/views/#{v}/remote", show: true)
126
+ end
120
127
  end
121
128
  rescue => err
122
129
  _tmp_error(err)
@@ -148,11 +155,12 @@ class RuneBlog
148
155
  end
149
156
 
150
157
  def process_post(sourcefile)
151
- log!(enter: __method__, args: [dir], level: 2)
158
+ log!(enter: __method__, args: [sourcefile], level: 2)
152
159
  nslug = sourcefile.sub(/.lt3/, "")
153
160
  dir = @root/:posts/nslug
154
- create_dir(dir)
155
- xlate cwd: dir, src: sourcefile # , debug: true
161
+ create_dirs(dir)
162
+ # FIXME dependencies?
163
+ xlate cwd: dir, src: @root/:drafts/sourcefile # , debug: true
156
164
  _deploy_local(dir)
157
165
  rescue => err
158
166
  _tmp_error(err)
@@ -323,14 +331,14 @@ class RuneBlog
323
331
  text = nil
324
332
  @theme = @view.dir/"themes/standard"
325
333
  post_entry_name = @theme/"blog/post_entry.lt3"
326
- xlate src: post_entry_name, dst: "/tmp/post_entry.html" # , debug: true
334
+ depend = [post_entry_name]
335
+ xlate src: post_entry_name, dst: "/tmp/post_entry.html", deps: depend # , debug: true
327
336
  @_post_entry ||= File.read("/tmp/post_entry.html")
328
337
  vp = post_lookup(id)
329
338
  nslug, aslug, title, date, teaser_text =
330
339
  vp.nslug, vp.aslug, vp.title, vp.date, vp.teaser_text
331
340
  path = vp.path
332
341
  url = aslug + ".html"
333
- # puts "--- vp = #{[vp.nslug, vp.aslug, vp.title, vp.date, vp.teaser_text].inspect}"; gets
334
342
  date = ::Date.parse(date)
335
343
  date = date.strftime("%B %e<br><div style='float: right'>%Y</div>")
336
344
  text = interpolate(@_post_entry, binding)
@@ -379,7 +387,7 @@ class RuneBlog
379
387
  meta = nil
380
388
  views = views + [self.view.to_s]
381
389
  views.uniq!
382
- Dir.chdir(@root/:posts) do
390
+ Dir.chdir(@root/"posts") do
383
391
  post = Post.create(title: title, teaser: teaser, body: body, pubdate: pubdate, views: views)
384
392
  post.edit unless testing
385
393
  post.build
@@ -390,15 +398,7 @@ class RuneBlog
390
398
  _tmp_error(err)
391
399
  end
392
400
 
393
- def edit_initial_post(file, testing = false)
394
- log!(enter: __method__, args: [file, testing], level: 3)
395
- debug "=== edit_initial_post #{file.inspect} => #{sourcefile}"
396
- result = system!("#@editor #{sourcefile} +8") unless testing
397
- raise EditorProblem(sourcefile) unless result
398
- process_post(sourcefile)
399
- nil
400
- rescue => err
401
- error(err)
401
+ def import_legacy_post(file, oldfile, testing = false)
402
402
  end
403
403
 
404
404
  def posts
@@ -436,11 +436,15 @@ class RuneBlog
436
436
  log!(enter: __method__, args: [view])
437
437
  vdir = @root/:views/view
438
438
  @theme = @root/:views/view/:themes/:standard
439
- xlate cwd: vdir/"themes/standard/etc",
439
+ depend = [vdir/"remote/etc/blog.css", @theme/"global.lt3",
440
+ @theme/"blog/head.lt3", @theme/"navbar/navbar.lt3",
441
+ @theme/"blog/index.lt3"] # FIXME what about assets?
442
+ xlate cwd: vdir/"themes/standard/etc", deps: depend,
440
443
  src: "blog.css.lt3", copy: vdir/"remote/etc/blog.css" # , debug: true
441
- xlate cwd: vdir/"themes/standard", force: true,
444
+ xlate cwd: vdir/"themes/standard", deps: depend, force: true,
442
445
  src: "blog/generate.lt3", dst: vdir/:remote/"index.html"
443
446
  copy("#{vdir}/assets/*", "#{vdir}/remote/assets/")
447
+ copy_widget_html(view)
444
448
  rescue => err
445
449
  _tmp_error(err)
446
450
  end
@@ -543,7 +547,8 @@ class RuneBlog
543
547
  @theme = @root/:views/view_name/:themes/:standard
544
548
  # Step 1...
545
549
  create_dirs(pdraft)
546
- xlate cwd: pdraft, src: draft, dst: "guts.html", debug: true
550
+ # FIXME dependencies?
551
+ xlate cwd: pdraft, src: draft, dst: "guts.html" # , debug: true
547
552
  _post_metadata(draft, pdraft)
548
553
  # Step 2...
549
554
  vposts = @root/:views/view_name/:posts
@@ -552,8 +557,10 @@ class RuneBlog
552
557
  copy(pdraft/"guts.html", @theme/:post)
553
558
  copy(pdraft/"vars.lt3", @theme/:post)
554
559
  # Step 4...
560
+ # FIXME dependencies?
555
561
  xlate cwd: @theme/:post, src: "generate.lt3", force: true,
556
- dst: remote/ahtml, copy: @theme/:post, debug: true
562
+ dst: remote/ahtml, copy: @theme/:post # , debug: true
563
+ # FIXME dependencies?
557
564
  xlate cwd: @theme/:post, src: "permalink.lt3",
558
565
  dst: remote/:permalink/ahtml # , debug: true
559
566
  copy_widget_html(view_name)
@@ -564,7 +571,13 @@ class RuneBlog
564
571
  def generate_post(draft)
565
572
  log!(enter: __method__, args: [draft], level: 1)
566
573
  views = _get_views(draft)
567
- views.each {|view| _handle_post(draft, view) }
574
+ views.each do |view|
575
+ unless self.view?(view)
576
+ puts "Warning: '#{view}' is not a view"
577
+ next
578
+ end
579
+ _handle_post(draft, view)
580
+ end
568
581
  rescue => err
569
582
  _tmp_error(err)
570
583
  end
@@ -2,7 +2,7 @@
2
2
  if ! (Object.constants.include?(:RuneBlog) && RuneBlog.constants.include?(:Path))
3
3
 
4
4
  class RuneBlog
5
- VERSION = "0.2.49"
5
+ VERSION = "0.2.54"
6
6
 
7
7
  path = Gem.find_files("runeblog").grep(/runeblog-/).first
8
8
  Path = File.dirname(path)
@@ -1,36 +1,41 @@
1
1
 
2
2
  LEXT = ".lt3"
3
3
 
4
- def stale?(src, dst, force = false)
4
+ def newer?(f1, f2)
5
+ File.mtime(f1) > File.mtime(f2)
6
+ end
7
+
8
+ def stale?(src, dst, deps, force = false)
5
9
  meh = File.new("/tmp/dammit-#{src.gsub(/\//, "-")}", "w")
6
10
  log!(enter: __method__, args: [src, dst], level: 3)
7
11
  raise "Source #{src} not found in #{Dir.pwd}" unless File.exist?(src)
8
12
  return true if force
9
13
  return true unless File.exist?(dst)
10
- return true if File.mtime(src) > File.mtime(dst)
14
+ return true if newer?(src, dst)
15
+ deps.each {|dep| return true if newer?(dep, dst) }
11
16
  return false
12
17
  end
13
18
 
14
19
  def xlate(cwd: Dir.pwd, src:,
15
- dst: (strip = true; src.sub(/.lt3$/,"")),
16
- copy: nil, debug: false, force: false)
20
+ dst: (strip = true; File.basename(src).sub(/.lt3$/,"")),
21
+ deps: [], copy: nil, debug: false, force: false)
17
22
  src += LEXT unless src.end_with?(LEXT)
18
- dst += ".html" unless dst.end_with?(".html") || strip
23
+ dst += ".html" unless (dst.end_with?(".html")) # || strip)
19
24
  indent = " "*12
20
25
  Dir.chdir(cwd) do
21
26
  if debug
22
- STDERR.puts "#{indent} -- xlate #{src} >#{dst}"
23
- STDERR.puts "#{indent} in: #{Dir.pwd}"
24
- STDERR.puts "#{indent} from: #{caller[0]}"
25
- STDERR.puts "#{indent} copy: #{copy}" if copy
27
+ puts "#{indent} -- xlate #{src} >#{dst}"
28
+ puts "#{indent} in: #{Dir.pwd}"
29
+ puts "#{indent} from: #{caller[0]}"
30
+ puts "#{indent} copy: #{copy}" if copy
26
31
  end
27
- stale = stale?(src, dst, force)
32
+ stale = stale?(src, dst, deps, force)
28
33
  if stale
29
34
  rc = system("livetext #{src} >#{dst}")
30
- STDERR.puts "...completed (shell returned #{rc})" if debug
35
+ puts "...completed (shell returned #{rc})" if debug
31
36
  system!("cp #{dst} #{copy}") if copy
32
37
  else
33
- STDERR.puts "#{indent} -- ^ Already up to date!" if debug
38
+ puts "#{indent} -- ^ Already up to date!" if debug
34
39
  return
35
40
  end
36
41
  end
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.2.49
4
+ version: 0.2.54
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hal Fulton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-21 00:00:00.000000000 Z
11
+ date: 2019-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: livetext