lib/spirit/render/html.rb in spirit-0.2 vs lib/spirit/render/html.rb in spirit-0.5

- old
+ new

@@ -1,137 +1,37 @@ -# ~*~ encoding: utf-8 ~*~ +require 'active_support/core_ext/module/delegation' + require 'spirit/render/errors' -require 'spirit/render/sanitize' require 'spirit/render/templates' +require 'spirit/render/processable' +require 'spirit/render/processors' module Spirit - module Render # HTML Renderer for Genie Markup Language, which is just GitHub Flavored # Markdown with Embedded YAML for describing problems. Designed for use # with Redcarpet. # @see Spirit::Tilt::Template # @see http://github.github.com/github-flavored-markdown/ class HTML < ::Redcarpet::Render::HTML + include Processable - @sanitize = Sanitize.new - class << self; attr_reader :sanitize end + delegate :solutions, to: :problems + attr_accessor :navigation, :problems, :nesting - # Paragraphs that start and end with '---' are treated as embedded YAML - # and are parsed for questions/answers. - PROBLEM_REGEX = /^"""$(.*?)^"""$/m + use Processors::SanitizeProcessor + use Processors::MathProcessor + use Processors::LayoutProcessor + use Processors::ProblemsProcessor + use Processors::PygmentsProcessor + use Processors::BlockImageProcessor + use Processors::HeadersProcessor - # Paragraphs that only contain images are rendered with {Spirit::Render::Image}. - IMAGE_REGEX = /\A\s*<img[^<>]+>\s*\z/m - - # Renderer configuration options. - CONFIGURATION = { - hard_wrap: true, - no_styles: true, - } - # Creates a new HTML renderer. - # @param [Hash] options described in the RedCarpet documentation. - def initialize(options={}) - super CONFIGURATION.merge options - @nav, @headers = Navigation.new, Headers.new - @prob, @img = 0, 0 # indices for Problem #, Figure # - @name = options.delete(:name) || 'untitled' - end - - # Pygmentizes code blocks. - # @param [String] code code block contents - # @param [String] marker name of language, for syntax highlighting - # @return [String] highlighted code - def block_code(code, marker) - #language, type, id = (marker || 'text').split ':' - #highlighted = Albino.colorize code, language - language, _, _ = (marker || 'text').split ':' - Albino.colorize code, language - # TODO - #case type - #when 'demo', 'test' - # executable id: id, raw: code, colored: highlighted - #else highlighted end - end - - # Detects block images and renders them as such. - # @return [String] rendered html - def paragraph(text) - case text - when IMAGE_REGEX then block_image(text) - else p(text) end - rescue RenderError => e # fall back to paragraph - Spirit.logger.warn e.message - p(text) - end - - # Increases all header levels by one and keeps a navigation bar. - # @return [String] rendered html - def header(text, level) - html, name = h(text, level += 1) - @nav.append(text, name) if level == 2 - html - end - - # Runs a first pass through the document to look for problem blocks. - # @param [String] document markdown document - def preprocess(document) - document.gsub(PROBLEM_REGEX) { |yaml| problem $1 } - end - - # Sanitizes the final document. - # @param [String] document html document - # @return [String] sanitized document - def postprocess(document) - HTML.sanitize.clean(@nav.render + document.force_encoding('utf-8')) - end - - private - - # Prepares an executable code block. - # @option opts [String] id author-supplied ID - # @option opts [String] raw code to execute - # @option opts [String] colored syntax highlighted code - # @return [String] - #def executable(opts) - # opts[:colored] + @exe.render(Object.new, id: opts[:id], raw: opts[:raw]) - #end - - # Prepares a problem form. Returns +yaml+ if the given text does not - # contain valid yaml markup for a problem. - # @param [String] yaml YAML markup - # @return [String] rendered HTML - def problem(yaml) - problem = Problem.parse(yaml) - Spirit.logger.record :problem, "ID: #{problem.id}" - problem.save!(@name) and problem.render(index: @prob += 1) - rescue RenderError - yaml - end - - # Prepares a block image. Raises {RenderError} if the given text does not - # contain a valid image block. - # @param [String] text markdown text - # @return [String] rendered HTML - def block_image(text) - Image.parse(text).render(index: @img += 1) - end - - # Wraps the given text with header tags. - # @return [String] rendered HTML - # @return [String] anchor name - def h(text, level) - header = @headers.add(text, level) - return header.render, header.name - end - - # Wraps the given text with paragraph tags. - # @param [String] text paragraph text - # @return [String] rendered html - def p(text) - '<p>' + text + '</p>' + # @param [Hash] opts described in the RedCarpet documentation + def initialize(opts={}) + super RENDERER_CONFIG.merge opts end end end