runeblog 0.2.96 → 0.3.03

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: 43bbc2d314d9a90cd34f558050a736ed58423f95576b0e32c3e36fc1405d756d
4
- data.tar.gz: fcb2d941bff2c4c0bb3e609b347f1afcf9a13bb8073b2868a1af6d07c0883332
3
+ metadata.gz: 981c7fd06d3616dd52825124cc99baf2822e45733c02d7d979750d95bb296a1a
4
+ data.tar.gz: 7662e51fbe7a7ac7986ef6c4f745a4d745774a1a36085a2ac666d1d96cc06a5d
5
5
  SHA512:
6
- metadata.gz: 0a6446ceda937da5da353cc0b1259c1ad54743b936e36c4f45fadf2cc4e8def5ee2d8f227ef4f2c5e63e192eabd27134ddfd36de533364fe35d4177d45d335b9
7
- data.tar.gz: 59c9fbab3e634c7fc99e147211b35e893b48cf6930deb331cba3cb1dbf36807bd746d8579c006fd27cd87ce5bd26eb34318b31e6c3c2b9580ae8c9b9856522e4
6
+ metadata.gz: a72de8c66f10ede4bec71970d46d3f1d48cb41546d8f600338cb8738d22419acc992ab9d88d3e5c8a6531d7f6b3a0b1e82bc80a12078032addaa6d2b5edb49cc
7
+ data.tar.gz: 556c8604bea8f8fbd42d78b8cfffcb8a8af183958698543d25969cd4d9511f986814b55488d98fe87ac81a5bea05dc51a058f7a0ce24f7a39271aa6e38697a30
data/bin/blog CHANGED
@@ -25,12 +25,14 @@ end
25
25
  def get_universal
26
26
  univ = "#{@blog.root}/data/universal.lt3"
27
27
  if yesno("Faster initial setup? (no: edit universal.lt3)")
28
- author = ask!("Author name: ")
29
- site = ask!("Site/domain: ")
28
+ author = ask!(" Author name: ")
29
+ site = ask!(" Site/domain: ")
30
30
  # Now stash it...
31
31
  str = File.read(univ)
32
32
  str = str.gsub(/AUTHOR/, author)
33
33
  str = str.gsub(/SITE_DOMAIN/, site)
34
+ File.write(univ, str)
35
+ # STDERR.puts "------ universal ------\n#{`cat #{univ}`}\n------------------------"
34
36
  else
35
37
  vim_params = '-c ":set hlsearch" -c ":hi Search ctermfg=2 ctermbg=6" +/"\(AUTHOR.*\|SITE.*\)"'
36
38
  edit_file(univ, vim: vim_params)
@@ -39,18 +41,20 @@ end
39
41
 
40
42
  def get_global
41
43
  if yesno("Faster view setup? (no: edit global.lt3)")
42
- view_name = ask!("\nFilename: ")
44
+ view_name = ask!("\n Filename: ")
43
45
  @blog.create_view(view_name) # call change_view??
44
- title = ask!("View title: ")
45
- subtitle = ask!("Subtitle : ")
46
- gname = "#{@blog.root}/views/#{view_name}/themes/standard/global.lt3"
47
- text = File.read(gname)
48
- text = text.gsub(/VIEW_NAME/, view_name)
49
- text = text.gsub(/VIEW_TITLE/, title)
50
- text = text.gsub(/VIEW_SUBTITLE/, subtitle)
51
- File.write(gname, text)
46
+ title = ask!(" View title: ")
47
+ subtitle = ask!(" Subtitle : ")
48
+ domain = ask!(" Domain : ")
49
+
50
+ vfile = "#{@blog.root}/views/#{view_name}/settings/view.txt"
51
+ hash = {/VIEW_NAME/ => view_name,
52
+ /VIEW_TITLE/ => title,
53
+ /VIEW_SUBTITLE/ => subtitle,
54
+ /VIEW_DOMAIN/ => domain}
55
+ @blog.complete_file(vfile, nil, hash)
52
56
  else
53
- view_name = ask!("\nFilename: ")
57
+ view_name = ask!("\n Filename: ")
54
58
  @blog.create_view(view_name) # call change_view??
55
59
  vim_params = '-c ":set hlsearch" -c ":hi Search ctermfg=2 ctermbg=6" +/"\(VIEW_.*\|SITE.*\)"'
56
60
  edit_file(@blog.view.dir/"themes/standard/global.lt3", vim: vim_params)
@@ -0,0 +1,18 @@
1
+ # 0 = disabled (installed but disabled)
2
+ # 1 = enabled (implies installed)
3
+ # x = excluded (not installed; does it even exist?)
4
+
5
+ reddit 0 # autopost, embed thread after blog post
6
+ facebook 0 # reader-like, reader post, autopost?
7
+ twitter 0 # reader-tweet, reader-follow, autotweet?
8
+
9
+ links 1 # widget: external links
10
+ news 1 # widget: news (external)
11
+ pages 1 # widget: internal pages
12
+ pinned 1 # widget: pinned posts
13
+
14
+ ad x # widget: embed advertising
15
+ bydates x # widget: browse posts by date
16
+ search x # widget: search posts
17
+ sitemap x # widget: site map
18
+ tag_cloud x # widget: tag cloud (clickable)
@@ -3,33 +3,18 @@
3
3
  . <variable> <value>
4
4
  . --------------------------------------------------
5
5
 
6
- .variables
7
- author AUTHOR
8
- blog VIEW_TITLE
9
- blog.desc VIEW_SUBTITLE
10
- site SITE
6
+ .variables view ../../settings/view.txt
7
+
8
+ .variables recent ../../settings/recent.txt
9
+
10
+ .variables publish ../../settings/publish.txt
11
11
 
12
+ .variables
12
13
  host http://SITE
13
14
  charset utf-8
14
15
  url http://SITE
15
16
  locale en_US
16
17
 
17
18
  font.family verdana
18
-
19
- post.title.color #010101
20
- post.title.size 28px
21
-
22
- post.text.color #0101a1
23
- post.text.size 22px
24
-
25
- post.date.color #9a9a9a
26
- post.date.size 15px
27
-
28
-
29
- publish.user root
30
- publish.server SITE
31
- publish.docroot /var/www/
32
- publish.path VIEW_NAME
33
- publish.proto http
34
19
  .end
35
20
 
@@ -8,14 +8,11 @@
8
8
  .nopara
9
9
 
10
10
  .variables
11
- . Identity
12
- author AUTHOR
13
- site SITE_DOMAIN
11
+ univ.author AUTHOR
12
+ univ.site SITE_DOMAIN
14
13
 
15
- . Style
16
14
  font.family verdana
17
15
 
18
- . Details
19
16
  charset utf-8
20
17
  locale en_US
21
18
  .end
@@ -25,9 +25,9 @@
25
25
  <body>
26
26
 
27
27
  <section class="post">
28
- <div class="entry-content">
28
+ <div class="recent-content">
29
29
  <table border=0 width=100%><tr>
30
- <td align=left valign=bottom><h2 class="post-title">The graffiti wall</h2></td>
30
+ <td align=left valign=bottom><h2 class="recent-title">The graffiti wall</h2></td>
31
31
  <td align=right valign=top><font size=-5><br></font>December 2, 2019</td>
32
32
  </tr></table><hr>
33
33
  <!-- Post number 3 -->
@@ -0,0 +1,18 @@
1
+ # 0 = disabled (installed but disabled)
2
+ # 1 = enabled (implies installed)
3
+ # x = excluded (not installed; does it even exist?)
4
+
5
+ reddit 0 # autopost, embed thread after blog post
6
+ facebook 0 # reader-like, reader post, autopost?
7
+ twitter 0 # reader-tweet, reader-follow, autotweet?
8
+
9
+ links 1 # widget: external links
10
+ news 1 # widget: news (external)
11
+ pages 1 # widget: internal pages
12
+ pinned 1 # widget: pinned posts
13
+
14
+ ad x # widget: embed advertising
15
+ bydates x # widget: browse posts by date
16
+ search x # widget: search posts
17
+ sitemap x # widget: site map
18
+ tag_cloud x # widget: tag cloud (clickable)
@@ -0,0 +1,5 @@
1
+ user root
2
+ server SITE
3
+ docroot /var/www/html
4
+ path VIEW_NAME # can be different
5
+ proto https
@@ -0,0 +1,6 @@
1
+ title.color #010101
2
+ title.size 28px
3
+ text.color #0101a1
4
+ text.size 22px
5
+ date.color #9a9a9a
6
+ date.size 15px
@@ -0,0 +1,4 @@
1
+ author VIEW_AUTHOR
2
+ title VIEW_TITLE
3
+ subtitle VIEW_SUBTITLE
4
+ site VIEW_SITE
@@ -15,6 +15,6 @@
15
15
 
16
16
  <rect x="20" y="20" rx="15" ry="15" width="98%" height="100" fill="url(#grad1)"/>
17
17
 
18
- <text x="45" y="70" class=heavy>$blog</text>
19
- <text x="45" y="98" class=small>$blog.desc</text>
18
+ <text x="45" y="70" class=heavy>$view.title</text>
19
+ <text x="45" y="98" class=small>$view.subtitle</text>
20
20
  </svg>
@@ -10,7 +10,7 @@
10
10
  <font size=-1>#{date}</font>
11
11
  </td>
12
12
  <td>
13
- <span class="post-title-text"><a href="#{url}" style="margin-top: -5px">#{title}</a></span>
13
+ <span class="recent-title-text"><a href="#{url}" style="margin-top: -5px">#{title}</a></span>
14
14
  <b>#{teaser_text}</b>&nbsp;&nbsp;
15
15
  <a style="text-decoration: none" href="#{url}"><small>Keep&nbsp;reading</small></a>
16
16
  </td>
@@ -3,40 +3,40 @@
3
3
  . Most of the global CSS goes here
4
4
  . --------------------------------------------------
5
5
 
6
- .seek themes/standard/global.lt3
6
+ .seek global.lt3
7
7
 
8
8
  body { font-family: $font.family }
9
9
 
10
- \.post-title a {
11
- color: $post.title.color;
10
+ \.recent-title a {
11
+ color: $recent.title.color;
12
12
  font-family: $font.family;
13
- font-size: $post.title.size;
13
+ font-size: $recent.title.size;
14
14
  float: right;
15
15
  display: inline-block;
16
16
  text-align: top;
17
17
  text-decoration: none;
18
18
  }
19
19
 
20
- \.post-title a:hover {
20
+ \.recent-title a:hover {
21
21
  text-decoration: none;
22
22
  }
23
23
 
24
- \.post-title-text a {
25
- color: $post.text.color;
24
+ \.recent-title-text a {
25
+ color: $recent.text.color;
26
26
  font-family: $font.family;
27
- font-size: $post.text.size;
27
+ font-size: $recent.text.size;
28
28
  display: block;
29
29
  text-decoration: none;
30
30
  }
31
31
 
32
- \.post-title-text a:hover {
32
+ \.recent-title-text a:hover {
33
33
  text-decoration: none;
34
34
  }
35
35
 
36
- \.post-date {
37
- color: $post.date.color;
36
+ \.recent-date {
37
+ color: $recent.date.color;
38
38
  font-family: $font.family;
39
- font-size: $post.date.size;
39
+ font-size: $recent.date.size;
40
40
  display: block;
41
41
  float: left;
42
42
  text-align: top;
@@ -22,9 +22,9 @@ style blog.css
22
22
  <body>
23
23
 
24
24
  <section class="post">
25
- <div class="entry-content">
25
+ <div class="recent-content">
26
26
  <table border=0 width=100%><tr>
27
- <td align=left valign=bottom><h2 class="post-title">$title</h2></td>
27
+ <td align=left valign=bottom><h2 class="recent-title">$title</h2></td>
28
28
  <td align=right valign=top><font size=-5><br></font>$longdate</td>
29
29
  </tr></table><hr>
30
30
  $.copy guts.html
@@ -21,7 +21,7 @@ description $teaser
21
21
  .end
22
22
 
23
23
  <section class="post">
24
- <div class="entry-content">
24
+ <div class="recent-content">
25
25
  $.copy guts.html
26
26
  </div>
27
27
  </section>
@@ -14,6 +14,26 @@ module RuneBlog::Helpers
14
14
  exit
15
15
  end
16
16
 
17
+ def read_features(view = nil)
18
+ hash = {}
19
+ if view.nil? # toplevel default
20
+ dir = @root/"data"
21
+ else
22
+ dir = @root/:views/self.view/:settings
23
+ end
24
+ file = dir/"features.txt"
25
+ lines = File.readlines(file)
26
+ lines.each do |line|
27
+ line = line.strip
28
+ line.sub!(/ #.*/, "") # trailing
29
+ next if line =~ /^ *#/ # leading
30
+ next if line.empty?
31
+ name, status = line.split
32
+ hash[name] = (status == "1") # enabled
33
+ end
34
+ @features = hash
35
+ end
36
+
17
37
  def get_repo_config
18
38
  log!(enter: __method__, level: 3)
19
39
  @editor = File.read(".blogs/data/EDITOR").chomp
@@ -27,15 +47,9 @@ module RuneBlog::Helpers
27
47
 
28
48
  def copy_data(tag, dest)
29
49
  data = RuneBlog::Path + "/../data" # files kept inside gem
30
- extra = RuneBlog::Path + "/../config" # files kept inside gem
31
- # FIXME names are confusing
32
- case tag
33
- when :config
34
- files = %w[ROOT VIEW EDITOR universal.lt3 global.lt3]
35
- files.each {|file| copy(data + "/" + file, dest) }
36
- when :extra # FIXME remove later
37
- # copy!(extra, dest)
38
- end
50
+ # FIXME tag no longer used
51
+ files = %w[ROOT VIEW EDITOR universal.lt3 global.lt3 features.txt]
52
+ files.each {|file| copy(data + "/" + file, dest) unless File.exist?(dest/file) }
39
53
  end
40
54
 
41
55
  def read_vars(file)
@@ -47,14 +61,15 @@ module RuneBlog::Helpers
47
61
  line = line.strip
48
62
  next if skip.include?(line[0])
49
63
  key, val = line.split(" ", 2)
50
- hash[key] = val
64
+ next if key.nil?
65
+ hash[key] = hash[key.to_sym] = val
51
66
  end
52
67
  hash
53
68
  rescue => err
54
69
  puts "Can't read vars file '#{file}': #{err}"
55
70
  puts err.backtrace.join("\n")
56
71
  puts "dir = #{Dir.pwd}"
57
- stop_RubyText
72
+ stop_RubyText rescue nil
58
73
  end
59
74
 
60
75
  def read_config(file, *syms)
@@ -111,15 +126,6 @@ module RuneBlog::Helpers
111
126
  File.write(root + "/data/EDITOR", editor + "\n")
112
127
  end
113
128
 
114
- # def new_dotfile(root: ".blogs", current_view: "test_view", editor: "vi")
115
- # log!(enter: __method__, args: [root, current_view, editor], level: 3)
116
- # root = Dir.pwd + "/" + root
117
- # x = OpenStruct.new
118
- # x.root, x.current_view, x.editor = root, current_view, editor
119
- # write_config(x, root + "/" + RuneBlog::ConfigFile)
120
- # write_repo_config
121
- # end
122
-
123
129
  def new_sequence
124
130
  log!(enter: __method__, level: 3)
125
131
  dump(0, "data/sequence")
@@ -72,7 +72,7 @@ def post_trailer
72
72
  tags = _var("post.tags")
73
73
  taglist = tags.empty? ? "" : "Tags: #{tags}"
74
74
 
75
- reddit_enabled = false # FIXME
75
+ reddit_enabled = @blog.features["reddit"]
76
76
  reddit_txt = ""
77
77
  if reddit_enabled
78
78
  vdir = @blog.root/:views/@blog.view
@@ -110,7 +110,7 @@ def faq
110
110
  _out %[&nbsp;<a data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample"><font size=+3>&#8964;</font></a>]
111
111
  _out %[&nbsp;<b>#{ques}</b>]
112
112
  _out %[<div class="collapse" id="#{id}"><br><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{ans}</font></div>\n]
113
- _out "<br>" unless @faq_count == 1
113
+ _out "<br>" # unless @faq_count == 1
114
114
  _optional_blank_line
115
115
  end
116
116
 
@@ -241,8 +241,8 @@ def _svg_title(*args)
241
241
  .subtitle { font: #{style2} #{size2} #{font2}; fill: #{color2} }
242
242
  </style>
243
243
  <rect x="10" y="10" rx="10" ry="10" width="#{width}" height="#{height}" fill="url(#grad1)"/>
244
- <text text-anchor="#{align}" x="#{x}" y="#{y}" class="title">#{Livetext::Vars[:blog]} </text>
245
- <text text-anchor="#{align2}" x="#{x2}" y="#{y2}" class="subtitle">#{Livetext::Vars["blog.desc"]} </text>
244
+ <text text-anchor="#{align}" x="#{x}" y="#{y}" class="title">#{Livetext::Vars["view.title"]} </text>
245
+ <text text-anchor="#{align2}" x="#{x2}" y="#{y2}" class="subtitle">#{Livetext::Vars["view.subtitle"]} </text>
246
246
  </svg>
247
247
  <!-- ^ how does syntax highlighting get messed up? </svg> -->
248
248
  HTML
@@ -275,6 +275,13 @@ def h6; _passthru "
#{@_data}
"; end
275
275
 
276
276
  def hr; _passthru "<hr>"; end
277
277
 
278
+ def nlist
279
+ _out "<ol>"
280
+ _body {|line| _out "<li>#{line}</li>" }
281
+ _out "</ol>"
282
+ _optional_blank_line
283
+ end
284
+
278
285
  def list
279
286
  _out "<ul>"
280
287
  _body {|line| _out "<li>#{line}</li>" }
@@ -439,18 +446,18 @@ def head # Does NOT output tags
439
446
  defaults = {}
440
447
  defaults = { "charset" => %[<meta charset="utf-8">],
441
448
  "http-equiv" => %[<meta http-equiv="X-UA-Compatible" content="IE=edge">],
442
- "title" => %[<title>\n #{_var(:blog)} | #{_var("blog.desc")}\n </title>],
449
+ "title" => %[<title>\n #{_var("view.title")} | #{_var("view.subtitle")}\n </title>],
443
450
  "generator" => %[<meta name="generator" content="Runeblog v #@version">],
444
- "og:title" => %[<meta property="og:title" content="#{_var(:blog)}">],
451
+ "og:title" => %[<meta property="og:title" content="#{_var("view.title")}">],
445
452
  "og:locale" => %[<meta property="og:locale" content="#{_var(:locale)}">],
446
- "description" => %[<meta name="description" content="#{_var("blog.desc")}">],
447
- "og:description" => %[<meta property="og:description" content="#{_var("blog.desc")}">],
453
+ "description" => %[<meta name="description" content="#{_var("view.subtitle")}">],
454
+ "og:description" => %[<meta property="og:description" content="#{_var("view.subtitle")}">],
448
455
  "linkc" => %[<link rel="canonical" href="#{_var(:host)}">],
449
456
  "og:url" => %[<meta property="og:url" content="#{_var(:host)}">],
450
- "og:site_name" => %[<meta property="og:site_name" content="#{_var(:blog)}">],
457
+ "og:site_name" => %[<meta property="og:site_name" content="#{_var("view.title")}">],
451
458
  # "style" => %[<link rel="stylesheet" href="etc/blog.css">],
452
459
  # ^ FIXME
453
- "feed" => %[<link type="application/atom+xml" rel="alternate" href="#{_var(:host)}/feed.xml" title="#{_var(:blog)}">],
460
+ "feed" => %[<link type="application/atom+xml" rel="alternate" href="#{_var(:host)}/feed.xml" title="#{_var("view.title")}">],
454
461
  "favicon" => %[<link rel="shortcut icon" type="image/x-icon" href="etc/favicon.ico">\n <link rel="apple-touch-icon" href="etc/favicon.ico">]
455
462
  }
456
463
  result = {}
@@ -682,7 +689,7 @@ end
682
689
 
683
690
  def _make_navbar(orient = :horiz)
684
691
  vdir = @root/:views/@blog.view
685
- title = _var(:blog)
692
+ title = _var("view.title")
686
693
 
687
694
  if orient == :horiz
688
695
  name = "navbar.html"
@@ -21,11 +21,15 @@ def stale?(src, dst, deps, force = false)
21
21
  end
22
22
 
23
23
  def preprocess(cwd: Dir.pwd, src:,
24
- dst: (strip = true; File.basename(src).sub(/.lt3$/,"")),
24
+ dst: nil, strip: false,
25
25
  deps: [], copy: nil, debug: false, force: false,
26
26
  mix: [], call: [], vars: {})
27
27
  src += LEXT unless src.end_with?(LEXT)
28
- dst += ".html" unless (dst.end_with?(".html") || strip)
28
+ if strip
29
+ dst = File.basename(src).sub(/.lt3$/,"")
30
+ else
31
+ dst += ".html" unless dst.end_with?(".html")
32
+ end
29
33
  sp = " "*12
30
34
  Dir.chdir(cwd) do
31
35
  if debug
@@ -47,4 +51,10 @@ def preprocess(cwd: Dir.pwd, src:,
47
51
  end
48
52
  end
49
53
 
54
+ def get_live_vars(src)
55
+ live = Livetext.customize(call: [".nopara"])
56
+ live.xform_file(src)
57
+ live
58
+ end
59
+
50
60
  end
@@ -3,26 +3,27 @@ if ! defined?(Already_publish)
3
3
  Already_publish = nil
4
4
 
5
5
  require 'pathmagic'
6
+ require 'processing'
6
7
 
7
8
  class RuneBlog::Publishing
8
9
  attr_reader :user, :server, :docroot, :path
9
10
 
10
-
11
11
  BadRemoteLogin = Exception.new("Can't login remotely")
12
12
  BadRemotePerms = Exception.new("Bad remote permissions")
13
13
 
14
14
  def initialize(view)
15
15
  log!(enter: __method__, args: [view.to_s])
16
16
  @blog = RuneBlog.blog
17
- gfile = @blog.root/:views/view/"themes/standard/global.lt3"
18
- data = File.readlines(gfile)
19
- # Please refactor the Hal out of this
20
- grab = ->(var) { data.grep(/^#{var} /).first.chomp.split(" ", 2)[1] }
21
- @user = grab.call("publish.user")
22
- @server = grab.call("publish.server")
23
- @docroot = grab.call("publish.docroot")
24
- @path = grab.call("publish.path")
25
- @proto = grab.call("publish.proto")
17
+ dir = @blog.root/:views/view/"themes/standard/"
18
+ gfile = dir/"global.lt3"
19
+ return unless File.exist?(gfile) # FIXME Hackish as hell
20
+
21
+ live = get_live_vars(gfile)
22
+ @user = live.vars["publish.user"]
23
+ @server = live.vars["publish.server"]
24
+ @docroot = live.vars["publish.docroot"]
25
+ @path = live.vars["publish.path"]
26
+ @proto = live.vars["publish.proto"]
26
27
  end
27
28
 
28
29
  def to_h
@@ -38,7 +38,7 @@ module RuneBlog::REPL
38
38
  @out
39
39
  end
40
40
 
41
- def cmd_config(arg, testing = false)
41
+ def OLD_cmd_config(arg, testing = false)
42
42
  hash = {"global.lt3 Global configuration" => "global.lt3",
43
43
  "banner/top.lt3 Text portion of banner" => "banner/top.lt3",
44
44
  "blog/generate.lt3 Generator for view (usu not edited)" => "blog/generate.lt3",
@@ -59,6 +59,32 @@ module RuneBlog::REPL
59
59
  edit_file(dir/target)
60
60
  end
61
61
 
62
+ def cmd_config(arg, testing = false)
63
+ hash = {"Global configuration" => "global.lt3",
64
+ " View-specific variables" => "../../settings/view.txt",
65
+ " Recent posts" => "../../settings/recent.txt",
66
+ " Publishing vars" => "../../settings/publish.txt",
67
+ "Banner description" => "blog/banner.lt3",
68
+ " Text portion of banner" => "banner/top.lt3",
69
+ "Generator for view (usu not edited)" => "blog/generate.lt3",
70
+ " HEAD info for view" => "blog/head.lt3",
71
+ " User-edited detail for view" => "blog/index.lt3",
72
+ "Generator for post entry in recent-posts" => "blog/post_entry.lt3",
73
+ "Global CSS" => "etc/blog.css.lt3",
74
+ "External JS/CSS (Bootstrap, etc.)" => "/etc/externals.lt3",
75
+ "Generator for a post" => "post/generate.lt3",
76
+ " HEAD info for post" => "post/head.lt3",
77
+ " Content for post" => "post/index.lt3",
78
+ "Generator for permalink" => "post/permalink.lt3",
79
+ }
80
+
81
+ dir = @blog.view.dir/"themes/standard/"
82
+ num, target = STDSCR.menu(title: "Edit file:", items: hash)
83
+ edit_file(dir/target)
84
+ end
85
+
86
+
87
+
62
88
  def cmd_manage(arg, testing = false)
63
89
  case arg
64
90
  when "pages"; _manage_pages(nil, testing = false)
@@ -40,7 +40,7 @@ class RuneBlog
40
40
  end
41
41
 
42
42
  attr_reader :views, :sequence
43
- attr_accessor :root, :editor
43
+ attr_accessor :root, :editor, :features
44
44
  attr_accessor :view # overridden
45
45
 
46
46
  attr_accessor :post_views, :post_tags, :dirty_views
@@ -120,8 +120,9 @@ class RuneBlog
120
120
  self.class.blog = self # Weird. Like a singleton - dumbass circular dependency?
121
121
 
122
122
  @root = Dir.pwd/root_rel
123
- write_repo_config(root: @root)
123
+ write_repo_config(root: @root) # ?? FIXME
124
124
  get_repo_config
125
+ read_features # top level
125
126
  @views = retrieve_views
126
127
  self.view = File.read(@root/"data/VIEW").chomp
127
128
  md = Dir.pwd.match(%r[.*/views/(.*?)/])
@@ -134,16 +135,67 @@ class RuneBlog
134
135
  @post_tags = []
135
136
  end
136
137
 
138
+ def complete_file(name, vars, hash)
139
+ debugging = vars.nil?
140
+ return if hash.empty?
141
+ text = File.read(name)
142
+ if vars.nil? # FIXME dumbest hack ever?
143
+ vars = {}
144
+ hash.values.each {|val| vars[val] = val }
145
+ end
146
+
147
+ hash.each_pair {|key, var| text.gsub!(key, vars[var]) }
148
+ File.write(name, text)
149
+ end
150
+
151
+ def _generate_settings(view = nil)
152
+ vars = read_vars("#@root/data/universal.lt3")
153
+ hash = {/AUTHOR/ => "view.author",
154
+ /SITE/ => "view.site",
155
+ /FONT/ => "font.family",
156
+ /CHARSET/ => :charset,
157
+ /LOCALE/ => :locale}
158
+
159
+ # rubytext.txt - LATER
160
+ # complete_file(settings/"rubytext.txt", {}
161
+
162
+ if view
163
+ settings = @root/view/"settings"
164
+ ### ??? Where to get hash of view-specific vars?
165
+
166
+ # features.txt - handle specially
167
+ fname = settings/"features.txt"
168
+
169
+ # view.txt
170
+ complete_file(settings/"view.txt",
171
+ /AUTHOR/ => "view.author",
172
+ /TITLE/ => "view.title",
173
+ /SUBTITLE/ => "view.subtitle",
174
+ /SITE/ => "view.site")
175
+
176
+ # publish.txt
177
+ complete_file(settings/"publish.txt",
178
+ /USER/ => "publish.user",
179
+ /SERVER/ => "publish.server",
180
+ /DOCROOT/ => "publish.docroot",
181
+ /PATH/ => "publish.path",
182
+ /PROTO/ => "publish.proto")
183
+
184
+ # recent.txt - SKIP THIS?
185
+ complete_file(settings/"recent.txt", {})
186
+ end
187
+ end
188
+
137
189
  def _generate_global
138
190
  vars = read_vars("#@root/data/universal.lt3")
139
191
  gfile = "#@root/data/global.lt3"
140
- global = File.read(gfile)
141
- global.gsub!(/AUTHOR/, vars["author"])
142
- global.gsub!(/SITE/, vars["site"])
143
- global.gsub!(/FONT/, vars["font.family"])
144
- global.gsub!(/CHARSET/, vars["charset"])
145
- global.gsub!(/LOCALE/, vars["locale"])
146
- File.write(gfile, global)
192
+ hash = {/AUTHOR/ => "univ.author",
193
+ /SITE/ => "univ.site",
194
+ /FONT/ => "font.family",
195
+ /CHARSET/ => :charset,
196
+ /LOCALE/ => :locale}
197
+ complete_file(gfile, vars, hash)
198
+ _generate_settings
147
199
  end
148
200
 
149
201
  def _deploy_local(dir)
@@ -151,10 +203,7 @@ class RuneBlog
151
203
  Dir.chdir(dir) do
152
204
  views = _retrieve_metadata(:views)
153
205
  views.each do |v|
154
- unless self.view?(v)
155
- puts "#{fx("Warning:", :red)} #{fx(v, :bold)} is not a view"
156
- next
157
- end
206
+ next unless _check_view?(v)
158
207
  system!("cp *html #@root/views/#{v}/remote", show: true)
159
208
  end
160
209
  end
@@ -162,6 +211,8 @@ class RuneBlog
162
211
  _tmp_error(err)
163
212
  end
164
213
 
214
+ # FIXME reconcile with _get_draft data
215
+
165
216
  def _retrieve_metadata(key)
166
217
  key = key.to_s
167
218
  lines = File.readlines("metadata.txt")
@@ -193,7 +244,7 @@ class RuneBlog
193
244
  dir = @root/:posts/nslug
194
245
  create_dirs(dir)
195
246
  # FIXME dependencies?
196
- preprocess cwd: dir, src: @root/:drafts/sourcefile, dst: @root/:posts/sourcefile.sub(/.lt3/, ",html"), # ZZZ
247
+ preprocess cwd: dir, src: @root/:drafts/sourcefile, dst: @root/:posts/sourcefile.sub(/.lt3/, ".html"), # ZZZ
197
248
  mix: "liveblog" # , debug: true
198
249
  _deploy_local(dir)
199
250
  rescue => err
@@ -244,11 +295,13 @@ class RuneBlog
244
295
  @view = nil
245
296
  when RuneBlog::View
246
297
  @view = arg
298
+ read_features(@view)
247
299
  _set_publisher
248
300
  when String
249
301
  new_view = str2view(arg)
250
302
  raise NoSuchView(arg) if new_view.nil?
251
303
  @view = new_view
304
+ read_features(@view)
252
305
  _set_publisher
253
306
  else
254
307
  raise CantAssignView(arg.class.to_s)
@@ -373,7 +426,7 @@ class RuneBlog
373
426
  html = "/tmp/post_entry.html"
374
427
  preprocess src: post_entry_name, dst: html,
375
428
  call: ".nopara" # , deps: depend # , debug: true
376
- @_post_entry ||= File.read(html)
429
+ @_post_entry = File.read(html)
377
430
  vp = post_lookup(id)
378
431
  nslug, aslug, title, date, teaser_text =
379
432
  vp.nslug, vp.aslug, vp.title, vp.date, vp.teaser_text
@@ -499,15 +552,14 @@ class RuneBlog
499
552
  @theme/"blog/head.lt3",
500
553
  # @theme/"navbar/navbar.lt3",
501
554
  @theme/"blog/index.lt3"] # FIXME what about assets?
502
- preprocess cwd: vdir/"themes/standard/etc", # deps: depend, debug: true,
503
- src: "blog.css.lt3", copy: vdir/"remote/etc/",
504
- call: ".nopara" # , dst: "blog.css"
555
+ preprocess cwd: vdir/"themes/standard/etc", src: "blog.css.lt3",
556
+ copy: vdir/"remote/etc/", call: [".nopara"], strip: true
505
557
  preprocess cwd: vdir/"themes/standard", deps: depend, force: true,
506
558
  src: "blog/generate.lt3", dst: vdir/:remote/"index.html",
507
559
  call: ".nopara"
508
560
  copy!("#{vdir}/themes/standard/banner/*", "#{vdir}/remote/banner/") # includes navbar/
509
561
  copy("#{vdir}/assets/*", "#{vdir}/remote/assets/")
510
- # rebuild widgets
562
+ # rebuild widgets?
511
563
  copy_widget_html(view)
512
564
  rescue => err
513
565
  STDERR.puts err
@@ -515,6 +567,27 @@ class RuneBlog
515
567
  # _tmp_error(err)
516
568
  end
517
569
 
570
+ def _get_draft_data(num, sym)
571
+ tag = prefix(num)
572
+ front = @blog.root/:drafts/tag
573
+ files = Dir[front + "*"]
574
+ raise "No draft #{num} found" if files.empty?
575
+ raise "Too many files found for #{num}!" if files.size > 1
576
+ file = files.first
577
+ lines = File.readlines(file)
578
+ case sym
579
+ when :views
580
+ view_line = lines.grep(/^.views /)
581
+ raise "More than one .views call in #{draft}" if view_line.size > 1
582
+ raise "No .views call in #{draft}" if view_line.size < 1
583
+ view_line = view_line.first
584
+ views = view_line[7..-1].split
585
+ return views.uniq
586
+ else
587
+ raise "Unknown symbol #{sym.inspect}"
588
+ end
589
+ end
590
+
518
591
  def _get_views(draft)
519
592
  log!(enter: __method__, args: [draft], level: 2)
520
593
  # FIXME dumb code
@@ -604,6 +677,8 @@ class RuneBlog
604
677
  log!(enter: __method__, args: [draft, view_name], level: 2)
605
678
  # break into separate methods?
606
679
 
680
+ return unless _check_view?(view_name)
681
+
607
682
  fname = File.basename(draft) # 0001-this-is-a-post.lt3
608
683
  nslug = fname.sub(/.lt3$/, "") # 0001-this-is-a-post
609
684
  aslug = nslug.sub(/\d\d\d\d-/, "") # this-is-a-post
@@ -633,30 +708,16 @@ class RuneBlog
633
708
  _tmp_error(err)
634
709
  end
635
710
 
711
+ def _check_view?(view)
712
+ flag = self.view?(view)
713
+ puts " Warning: '#{view}' is not a view" unless flag
714
+ flag
715
+ end
716
+
636
717
  def generate_post(draft, force = false)
637
718
  log!(enter: __method__, args: [draft], level: 1)
638
719
  views = _get_views(draft)
639
- views.each do |view|
640
- unless self.view?(view)
641
- puts "Warning: '#{view}' is not a view"
642
- next
643
- end
644
- _handle_post(draft, view)
645
- end
646
- rescue => err
647
- _tmp_error(err)
648
- end
649
-
650
- def rebuild_post(file)
651
- log!(enter: __method__, args: [file])
652
- raise "Doesn't currently work"
653
- debug "Called rebuild_post(#{file.inspect})"
654
- raise ArgumentError unless file.is_a?(String)
655
- meta = process_post(file)
656
- @views_dirty ||= []
657
- @views_dirty << meta.views
658
- @views_dirty.flatten!
659
- @views_dirty.uniq!
720
+ views.each {|view| _handle_post(draft, view) }
660
721
  rescue => err
661
722
  _tmp_error(err)
662
723
  end
@@ -3,7 +3,7 @@ if !defined?(RuneBlog::Path)
3
3
  # if ! (Object.constants.include?(:RuneBlog) && RuneBlog.constants.include?(:Path))
4
4
 
5
5
  class RuneBlog
6
- VERSION = "0.2.96"
6
+ VERSION = "0.3.03"
7
7
 
8
8
  path = Gem.find_files("runeblog").grep(/runeblog-/).first
9
9
  Path = File.dirname(path)
@@ -15,6 +15,8 @@ class RuneBlog::View
15
15
  @can_publish = true # FIXME
16
16
  @blog.view = self
17
17
  gfile = @blog.root/"views/#{name}/themes/standard/global.lt3"
18
+ return unless File.exist?(gfile) # Hackish!! how is View.new called from create_view??
19
+
18
20
  live = Livetext.customize(call: ".nopara")
19
21
  live.xform_file(gfile)
20
22
  @globals = live.vars
@@ -20,7 +20,7 @@ spec = Gem::Specification.new do |s|
20
20
  s.authors = ["Hal Fulton"]
21
21
  s.email = 'rubyhacker@gmail.com'
22
22
  s.executables << "blog"
23
- s.add_runtime_dependency 'livetext', '~> 0.8', '>= 0.8.99'
23
+ s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.01'
24
24
  s.add_runtime_dependency 'rubytext', '~> 0.1', '>= 0.1.20'
25
25
 
26
26
  s.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.0'
@@ -31,7 +31,7 @@ end
31
31
  @fake_date = Date.today - 20
32
32
 
33
33
  def make_post(x, title, teaser, body, views=[])
34
- debug " make_post #{bold(title)}"
34
+ debug " make_post #{bold(title)}"
35
35
  pubdate = @fake_date.strftime("%Y-%m-%d")
36
36
  @fake_date += (rand(2) + 1)
37
37
  x.create_new_post(title, true, teaser: teaser, body: body, views: views,
@@ -53,28 +53,26 @@ puts
53
53
  debug bold("Generating test blog...")
54
54
 
55
55
  system("rm -rf .blogs")
56
- RuneBlog.create_new_blog_repo(".blogs")
57
- x = RuneBlog.new(".blogs")
56
+ RuneBlog.create_new_blog_repo # (".blogs")
57
+ x = RuneBlog.new # (".blogs")
58
58
 
59
59
  debug("create_view: #{bold('around_austin')}")
60
60
  x.create_view("around_austin") # FIXME remember view title!
61
61
 
62
- #### FIXME later!!
63
- vars = <<-VARS
64
-
65
- .variables
66
- blog Around Austin
67
- blog.desc The view from downtown...
62
+ #### FIXME
68
63
 
69
- font.family verdana
70
- .end
64
+ vars = <<-VARS
65
+ author Hal Fulton
66
+ title Around Austin
67
+ subtitle The view from downtown...
68
+ domain foo.com
71
69
  VARS
72
- File.open(".blogs/views/around_austin/themes/standard/global.lt3", "a") do |f|
73
- f.puts vars
74
- end
70
+ vfile = ".blogs/views/around_austin/settings/view.txt"
71
+ File.open(vfile, "w") {|f| f.puts vars }
72
+
75
73
  ####
76
74
 
77
- debug("-- change_view: #{bold('around_austin')}")
75
+ debug("change_view: #{bold('around_austin')}")
78
76
  x.change_view("around_austin") # 1 2 7 8 9
79
77
 
80
78
  make_post(x, "What's at Stubbs...", <<-EXCERPT, <<-BODY)
@@ -144,11 +142,10 @@ But I first heard of them
144
142
  in 2005.
145
143
  BODY
146
144
 
147
- debug
148
- debug "** generate_index #{bold("around_austin")}"
145
+ debug "generate_index #{bold("around_austin")}"
149
146
  x.generate_index("around_austin")
150
147
 
151
- debug("** generate_view: #{bold('around_austin')}")
148
+ debug("generate_view: #{bold('around_austin')}")
152
149
  x.generate_view("around_austin")
153
150
 
154
151
  debug bold("...finished.\n")
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.96
4
+ version: 0.3.03
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-12-24 00:00:00.000000000 Z
11
+ date: 2019-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: livetext
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.8'
19
+ version: '0.9'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.8.99
22
+ version: 0.9.01
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0.8'
29
+ version: '0.9'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.8.99
32
+ version: 0.9.01
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rubytext
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -85,6 +85,7 @@ files:
85
85
  - data/EDITOR
86
86
  - data/ROOT
87
87
  - data/VIEW
88
+ - data/features.txt
88
89
  - data/global.lt3
89
90
  - data/universal.lt3
90
91
  - empty_view/assets/austin-pano.jpg
@@ -109,6 +110,7 @@ files:
109
110
  - empty_view/config/twitter/twitter.rb
110
111
  - empty_view/posts/GIT_IS_DUMB
111
112
  - empty_view/remote/assets/GIT_IS_DUMB
113
+ - empty_view/remote/banner/navbar/GIT_IS_DUMB
112
114
  - empty_view/remote/etc/GIT_IS_DUMB
113
115
  - empty_view/remote/permalink/GIT_IS_DUMB
114
116
  - empty_view/remote/widgets/ad/GIT_IS_DUMB
@@ -116,6 +118,10 @@ files:
116
118
  - empty_view/remote/widgets/news/GIT_IS_DUMB
117
119
  - empty_view/remote/widgets/pages/GIT_IS_DUMB
118
120
  - empty_view/remote/widgets/pinned/GIT_IS_DUMB
121
+ - empty_view/settings/features.txt
122
+ - empty_view/settings/publish.txt
123
+ - empty_view/settings/recent.txt
124
+ - empty_view/settings/view.txt
119
125
  - empty_view/themes/standard/README
120
126
  - empty_view/themes/standard/banner/banner.lt3
121
127
  - empty_view/themes/standard/banner/navbar/about.lt3
@@ -131,7 +137,6 @@ files:
131
137
  - empty_view/themes/standard/etc/externals.lt3
132
138
  - empty_view/themes/standard/etc/favicon.ico
133
139
  - empty_view/themes/standard/etc/misc.js
134
- - empty_view/themes/standard/global.lt3
135
140
  - empty_view/themes/standard/post/generate.lt3
136
141
  - empty_view/themes/standard/post/head.lt3
137
142
  - empty_view/themes/standard/post/index.lt3
@@ -1,35 +0,0 @@
1
- . --------------------------------------------------
2
- . Global settings are stored here in the form
3
- . <variable> <value>
4
- . --------------------------------------------------
5
-
6
- .variables
7
- author Your name here
8
- blog Blog title goes here
9
- blog.desc Subtitle (if any) goes here
10
- site rubyhacker.com
11
-
12
- host localhost:4000//
13
- charset utf-8
14
- url localhost:4000//
15
- locale en_US
16
-
17
- font.family verdana
18
-
19
- post.title.color #010101
20
- post.title.size 28px
21
-
22
- post.text.color #0101a1
23
- post.text.size 22px
24
-
25
- post.date.color #9a9a9a
26
- post.date.size 15px
27
-
28
-
29
- publish.user root
30
- publish.server rubyhacker.com
31
- publish.docroot /var/www/
32
- publish.path stuff
33
- publish.proto http
34
- .end
35
-