schizm 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6f84ad79aced293697aa2a4377ef3e2e441c437e
4
+ data.tar.gz: 28a1c9d028c5de7ca4e1c73894d5c04ab860810d
5
+ SHA512:
6
+ metadata.gz: c305dee798979981a5eba2ffc1c2609d945afa2b5aea5da14fc134935c8494ea27e29eeb67ed01c114ee474b831cca81683b1c5268591d3ca232f775769eeb9a
7
+ data.tar.gz: 4a10c89712aa6365cf1e4e31053a12f42231f6aac038b9ee74d403c314734d6511a28d30424cf1acc6d169c22e3e6d91dd1fc2ea1abbd999b7a989121bf0081c
data/bin/schizm ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require_relative "../lib/schizm/env.rb"
4
+ require_relative "../lib/schizm/chunk.rb"
5
+ require_relative "../lib/schizm/match.rb"
6
+ require_relative "../lib/schizm/parse.rb"
7
+ require_relative "../lib/schizm/markup.rb"
8
+ require_relative "../lib/schizm/string.rb"
9
+
10
+ case ARGV.shift
11
+ when "init"
12
+ Schizm::Env::Opts.init.order!
13
+ Schizm::Env.init
14
+ when "build"
15
+ Schizm::Env::Opts.build.order!
16
+ Schizm::Env.build
17
+ when "install-path"
18
+ puts Schizm::Env.home
19
+ exit 0
20
+ when "info"
21
+ # TODO
22
+ exit 0
23
+ else
24
+ puts <<HELP
25
+ Usage: schizm MODE [OPTIONS]
26
+ `schizm init [OPTIONS]`
27
+ \tNew project in working directory.
28
+ `schizm build [OPTIONS]`
29
+ \tBuild project in working directory.
30
+ `schizm install-path`
31
+ \tDisplay schizm's install directory.
32
+ `schizm info`
33
+ \tDisplay additional information.
34
+ HELP
35
+ exit 0
36
+ end
@@ -0,0 +1,130 @@
1
+ require_relative 'env'
2
+ require_relative 'string'
3
+ require_relative 'match'
4
+
5
+ module Schizm
6
+
7
+ class Chunk
8
+
9
+ def initialize where, label
10
+ @where = String.new where
11
+ @label = String.new label
12
+ @share = Env.var[:share] if Env.var? :share
13
+ @target = nil
14
+ @blocks = Array.new
15
+ @labels = Array.new
16
+ @params = Hash.new
17
+ end
18
+
19
+ attr_reader :where
20
+ attr_reader :label
21
+ attr_accessor :share
22
+ attr_accessor :target
23
+ attr_accessor :blocks
24
+
25
+ # Boolean reader for +@share+.
26
+ def share?
27
+ case
28
+ when (@share == true) then return true
29
+ when (@share != true) then return false
30
+ end
31
+ end
32
+
33
+ # Boolean reader for +@target+.
34
+ def target?
35
+ return false unless @target.is_a? ::String
36
+ return false unless @target != ""
37
+ return true
38
+ end
39
+
40
+ # Hash organizing active chunks by +@where+ and +@label+.
41
+ @@hash =
42
+ Hash.new do |hash, where|
43
+ hash[where] =
44
+ Hash.new do |hash, label|
45
+ hash[label] = Chunk.new where, label
46
+ end
47
+ end
48
+
49
+ # Hash reader.
50
+ def self.hash
51
+ @@hash
52
+ end
53
+
54
+ # Hash iteration interface.
55
+ def self.each
56
+ @@hash.each do |where, hash|
57
+ hash.each do |label, chunk|
58
+ yield chunk
59
+ end
60
+ end
61
+ end
62
+
63
+ # Push a code block.
64
+ def push block, label = nil
65
+ block = String.new block
66
+ label = String.new label if label
67
+ @blocks.push block
68
+ @labels.push label
69
+ end
70
+
71
+ # Find a chunk relative to +self+. That is, consider only
72
+ # chunks defined in the same file, plus chunks shared with the
73
+ # entire project.
74
+ def find label
75
+ Chunk.each do |chunk|
76
+ if chunk.label == label and
77
+ (chunk.where == @where or chunk.share?)
78
+ return chunk
79
+ end
80
+ end
81
+ nil
82
+ end
83
+
84
+ # Resolve chunk references to generate the final source string.
85
+ def to_s *trace
86
+ if trace.include? @label
87
+ raise "Infinite recursion!"
88
+ end
89
+ total = String.new(@blocks.join "\n\n")
90
+ total.trim!
91
+ while true
92
+ unless (total.sub! CHUNK_LABEL do
93
+ if (chunk = find $1)
94
+ replace = chunk.to_s *trace, @label
95
+ replace.gsub /(?<=\n)/, " " * String.new($`).find_indent
96
+ else
97
+ "/* " + $1 + " ... */"
98
+ end
99
+ end)
100
+ break
101
+ end
102
+ end
103
+ if target?
104
+ if Env.var? :guard and @target =~ HEADER_PATH
105
+ guardify = String.new(@target).guardify
106
+ if Env.var? :title
107
+ guardify.prepend "_"
108
+ guardify.prepend String.new(Env.var[:title]).guardify
109
+ end
110
+ total.prepend "\#define #{guardify}\n\n"
111
+ total.prepend "\#ifndef #{guardify}\n"
112
+ total.concat "\n\n"
113
+ total.concat "\#endif /* \#ifndef #{guardify} */"
114
+ end
115
+ if File.file? "LICENSE"
116
+ total.prepend "\n"
117
+ total.prepend String.new(File.read("LICENSE")).comment
118
+ end
119
+ end
120
+ total
121
+ end
122
+
123
+ # Identifier for a particular block.
124
+ def id block = @blocks.size
125
+ "#{@label.slugify}-#{block}"
126
+ end
127
+
128
+ end
129
+
130
+ end
data/lib/schizm/env.rb ADDED
@@ -0,0 +1,421 @@
1
+ require 'etc'
2
+ require 'optparse'
3
+ require 'pathname'
4
+ require 'tempfile'
5
+ require 'sass'
6
+ require_relative 'env_colors'
7
+
8
+ module Schizm
9
+
10
+ module Env
11
+
12
+ @@var = {}
13
+
14
+ def self.var
15
+ return @@var
16
+ end
17
+
18
+ def self.var? key
19
+ return true if @@var.has_key?(key) and
20
+ @@var[key] != nil and @@var[key] != false
21
+ return false
22
+ end
23
+
24
+ # Prompt yes/no question.
25
+ def self.yes? string, backup
26
+ backup = backup.downcase[0]
27
+ print "#{string} [Y/n] " if backup == "y"
28
+ print "#{string} [y/N] " if backup == "n"
29
+ answer = gets.strip.downcase[0]
30
+ return answer == "y" if answer != ""
31
+ return backup == "y"
32
+ end
33
+
34
+ def self.write target, string
35
+ if (not File.file? target or
36
+ var? :rewrite or
37
+ yes? "Rewrite '#{target}'?", "n")
38
+ puts "Writing '#{target}'" if var? :verbose
39
+ file = File.open target, "wb"
40
+ file.write string.to_s
41
+ file.close
42
+ end
43
+ end
44
+
45
+ # Current user's name.
46
+ def self.thisuser
47
+ return Etc.getpwnam(Etc.getlogin).gecos.split(/,/).first
48
+ end
49
+
50
+ # Current user's working directory.
51
+ def self.thisdirname
52
+ return File.basename(Dir.pwd)
53
+ end
54
+
55
+ # Current project title.
56
+ def self.title
57
+ return var[:title] if var? :title
58
+ return thisdirname
59
+ end
60
+
61
+ # Current project brief.
62
+ def self.brief
63
+ return var[:brief] if var? :brief
64
+ return ""
65
+ end
66
+
67
+ # Current project author.
68
+ def self.author
69
+ return var[:author] if var? :author
70
+ return thisuser
71
+ end
72
+
73
+ # Current project year.
74
+ def self.year
75
+ return var[:year] if var? :year
76
+ return Time.new.year.to_s
77
+ end
78
+
79
+ # Schizm install directory.
80
+ def self.home
81
+ path = File.dirname __FILE__ # $HOME/lib/schizm
82
+ path = File.dirname path # $HOME/lib
83
+ path = File.dirname path # $HOME
84
+ return File.absolute_path path
85
+ end
86
+
87
+ # Load resource from Schizm install directory.
88
+ def self.resource *args
89
+ return File.read File.join(home, "res", *args)
90
+ end
91
+
92
+ def self.init
93
+ dirnames = [
94
+ "src",
95
+ "zrc",
96
+ "docs",
97
+ "docs/assets",
98
+ "docs/assets/css",
99
+ "docs/assets/fonts",
100
+ "docs/assets/js",
101
+ "docs/_includes",
102
+ "docs/_layouts",
103
+ "docs/_plugins",
104
+ "docs/_posts",
105
+ "docs/_docs",
106
+ "docs/_site"
107
+ ]
108
+ dirnames.each do |dirname|
109
+ unless File.directory? dirname
110
+ Dir.mkdir dirname
111
+ end
112
+ end
113
+ license = ""
114
+ if var? :license
115
+ license = var[:license]
116
+ content = "Copyright (c) "
117
+ content << "#{author} #{year}\n\n"
118
+ content << "#{resource("license", license)}"
119
+ write "LICENSE", content
120
+ end
121
+ write "README.md", <<README
122
+ # #{title}
123
+ README
124
+ write "Makefile", <<MAKEFILE
125
+ SHELL := /bin/bash
126
+ MKDIR := mkdir -p
127
+ RMDIR := rm -r -f
128
+
129
+ SCHIZM := schizm
130
+ ZFLAGS := --input zrc
131
+ ZFLAGS += --output-src src
132
+ ZFLAGS += --output-doc docs/_docs
133
+ ZFLAGS += --rewrite
134
+ ZFLAGS += --verbose
135
+ ZFLAGS += --title "#{title}"
136
+ ZFLAGS += --brief "#{brief}"
137
+ ZFLAGS += --author "#{author}"
138
+ ZFLAGS += --year "#{year}"
139
+
140
+ doc:
141
+ \t@$(SCHIZM) build --only-doc $(ZFLAGS)
142
+
143
+ src:
144
+ \t@$(SCHIZM) build --only-src $(ZFLAGS)
145
+
146
+ .PHONY: doc
147
+
148
+ .PHONY: src
149
+
150
+ clean:
151
+ \t@$(RMDIR) src docs/_docs docs/_site
152
+ \t@$(MKDIR) src docs/_docs docs/_site
153
+
154
+ .PHONY: clean
155
+ MAKEFILE
156
+ write ".gitignore", <<GITIGNORE
157
+ *.swp
158
+ *.tmp
159
+ docs/_site
160
+ GITIGNORE
161
+ write "docs/_config.yaml", <<YAMLCONFIG
162
+ source: .
163
+ destination: _site
164
+ plugins_dir: _plugins
165
+ layouts_dir: _layouts
166
+ includes_dir: _includes
167
+ collections:
168
+ posts:
169
+ output: true
170
+ docs:
171
+ output: true
172
+ encoding: "utf-8"
173
+ markdown: kramdown
174
+ markdown_ext: "markdown,md"
175
+ author: "#{author}"
176
+ title: "#{title}"
177
+ brief: "#{brief}"
178
+ YAMLCONFIG
179
+ assets = {
180
+ "schizm.liquid" => "docs/_layouts",
181
+ "schizm.js" => "docs/assets/js",
182
+ "fonts/fira-code.css" => "docs/assets/fonts",
183
+ "fonts/fira-code-light.otf" => "docs/assets/fonts",
184
+ "fonts/fira-code-regular.otf" => "docs/assets/fonts",
185
+ "fonts/fira-code-medium.otf" => "docs/assets/fonts",
186
+ "fonts/fira-code-bold.otf" => "docs/assets/fonts",
187
+ "fonts/genericons-neue.css" => "docs/assets/fonts",
188
+ "fonts/genericons-neue.eot" => "docs/assets/fonts",
189
+ "fonts/genericons-neue.ttf" => "docs/assets/fonts",
190
+ "fonts/genericons-neue.woff2" => "docs/assets/fonts",
191
+ "fonts/social-logos.css" => "docs/assets/fonts",
192
+ "fonts/social-logos.eot" => "docs/assets/fonts",
193
+ "fonts/social-logos.ttf" => "docs/assets/fonts",
194
+ "fonts/social-logos.woff2" => "docs/assets/fonts"
195
+ }
196
+ assets.each do |from, to|
197
+ write File.join(to, File.basename(from)), resource(from)
198
+ end
199
+ color1 = "purple"
200
+ color2 = "teal"
201
+ color1 = var[:primary_color].downcase if var? :primary_color
202
+ color2 = var[:secondary_color].downcase if var? :secondary_color
203
+ sass_source = <<SASS
204
+ #{sass_colors color1, "primary"}
205
+ #{sass_colors color2, "secondary"}
206
+ #{resource "scss/fonts.scss"}
207
+ #{resource "scss/mixin.scss"}
208
+ #{resource "scss/style.scss"}
209
+ SASS
210
+ sass_options = {
211
+ :syntax => :scss,
212
+ :sourcemap => :none,
213
+ :style => :nested,
214
+ :cache => false
215
+ }
216
+ write "docs/assets/css/schizm.css", Sass::Engine.new(sass_source, sass_options).render
217
+ end
218
+
219
+ def self.delete dir
220
+ if Dir.exist? dir
221
+ Dir.foreach dir do |ent|
222
+ next if ent == '.'
223
+ next if ent == '..'
224
+ path = File.join dir, ent
225
+ File.delete path if File.file? path
226
+ self.delete path if File.directory? path
227
+ end
228
+ end
229
+ end
230
+
231
+ def self.blaze path
232
+ dir = ''
233
+ path = File.dirname path
234
+ path = File.absolute_path path
235
+ dirs = path.split File::SEPARATOR
236
+ dirs.each do |sub|
237
+ dir = File.join dir, sub
238
+ Dir.mkdir dir unless Dir.exist? dir
239
+ end
240
+ end
241
+
242
+ def self.path_from from, dest
243
+ from = Pathname.new from
244
+ dest = Pathname.new dest
245
+ dest.relative_path_from(from).to_s
246
+ end
247
+
248
+ def self.path_href path
249
+ "/docs/#{path_from var[:output_doc], path}"
250
+ end
251
+
252
+ def self.build
253
+ zrc_root = var[:input]
254
+ doc_root = var[:output_doc]
255
+ src_root = var[:output_src]
256
+ zrc_globs = []
257
+ zrc_globs.push File.join(zrc_root, "*.zrc")
258
+ zrc_globs.push File.join(zrc_root, "*/*.zrc")
259
+ zrc_paths = Dir.glob zrc_globs
260
+ raise "No input files." if zrc_paths.empty?
261
+ delete doc_root if var? :clean_doc
262
+ delete src_root if var? :clean_src
263
+ blaze doc_root
264
+ blaze src_root
265
+ zrc_paths.each do |path|
266
+ where = path_from zrc_root, path
267
+ where = File.join doc_root, where.chomp(".zrc").concat(".html")
268
+ input = File.read path
269
+ Parse.hash[where] =
270
+ Parse.page_elems where, input
271
+ end
272
+ unless Env.var? :only_src
273
+ Parse.hash.each do |where, parse|
274
+ blaze where
275
+ write where, <<PARSE
276
+ ---
277
+ layout: schizm
278
+ author: "#{author}"
279
+ title: "#{parse.guess_title}"
280
+ description: "#{parse.guess_description}"
281
+ #{parse.guess_parts}
282
+ ---
283
+ #{parse.to_s}
284
+ PARSE
285
+ end
286
+ end
287
+ unless Env.var? :only_doc
288
+ Chunk.each do |chunk|
289
+ if chunk.target?
290
+ blaze where = File.join(src_root, chunk.target)
291
+ write where, chunk
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+ module Opts
298
+
299
+ def self.init
300
+ OptionParser.new do |optparse|
301
+ optparse.banner = "Usage: schizm init [OPTIONS]"
302
+ optparse.on "-v", "--verbose", "Verbose messages?" do
303
+ Env.var[:verbose] = true
304
+ end
305
+ optparse.on "-r", "--rewrite", "Rewrite files without asking?" do
306
+ Env.var[:rewrite] = true
307
+ end
308
+ optparse.on "-t", "--title STR", "Set project title." do |str|
309
+ Env.var[:title] = str
310
+ end
311
+ optparse.on "-b", "--brief STR", "Set project brief." do |str|
312
+ Env.var[:brief] = str
313
+ end
314
+ optparse.on "-a", "--author STR", "Specify project author(s)." do |str|
315
+ Env.var[:author] = str
316
+ end
317
+ optparse.on "-y", "--year STR", "Specify project year(s)." do |str|
318
+ Env.var[:year] = str
319
+ end
320
+ license_enum = [
321
+ "BSD-2-Clause",
322
+ "BSD-3-Clause",
323
+ "GPL-2.0",
324
+ "GPL-3.0",
325
+ "LGPL-2.1",
326
+ "LGPL-3.0",
327
+ "MIT",
328
+ "MPL-2.0"
329
+ ]
330
+ license_help = <<LIC
331
+ Select license, none by default.
332
+ \t"BSD-2-Clause" ... the 2-clause BSD License
333
+ \t"BSD-3-Clause" ... the 3-clause BSD License
334
+ \t"GPL-2.0" ........ the GNU General Public License v2.0
335
+ \t"GPL-3.0" ........ the GNU General Public License v3.0
336
+ \t"LGPL-2.1" ....... the GNU Lesser General Public License v2.1
337
+ \t"LGPL-3.0" ....... the GNU Lesser General Public License v3.0
338
+ \t"MIT" ............ the MIT License
339
+ \t"MPL-2.0" ........ the Mozilla Public License v2.0
340
+ LIC
341
+ optparse.on "-l", "--license ENUM",
342
+ license_enum,
343
+ license_help do |str|
344
+ Env.var[:license] = str
345
+ end
346
+ optparse.on "-p", "--primary-color ENUM", Env::COLORS.keys,
347
+ "Specify primary color." do |str|
348
+ Env.var[:primary_color] = str
349
+ end
350
+ optparse.on "-s", "--secondary-color ENUM", Env::COLORS.keys,
351
+ "Specify secondary color." do |str|
352
+ Env.var[:secondary_color] = str
353
+ end
354
+ optparse.on_tail "-h", "--help", "Display this help." do
355
+ puts optparse
356
+ exit 0
357
+ end
358
+ end
359
+ end
360
+
361
+ def self.build
362
+ Env.var[:input] = "zrc"
363
+ Env.var[:output_doc] = "./docs/_docs"
364
+ Env.var[:output_src] = "./src"
365
+ Env.var[:guard] = true
366
+ OptionParser.new do |optparse|
367
+ optparse.banner = "Usage: schizm build [OPTIONS]"
368
+ optparse.on "-v", "--verbose", "Verbose messages?" do
369
+ Env.var[:verbose] = true
370
+ end
371
+ optparse.on "-r", "--rewrite", "Rewrite files without asking?" do
372
+ Env.var[:rewrite] = true
373
+ end
374
+ optparse.on "-t", "--title STR", "Set project title." do |str|
375
+ Env.var[:title] = str
376
+ end
377
+ optparse.on "-b", "--brief STR", "Set project brief." do |str|
378
+ Env.var[:brief] = str
379
+ end
380
+ optparse.on "-a", "--author STR", "Specify project author(s)." do |str|
381
+ Env.var[:author] = str
382
+ end
383
+ optparse.on "-y", "--year STR", "Specify project year(s)." do |str|
384
+ Env.var[:year] = str
385
+ end
386
+ optparse.on "--input STR",
387
+ "Where to look for input files." do |str|
388
+ Env.var[:input] = str
389
+ end
390
+ optparse.on "--output-doc STR",
391
+ "Where to write documentation files." do |str|
392
+ Env.var[:output_doc] = str
393
+ end
394
+ optparse.on "--output-src STR",
395
+ "Where to write source files." do |str|
396
+ Env.var[:output_src] = str
397
+ end
398
+ optparse.on "--only-doc", "Build only documention files?" do
399
+ Env.var[:only_doc] = true
400
+ end
401
+ optparse.on "--only-src", "Build only source files?" do
402
+ Env.var[:only_src] = true
403
+ end
404
+ optparse.on "--[no-]guard", "Guard output headers?" do |ans|
405
+ Env.var[:guard] = ans
406
+ end
407
+ optparse.on "--[no-]share", "Share chunks by default?" do |ans|
408
+ Env.var[:share] = ans
409
+ end
410
+ optparse.on_tail "-h", "--help", "Display this help." do
411
+ puts optparse
412
+ exit 0
413
+ end
414
+ end
415
+ end
416
+
417
+ end # module Opts
418
+
419
+ end # module Env
420
+
421
+ end # module Schizm