mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-06 03:01:43 -04:00
Merge branch 'master' into frontmatter-defaults
This commit is contained in:
@@ -20,6 +20,7 @@ require 'fileutils'
|
||||
require 'time'
|
||||
require 'safe_yaml'
|
||||
require 'English'
|
||||
require 'pathname'
|
||||
|
||||
# 3rd party
|
||||
require 'liquid'
|
||||
@@ -61,7 +62,7 @@ require_all 'jekyll/tags'
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
|
||||
module Jekyll
|
||||
VERSION = '1.2.0'
|
||||
VERSION = '1.2.1'
|
||||
|
||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||
# options with anything in _config.yml, and adding the given options on top.
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'set'
|
||||
|
||||
module Jekyll
|
||||
class Site
|
||||
# Handles the cleanup of a site's destination before the site is built.
|
||||
# Handles the cleanup of a site's destination before it is built.
|
||||
class Cleaner
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@@ -15,14 +15,14 @@ module Jekyll
|
||||
|
||||
private
|
||||
|
||||
# Private: The list of files and directories to be deleted during the cleanup process
|
||||
# Private: The list of files and directories to be deleted during cleanup process
|
||||
#
|
||||
# Returns an Array with the file and directory paths
|
||||
# Returns an Array of the file and directory paths
|
||||
def obsolete_files
|
||||
(existing_files - new_files - new_dirs + replaced_files).to_a
|
||||
end
|
||||
|
||||
# Private: The list of existing files, except those included in keep_files and hidden files.
|
||||
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
@@ -33,7 +33,7 @@ module Jekyll
|
||||
files
|
||||
end
|
||||
|
||||
# Private: The list of files to be created when the site is built.
|
||||
# Private: The list of files to be created when site is built.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def new_files
|
||||
@@ -42,7 +42,7 @@ module Jekyll
|
||||
files
|
||||
end
|
||||
|
||||
# Private: The list of directories to be created when the site is built.
|
||||
# Private: The list of directories to be created when site is built.
|
||||
# These are the parent directories of the files in #new_files.
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
@@ -57,7 +57,7 @@ module Jekyll
|
||||
new_dirs.select { |dir| File.file?(dir) }.to_set
|
||||
end
|
||||
|
||||
# Private: creates a regular expression from the config's keep_files array
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||
@@ -70,4 +70,4 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- encoding: utf-8 -*-
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve < Command
|
||||
@@ -10,32 +10,56 @@ module Jekyll
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
|
||||
# recreate NondisclosureName under utf-8 circumstance
|
||||
fh_option = WEBrick::Config::FileHandler
|
||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||
|
||||
s = HTTPServer.new(
|
||||
:Port => options['port'],
|
||||
:BindAddress => options['host'],
|
||||
:MimeTypes => mime_types,
|
||||
:DoNotReverseLookup => true
|
||||
)
|
||||
s = HTTPServer.new(webrick_options(options))
|
||||
|
||||
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
||||
|
||||
Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
|
||||
|
||||
if options['detach'] # detach the server
|
||||
pid = Process.fork {s.start}
|
||||
pid = Process.fork { s.start }
|
||||
Process.detach(pid)
|
||||
pid
|
||||
Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
|
||||
else # create a new server thread, then join it with current terminal
|
||||
t = Thread.new { s.start }
|
||||
trap("INT") { s.shutdown }
|
||||
t.join()
|
||||
end
|
||||
end
|
||||
|
||||
def self.webrick_options(config)
|
||||
opts = {
|
||||
:Port => config['port'],
|
||||
:BindAddress => config['host'],
|
||||
:MimeTypes => self.mime_types,
|
||||
:DoNotReverseLookup => true,
|
||||
:StartCallback => start_callback(config['detach'])
|
||||
}
|
||||
|
||||
if !config['verbose']
|
||||
opts.merge!({
|
||||
:AccessLog => [],
|
||||
:Logger => Log::new([], Log::WARN)
|
||||
})
|
||||
end
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
def self.start_callback(detached)
|
||||
unless detached
|
||||
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
||||
end
|
||||
end
|
||||
|
||||
def self.mime_types
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,10 +10,13 @@ module Jekyll
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => '_plugins',
|
||||
'layouts' => '_layouts',
|
||||
'data_source' => '_data',
|
||||
'keep_files' => ['.git','.svn'],
|
||||
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'encoding' => nil, # use the system encoding
|
||||
|
||||
'safe' => false,
|
||||
'detach' => false, # default to not detaching the server
|
||||
'show_drafts' => nil,
|
||||
|
||||
@@ -21,16 +21,23 @@ module Jekyll
|
||||
self.content || ''
|
||||
end
|
||||
|
||||
# Returns merged optin hash for File.read of self.site (if exists)
|
||||
# and a given param
|
||||
def merged_file_read_opts(opts)
|
||||
(self.site ? self.site.file_read_opts : {}).merge(opts)
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
#
|
||||
# base - The String path to the dir containing the file.
|
||||
# name - The String filename of the file.
|
||||
# opts - optional parameter to File.read, default at site configs
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name)
|
||||
def read_yaml(base, name, opts = {})
|
||||
begin
|
||||
self.content = File.read(File.join(base, name))
|
||||
|
||||
self.content = File.read_with_options(File.join(base, name),
|
||||
merged_file_read_opts(opts))
|
||||
if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
self.data = YAML.safe_load($1)
|
||||
@@ -78,10 +85,13 @@ module Jekyll
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns the converted content
|
||||
def render_liquid(content, payload, info)
|
||||
def render_liquid(content, payload, info, path = nil)
|
||||
Liquid::Template.parse(content).render!(payload, info)
|
||||
rescue Tags::IncludeTagError => e
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}"
|
||||
raise e
|
||||
rescue Exception => e
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{self.path}"
|
||||
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || self.path}"
|
||||
raise e
|
||||
end
|
||||
|
||||
@@ -113,7 +123,8 @@ module Jekyll
|
||||
|
||||
self.output = self.render_liquid(layout.content,
|
||||
payload,
|
||||
info)
|
||||
info,
|
||||
File.join(self.site.config['layouts'], layout.name))
|
||||
|
||||
if layout = layouts[layout.data["layout"]]
|
||||
if used.include?(layout)
|
||||
|
||||
@@ -83,3 +83,18 @@ module Enumerable
|
||||
any? { |exp| File.fnmatch?(exp, e) }
|
||||
end
|
||||
end
|
||||
|
||||
# Ruby 1.8's File.read don't support option.
|
||||
# read_with_options ignore optional parameter for 1.8,
|
||||
# and act as alias for 1.9 or later.
|
||||
class File
|
||||
if RUBY_VERSION < '1.9'
|
||||
def self.read_with_options(path, opts = {})
|
||||
self.read(path)
|
||||
end
|
||||
else
|
||||
def self.read_with_options(path, opts = {})
|
||||
self.read(path, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,10 +19,10 @@ module Jekyll
|
||||
]
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID.concat(%w[
|
||||
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
|
||||
content
|
||||
excerpt
|
||||
])
|
||||
]
|
||||
|
||||
# Post name validator. Post filenames must be like:
|
||||
# 2008-11-05-my-awesome-post.textile
|
||||
|
||||
@@ -3,7 +3,7 @@ module Jekyll
|
||||
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
||||
:categories, :exclude, :include, :source, :dest, :lsi, :pygments,
|
||||
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts
|
||||
|
||||
attr_accessor :converters, :generators
|
||||
|
||||
@@ -22,6 +22,9 @@ module Jekyll
|
||||
self.plugins = plugins_path
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
|
||||
self.file_read_opts = {}
|
||||
self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
|
||||
|
||||
self.reset
|
||||
self.setup
|
||||
end
|
||||
@@ -53,6 +56,7 @@ module Jekyll
|
||||
self.static_files = []
|
||||
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
||||
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
||||
self.data = {}
|
||||
|
||||
if self.limit_posts < 0
|
||||
raise ArgumentError, "limit_posts must be a non-negative number"
|
||||
@@ -63,11 +67,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def setup
|
||||
# Check that the destination dir isn't the source dir or a directory
|
||||
# parent to the source dir.
|
||||
if self.source =~ /^#{self.dest}/
|
||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
ensure_not_in_dest
|
||||
|
||||
# If safe mode is off, load in any Ruby files under the plugins
|
||||
# directory.
|
||||
@@ -83,6 +83,17 @@ module Jekyll
|
||||
self.generators = instantiate_subclasses(Jekyll::Generator)
|
||||
end
|
||||
|
||||
# Check that the destination dir isn't the source dir or a directory
|
||||
# parent to the source dir.
|
||||
def ensure_not_in_dest
|
||||
dest = Pathname.new(self.dest)
|
||||
Pathname.new(self.source).ascend do |path|
|
||||
if path == dest
|
||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Internal: Setup the plugin search path
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
@@ -100,6 +111,7 @@ module Jekyll
|
||||
def read
|
||||
self.read_layouts
|
||||
self.read_directories
|
||||
self.read_data(config['data_source'])
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<layouts> and create a new Layout object
|
||||
@@ -110,7 +122,7 @@ module Jekyll
|
||||
base = File.join(self.source, self.config['layouts'])
|
||||
return unless File.exists?(base)
|
||||
entries = []
|
||||
Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
|
||||
Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) }
|
||||
|
||||
entries.each do |f|
|
||||
name = f.split(".")[0..-2].join(".")
|
||||
@@ -187,6 +199,25 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
# Read and parse all yaml files under <source>/<dir>
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data(dir)
|
||||
base = File.join(self.source, dir)
|
||||
return unless File.directory?(base) && (!self.safe || !File.symlink?(base))
|
||||
|
||||
entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
|
||||
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||
|
||||
entries.each do |entry|
|
||||
path = File.join(self.source, dir, entry)
|
||||
next if File.symlink?(path) && self.safe
|
||||
|
||||
key = sanitize_filename(File.basename(entry, '.*'))
|
||||
self.data[key] = YAML.safe_load_file(path)
|
||||
end
|
||||
end
|
||||
|
||||
# Run each of the Generators.
|
||||
#
|
||||
# Returns nothing.
|
||||
@@ -252,6 +283,14 @@ module Jekyll
|
||||
hash
|
||||
end
|
||||
|
||||
# Prepare site data for site payload. The method maintains backward compatibility
|
||||
# if the key 'data' is already used in _config.yml.
|
||||
#
|
||||
# Returns the Hash to be hooked to site.data.
|
||||
def site_data
|
||||
self.config['data'] || self.data
|
||||
end
|
||||
|
||||
# The Hash payload containing site-wide data.
|
||||
#
|
||||
# Returns the Hash: { "site" => data } where data is a Hash with keys:
|
||||
@@ -273,7 +312,8 @@ module Jekyll
|
||||
"pages" => self.pages,
|
||||
"html_pages" => self.pages.reject { |page| !page.html? },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
"tags" => post_attr_hash('tags')})}
|
||||
"tags" => post_attr_hash('tags'),
|
||||
"data" => site_data})}
|
||||
end
|
||||
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
@@ -387,5 +427,11 @@ module Jekyll
|
||||
def site_cleaner
|
||||
@site_cleaner ||= Cleaner.new(self)
|
||||
end
|
||||
|
||||
def sanitize_filename(name)
|
||||
name = name.gsub(/[^\w\s_-]+/, '')
|
||||
name = name.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
||||
name = name.gsub(/\s+/, '_')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,15 @@ module Jekyll
|
||||
gist_id, filename = tag_contents[0], tag_contents[1]
|
||||
gist_script_tag(gist_id, filename)
|
||||
else
|
||||
"Error parsing gist id"
|
||||
raise ArgumentError.new <<-eos
|
||||
Syntax error in tag 'gist' while parsing the following markup:
|
||||
|
||||
#{@markup}
|
||||
|
||||
Valid syntax:
|
||||
for public gists: {% gist 1234567 %}
|
||||
for private gists: {% gist user/1234567 %}
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module Jekyll
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup.strip =~ SYNTAX
|
||||
@lang = $1
|
||||
@lang = $1.downcase
|
||||
@options = {}
|
||||
if defined?($2) && $2 != ''
|
||||
$2.split.each do |opt|
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
module Jekyll
|
||||
module Tags
|
||||
class IncludeTagError < StandardError
|
||||
attr_accessor :path
|
||||
|
||||
def initialize(msg, path)
|
||||
super(msg)
|
||||
@path = path
|
||||
end
|
||||
end
|
||||
|
||||
class IncludeTag < Liquid::Tag
|
||||
|
||||
MATCHER = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
|
||||
|
||||
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||
|
||||
INCLUDES_DIR = '_includes'
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@file, @params = markup.strip.split(' ', 2);
|
||||
validate_params if @params
|
||||
end
|
||||
|
||||
def parse_params(context)
|
||||
validate_syntax
|
||||
|
||||
params = {}
|
||||
markup = @params
|
||||
|
||||
while match = MATCHER.match(markup) do
|
||||
while match = VALID_SYNTAX.match(markup) do
|
||||
markup = markup[match.end(0)..-1]
|
||||
|
||||
value = if match[2]
|
||||
@@ -31,55 +43,91 @@ module Jekyll
|
||||
params
|
||||
end
|
||||
|
||||
# ensure the entire markup string from start to end is valid syntax, and params are separated by spaces
|
||||
def validate_syntax
|
||||
full_matcher = Regexp.compile('\A\s*(?:' + MATCHER.to_s + '(?=\s|\z)\s*)*\z')
|
||||
unless @params =~ full_matcher
|
||||
raise SyntaxError.new <<-eos
|
||||
def validate_file_name
|
||||
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
||||
raise ArgumentError.new <<-eos
|
||||
Invalid syntax for include tag. File contains invalid characters or sequences:
|
||||
|
||||
#{@file}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
def validate_params
|
||||
full_valid_syntax = Regexp.compile('\A\s*(?:' + VALID_SYNTAX.to_s + '(?=\s|\z)\s*)*\z')
|
||||
unless @params =~ full_valid_syntax
|
||||
raise ArgumentError.new <<-eos
|
||||
Invalid syntax for include tag:
|
||||
|
||||
#{@params}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
{% include file.ext param='value' param2="value" %}
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
includes_dir = File.join(context.registers[:site].source, '_includes')
|
||||
# Grab file read opts in the context
|
||||
def file_read_opts(context)
|
||||
context.registers[:site].file_read_opts
|
||||
end
|
||||
|
||||
if error = validate_file(includes_dir)
|
||||
return error
|
||||
end
|
||||
|
||||
source = File.read(File.join(includes_dir, @file))
|
||||
partial = Liquid::Template.parse(source)
|
||||
|
||||
context.stack do
|
||||
context['include'] = parse_params(context) if @params
|
||||
partial.render(context)
|
||||
def retrieve_variable(context)
|
||||
if /\{\{([\w\-\.]+)\}\}/ =~ @file
|
||||
raise ArgumentError.new("No variable #{$1} was found in include tag") if context[$1].nil?
|
||||
@file = context[$1]
|
||||
end
|
||||
end
|
||||
|
||||
def validate_file(includes_dir)
|
||||
if File.symlink?(includes_dir)
|
||||
return "Includes directory '#{includes_dir}' cannot be a symlink"
|
||||
end
|
||||
def render(context)
|
||||
dir = File.join(context.registers[:site].source, INCLUDES_DIR)
|
||||
validate_dir(dir, context.registers[:site].safe)
|
||||
|
||||
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
||||
return "Include file '#{@file}' contains invalid characters or sequences"
|
||||
end
|
||||
retrieve_variable(context)
|
||||
validate_file_name
|
||||
|
||||
file = File.join(includes_dir, @file)
|
||||
file = File.join(dir, @file)
|
||||
validate_file(file, context.registers[:site].safe)
|
||||
|
||||
partial = Liquid::Template.parse(source(file, context))
|
||||
|
||||
context.stack do
|
||||
context['include'] = parse_params(context) if @params
|
||||
partial.render!(context)
|
||||
end
|
||||
rescue => e
|
||||
raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
|
||||
end
|
||||
|
||||
def validate_dir(dir, safe)
|
||||
if File.symlink?(dir) && safe
|
||||
raise IOError.new "Includes directory '#{dir}' cannot be a symlink"
|
||||
end
|
||||
end
|
||||
|
||||
def validate_file(file, safe)
|
||||
if !File.exists?(file)
|
||||
return "Included file #{@file} not found in _includes directory"
|
||||
elsif File.symlink?(file)
|
||||
return "The included file '_includes/#{@file}' should not be a symlink"
|
||||
raise IOError.new "Included file '#{@file}' not found in '#{INCLUDES_DIR}' directory"
|
||||
elsif File.symlink?(file) && safe
|
||||
raise IOError.new "The included file '#{INCLUDES_DIR}/#{@file}' should not be a symlink"
|
||||
end
|
||||
end
|
||||
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def source(file, context)
|
||||
File.read_with_options(file, file_read_opts(context))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,9 +50,11 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
puts "ERROR: post_url: \"#{@orig_post}\" could not be found"
|
||||
raise ArgumentError.new <<-eos
|
||||
Could not find post "#{@orig_post}" in tag 'post_url'.
|
||||
|
||||
return "#"
|
||||
Make sure the post exists and the name is correct.
|
||||
eos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,16 +34,16 @@ a:visited { color: #a0a; }
|
||||
/* Home
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
ul.posts {
|
||||
.posts {
|
||||
list-style-type: none;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
ul.posts li {
|
||||
.posts li {
|
||||
line-height: 1.75em;
|
||||
}
|
||||
|
||||
ul.posts span {
|
||||
.posts span {
|
||||
color: #aaa;
|
||||
font-family: Monaco, "Courier New", monospace;
|
||||
font-size: 80%;
|
||||
@@ -63,38 +63,38 @@ ul.posts span {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.site .header a {
|
||||
.header a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site .header h1.title {
|
||||
.title {
|
||||
display: inline-block;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.site .header h1.title a {
|
||||
.title a {
|
||||
color: #a00;
|
||||
}
|
||||
|
||||
.site .header h1.title a:hover {
|
||||
.title a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.site .header a.extra {
|
||||
.header a.extra {
|
||||
color: #aaa;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.site .header a.extra:hover {
|
||||
.header a.extra:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.site .meta {
|
||||
.meta {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.site .footer {
|
||||
.footer {
|
||||
font-size: 80%;
|
||||
color: #666;
|
||||
border-top: 4px solid #eee;
|
||||
@@ -102,22 +102,22 @@ ul.posts span {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site .footer .contact {
|
||||
.footer .contact {
|
||||
float: left;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
.site .footer .contact a {
|
||||
.footer .contact a {
|
||||
color: #8085C1;
|
||||
}
|
||||
|
||||
.site .footer .rss {
|
||||
.footer .rss {
|
||||
margin-top: 1.1em;
|
||||
margin-right: -.2em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.site .footer .rss img {
|
||||
.footer .rss img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user