jekyll_new_page 0.6
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 +7 -0
- data/bin/new_from_template +46 -0
- data/lib/jekyll_new_page.rb +61 -0
- data/lib/new_page/input_hash.rb +188 -0
- data/lib/new_page/process_template.rb +68 -0
- metadata +91 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: df0e076b6b2d46c74606c84e450c4ef65ea18d466a6a4601c528ba5558645612
|
|
4
|
+
data.tar.gz: 2f038313dd4ea563f64aeec075c18f81a541ceca5bc088234deb8531e84f62d5
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f9c25ac0716449256113720eb27f37771880b5f3357faae150382b5c2858cdcefdb70c53e762259126451df75f5833a1915e35c26e8d299247b419be5b649904
|
|
7
|
+
data.tar.gz: ee03f9a7e86730e83d4d5fdc010eb796c620ef58a0f57cbee4ede085ca097c1e4b47d041be3055c2ac260ea20efd08713962f825c32d279eeb9bd05cce5936ce
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative "../lib/new_page/process_template.rb"
|
|
4
|
+
require_relative "../lib/new_page/input_hash.rb"
|
|
5
|
+
|
|
6
|
+
require 'optparse'
|
|
7
|
+
|
|
8
|
+
options = {}
|
|
9
|
+
OptionParser.new do |opts|
|
|
10
|
+
opts.banner = "Usage: new_from_template [options]"
|
|
11
|
+
|
|
12
|
+
opts.separator ""
|
|
13
|
+
opts.separator "\tCreates a new file based on a liquid template."
|
|
14
|
+
opts.separator ""
|
|
15
|
+
opts.separator "Options:"
|
|
16
|
+
|
|
17
|
+
opts.on("-o", "--output [NAME]", "Path where the file is to be created.") do |out|
|
|
18
|
+
options[:output] = out
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
opts.on( "-n", "--name=NAME", "Name of the created file. If there's no extension the same extension of the template will be used.") do |name|
|
|
22
|
+
options[:name] = name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
opts.on( "--template FILE|DIRECTORY", "Template file or directory. This should point to either a directory with the templates or the actual template.") do |template|
|
|
26
|
+
options[:path] = template
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
opts.on("--template_name=[NAME]", "Template name, name or \"glob\" of the template. This options uses '--template' as a directory, it is an error if '--template' specifies a file and there's also a '--template-name' specified.") do |template_name|
|
|
30
|
+
options[:template_name] = template_name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
opts.separator ""
|
|
34
|
+
opts.separator "Common options:"
|
|
35
|
+
|
|
36
|
+
opts.on_tail("-h", "--help", "-?", "Shows this message") do
|
|
37
|
+
puts opts
|
|
38
|
+
exit
|
|
39
|
+
end
|
|
40
|
+
end.parse!
|
|
41
|
+
|
|
42
|
+
options[:dir] = false
|
|
43
|
+
|
|
44
|
+
processor = NewPage::ProcessTemplate.new(context: NewPage::InputableContext.new, **options)
|
|
45
|
+
processor.render({})
|
|
46
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require 'pathname'
|
|
5
|
+
|
|
6
|
+
require 'jekyll'
|
|
7
|
+
|
|
8
|
+
require 'new_page/input_hash.rb'
|
|
9
|
+
require 'new_page/process_template.rb'
|
|
10
|
+
|
|
11
|
+
module NewPage
|
|
12
|
+
|
|
13
|
+
class CreateNewPage < Jekyll::Command
|
|
14
|
+
class << self
|
|
15
|
+
|
|
16
|
+
def init_with_program(c)
|
|
17
|
+
c.command("create-page".to_sym) do |prog|
|
|
18
|
+
prog.syntax "create-page [options] <Template name>"
|
|
19
|
+
prog.description "create a new page, based on a liquid template."
|
|
20
|
+
|
|
21
|
+
prog.option 'output', '-o', '--output PATH', 'Path where to create the new document.' do |out|
|
|
22
|
+
return Pathname.new(out)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
prog.option 'path', '--path [PATH]', 'Path where to locate the template.'
|
|
26
|
+
prog.option 'name', '-n', '--name NAME', 'Name of the document'
|
|
27
|
+
prog.option 'dir', '-d', '--create-subdir', 'Create a subdir to store the new page'
|
|
28
|
+
|
|
29
|
+
prog.action do |args, options|
|
|
30
|
+
options.transform_keys! { |old_key| old_key.to_sym }
|
|
31
|
+
|
|
32
|
+
raise ArgumentError("Need to specify a template name") if args.size > 1
|
|
33
|
+
raise ArgumentError("No output path specified.") if options[:output].nil?
|
|
34
|
+
raise ArgumentError("No page name specified.") if options[:name].nil?
|
|
35
|
+
|
|
36
|
+
options[:dir] = false unless options.include? :dir
|
|
37
|
+
|
|
38
|
+
[:output, :path].each do |key|
|
|
39
|
+
options[key] = Pathname.new(options[key]) unless options[key].nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
options[:template_name] = args[0] || '*'
|
|
43
|
+
|
|
44
|
+
options[:history_file] = options[:output] / Pathname.new('.history.txt')
|
|
45
|
+
context = InputableContext.new(outer_scope: {name: options[:name]}, reader: NewPage::ReadlineInputHandler, completion_handler: NewPage::HistoryHandler, **options)
|
|
46
|
+
|
|
47
|
+
begin
|
|
48
|
+
process = ProcessTemplate.new(context: context, **options)
|
|
49
|
+
|
|
50
|
+
process.render(context)
|
|
51
|
+
|
|
52
|
+
exec('nvim', "#{process.output_file}")
|
|
53
|
+
rescue ArgumentError => error
|
|
54
|
+
print error.message
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
require 'liquid'
|
|
2
|
+
require 'readline'
|
|
3
|
+
require 'set'
|
|
4
|
+
|
|
5
|
+
module NewPage
|
|
6
|
+
|
|
7
|
+
class HistoryHandler
|
|
8
|
+
attr_reader :completion
|
|
9
|
+
|
|
10
|
+
def initialize(history_file: Pathname.new(".history.yaml"), **)
|
|
11
|
+
if (history_file.is_a? Pathname)
|
|
12
|
+
@history_file = history_file
|
|
13
|
+
else
|
|
14
|
+
@history_file = Pathname.new(history_file)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@completion = read_history(history_file)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def [](key)
|
|
21
|
+
@completion[key]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def []=(key, value)
|
|
25
|
+
@completion[key] = value
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def include?
|
|
29
|
+
@completions.include?(key)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def read_history
|
|
33
|
+
YAML.load_file(@history_file)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def write_history
|
|
37
|
+
File.open { |file| file.write { |out| out << @completion.to_yaml } }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class NoCompletion < Hash
|
|
42
|
+
def completion
|
|
43
|
+
return {}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def write_history
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class ReadlineInputHandler
|
|
51
|
+
attr_reader :history
|
|
52
|
+
|
|
53
|
+
def initialize(**args)
|
|
54
|
+
print "#{self} -> #{args}\n"
|
|
55
|
+
if (args.include?('completion_handler'))
|
|
56
|
+
@history = args['completion_handler'].new(**args)
|
|
57
|
+
else
|
|
58
|
+
@history = NoCompletion.new
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def completion
|
|
63
|
+
@history.completion
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def update_completion(key, value)
|
|
67
|
+
values = value.split /[ \t]/
|
|
68
|
+
if (completion.include?(key)) then
|
|
69
|
+
completion[key] += values
|
|
70
|
+
else
|
|
71
|
+
completion[key] = values
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def input(key)
|
|
76
|
+
print "Reading #{key} at #{self}"
|
|
77
|
+
old = Readline.completion_proc
|
|
78
|
+
Readline.completion_proc = proc do |partial|
|
|
79
|
+
if completion.include? key.to_s then
|
|
80
|
+
completion[key.to_s].query(/^#{Regexp.escape(partial)}/)
|
|
81
|
+
else
|
|
82
|
+
[]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
line = ""
|
|
86
|
+
begin
|
|
87
|
+
line = Readline.readline("#{key} : ", true).strip
|
|
88
|
+
ensure
|
|
89
|
+
Readline.completion_proc = old unless old.nil?
|
|
90
|
+
end
|
|
91
|
+
update_completion(key, line)
|
|
92
|
+
@history.write_history
|
|
93
|
+
line
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class NoInput
|
|
98
|
+
def input(key)
|
|
99
|
+
return nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class InputHash < Hash
|
|
104
|
+
attr_reader :reader, :filled_keys
|
|
105
|
+
|
|
106
|
+
def normalize_key(key)
|
|
107
|
+
return key.to_s.strip.tr("._ ", "-").to_sym
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def initialize(data = {}, reader: NoInput, **args)
|
|
111
|
+
if (reader != NoInput)
|
|
112
|
+
@reader = reader.new(**args)
|
|
113
|
+
else
|
|
114
|
+
@reader = reader.new()
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
super()
|
|
118
|
+
|
|
119
|
+
data = Hash.new unless data.is_a? Hash
|
|
120
|
+
|
|
121
|
+
merge! data.transform_keys { |k| normalize_key(k) }
|
|
122
|
+
@filled_keys = data.keys
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def filled?(key)
|
|
126
|
+
return filled_keys.include?(key)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def include?(key)
|
|
130
|
+
return super.include?(key) || filled?(key)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def [](key)
|
|
134
|
+
key = normalize_key(key)
|
|
135
|
+
if (@filled_keys.include?(key))
|
|
136
|
+
value = super(key)
|
|
137
|
+
else
|
|
138
|
+
print "Reading #{key} with #{@reader}\n"
|
|
139
|
+
value = @reader.input(key) unless @filled_keys.include?(key)
|
|
140
|
+
self[key]=value
|
|
141
|
+
end
|
|
142
|
+
value
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def []=(key, value)
|
|
146
|
+
key=normalize_key(key)
|
|
147
|
+
@filled_keys += [ key ] unless @filled_keys.include?(key)
|
|
148
|
+
super(key, value)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
class InputableContext < ::Liquid::Context
|
|
153
|
+
|
|
154
|
+
def initialize(enviroments: {}, outer_scope: {}, registers: {}, rethrow_errors: true, resource_limits: nil, **args)
|
|
155
|
+
print "InputableContext #{args}\n"
|
|
156
|
+
@context_args= args
|
|
157
|
+
|
|
158
|
+
environments = [environments].flatten.map { |env| new_hash(env) }
|
|
159
|
+
outer_scope = new_hash(outer_scope) unless outer_scope.is_a? InputHash
|
|
160
|
+
|
|
161
|
+
super(environments, outer_scope, registers, rethrow_errors, resource_limits)
|
|
162
|
+
@filled_keys = []
|
|
163
|
+
|
|
164
|
+
Readline.completion_append_character = " "
|
|
165
|
+
Readline.completer_word_break_characters = " \t"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def hash_create_args
|
|
169
|
+
@context_args
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def new_hash(source)
|
|
173
|
+
source = {} if source.nil?
|
|
174
|
+
return InputHash.new(source, **@context_args)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def do_not_input(*keys)
|
|
178
|
+
keys.map { |key| key.to_sym }.each do |key|
|
|
179
|
+
@filled_keys << key unless @data.has_key? key
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def push(new_scope)
|
|
184
|
+
new_scope = new_hash(new_scope) unless new_scope.is_a? InputHash
|
|
185
|
+
super(new_hash(new_scope))
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'liquid'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
module NewPage
|
|
5
|
+
|
|
6
|
+
class ProcessTemplate
|
|
7
|
+
TEMPLATE_PATH = Pathname.new("_template")
|
|
8
|
+
attr :file, :output_file, :context
|
|
9
|
+
|
|
10
|
+
def initialize(output:, template_name: nil, name: nil, dir: false, path: nil, data: {}, context: nil, **)
|
|
11
|
+
@path = if (path.nil?) then
|
|
12
|
+
Pathname.new(output) / TEMPLATE_PATH
|
|
13
|
+
else
|
|
14
|
+
Pathname.new(path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
output = Pathname.new(output)
|
|
18
|
+
|
|
19
|
+
if (name.nil?) then
|
|
20
|
+
name = output.basename
|
|
21
|
+
output = output.dirname
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if (dir) then
|
|
25
|
+
@output = Pathname.new(output) / Pathname.new(name)
|
|
26
|
+
FileUtils.mkdir_p(@output) unless @output.directory?
|
|
27
|
+
name = 'index'
|
|
28
|
+
else
|
|
29
|
+
@output = Pathname.new(output)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@context = context
|
|
33
|
+
|
|
34
|
+
if not template_name.nil? then
|
|
35
|
+
templates = if (@path / template_name).file? then
|
|
36
|
+
[ @path / template_name ]
|
|
37
|
+
else
|
|
38
|
+
glob = File.expand_path(@path) + "/#{template_name}"
|
|
39
|
+
Dir::glob(glob)
|
|
40
|
+
end
|
|
41
|
+
templates.map! { |name| Pathname.new(name) }
|
|
42
|
+
|
|
43
|
+
raise ArgumentError.new("Ambiguos template name #{template_name} : #{templates}") if templates.size > 1
|
|
44
|
+
|
|
45
|
+
raise ArgumentError.new("No such template #{template_name} at #{glob}") if templates.empty? || !templates[0].file?
|
|
46
|
+
@input_file = templates[0]
|
|
47
|
+
else
|
|
48
|
+
if @path.file? then
|
|
49
|
+
@input_file = @path
|
|
50
|
+
@path = @path.dirname
|
|
51
|
+
else
|
|
52
|
+
@input_file = @path / template_name
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
@output_file = @output / Pathname.new(name).sub_ext(@input_file.extname)
|
|
57
|
+
|
|
58
|
+
raise "#{@input_file} cannot be the same as #{@output_file}" if @input_file == @output_file
|
|
59
|
+
|
|
60
|
+
@template = Liquid::Template.parse(File.read(@input_file))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def render(defaults)
|
|
64
|
+
@output_file.write(@template.render(@context), mode: 'w')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll_new_page
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: '0.6'
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Victor Bogado da Silva Lins
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: bundler
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: test-unit
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake-compiler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
description: Makes it easy to create a new page, without adding a bunch of boiler
|
|
55
|
+
plate manually.
|
|
56
|
+
email: victor@bogado.net
|
|
57
|
+
executables:
|
|
58
|
+
- new_from_template
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- bin/new_from_template
|
|
63
|
+
- lib/jekyll_new_page.rb
|
|
64
|
+
- lib/new_page/input_hash.rb
|
|
65
|
+
- lib/new_page/process_template.rb
|
|
66
|
+
homepage: https://www.github.com/bogado/jekyll-new-page-creator
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
69
|
+
metadata: {}
|
|
70
|
+
rdoc_options: []
|
|
71
|
+
require_paths:
|
|
72
|
+
- lib
|
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '3.0'
|
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
requirements:
|
|
84
|
+
- reline
|
|
85
|
+
- readline
|
|
86
|
+
- liquid
|
|
87
|
+
- jekyll
|
|
88
|
+
rubygems_version: 4.0.6
|
|
89
|
+
specification_version: 4
|
|
90
|
+
summary: Create a new page, based on a template stored on a '_template' directory.
|
|
91
|
+
test_files: []
|