diff --git a/README.md b/README.md index 76867b9..a990709 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,18 @@ Repubmark ========= A Markdown-inspired markup language that can be compiled into HTML and Gemtext. + + + +Examples +-------- + +* `./exe/repubmark examples/config.yml word_count < examples/hello.repub` +* `./exe/repubmark examples/config.yml http < examples/hello.repub` +* `./exe/repubmark examples/config.yml gemini < examples/hello.repub` +* `./exe/repubmark examples/config.yml rss < examples/hello.repub` + +* `./exe/repubmark examples/config.yml word_count < examples/full.repub` +* `./exe/repubmark examples/config.yml http < examples/full.repub` +* `./exe/repubmark examples/config.yml gemini < examples/full.repub` +* `./exe/repubmark examples/config.yml rss < examples/full.repub` diff --git a/config/gemini.yml b/config/gemini.yml deleted file mode 100644 index 2f7f7e7..0000000 --- a/config/gemini.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -format: gemtext - -base_url: 'gemini://causa-arcana.com' -current_path: '/xx/blog/xxxx/xx/xx/xxxxx.xxx' -images_prefix: '/assets/images/blog' -relative_urls: true diff --git a/config/http.yml b/config/http.yml deleted file mode 100644 index 12653c7..0000000 --- a/config/http.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -format: html - -base_url: 'https://causa-arcana.com' -current_path: '/xx/blog/xxxx/xx/xx/xxxxx.xxx' -images_prefix: '/assets/images/blog' -relative_urls: true - -css_class_annotation: 'nice-annotation' -css_class_blockquote_figure: 'nice-blockquote' -css_class_figure_self: 'nice-figure' -css_class_figure_wrap: 'd-flex justify-content-center' -css_class_figures_left: 'col-xl-6' -css_class_figures_right: 'col-xl-6' -css_class_figures_wrap: 'row' -css_class_iframe_wrap: 'ratio ratio-16x9' diff --git a/config/rss.yml b/config/rss.yml deleted file mode 100644 index 93c58be..0000000 --- a/config/rss.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -format: html - -base_url: 'https://causa-arcana.com' -current_path: '/xx/blog/xxxx/xx/xx/xxxxx.xxx' -images_prefix: '/assets/images/blog' -relative_urls: false - -css_class_annotation: 'nice-annotation' -css_class_blockquote_figure: 'nice-blockquote' -css_class_figure_self: 'nice-figure' -css_class_figure_wrap: 'd-flex justify-content-center' -css_class_figures_left: 'col-xl-6' -css_class_figures_right: 'col-xl-6' -css_class_figures_wrap: 'row' -css_class_iframe_wrap: 'ratio ratio-16x9' diff --git a/config/word_count.yml b/config/word_count.yml deleted file mode 100644 index 1c93588..0000000 --- a/config/word_count.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -format: word_count diff --git a/examples/config.yml b/examples/config.yml new file mode 100644 index 0000000..7af5ebf --- /dev/null +++ b/examples/config.yml @@ -0,0 +1,43 @@ +--- +########## +# Shared # +########## + +paths: &paths + current_path: '/xxxxx.xxx' + images_prefix: '/assets/images' + +css_classes: &css_classes + css_class_annotation: 'nice-annotation' + css_class_blockquote_figure: 'nice-blockquote' + css_class_figure_self: 'nice-figure' + css_class_figure_wrap: 'd-flex justify-content-center' + css_class_figures_left: 'col-xl-6' + css_class_figures_right: 'col-xl-6' + css_class_figures_wrap: 'row' + css_class_iframe_wrap: 'ratio ratio-16x9' + +############ +# Profiles # +############ + +word_count: + format: word_count + +gemini: + <<: *paths + format: gemtext + relative_urls: true + +http: + <<: *paths + <<: *css_classes + format: html + relative_urls: true + +rss: + <<: *paths + <<: *css_classes + format: html + relative_urls: false + base_url: 'https://example.com' diff --git a/examples/full.gmi b/examples/full.gmi new file mode 100644 index 0000000..0e9be72 --- /dev/null +++ b/examples/full.gmi @@ -0,0 +1,36 @@ +Gemtext prolofue + + + +Annotation paragraph text + + + +> Blockquote paragraph text +Blockquote caption text + +``` +[[:foo, 1], [:bar, 2], [:car, 3]].each do |str, num| + puts str + puts num**2 +end +``` + +=> https://example.com Example.com + +=> assets/images/foo.jpg The Foo + +=> assets/images/qwe.jpg The Qwe +=> assets/images/rty.jpg The Rty + +## Chapter 1 + +Chapter 1 paragraph text + +## Chapter 2 + +Chapter 2 paragraph text + + + +Gemtext epilogue diff --git a/examples/full.html b/examples/full.html new file mode 100644 index 0000000..1b6df1b --- /dev/null +++ b/examples/full.html @@ -0,0 +1,83 @@ +
+HTTP prologue +
+
+

+ +Annotation paragraph text + +

+
+
+
+

+ +Blockquote paragraph text + +

+
+
+ +Blockquote caption text + +
+
+
    1 [[:foo, 1], [:bar, 2], [:car, 3]].each do |str, num|
+    2   puts str
+    3   puts num**2
+    4 end
+
+
+ +
+
+
+The Foo +
+The Foo +
+
+
+
+
+
+
+The Qwe +
+The Qwe +
+
+
+
+
+
+
+The Rty +
+The Rty +
+
+
+
+
+

Chapter 1

+

+ +Chapter 1 paragraph text + +

+

Chapter 2

+

+ +Chapter 2 paragraph text + +

+
+HTTP epilogue +
diff --git a/examples/full.repub b/examples/full.repub new file mode 100644 index 0000000..3efd649 --- /dev/null +++ b/examples/full.repub @@ -0,0 +1,60 @@ +article.prologue do |custom| + custom.for :html, 'HTTP prologue' + custom.for :gemtext, 'Gemtext prolofue' +end + +article.annotation do |annotation| + annotation.paragraph do |paragraph| + paragraph.text 'Annotation paragraph text' + end +end + + + +article.blockquote do |blockquote| + blockquote.paragraph do |paragraph| + paragraph.text 'Blockquote paragraph text' + end + blockquote.caption do |caption| + caption.text 'Blockquote caption text' + end +end + +article.code_block :ruby, <<~CODE +[[:foo, 1], [:bar, 2], [:car, 3]].each do |str, num| + puts str + puts num**2 +end +CODE + +article.iframe 'Example.com', 'https://example.com' + +article.nice_figure 'foo.jpg', 'The Foo' + +article.nice_figures do |figures| + figures.figure 'qwe.jpg', 'The Qwe' + figures.figure 'rty.jpg', 'The Rty' +end + + + +article.chapter 'Chapter 1' do |chapter| + chapter.paragraph do |paragraph| + paragraph.text 'Chapter 1 paragraph text' + end +end + + + +article.chapter 'Chapter 2' do |chapter| + chapter.paragraph do |paragraph| + paragraph.text 'Chapter 2 paragraph text' + end +end + + + +article.epilogue do |custom| + custom.for :html, 'HTTP epilogue' + custom.for :gemtext, 'Gemtext epilogue' +end diff --git a/examples/hello.gmi b/examples/hello.gmi new file mode 100644 index 0000000..8ab686e --- /dev/null +++ b/examples/hello.gmi @@ -0,0 +1 @@ +Hello, World! diff --git a/examples/hello.html b/examples/hello.html new file mode 100644 index 0000000..3a1702f --- /dev/null +++ b/examples/hello.html @@ -0,0 +1,5 @@ +

+ +Hello, World! + +

diff --git a/examples/hello.repub b/examples/hello.repub new file mode 100644 index 0000000..e2bb7eb --- /dev/null +++ b/examples/hello.repub @@ -0,0 +1,3 @@ +article.paragraph do |paragraph| + paragraph.text 'Hello, World!' +end diff --git a/exe/repubmark b/exe/repubmark index b8eda74..2b112da 100755 --- a/exe/repubmark +++ b/exe/repubmark @@ -8,7 +8,10 @@ require 'bundler/setup' require 'repubmark' -config = Repubmark::Config.load_file String ARGV[0] +config_filename = String(ARGV[0]).freeze +profile = String(ARGV[1]).freeze + +config = Repubmark::Config.load_file config_filename, profile $article = Repubmark::Elems::Article.new config template = $stdin.read.freeze diff --git a/lib/repubmark/config.rb b/lib/repubmark/config.rb index 4f28979..b278af3 100644 --- a/lib/repubmark/config.rb +++ b/lib/repubmark/config.rb @@ -21,8 +21,12 @@ module Repubmark attr_reader :format - def self.load_file(filename) - new(**YAML.safe_load_file(filename).transform_keys(&:to_sym)) + def self.load_file(filename, profile) + config_data = YAML.safe_load_file filename, aliases: true + profile_data = config_data[profile] + raise 'Unknown profile' if profile_data.nil? + + new(**profile_data.transform_keys(&:to_sym)) end def initialize(format:, **kwargs) diff --git a/test.rb b/test.rb new file mode 100755 index 0000000..62a31a0 --- /dev/null +++ b/test.rb @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'open3' + +EXE = File.expand_path('exe/repubmark', __dir__).freeze +EXAMPLES = File.expand_path('examples', __dir__).freeze +EXAMPLES_GLOB = File.expand_path('examples/*.repub', __dir__).freeze +CONFIG = File.expand_path('examples/config.yml', __dir__).freeze + +PROFILES = [ + %w[http html], + %w[gemini gmi], +].map(&:freeze).freeze + +Dir[EXAMPLES_GLOB].each do |example_filename| + example = File.read example_filename + PROFILES.each do |profile_name, expected_ext| + expected_filename = "#{example_filename[...-6]}.#{expected_ext}" + expected = File.read expected_filename + + puts '=' * 80 + puts "Config: #{CONFIG}" + puts "Example: #{example_filename}" + puts "Profile: #{profile_name}" + puts "Expected: #{expected_filename}" + puts '-' * 80 + puts example.strip + puts '-' * 80 + puts expected.strip + + stdin, stdout, wait_thr = Open3.popen2 EXE, CONFIG, profile_name + stdin.puts example + stdin.close + result = stdout.read + stdout.close + raise 'Template engine error' unless wait_thr.value.success? + next if result == expected + + puts '-' * 80 + puts result.strip + puts '=' * 80 + raise 'Invalid output' + end +end + +puts '=' * 80