runeblog 0.2.48 → 0.2.53

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: d4bd7b67f736b85651eb0650c5af974cbcf74fce48be345920e9bac4c9dba9dd
4
- data.tar.gz: 5fda0c05a32e16103e7f7f31b7ffe104c307b63c2e14e96216644dfbc6fdefff
3
+ metadata.gz: 1c84711a690b4971d21429ef66c4db28266d341b114bf509d4960567bee4cf8e
4
+ data.tar.gz: c3b4d53efe40ba4dfe0e662b20d4bba52d965b11c42f9f580c2063ca92f50aa3
5
5
  SHA512:
6
- metadata.gz: 55b9141f9b2d0d7a06cb5134d1e1da871cd78c2dffa7502310d0ae0caedec7c27eabfa28dc7957754f611122283abc2bc833512e58f9414a541b87d8cf4e146f
7
- data.tar.gz: 60b1546750066d75a623a3ca7866b5f5307b31e14a806a85f726fe87507ab1c3d24c5ce7737742ffdb3e41fb7cbcb0eac244089c9f96efddc6534299e9ab9ef1
6
+ metadata.gz: c883e358c02c48d38fb8dc647e6d70639d9f9fcc5362da5d672cb991a176c80cb1539bb41c839ce7894a438132e61e2ad50f2025c084dee3251329c6ad218676
7
+ data.tar.gz: 98e87ccae2538738ea5b43c0d1d8afbbd9069c8dea0502d24687b9a73b59f6da3ebb86878a1b86b07ba40b4fd921e9b816c2627dad2a140877ba0396ee5824f2
@@ -0,0 +1,18 @@
1
+ . --------------------------------------------------
2
+ . This is a sample file typical of page referenced
3
+ . directly from the navigation bar.
4
+ . It is like a special case of a page in the "pages"
5
+ . widget.
6
+ . --------------------------------------------------
7
+
8
+ .set this.title="About me"
9
+ . make this better later
10
+ <html><body>
11
+ <div class="content container-fluid mt-4">
12
+ <div class="row">
13
+ <h1>$this.title</h1>
14
+ . content starts here...
15
+ Blah blah blah...
16
+ </div>
17
+ </div>
18
+ </body></html>
@@ -0,0 +1,18 @@
1
+ . --------------------------------------------------
2
+ . This is a sample file typical of page referenced
3
+ . directly from the navigation bar.
4
+ . It is like a special case of a page in the "pages"
5
+ . widget.
6
+ . --------------------------------------------------
7
+
8
+ .set this.title="Contact"
9
+ . make this better later
10
+ <html><body>
11
+ <div class="content container-fluid mt-4">
12
+ <div class="row">
13
+ <h1>$this.title</h1>
14
+ . content starts here...
15
+ How to contact me by email, smoke signals, ICBM, seance, ...
16
+ </div>
17
+ </div>
18
+ </body></html>
@@ -0,0 +1 @@
1
+ .include ../widgets/pages/faq.lt3
@@ -0,0 +1,17 @@
1
+ . --------------------------------------------------
2
+ . This defines the content of the navigation bar.
3
+ . The first one is a special case.
4
+ . The others are understood to refer to .lt3 files
5
+ . such as navbar/about.lt3 (which is processed into
6
+ . HTML).
7
+ . The title may be more than one word. Quotes are
8
+ . not needed.
9
+ . --------------------------------------------------
10
+
11
+ .navbar2
12
+ index Home
13
+ about About
14
+ contact Contact
15
+ faq FAQ
16
+ .end
17
+
@@ -8,7 +8,7 @@
8
8
  . not needed.
9
9
  . --------------------------------------------------
10
10
 
11
- .navbar
11
+ .navbar2
12
12
  index Home
13
13
  about About
14
14
  contact Contact
@@ -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>
@@ -30,6 +30,9 @@ module RuneBlog::REPL
30
30
  "cv" => :cmd_change_view, # 0-arity must come second
31
31
 
32
32
  "config" => :cmd_config,
33
+ "manage $widget" => :cmd_manage,
34
+
35
+ "legacy" => :cmd_legacy,
33
36
 
34
37
  "list posts" => :cmd_list_posts,
35
38
  "lsp" => :cmd_list_posts,
@@ -186,25 +189,6 @@ module RuneBlog::REPL
186
189
  slug[0..3] + slug[4..-1]
187
190
  end
188
191
 
189
- def import(arg = nil)
190
- raise "Not implemented at present..."
191
- arg = nil if arg == ""
192
- arg ||= ask("Filename: ") # check validity later
193
- name = arg
194
- grep = `grep ^.title #{name}`
195
- @title = grep.sub(/^.title /, "")
196
- @slug = @blog.make_slug(@title) # import (not impl)
197
- @fname = @slug + ".lt3"
198
- result = system!("cp #{name} #@root/drafts/#@fname")
199
- raise CantCopy(name, "#@root/drafts/#@fname") unless result
200
-
201
- edit_initial_post(@fname)
202
- process_post(@fname)
203
- link_post_all_views(@meta)
204
- rescue => err
205
- error(err)
206
- end
207
-
208
192
  def tags_for_view(vname = @blog.view)
209
193
  Dir.chdir(vname) do
210
194
  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'
@@ -64,10 +65,61 @@ def post_trailer
64
65
  # damned syntax highlighting
65
66
  end
66
67
 
68
+ def faq
69
+ @faq_count ||= 0
70
+ _out "<br>" if @faq_count == 0
71
+ @faq_count += 1
72
+ ques = _data.chomp
73
+ ans = _body_text
74
+ id = "faq#@faq_count"
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>]
77
+ _out %[&nbsp;<b>#{ques}</b>]
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
82
+ _optional_blank_line
83
+ end
84
+
67
85
  def backlink
68
86
  _out %[<br><a href="javascript:history.go(-1)">[Back]</a>]
69
87
  end
70
88
 
89
+ def banner # still experimental
90
+ _out "<table>"
91
+ _body do |line|
92
+ pieces = line.split
93
+ cols = pieces.size
94
+ span = cols == 2 ? 1 : 2 # whaaat?
95
+ _out " <tr>"
96
+ pieces.each do |piece|
97
+ _out " <td colspan=#{span}>"
98
+ case
99
+ when piece.start_with?("hnav")
100
+ # horizontal navbar
101
+ # _out "<center>hnav1 hnav2 hnav3 hnav4</center>"
102
+ when piece.start_with?("vnav")
103
+ # vertical navbar
104
+ # _out "vnav1<br>vnav2<br>vnav3<br>vnav4<br>"
105
+ when piece.start_with?("text")
106
+ file = piece.split(":")[1]
107
+ file ||= "banner/text.html"
108
+ _out File.read(file)
109
+ when piece.start_with?("image")
110
+ image = piece.split(":")[1]
111
+ image ||= "banner/banner.jpg"
112
+ _out " <img src=#{image} height=100></img>"
113
+ else
114
+ _out " '#{piece}' isn't known"
115
+ end
116
+ _out " </td>"
117
+ end
118
+ _out " </tr>"
119
+ end
120
+ _out "</table>"
121
+ end
122
+
71
123
  def quote
72
124
  _passthru "<blockquote>"
73
125
  _passthru _body.join(" ")
@@ -219,6 +271,18 @@ def pin
219
271
  _debug "data = #{_args}"
220
272
  # verify only already-specified views?
221
273
  @meta.pinned = _args.dup
274
+ dir = @blog.view.dir/"themes/standard/widgets/pinned/"
275
+ datafile = dir/"list.data"
276
+ pins = File.readlines(datafile) rescue []
277
+ damn = File.new("/tmp/dammit", "w")
278
+ pins << "#{@meta.num} #{@meta.title}\n"
279
+ damn.puts pins
280
+ pins.uniq!
281
+ damn.puts pins
282
+ damn.close
283
+ File.open(datafile, "w") do
284
+ pins.each {|pin| File.puts pin }
285
+ end
222
286
  _optional_blank_line
223
287
  end
224
288
 
@@ -402,7 +466,12 @@ def sidebar
402
466
  end
403
467
  end
404
468
 
405
- xlate cwd: wtag, src: tag, dst: tcard # , debug: (tag == "ad")
469
+ depend = %w[card.css main.css custom.rb local.rb]
470
+ depend += ["#{wtag}.lt3", "#{wtag}.rb"]
471
+ depend += %w[pieces/card-head.lt3 pieces/card-tail.lt3]
472
+ depend += %w[pieces/main-head.lt3 pieces/main-tail.lt3]
473
+ depend.map! {|x| @blog.view.dir/"themes/standard/widgets"/wtag/x }
474
+ xlate cwd: wtag, src: tag, dst: tcard, force: true, deps: depend , debug: (tag == "ad")
406
475
  _include_file wtag/tcard
407
476
  end
408
477
  _out %[</div>]
@@ -412,6 +481,26 @@ rescue => err
412
481
  exit
413
482
  end
414
483
 
484
+ =begin
485
+ ets/widgets/pages//card.css
486
+ ets/widgets/pages//custom.rb
487
+ ets/widgets/pages//disclaim.lt3
488
+ ets/widgets/pages//faq.lt3
489
+ ets/widgets/pages//like-dislike.lt3
490
+ ets/widgets/pages//list.data
491
+ ets/widgets/pages//local-vars.lt3
492
+ ets/widgets/pages//local.rb
493
+ ets/widgets/pages//main.css
494
+ ets/widgets/pages//other-stuff.lt3
495
+ ets/widgets/pages//pages.lt3
496
+ ets/widgets/pages//pages.rb
497
+ ets/widgets/pages//pieces
498
+ ets/widgets/pages//pieces/card-head.lt3
499
+ ets/widgets/pages//pieces/card-tail.lt3
500
+ ets/widgets/pages//pieces/main-head.lt3
501
+ ets/widgets/pages//pieces/main-tail.lt3
502
+ =end
503
+
415
504
  def stylesheet
416
505
  lines = _body
417
506
  url = lines[0]
@@ -556,6 +645,42 @@ def tag_cloud
556
645
  _out close
557
646
  end
558
647
 
648
+ def vnavbar
649
+ end
650
+
651
+ def navbar2
652
+ vdir = @blog.view.dir
653
+ title = _var(:blog)
654
+
655
+ open = <<-HTML
656
+ <nav class="navbar navbar-light bg-light">
657
+ <a class="navbar-brand" href="index.html">#{title}</a>
658
+ <ul class="navbar-nav mr-auto">
659
+ HTML
660
+ close = <<-HTML
661
+ </ul>
662
+ </div>
663
+ </nav>
664
+ HTML
665
+
666
+ first = true
667
+ _out open
668
+ lines = _body
669
+ lines.each do |line|
670
+ basename, cdata = line.chomp.strip.split(" ", 2)
671
+ full = :navbar/basename+".html"
672
+ href_main = _main(full)
673
+ if first
674
+ first = false # hardcode this part??
675
+ _out %[<li class="nav-item active"> <a class="nav-link" href="index.html">#{cdata}<span class="sr-only">(current)</span></a> </li>]
676
+ else
677
+ xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html" # , debug: true
678
+ _out %[<li class="nav-item"> <a class="nav-link" #{href_main}>#{cdata}</a> </li>]
679
+ end
680
+ end
681
+ _out close
682
+ end
683
+
559
684
  def navbar
560
685
  vdir = @blog.view.dir
561
686
  title = _var(:blog)
@@ -593,7 +718,8 @@ def navbar
593
718
  first = false # hardcode this part??
594
719
  _out %[<li class="nav-item active"> <a class="nav-link" href="index.html">#{cdata}<span class="sr-only">(current)</span></a> </li>]
595
720
  else
596
- xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html" # , debug: true
721
+ depend = Find.find(@blog.root/:views/@blog.view.to_s/"themes/standard/navbar/").to_a
722
+ xlate cwd: "navbar", src: basename, dst: vdir/"remote/navbar"/basename+".html", deps: depend # , debug: true
597
723
  _out %[<li class="nav-item"> <a class="nav-link" #{href_main}>#{cdata}</a> </li>]
598
724
  end
599
725
  end
@@ -753,7 +879,7 @@ end
753
879
 
754
880
  def _write_metadata
755
881
  File.write("teaser.txt", @meta.teaser)
756
- fields = [:num, :title, :date, :pubdate, :views, :tags]
882
+ fields = [:num, :title, :date, :pubdate, :views, :tags, :pinned]
757
883
  fname2 = "metadata.txt"
758
884
  f2 = File.open(fname2, "w") do |f2|
759
885
  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"
@@ -37,7 +37,77 @@ module RuneBlog::REPL
37
37
  @out
38
38
  end
39
39
 
40
- def cmd_pages(arg, testing = false)
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"]
45
+ name = ["global.lt3", "blog/generate.lt3", "blog/head.lt3", "blog/index.lt3",
46
+ "blog/post_entry.lt3", "etc/blog.css.lt3", "blog/externals.lt3",
47
+ "post/generate.lt3", "post/head.lt3", "post/index.lt3",
48
+ "post/permalink.lt3"]
49
+ dir = @blog.view.dir/"themes/standard/"
50
+ num, str = STDSCR.menu(title: "Edit file:", items: list)
51
+ target = name[num]
52
+ edit_file(dir/target)
53
+ end
54
+
55
+ def cmd_manage(arg, testing = false)
56
+ case arg
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??
61
+ else
62
+ puts "#{arg} is unknown"
63
+ end
64
+ end
65
+
66
+ def _manage_pinned(arg, testing = false) # cloned from manage_links
67
+ check_empty(arg)
68
+ dir = @blog.view.dir/"themes/standard/widgets/pinned"
69
+ data = dir/"list.data"
70
+ edit_file(data)
71
+ end
72
+
73
+ def _manage_navbar(arg, testing = false) # cloned from manage_pages
74
+ puts "Got to #{__method__}"
75
+ check_empty(arg)
76
+ dir = @blog.view.dir/"themes/standard/navbar"
77
+ files = Dir.entries(dir) - %w[. .. navbar.lt3]
78
+ new_item = " [New item] "
79
+ main_file = "[ navbar.lt3 ]"
80
+ files = [main_file] + files + [new_item]
81
+ num, fname = STDSCR.menu(title: "Edit navbar:", items: files)
82
+ return if fname.nil?
83
+ case fname
84
+ when new_item
85
+ print "Page title: "
86
+ title = RubyText.gets
87
+ title.chomp!
88
+ print "File name (.lt3): "
89
+ fname = RubyText.gets
90
+ fname << ".lt3" unless fname.end_with?(".lt3")
91
+ new_file = dir/fname
92
+ File.open(new_file, "w") do |f|
93
+ f.puts "<h1>#{title}</h1>\n\n\n "
94
+ f.puts ".backlink"
95
+ end
96
+ edit_file(new_file)
97
+ when main_file
98
+ edit_file(main_file[2..-3])
99
+ else
100
+ edit_file(dir/fname)
101
+ end
102
+ end
103
+
104
+ def _manage_links(arg, testing = false)
105
+ dir = @blog.view.dir/"themes/standard/widgets/links"
106
+ data = dir/"list.data"
107
+ edit_file(data)
108
+ end
109
+
110
+ def _manage_pages(arg, testing = false)
41
111
  check_empty(arg)
42
112
  dir = @blog.view.dir/"themes/standard/widgets/pages"
43
113
  # Assume child files already generated (and list.data??)
@@ -195,6 +265,10 @@ module RuneBlog::REPL
195
265
 
196
266
  def cmd_new_view(arg, testing = false)
197
267
  reset_output
268
+ if arg.nil?
269
+ arg = ask("\nFilename: ")
270
+ puts
271
+ end
198
272
  @blog.create_view(arg)
199
273
  edit_file(@blog.view.dir/"themes/standard/global.lt3")
200
274
  @blog.change_view(arg)
@@ -213,6 +287,10 @@ module RuneBlog::REPL
213
287
  def cmd_new_post(arg, testing = false)
214
288
  reset_output
215
289
  check_empty(arg)
290
+ if @blog.views.empty?
291
+ puts "\n Create a view before creating the first post!\n "
292
+ return
293
+ end
216
294
  title = ask("\nTitle: ")
217
295
  puts
218
296
  @blog.create_new_post(title)
@@ -267,7 +345,7 @@ module RuneBlog::REPL
267
345
  end
268
346
 
269
347
  file = files.first
270
- draft = "#{@blog.root}/drafts/#{file}"
348
+ draft = "#{file}" # FIXME ?
271
349
  result = edit_file(draft)
272
350
  @blog.generate_post(draft)
273
351
  rescue => err
@@ -374,54 +452,94 @@ module RuneBlog::REPL
374
452
  @out
375
453
  end
376
454
 
455
+ def cmd_legacy(arg = nil)
456
+ # dir = ask("Dir = ")
457
+ dir = "sources/computing"
458
+ puts "Importing from: #{dir}"
459
+ files = Dir[dir/"**"]
460
+ files.each do |fname|
461
+ name = fname
462
+ cmd = "grep ^.title #{name}"
463
+ grep = `#{cmd}` # find .title
464
+ @title = grep.sub(/^.title /, "")
465
+ num = `grep ^.post #{name}`.sub(/^.post /, "").to_i
466
+ seq = @blog.get_sequence
467
+ tnum = File.basename(fname).to_i
468
+
469
+ raise "num != seq + 1" if num != seq + 1
470
+ raise "num != tnum" if num != tnum
471
+ seq = @blog.next_sequence
472
+ raise "num != seq" if num != seq
473
+
474
+ label = '%04d' % num
475
+ slug0 = @title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
476
+ @slug = "#{label}-#{slug0}"
477
+ @fname = @slug + ".lt3"
478
+ cmd = "cp #{name} #{@blog.root}/drafts/#@fname"
479
+ result = system!(cmd)
480
+ raise CantCopy(name, "#{@blog.root}/drafts/#@fname") unless result
481
+ puts(`ls -l #{@blog.root}/drafts`)
482
+ puts "@fname = #@fname"
483
+ puts "Pause..."
484
+ gets
485
+ # post = Post.load(@slug)
486
+ draft = "#{@blog.root}/drafts/#@fname"
487
+ @meta = @blog.generate_post(draft)
488
+ puts
489
+ sleep 2
490
+ end
491
+ rescue => err
492
+ error(err)
493
+ end
494
+
495
+ Help = <<-EOS
496
+
497
+ {Basics:} {Views:}
498
+ ------------------------------------------- -------------------------------------------
499
+ {h, help} This message {change view VIEW} Change current view
500
+ {q, quit} Exit the program {cv VIEW} Change current view
501
+ {v, version} Print version information {new view} Create a new view
502
+ {list views} List all views available
503
+ {lsv} Same as: list views
504
+
505
+ {Posts:} {Advanced:}
506
+ ------------------------------------------- -------------------------------------------
507
+ {p, post} Create a new post {config} Edit various system files
508
+ {new post} Same as p, post {customize} (BUGGY) Change set of tags, extra views
509
+ {lsp, list posts} List posts in current view {preview} Look at current (local) view in browser
510
+ {lsd, list drafts} List all drafts (all views) {browse} Look at current (published) view in browser
511
+ {delete ID [ID...]} Remove multiple posts {rebuild} Regenerate all posts and relink
512
+ {undelete ID} Undelete a post {publish} Publish (current view)
513
+ {edit ID} Edit a post {ssh} Login to remote server
514
+ {import ASSETS} Import assets (images, etc.) {manage WIDGET} Manage content/layout of a widget
515
+ EOS
516
+
377
517
  def cmd_help(arg, testing = false)
378
518
  reset_output
379
519
  check_empty(arg)
380
- msg = <<-EOS
381
-
382
- Commands:
383
-
384
- h, help This message
385
- q, quit Exit the program
386
- v, version Print version information
387
-
388
- change view VIEW Change current view
389
- cv VIEW Change current view
390
-
391
- new view Create a new view
392
-
393
- list views List all views available
394
- lsv Same as: list views
395
-
396
- * config Edit the publish file or the templates
397
- * customize (BUGGY) Change set of tags, extra views
398
-
399
- p, post Create a new post
400
- new post Same as post (create a post)
401
-
402
- * import ASSETS Import assets (images, etc.)
403
-
404
- lsp, list posts List posts in current view
405
-
406
- lsd, list drafts List all posts regardless of view
407
-
408
- delete ID [ID...] Remove multiple posts
409
- undelete ID Undelete a post
410
- edit ID Edit a post
411
-
412
- preview Look at current (local) view in browser
413
- browse Look at current (published) view in browser
414
- rebuild Regenerate all posts and relink
415
- publish Publish (current view)
416
- ssh Login to remote server
417
- EOS
520
+ msg = Help
418
521
  output msg
419
522
  msg.each_line do |line|
420
- next if testing
421
- line.chomp!
422
- s1, s2 = line[0..22], line[23..-1]
423
- print fx(s1, :bold)
424
- puts s2
523
+ e = line.each_char
524
+ first = true
525
+ loop do
526
+ s1 = ""
527
+ c = e.next
528
+ if c == "{"
529
+ s2 = first ? "" : " "
530
+ first = false
531
+ loop do
532
+ c = e.next
533
+ break if c == "}"
534
+ s2 << c
535
+ end
536
+ print fx(s2, :bold)
537
+ s2 = ""
538
+ else
539
+ s1 << c
540
+ end
541
+ print s1
542
+ end
425
543
  end
426
544
  puts unless testing
427
545
  @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,16 @@ 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
+ puts "VIEW = #{v} dir = #{dir}"
122
+ unless self.view?(v)
123
+ puts "#{fx("Warning:", :red)} #{fx(v, :bold)} is not a view"
124
+ next
125
+ end
126
+ puts "pwd = #{Dir.pwd}"
127
+ puts "cp *html #@root/views/#{v}/remote"
128
+ system!("cp *html #@root/views/#{v}/remote", show: true)
129
+ end
120
130
  end
121
131
  rescue => err
122
132
  _tmp_error(err)
@@ -148,11 +158,16 @@ class RuneBlog
148
158
  end
149
159
 
150
160
  def process_post(sourcefile)
151
- log!(enter: __method__, args: [dir], level: 2)
161
+ log!(enter: __method__, args: [sourcefile], level: 2)
152
162
  nslug = sourcefile.sub(/.lt3/, "")
153
163
  dir = @root/:posts/nslug
154
- create_dir(dir)
155
- xlate cwd: dir, src: sourcefile # , debug: true
164
+ # puts "sourcefile = #{sourcefile}"
165
+ puts "-- dir = #{dir}\n pwd = #{Dir.pwd}\n @root = #@root"
166
+ gets
167
+ create_dirs(dir)
168
+ # FIXME dependencies?
169
+ xlate cwd: dir, src: @root/:drafts/sourcefile # , debug: true
170
+ # puts `ls -l #{dir}`
156
171
  _deploy_local(dir)
157
172
  rescue => err
158
173
  _tmp_error(err)
@@ -323,7 +338,8 @@ class RuneBlog
323
338
  text = nil
324
339
  @theme = @view.dir/"themes/standard"
325
340
  post_entry_name = @theme/"blog/post_entry.lt3"
326
- xlate src: post_entry_name, dst: "/tmp/post_entry.html" # , debug: true
341
+ depend = [post_entry_name]
342
+ xlate src: post_entry_name, dst: "/tmp/post_entry.html", deps: depend # , debug: true
327
343
  @_post_entry ||= File.read("/tmp/post_entry.html")
328
344
  vp = post_lookup(id)
329
345
  nslug, aslug, title, date, teaser_text =
@@ -379,7 +395,7 @@ class RuneBlog
379
395
  meta = nil
380
396
  views = views + [self.view.to_s]
381
397
  views.uniq!
382
- Dir.chdir(@root/:posts) do
398
+ Dir.chdir(@root/"posts") do
383
399
  post = Post.create(title: title, teaser: teaser, body: body, pubdate: pubdate, views: views)
384
400
  post.edit unless testing
385
401
  post.build
@@ -390,15 +406,7 @@ class RuneBlog
390
406
  _tmp_error(err)
391
407
  end
392
408
 
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)
409
+ def import_legacy_post(file, oldfile, testing = false)
402
410
  end
403
411
 
404
412
  def posts
@@ -436,9 +444,12 @@ class RuneBlog
436
444
  log!(enter: __method__, args: [view])
437
445
  vdir = @root/:views/view
438
446
  @theme = @root/:views/view/:themes/:standard
439
- xlate cwd: vdir/"themes/standard/etc",
447
+ depend = [vdir/"remote/etc/blog.css", @theme/"global.lt3",
448
+ @theme/"blog/head.lt3", @theme/"navbar/navbar.lt3",
449
+ @theme/"blog/index.lt3"] # FIXME what about assets?
450
+ xlate cwd: vdir/"themes/standard/etc", deps: depend,
440
451
  src: "blog.css.lt3", copy: vdir/"remote/etc/blog.css" # , debug: true
441
- xlate cwd: vdir/"themes/standard",
452
+ xlate cwd: vdir/"themes/standard", deps: depend,
442
453
  src: "blog/generate.lt3", dst: vdir/:remote/"index.html"
443
454
  copy("#{vdir}/assets/*", "#{vdir}/remote/assets/")
444
455
  rescue => err
@@ -448,6 +459,7 @@ class RuneBlog
448
459
  def _get_views(draft)
449
460
  log!(enter: __method__, args: [draft], level: 2)
450
461
  # FIXME dumb code
462
+ # view_line = File.readlines(self.root/:drafts/draft).grep(/^.views /)
451
463
  view_line = File.readlines(draft).grep(/^.views /)
452
464
  raise "More than one .views call!" if view_line.size > 1
453
465
  raise "No .views call!" if view_line.size < 1
@@ -543,7 +555,8 @@ class RuneBlog
543
555
  @theme = @root/:views/view_name/:themes/:standard
544
556
  # Step 1...
545
557
  create_dirs(pdraft)
546
- xlate cwd: pdraft, src: draft, dst: "guts.html", debug: true
558
+ # FIXME dependencies?
559
+ xlate cwd: pdraft, src: draft, dst: "guts.html" # , debug: true
547
560
  _post_metadata(draft, pdraft)
548
561
  # Step 2...
549
562
  vposts = @root/:views/view_name/:posts
@@ -552,8 +565,10 @@ class RuneBlog
552
565
  copy(pdraft/"guts.html", @theme/:post)
553
566
  copy(pdraft/"vars.lt3", @theme/:post)
554
567
  # Step 4...
568
+ # FIXME dependencies?
555
569
  xlate cwd: @theme/:post, src: "generate.lt3", force: true,
556
- dst: remote/ahtml, copy: @theme/:post, debug: true
570
+ dst: remote/ahtml, copy: @theme/:post # , debug: true
571
+ # FIXME dependencies?
557
572
  xlate cwd: @theme/:post, src: "permalink.lt3",
558
573
  dst: remote/:permalink/ahtml # , debug: true
559
574
  copy_widget_html(view_name)
@@ -564,7 +579,13 @@ class RuneBlog
564
579
  def generate_post(draft)
565
580
  log!(enter: __method__, args: [draft], level: 1)
566
581
  views = _get_views(draft)
567
- views.each {|view| _handle_post(draft, view) }
582
+ views.each do |view|
583
+ unless self.view?(view)
584
+ puts "Warning: '#{view}' is not a view"
585
+ next
586
+ end
587
+ _handle_post(draft, view)
588
+ end
568
589
  rescue => err
569
590
  _tmp_error(err)
570
591
  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.48"
5
+ VERSION = "0.2.53"
6
6
 
7
7
  path = Gem.find_files("runeblog").grep(/runeblog-/).first
8
8
  Path = File.dirname(path)
@@ -1,21 +1,26 @@
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
@@ -24,7 +29,8 @@ def xlate(cwd: Dir.pwd, src:,
24
29
  STDERR.puts "#{indent} from: #{caller[0]}"
25
30
  STDERR.puts "#{indent} copy: #{copy}" if copy
26
31
  end
27
- stale = stale?(src, dst, force)
32
+ stale = stale?(src, dst, deps, force)
33
+ # puts "stale? src = #{src}\n dst = #{dst}\n #{stale}"
28
34
  if stale
29
35
  rc = system("livetext #{src} >#{dst}")
30
36
  STDERR.puts "...completed (shell returned #{rc})" if debug
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.48
4
+ version: 0.2.53
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-20 00:00:00.000000000 Z
11
+ date: 2019-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: livetext
@@ -69,6 +69,11 @@ files:
69
69
  - empty_view/remote/navbar/GIT_IS_DUMB
70
70
  - empty_view/remote/permalink/GIT_IS_DUMB
71
71
  - empty_view/themes/standard/README
72
+ - empty_view/themes/standard/banner/about.lt3
73
+ - empty_view/themes/standard/banner/blog-banner.jpg
74
+ - empty_view/themes/standard/banner/contact.lt3
75
+ - empty_view/themes/standard/banner/faq.lt3
76
+ - empty_view/themes/standard/banner/navbar.lt3
72
77
  - empty_view/themes/standard/blog/generate.lt3
73
78
  - empty_view/themes/standard/blog/head.lt3
74
79
  - empty_view/themes/standard/blog/index.lt3