Class: Utopia::Project::Base

Inherits:
Object
  • Object
show all
Extended by:
Thread::Local
Defined in:
lib/utopia/project/base.rb

Overview

Provides structured access to a project directory which contains source code and guides.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root = Dir.pwd) ⇒ Base

Initialize the project with the given root path.



55
56
57
58
59
60
61
62
63
# File 'lib/utopia/project/base.rb', line 55

def initialize(root = Dir.pwd)
  @root = root
  
  @source_path = Utopia::Path["/source"]
  
  @index = Decode::Index.new
  
  @links = Utopia::Content::Links.new(@root)
end

Instance Attribute Details

#indexObject

The source code index which is used for generating pages.



71
72
73
# File 'lib/utopia/project/base.rb', line 71

def index
  @index
end

#rootObject (readonly)

The file-system path to the root of the project.



67
68
69
# File 'lib/utopia/project/base.rb', line 67

def root
  @root
end

Class Method Details

.localObject



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/utopia/project/base.rb', line 41

def self.local
  instance = self.new
  
  source_files = Dir.glob(
    File.expand_path("lib/**/*.rb", instance.root)
  )
  
  instance.update(source_files)
  
  return instance
end

Instance Method Details

#best(definitions) ⇒ Object

Given an array of defintions, return the best definition for the purposes of generating documentation.



91
92
93
94
95
96
97
98
99
# File 'lib/utopia/project/base.rb', line 91

def best(definitions)
  definitions.each do |definition|
    if definition.documentation
      return definition
    end
  end
  
  return definitions.first
end

#document(text, definition = nil, language: definition&.language) ⇒ Object

Convert the given markdown text into HTML.

  • Updates source code references (‘identifier`) into links.

  • Uses Kramdown to convert the text into HTML.



133
134
135
136
137
138
139
# File 'lib/utopia/project/base.rb', line 133

def document(text, definition = nil, language: definition&.language)
  text = text&.gsub(/(?<!`){(.*?)}/) do |match|
    linkify($1, definition, language: language)
  end
  
  return Kramdown::Document.new(text, syntax_highlighter: nil)
end

#format(text, definition = nil, language: definition&.language) ⇒ Object

Format the given text in the context of the given definition and language. See #document for details.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/utopia/project/base.rb', line 112

def format(text, definition = nil, language: definition&.language)
  case text
  when Enumerable
    text = text.to_a.join("\n")
  when nil
    return nil
  end
  
  if document = self.document(text, definition, language: language)
    return Trenni::MarkupString.raw(
      document.to_html
    )
  end
end

#guidesObject

Enumerate over all available guides in order.



193
194
195
196
197
198
199
200
201
202
203
# File 'lib/utopia/project/base.rb', line 193

def guides
  return to_enum(:guides) unless block_given?
  
  @links.index("/guides").each do |link|
    guide_path = File.join(@root, link.path)
    
    next unless File.directory?(guide_path)
    
    yield Guide.new(self, guide_path)
  end
end

#id_for(definition, suffix = nil) ⇒ Object

Compute a unique string which can be used as ‘id` attribute in the HTML output.



168
169
170
171
172
173
174
# File 'lib/utopia/project/base.rb', line 168

def id_for(definition, suffix = nil)
  if suffix
    "#{definition.qualified_name}-#{suffix}"
  else
    definition.qualified_name
  end
end

Compute a link href to the given definition for use within the HTML output.



178
179
180
181
182
183
184
185
186
187
# File 'lib/utopia/project/base.rb', line 178

def link_for(definition)
  path = definition.lexical_path.map{|entry| entry.to_s}
  
  if definition.container?
    return Trenni::Reference.new(@source_path + path + "index")
  else
    name = path.pop
    return Trenni::Reference.new(@source_path + path + "index", fragment: id_for(definition))
  end
end

#linkify(text, definition = nil, language: definition&.language) ⇒ Object

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



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/utopia/project/base.rb', line 144

def linkify(text, definition = nil, language: definition&.language)
  reference = @index.languages.parse_reference(text, default_language: language)
  
  Trenni::Builder.fragment do |builder|
    if reference and definition = @index.lookup(reference, relative_to: definition)&.first
      builder.inline('a', href: link_for(definition)) do
        builder.inline('code', class: "language-#{definition.language.name}") do
          builder.text definition.qualified_form
        end
      end
    elsif reference
      builder.inline('code', class: "language-#{reference.language.name}") do
        builder.text text
      end
    else
      builder.inline('code') do
        builder.text text
      end
    end
  end
end

#lookup(path) ⇒ Object

Given a lexical path, find the best definition for that path.



103
104
105
106
107
# File 'lib/utopia/project/base.rb', line 103

def lookup(path)
  if node = @index.trie.lookup(path.map(&:to_sym))
    return node, best(node.values)
  end
end

#path_for(file_name) ⇒ Object

Return the absolute path for the given file name, if it exists in the project.



76
77
78
79
80
81
# File 'lib/utopia/project/base.rb', line 76

def path_for(file_name)
  full_path = File.expand_path(file_name, @root)
  if File.exist?(full_path)
    return full_path
  end
end

#update(paths) ⇒ Object

Update the index with the specified paths.



85
86
87
# File 'lib/utopia/project/base.rb', line 85

def update(paths)
  @index.update(paths)
end