runeblog 0.2.48 → 0.2.53

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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