rscons/rb/gen_user_guide.rb

115 lines
3.4 KiB
Ruby

#!/usr/bin/env ruby
require "erb"
require "fileutils"
require "redcarpet"
require "syntax"
require "syntax/convertors/html"
require "rscons/version"
def load_file(file_name)
contents = File.read(file_name)
contents.gsub(/\$\{include (.*?)\}/) do |match|
include_file_name = $1
File.read(include_file_name)
end
end
class Generator
class Section
attr_reader :number
attr_reader :title
attr_reader :new_page
attr_reader :contents
attr_reader :anchor
def initialize(number, title, new_page)
@number = number
@title = title.gsub(/[`]/, "")
@new_page = new_page
@contents = ""
@anchor = "s" + ("#{number} #{title}").gsub(/[^a-zA-Z0-9]/, "_")
end
def append(contents)
@contents += contents
end
end
def initialize(input, output_file, multi_file)
@sections = []
@current_section_number = [0]
@lines = input.lines
while @lines.size > 0
line = @lines.slice!(0)
if line =~ /^```(.*)$/
@sections.last.append(gather_code_section($1))
elsif line =~ /^(#+)(>)?\s*(.*)$/
level_text, new_page_text, title_text = $1, $2, $3
level = $1.size
new_page = !new_page_text.nil?
section_number = get_next_section_number(level)
@sections << Section.new(section_number, title_text, new_page)
@sections.last.append("#{level_text} #{section_number} #{title_text}")
elsif @sections.size > 0
@sections.last.append(line)
end
end
renderer = Redcarpet::Render::HTML.new
@markdown_renderer = Redcarpet::Markdown.new(renderer)
content = %[<h1>Table of Contents</h1>\n]
@sections.each do |section|
indent = section.number.split(".").size - 1
content += %[<span style="padding-left: #{4 * indent}ex;">]
content += %[<a href="##{section.anchor}">#{section.number} #{section.title}</a><br/>\n]
content += %[</span>]
end
@sections.each do |section|
content += %[<a name="#{section.anchor}" />]
content += @markdown_renderer.render(section.contents)
end
changelog = @markdown_renderer.render(File.read("CHANGELOG.md"))
content.gsub!("${changelog}", changelog)
template = File.read("rb/assets/user_guide.html.erb")
erb = ERB.new(template, nil, "<>")
html_result = erb.result(binding.clone)
File.open(output_file, "w") do |fh|
fh.write(html_result)
end
end
def gather_code_section(syntax)
code = ""
loop do
line = @lines.slice!(0)
if line =~ /^```/
break
end
code += line
end
if syntax != ""
convertor = Syntax::Convertors::HTML.for_syntax(syntax)
%[<div class="code #{syntax}_code">\n#{convertor.convert(code)}\n</div>\n]
else
%[<div class="code">\n<pre>#{code}</pre>\n</div>\n]
end
end
def get_next_section_number(level)
if @current_section_number.size == level - 1
@current_section_number << 1
elsif @current_section_number.size >= level
@current_section_number[level - 1] += 1
@current_section_number.slice!(level, @current_section_number.size)
else
raise "Section level change from #{@current_section_number.size} to #{level}"
end
@current_section_number.join(".")
end
end
input = load_file("doc/user_guide.md")
FileUtils.rm_rf("gen/user_guide")
FileUtils.mkdir_p("gen/user_guide")
Generator.new(input, "gen/user_guide/user_guide.html", false)