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.

Parameters:

  • root (String) (defaults to: Dir.pwd)

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



53
54
55
56
57
58
59
# File 'lib/utopia/project/base.rb', line 53

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

Instance Attribute Details

#indexObject (readonly)

The source code index which is used for generating pages.



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

def index
  @index
end

#rootObject (readonly)

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



62
63
64
# File 'lib/utopia/project/base.rb', line 62

def root
  @root
end

Class Method Details

.localObject



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

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



82
83
84
85
86
87
88
89
90
# File 'lib/utopia/project/base.rb', line 82

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

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



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/utopia/project/base.rb', line 98

def format(text, symbol = nil, language: symbol&.language)
  if text.is_a?(Enumerable)
    text = text.to_a.join("\n")
  end
  
  if language
    text = text&.gsub(/{(.*?)}/) do |match|
      linkify($1, symbol, language: language)
    end
  end
  
  return Trenni::MarkupString.raw(
    Kramdown::Document.new(text, syntax_highlighter: nil).to_html
  )
end

#guidesObject



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

def guides
  guides_root = File.expand_path("guides", @root)
  
  # There are no guides if there is no directory:
  return unless File.directory?(guides_root)
  
  return to_enum(:guides) unless block_given?
  
  Dir.each_child(guides_root) do |entry|
    guide_path = File.join(guides_root, entry)
    
    next unless File.directory?(guide_path)
    
    yield Guide.new(self, guide_path)
  end
end

#id_for(symbol) ⇒ Object

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



133
134
135
# File 'lib/utopia/project/base.rb', line 133

def id_for(symbol)
  symbol.qualified_name
end

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



138
139
140
141
142
143
144
145
146
147
# File 'lib/utopia/project/base.rb', line 138

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



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/utopia/project/base.rb', line 114

def linkify(text, symbol = nil, language: symbol&.language)
  reference = language.reference(text)
  
  Trenni::Builder.fragment do |builder|
    if 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
    else
      builder.inline('code', class: "language-#{symbol.language.name}") do
        builder.text text
      end
    end
  end
end

#lookup(path) ⇒ Object



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

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.

Parameters:

  • file_name (String)

    The relative path to the project file, e.g. ‘README.md`.



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

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.

Parameters:

  • paths (Array(String))

    The paths to load and parse.



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

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