# -*- coding: utf-8 -*- require 'nora_mark/html/util' require 'nora_mark/html/pages' require 'nora_mark/html/context' require 'nora_mark/html/tag_writer' require 'nora_mark/html/frontmatter_writer' require 'nora_mark/html/paragraph_writer' require 'nora_mark/html/writer_selector' require 'nora_mark/html/abstract_node_writer' module NoraMark module Html class Generator include Util attr_reader :context def initialize(param = {}) @context = Context.new(param) article_writer = TagWriter.create('article', self) section_writer = TagWriter.create('section', self) link_writer = TagWriter.create('a', self, trailer: '', node_preprocessor: proc do |node| (node.attrs ||= {}).merge!({href: [node.parameters[0]]}) node end) frontmatter_writer = FrontmatterWriter.new self paragraph_writer = ParagraphWriter.new self abstract_node_writer = AbstractNodeWriter.new self @writers = { Paragraph => paragraph_writer, ParagraphGroup => paragraph_writer, Breakline => TagWriter.create('br', self, node_preprocessor: proc do |node| node.body_empty = true node end), LineCommand => WriterSelector.new(self, { 'image' => TagWriter.create('div', self, node_preprocessor: proc do |node| add_class_if_empty node, 'img-wrap' node end, write_body_preprocessor: proc do |node| src = node.parameters[0].strip alt = (node.parameters[1] || '').strip caption_before = node.named_parameters[:caption_before] if caption_before && children_not_empty(node) output "

"; write_children node; output "

" end output "#{escape_html alt}" if !caption_before && children_not_empty(node) output "

"; write_children node; output "

" end :done end ), }), Block => WriterSelector.new(self, { 'd' => TagWriter.create('div', self), 'art' => article_writer, 'arti' => article_writer, 'article' => article_writer, 'sec' => section_writer, 'sect' => section_writer, 'section' => section_writer, }), Newpage => TagWriter.create('div', self, node_preprocessor: proc do |node| node.no_tag = true node end, write_body_preprocessor: proc do |node| title = nil if node.parameters.size > 0 && node.parameters[0].size > 0 title = escape_html node.parameters.first end @context.title = title unless title.nil? @context.end_html :done end ), Inline => WriterSelector.new(self, { 'link' => link_writer, 'l' => link_writer, 's' => TagWriter.create('span', self), 'img' => TagWriter.create('img', self, node_preprocessor: proc do |node| node.body_empty = true #TODO : it is not just an item's attribute, 'img_inline' has no body. maybe should specify in parser.{rb|kpeg} (node.attrs ||= {}).merge!({src: [node.parameters[0] ]}) node.attrs.merge!({alt: [ escape_html(node.parameters[1].strip)]}) if (node.parameters.size > 1 && node.parameters[1].size > 0) node end) , 'tcy' => TagWriter.create('span', self, node_preprocessor: proc do |node| add_class node, 'tcy' node end), 'ruby' => TagWriter.create('ruby', self, write_body_preprocessor: proc do |node| write_children node output "(#{escape_html node.parameters[0].strip})" :done end), }, trailer_default:'' ), OrderedList => TagWriter.create('ol', self), UnorderedList => TagWriter.create('ul', self), UlItem => TagWriter.create('li', self), OlItem => TagWriter.create('li', self), DefinitionList => TagWriter.create('dl', self), DLItem => TagWriter.create('', self, chop_last_space: true, node_preprocessor: proc do |node| node.no_tag = true; node end, write_body_preprocessor: proc do |node| output "
"; write_array node.parameters[0]; output "
\n" output "
"; write_children node; output "
\n" :done end), Document => abstract_node_writer, Page => abstract_node_writer, #headed-section HeadedSection => TagWriter.create('section', self, write_body_preprocessor: proc do |node| output "" write_array node.heading @generator.context.chop_last_space output "\n" :continue end), # frontmatter Frontmatter => frontmatter_writer, # pre-formatted PreformattedBlock => TagWriter.create('pre', self, node_preprocessor: proc do |node| if node.codelanguage (node.attrs ||= {}).merge!({'data-code-language' => [node.codelanguage]}) add_class node, "code-#{node.codelanguage}" end node end, write_body_preprocessor: proc do |node| output "" if node.name == 'code' output escape_html(node.content.join "\n") output "" if node.name == 'code' :done end), } end def convert(parsed_result) children = parsed_result.content @context.file_basename = parsed_result.document_name children.each { |node| to_html(node) } @context.result end def to_html(node) if node.is_a? String @context << escape_html(node) elsif node.is_a? Hash writer = @writers[node[:type]] if writer.nil? warn "can't find html generator for \"#{node}\"" @context << escape_html(node[:raw_text]) else writer.write(node) end elsif node.kind_of? Text @context << escape_html(node.content) else writer = @writers[node.class] if writer.nil? warn "can't find html generator for \"#{node.class}\"" else writer.write(node) end end end end end end