Class: Ottogen::Ottogen

Inherits:
Object
  • Object
show all
Defined in:
lib/ottogen/ottogen.rb

Constant Summary collapse

BUILD_DIR =
'_build'

Class Method Summary collapse

Class Method Details



73
74
75
76
77
78
79
# File 'lib/ottogen/ottogen.rb', line 73

def self.apply_permalink(doc, config)
  template = doc.front_matter['permalink']
  template ||= config['permalink'] if doc.is_a?(Post)
  return if template.nil?

  doc.permalink = Permalink.expand(template, doc)
end

.build(drafts: false) ⇒ Object



42
43
44
45
46
47
48
49
50
# File 'lib/ottogen/ottogen.rb', line 42

def self.build(drafts: false)
  puts '🔨 Building static site...'
  error_if_not_otto_project
  config = load_config(drafts: drafts)
  FileUtils.mkdir_p(BUILD_DIR)
  FileUtils.cp_r 'assets/', "#{BUILD_DIR}/assets"
  documents_for(config).each { |doc| convert_document(doc, config) }
  puts ''
end

.cleanObject



134
135
136
137
138
139
140
141
# File 'lib/ottogen/ottogen.rb', line 134

def self.clean
  puts '🧽 Cleaning build directory...'
  error_if_not_otto_project
  return unless Dir.exist?(BUILD_DIR)

  FileUtils.rmtree(BUILD_DIR)
  puts ''
end

.collect_problemsObject



126
127
128
129
130
131
132
# File 'lib/ottogen/ottogen.rb', line 126

def self.collect_problems
  problems = []
  problems << '.otto marker missing (run `otto init` first)' unless File.exist?('.otto')
  problems << 'config.yml missing' unless File.exist?('config.yml')
  problems << 'pages/ directory missing' unless Dir.exist?('pages')
  problems
end

.convert_document(doc, config) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/ottogen/ottogen.rb', line 64

def self.convert_document(doc, config)
  apply_permalink(doc, config)
  html = render_document(doc, config)
  write_output(doc.output_path(BUILD_DIR), html)
rescue Layout::Error => e
  puts "❌ Error in #{doc.path}: #{e.message}"
  exit(1)
end

.doctorObject



115
116
117
118
119
120
121
122
123
124
# File 'lib/ottogen/ottogen.rb', line 115

def self.doctor
  problems = collect_problems
  if problems.empty?
    puts '✅ All checks passed'
  else
    puts '❌ Problems:'
    problems.each { |p| puts "  - #{p}" }
    exit(1)
  end
end

.documents_for(config) ⇒ Object



52
53
54
55
# File 'lib/ottogen/ottogen.rb', line 52

def self.documents_for(config)
  collection_items = config.collections.values.flat_map { |c| c.output? ? c.items : [] }
  load_pages + config.posts + collection_items
end

.error_if_not_otto_projectObject



177
178
179
180
181
182
# File 'lib/ottogen/ottogen.rb', line 177

def self.error_if_not_otto_project
  return if File.exist?('.otto')

  puts '❌ Error: Current directory is not an otto project'
  exit(1)
end

.generate(page) ⇒ Object



98
99
100
101
102
103
# File 'lib/ottogen/ottogen.rb', line 98

def self.generate(page)
  puts '📝 Generating a new page...'
  error_if_not_otto_project
  page_title = page.split('-').map(&:capitalize).join(' ')
  File.write("pages/#{page}.adoc", "= #{page_title}\n")
end

.init(dir) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ottogen/ottogen.rb', line 21

def self.init(dir)
  puts '✨ Initializing static site...'
  if !dir.nil? && Dir.exist?(dir)
    puts '❌ Error: Directory already exists'
    exit(1)
  end

  if dir.nil?
    files_in_current_dir = Dir.glob('**/*')
    unless files_in_current_dir.empty?
      puts '❌ Error: Directory must be empty'
      exit(1)
    end
    init_in_current_dir
  else
    init_with_dir(dir)
  end

  puts ''
end

.init_in_current_dirObject



173
174
175
# File 'lib/ottogen/ottogen.rb', line 173

def self.init_in_current_dir
  Scaffold.write('.')
end

.init_with_dir(dir) ⇒ Object



168
169
170
171
# File 'lib/ottogen/ottogen.rb', line 168

def self.init_with_dir(dir)
  Dir.mkdir(dir)
  Scaffold.write(dir)
end

.load_config(drafts: false) ⇒ Object



184
185
186
187
188
189
# File 'lib/ottogen/ottogen.rb', line 184

def self.load_config(drafts: false)
  Config.load(drafts: drafts)
rescue Config::Error => e
  puts "❌ Error: #{e.message}"
  exit(1)
end

.load_pagesObject



57
58
59
60
61
62
# File 'lib/ottogen/ottogen.rb', line 57

def self.load_pages
  Dir.glob('pages/**/*.adoc').map { |path| Page.read(path) }
rescue Page::Error => e
  puts "❌ Error: #{e.message}"
  exit(1)
end

.new_post(title) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/ottogen/ottogen.rb', line 105

def self.new_post(title)
  error_if_not_otto_project
  FileUtils.mkdir_p('_posts')
  slug = Permalink.slugify(title)
  date = Date.today
  path = "_posts/#{date.iso8601}-#{slug}.adoc"
  File.write(path, "---\ntitle: #{title}\ndate: #{date.iso8601}\n---\n\n")
  puts "📝 Created #{path}"
end

.render_document(doc, config) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ottogen/ottogen.rb', line 81

def self.render_document(doc, config)
  layout_name = doc.front_matter['layout']
  attributes = config.asciidoctor_attributes.merge(doc.asciidoctor_attributes)
  body = Asciidoctor.convert(doc.body,
                             safe: :safe,
                             standalone: layout_name.nil?,
                             attributes: attributes)
  return body unless layout_name

  Layout.find(layout_name).render(content: body, site: config, page: doc)
end

.serveObject



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/ottogen/ottogen.rb', line 143

def self.serve
  puts '🤖 Starting server...'
  error_if_not_otto_project
  root = File.expand_path("#{Dir.pwd}/#{Ottogen::BUILD_DIR}")
  server = WEBrick::HTTPServer.new Port: 8778, DocumentRoot: root
  trap 'INT' do
    server.shutdown
  end
  server.start
rescue Errno::EADDRINUSE
  puts '❌ Server port already in use'
  exit(1)
end

.watch(drafts: false) ⇒ Object



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

def self.watch(drafts: false)
  puts '👀 Watching files...'
  error_if_not_otto_project
  listener = Listen.to(Dir.pwd, ignore: [/_build/]) do |modified, added, removed|
    puts(modified: modified, added: added, removed: removed)
    build(drafts: drafts)
  end
  listener.start
  sleep
end

.write_output(path, html) ⇒ Object



93
94
95
96
# File 'lib/ottogen/ottogen.rb', line 93

def self.write_output(path, html)
  FileUtils.mkdir_p(File.dirname(path))
  File.write(path, html)
end