class Utopia::Project::Document

Public Class Methods

new(text, base = nil, definition: nil, default_language: nil) click to toggle source
# File lib/utopia/project/document.rb, line 28
def initialize(text, base = nil, definition: nil, default_language: nil)
        @text = text
        @base = base
        @index = base&.index
        
        @definition = definition
        @default_language = default_language
        
        @root = nil
end

Public Instance Methods

code_node(content, language = nil) click to toggle source
# File lib/utopia/project/document.rb, line 110
def code_node(content, language = nil)
        if language
                node = inline_html_node(
                        "<code class=\"language-#{language}\">#{Trenni::Strings.to_html(content)}</code>"
                )
        else
                node = Markly::Node.new(:code)
                node.string_content = content
                return node
        end
        
        return node
end
first_child() click to toggle source
# File lib/utopia/project/document.rb, line 43
def first_child
        self.root.first_child
end
html_node(content, type = :html) click to toggle source
# File lib/utopia/project/document.rb, line 82
def html_node(content, type = :html)
        node = Markly::Node.new(:html)
        node.string_content = content
        return node
end
inline_html_node(content) click to toggle source
# File lib/utopia/project/document.rb, line 88
def inline_html_node(content)
        node = Markly::Node.new(:inline_html)
        node.string_content = content
        return node
end
paragraph_node(child) click to toggle source
# File lib/utopia/project/document.rb, line 76
def paragraph_node(child)
        node = Markly::Node.new(:paragraph)
        node.append_child(child)
        return node
end
replace_section(name) { |header| ... } click to toggle source
# File lib/utopia/project/document.rb, line 47
def replace_section(name)
        child = self.first_child
        
        while child
                if child.type == :header
                        header = child
                        
                        # We found the matched header:
                        if header.first_child.to_plaintext.include?(name)
                                # Now subsequent children:
                                current = header.next
                                while current.type != :header and following = current.next
                                        current.delete
                                        current = following
                                end
                                
                                return yield(header)
                        end
                end
                
                child = child.next
        end
end
root() click to toggle source
# File lib/utopia/project/document.rb, line 39
def root
        @root ||= resolve(Markly.parse(@text, extensions: [:table]))
end
text_node(content) click to toggle source
# File lib/utopia/project/document.rb, line 94
def text_node(content)
        node = Markly::Node.new(:text)
        node.string_content = content
        return node
end
to_html(node = self.root, **options) click to toggle source
# File lib/utopia/project/document.rb, line 71
def to_html(node = self.root, **options)
        renderer = Markly::HTMLRenderer.new(ids: true, flags: Markly::UNSAFE, **options)
        Trenni::MarkupString.raw(renderer.render(node))
end

Private Instance Methods

reference_node(content) click to toggle source

Replace source code references in the given text with HTML anchors.

# File lib/utopia/project/document.rb, line 128
def reference_node(content)
        if reference = @index.languages.parse_reference(content, default_language: @default_language)
                definition = @index.lookup(reference, relative_to: @definition)
        end
        
        if definition
                link_node(reference.identifier, @base.link_for(definition),
                        code_node(definition.qualified_form, reference.language.name)
                )
        elsif reference
                code_node(reference.identifier, reference.language.name)
        else
                code_node(content)
        end
end
resolve(root) click to toggle source
# File lib/utopia/project/document.rb, line 144
def resolve(root)
        return root if @index.nil?
        
        root.walk do |node|
                if node.type == :text
                        content = node.string_content
                        offset = 0
                        
                        while match = content.match(/{(?<reference>.*?)}/, offset)
                                a, b = match.offset(0)
                                
                                if a > offset
                                        node.insert_before(
                                                text_node(content[offset...a])
                                        )
                                end
                                
                                node.insert_before(
                                        reference_node(match[:reference])
                                )
                                
                                offset = b
                        end
                        
                        if offset == content.bytesize
                                node.delete
                        else
                                node.string_content = content[offset..-1]
                        end
                end
        end
        
        return root
end