diff options
Diffstat (limited to 'railties/guides/rails_guides/generator.rb')
-rw-r--r-- | railties/guides/rails_guides/generator.rb | 101 |
1 files changed, 68 insertions, 33 deletions
diff --git a/railties/guides/rails_guides/generator.rb b/railties/guides/rails_guides/generator.rb index e30dd2d5f7..f577182f5f 100644 --- a/railties/guides/rails_guides/generator.rb +++ b/railties/guides/rails_guides/generator.rb @@ -1,3 +1,49 @@ +# --------------------------------------------------------------------------- +# +# This script generates the guides. It can be invoked either directly or via the +# generate_guides rake task within the railties directory. +# +# Guides are taken from the source directory, and the resulting HTML goes into the +# output directory. Assets are stored under files, and copied to output/files as +# part of the generation process. +# +# Some arguments may be passed via environment variables: +# +# WARNINGS +# If you are writing a guide, please work always with WARNINGS=1. Users can +# generate the guides, and thus this flag is off by default. +# +# Internal links (anchors) are checked. If a reference is broken levenshtein +# distance is used to suggest an existing one. This is useful since IDs are +# generated by Textile from headers and thus edits alter them. +# +# Also detects duplicated IDs. They happen if there are headers with the same +# text. Please do resolve them, if any, so guides are valid XHTML. +# +# ALL +# Set to "1" to force the generation of all guides. +# +# ONLY +# Use ONLY if you want to generate only one or a set of guides. Prefixes are +# enough: +# +# # generates only association_basics.html +# ONLY=assoc ruby rails_guides.rb +# +# Separate many using commas: +# +# # generates only +# ONLY=assoc,migrations ruby rails_guides.rb +# +# Note that if you are working on a guide generation will by default process +# only that one, so ONLY is rarely used nowadays. +# +# EDGE +# Set to "1" to indicate generated guides should be marked as edge. This +# inserts a badge and changes the preamble of the home page. +# +# --------------------------------------------------------------------------- + require 'set' require 'fileutils' @@ -11,11 +57,14 @@ require 'rails_guides/levenshtein' module RailsGuides class Generator - attr_reader :guides_dir, :source_dir, :output_dir + attr_reader :guides_dir, :source_dir, :output_dir, :edge + + GUIDES_RE = /\.(?:textile|html\.erb)$/ def initialize(output=nil) initialize_dirs(output) create_output_dir_if_needed + set_edge end def generate @@ -32,7 +81,11 @@ module RailsGuides def create_output_dir_if_needed FileUtils.mkdir_p(output_dir) - end + end + + def set_edge + @edge = ENV['EDGE'] == '1' + end def generate_guides guides_to_generate.each do |guide| @@ -42,24 +95,23 @@ module RailsGuides end def guides_to_generate - guides = Dir.entries(source_dir).grep(/\.textile(?:\.erb)?$/) - ENV.key?("ONLY") ? select_only(guides) : guides + guides = Dir.entries(source_dir).grep(GUIDES_RE) + ENV.key?('ONLY') ? select_only(guides) : guides end def select_only(guides) - prefixes = ENV["ONLY"].split(",").map(&:strip) + prefixes = ENV['ONLY'].split(",").map(&:strip) guides.select do |guide| prefixes.any? {|p| guide.start_with?(p)} end end def copy_assets - FileUtils.cp_r(File.join(guides_dir, 'images'), File.join(output_dir, 'images')) - FileUtils.cp_r(File.join(guides_dir, 'files'), File.join(output_dir, 'files')) + FileUtils.cp_r(Dir.glob("#{guides_dir}/assets/*"), output_dir) end def output_file_for(guide) - guide.sub(/\.textile(?:\.erb)?$/, '.html') + guide.sub(GUIDES_RE, '.html') end def generate?(source_file, output_file) @@ -71,13 +123,12 @@ module RailsGuides def generate_guide(guide, output_file) puts "Generating #{output_file}" File.open(File.join(output_dir, output_file), 'w') do |f| - view = ActionView::Base.new(source_dir) + view = ActionView::Base.new(source_dir, :edge => edge) view.extend(Helpers) - - if guide =~ /\.textile\.erb$/ - # Generate the erb pages with textile formatting - e.g. index/authors + + if guide =~ /\.html\.erb$/ + # Generate the special pages like the home. result = view.render(:layout => 'layout', :file => guide) - result = textile(result) else body = File.read(File.join(source_dir, guide)) body = set_header_section(body, view) @@ -85,14 +136,9 @@ module RailsGuides result = view.render(:layout => 'layout', :text => textile(body)) - warn_about_broken_links(result) if ENV.key?("WARN_BROKEN_LINKS") + warn_about_broken_links(result) if ENV['WARNINGS'] == '1' end - - # FIXME: If the doctype is in the layout textile escapes it. - # Things should be set up in a way that prevents that, a doctype - # belongs to the layout. - result = insert_doctype(result) - result = insert_edge_badge(result) if ENV.key?('INSERT_EDGE_BADGE') + f.write result end end @@ -130,7 +176,7 @@ module RailsGuides view.content_tag(:li, l.html_safe) end - children_ul = view.content_tag(:ul, children.join(" ").html_safe) + children_ul = children.empty? ? "" : view.content_tag(:ul, children.join(" ").html_safe) index << view.content_tag(:li, link.html_safe + children_ul.html_safe) end @@ -181,7 +227,7 @@ module RailsGuides anchors = Set.new html.scan(/<h\d\s+id="([^"]+)/).flatten.each do |anchor| if anchors.member?(anchor) - puts "*** DUPLICATE HEADER ID: #{anchor}, please consider rewording" if ENV.key?("WARN_DUPLICATE_HEADERS") + puts "*** DUPLICATE ID: #{anchor}, please put and explicit ID, e.g. h4(#explicit-id), or consider rewording" else anchors << anchor end @@ -203,16 +249,5 @@ module RailsGuides end end end - - def insert_doctype(html) - <<EOS + html -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -EOS - end - - def insert_edge_badge(html) - html.sub(/<body[^>]*>/, '\&<img src="images/edge_badge.png" style="position:fixed; right:0px; top:0px; border:none; z-index:100"/>') - end end end |