repubmark 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +46 -0
- data/.rubocop_todo.yml +129 -0
- data/.yardopts +4 -0
- data/LICENSE +21 -0
- data/README.md +21 -0
- data/Rakefile +60 -0
- data/examples/config.yml +71 -0
- data/examples/full.chapters.json +22 -0
- data/examples/full.gmi +44 -0
- data/examples/full.html +114 -0
- data/examples/full.repub +91 -0
- data/examples/full.summary.txt +2 -0
- data/examples/hello.chapters.json +3 -0
- data/examples/hello.gmi +1 -0
- data/examples/hello.html +5 -0
- data/examples/hello.repub +3 -0
- data/examples/hello.summary.txt +1 -0
- data/exe/repubmark +46 -0
- data/lib/repubmark/config.rb +53 -0
- data/lib/repubmark/elems/abbrev.rb +52 -0
- data/lib/repubmark/elems/annotation.rb +48 -0
- data/lib/repubmark/elems/article.rb +96 -0
- data/lib/repubmark/elems/base.rb +104 -0
- data/lib/repubmark/elems/blockquote.rb +80 -0
- data/lib/repubmark/elems/canvas.rb +104 -0
- data/lib/repubmark/elems/caption.rb +69 -0
- data/lib/repubmark/elems/chapter.rb +148 -0
- data/lib/repubmark/elems/code_block.rb +70 -0
- data/lib/repubmark/elems/code_inline.rb +35 -0
- data/lib/repubmark/elems/figure.rb +73 -0
- data/lib/repubmark/elems/figures.rb +47 -0
- data/lib/repubmark/elems/footnote.rb +87 -0
- data/lib/repubmark/elems/footnotes_category.rb +48 -0
- data/lib/repubmark/elems/fraction.rb +31 -0
- data/lib/repubmark/elems/iframe.rb +62 -0
- data/lib/repubmark/elems/joint.rb +176 -0
- data/lib/repubmark/elems/link.rb +56 -0
- data/lib/repubmark/elems/list.rb +84 -0
- data/lib/repubmark/elems/list_item.rb +147 -0
- data/lib/repubmark/elems/note.rb +40 -0
- data/lib/repubmark/elems/paragraph.rb +42 -0
- data/lib/repubmark/elems/power.rb +34 -0
- data/lib/repubmark/elems/quote.rb +53 -0
- data/lib/repubmark/elems/section.rb +58 -0
- data/lib/repubmark/elems/separator.rb +17 -0
- data/lib/repubmark/elems/special.rb +37 -0
- data/lib/repubmark/elems/text.rb +43 -0
- data/lib/repubmark/highlight.rb +85 -0
- data/lib/repubmark/titled_ref.rb +16 -0
- data/lib/repubmark/version.rb +6 -0
- data/lib/repubmark.rb +125 -0
- data/tests/examples.rb +51 -0
- metadata +129 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Repubmark
|
4
|
+
module Elems
|
5
|
+
# TODO: maybe don't allow mdash everywhere
|
6
|
+
class Special < Base
|
7
|
+
parents :Joint
|
8
|
+
|
9
|
+
HTML = {
|
10
|
+
ellipsis: '…',
|
11
|
+
mdash: '—',
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
UNICODE = {
|
15
|
+
ellipsis: '…',
|
16
|
+
mdash: '—',
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def initialize(parent, name)
|
20
|
+
super parent
|
21
|
+
name = String(name).to_sym.freeze
|
22
|
+
HTML.fetch name
|
23
|
+
@name = name
|
24
|
+
end
|
25
|
+
|
26
|
+
#################
|
27
|
+
# Basic methods #
|
28
|
+
#################
|
29
|
+
|
30
|
+
def to_summary_plain = UNICODE.fetch @name
|
31
|
+
|
32
|
+
def to_html = HTML.fetch @name
|
33
|
+
|
34
|
+
def to_gemtext = UNICODE.fetch @name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Repubmark
|
4
|
+
module Elems
|
5
|
+
class Text < Base
|
6
|
+
parents :Joint
|
7
|
+
|
8
|
+
def initialize(parent, str, bold: false, italic: false)
|
9
|
+
super parent
|
10
|
+
|
11
|
+
self.str = str
|
12
|
+
|
13
|
+
@bold = !!bold
|
14
|
+
@italic = !!italic
|
15
|
+
end
|
16
|
+
|
17
|
+
#################
|
18
|
+
# Basic methods #
|
19
|
+
#################
|
20
|
+
|
21
|
+
def word_count = count_words @str
|
22
|
+
|
23
|
+
def to_summary_plain = @str
|
24
|
+
|
25
|
+
def to_html = str_to_html
|
26
|
+
|
27
|
+
def to_gemtext = @str
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def str=(str)
|
32
|
+
@str = String(str).split.join(' ').freeze
|
33
|
+
end
|
34
|
+
|
35
|
+
def str_to_html
|
36
|
+
result = @str
|
37
|
+
result = "<em>#{result}</em>" if @italic
|
38
|
+
result = "<strong>#{result}</strong>" if @bold
|
39
|
+
result.freeze
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Repubmark
|
4
|
+
class Highlight
|
5
|
+
NO_SYNTAX = 'txt'
|
6
|
+
|
7
|
+
NO_LINE_NUMBERS = %i[sh_hist].freeze
|
8
|
+
|
9
|
+
SYNTAXES = {
|
10
|
+
certbot: 'ini',
|
11
|
+
css: 'css',
|
12
|
+
hjson: nil,
|
13
|
+
html: 'html',
|
14
|
+
ini: 'ini',
|
15
|
+
knockd: nil,
|
16
|
+
nginx: 'nginx',
|
17
|
+
openssh: nil,
|
18
|
+
ruby: 'ruby',
|
19
|
+
sh_hist: nil,
|
20
|
+
sysctl: nil,
|
21
|
+
torrc: nil,
|
22
|
+
wireguard: 'ini',
|
23
|
+
yggdrasil: nil, # Hjson
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
private_class_method :new
|
27
|
+
|
28
|
+
def self.call(...) = new(...).call
|
29
|
+
|
30
|
+
attr_reader :syntax, :str
|
31
|
+
|
32
|
+
def initialize(syntax, str)
|
33
|
+
self.syntax = syntax
|
34
|
+
self.str = str
|
35
|
+
end
|
36
|
+
|
37
|
+
def call
|
38
|
+
Open3.popen2(*cmdline) do |stdin, stdout, wait_thr|
|
39
|
+
stdin.write str
|
40
|
+
stdin.close
|
41
|
+
result = stdout.read.freeze
|
42
|
+
raise 'Highlight error' unless wait_thr.value.success?
|
43
|
+
|
44
|
+
"<pre><code>#{result}</code></pre>\n".freeze
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def syntax=(syntax)
|
51
|
+
return @syntax = nil if syntax.nil?
|
52
|
+
|
53
|
+
unless syntax.instance_of? Symbol
|
54
|
+
raise TypeError, "Expected #{Symbol}, got #{syntax.class}"
|
55
|
+
end
|
56
|
+
|
57
|
+
SYNTAXES.fetch syntax
|
58
|
+
|
59
|
+
@syntax = syntax
|
60
|
+
end
|
61
|
+
|
62
|
+
def str=(str)
|
63
|
+
str = String(str).strip.freeze
|
64
|
+
raise 'Expected non-empty string' if str.empty?
|
65
|
+
|
66
|
+
@str = str
|
67
|
+
end
|
68
|
+
|
69
|
+
def cmdline
|
70
|
+
@cmdline ||= [
|
71
|
+
'highlight',
|
72
|
+
'--stdout',
|
73
|
+
'--fragment',
|
74
|
+
'--out-format',
|
75
|
+
'html',
|
76
|
+
'--syntax',
|
77
|
+
SYNTAXES[syntax] || NO_SYNTAX,
|
78
|
+
].tap do |cmdline|
|
79
|
+
unless syntax.nil? || NO_LINE_NUMBERS.include?(syntax)
|
80
|
+
cmdline << '--line-numbers'
|
81
|
+
end
|
82
|
+
end.freeze
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/repubmark.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'date'
|
5
|
+
require 'forwardable'
|
6
|
+
require 'open3'
|
7
|
+
require 'pathname'
|
8
|
+
require 'uri'
|
9
|
+
require 'yaml'
|
10
|
+
|
11
|
+
require 'addressable'
|
12
|
+
|
13
|
+
require_relative 'repubmark/config'
|
14
|
+
require_relative 'repubmark/highlight'
|
15
|
+
require_relative 'repubmark/titled_ref'
|
16
|
+
|
17
|
+
require_relative 'repubmark/elems/base'
|
18
|
+
|
19
|
+
# Top-level element
|
20
|
+
require_relative 'repubmark/elems/article'
|
21
|
+
|
22
|
+
# Always inside Article
|
23
|
+
require_relative 'repubmark/elems/annotation'
|
24
|
+
require_relative 'repubmark/elems/footnotes_category'
|
25
|
+
# Always inside Article, Chapter
|
26
|
+
require_relative 'repubmark/elems/chapter'
|
27
|
+
# Always inside Annotation, Blockquote, Chapter
|
28
|
+
require_relative 'repubmark/elems/canvas'
|
29
|
+
|
30
|
+
# Always inside Canvas
|
31
|
+
require_relative 'repubmark/elems/blockquote'
|
32
|
+
require_relative 'repubmark/elems/code_block'
|
33
|
+
require_relative 'repubmark/elems/figures'
|
34
|
+
require_relative 'repubmark/elems/iframe'
|
35
|
+
require_relative 'repubmark/elems/paragraph'
|
36
|
+
require_relative 'repubmark/elems/separator'
|
37
|
+
|
38
|
+
# Always inside Canvas, Figures
|
39
|
+
require_relative 'repubmark/elems/figure'
|
40
|
+
# Always inside Canvas, ListItem
|
41
|
+
require_relative 'repubmark/elems/list'
|
42
|
+
# Always inside List
|
43
|
+
require_relative 'repubmark/elems/list_item'
|
44
|
+
|
45
|
+
# Always inside Caption, Quote
|
46
|
+
require_relative 'repubmark/elems/joint'
|
47
|
+
# Always inside Blockquote, Figure, Footnote, ListItem, Paragraph
|
48
|
+
require_relative 'repubmark/elems/caption'
|
49
|
+
# Always inside Caption, Joint, Quote
|
50
|
+
require_relative 'repubmark/elems/quote'
|
51
|
+
|
52
|
+
# Always inside Joint
|
53
|
+
require_relative 'repubmark/elems/abbrev'
|
54
|
+
require_relative 'repubmark/elems/code_inline'
|
55
|
+
require_relative 'repubmark/elems/fraction'
|
56
|
+
require_relative 'repubmark/elems/note'
|
57
|
+
require_relative 'repubmark/elems/section'
|
58
|
+
require_relative 'repubmark/elems/special'
|
59
|
+
require_relative 'repubmark/elems/text'
|
60
|
+
require_relative 'repubmark/elems/link'
|
61
|
+
require_relative 'repubmark/elems/power'
|
62
|
+
|
63
|
+
# Always inside FootnotesCategory
|
64
|
+
require_relative 'repubmark/elems/footnote'
|
65
|
+
|
66
|
+
##
|
67
|
+
# A Markdown-inspired markup language that can be compiled into HTML and
|
68
|
+
# Gemtext.
|
69
|
+
#
|
70
|
+
module Repubmark
|
71
|
+
FORMATS = %i[chapters gemtext html summary_plain word_count].freeze
|
72
|
+
|
73
|
+
SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/
|
74
|
+
|
75
|
+
UNICODE_SUPS = {
|
76
|
+
'0' => '⁰',
|
77
|
+
'1' => '¹',
|
78
|
+
'2' => '²',
|
79
|
+
'3' => '³',
|
80
|
+
'4' => '⁴',
|
81
|
+
'5' => '⁵',
|
82
|
+
'6' => '⁶',
|
83
|
+
'7' => '⁷',
|
84
|
+
'8' => '⁸',
|
85
|
+
'9' => '⁹',
|
86
|
+
'+' => '⁺',
|
87
|
+
'-' => '⁻',
|
88
|
+
'=' => '⁼',
|
89
|
+
'(' => '⁽',
|
90
|
+
')' => '⁾',
|
91
|
+
}.freeze
|
92
|
+
|
93
|
+
UNICODE_SUBS = {
|
94
|
+
'0' => '₀',
|
95
|
+
'1' => '₁',
|
96
|
+
'2' => '₂',
|
97
|
+
'3' => '₃',
|
98
|
+
'4' => '₄',
|
99
|
+
'5' => '₅',
|
100
|
+
'6' => '₆',
|
101
|
+
'7' => '₇',
|
102
|
+
'8' => '₈',
|
103
|
+
'9' => '₉',
|
104
|
+
'+' => '₊',
|
105
|
+
'-' => '₋',
|
106
|
+
'=' => '₌',
|
107
|
+
'(' => '₍',
|
108
|
+
')' => '₎',
|
109
|
+
}.freeze
|
110
|
+
|
111
|
+
def self.validate_slug!(slug)
|
112
|
+
slug = String(slug).freeze
|
113
|
+
raise 'Invalid slug' unless SLUG_RE.match? slug
|
114
|
+
|
115
|
+
slug
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.unicode_sup(val)
|
119
|
+
String(val).each_char.map { |chr| UNICODE_SUPS.fetch chr }.join.freeze
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.unicode_sub(val)
|
123
|
+
String(val).each_char.map { |chr| UNICODE_SUBS.fetch chr }.join.freeze
|
124
|
+
end
|
125
|
+
end
|
data/tests/examples.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'open3'
|
5
|
+
|
6
|
+
ROOT = File.expand_path('..', __dir__).freeze
|
7
|
+
|
8
|
+
EXE = File.expand_path('exe/repubmark', ROOT).freeze
|
9
|
+
EXAMPLES = File.expand_path('examples', ROOT).freeze
|
10
|
+
EXAMPLES_GLOB = File.expand_path('examples/*.repub', ROOT).freeze
|
11
|
+
CONFIG = File.expand_path('examples/config.yml', ROOT).freeze
|
12
|
+
|
13
|
+
PROFILES = [
|
14
|
+
%w[summary_plain summary.txt],
|
15
|
+
%w[http html],
|
16
|
+
%w[gemini gmi],
|
17
|
+
%w[chapters chapters.json],
|
18
|
+
].map(&:freeze).freeze
|
19
|
+
|
20
|
+
Dir[EXAMPLES_GLOB].each do |example_filename|
|
21
|
+
example = File.read example_filename
|
22
|
+
PROFILES.each do |profile_name, expected_ext|
|
23
|
+
expected_filename = "#{example_filename[...-6]}.#{expected_ext}"
|
24
|
+
expected = File.read expected_filename
|
25
|
+
|
26
|
+
puts '=' * 80
|
27
|
+
puts "Config: #{CONFIG}"
|
28
|
+
puts "Example: #{example_filename}"
|
29
|
+
puts "Profile: #{profile_name}"
|
30
|
+
puts "Expected: #{expected_filename}"
|
31
|
+
puts '-' * 80
|
32
|
+
puts example.strip
|
33
|
+
puts '-' * 80
|
34
|
+
puts expected.strip
|
35
|
+
|
36
|
+
stdin, stdout, wait_thr = Open3.popen2 EXE, CONFIG, profile_name
|
37
|
+
stdin.puts example
|
38
|
+
stdin.close
|
39
|
+
result = stdout.read
|
40
|
+
stdout.close
|
41
|
+
raise 'Template engine error' unless wait_thr.value.success?
|
42
|
+
next if result == expected
|
43
|
+
|
44
|
+
puts '-' * 80
|
45
|
+
puts result.strip
|
46
|
+
puts '=' * 80
|
47
|
+
raise 'Invalid output'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
puts '=' * 80
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: repubmark
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Kotov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.14'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.14'
|
41
|
+
description: A Markdown-inspired markup language that can be compiled into HTML and
|
42
|
+
Gemtext
|
43
|
+
email:
|
44
|
+
- me+repubmark@kotovalexarian.com
|
45
|
+
executables:
|
46
|
+
- repubmark
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".rubocop.yml"
|
51
|
+
- ".rubocop_todo.yml"
|
52
|
+
- ".yardopts"
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- examples/config.yml
|
57
|
+
- examples/full.chapters.json
|
58
|
+
- examples/full.gmi
|
59
|
+
- examples/full.html
|
60
|
+
- examples/full.repub
|
61
|
+
- examples/full.summary.txt
|
62
|
+
- examples/hello.chapters.json
|
63
|
+
- examples/hello.gmi
|
64
|
+
- examples/hello.html
|
65
|
+
- examples/hello.repub
|
66
|
+
- examples/hello.summary.txt
|
67
|
+
- exe/repubmark
|
68
|
+
- lib/repubmark.rb
|
69
|
+
- lib/repubmark/config.rb
|
70
|
+
- lib/repubmark/elems/abbrev.rb
|
71
|
+
- lib/repubmark/elems/annotation.rb
|
72
|
+
- lib/repubmark/elems/article.rb
|
73
|
+
- lib/repubmark/elems/base.rb
|
74
|
+
- lib/repubmark/elems/blockquote.rb
|
75
|
+
- lib/repubmark/elems/canvas.rb
|
76
|
+
- lib/repubmark/elems/caption.rb
|
77
|
+
- lib/repubmark/elems/chapter.rb
|
78
|
+
- lib/repubmark/elems/code_block.rb
|
79
|
+
- lib/repubmark/elems/code_inline.rb
|
80
|
+
- lib/repubmark/elems/figure.rb
|
81
|
+
- lib/repubmark/elems/figures.rb
|
82
|
+
- lib/repubmark/elems/footnote.rb
|
83
|
+
- lib/repubmark/elems/footnotes_category.rb
|
84
|
+
- lib/repubmark/elems/fraction.rb
|
85
|
+
- lib/repubmark/elems/iframe.rb
|
86
|
+
- lib/repubmark/elems/joint.rb
|
87
|
+
- lib/repubmark/elems/link.rb
|
88
|
+
- lib/repubmark/elems/list.rb
|
89
|
+
- lib/repubmark/elems/list_item.rb
|
90
|
+
- lib/repubmark/elems/note.rb
|
91
|
+
- lib/repubmark/elems/paragraph.rb
|
92
|
+
- lib/repubmark/elems/power.rb
|
93
|
+
- lib/repubmark/elems/quote.rb
|
94
|
+
- lib/repubmark/elems/section.rb
|
95
|
+
- lib/repubmark/elems/separator.rb
|
96
|
+
- lib/repubmark/elems/special.rb
|
97
|
+
- lib/repubmark/elems/text.rb
|
98
|
+
- lib/repubmark/highlight.rb
|
99
|
+
- lib/repubmark/titled_ref.rb
|
100
|
+
- lib/repubmark/version.rb
|
101
|
+
- tests/examples.rb
|
102
|
+
homepage: https://git.causa-arcana.com/causa-arcana/repubmark
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata:
|
106
|
+
rubygems_mfa_required: 'true'
|
107
|
+
homepage_uri: https://git.causa-arcana.com/causa-arcana/repubmark
|
108
|
+
source_code_uri: https://git.causa-arcana.com/causa-arcana/repubmark
|
109
|
+
documentation_uri: https://www.rubydoc.info/gems/repubmark/0.0.0
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.2'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubygems_version: 3.4.19
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: A Markdown-inspired markup language that can be compiled into HTML and Gemtext
|
129
|
+
test_files: []
|