runeblog 0.2.98 → 0.3.04
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 +4 -4
- data/bin/blog +16 -12
- data/data/features.txt +18 -0
- data/data/global.lt3 +6 -24
- data/data/universal.lt3 +2 -5
- data/empty_view/remote/banner/navbar/GIT_IS_DUMB +0 -0
- data/empty_view/settings/features.txt +18 -0
- data/empty_view/settings/publish.txt +5 -0
- data/empty_view/settings/recent.txt +11 -0
- data/empty_view/settings/view.txt +4 -0
- data/empty_view/themes/standard/banner/top.lt3 +2 -2
- data/lib/helpers-blog.rb +26 -20
- data/lib/liveblog.rb +18 -11
- data/lib/processing.rb +6 -2
- data/lib/publish.rb +2 -0
- data/lib/repl.rb +22 -16
- data/lib/runeblog.rb +109 -43
- data/lib/runeblog_version.rb +1 -1
- data/lib/view.rb +6 -0
- data/runeblog.gemspec +1 -1
- data/test/austin.rb +15 -18
- metadata +12 -8
- data/empty_view/themes/standard/global.lt3 +0 -32
- data/empty_view/themes/standard/recent.txt +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fad63c680c64fff5ca7fab06ee3c95a2d1b51f4bd4d3c0e74b21b917599f9086
|
4
|
+
data.tar.gz: '0906af618397683f84fd78d43b6f7742fbc64d9872290ea96067447079f45637'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0aa69a9da231a7fa90f64f86ebcf0d4d1cc135d59682f5fb313b129374a8e976011578ad1f962baca9fbe0a095134b7d22d185a542f195f317ed0d56e6172a4
|
7
|
+
data.tar.gz: da1e4bd77770d91aa872fe61d2a8e17fad3f26fbc5ed766a84adb15c5087a780e57940a6ceebf5656e169bde4b05a439d138e696c00ef1c7fd8b2ab2b15c330c
|
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!("\
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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!("\
|
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)
|
data/data/features.txt
ADDED
@@ -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)
|
data/data/global.lt3
CHANGED
@@ -3,12 +3,13 @@
|
|
3
3
|
. <variable> <value>
|
4
4
|
. --------------------------------------------------
|
5
5
|
|
6
|
-
.variables
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
@@ -17,22 +18,3 @@ locale en_US
|
|
17
18
|
font.family verdana
|
18
19
|
.end
|
19
20
|
|
20
|
-
.variables recent
|
21
|
-
title.color #010101
|
22
|
-
title.size 28px
|
23
|
-
|
24
|
-
text.color #0101a1
|
25
|
-
text.size 22px
|
26
|
-
|
27
|
-
date.color #9a9a9a
|
28
|
-
date.size 15px
|
29
|
-
.end
|
30
|
-
|
31
|
-
.variables publish
|
32
|
-
user root
|
33
|
-
server SITE
|
34
|
-
docroot /var/www/
|
35
|
-
path VIEW_NAME
|
36
|
-
proto http
|
37
|
-
.end
|
38
|
-
|
data/data/universal.lt3
CHANGED
File without changes
|
@@ -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)
|
@@ -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>$
|
19
|
-
<text x="45" y="98" class=small>$
|
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>
|
data/lib/helpers-blog.rb
CHANGED
@@ -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
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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")
|
data/lib/liveblog.rb
CHANGED
@@ -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 =
|
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 %[ <a data-toggle="collapse" href="##{id}" role="button" aria-expanded="false" aria-controls="collapseExample"><font size=+3>⌄</font></a>]
|
111
111
|
_out %[ <b>#{ques}</b>]
|
112
112
|
_out %[<div class="collapse" id="#{id}"><br><font size=+1> #{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[
|
245
|
-
<text text-anchor="#{align2}" x="#{x2}" y="#{y2}" class="subtitle">#{Livetext::Vars["
|
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(
|
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(
|
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("
|
447
|
-
"og:description" => %[<meta property="og:description" content="#{_var("
|
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(
|
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(
|
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(
|
692
|
+
title = _var("view.title")
|
686
693
|
|
687
694
|
if orient == :horiz
|
688
695
|
name = "navbar.html"
|
data/lib/processing.rb
CHANGED
@@ -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:
|
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
|
-
|
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
|
data/lib/publish.rb
CHANGED
@@ -16,6 +16,8 @@ class RuneBlog::Publishing
|
|
16
16
|
@blog = RuneBlog.blog
|
17
17
|
dir = @blog.root/:views/view/"themes/standard/"
|
18
18
|
gfile = dir/"global.lt3"
|
19
|
+
return unless File.exist?(gfile) # FIXME Hackish as hell
|
20
|
+
|
19
21
|
live = get_live_vars(gfile)
|
20
22
|
@user = live.vars["publish.user"]
|
21
23
|
@server = live.vars["publish.server"]
|
data/lib/repl.rb
CHANGED
@@ -14,20 +14,21 @@ module RuneBlog::REPL
|
|
14
14
|
result = system!("#{@blog.editor} #{file} #{params}")
|
15
15
|
raise EditorProblem(file) unless result
|
16
16
|
STDSCR.restback
|
17
|
-
|
17
|
+
cmd_clear(nil)
|
18
18
|
end
|
19
19
|
|
20
20
|
def cmd_quit(arg, testing = false)
|
21
21
|
cmd_clear(nil)
|
22
|
+
sleep 0.1
|
22
23
|
RubyText.stop
|
23
24
|
sleep 0.1
|
24
|
-
|
25
|
+
system("clear")
|
25
26
|
sleep 0.1
|
26
27
|
exit
|
27
28
|
end
|
28
29
|
|
29
30
|
def cmd_clear(arg, testing = false)
|
30
|
-
|
31
|
+
STDSCR.rows.times { puts " "*(STDSCR.cols-1) }
|
31
32
|
STDSCR.clear
|
32
33
|
end
|
33
34
|
|
@@ -39,19 +40,24 @@ module RuneBlog::REPL
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def cmd_config(arg, testing = false)
|
42
|
-
hash = {"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"
|
52
|
-
"
|
53
|
-
"
|
54
|
-
"
|
43
|
+
hash = {"Global configuration" => "global.lt3",
|
44
|
+
" View-specific variables" => "../../settings/view.txt",
|
45
|
+
" Recent posts" => "../../settings/recent.txt",
|
46
|
+
" Publishing vars" => "../../settings/publish.txt",
|
47
|
+
" Config for reddit" => "../../config/reddit/credentials.txt",
|
48
|
+
" Config for Facebook" => "../../config/facebook/credentials.txt",
|
49
|
+
" Config for Twitter" => "../../config/twitter/credentials.txt",
|
50
|
+
"View generator" => "blog/generate.lt3",
|
51
|
+
" Banner: Description" => "blog/banner.lt3",
|
52
|
+
" Banner: Text portion" => "banner/top.lt3",
|
53
|
+
" HEAD info for view" => "blog/head.lt3",
|
54
|
+
" User-edited detail for view" => "blog/index.lt3",
|
55
|
+
" Generator for recent-posts entry" => "blog/post_entry.lt3",
|
56
|
+
"Generator for a post" => "post/generate.lt3",
|
57
|
+
" HEAD info for post" => "post/head.lt3",
|
58
|
+
" Content for post" => "post/index.lt3",
|
59
|
+
"Global CSS" => "etc/blog.css.lt3",
|
60
|
+
"External JS/CSS (Bootstrap, etc.)" => "/etc/externals.lt3"
|
55
61
|
}
|
56
62
|
|
57
63
|
dir = @blog.view.dir/"themes/standard/"
|
data/lib/runeblog.rb
CHANGED
@@ -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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
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")
|
@@ -244,11 +295,15 @@ class RuneBlog
|
|
244
295
|
@view = nil
|
245
296
|
when RuneBlog::View
|
246
297
|
@view = arg
|
298
|
+
read_features(@view)
|
299
|
+
@view.get_globals
|
247
300
|
_set_publisher
|
248
301
|
when String
|
249
302
|
new_view = str2view(arg)
|
250
303
|
raise NoSuchView(arg) if new_view.nil?
|
251
304
|
@view = new_view
|
305
|
+
read_features(@view)
|
306
|
+
@view.get_globals
|
252
307
|
_set_publisher
|
253
308
|
else
|
254
309
|
raise CantAssignView(arg.class.to_s)
|
@@ -324,6 +379,7 @@ class RuneBlog
|
|
324
379
|
add_view(view_name)
|
325
380
|
mark_last_published("Initial creation")
|
326
381
|
system("cp #@root/data/global.lt3 #@root/views/#{view_name}/themes/standard/global.lt3")
|
382
|
+
@view.get_globals
|
327
383
|
rescue => err
|
328
384
|
_tmp_error(err)
|
329
385
|
end
|
@@ -373,7 +429,7 @@ class RuneBlog
|
|
373
429
|
html = "/tmp/post_entry.html"
|
374
430
|
preprocess src: post_entry_name, dst: html,
|
375
431
|
call: ".nopara" # , deps: depend # , debug: true
|
376
|
-
@_post_entry
|
432
|
+
@_post_entry = File.read(html)
|
377
433
|
vp = post_lookup(id)
|
378
434
|
nslug, aslug, title, date, teaser_text =
|
379
435
|
vp.nslug, vp.aslug, vp.title, vp.date, vp.teaser_text
|
@@ -404,16 +460,18 @@ class RuneBlog
|
|
404
460
|
return posts[0..19] # return 20 at most
|
405
461
|
end
|
406
462
|
|
407
|
-
def collect_recent_posts(file)
|
463
|
+
def collect_recent_posts(file = "recent.html")
|
408
464
|
log!(enter: __method__, args: [file], level: 3)
|
465
|
+
vars = self.view.globals
|
409
466
|
text = <<-HTML
|
410
467
|
<html>
|
411
468
|
<head><link rel="stylesheet" href="etc/blog.css"></head>
|
412
|
-
<body>
|
469
|
+
<body style="background-color: #{vars["recent.bgcolor"]}">
|
413
470
|
HTML
|
414
471
|
posts = _sorted_posts
|
415
472
|
if posts.size > 0
|
416
|
-
|
473
|
+
# estimate how many we want
|
474
|
+
wanted = [vars["recent.count"].to_i, posts.size].min
|
417
475
|
enum = posts.each
|
418
476
|
entries = []
|
419
477
|
wanted.times do
|
@@ -485,7 +543,7 @@ class RuneBlog
|
|
485
543
|
log!(enter: __method__, args: [view], pwd: true, dir: true)
|
486
544
|
raise ArgumentError unless view.is_a?(String) || view.is_a?(RuneBlog::View)
|
487
545
|
@vdir = @root/:views/view
|
488
|
-
num = collect_recent_posts
|
546
|
+
num = collect_recent_posts
|
489
547
|
return num
|
490
548
|
rescue => err
|
491
549
|
_tmp_error(err)
|
@@ -499,15 +557,14 @@ class RuneBlog
|
|
499
557
|
@theme/"blog/head.lt3",
|
500
558
|
# @theme/"navbar/navbar.lt3",
|
501
559
|
@theme/"blog/index.lt3"] # FIXME what about assets?
|
502
|
-
preprocess cwd: vdir/"themes/standard/etc",
|
503
|
-
|
504
|
-
call: ".nopara" # , dst: "blog.css"
|
560
|
+
preprocess cwd: vdir/"themes/standard/etc", src: "blog.css.lt3",
|
561
|
+
copy: vdir/"remote/etc/", call: [".nopara"], strip: true
|
505
562
|
preprocess cwd: vdir/"themes/standard", deps: depend, force: true,
|
506
563
|
src: "blog/generate.lt3", dst: vdir/:remote/"index.html",
|
507
564
|
call: ".nopara"
|
508
565
|
copy!("#{vdir}/themes/standard/banner/*", "#{vdir}/remote/banner/") # includes navbar/
|
509
566
|
copy("#{vdir}/assets/*", "#{vdir}/remote/assets/")
|
510
|
-
# rebuild widgets
|
567
|
+
# rebuild widgets?
|
511
568
|
copy_widget_html(view)
|
512
569
|
rescue => err
|
513
570
|
STDERR.puts err
|
@@ -515,6 +572,27 @@ class RuneBlog
|
|
515
572
|
# _tmp_error(err)
|
516
573
|
end
|
517
574
|
|
575
|
+
def _get_draft_data(num, sym)
|
576
|
+
tag = prefix(num)
|
577
|
+
front = @blog.root/:drafts/tag
|
578
|
+
files = Dir[front + "*"]
|
579
|
+
raise "No draft #{num} found" if files.empty?
|
580
|
+
raise "Too many files found for #{num}!" if files.size > 1
|
581
|
+
file = files.first
|
582
|
+
lines = File.readlines(file)
|
583
|
+
case sym
|
584
|
+
when :views
|
585
|
+
view_line = lines.grep(/^.views /)
|
586
|
+
raise "More than one .views call in #{draft}" if view_line.size > 1
|
587
|
+
raise "No .views call in #{draft}" if view_line.size < 1
|
588
|
+
view_line = view_line.first
|
589
|
+
views = view_line[7..-1].split
|
590
|
+
return views.uniq
|
591
|
+
else
|
592
|
+
raise "Unknown symbol #{sym.inspect}"
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
518
596
|
def _get_views(draft)
|
519
597
|
log!(enter: __method__, args: [draft], level: 2)
|
520
598
|
# FIXME dumb code
|
@@ -604,6 +682,8 @@ class RuneBlog
|
|
604
682
|
log!(enter: __method__, args: [draft, view_name], level: 2)
|
605
683
|
# break into separate methods?
|
606
684
|
|
685
|
+
return unless _check_view?(view_name)
|
686
|
+
|
607
687
|
fname = File.basename(draft) # 0001-this-is-a-post.lt3
|
608
688
|
nslug = fname.sub(/.lt3$/, "") # 0001-this-is-a-post
|
609
689
|
aslug = nslug.sub(/\d\d\d\d-/, "") # this-is-a-post
|
@@ -633,30 +713,16 @@ class RuneBlog
|
|
633
713
|
_tmp_error(err)
|
634
714
|
end
|
635
715
|
|
716
|
+
def _check_view?(view)
|
717
|
+
flag = self.view?(view)
|
718
|
+
puts " Warning: '#{view}' is not a view" unless flag
|
719
|
+
flag
|
720
|
+
end
|
721
|
+
|
636
722
|
def generate_post(draft, force = false)
|
637
723
|
log!(enter: __method__, args: [draft], level: 1)
|
638
724
|
views = _get_views(draft)
|
639
|
-
views.each
|
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!
|
725
|
+
views.each {|view| _handle_post(draft, view) }
|
660
726
|
rescue => err
|
661
727
|
_tmp_error(err)
|
662
728
|
end
|
data/lib/runeblog_version.rb
CHANGED
data/lib/view.rb
CHANGED
@@ -14,7 +14,13 @@ class RuneBlog::View
|
|
14
14
|
@publisher = RuneBlog::Publishing.new(name)
|
15
15
|
@can_publish = true # FIXME
|
16
16
|
@blog.view = self
|
17
|
+
get_globals
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_globals
|
17
21
|
gfile = @blog.root/"views/#{name}/themes/standard/global.lt3"
|
22
|
+
return unless File.exist?(gfile) # Hackish!! how is View.new called from create_view??
|
23
|
+
|
18
24
|
live = Livetext.customize(call: ".nopara")
|
19
25
|
live.xform_file(gfile)
|
20
26
|
@globals = live.vars
|
data/runeblog.gemspec
CHANGED
@@ -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.
|
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'
|
data/test/austin.rb
CHANGED
@@ -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 "
|
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
|
63
|
-
vars = <<-VARS
|
64
|
-
|
65
|
-
.variables
|
66
|
-
blog Around Austin
|
67
|
-
blog.desc The view from downtown...
|
62
|
+
#### FIXME
|
68
63
|
|
69
|
-
|
70
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
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("
|
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("
|
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.
|
4
|
+
version: 0.3.04
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hal Fulton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-01 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.
|
19
|
+
version: '0.9'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
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.
|
29
|
+
version: '0.9'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
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,12 +137,10 @@ 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
|
138
143
|
- empty_view/themes/standard/post/permalink.lt3
|
139
|
-
- empty_view/themes/standard/recent.txt
|
140
144
|
- empty_view/themes/standard/widgets/README
|
141
145
|
- empty_view/themes/standard/widgets/ad/ad.lt3
|
142
146
|
- empty_view/themes/standard/widgets/ad/ad1.png
|
@@ -1,32 +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
|
-
recent.title.color #010101
|
20
|
-
recent.title.size 28px
|
21
|
-
recent.text.color #0101a1
|
22
|
-
recent.text.size 22px
|
23
|
-
recent.date.color #9a9a9a
|
24
|
-
recent.date.size 15px
|
25
|
-
|
26
|
-
publish.user root
|
27
|
-
publish.server rubyhacker.com
|
28
|
-
publish.docroot /var/www/
|
29
|
-
publish.path stuff
|
30
|
-
publish.proto http
|
31
|
-
.end
|
32
|
-
|