aboutsummaryrefslogtreecommitdiff
path: root/wruby.rb
blob: d4f49e680c81f4c1b9422a1d041793969ca85646 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
require 'kramdown'
require 'fileutils'
require 'date'
require 'rss'
require 'find'
require 'yaml'

# Load configuration
config = YAML.load_file('_config.yml')

site_url = config['site_url']
site_name = config['site_name']
author_name = config['author_name']

posts_dir = config['directories']['posts']
pages_dir = config['directories']['pages']
public_dir = config['directories']['public']
output_dir = config['directories']['output']
posts_output_dir = config['directories']['posts_output']
pages_output_dir = config['directories']['pages_output']

header_file = config['files']['header']
footer_file = config['files']['footer']
root_index_file = config['files']['root_index']
posts_index_file = config['files']['posts_index']
rss_file = config['files']['rss']

post_count = config['misc']['post_count']

# Make sure output directories exist
[posts_output_dir, pages_output_dir].each { |dir| FileUtils.mkdir_p(dir) }

# Read the footer content
footer_content = File.read(footer_file)

# Replace the title meta tag in the header.html
def replace_title_placeholder(header_content, title)
  header_content.gsub('<title>{{TITLE}}</title>', "<title>#{title}</title>")
end

# Grab the title from each markdown file
def extract_title_from_md(lines)
  first_line = lines.first
  first_line&.start_with?('# ') ? first_line[2..-1].strip : 'Blog Index'
end

# Convert markdown files
def process_markdown_files(input_directory, output_directory, header_content, footer_content)
  items = []

  Find.find(input_directory) do |path|
    next unless path =~ /\.md\z/

    md_content = File.read(path)
    lines = md_content.lines

    title = extract_title_from_md(lines)
    date = Date.parse(lines[2]&.strip || '') rescue Date.today
    html_content = Kramdown::Document.new(md_content).to_html

    relative_path = path.sub(input_directory + '/', '').sub('.md', '')
    item_dir = File.join(output_directory, relative_path)
    output_file = "#{item_dir}/index.html"
    FileUtils.mkdir_p(item_dir)

    header = replace_title_placeholder(header_content, title)
    File.write(output_file, header + html_content + footer_content)

    items << { title: title, date: date, link: relative_path + '/', content: html_content }
  end

  items
end

# Create the root index file
def generate_index(posts, header_content, footer_content, root_index_file, post_count, output_dir, posts_dir)
  root_index_content = File.read(root_index_file)
  root_title = extract_title_from_md(root_index_content.lines)
  root_html = Kramdown::Document.new(root_index_content).to_html

  header = replace_title_placeholder(header_content, root_title)

  index_content = header + root_html + "<ul class=\"posts\">\n"
  posts.first(post_count).each { |post| index_content << "<li><span>#{post[:date]}</span><a href='/#{posts_dir}/#{post[:link]}'>#{post[:title]}</a></li>\n" }
  index_content << "</ul>\n<p><a href='/#{posts_dir}'>View all posts &rarr;</a></p>\n" + footer_content

  File.write("#{output_dir}/index.html", index_content)
end

# Create the full posts list page
def generate_full_posts_list(posts, header_content, footer_content, posts_index_file, output_dir, posts_dir)
  posts_index_content = File.read(posts_index_file)
  posts_title = extract_title_from_md(posts_index_content.lines)
  posts_html = Kramdown::Document.new(posts_index_content).to_html

  header = replace_title_placeholder(header_content, posts_title)

  list_content = header + posts_html + "<ul class=\"posts\">\n"
  posts.each { |post| list_content << "<li><span>#{post[:date]}</span><a href='/#{posts_dir}/#{post[:link]}'>#{post[:title]}</a></li>\n" }
  list_content << "</ul>\n" + footer_content

  File.write("#{output_dir}/posts/index.html", list_content)
end

# Generate the RSS 2.0 feed
def generate_rss(posts, rss_file, author_name, site_name, site_url, posts_dir)
  rss = RSS::Maker.make("2.0") do |maker|
    maker.channel.author = author_name
    maker.channel.updated = Time.now.to_s
    maker.channel.title = "#{site_name} RSS Feed"
    maker.channel.description = "The official RSS Feed for #{site_url}"
    maker.channel.link = site_url

    posts.each do |post|
      date = Date.parse(post[:date].to_s).to_time + 12*60*60 # Force time to midday
      item_link = "#{site_url}/#{posts_dir}/#{post[:link]}"
      item_title = post[:title]
      item_content = post[:content]

      maker.items.new_item do |item|
        item.link = item_link
        item.title = item_title
        item.updated = date.to_s
        item.pubDate = date.rfc822
        item.description = item_content
      end
    end
  end

  File.write(rss_file, rss)
end

# Process header, posts, pages, etc.
header_content = File.read(header_file)

posts = process_markdown_files(posts_dir, posts_output_dir, header_content, footer_content).sort_by { |post| -post[:date].to_time.to_i }
pages = process_markdown_files(pages_dir, pages_output_dir, header_content, footer_content)

generate_index(posts, header_content, footer_content, root_index_file, post_count, output_dir, posts_dir)
generate_full_posts_list(posts, header_content, footer_content, posts_index_file, output_dir, posts_dir)
FileUtils.cp_r(public_dir, output_dir)
generate_rss(posts, rss_file, author_name, site_name, site_url, posts_dir)

puts "Blog built successfully in '#{output_dir}' folder. Have a great day!"