module StaticCms require 'fileutils' require 'ruby_patch' require 'static_cms/version' require 'static_cms/patch' SITE_TEMPLATE_DIR = File.join(__DIR__, '../data/site_template') module Command def self.init(dir = '.') FileUtils.mkdir_p(dir) success = false FileUtils.cd(dir){|dir| success = system <<-EOS git init > #{File::NULL} git commit --allow-empty -m 'Empty commit.' > #{File::NULL} cp -r #{File.join(SITE_TEMPLATE_DIR, '*')} . > #{File::NULL} git add . > #{File::NULL} git commit -m 'Copied from site template.' > #{File::NULL} EOS } success end def self.update site_template_dir = File.join(__DIR__, '../data/site_template') FileUtils.cp_r(File.join(site_template_dir, 'templates'), '.') FileUtils.cp_r(File.join(site_template_dir, 'sources'), '.') FileUtils.cp_r(File.join(site_template_dir, 'statics'), '.') FileUtils.cp(File.join(site_template_dir, 'rakefile'), '.') end end class Site require 'yaml' CONFIG_DEFAULT = { 'lang' => 'en', 'www' => nil, 'dir' => File.join(__DIR__, 'root'), 'author' => '', 'robots' => 'noarchive', 'favicon' => 'images/favicon.png', 'charset' => 'utf-8', } attr_accessor :page_alist attr_accessor *(CONFIG_DEFAULT.keys) def initialize config = CONFIG_DEFAULT.merge(YAML.load_file('config.yaml')) @www = config.delete('www') @www += '/' unless @www[-1] == '/' config.each{|k, v| instance_variable_set("@#{k}", v)} @page_alist = Hash.new{|h, k| raise KeyError, k} YAML.load_file('pages.yaml')\ .sort\ .each{|name, params| @page_alist[name] = ::StaticCms::Page.new(self, name, params) } end end class Page require 'fileutils' require 'haml' PARAMS_DEFAULT ={ 'visible' => true, 'title' => '', 'template' => 'default', 'articles' => [], 'statics' => [], 'sources' => [], 'base' => nil, } attr_accessor :site, :name, :dir, :template_file attr_accessor *(PARAMS_DEFAULT.keys) def initialize(site, name, params = {}) @site = site @name = name @dir = File.join("root", @name) params = PARAMS_DEFAULT.merge(params) @template = params.delete('template') @template_file = File.join('templates', @template) + '.html.haml' @articles = params.delete('articles').map{|name| ::StaticCms::Article.use(self, name)} @statics = params.delete('statics').map{|file| File.join('statics', file)} @sources = params.delete('sources').map{|file| File.join('sources', file)} @base = params.delete('base') || @site.www params.each{|k, v| instance_variable_set("@#{k}", v) } end def generate FileUtils.mkdir_p(@dir) if @visible @statics.each{|file| cp_if_new(file)} @sources.each{|file| compile(file)} template_file = @template_file else @statics.each{|file| FileUtils.rm_rf(static_target(file))} @sources.each{|file| FileUtils.rm_rf(compile_target(file))} template_file = 'templates/moved.html.haml' end html = ::Haml::Engine.new(File.read(template_file)).render(self) target = File.join(@dir, 'index.html') open(target, 'w'){|io| io.write(html) io.flush io.fsync } end private def haml(text) ::Haml::Engine.new(text).render(self) end def nth_page_from_self(n) index = (@site.page_alist.to_a.index{|name, page| name == @name} + n)%@site.page_alist.size @site.page_alist.to_a[index][1] end def link_to_article(name) article = ::StaticCms::Article.alist[name] page = article.pages.first url = File.join(@site.www, page.name, "index.html\##{name}") "#{article.title}" end def cp_if_new(source) target = static_target(source) if !File.file?(target) || File.mtime(source) > File.mtime(target) FileUtils.cp(source, target) FileUtils.chmod(0644, target) end end def compile(source) ext = File.extname(source) target = compile_target(source) case ext when /\A\.sass\z/ system "sass #{source} > #{target}" else raise NotImplementedError, file end end def static_target(source) File.join(@dir, File.basename(source)) end def compile_target(source) ext = File.extname(source) File.join(@dir, File.basename(source, ext)) end end module Helpers require 'haml' EXT_TO_LANG = Hash.new(:general)\ .merge({ '.f90' => :fortran, '.f95' => :fortran, '.f03' => :fortran, '.f08' => :fortran, '.f' => :fortran, '.f77' => :fortran, '.rb' => :ruby, }) module_function def to_plain(text) escaped_text = ::Haml::Helpers.html_escape(text) ::Haml::Helpers.preserve(escaped_text) end def to_code(text, lang = :general) pre_text = to_plain(text) "
#{pre_text}
"
end
end
class Article
@alist = Hash.new{|h, k| raise KeyError, k.to_s}
def self.alist
@alist
end
PARAMS_DEFAULT = {
'title' => '',
}
attr_accessor :pages, :name, :file, :data
attr_accessor *(PARAMS_DEFAULT.keys)
def initialize(name)
@pages = []
@name = name
@file = File.join('articles', name) + '.html.yhaml'
yaml, @data = File.read(@file).split(/^\.\.\.$/, 2)
params = PARAMS_DEFAULT.merge(YAML.load(yaml))
params.each{|k, v| instance_variable_set("@#{k}", v)}
self.class.alist[@name] = self
end
def self.load
`git ls-files articles`.split\
.select{|f| f =~ /\.html\.yhaml\z/}\
.map{|f| f.sub(/\Aarticles\//, '')}\
.map{|f| File.basename(f, '.html.yhaml')}\
.each{|name| self.new(name)}
end
def self.use(page, name)
self.load unless self.alist.has_key?(name)
raise ArgumentError, name unless self.alist.has_key?(name)
article = self.alist[name]
article.pages << page
article
end
end
require 'thor'
class Runner < Thor
desc "init [DIR]", "Initialize DIR directory for StaticCms [default: .]."
def init(dir = '.')
::StaticCms::Command.init(dir)
end
desc "update", "Update templates, sources, statics (and more)."
def update
::StaticCms::Command.update
end
end
end