usmu 0.1.0-java
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/.cane +4 -0
- data/.gitignore +17 -0
- data/.rspec +5 -0
- data/.travis.yml +34 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/Gemfile-jruby +4 -0
- data/LICENSE.md +22 -0
- data/README.md +50 -0
- data/Rakefile +61 -0
- data/bin/usmu +10 -0
- data/cucumber.yml +2 -0
- data/lib/usmu/configuration.rb +83 -0
- data/lib/usmu/layout.rb +166 -0
- data/lib/usmu/page.rb +19 -0
- data/lib/usmu/site_generator.rb +82 -0
- data/lib/usmu/static_file.rb +39 -0
- data/lib/usmu/ui/console.rb +26 -0
- data/lib/usmu/ui.rb +7 -0
- data/lib/usmu/version.rb +5 -0
- data/lib/usmu.rb +12 -0
- data/test/expected-site/default.html +3 -0
- data/test/expected-site/embedded.html +15 -0
- data/test/expected-site/index.html +14 -0
- data/test/expected-site/robots.txt +1 -0
- data/test/features/generator.feature +10 -0
- data/test/features/step_definitions/step_general.rb +18 -0
- data/test/site/content/default.md +3 -0
- data/test/site/content/embedded.md +1 -0
- data/test/site/content/embedded.meta.yml +2 -0
- data/test/site/content/index.md +3 -0
- data/test/site/content/index.meta.yml +3 -0
- data/test/site/content/robots.txt +1 -0
- data/test/site/layouts/embedded.meta.yml +2 -0
- data/test/site/layouts/embedded.slim +2 -0
- data/test/site/layouts/html.meta.yml +2 -0
- data/test/site/layouts/html.slim +8 -0
- data/test/site/usmu.yml +15 -0
- data/test/spec/configuration_spec.rb +51 -0
- data/test/spec/layout_spec.rb +27 -0
- data/test/spec/page_spec.rb +15 -0
- data/test/spec/site_generator_spec.rb +32 -0
- data/test/spec/spec_helper.rb +85 -0
- data/test/spec/static_file_spec.rb +20 -0
- data/test/spec/support/shared_layout.rb +111 -0
- data/usmu-jruby.gemspec +34 -0
- data/usmu.gemspec +35 -0
- metadata +285 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 726f831d3d6e597914f648fc22e0fc20186da395
|
4
|
+
data.tar.gz: 5b1512b73c9bb120edbdafde348ee584d30a60c8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc8ef55cd3f4ec4746ad2426a3e82e1de1d5956dcfa8ab0b5dc8ed908c945723a4306d58c4af2dd84f76e8ae124b5ba5c5b561223fb4a8907070b46237e66a96
|
7
|
+
data.tar.gz: 8727555906c5a1093e8107983685e899da7fd2a66a897fff5fba7462e49fe59bcc4477b5e02e196e0dc9f1e750642efe242cfa1c52efc8fa277a34b7847d420a
|
data/.cane
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
language: ruby
|
2
|
+
script: rake ci
|
3
|
+
rvm:
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
6
|
+
- ruby-head
|
7
|
+
- jruby-19mode
|
8
|
+
- jruby-head
|
9
|
+
- rbx-2
|
10
|
+
- rbx-head
|
11
|
+
gemfile:
|
12
|
+
- Gemfile
|
13
|
+
- Gemfile-jruby
|
14
|
+
matrix:
|
15
|
+
exclude:
|
16
|
+
- rvm: 2.0
|
17
|
+
gemfile: Gemfile-jruby
|
18
|
+
- rvm: 2.1
|
19
|
+
gemfile: Gemfile-jruby
|
20
|
+
- rvm: ruby-head
|
21
|
+
gemfile: Gemfile-jruby
|
22
|
+
- rvm: jruby-19mode
|
23
|
+
gemfile: Gemfile
|
24
|
+
- rvm: jruby-head
|
25
|
+
gemfile: Gemfile
|
26
|
+
- rvm: rbx-2
|
27
|
+
gemfile: Gemfile-jruby
|
28
|
+
- rvm: rbx-head
|
29
|
+
gemfile: Gemfile-jruby
|
30
|
+
allow_failures:
|
31
|
+
- rvm: jruby-19mode
|
32
|
+
- rvm: jruby-head
|
33
|
+
- rvm: rbx-2
|
34
|
+
- rvm: rbx-head
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--private --protected --hide-void-return -m markdown -M redcarpet lib/**/*.rb - README.md
|
data/Gemfile
ADDED
data/Gemfile-jruby
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Matthew Scharley and contributors
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# usmu [](https://travis-ci.org/usmu/usmu)
|
2
|
+
|
3
|
+
**Source:** [https://github.com/usmu/usmu](https://github.com/usmu/usmu)
|
4
|
+
**Author:** Matthew Scharley
|
5
|
+
**Contributors:** [See contributors on GitHub][gh-contrib]
|
6
|
+
**Bugs/Support:** [Github Issues][gh-issues]
|
7
|
+
**Copyright:** 2014
|
8
|
+
**License:** [MIT license][license]
|
9
|
+
**Status:** Active
|
10
|
+
|
11
|
+
## Synopsis
|
12
|
+
|
13
|
+
`usmu` is a static site generator intended to be used with the future Rails-based editing platform. It can also be used
|
14
|
+
to generate locally if you don't wish to use the web-based editor.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
$ gem install usmu
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
TODO: Write usage instructions here
|
23
|
+
|
24
|
+
## Compatibility
|
25
|
+
|
26
|
+
As a baseline `usmu` will pull in Slim for layouts and Redcarpet for content written in Markdown. However we use the
|
27
|
+
Tilt API to render all layouts and content, therefore you should be able to use anything supported by Tilt including
|
28
|
+
Sass, Less, Textile and [many others][tilt-support], you just need to ensure you have the correct gems installed.
|
29
|
+
|
30
|
+
If you want to further [configure the way your template's are processed][template-options] then you can specify
|
31
|
+
configurations for each template engine. Just add it to your `usmu.yml`:
|
32
|
+
|
33
|
+
```yaml
|
34
|
+
slim:
|
35
|
+
:pretty: true
|
36
|
+
```
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
1. Fork it
|
41
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
42
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
43
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
44
|
+
5. Create a new Pull Request
|
45
|
+
|
46
|
+
[gh-contrib]: https://github.com/usmu/usmu/graphs/contributors
|
47
|
+
[gh-issues]: https://github.com/usmu/usmu/issues
|
48
|
+
[license]: https://github.com/usmu/usmu/blob/master/LICENSE.md
|
49
|
+
[tilt-support]: https://github.com/rtomayko/tilt/blob/master/README.md
|
50
|
+
[template-options]: https://github.com/rtomayko/tilt/blob/master/docs/TEMPLATES.md
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'cucumber'
|
6
|
+
require 'cucumber/rake/task'
|
7
|
+
require 'usmu/version'
|
8
|
+
|
9
|
+
def current_gems
|
10
|
+
Dir["pkg/usmu-#{Usmu::VERSION}*.gem"]
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
14
|
+
t.pattern = 'test/spec/**/*_spec.rb'
|
15
|
+
end
|
16
|
+
|
17
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
18
|
+
t.cucumber_opts = 'test/features'
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Run all test scripts'
|
22
|
+
task :test => [:clean, :spec, :features]
|
23
|
+
|
24
|
+
desc 'Run CI test suite'
|
25
|
+
task :ci => [:test]
|
26
|
+
|
27
|
+
desc 'Clean up after tests'
|
28
|
+
task :clean do
|
29
|
+
rm_r 'test/site/site' if File.exist? 'test/site/site'
|
30
|
+
current_gems.each {|f| rm f }
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace :gem do
|
34
|
+
desc 'Build gems'
|
35
|
+
task :build => [:clean] do
|
36
|
+
mkdir 'pkg' unless File.exist? 'pkg'
|
37
|
+
Dir['*.gemspec'].each do |gemspec|
|
38
|
+
sh "gem build #{gemspec}"
|
39
|
+
end
|
40
|
+
Dir['*.gem'].each do |gem|
|
41
|
+
mv gem, "pkg/#{gem}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'Install gem'
|
46
|
+
task :install => ['gem:build'] do
|
47
|
+
if RUBY_PLATFORM == 'java'
|
48
|
+
sh "gem install pkg/usmu-#{Usmu::VERSION}-java.gem"
|
49
|
+
else
|
50
|
+
sh "gem install pkg/usmu-#{Usmu::VERSION}.gem"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Deploy gems to rubygems'
|
55
|
+
task :deploy => ['gem:build'] do
|
56
|
+
current_gems.each do |gem|
|
57
|
+
sh "gem push #{gem}"
|
58
|
+
end
|
59
|
+
sh "git tag #{Usmu::VERSION}" if File.exist? '.git'
|
60
|
+
end
|
61
|
+
end
|
data/bin/usmu
ADDED
data/cucumber.yml
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Usmu
|
4
|
+
# This class is used to represent a configuration file. This file should be a YAML file and called `usmu.yml`
|
5
|
+
# by default.
|
6
|
+
class Configuration
|
7
|
+
# @!attribute [r] config_file
|
8
|
+
# @return [String] the name of the file used to load the configuration.
|
9
|
+
attr_reader :config_file
|
10
|
+
# @!attribute [r] config_file
|
11
|
+
# @return [String] the folder that the configuration was loaded from.
|
12
|
+
attr_reader :config_dir
|
13
|
+
|
14
|
+
# Load a configuration from a YAML file on disk.
|
15
|
+
#
|
16
|
+
# @return [Usmu::Configuration]
|
17
|
+
def self.from_file(filename)
|
18
|
+
from_hash(YAML.load_file(filename), filename)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load a configuration from a hash.
|
22
|
+
#
|
23
|
+
# @return [Usmu::Configuration]
|
24
|
+
def self.from_hash(hash, config_path = nil)
|
25
|
+
self.new(hash, config_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @!attribute [r] source_path
|
29
|
+
# @return [String] the full path to the source folder
|
30
|
+
def source_path
|
31
|
+
get_path @config['source'] || 'src'
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!attribute [r] destination_path
|
35
|
+
# @return [String] the full path to the destination folder
|
36
|
+
def destination_path
|
37
|
+
get_path @config['destination'] || 'site'
|
38
|
+
end
|
39
|
+
|
40
|
+
# @!attribute [r] layouts_path
|
41
|
+
# @return [String] the full path to the layouts folder
|
42
|
+
def layouts_path
|
43
|
+
get_path @config['layouts'] || 'layouts'
|
44
|
+
end
|
45
|
+
|
46
|
+
# An index accessor to directly access the configuration file. It should be noted that `['source']` and
|
47
|
+
# `#source_path` and other similar pairs will have different values. `['source']` is the raw value from the
|
48
|
+
# configuration file while the latter is a path on the system, potentially altered by the path from the current
|
49
|
+
# working directory to the configuration file and other factors. The accessor functions such as `#source_path`
|
50
|
+
# should be preferred for most usages.
|
51
|
+
#
|
52
|
+
# @param [String, Symbol] index The index to return.
|
53
|
+
# @return [Array, Hash, String, Symbol] Returns a value from the hash loaded from YAML. The type of value will
|
54
|
+
# ultimately depend on the configuration file and the index provided.
|
55
|
+
def [](index)
|
56
|
+
@config[index]
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# This class has a private constructor.
|
62
|
+
#
|
63
|
+
# @see Usmu::Configuration.from_file
|
64
|
+
# @see Usmu::Configuration.from_hash
|
65
|
+
def initialize(hash, config_path)
|
66
|
+
@config = hash
|
67
|
+
@config_file = config_path
|
68
|
+
@config_dir = config_path ? File.dirname(config_path) : nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# Helper function to transform a relative path in the configuration file to a relative path from the current
|
72
|
+
# working directory.
|
73
|
+
#
|
74
|
+
# @return [String]
|
75
|
+
def get_path(path)
|
76
|
+
if @config_dir.nil?
|
77
|
+
path
|
78
|
+
else
|
79
|
+
File.join(@config_dir, path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/usmu/layout.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require 'deep_merge'
|
3
|
+
require 'usmu/static_file'
|
4
|
+
|
5
|
+
module Usmu
|
6
|
+
# Class to represent files templated with a Tilt library. Most of the custom rendering logic is contained here.
|
7
|
+
class Layout < StaticFile
|
8
|
+
# @!attribute [r] type
|
9
|
+
# @return [String] the type of file this is. This is used to determine which template engine to use.
|
10
|
+
attr_reader :type
|
11
|
+
|
12
|
+
# @param configuration [Usmu::Configuration] The configuration for the website we're generating.
|
13
|
+
# @param name [String] The name of the file in the source directory.
|
14
|
+
# @param type [String] The type of template to use with the file. Used for testing purposes.
|
15
|
+
# @param content [String] The content of the file. Used for testing purposes.
|
16
|
+
# @param metadata [String] The metadata for the file. Used for testing purposes.
|
17
|
+
def initialize(configuration, name, type = nil, content = nil, metadata = nil)
|
18
|
+
super(configuration, name)
|
19
|
+
|
20
|
+
if type.nil?
|
21
|
+
type = name.split('.').last
|
22
|
+
unless ::Tilt.default_mapping[type]
|
23
|
+
raise "Templates of type '#{type}' aren't currently supported by Tilt. " +
|
24
|
+
'Do you have the required gem installed?'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
@type = type
|
28
|
+
path = File.join("#{content_path}", "#{name[0, name.length - type.length - 1]}")
|
29
|
+
|
30
|
+
if content.nil?
|
31
|
+
content = File.read("#{path}.#{type}")
|
32
|
+
end
|
33
|
+
@content = content
|
34
|
+
|
35
|
+
if metadata.nil?
|
36
|
+
meta_file = "#{path}.meta.yml"
|
37
|
+
metadata = if File.exist? meta_file
|
38
|
+
YAML.load_file(meta_file)
|
39
|
+
else
|
40
|
+
{}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@metadata = metadata
|
44
|
+
|
45
|
+
@parent = Layout.find_layout(configuration, metadata['layout'])
|
46
|
+
end
|
47
|
+
|
48
|
+
# @!attribute [r] metadata
|
49
|
+
# @return [Hash] the metadata associated with this layout.
|
50
|
+
#
|
51
|
+
# Returns the metadata associated with this layout.
|
52
|
+
#
|
53
|
+
# This will include any metadata from parent templates and default metadata
|
54
|
+
def metadata
|
55
|
+
if @parent.nil?
|
56
|
+
@metadata.deep_merge(@configuration['default meta'] || {})
|
57
|
+
else
|
58
|
+
@metadata.deep_merge(@parent.metadata)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Renders the file with any templating language required and returns the result
|
63
|
+
#
|
64
|
+
# @param variables [Hash] Variables to be used in the template.
|
65
|
+
# @return [String] The rendered file.
|
66
|
+
def render(variables = {})
|
67
|
+
content = template_class.new("#{@name}.#{@type}", 1, @configuration[provider_name]) { @content }.
|
68
|
+
render(nil, get_variables(variables))
|
69
|
+
has_cr = content.index("\r")
|
70
|
+
content += (has_cr ? "\r\n" : "\n") if content[-1] != "\n"
|
71
|
+
if @parent.nil?
|
72
|
+
content
|
73
|
+
else
|
74
|
+
@parent.render({'content' => content})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @!attribute [r] output_extension
|
79
|
+
# @return [String] the extension to use with the output file.
|
80
|
+
def output_extension
|
81
|
+
'html'
|
82
|
+
end
|
83
|
+
|
84
|
+
# @!attribute [r] output_filename
|
85
|
+
# @return [String] the filename to use in the output directory.
|
86
|
+
#
|
87
|
+
# Returns the filename to use for the output directory with any modifications to the input filename required.
|
88
|
+
def output_filename
|
89
|
+
@name[0..@name.rindex('.')] + output_extension
|
90
|
+
end
|
91
|
+
|
92
|
+
# Static method to create a layout for a given configuration by it's name if it exists. This differs from
|
93
|
+
# `#initialise` in that it allows different types of values to be supplied as the name and will not fail if name
|
94
|
+
# is nil
|
95
|
+
#
|
96
|
+
# @param configuration [Usmu::Configuration] The configuration to use for the search
|
97
|
+
# @param name [String]
|
98
|
+
# If name is a string then search for a template with that name. Name here should not include
|
99
|
+
# file extension, eg. body not body.slim. If name is not a string then it will be returned verbatim. This means
|
100
|
+
# that name is nilable and can also be passed in as an Usmu::Layout already for testing purposes.
|
101
|
+
# @return [Usmu::Layout]
|
102
|
+
def self.find_layout(configuration, name)
|
103
|
+
if name.class.name == 'String'
|
104
|
+
Dir["#{configuration.layouts_path}/#{name}.*"].each do |f|
|
105
|
+
filename = File.basename(f)
|
106
|
+
if filename != "#{name}.meta.yml"
|
107
|
+
return new(configuration, f[(configuration.layouts_path.length + 1)..f.length])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
name
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Tests if a given file is a valid Tilt template based on the filename.
|
116
|
+
#
|
117
|
+
# @param folder_type [String]
|
118
|
+
# One of `"source"` or `"layout"` depending on where the template is in the source tree.
|
119
|
+
# Not used by Usmu::Layout directly but intended to be available for future API.
|
120
|
+
# @param name [String] The filename to be tested.
|
121
|
+
# @return [Boolean]
|
122
|
+
def self.is_valid_file?(folder_type, name)
|
123
|
+
type = name.split('.').last
|
124
|
+
::Tilt.default_mapping[type] ? true : false
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
129
|
+
# @!attribute [r] template_class
|
130
|
+
# @return [Tilt::Template] the Tilt template engine for this layout
|
131
|
+
def template_class
|
132
|
+
@template_class ||= ::Tilt.default_mapping[@type]
|
133
|
+
end
|
134
|
+
|
135
|
+
# @!attribute [r] provider_name
|
136
|
+
# @return [String] the Tilt template engine's name for this layout
|
137
|
+
#
|
138
|
+
# Returns the Tilt template engine's name for this layout.
|
139
|
+
#
|
140
|
+
# This is used to determine which settings to use from the configuration file.
|
141
|
+
def provider_name
|
142
|
+
Tilt.default_mapping.lazy_map[@type].select {|x| x[0] == template_class.name }.first[1].split('/').last
|
143
|
+
end
|
144
|
+
|
145
|
+
# @!attribute [r] content_path
|
146
|
+
# @return [string] the base path to the files used by this class.
|
147
|
+
#
|
148
|
+
# Returns the base path to the files used by this class.
|
149
|
+
#
|
150
|
+
# This folder should be the parent folder for the file named by the name attribute.
|
151
|
+
#
|
152
|
+
# @see #name
|
153
|
+
def content_path
|
154
|
+
@configuration.layouts_path
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
# Utility function which collates variables to pass to the template engine.
|
160
|
+
#
|
161
|
+
# @return [Hash]
|
162
|
+
def get_variables(variables)
|
163
|
+
variables.deep_merge(metadata).deep_merge({site: @configuration})
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/lib/usmu/page.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Usmu
|
3
|
+
# Represents a page in the source directory of the website.
|
4
|
+
class Page < Layout
|
5
|
+
protected
|
6
|
+
|
7
|
+
# @!attribute [r] content_path
|
8
|
+
# @return [string] the base path to the files used by this class.
|
9
|
+
#
|
10
|
+
# Returns the base path to the files used by this class.
|
11
|
+
#
|
12
|
+
# This folder should be the parent folder for the file named by the name attribute.
|
13
|
+
#
|
14
|
+
# @see #name
|
15
|
+
def content_path
|
16
|
+
@configuration.source_path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Usmu
|
4
|
+
# This is the class that brings everything together to generate a new website.
|
5
|
+
class SiteGenerator
|
6
|
+
# @param [Usmu::Configuration] configuration The configuration to use for generating the website
|
7
|
+
def initialize(configuration)
|
8
|
+
@configuration = configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
# @!attribute [r] layouts
|
12
|
+
# @return [Array<Usmu::Layout>] a list of layouts available in this website.
|
13
|
+
def layouts
|
14
|
+
get_renderables @configuration.layouts_path, true
|
15
|
+
end
|
16
|
+
|
17
|
+
# @!attribute [r] renderables
|
18
|
+
# @return [Array<Usmu::StaticFile>] a list of renderable files from the source folder.
|
19
|
+
# will be a subclass of this class.
|
20
|
+
# @see Usmu::StaticFile
|
21
|
+
#
|
22
|
+
# Returns a list of renderable files from the source folder.
|
23
|
+
#
|
24
|
+
# The only guarantee made for individual files is that they will conform to the interface defined by
|
25
|
+
# Usmu::StaticFile and thus be renderable, however most files will be one of the subclasses of that class.
|
26
|
+
def renderables
|
27
|
+
get_renderables @configuration.source_path, false
|
28
|
+
end
|
29
|
+
|
30
|
+
# @!attribute [r] pages
|
31
|
+
# @return [Array<Usmu::Page>] a list of pages from the source folder. This is any file in the source folder which
|
32
|
+
# is not static.
|
33
|
+
def pages
|
34
|
+
renderables.select {|r| r.class.name != 'Usmu::StaticFile'}
|
35
|
+
end
|
36
|
+
|
37
|
+
# @!attribute [r] files
|
38
|
+
# @return [Array<Usmu::StaticFile>] a list of static files from the source folder.
|
39
|
+
def files
|
40
|
+
renderables.select {|r| r.class.name == 'Usmu::StaticFile'}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generate the website according to the configuration given.
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
def generate
|
47
|
+
renderables.each do |page|
|
48
|
+
file = File.join(@configuration.destination_path, page.output_filename)
|
49
|
+
directory = File.dirname(file)
|
50
|
+
|
51
|
+
unless File.directory?(directory)
|
52
|
+
FileUtils.mkdir_p(directory)
|
53
|
+
end
|
54
|
+
|
55
|
+
File.write file, page.render
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Helper function to search a directory recursively and return a list of files that are renderable.
|
63
|
+
#
|
64
|
+
# @param [String] directory the directory to search
|
65
|
+
# @param [Boolean] layout is this directory a layouts_path
|
66
|
+
# @return [Array<Usmu::Layout>, Array<Usmu::StaticFile>] Either an array of Layouts or StaticFiles in the directory
|
67
|
+
def get_renderables(directory, layout)
|
68
|
+
Dir["#{directory}/**/*"].select {|f| !f.match(/\.meta.yml$/) }.map do |f|
|
69
|
+
filename = f[(directory.length + 1)..f.length]
|
70
|
+
if layout
|
71
|
+
Usmu::Layout.new(@configuration, filename)
|
72
|
+
else
|
73
|
+
if Usmu::Layout.is_valid_file? 'source', filename
|
74
|
+
Usmu::Page.new(@configuration, filename)
|
75
|
+
else
|
76
|
+
Usmu::StaticFile.new(@configuration, filename)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module Usmu
|
3
|
+
# Represents a static file which should be transferred to the destination unchanged. This also acts as the base
|
4
|
+
# class for all layouts and page types. The basic interface defined here is used to process all types of files.
|
5
|
+
class StaticFile
|
6
|
+
# @!attribute [r] name
|
7
|
+
# @return [String] the name of the file in the source directory
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
# @param configuration [Usmu::Configuration] The configuration for the website we're generating.
|
11
|
+
# @param name [String] The name of the file in the source directory.
|
12
|
+
# @param type [String] The type of template to use with the file. Not used for StaticFile.
|
13
|
+
# Used for testing purposes.
|
14
|
+
# @param content [String] The content of the file. Used for testing purposes.
|
15
|
+
# @param metadata [String] The metadata for the file. Used for testing purposes.
|
16
|
+
def initialize(configuration, name, type = nil, content = nil, metadata = nil)
|
17
|
+
@configuration = configuration
|
18
|
+
@name = name
|
19
|
+
@type = type
|
20
|
+
@content = content
|
21
|
+
end
|
22
|
+
|
23
|
+
# Renders the file with any templating language required and returns the result
|
24
|
+
#
|
25
|
+
# @param variables [Hash] Variables to be used in the template.
|
26
|
+
# @return [String] The rendered file
|
27
|
+
def render(variables = {})
|
28
|
+
@content || File.read(File.join(@configuration.source_path, @name))
|
29
|
+
end
|
30
|
+
|
31
|
+
# @!attribute [r] output_filename
|
32
|
+
# @return [String] the filename to use in the output directory.
|
33
|
+
#
|
34
|
+
# Returns the filename to use for the output directory with any modifications to the input filename required.
|
35
|
+
def output_filename
|
36
|
+
@name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'usmu'
|
2
|
+
require 'trollop'
|
3
|
+
|
4
|
+
module Usmu
|
5
|
+
module Ui
|
6
|
+
# This is the CLI UI controller. This is initialised by the usmu binary to control the generation process.
|
7
|
+
class Console
|
8
|
+
# @!attribute [r] configuration
|
9
|
+
# @return [Usmu::Configuration] the configuration for the site we will generate.
|
10
|
+
attr_reader :configuration
|
11
|
+
|
12
|
+
# @param [Array<String>] args Command line arguments. Typically ARGV should be passed here.
|
13
|
+
def initialize(args)
|
14
|
+
@args = args
|
15
|
+
@configuration = Usmu::Configuration.from_file(File.join(args[0] || '.', 'usmu.yml'))
|
16
|
+
end
|
17
|
+
|
18
|
+
# This will run the command as setup in `#initialize`
|
19
|
+
#
|
20
|
+
# @return [void]
|
21
|
+
def execute
|
22
|
+
Usmu::SiteGenerator.new(@configuration).generate
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/usmu/ui.rb
ADDED