mr_hyde 0.1.0 → 0.2.0
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/.gitignore +1 -0
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/bin/mrhyde +56 -10
- data/lib/mr_hyde/commands/build.rb +3 -2
- data/lib/mr_hyde/commands/list.rb +41 -0
- data/lib/mr_hyde/commands/new.rb +3 -9
- data/lib/mr_hyde/commands/remove.rb +2 -2
- data/lib/mr_hyde/commands/serve.rb +26 -0
- data/lib/mr_hyde/configuration.rb +17 -5
- data/lib/mr_hyde/extensions/new.rb +54 -2
- data/lib/mr_hyde/jekyll_ext/converters/scss.rb +18 -0
- data/lib/mr_hyde/jekyll_ext/jekyll.rb +16 -0
- data/lib/mr_hyde/jekyll_ext/site.rb +47 -0
- data/lib/mr_hyde/jekyll_ext/tags/include.rb +23 -0
- data/lib/mr_hyde/site.rb +234 -0
- data/lib/mr_hyde/version.rb +1 -1
- data/lib/mr_hyde.rb +125 -24
- data/lib/site_template/_config.yml +14 -0
- data/lib/site_template/_mrhyde.yml +2 -11
- data/lib/site_template/sources/_assets/_sass/_base.scss +204 -0
- data/lib/site_template/sources/_assets/_sass/_functions.scss +11 -0
- data/lib/site_template/sources/_assets/_sass/_grid.scss +544 -0
- data/lib/site_template/sources/_assets/_sass/_layout.scss +241 -0
- data/lib/site_template/sources/_assets/_sass/_newbase.scss +488 -0
- data/lib/site_template/sources/_assets/_sass/_normalize.scss +424 -0
- data/lib/site_template/sources/_assets/_sass/_syntax-highlighting.scss +67 -0
- data/lib/site_template/sources/_includes/footer.html +58 -0
- data/lib/site_template/sources/_includes/head.html +12 -0
- data/lib/site_template/sources/_includes/header.html +31 -0
- data/lib/site_template/sources/_layouts/default.html +25 -0
- data/lib/site_template/sources/_layouts/page.html +14 -0
- data/lib/site_template/sources/_layouts/post.html +15 -0
- data/lib/site_template/sources/main_site/about.md +9 -0
- data/lib/site_template/sources/main_site/css/main.scss +55 -0
- data/lib/site_template/sources/main_site/css/normalize.css +427 -0
- data/lib/site_template/sources/main_site/index.md +17 -0
- data/lib/site_template/sources/main_site/js/main.coffee +27 -0
- data/lib/subsite_template/_config.yml +2 -0
- data/lib/subsite_template/_posts/0000-00-00-welcome-to-mr-hyde.markdown.erb +27 -0
- data/lib/subsite_template/about.md +9 -0
- data/lib/subsite_template/assets/dr_jekyll_and_mr_hyde_poster.png +0 -0
- data/lib/subsite_template/feed.xml +30 -0
- data/lib/subsite_template/index.html +26 -0
- data/resources/mrhyde-logo-red.png +0 -0
- data/resources/mrhyde-logo.png +0 -0
- data/spec/build_spec.rb +26 -27
- data/spec/list_spec.rb +37 -0
- data/spec/new_spec.rb +53 -25
- data/spec/rm_spec.rb +30 -31
- metadata +38 -8
- data/lib/mr_hyde/blog.rb +0 -146
- data/lib/mr_hyde/extensions/.new.rb.swp +0 -0
- data/lib/site_template/site/css/main.css +0 -0
- data/lib/site_template/site/index.html +0 -0
- data/test/blog_test.rb +0 -46
data/lib/mr_hyde/site.rb
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
require "jekyll"
|
2
|
+
require "fileutils"
|
3
|
+
require "mr_hyde"
|
4
|
+
require "mr_hyde/configuration"
|
5
|
+
|
6
|
+
module MrHyde
|
7
|
+
class Site
|
8
|
+
class << self
|
9
|
+
def init(args, opts)
|
10
|
+
opts = MrHyde.configuration(opts)
|
11
|
+
@source = if opts['main']
|
12
|
+
File.join MrHyde.source, MrHyde.sources
|
13
|
+
else
|
14
|
+
File.join MrHyde.source, MrHyde.sources_sites
|
15
|
+
end
|
16
|
+
yield if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
# Creates the directory and necessary files for the site
|
20
|
+
# Params:
|
21
|
+
# args
|
22
|
+
# String => creates the concrete site
|
23
|
+
# Array[String] => creates the correspondings site names
|
24
|
+
# opts
|
25
|
+
# Hash
|
26
|
+
# 'force' => 'force' Install the new site over an exiting path
|
27
|
+
# 'blank' => 'blank' Creates a blank site
|
28
|
+
#
|
29
|
+
def create(args, opts = {})
|
30
|
+
init(args, opts)
|
31
|
+
|
32
|
+
if args.kind_of? Array and not args.empty?
|
33
|
+
args.each do |bn|
|
34
|
+
begin
|
35
|
+
create_site(bn, opts)
|
36
|
+
rescue Exception => e
|
37
|
+
raise e unless e.class == SystemExit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
elsif args.kind_of? String
|
41
|
+
create_site args, opts
|
42
|
+
end
|
43
|
+
rescue Exception => e
|
44
|
+
MrHyde.logger.error "cannot create site: #{e}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Removes the site directory
|
48
|
+
# Params:
|
49
|
+
# args
|
50
|
+
# String => removes the concrete site
|
51
|
+
# Array[String] => removes the correspondings site names
|
52
|
+
# empty => remove all sites with the option 'all'
|
53
|
+
# opts
|
54
|
+
# Hash
|
55
|
+
# 'all' => 'all' Removes all built sites
|
56
|
+
# 'full' => 'full' Removes built and source site/s
|
57
|
+
#
|
58
|
+
def remove(args, opts = {})
|
59
|
+
init(args, opts)
|
60
|
+
|
61
|
+
if opts['all']
|
62
|
+
list(MrHyde.sources_sites).each do |sm|
|
63
|
+
remove_site sm, opts
|
64
|
+
end
|
65
|
+
elsif args.kind_of? Array
|
66
|
+
args.each do |sm|
|
67
|
+
remove_site sm, opts
|
68
|
+
end
|
69
|
+
else
|
70
|
+
remove_site args, opts
|
71
|
+
end
|
72
|
+
rescue Exception => e
|
73
|
+
MrHyde.logger.error "cannot remove the site: #{e}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Builds the site
|
77
|
+
# Params:
|
78
|
+
# :name
|
79
|
+
# String => builds the concrete site
|
80
|
+
# Array[String] => builds the correspondings site names
|
81
|
+
# empty => builds all sites with option 'all'
|
82
|
+
# opts
|
83
|
+
# Hash
|
84
|
+
# 'all' => 'all' Builds all built sites
|
85
|
+
#
|
86
|
+
def build(args, opts = {})
|
87
|
+
init(args, opts)
|
88
|
+
|
89
|
+
unless opts.delete('main')
|
90
|
+
# If there is no main site then it is built
|
91
|
+
build_main_site(opts) unless File.exist? MrHyde.destination
|
92
|
+
|
93
|
+
if opts["all"]
|
94
|
+
build_sites list(MrHyde.sources_sites), opts
|
95
|
+
elsif args.kind_of? Array
|
96
|
+
build_sites args, opts
|
97
|
+
elsif args.kind_of? String
|
98
|
+
build_site args, opts
|
99
|
+
end
|
100
|
+
else
|
101
|
+
# Fetching the list of built sites to rebuild again once the main site has been built
|
102
|
+
if File.exist? MrHyde.destination
|
103
|
+
nested_sites = built_list
|
104
|
+
build_main_site(opts)
|
105
|
+
build_sites nested_sites, opts
|
106
|
+
else
|
107
|
+
build_main_site(opts)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
rescue Exception => e
|
111
|
+
MrHyde.logger.error "cannot build site: #{e}"
|
112
|
+
MrHyde.logger.error e.backtrace
|
113
|
+
end
|
114
|
+
|
115
|
+
# This method returns a list of nested sites
|
116
|
+
#
|
117
|
+
def list(path)
|
118
|
+
entries = Dir.entries(path)
|
119
|
+
entries.reject! { |item| item == '.' or item == '..' }
|
120
|
+
entries
|
121
|
+
end
|
122
|
+
|
123
|
+
def sources_list
|
124
|
+
list MrHyde.sources_sites
|
125
|
+
end
|
126
|
+
|
127
|
+
def built_list
|
128
|
+
return [] unless File.exist? MrHyde.destination
|
129
|
+
sources = sources_list
|
130
|
+
builts = list(MrHyde.destination)
|
131
|
+
|
132
|
+
builts.select do |site|
|
133
|
+
site if sources.include?(site)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def exist?(name, opts)
|
138
|
+
File.exist? File.join(@source, name)
|
139
|
+
end
|
140
|
+
|
141
|
+
def built?(name, opts)
|
142
|
+
File.exist? File.join(MrHyde.destination, name)
|
143
|
+
end
|
144
|
+
|
145
|
+
def has_custom_config?(name, opts)
|
146
|
+
File.exist? custom_config(name, opts)
|
147
|
+
end
|
148
|
+
|
149
|
+
def site_path(name)
|
150
|
+
source = is_main?(name) ? @source : File.join(MrHyde.source, MrHyde.sources_sites)
|
151
|
+
Jekyll.sanitized_path(source , name)
|
152
|
+
end
|
153
|
+
|
154
|
+
def custom_config(name, opts)
|
155
|
+
File.join site_path(name), opts['jekyll_config']
|
156
|
+
end
|
157
|
+
|
158
|
+
def is_main?(name)
|
159
|
+
File.directory? File.join(MrHyde.sources, name)
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def create_site(args, opts = {})
|
165
|
+
begin
|
166
|
+
if args.kind_of? Array
|
167
|
+
args.each do |name|
|
168
|
+
raise() if is_main(args)
|
169
|
+
end
|
170
|
+
else
|
171
|
+
raise() if is_main?(args)
|
172
|
+
end
|
173
|
+
rescue Exception => e
|
174
|
+
raise ArgumentError, 'The site\'s name cannot be the same than the main site name'
|
175
|
+
end
|
176
|
+
|
177
|
+
MrHyde::Extensions::New.process [File.join(MrHyde.sources_sites, args)], opts
|
178
|
+
MrHyde.logger.info "New #{args} created in #{MrHyde.sources_sites}"
|
179
|
+
exist? args, opts
|
180
|
+
end
|
181
|
+
|
182
|
+
def remove_site(name, opts = {})
|
183
|
+
# OBSOLOTE
|
184
|
+
# This checking is not mandatory, never can be removed form here the main site
|
185
|
+
if is_main?(name)
|
186
|
+
MrHyde.logger.warning "Cannot remove main site: #{name}"
|
187
|
+
return
|
188
|
+
end
|
189
|
+
|
190
|
+
if opts['full'] and File.exist? File.join(MrHyde.sources_sites, name)
|
191
|
+
FileUtils.remove_dir File.join(MrHyde.sources_sites, name)
|
192
|
+
MrHyde.logger.info "#{name} removed from #{MrHyde.sources_sites}"
|
193
|
+
end
|
194
|
+
if File.exist? File.join(MrHyde.destination, name)
|
195
|
+
FileUtils.remove_dir File.join(MrHyde.destination, name)
|
196
|
+
MrHyde.logger.info "#{name} removed from #{MrHyde.destination}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def build_sites(site_names, opts)
|
201
|
+
site_names.each do |sn|
|
202
|
+
begin
|
203
|
+
build_site(sn, opts)
|
204
|
+
rescue Exception => e
|
205
|
+
MrHyde.logger.error e
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def build_site(name, opts)
|
211
|
+
conf = MrHyde.site_configuration(name)
|
212
|
+
Jekyll::Commands::Build.process conf
|
213
|
+
MrHyde.logger.info "#{name} built in #{MrHyde.destination}"
|
214
|
+
built? name, opts
|
215
|
+
end
|
216
|
+
|
217
|
+
def build_main_site(opts)
|
218
|
+
conf = MrHyde.main_site_configuration
|
219
|
+
Jekyll::Commands::Build.process conf
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
def check_site(site_name, method, message)
|
224
|
+
if not send(method, site_name)
|
225
|
+
MrHyde.logger.debug message
|
226
|
+
return false
|
227
|
+
end
|
228
|
+
true
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
end
|
data/lib/mr_hyde/version.rb
CHANGED
data/lib/mr_hyde.rb
CHANGED
@@ -1,50 +1,112 @@
|
|
1
|
-
require "mr_hyde/version"
|
2
|
-
require "mr_hyde/blog"
|
3
|
-
require "mr_hyde/configuration"
|
4
|
-
require "mr_hyde/commands/new"
|
5
|
-
require "mr_hyde/commands/build"
|
6
|
-
|
7
|
-
require "logger"
|
8
1
|
require "fileutils"
|
2
|
+
require "logger"
|
9
3
|
|
10
|
-
require "jekyll/stevenson"
|
11
4
|
require "jekyll/log_adapter"
|
12
5
|
require "jekyll/utils"
|
13
6
|
|
7
|
+
require "mr_hyde/version"
|
8
|
+
require "mr_hyde/site"
|
9
|
+
require "mr_hyde/configuration"
|
10
|
+
require "mr_hyde/commands/new"
|
11
|
+
require "mr_hyde/commands/build"
|
12
|
+
|
14
13
|
module MrHyde
|
14
|
+
require "mr_hyde/jekyll_ext/jekyll"
|
15
|
+
require "mr_hyde/jekyll_ext/site"
|
16
|
+
require "mr_hyde/jekyll_ext/tags/include"
|
17
|
+
require "mr_hyde/jekyll_ext/converters/scss"
|
18
|
+
|
15
19
|
class << self
|
20
|
+
attr_reader :source, :config
|
16
21
|
attr_accessor :configuration
|
17
22
|
|
23
|
+
# OBSOLETE
|
18
24
|
def configure
|
19
25
|
self.configuration ||= Configuration.new
|
20
26
|
yield(configuration) if block_given?
|
21
27
|
end
|
22
28
|
|
29
|
+
# Mr.Hyde Configuration
|
23
30
|
def configuration(override = Hash.new)
|
24
|
-
config = Configuration
|
25
|
-
|
31
|
+
@config = private_configuration(override, Configuration::DEFAULTS)
|
32
|
+
@source = File.expand_path(config['source'])
|
33
|
+
@source = Dir.pwd unless @source == Dir.pwd
|
34
|
+
@source = @source.freeze
|
35
|
+
@config
|
36
|
+
end
|
37
|
+
|
38
|
+
# Jekyll Configuration
|
39
|
+
def main_site_configuration
|
40
|
+
# The order is important here, the last one overrides the previous ones
|
41
|
+
site_configuration nil
|
42
|
+
end
|
43
|
+
|
44
|
+
# Jekyll per site configuration
|
45
|
+
# This method gets the config files which must be read from jekyll.
|
46
|
+
# _config.yml < sources/sites/site/_config.yml < override
|
47
|
+
#
|
48
|
+
def site_configuration(site_name = nil)
|
49
|
+
jekyll_config = jekyll_defaults(site_name)
|
50
|
+
site_name ||= config['mainsite']
|
51
|
+
opts = {}
|
26
52
|
|
27
|
-
|
28
|
-
|
29
|
-
|
53
|
+
# The order is important here, the last one overrides the previous one
|
54
|
+
opts['config'] = []
|
55
|
+
opts['config'] << Jekyll.sanitized_path(source, config['jekyll_config']) if has_jekyll_config?
|
56
|
+
opts['config'] << Site.custom_config(site_name, config) if Site.has_custom_config?(site_name, config)
|
57
|
+
|
58
|
+
jekyll_config.merge(opts)
|
59
|
+
end
|
60
|
+
|
61
|
+
# If no site name is passed in then the configuration defaults are set for the main site
|
62
|
+
def jekyll_defaults(site_name = nil)
|
63
|
+
conf = if site_name
|
64
|
+
{ 'baseurl' => '/' + site_name,
|
65
|
+
'destination' => File.join(MrHyde.destination, site_name),
|
66
|
+
'source' => File.join(MrHyde.sources_sites, site_name) }
|
67
|
+
else
|
68
|
+
site_name = config['mainsite']
|
69
|
+
{ 'source' => File.join(sources, site_name),
|
70
|
+
'destination' => File.join(MrHyde.destination) }
|
30
71
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
72
|
+
|
73
|
+
conf.merge({ 'layouts' => File.join(MrHyde.sources, config['layouts']) })
|
74
|
+
end
|
75
|
+
|
76
|
+
def has_jekyll_config?
|
77
|
+
File.exist? File.expand_path(source, @config['jekyll_config'])
|
78
|
+
end
|
79
|
+
|
80
|
+
def sources
|
81
|
+
config['sources']
|
82
|
+
end
|
83
|
+
|
84
|
+
def sources_sites
|
85
|
+
File.join config['sources'], config['sources_sites']
|
86
|
+
end
|
87
|
+
|
88
|
+
def destination
|
89
|
+
config['destination']
|
90
|
+
end
|
91
|
+
|
92
|
+
def main_site
|
93
|
+
File.join source, sources, config['mainsite']
|
36
94
|
end
|
37
95
|
|
38
96
|
# Public: Fetch the logger instance for this Jekyll process.
|
39
97
|
#
|
40
98
|
# Returns the LogAdapter instance.
|
41
99
|
def logger
|
42
|
-
|
100
|
+
@logger = LogAdapter.new(Stevenson.new, (ENV['MRHYDE_LOG_LEVEL'] || :info).to_sym)
|
101
|
+
end
|
102
|
+
|
103
|
+
def logger=(writer)
|
104
|
+
@logger = LogAdapter.new(writer)
|
43
105
|
end
|
44
106
|
|
45
107
|
# Creates the folders for the sources and destination,
|
46
108
|
# by default will be created under root folder.
|
47
|
-
# Copies the default _config.yml for all
|
109
|
+
# Copies the default _config.yml for all sites, in root folder.
|
48
110
|
#
|
49
111
|
# Throws a SystemExit exception
|
50
112
|
#
|
@@ -57,7 +119,7 @@ module MrHyde
|
|
57
119
|
end
|
58
120
|
|
59
121
|
if opts['blank']
|
60
|
-
|
122
|
+
create_blank_site new_site_path
|
61
123
|
else
|
62
124
|
create_sample_files new_site_path
|
63
125
|
end
|
@@ -68,6 +130,14 @@ module MrHyde
|
|
68
130
|
Commands::Build.process opts
|
69
131
|
end
|
70
132
|
|
133
|
+
def built_list
|
134
|
+
Site.built_list
|
135
|
+
end
|
136
|
+
|
137
|
+
def sources_list
|
138
|
+
Site.sources_list
|
139
|
+
end
|
140
|
+
|
71
141
|
private
|
72
142
|
|
73
143
|
def preserve_source_location?(path, opts)
|
@@ -76,18 +146,49 @@ module MrHyde
|
|
76
146
|
|
77
147
|
def create_sample_files(path)
|
78
148
|
FileUtils.cp_r site_template + '/.', path
|
79
|
-
|
80
|
-
|
149
|
+
MrHyde.logger.info "New Mr. Hyde Site installed in #{path}"
|
150
|
+
# Copying the original _config.yml from jekyll to mrhyde folder
|
151
|
+
# jekyll_config = MrHyde::Extensions::New.default_config_file
|
152
|
+
# FileUtils.copy_file(jekyll_config, File.join(path, File.basename(jekyll_config)))
|
153
|
+
# Creating the default jekyll site in mrhyde
|
81
154
|
Dir.chdir(path) do
|
82
155
|
FileUtils.mkdir(%w(sources)) unless File.exist? 'sources'
|
83
|
-
|
156
|
+
Site.create ['sample-site'], { 'force' => 'force' }
|
157
|
+
Site.create ['sample-full-site'], { 'full' => 'full', 'force' => 'force' }
|
84
158
|
end
|
159
|
+
end
|
85
160
|
|
161
|
+
def create_blank_site(path)
|
162
|
+
Dir.chdir(path) do
|
163
|
+
FileUtils.mkdir('sources')
|
164
|
+
Dir.chdir('sources') do
|
165
|
+
FileUtils.mkdir %w(_layouts _includes main_site)
|
166
|
+
end
|
167
|
+
Dir.chdir(File.join('sources', 'main_site')) do
|
168
|
+
FileUtils.touch 'index.html'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
MrHyde.logger.info "New Mr. Hyde Site installed in #{path}"
|
86
172
|
end
|
87
173
|
|
88
174
|
def site_template
|
89
175
|
File.expand_path("./site_template", File.dirname(__FILE__))
|
90
176
|
end
|
177
|
+
|
178
|
+
def private_configuration(override = Hash.new, defaults)
|
179
|
+
config = Configuration[defaults]
|
180
|
+
override = Configuration[override].stringify_keys
|
181
|
+
|
182
|
+
unless override.delete('skip_config_files')
|
183
|
+
override['config'] ||= config['config']
|
184
|
+
config = config.read_config_files(config.config_files(override))
|
185
|
+
end
|
186
|
+
# Merge DEFAULTS < _config.yml < override
|
187
|
+
config = Jekyll::Utils.deep_merge_hashes(config, override).stringify_keys
|
188
|
+
set_timezone(config['timezone']) if config['timezone']
|
189
|
+
|
190
|
+
config
|
191
|
+
end
|
91
192
|
end
|
92
193
|
|
93
194
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Site settings
|
2
|
+
title: Global Site Title
|
3
|
+
subtitle: This is is the global subtitle
|
4
|
+
email: your-email@domain.com
|
5
|
+
description: > # this means to ignore newlines until "baseurl:"
|
6
|
+
This is the parent site of all generated sites by Mr. Hyde.
|
7
|
+
Write an awesome description for your new site here. You can edit this
|
8
|
+
line in _config.yml. It will appear in your document head meta (for
|
9
|
+
Google search results) and in your feed.xml site description.
|
10
|
+
baseurl: "" # the subpath of your site, e.g. /blog/
|
11
|
+
mainsite: "main_site" # this is the name of the root default site, where all sites will be nested
|
12
|
+
url: "http://yourdomain.com" # the base hostname & protocol for your site
|
13
|
+
twitter_username: mrhyderb
|
14
|
+
github_username: mrhyde
|
@@ -1,11 +1,2 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
email: your-email@domain.com
|
4
|
-
description: > # this means to ignore newlines until "baseurl:"
|
5
|
-
Write an awesome description for your new site here. You can edit this
|
6
|
-
line in _config.yml. It will appear in your document head meta (for
|
7
|
-
Google search results) and in your feed.xml site description.
|
8
|
-
baseurl: "" # the subpath of your site, e.g. /blog/
|
9
|
-
url: "http://yourdomain.com" # the base hostname & protocol for your site
|
10
|
-
twitter_username: mrhyderb
|
11
|
-
github_username: mrhyde
|
1
|
+
# Mr. Hyde settings
|
2
|
+
mainsite: "main_site" # this is the name of the root default site, where all sites will be nested
|
@@ -0,0 +1,204 @@
|
|
1
|
+
/**
|
2
|
+
* Reset some basic elements
|
3
|
+
*/
|
4
|
+
body, h1, h2, h3, h4, h5, h6,
|
5
|
+
p, blockquote, pre, hr,
|
6
|
+
dl, dd, ol, ul, figure {
|
7
|
+
margin: 0;
|
8
|
+
padding: 0;
|
9
|
+
}
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Basic styling
|
15
|
+
*/
|
16
|
+
body {
|
17
|
+
font-family: $base-font-family;
|
18
|
+
font-size: $base-font-size;
|
19
|
+
line-height: $base-line-height;
|
20
|
+
font-weight: 300;
|
21
|
+
color: $text-color;
|
22
|
+
background-color: $background-color;
|
23
|
+
-webkit-text-size-adjust: 100%;
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Set `margin-bottom` to maintain vertical rhythm
|
30
|
+
*/
|
31
|
+
h1, h2, h3, h4, h5, h6,
|
32
|
+
p, blockquote, pre,
|
33
|
+
ul, ol, dl, figure,
|
34
|
+
%vertical-rhythm {
|
35
|
+
margin-bottom: $spacing-unit / 2;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Images
|
42
|
+
*/
|
43
|
+
img {
|
44
|
+
max-width: 100%;
|
45
|
+
vertical-align: middle;
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Figures
|
52
|
+
*/
|
53
|
+
figure > img {
|
54
|
+
display: block;
|
55
|
+
}
|
56
|
+
|
57
|
+
figcaption {
|
58
|
+
font-size: $small-font-size;
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Lists
|
65
|
+
*/
|
66
|
+
ul, ol {
|
67
|
+
margin-left: $spacing-unit;
|
68
|
+
}
|
69
|
+
|
70
|
+
li {
|
71
|
+
> ul,
|
72
|
+
> ol {
|
73
|
+
margin-bottom: 0;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Headings
|
81
|
+
*/
|
82
|
+
h1, h2, h3, h4, h5, h6 {
|
83
|
+
font-weight: 300;
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Links
|
90
|
+
*/
|
91
|
+
a {
|
92
|
+
color: $brand-color;
|
93
|
+
text-decoration: none;
|
94
|
+
|
95
|
+
&:visited {
|
96
|
+
color: darken($brand-color, 15%);
|
97
|
+
}
|
98
|
+
|
99
|
+
&:hover {
|
100
|
+
color: $text-color;
|
101
|
+
text-decoration: underline;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Blockquotes
|
109
|
+
*/
|
110
|
+
blockquote {
|
111
|
+
color: $grey-color;
|
112
|
+
border-left: 4px solid $grey-color-light;
|
113
|
+
padding-left: $spacing-unit / 2;
|
114
|
+
font-size: 18px;
|
115
|
+
letter-spacing: -1px;
|
116
|
+
font-style: italic;
|
117
|
+
|
118
|
+
> :last-child {
|
119
|
+
margin-bottom: 0;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Code formatting
|
127
|
+
*/
|
128
|
+
pre,
|
129
|
+
code {
|
130
|
+
font-size: 15px;
|
131
|
+
border: 1px solid $grey-color-light;
|
132
|
+
border-radius: 3px;
|
133
|
+
background-color: #eef;
|
134
|
+
}
|
135
|
+
|
136
|
+
code {
|
137
|
+
padding: 1px 5px;
|
138
|
+
}
|
139
|
+
|
140
|
+
pre {
|
141
|
+
padding: 8px 12px;
|
142
|
+
overflow-x: scroll;
|
143
|
+
|
144
|
+
> code {
|
145
|
+
border: 0;
|
146
|
+
padding-right: 0;
|
147
|
+
padding-left: 0;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Wrapper
|
155
|
+
*/
|
156
|
+
.wrapper {
|
157
|
+
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
|
158
|
+
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
|
159
|
+
margin-right: auto;
|
160
|
+
margin-left: auto;
|
161
|
+
padding-right: $spacing-unit;
|
162
|
+
padding-left: $spacing-unit;
|
163
|
+
@extend %clearfix;
|
164
|
+
|
165
|
+
@include media-query($on-laptop) {
|
166
|
+
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
|
167
|
+
max-width: calc(#{$content-width} - (#{$spacing-unit}));
|
168
|
+
padding-right: $spacing-unit / 2;
|
169
|
+
padding-left: $spacing-unit / 2;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Clearfix
|
177
|
+
*/
|
178
|
+
%clearfix {
|
179
|
+
|
180
|
+
&:after {
|
181
|
+
content: "";
|
182
|
+
display: table;
|
183
|
+
clear: both;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Icons
|
191
|
+
*/
|
192
|
+
.icon {
|
193
|
+
|
194
|
+
> svg {
|
195
|
+
display: inline-block;
|
196
|
+
width: 16px;
|
197
|
+
height: 16px;
|
198
|
+
vertical-align: middle;
|
199
|
+
|
200
|
+
path {
|
201
|
+
fill: $grey-color;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|