aboutsummaryrefslogtreecommitdiffstats
path: root/guides/rails_guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides/rails_guides')
-rw-r--r--guides/rails_guides/generator.rb167
-rw-r--r--guides/rails_guides/markdown.rb15
-rw-r--r--guides/rails_guides/markdown/renderer.rb45
3 files changed, 112 insertions, 115 deletions
diff --git a/guides/rails_guides/generator.rb b/guides/rails_guides/generator.rb
index a818ca9d72..28164a3cb4 100644
--- a/guides/rails_guides/generator.rb
+++ b/guides/rails_guides/generator.rb
@@ -1,54 +1,3 @@
-# ---------------------------------------------------------------------------
-#
-# This script generates the guides. It can be invoked via the
-# guides:generate rake task within the guides 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 Markdown 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 rake guides:generate
-#
-# Separate many using commas:
-#
-# # generates only association_basics.html and command_line.html
-# ONLY=assoc,command rake guides:generate
-#
-# Note that if you are working on a guide generation will by default process
-# only that one, so ONLY is rarely used nowadays.
-#
-# GUIDES_LANGUAGE
-# Use GUIDES_LANGUAGE when you want to generate translated guides in
-# <tt>source/<GUIDES_LANGUAGE></tt> folder (such as <tt>source/es</tt>).
-# Ignore it when generating English guides.
-#
-# 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"
@@ -64,46 +13,37 @@ require "rails_guides/levenshtein"
module RailsGuides
class Generator
- attr_reader :guides_dir, :source_dir, :output_dir, :edge, :warnings, :all
-
GUIDES_RE = /\.(?:erb|md)\z/
- def initialize(output = nil)
- set_flags_from_environment
+ def initialize(edge:, version:, all:, only:, kindle:, language:)
+ @edge = edge
+ @version = version
+ @all = all
+ @only = only
+ @kindle = kindle
+ @language = language
- if kindle?
+ if @kindle
check_for_kindlegen
register_kindle_mime_types
end
- initialize_dirs(output)
+ initialize_dirs
create_output_dir_if_needed
- end
-
- def set_flags_from_environment
- @edge = ENV["EDGE"] == "1"
- @warnings = ENV["WARNINGS"] == "1"
- @all = ENV["ALL"] == "1"
- @kindle = ENV["KINDLE"] == "1"
- @version = ENV["RAILS_VERSION"] || "local"
- @lang = ENV["GUIDES_LANGUAGE"]
- end
-
- def register_kindle_mime_types
- Mime::Type.register_alias("application/xml", :opf, %w(opf))
- Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
+ initialize_markdown_renderer
end
def generate
generate_guides
copy_assets
- generate_mobi if kindle?
+ generate_mobi if @kindle
end
private
- def kindle?
- @kindle
+ def register_kindle_mime_types
+ Mime::Type.register_alias("application/xml", :opf, %w(opf))
+ Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
end
def check_for_kindlegen
@@ -114,29 +54,35 @@ module RailsGuides
def generate_mobi
require "rails_guides/kindle"
- out = "#{output_dir}/kindlegen.out"
- Kindle.generate(output_dir, mobi, out)
+ out = "#{@output_dir}/kindlegen.out"
+ Kindle.generate(@output_dir, mobi, out)
puts "(kindlegen log at #{out})."
end
def mobi
- "ruby_on_rails_guides_#@version%s.mobi" % (@lang.present? ? ".#@lang" : "")
+ mobi = "ruby_on_rails_guides_#{@version || @edge[0, 7]}"
+ mobi += ".#{@language}" if @language
+ mobi += ".mobi"
end
- def initialize_dirs(output)
- @guides_dir = File.join(File.dirname(__FILE__), "..")
- @source_dir = "#@guides_dir/source/#@lang"
- @output_dir = if output
- output
- elsif kindle?
- "#@guides_dir/output/kindle/#@lang"
- else
- "#@guides_dir/output/#@lang"
- end.sub(%r</$>, "")
+ def initialize_dirs
+ @guides_dir = File.expand_path("..", __dir__)
+
+ @source_dir = "#{@guides_dir}/source"
+ @source_dir += "/#{@language}" if @language
+
+ @output_dir = "#{@guides_dir}/output"
+ @output_dir += "/kindle" if @kindle
+ @source_dir += "/#{@language}" if @language
end
def create_output_dir_if_needed
- FileUtils.mkdir_p(output_dir)
+ FileUtils.mkdir_p(@output_dir)
+ end
+
+ def initialize_markdown_renderer
+ Markdown::Renderer.edge = @edge
+ Markdown::Renderer.version = @version
end
def generate_guides
@@ -147,27 +93,27 @@ module RailsGuides
end
def guides_to_generate
- guides = Dir.entries(source_dir).grep(GUIDES_RE)
+ guides = Dir.entries(@source_dir).grep(GUIDES_RE)
- if kindle?
- Dir.entries("#{source_dir}/kindle").grep(GUIDES_RE).map do |entry|
+ if @kindle
+ Dir.entries("#{@source_dir}/kindle").grep(GUIDES_RE).map do |entry|
next if entry == "KINDLE.md"
guides << "kindle/#{entry}"
end
end
- ENV.key?("ONLY") ? select_only(guides) : guides
+ @only ? select_only(guides) : guides
end
def select_only(guides)
- prefixes = ENV["ONLY"].split(",").map(&:strip)
+ prefixes = @only.split(",").map(&:strip)
guides.select do |guide|
- guide.start_with?("kindle".freeze, *prefixes)
+ guide.start_with?("kindle", *prefixes)
end
end
def copy_assets
- FileUtils.cp_r(Dir.glob("#{guides_dir}/assets/*"), output_dir)
+ FileUtils.cp_r(Dir.glob("#{@guides_dir}/assets/*"), @output_dir)
end
def output_file_for(guide)
@@ -179,22 +125,28 @@ module RailsGuides
end
def output_path_for(output_file)
- File.join(output_dir, File.basename(output_file))
+ File.join(@output_dir, File.basename(output_file))
end
def generate?(source_file, output_file)
- fin = File.join(source_dir, source_file)
+ fin = File.join(@source_dir, source_file)
fout = output_path_for(output_file)
- all || !File.exist?(fout) || File.mtime(fout) < File.mtime(fin)
+ @all || !File.exist?(fout) || File.mtime(fout) < File.mtime(fin)
end
def generate_guide(guide, output_file)
output_path = output_path_for(output_file)
puts "Generating #{guide} as #{output_file}"
- layout = kindle? ? "kindle/layout" : "layout"
+ layout = @kindle ? "kindle/layout" : "layout"
File.open(output_path, "w") do |f|
- view = ActionView::Base.new(source_dir, edge: @edge, version: @version, mobi: "kindle/#{mobi}", lang: @lang)
+ view = ActionView::Base.new(
+ @source_dir,
+ edge: @edge,
+ version: @version,
+ mobi: "kindle/#{mobi}",
+ language: @language
+ )
view.extend(Helpers)
if guide =~ /\.(\w+)\.erb$/
@@ -202,10 +154,15 @@ module RailsGuides
# Passing a template handler in the template name is deprecated. So pass the file name without the extension.
result = view.render(layout: layout, formats: [$1], file: $`)
else
- body = File.read(File.join(source_dir, guide))
- result = RailsGuides::Markdown.new(view, layout).render(body)
-
- warn_about_broken_links(result) if @warnings
+ body = File.read("#{@source_dir}/#{guide}")
+ result = RailsGuides::Markdown.new(
+ view: view,
+ layout: layout,
+ edge: @edge,
+ version: @version
+ ).render(body)
+
+ warn_about_broken_links(result)
end
f.write(result)
@@ -231,7 +188,7 @@ module RailsGuides
# Footnotes.
anchors += Set.new(html.scan(/<p\s+class="footnote"\s+id="([^"]+)/).flatten)
anchors += Set.new(html.scan(/<sup\s+class="footnote"\s+id="([^"]+)/).flatten)
- return anchors
+ anchors
end
def check_fragment_identifiers(html, anchors)
diff --git a/guides/rails_guides/markdown.rb b/guides/rails_guides/markdown.rb
index 009e5aff99..bf2cc82c7c 100644
--- a/guides/rails_guides/markdown.rb
+++ b/guides/rails_guides/markdown.rb
@@ -4,12 +4,14 @@ require "rails_guides/markdown/renderer"
module RailsGuides
class Markdown
- def initialize(view, layout)
- @view = view
- @layout = layout
+ def initialize(view:, layout:, edge:, version:)
+ @view = view
+ @layout = layout
+ @edge = edge
+ @version = version
@index_counter = Hash.new(0)
- @raw_header = ""
- @node_ids = {}
+ @raw_header = ""
+ @node_ids = {}
end
def render(body)
@@ -60,7 +62,8 @@ module RailsGuides
autolink: true,
strikethrough: true,
superscript: true,
- tables: true)
+ tables: true
+ )
end
def extract_raw_header_and_body
diff --git a/guides/rails_guides/markdown/renderer.rb b/guides/rails_guides/markdown/renderer.rb
index deab741023..20cbd568c9 100644
--- a/guides/rails_guides/markdown/renderer.rb
+++ b/guides/rails_guides/markdown/renderer.rb
@@ -1,9 +1,7 @@
module RailsGuides
class Markdown
class Renderer < Redcarpet::Render::HTML
- def initialize(options = {})
- super
- end
+ cattr_accessor :edge, :version
def block_code(code, language)
<<-HTML
@@ -15,6 +13,16 @@ module RailsGuides
HTML
end
+ def link(url, title, content)
+ if url.start_with?("http://api.rubyonrails.org")
+ %(<a href="#{api_link(url)}">#{content}</a>)
+ elsif title
+ %(<a href="#{url}" title="#{title}">#{content}</a>)
+ else
+ %(<a href="#{url}">#{content}</a>)
+ end
+ end
+
def header(text, header_level)
# Always increase the heading level by 1, so we can use h1, h2 heading in the document
header_level += 1
@@ -23,7 +31,9 @@ HTML
end
def paragraph(text)
- if text =~ /^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:]/
+ if text =~ %r{^NOTE:\s+Defined\s+in\s+<code>(.*?)</code>\.?$}
+ %(<div class="note"><p>Defined in <code><a href="#{github_file_url($1)}">#{$1}</a></code>.</p></div>)
+ elsif text =~ /^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:]/
convert_notes(text)
elsif text.include?("DO NOT READ THIS FILE ON GITHUB")
elsif text =~ /^\[<sup>(\d+)\]:<\/sup> (.+)$/
@@ -79,6 +89,33 @@ HTML
%(<div class="#{css_class}"><p>#{$2.strip}</p></div>)
end
end
+
+ def github_file_url(file_path)
+ tree = version || edge
+
+ root = file_path[%r{(.+)/}, 1]
+ path = case root
+ when "abstract_controller", "action_controller", "action_dispatch"
+ "actionpack/lib/#{file_path}"
+ when /\A(action|active)_/
+ "#{root.sub("_", "")}/lib/#{file_path}"
+ else
+ file_path
+ end
+
+
+ "https://github.com/rails/rails/tree/#{tree}/#{path}"
+ end
+
+ def api_link(url)
+ if url =~ %r{http://api\.rubyonrails\.org/v\d+\.}
+ url
+ elsif edge
+ url.sub("api", "edgeapi")
+ else
+ url.sub(/(?<=\.org)/, "/#{version}")
+ end
+ end
end
end
end