aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.rb188
-rw-r--r--lib/extensions/document_title_processor.rb15
-rw-r--r--lib/extensions/lang_attribute_processor.rb9
-rw-r--r--lib/extensions/revision_history_processor.rb27
-rw-r--r--lib/extensions/section_id_validator.rb29
-rw-r--r--lib/extensions/source_id_processor.rb12
-rw-r--r--lib/extensions/source_id_validator.rb32
-rw-r--r--lib/extensions/tags_processor.rb20
-rw-r--r--lib/html_converter.rb16
-rw-r--r--lib/parser.rb59
-rw-r--r--lib/revision.rb3
-rw-r--r--lib/tag.rb26
12 files changed, 0 insertions, 436 deletions
diff --git a/lib/command.rb b/lib/command.rb
deleted file mode 100644
index 3a47669..0000000
--- a/lib/command.rb
+++ /dev/null
@@ -1,188 +0,0 @@
-module NulDoc
- class Command
- def initialize(config)
- @config = config
- @content_dir = @config[:content_dir]
- @dest_dir = @config[:dest_dir]
- @static_dir = @config[:static_dir]
- @template_dir = @config[:template_dir]
- @parser = NulDoc::Parser.new(
- {
- 'stylesheets' => stylesheets,
- 'author' => @config[:author],
- 'site-copyright-year' => @config[:site_copyright_year],
- 'site-name' => @config[:site_name],
- },
- @content_dir,
- @template_dir,
- )
- end
-
- def run
- posts = generate_posts(@content_dir + '/posts')
- generate_tags(posts)
- generate_post_list(posts)
- end
-
- private
-
- def generate_posts(source_dir)
- post_files = collect_post_files(source_dir)
- posts = parse_posts(post_files)
- output_posts(posts)
- posts
- end
-
- def collect_post_files(source_dir)
- file_paths = []
- Dir.glob('**/*.adoc', base: source_dir, sort: true) do |path|
- file_paths << "#{source_dir}/#{path}"
- end
- file_paths
- end
-
- def parse_posts(post_file_paths)
- post_file_paths.map { @parser.parse_file(_1, 'post') }
- end
-
- def output_posts(posts)
- posts.each do |post|
- destination_file_path = post.attributes['source-file-path']
- .sub(@content_dir, @dest_dir)
- .sub('.adoc', '/index.html')
- destination_dir = File.dirname(destination_file_path)
- unless Dir.exist?(destination_dir)
- FileUtils.makedirs(destination_dir)
- end
- open(destination_file_path, 'w') do |f|
- f.puts(post.convert)
- end
- end
- end
-
- def generate_tags(posts)
- tags_and_posts = collect_tags(posts)
- tag_docs = build_tag_docs(tags_and_posts)
- output_tags(tag_docs)
- end
-
- def collect_tags(posts)
- tags_and_posts = {}
- posts.each do |post|
- post.attributes['tags'].each do |tag|
- tags_and_posts[tag] ||= []
- tags_and_posts[tag] << post
- end
- end
- tags_and_posts
- .transform_values {|posts|
- posts.sort_by {|post|
- post.attributes['revision-history'].first.date # created_at
- }.reverse
- }
- .sort_by {|tag, _| tag.slug }
- .to_h
- end
-
- def build_tag_docs(tags_and_posts)
- tags_and_posts.map do |tag, posts|
- [tag, build_tag_doc(tag, posts)]
- end
- end
-
- def build_tag_doc(tag, posts)
- converter = NulDoc::HTMLConverter.new(nil, { template_dirs: [@template_dir] })
- converter.convert_document(
- (Class.new do
- def initialize(config, tag, posts, stylesheets)
- @config = config
- @tag = tag
- @posts = posts
- @stylesheets = stylesheets
- end
- def attr(name)
- case name
- when 'document-type'; 'tag'
- when 'stylesheets'; @stylesheets
- when 'author'; @config[:author]
- when 'site-copyright-year'; @config[:site_copyright_year]
- when 'site-name'; @config[:site_name]
- when 'lang'; 'ja-JP' # TODO
- when 'copyright-year'; @posts.last.attributes['revision-history'].first.date.year
- when 'description'; "タグ「#{@tag.label}」のついた記事一覧"
- else raise "Unknown attr: #{name}"
- end
- end
- def title; @tag.label; end
- def posts; @posts; end
- end).new(@config, tag, posts, stylesheets)
- )
- end
-
- def output_tags(tag_docs)
- tag_docs.each do |tag, html|
- destination_file_path = "#{@dest_dir}/tags/#{tag.slug}/index.html"
- destination_dir = File.dirname(destination_file_path)
- unless Dir.exist?(destination_dir)
- FileUtils.makedirs(destination_dir)
- end
- open(destination_file_path, 'w') do |f|
- f.puts(html)
- end
- end
- end
-
- def generate_post_list(posts)
- html = build_post_list_doc(posts)
- output_post_list(html)
- end
-
- def build_post_list_doc(posts)
- converter = NulDoc::HTMLConverter.new(nil, { template_dirs: [@template_dir] })
- converter.convert_document(
- (Class.new do
- def initialize(config, posts, stylesheets)
- @config = config
- @posts = posts
- @stylesheets = stylesheets
- end
- def attr(name)
- case name
- when 'document-type'; 'post_list'
- when 'stylesheets'; @stylesheets
- when 'author'; @config[:author]
- when 'site-copyright-year'; @config[:site_copyright_year]
- when 'site-name'; @config[:site_name]
- when 'lang'; 'ja-JP' # TODO
- when 'copyright-year'; @config[:site_copyright_year]
- when 'description'; '投稿した記事の一覧'
- else raise "Unknown attr: #{name}"
- end
- end
- def title; '投稿一覧'; end
- def posts; @posts; end
- end).new(@config, posts.reverse, stylesheets)
- )
- end
-
- def output_post_list(html)
- destination_file_path = "#{@dest_dir}/posts/index.html"
- destination_dir = File.dirname(destination_file_path)
- unless Dir.exist?(destination_dir)
- FileUtils.makedirs(destination_dir)
- end
- open(destination_file_path, 'w') do |f|
- f.puts(html)
- end
- end
-
- def stylesheets
- stylesheet_file_names = %w[hl.css style.css custom.css]
- stylesheet_file_names.map {|ss_file_name|
- ss_file_path = "#{@static_dir}/#{ss_file_name}"
- hash = Digest::MD5.file(ss_file_path).hexdigest
- "/#{ss_file_name}?#{hash}"
- }
- end
- end
-end
diff --git a/lib/extensions/document_title_processor.rb b/lib/extensions/document_title_processor.rb
deleted file mode 100644
index fd25844..0000000
--- a/lib/extensions/document_title_processor.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Nuldoc
- module Extensions
- class DocumentTitleProcessor < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- doc.title = substitute_document_title(doc.title)
- end
-
- private
-
- def substitute_document_title(title)
- title.sub(/\A\[(.+?)\] /, '【\1】')
- end
- end
- end
-end
diff --git a/lib/extensions/lang_attribute_processor.rb b/lib/extensions/lang_attribute_processor.rb
deleted file mode 100644
index 65511bc..0000000
--- a/lib/extensions/lang_attribute_processor.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Nuldoc
- module Extensions
- class LangAttributeProcessor < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- doc.attributes['lang'] ||= 'ja-JP'
- end
- end
- end
-end
diff --git a/lib/extensions/revision_history_processor.rb b/lib/extensions/revision_history_processor.rb
deleted file mode 100644
index f416de0..0000000
--- a/lib/extensions/revision_history_processor.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-module Nuldoc
- module Extensions
- class RevisionHistoryProcessor < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- revisions = []
- i = 1
- loop do
- break unless (rev = doc.attributes["revision-#{i}"])
- revisions << parse_revision(rev)
- i += 1
- end
- doc.attributes['revision-history'] = revisions
- end
-
- private
-
- def parse_revision(rev)
- m = rev.match(/\A(\d\d\d\d-\d\d-\d\d) (.*)\z/)
- raise unless m
- Revision.new(
- date: Date.parse(m[1], '%Y-%m-%d'),
- remark: m[2],
- )
- end
- end
- end
-end
diff --git a/lib/extensions/section_id_validator.rb b/lib/extensions/section_id_validator.rb
deleted file mode 100644
index 2ad496c..0000000
--- a/lib/extensions/section_id_validator.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Nuldoc
- module Extensions
- class SectionIdValidator < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- errors = []
- (doc.find_by(context: :section) {_1.level > 0}).each do |section|
- errors << validate_section(section)
- end
- error_message = errors.compact.join("\n")
- unless error_message.empty?
- raise "SectionIdValidator (#{doc.attributes['source-file-path']}):\n#{error_message}"
- end
- end
-
- private
-
- def validate_section(section)
- id = section.id
- unless id
- return "Section '#{section.title}': each section MUST have an id."
- end
- unless id.match?(/\A[-0-9a-z]+\z/)
- return "Section '#{section.title}' (##{id}): section id MUST consist of either hyphen, digits or lowercases."
- end
- nil
- end
- end
- end
-end
diff --git a/lib/extensions/source_id_processor.rb b/lib/extensions/source_id_processor.rb
deleted file mode 100644
index 13813e0..0000000
--- a/lib/extensions/source_id_processor.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Nuldoc
- module Extensions
- class SourceIdProcessor < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- errors = []
- (doc.find_by(context: :listing) {_1.style == 'source'}).each do |source|
- source.id = "source.#{source.id}"
- end
- end
- end
- end
-end
diff --git a/lib/extensions/source_id_validator.rb b/lib/extensions/source_id_validator.rb
deleted file mode 100644
index 6e04deb..0000000
--- a/lib/extensions/source_id_validator.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-module Nuldoc
- module Extensions
- class SourceIdValidator < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- errors = []
- (doc.find_by(context: :listing) {_1.style == 'source'}).each do |source|
- errors << validate_section(source)
- end
- error_message = errors.compact.join("\n")
- unless error_message.empty?
- raise "SourceIdValidator (#{doc.attributes['source-file-path']}):\n#{error_message}"
- end
- end
-
- private
-
- def validate_section(source)
- id = source.id
- unless id
- return "Each source MUST have an id."
- end
- if id.start_with?('source.')
- return "Source id (##{id}) MUST NOT start with 'source.', which is appended by `nul`."
- end
- unless id.match?(/\A[-0-9a-z]+\z/)
- return "Source id (##{id}) MUST consist of either hypen, digits or lowercases."
- end
- nil
- end
- end
- end
-end
diff --git a/lib/extensions/tags_processor.rb b/lib/extensions/tags_processor.rb
deleted file mode 100644
index efbd2a8..0000000
--- a/lib/extensions/tags_processor.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-module Nuldoc
- module Extensions
- class TagsProcessor < Asciidoctor::Extensions::TreeProcessor
- def process(doc)
- doc.attributes['tags'] = convert_tags(doc.attributes['tags'])
- end
-
- private
-
- def convert_tags(tags)
- return [] unless tags
-
- tags
- .split(',')
- .map(&:strip)
- .map { Tag.from_slug(_1) }
- end
- end
- end
-end
diff --git a/lib/html_converter.rb b/lib/html_converter.rb
deleted file mode 100644
index 126d72a..0000000
--- a/lib/html_converter.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module NulDoc
- class HTMLConverter < (Asciidoctor::Converter.for 'html5')
- register_for 'html5'
-
- def initialize(backend, opts)
- super
- @template_dir = opts[:template_dirs].first
- end
-
- def convert_document(node)
- template_file_name = "document__#{node.attr('document-type')}.html.erb"
- erb = Tilt::ERBTemplate.new("#{@template_dir}/#{template_file_name}")
- erb.render(node, {})
- end
- end
-end
diff --git a/lib/parser.rb b/lib/parser.rb
deleted file mode 100644
index f241c4d..0000000
--- a/lib/parser.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-module NulDoc
- class Parser
- def initialize(common_attributes, content_dir, template_dir)
- @common_attributes = common_attributes
- @content_dir = content_dir
- @template_dir = template_dir
- end
-
- def parse_file(file_path, document_type)
- Asciidoctor.load_file(
- file_path,
- backend: :html5,
- doctype: :article,
- standalone: true,
- safe: :unsafe,
- template_dirs: [@template_dir],
- template_engine: 'erb',
- template_engine_options: { erb: { trim: '<>' } },
- attributes: @common_attributes.merge({
- 'document-type' => document_type,
- 'source-file-path' => file_path,
- 'href' => file_path.sub(@content_dir, '').sub('.adoc', '/'),
- 'source-highlighter' => 'rouge',
- 'reproducible' => true,
- 'sectids' => false,
- }),
- extension_registry: Asciidoctor::Extensions.create do
- tree_processor Nuldoc::Extensions::RevisionHistoryProcessor
- tree_processor Nuldoc::Extensions::DocumentTitleProcessor
- tree_processor Nuldoc::Extensions::LangAttributeProcessor
- # tree_processor Nuldoc::Extensions::SectionIdValidator
- # tree_processor Nuldoc::Extensions::SourceIdValidator
- tree_processor Nuldoc::Extensions::TagsProcessor
-
- # MUST BE AT THE END
- tree_processor Nuldoc::Extensions::SourceIdProcessor
- end,
- )
- end
-
- def parse_string(s, copyright_year)
- Asciidoctor.convert(
- s,
- backend: :html5,
- doctype: :article,
- safe: :unsafe,
- template_dirs: [@template_dir],
- template_engine: 'erb',
- attributes: @common_attributes.merge({
- 'copyright-year' => copyright_year,
- }),
- extension_registry: Asciidoctor::Extensions.create do
- tree_processor Nuldoc::Extensions::LangAttributeProcessor
- tree_processor Nuldoc::Extensions::TagsProcessor
- end,
- )
- end
- end
-end
diff --git a/lib/revision.rb b/lib/revision.rb
deleted file mode 100644
index b986a14..0000000
--- a/lib/revision.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-module Nuldoc
- Revision = Struct.new(:date, :remark, keyword_init: true)
-end
diff --git a/lib/tag.rb b/lib/tag.rb
deleted file mode 100644
index a7c13b2..0000000
--- a/lib/tag.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-module Nuldoc
- Tag = Struct.new(:slug, :label, keyword_init: true) do
- LABELS = {
- 'conference' => 'カンファレンス',
- 'cpp' => 'C++',
- 'cpp17' => 'C++ 17',
- 'note-to-self' => '備忘録',
- 'php' => 'PHP',
- 'phpcon' => 'PHP カンファレンス',
- 'phperkaigi' => 'PHPerKaigi',
- 'python' => 'Python',
- 'python3' => 'Python 3',
- 'ruby' => 'Ruby',
- 'ruby3' => 'Ruby 3',
- 'rust' => 'Rust',
- 'vim' => 'Vim',
- }
-
- def self.from_slug(slug)
- Tag.new(
- slug: slug,
- label: (LABELS[slug] || raise("No label for tag '#{slug}'")),
- )
- end
- end
-end