mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-03-25 09:05:47 +00:00
Replace the Swift site generator with a Ruby and Phlex implementation. Loads site and projects from TOML, derive site metadata from posts. Migrate from make to bake and add standardrb and code coverage tasks. Update CI and docs to match the new workflow, and remove unused assets/dependencies plus obsolete tooling.
124 lines
3 KiB
Ruby
124 lines
3 KiB
Ruby
require "kramdown"
|
|
require "pressa/posts/models"
|
|
require "pressa/posts/metadata"
|
|
|
|
module Pressa
|
|
module Posts
|
|
class PostRepo
|
|
EXCERPT_LENGTH = 300
|
|
|
|
def initialize(output_path: "posts")
|
|
@output_path = output_path
|
|
@posts_by_year = {}
|
|
end
|
|
|
|
def read_posts(posts_dir)
|
|
enumerate_markdown_files(posts_dir) do |file_path|
|
|
post = read_post(file_path)
|
|
add_post_to_hierarchy(post)
|
|
end
|
|
|
|
PostsByYear.new(by_year: @posts_by_year)
|
|
end
|
|
|
|
private
|
|
|
|
def enumerate_markdown_files(dir, &block)
|
|
Dir.glob(File.join(dir, "**", "*.md")).each(&block)
|
|
end
|
|
|
|
def read_post(file_path)
|
|
content = File.read(file_path)
|
|
metadata = PostMetadata.parse(content)
|
|
|
|
body_markdown = content.sub(/\A---\s*\n.*?\n---\s*\n/m, "")
|
|
|
|
html_body = render_markdown(body_markdown)
|
|
|
|
slug = File.basename(file_path, ".md")
|
|
path = generate_path(slug, metadata.date)
|
|
excerpt = generate_excerpt(body_markdown)
|
|
|
|
Post.new(
|
|
slug:,
|
|
title: metadata.title,
|
|
author: metadata.author,
|
|
date: metadata.date,
|
|
formatted_date: metadata.formatted_date,
|
|
link: metadata.link,
|
|
tags: metadata.tags,
|
|
body: html_body,
|
|
excerpt:,
|
|
path:
|
|
)
|
|
end
|
|
|
|
def render_markdown(markdown)
|
|
Kramdown::Document.new(
|
|
markdown,
|
|
input: "GFM",
|
|
hard_wrap: false,
|
|
syntax_highlighter: "rouge",
|
|
syntax_highlighter_opts: {
|
|
line_numbers: false,
|
|
wrap: true
|
|
}
|
|
).to_html
|
|
end
|
|
|
|
def generate_path(slug, date)
|
|
year = date.year
|
|
month = format("%02d", date.month)
|
|
"/#{@output_path}/#{year}/#{month}/#{slug}"
|
|
end
|
|
|
|
def generate_excerpt(markdown)
|
|
text = markdown.dup
|
|
|
|
text.gsub!(/!\[[^\]]*\]\([^)]+\)/, "")
|
|
text.gsub!(/!\[[^\]]*\]\[[^\]]+\]/, "")
|
|
|
|
text.gsub!(/\[([^\]]+)\]\([^)]+\)/, '\1')
|
|
text.gsub!(/\[([^\]]+)\]\[[^\]]+\]/, '\1')
|
|
|
|
text.gsub!(/(?m)^\[[^\]]+\]:\s*\S.*$/, "")
|
|
|
|
text.gsub!(/<[^>]+>/, "")
|
|
|
|
text.gsub!(/\s+/, " ")
|
|
text.strip!
|
|
|
|
return "..." if text.empty?
|
|
|
|
"#{text[0...EXCERPT_LENGTH]}..."
|
|
end
|
|
|
|
def add_post_to_hierarchy(post)
|
|
year = post.year
|
|
month_num = post.month
|
|
|
|
@posts_by_year[year] ||= create_year_posts(year)
|
|
year_posts = @posts_by_year[year]
|
|
|
|
month_posts = year_posts.by_month[month_num]
|
|
if month_posts
|
|
updated_posts = month_posts.posts + [post]
|
|
year_posts.by_month[month_num] = MonthPosts.new(
|
|
month: month_posts.month,
|
|
posts: updated_posts
|
|
)
|
|
else
|
|
month = Month.from_date(post.date)
|
|
year_posts.by_month[month_num] = MonthPosts.new(
|
|
month:,
|
|
posts: [post]
|
|
)
|
|
end
|
|
end
|
|
|
|
def create_year_posts(year)
|
|
YearPosts.new(year:, by_month: {})
|
|
end
|
|
end
|
|
end
|
|
end
|