diff options
| author | nsfisis <nsfisis@gmail.com> | 2022-12-23 23:27:09 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-06 01:46:04 +0900 |
| commit | 88ba6cfe220216f371f8756921059fac51a21262 (patch) | |
| tree | f272db2a0a3340f103df6618f19a101e65941b37 /lib | |
| parent | 8f988a6e899aed678406ddfac1be4ef105439274 (diff) | |
| download | blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.tar.gz blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.tar.zst blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.zip | |
AsciiDoc to DocBook
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.rb | 188 | ||||
| -rw-r--r-- | lib/extensions/document_title_processor.rb | 15 | ||||
| -rw-r--r-- | lib/extensions/lang_attribute_processor.rb | 9 | ||||
| -rw-r--r-- | lib/extensions/revision_history_processor.rb | 27 | ||||
| -rw-r--r-- | lib/extensions/section_id_validator.rb | 29 | ||||
| -rw-r--r-- | lib/extensions/source_id_processor.rb | 12 | ||||
| -rw-r--r-- | lib/extensions/source_id_validator.rb | 32 | ||||
| -rw-r--r-- | lib/extensions/tags_processor.rb | 20 | ||||
| -rw-r--r-- | lib/html_converter.rb | 16 | ||||
| -rw-r--r-- | lib/parser.rb | 59 | ||||
| -rw-r--r-- | lib/revision.rb | 3 | ||||
| -rw-r--r-- | lib/tag.rb | 26 |
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 |
