mayuki 0.0.1
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.
- data/bin/mayuki +44 -0
- data/lib/mayuki.rb +188 -0
- data/lib/mayuki/liquid_filter.rb +33 -0
- data/lib/mayuki/version.rb +4 -0
- metadata +100 -0
data/bin/mayuki
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require 'mayuki/version.rb'
|
6
|
+
|
7
|
+
help = "Usage: mayuki [options]"
|
8
|
+
|
9
|
+
options = {}
|
10
|
+
OptionParser.new do |opts|
|
11
|
+
opts.banner = help
|
12
|
+
|
13
|
+
opts.on("--preview [PORT]", "--server [PORT]", "Start web server (default port 4000)") do |port|
|
14
|
+
options[:server] = true
|
15
|
+
if port.nil?
|
16
|
+
options[:server_port] = 4000
|
17
|
+
else
|
18
|
+
options[:server_port] = port
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on("--version", "Display current version") do
|
23
|
+
puts "Mayuki " + Mayuki::VERSION
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
end.parse!
|
27
|
+
|
28
|
+
require 'mayuki'
|
29
|
+
dir_o = Mayuki::mayuki
|
30
|
+
|
31
|
+
if options[:server]
|
32
|
+
require 'webrick'
|
33
|
+
include WEBrick
|
34
|
+
|
35
|
+
mime_types = WEBrick::HTTPUtils::DefaultMimeTypes
|
36
|
+
mime_types.store("js", "application/javascript")
|
37
|
+
|
38
|
+
s = HTTPServer.new(:Port => options[:server_port], :MimeTypes => mime_types)
|
39
|
+
s.mount("/", HTTPServlet::FileHandler, dir_o)
|
40
|
+
t = Thread.new { s.start }
|
41
|
+
|
42
|
+
trap("INT") { s.shutdown }
|
43
|
+
t.join()
|
44
|
+
end
|
data/lib/mayuki.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'liquid'
|
2
|
+
require 'rdiscount'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'mayuki/liquid_filter.rb'
|
6
|
+
|
7
|
+
module Mayuki
|
8
|
+
|
9
|
+
def self.mayuki(input_dir = ".")
|
10
|
+
|
11
|
+
# Set default configuration
|
12
|
+
conf_global = {
|
13
|
+
"_output" => File.join(input_dir, "_output"),
|
14
|
+
"_render" => ["liquid"],
|
15
|
+
"_export" => [],
|
16
|
+
"_pygments" => false
|
17
|
+
}
|
18
|
+
|
19
|
+
# Load global configuration
|
20
|
+
Dir[File.join(input_dir, "_conf*/*"),
|
21
|
+
File.join(input_dir, "_conf*.yaml"),
|
22
|
+
File.join(input_dir, "_conf*.yml")
|
23
|
+
].each do |f|
|
24
|
+
begin
|
25
|
+
conf_global.merge!(YAML.load_file(f))
|
26
|
+
rescue
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prepare global output directory
|
31
|
+
Dir.mkdir(conf_global["_output"]) unless Dir.exist?(conf_global["_output"])
|
32
|
+
|
33
|
+
# Recurse each directory
|
34
|
+
Dir[File.join(input_dir, "/"), File.join(input_dir, "**/*/")].each do |d|
|
35
|
+
|
36
|
+
# Strip relative path
|
37
|
+
rel = d.split(File.join(input_dir, "/"))[1]
|
38
|
+
rel = "." unless rel
|
39
|
+
|
40
|
+
# Skip if the directory is intended to be ignored
|
41
|
+
next if not d.split("/").reduce(true) { |result, elem| result and elem[0] != "_" }
|
42
|
+
|
43
|
+
# Get global configuration
|
44
|
+
conf = Hash[conf_global]
|
45
|
+
|
46
|
+
# Load local configuration
|
47
|
+
Dir[File.join(d, "_conf*/*"),
|
48
|
+
File.join(d, "_conf*.yaml"),
|
49
|
+
File.join(d, "_conf*.yml")
|
50
|
+
].each do |f|
|
51
|
+
begin
|
52
|
+
conf.merge!(YAML.load_file(f))
|
53
|
+
rescue
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Prepare local output directory
|
58
|
+
Dir.mkdir(conf["_output"]) unless Dir.exist?(conf["_output"])
|
59
|
+
Dir.mkdir(File.join(conf["_output"], rel)) unless Dir.exist?(File.join(conf["_output"], rel))
|
60
|
+
|
61
|
+
# Process each file
|
62
|
+
Dir[File.join(d, "*")].each do |f|
|
63
|
+
|
64
|
+
# Skip if it is a directory
|
65
|
+
next if not File.file?(f)
|
66
|
+
|
67
|
+
# Skip if the file is intended to be ignored
|
68
|
+
next if File.basename(f).start_with?("_")
|
69
|
+
|
70
|
+
# Get local configuration
|
71
|
+
conf_infile = Hash[conf]
|
72
|
+
|
73
|
+
# Markdown / HTML file (parsing)
|
74
|
+
if [".markdown", ".md",
|
75
|
+
".htm", ".html"
|
76
|
+
].index(File.extname(f))
|
77
|
+
|
78
|
+
# Read text and metadata
|
79
|
+
part1, sep, part2 = IO.read(f).partition("\n---")
|
80
|
+
if sep == ""
|
81
|
+
text = part1
|
82
|
+
else
|
83
|
+
yaml, text = [part1, part2]
|
84
|
+
|
85
|
+
# Load in-file configuration
|
86
|
+
begin
|
87
|
+
conf_infile.merge!(YAML.load(yaml))
|
88
|
+
rescue
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Set environment variables for filter module
|
93
|
+
$dir_i = d
|
94
|
+
$dir_o = File.join(conf_infile["_output"], rel)
|
95
|
+
|
96
|
+
# Render text
|
97
|
+
["liquid", "markdown"].each do |r|
|
98
|
+
if conf_infile["_render"].index(r)
|
99
|
+
text = method("render_" + r).call(text)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Export text
|
104
|
+
if conf_infile["_export"].index("html")
|
105
|
+
|
106
|
+
text = export_html(text, conf_infile)
|
107
|
+
IO.write(File.join(conf_infile["_output"], rel, File.basename(f, File.extname(f)) + ".html"), text)
|
108
|
+
|
109
|
+
elsif conf_infile["_export"].index("html_article")
|
110
|
+
|
111
|
+
text = export_html_article(text, conf_infile)
|
112
|
+
IO.write(File.join(conf_infile["_output"], rel, File.basename(f, File.extname(f)) + ".html"), text)
|
113
|
+
|
114
|
+
elsif conf_infile["_export"].index("html_full")
|
115
|
+
|
116
|
+
text = export_html_full(text, conf_infile)
|
117
|
+
IO.write(File.join(conf_infile["_output"], rel, File.basename(f, File.extname(f)) + ".html"), text)
|
118
|
+
|
119
|
+
else
|
120
|
+
|
121
|
+
text = yaml + "\n---\n" + text if sep != ""
|
122
|
+
IO.write(File.join(conf_infile["_output"], rel, File.basename(f)), text)
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
# Export pygments stylesheet (_pygments.css)
|
127
|
+
if conf_infile["_pygments"]
|
128
|
+
IO.write(File.join(conf_infile["_output"], rel, "_pygments.css"),
|
129
|
+
".pygments td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n"\
|
130
|
+
".pygments span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n"\
|
131
|
+
".pygments pre { line-height: 125%; }\n")
|
132
|
+
|
133
|
+
system("pygmentize -f html -S default -a .pygments "\
|
134
|
+
">> #{File.join(conf_infile["_output"], rel, "_pygments.css")}")
|
135
|
+
end
|
136
|
+
|
137
|
+
# Other file (copying)
|
138
|
+
else
|
139
|
+
|
140
|
+
# Read text
|
141
|
+
text = IO.read(f)
|
142
|
+
|
143
|
+
# Export text
|
144
|
+
IO.write(File.join(conf_infile["_output"], rel, File.basename(f)), text)
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
conf_global["_output"]
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.render_liquid(text)
|
157
|
+
Liquid::Template.parse(text).render({}, :filters => [LiquidFilter])
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.render_markdown(text)
|
161
|
+
RDiscount.new(text).to_html
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.export_html(text, conf)
|
165
|
+
(conf["_pygments"] ? "<link href='_pygments.css' rel='stylesheet'>\n" : "") +
|
166
|
+
"#{text}"
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.export_html_article(text, conf)
|
170
|
+
(conf["_pygments"] ? "<link href='_pygments.css' rel='stylesheet'>\n" : "") +
|
171
|
+
"<article>\n"\
|
172
|
+
"#{text}"\
|
173
|
+
"\n</article>"
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.export_html_full(text, conf)
|
177
|
+
"<!DOCTYPE html>\n"\
|
178
|
+
"<html>\n"\
|
179
|
+
"<head>\n" +
|
180
|
+
(conf["_pygments"] ? "<link href='_pygments.css' rel='stylesheet'>\n" : "") +
|
181
|
+
"</head>\n"\
|
182
|
+
"<body>\n<article>\n"\
|
183
|
+
"#{text}"\
|
184
|
+
"\n</article>\n</body>"\
|
185
|
+
"\n</html>"
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module LiquidFilter
|
2
|
+
|
3
|
+
def source(input, lang)
|
4
|
+
system("pygmentize -f html -l #{lang} -O linenos=1 "\
|
5
|
+
"-o #{File.join($dir_o, input)}.html #{File.join($dir_i, input)}")
|
6
|
+
text = IO.read(File.join($dir_o, "#{input}.html"))
|
7
|
+
File.delete(File.join($dir_o, "#{input}.html"))
|
8
|
+
|
9
|
+
"<blockquote>\n"\
|
10
|
+
"<div class='pygments'>\n"\
|
11
|
+
"#{text}"\
|
12
|
+
"\n</div>"\
|
13
|
+
"\n</blockquote>"
|
14
|
+
end
|
15
|
+
|
16
|
+
def src(input, lang)
|
17
|
+
source(input, lang)
|
18
|
+
end
|
19
|
+
|
20
|
+
def code(input)
|
21
|
+
system("pygmentize -f html -O linenos=1 "\
|
22
|
+
"-o #{File.join($dir_o, input)}.html #{File.join($dir_i, input)}")
|
23
|
+
text = IO.read(File.join($dir_o, "#{input}.html"))
|
24
|
+
File.delete(File.join($dir_o, "#{input}.html"))
|
25
|
+
|
26
|
+
"<blockquote>\n"\
|
27
|
+
"<div class='pygments'>\n"\
|
28
|
+
"#{text}"\
|
29
|
+
"\n</div>"\
|
30
|
+
"\n</blockquote>"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mayuki
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mort Yao
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: liquid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.3'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rdiscount
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.6'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.6'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.9'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
description: Mayuki is a minimalist Markdown/YAML-based static wiki generator.
|
63
|
+
email: mort.yao@gmail.com
|
64
|
+
executables:
|
65
|
+
- mayuki
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- bin/mayuki
|
70
|
+
- lib/mayuki.rb
|
71
|
+
- lib/mayuki/liquid_filter.rb
|
72
|
+
- lib/mayuki/version.rb
|
73
|
+
homepage: https://github.com/soimort/mayuki
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements:
|
93
|
+
- Pygments >= 1.5
|
94
|
+
- Git >= 1.7
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.8.23
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: Markdown/YAML-based static wiki generator.
|
100
|
+
test_files: []
|