require "html_to_prosemirror/version" require "html_to_prosemirror/marks/mark" require "html_to_prosemirror/marks/bold" require "html_to_prosemirror/marks/code" require "html_to_prosemirror/marks/italic" require "html_to_prosemirror/marks/link" require "html_to_prosemirror/nodes/node" require "html_to_prosemirror/nodes/bullet_list" require "html_to_prosemirror/nodes/code_block_wrapper" require "html_to_prosemirror/nodes/code_block" require "html_to_prosemirror/nodes/hard_break" require "html_to_prosemirror/nodes/heading" require "html_to_prosemirror/nodes/image" require "html_to_prosemirror/nodes/list_item" require "html_to_prosemirror/nodes/ordered_list" require "html_to_prosemirror/nodes/paragraph" require "html_to_prosemirror/nodes/text" require "html_to_prosemirror/nodes/user" require 'nokogiri' module HtmlToProsemirror class Error < StandardError; end # Your code goes here... class Renderer def initialize() @storedMarks = [] @marks = [ HtmlToProsemirror::Marks::Bold, HtmlToProsemirror::Marks::Code, HtmlToProsemirror::Marks::Italic, HtmlToProsemirror::Marks::Link ] @nodes = [ HtmlToProsemirror::Nodes::BulletList, HtmlToProsemirror::Nodes::CodeBlockWrapper, HtmlToProsemirror::Nodes::CodeBlock, HtmlToProsemirror::Nodes::HardBreak, HtmlToProsemirror::Nodes::Heading, HtmlToProsemirror::Nodes::Image, HtmlToProsemirror::Nodes::ListItem, HtmlToProsemirror::Nodes::OrderedList, HtmlToProsemirror::Nodes::Paragraph, HtmlToProsemirror::Nodes::Text, HtmlToProsemirror::Nodes::User ] end def render(value) minified = minify_html(value.strip! || value) @document = Nokogiri::HTML.fragment(minified) content = render_children(@document) return { type: 'doc', content: content, } end private # def get_document_body # return @document.search('body')[0]; # end def render_children(node) nodes = [] node.children.each do |child| child_node = get_matching_node(child) if( child_node) item = child_node.data() if (item === nil) if (child.children.length > 0) nodes = nodes + render_children(child) end next end if (child.children.length > 0) item = item.merge({ content: render_children(child), }) end if (@storedMarks.count > 0) item = item.merge({ marks: @storedMarks, }) @storedMarks = []; end # if (child_node.wrapper) # item['content'] = [ # instance.wrapper.merge({ # content: item['content'], # }), # ] # end nodes.push(item) end child_mark = get_matching_mark(child) if (child_mark) @storedMarks.push(child_mark.data()) if (child.children.length > 0) nodes = nodes + render_children(child) end end end return nodes; end # Find which Node matches the Html Node def get_matching_node(item) return get_matching_class(item, @nodes) end # Find which Mark matches the HtmlElement def get_matching_mark(item) return get_matching_class(item, @marks) end # Find which class matches the HtmlElement def get_matching_class(node, classes) found = classes.select do |clazz| instance = clazz.new(node) if (instance.matching()) return instance end end found.first end def minify_html(html) # 1. Remove all comments: gsub(/(|\/\*[^\*]*\*\/|^(\t|\s)*\/\/.*)/, '') # 1.1 html comments without special characters: # 1.2. Remove javascript comments e.g. /* */ and // \/\*[^\*]*\*\/ and ^(\t|\s)*\/\/.* # 3. Replace all carrier return and all tabs by a single space gsub(/(\n|\t)/, ' '). # 4. Replace any consecutive spaces by a single space gsub(/\s{2,}/, ' ') # 5. Remove space between tags gsub(/>\s+<').strip. html.gsub(/(|\/\*[^\*]*\*\/|^(\t|\s)*\/\/.*)/, ''). gsub(/(\n|\t)/, ' '). gsub(/\s{2,}/, ' '). gsub(/>\s+<').strip end end end