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 (readonly)

The source code index which is used for generating pages.



69
70
71
# File 'lib/utopia/project/base.rb', line 69

def index
  @index
end

#rootObject (readonly)

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



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

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(symbols) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/utopia/project/base.rb', line 86

def best(symbols)
	symbols.each do |symbol|
		if symbol.documentation
			return symbol
		end
	end
	
	return symbols.first
end

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



117
118
119
120
121
122
123
# File 'lib/utopia/project/base.rb', line 117

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

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



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/utopia/project/base.rb', line 102

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

#guidesObject



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

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(symbol, suffix = nil) ⇒ Object

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



148
149
150
151
152
153
154
# File 'lib/utopia/project/base.rb', line 148

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

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



157
158
159
160
161
162
163
164
165
166
# File 'lib/utopia/project/base.rb', line 157

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

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



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/utopia/project/base.rb', line 125

def linkify(text, symbol = nil, language: symbol&.language)
	reference = @index.languages.parse_reference(text, default_language: language)
	
	Trenni::Builder.fragment do |builder|
		if reference and definition = @index.lookup(reference, relative_to: symbol)&.first
			builder.inline('a', href: link_for(definition)) do
				builder.inline('code', class: "language-#{definition.language.name}") do
					builder.text definition.short_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



96
97
98
99
100
# File 'lib/utopia/project/base.rb', line 96

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.



73
74
75
76
77
78
# File 'lib/utopia/project/base.rb', line 73

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.



82
83
84
# File 'lib/utopia/project/base.rb', line 82

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