# -*- encoding: utf-8 -*- # # This file initializes all the extensions shipped with webgen. ######################################################################## # Used validators and other objects true_or_false = lambda do |val| raise "The value has to be 'true' or 'false'" unless val == true || val == false val end is_string = lambda do |val| raise "The value has to be a string" unless val.kind_of?(String) val end is_array = lambda do |val| raise "The value has to be an array" unless val.kind_of?(Array) val end is_hash = lambda do |val| raise "The value has to be a hash" unless val.kind_of?(Hash) val end is_integer = lambda do |val| raise "The value has to be an integer" unless val.kind_of?(Integer) val end symbolic_hash = lambda do |val| raise 'The value has to be a hash' unless val.kind_of?(Hash) val.each_with_object({}) {|(k,v), h| h[k.to_sym] = v} end ######################################################################## # General configuration parameters option('website.tmpdir', 'tmp', &is_string) option('website.cache', ['file', 'webgen.cache']) do |val| raise "The value has to be an array with two values" unless val.kind_of?(Array) && val.length == 2 val.map! {|v| v.to_s} raise "The first value has to be 'file' or 'string'" unless val[0] == 'file' || val[0] == 'string' val end option('website.dry_run', false, &true_or_false) option('website.lang', 'en') do |val| lang = LanguageManager.language_for_code(val) raise "Unknown language code '#{val}'" if lang.nil? lang end option('website.base_url', '', &is_string) option('website.link_to_current_page', true, &true_or_false) ######################################################################## # Everything related to the content processor extension require 'webgen/content_processor' website.ext.content_processor = content_processor = Webgen::ContentProcessor.new content_processor.register('Blocks') content_processor.register('Builder') content_processor.register('CSSMinify', :name => 'cssminify') content_processor.register('Erb') option('content_processor.erb.trim_mode', nil, &is_string) content_processor.register('Erubis') option('content_processor.erubis.use_pi', false, &true_or_false) option('content_processor.erubis.options', {}, &symbolic_hash) content_processor.register('Fragments') content_processor.register('Haml', :ext_map => {'haml' => 'html'}) content_processor.register('HtmlHead') content_processor.register('Kramdown') option('content_processor.kramdown.options', {:auto_ids => true}, &symbolic_hash) option('content_processor.kramdown.handle_links', true, &true_or_false) option('content_processor.kramdown.ignore_unknown_fragments', false, &true_or_false) content_processor.register('Maruku') content_processor.register('Rainpress') option('content_processor.rainpress.options', {}, &is_hash) content_processor.register('RDiscount', :name => 'rdiscount') content_processor.register('RDoc', :name => 'rdoc', :ext_map => {'rdoc' => 'html'}) content_processor.register('RedCloth', :name => 'redcloth', :ext_map => {'textile' => 'html'}) option('content_processor.redcloth.hard_breaks', false, &true_or_false) content_processor.register('Ruby') content_processor.register('Sass', :ext_map => {'sass' => 'css'}) content_processor.register('Scss', :ext_map => {'scss' => 'css'}) option('content_processor.sass.options', {}, &symbolic_hash) website.ext.sass_load_paths = [] content_processor.register('Tags') content_processor.register('Tidy') option('content_processor.tidy.options', "-raw", &is_string) content_processor.register('Tikz', :ext_map => {'tikz' => 'png'}) option('content_processor.tikz.libraries', [], &is_array) option('content_processor.tikz.opts', '', &is_string) option('content_processor.tikz.resolution', '72 72',) do |val| raise "The value has to be a string in the format 'RENDER_RES OUTPUT_RES'" unless val.kind_of?(String) && val =~ /^\d+\s+\d+$/ val end option('content_processor.tikz.transparent', false, &true_or_false) option('content_processor.tikz.template', '/templates/tikz.template', &is_string) option('content_processor.tikz.engine', 'pdflatex', &is_string) content_processor.register('Xmllint') option('content_processor.xmllint.options', "--catalogs --noout --valid", &is_string) ######################################################################## # The Context extensions website.ext.context_modules = [] ######################################################################## # Everything related to the destination extension require 'webgen/destination' option('destination', ['file_system', 'out']) do |val| raise "The value needs to be an array with at least one value (the destination extension name)" unless val.kind_of?(Array) && val.length >=1 val end website.ext.destination = destination = Webgen::Destination.new(website) destination.register("FileSystem") # TODO: Do we really need this option? #config.output.do_deletion(false, :doc => 'Specifies whether the generated output paths should be deleted once the sources are deleted') ######################################################################## # Everything related to the item tracker extension require 'webgen/item_tracker' website.ext.item_tracker = item_tracker = Webgen::ItemTracker.new(website) item_tracker.register('NodeContent') item_tracker.register('NodeMetaInfo') website.blackboard.add_listener(:after_node_created, 'item_tracker.node_meta_info') do |node| item_tracker.add(node, :node_meta_info, node) item_tracker.add(node, :node_meta_info, node, Webgen::ItemTracker::NodeMetaInfo::CONTENT_MODIFICATION_KEY) end item_tracker.register('Nodes') item_tracker.register('File') item_tracker.register('MissingNode') website.blackboard.add_listener(:node_resolution_failed, 'item_tracker.missing_node') do |path, lang| if website.ext.path_handler.current_dest_node website.ext.item_tracker.add(website.ext.path_handler.current_dest_node, :missing_node, path, lang) website.logger.error do ["Could not resolve '#{path}' in language '#{lang}' in <#{website.ext.path_handler.current_dest_node}>", "webgen will automatically try to resolve this error by rendering this path again later.", "If the error persists, the content of the path in question needs to be edited to correct the error."] end end end item_tracker.register('TemplateChain') ######################################################################## # The link definitions extension website.ext.link_definitions = {} ######################################################################## # Miscellaneous extensions website.ext.misc = OpenStruct.new require 'webgen/misc/dummy_index' website.ext.misc.dummy_index = Webgen::Misc::DummyIndex.new(website) option('misc.dummy_index.enabled', true, &true_or_false) option('misc.dummy_index.directory_indexes', ['index.html']) ######################################################################## # Everything related to the node finder extension require 'webgen/node_finder' website.ext.node_finder = Webgen::NodeFinder.new(website) option('node_finder.option_sets', {}) ######################################################################## # Everything related to the path handler extension require 'webgen/path_handler' option('path_handler.patterns.case_sensitive', false, &true_or_false) option('path_handler.patterns.match_leading_dot', false, &true_or_false) option('path_handler.lang_code_in_dest_path', 'except_default') do |val| if val == true || val == false || val == 'except_default' val else raise "The value has to be 'true', 'false' or 'except_default'" end end option('path_handler.version_in_dest_path', 'except_default') do |val| if val == true || val == false || val == 'except_default' val else raise "The value has to be 'true', 'false' or 'except_default'" end end option('path_handler.default_template', 'default.template') website.ext.path_handler = path_handler = Webgen::PathHandler.new(website) # handlers are registered in invocation order path_handler.register('Directory') path_handler.register('MetaInfo', :patterns => ['/**/metainfo', '/**/*.metainfo']) path_handler.register('Template') path_handler.register('Page') path_handler.register('Copy') path_handler.register('Feed') path_handler.register('Sitemap') path_handler.register('Virtual') path_handler.register('Api') ######################################################################## # Everything related to the source extension require 'webgen/source' sources_validator = lambda do |val| raise "The value has to be an array of arrays" unless val.kind_of?(Array) && val.all? {|item| item.kind_of?(Array)} raise "Each sub array needs to specify at least the mount point and source extension name" unless val.all? {|item| item.length >= 2} val end option('sources', [['/', :file_system, 'src']], &sources_validator) option('sources.ignore_paths', ['**/*~', '**/.svn/**', '**/.gitignore']) do |val| raise "The value has to be an array of patterns" unless val.kind_of?(Array) && val.all? {|item| item.kind_of?(String)} val end website.ext.source = source = Webgen::Source.new(website) source.register("FileSystem") source.register("Stacked") source.register("TarArchive") source.passive_sources << ['/', :file_system, File.join(Webgen::Utils.data_dir, 'passive_sources')] ######################################################################## # Everything related to the tag extension require 'webgen/tag' website.ext.tag = tag = Webgen::Tag.new(website) option('tag.prefix', '', &is_string) tag.register('Date') option('tag.date.format', '%Y-%m-%d %H:%M:%S', &is_string) option('tag.date.mi', nil, &is_string) tag.register('MetaInfo', :names => ['meta_info', :default]) option('tag.meta_info.escape_html', true, &true_or_false) option('tag.meta_info.mi', nil, &is_string) tag.register('Relocatable', :names => ['relocatable', 'r'], :mandatory => ['path']) option('tag.relocatable.path', nil, &is_string) option('tag.relocatable.ignore_unknown_fragment', false, &true_or_false) tag.register('Link', :mandatory => ['path']) option('tag.link.path', nil, &is_string) option('tag.link.attr', {}, &is_hash) tag.register('ExecuteCommand', :mandatory => ['command']) option('tag.execute_command.command', nil, &is_string) option('tag.execute_command.process_output', true, &true_or_false) option('tag.execute_command.escape_html', true, &true_or_false) tag.register('IncludeFile', :mandatory => ['filename']) option('tag.include_file.filename', nil, &is_string) option('tag.include_file.process_output', true, &true_or_false) option('tag.include_file.escape_html', true, &true_or_false) tag.register('Coderay', :mandatory => ['lang']) option('tag.coderay.lang', 'ruby') option('tag.coderay.process_body', true, &true_or_false) option('tag.coderay.wrap', 'div') do |val| val = val.to_s.intern raise "The value has to be either div or span" unless val == :div || val == :span val end option('tag.coderay.css', 'style') do |val| val = val.to_s raise "The value has to be class, style or other" unless %w[class style other].include?(val) val end option('tag.coderay.line_numbers', true, &true_or_false) option('tag.coderay.line_number_start', 1, &is_integer) option('tag.coderay.bold_every', 10, &is_integer) option('tag.coderay.tab_width', 8, &is_integer) tag.register('Tikz', :mandatory => ['path']) option('tag.tikz.path', nil, &is_string) option('tag.tikz.img_attr', {}, &is_hash) tag.register('Langbar') option('tag.langbar.show_single_lang', true, &true_or_false) option('tag.langbar.show_own_lang', true, &true_or_false) option('tag.langbar.template', '/templates/tag.template') option('tag.langbar.separator', ' | ') option('tag.langbar.mapping', {}, &is_hash) tag.register('BreadcrumbTrail') option('tag.breadcrumb_trail.omit_dir_index', false, &true_or_false) option('tag.breadcrumb_trail.start_level', 0, &is_integer) option('tag.breadcrumb_trail.end_level', -1, &is_integer) option('tag.breadcrumb_trail.separator', ' / ', &is_string) option('tag.breadcrumb_trail.template', '/templates/tag.template',) tag.register('Menu') option('tag.menu.style', 'nested') do |val| raise "The value has to be 'nested' or 'flat'" unless %w[nested flat].include?(val.to_s) val.to_s end option('tag.menu.options', {}) option('tag.menu.template', '/templates/tag.template') option('tag.menu.css_class', nil) option('tag.menu.item_level_class', 'webgen-menu-level') option('tag.menu.item_submenu_class', 'webgen-menu-submenu') option('tag.menu.item_submenu_inhierarchy_class', 'webgen-menu-submenu-inhierarchy') option('tag.menu.item_selected_class', 'webgen-menu-item-selected') option('tag.menu.tracking_style', 'meta_info') do |val| val.to_s.intern end ######################################################################## # Everything related to the task extension require 'webgen/task' website.ext.task = task = Webgen::Task.new(website) task.register('GenerateWebsite') task.register('CreateWebsite', :data => {:templates => {}}) task.register('CreateBundle') load("built-in-show-changes")