marko 0.1.0 → 0.4.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 +4 -4
- data/.dockerignore +12 -0
- data/.rubocop.yml +45 -0
- data/CHANGELOG.md +54 -1
- data/Dockerfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +24 -35
- data/Rakefile +2 -6
- data/exe/marko +4 -20
- data/lib/basic.rb +27 -0
- data/lib/marko/chain.rb +44 -0
- data/lib/marko/cli.rb +119 -121
- data/lib/marko/config.rb +30 -20
- data/lib/marko/errors.rb +38 -0
- data/lib/marko/model/markup.rb +33 -0
- data/lib/marko/model/topic.rb +126 -0
- data/lib/marko/model/tree_node.rb +34 -0
- data/lib/marko/model.rb +10 -0
- data/lib/marko/parser/metadata.rb +28 -0
- data/lib/marko/parser/source.rb +52 -0
- data/lib/marko/parser/topic.rb +33 -0
- data/lib/marko/parser.rb +8 -19
- data/lib/marko/renderers/artifact.rb +29 -0
- data/lib/marko/renderers/content.rb +37 -0
- data/lib/marko/renderers/link.rb +19 -0
- data/lib/marko/renderers/metadata.rb +34 -0
- data/lib/marko/renderers/nested_list.rb +21 -0
- data/lib/marko/renderers/nested_tree.rb +22 -0
- data/lib/marko/renderers/renderer.rb +17 -0
- data/lib/marko/renderers/title.rb +16 -0
- data/lib/marko/renderers/topic.rb +24 -0
- data/lib/marko/renderers/url.rb +16 -0
- data/lib/marko/renderers.rb +17 -0
- data/lib/marko/scanner.rb +39 -0
- data/lib/marko/tasks/assemble.rb +52 -0
- data/lib/marko/tasks/compile.rb +19 -0
- data/lib/marko/tasks/load.rb +13 -0
- data/lib/marko/tasks/parse.rb +27 -0
- data/lib/marko/tasks/scan.rb +18 -0
- data/lib/marko/tasks/validate.rb +32 -0
- data/lib/marko/tasks.rb +13 -0
- data/lib/marko/validators/lost_index.rb +21 -0
- data/lib/marko/validators/lost_links.rb +25 -0
- data/lib/marko/validators/lost_parent.rb +21 -0
- data/lib/marko/validators/non_unique_id.rb +23 -0
- data/lib/marko/validators.rb +11 -0
- data/lib/marko/version.rb +1 -3
- data/lib/marko.rb +11 -35
- metadata +47 -54
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -22
- data/lib/assets/demo/README.md +0 -13
- data/lib/assets/demo/src/fr/assemble.md +0 -27
- data/lib/assets/demo/src/fr/compile.md +0 -25
- data/lib/assets/demo/src/fr/markup.md +0 -111
- data/lib/assets/demo/src/fr/storage.md +0 -16
- data/lib/assets/demo/src/fr/treenode.md +0 -34
- data/lib/assets/demo/src/index.md +0 -34
- data/lib/assets/demo/src/intro.md +0 -98
- data/lib/assets/demo/src/ui/cli.md +0 -26
- data/lib/assets/demo/src/ui/gem.md +0 -14
- data/lib/assets/demo/src/ur/uc.create.project.md +0 -8
- data/lib/assets/demo/src/ur/uc.general.flow.md +0 -14
- data/lib/assets/init/README.md +0 -61
- data/lib/assets/init/Rakefile +0 -100
- data/lib/assets/init/tt/artifact.md.tt +0 -3
- data/lib/marko/artifact.rb +0 -3
- data/lib/marko/assembler.rb +0 -82
- data/lib/marko/compiler.rb +0 -16
- data/lib/marko/gadgets/pluggable.rb +0 -55
- data/lib/marko/gadgets/sentry.rb +0 -66
- data/lib/marko/gadgets/service.rb +0 -52
- data/lib/marko/gadgets.rb +0 -3
- data/lib/marko/loader.rb +0 -38
- data/lib/marko/markup/compiler.rb +0 -36
- data/lib/marko/markup/decorator.rb +0 -65
- data/lib/marko/markup/macro.rb +0 -176
- data/lib/marko/markup/parser.rb +0 -122
- data/lib/marko/markup/storage.rb +0 -100
- data/lib/marko/markup/validator.rb +0 -101
- data/lib/marko/markup.rb +0 -24
- data/lib/marko/services/assemble.rb +0 -16
- data/lib/marko/services/compile.rb +0 -30
- data/lib/marko/services.rb +0 -2
- data/lib/marko/storage.rb +0 -36
- data/lib/marko/tree_node.rb +0 -128
- data/lib/marko/validator.rb +0 -19
- data/marko.gemspec +0 -44
@@ -1,101 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../validator"
|
4
|
-
|
5
|
-
module Marko
|
6
|
-
module Markup
|
7
|
-
class Validator < Marko::Validator
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@inspectors = []
|
11
|
-
@inspectors << TheSameId.new
|
12
|
-
@inspectors << LostParent.new
|
13
|
-
@inspectors << LostIndex.new
|
14
|
-
@inspectors << LostLink.new
|
15
|
-
end
|
16
|
-
|
17
|
-
# see Marko::Validator#call
|
18
|
-
def call(tree)
|
19
|
-
[].tap{|errors|
|
20
|
-
@inspectors.each{|spectr| errors.concat(spectr.(tree)) }
|
21
|
-
}
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
class Inspector
|
27
|
-
def call(tree)
|
28
|
-
select(tree).then{ report(_1) }
|
29
|
-
end
|
30
|
-
|
31
|
-
def select(tree)
|
32
|
-
fail "the abstract method must be overriden"
|
33
|
-
end
|
34
|
-
|
35
|
-
def report(errs)
|
36
|
-
fail "the abstract method must be overriden"
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
class TheSameId < Inspector
|
42
|
-
def select(tree)
|
43
|
-
fn = proc{|n, memo| memo[n.id] ||= []; memo[n.id] << n}
|
44
|
-
tree
|
45
|
-
.each_with_object({}, &fn)
|
46
|
-
.select{|_, v| v.size > 1}
|
47
|
-
end
|
48
|
-
|
49
|
-
def report(errs)
|
50
|
-
# the same id [ref] found twice
|
51
|
-
# src/source2.md:22 >> ## header
|
52
|
-
# src/source3.md:11 >> ## header
|
53
|
-
errs.map{|id, nodes|
|
54
|
-
sources = nodes.map{|n| " #{n[:origin]}\n"}.join
|
55
|
-
"the same id [#{id}] found in\n#{sources}"
|
56
|
-
}
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class LostParent < Inspector
|
61
|
-
def select(tree)
|
62
|
-
tree.select{|n| n[:parent] && n.parent_id != n[:parent]}
|
63
|
-
end
|
64
|
-
|
65
|
-
def report(errs)
|
66
|
-
# lost parent [ref] src/source2.md:22 >> ## header
|
67
|
-
errs.map{|n| "lost parent [#{n[:parent]}] found in #{n[:origin]}\n"}
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class LostIndex < Inspector
|
72
|
-
def select(tree)
|
73
|
-
lost = proc{|n| n.order_index.reject{|i| n.find_item(i)}}
|
74
|
-
tree
|
75
|
-
.select{|n| n.order_index.any? && lost.(n).any?}
|
76
|
-
.map{|n| [n[:origin], lost.(n)]} # @todo second time calculation
|
77
|
-
end
|
78
|
-
|
79
|
-
def report(errs)
|
80
|
-
# lost index [a, b] src/source2.md:22 >> ## header
|
81
|
-
errs.map{|orig, lost| "lost index [#{lost.join(', ')}] in #{orig}\n" }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
class LostLink < Inspector
|
86
|
-
def select(tree)
|
87
|
-
lost = proc{|n| n.links.reject{|i| n.find_node(i)}}
|
88
|
-
tree
|
89
|
-
.select{|n| lost.(n).any? }
|
90
|
-
.map{|n| [n[:origin], lost.(n)]} # @todo second time #lost calculation
|
91
|
-
end
|
92
|
-
|
93
|
-
# @todo report link line number in the origin
|
94
|
-
def report(errs)
|
95
|
-
# lost links [ref] src/source2.md:22 >> ## header
|
96
|
-
errs.map{|orig, lost| "lost link [#{lost.join(', ')}] in #{orig}\n"}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
data/lib/marko/markup.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require_relative "markup/parser"
|
2
|
-
require_relative "markup/storage"
|
3
|
-
require_relative "markup/validator"
|
4
|
-
require_relative "markup/macro"
|
5
|
-
require_relative "markup/decorator"
|
6
|
-
require_relative "markup/compiler"
|
7
|
-
require_relative "config"
|
8
|
-
|
9
|
-
|
10
|
-
module Marko
|
11
|
-
|
12
|
-
ParserPlug.plug Markup::Parser
|
13
|
-
StoragePlug.plug Markup::Storage
|
14
|
-
CompilerPlug.plug Markup::Compiler
|
15
|
-
ValidatorPlug.plug Markup::Validator
|
16
|
-
|
17
|
-
# ParserPlug = Markup::Parser.plug
|
18
|
-
# StoragePlug = Markup::Storage.plug
|
19
|
-
# @todo let Decorator know
|
20
|
-
MacroProcPlug = Markup::MacroProcessor.plug
|
21
|
-
# ValidatorPlug = Markup::Validator.plug
|
22
|
-
# CompilerPlug = Markup::Compiler.plug
|
23
|
-
|
24
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require_relative "../gadgets"
|
2
|
-
require_relative "../assembler"
|
3
|
-
|
4
|
-
module Marko
|
5
|
-
module Services
|
6
|
-
|
7
|
-
# Assemblage service
|
8
|
-
# @todo assemble projects bu url
|
9
|
-
class Assemble < Service
|
10
|
-
def call
|
11
|
-
Assembler.(&@block)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require_relative "../gadgets"
|
2
|
-
require_relative "../assembler"
|
3
|
-
|
4
|
-
module Marko
|
5
|
-
module Services
|
6
|
-
|
7
|
-
# Compitation service
|
8
|
-
class Compile < Service
|
9
|
-
def initialize(tree: nil, template: '', filename: '', &block)
|
10
|
-
@tree = MustbeTreeNode.(tree) if tree
|
11
|
-
@template = MustbeString.(template)
|
12
|
-
@filename = MustbeString.(filename)
|
13
|
-
@block = block
|
14
|
-
|
15
|
-
art = Marko.artifact
|
16
|
-
@template = art.template if @template.empty?
|
17
|
-
@filename = art.filename if @filename.empty?
|
18
|
-
end
|
19
|
-
|
20
|
-
def call
|
21
|
-
storage = StoragePlug.plugged
|
22
|
-
compiler = CompilerPlug.plugged
|
23
|
-
erb = storage.content(@template)
|
24
|
-
@tree = Assembler.(&@block) unless @tree
|
25
|
-
compiler.(@tree, erb, @filename, &@block) # => filename
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
data/lib/marko/services.rb
DELETED
data/lib/marko/storage.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "gadgets"
|
4
|
-
require_relative "artifact"
|
5
|
-
|
6
|
-
module Marko
|
7
|
-
|
8
|
-
# The base class that represents sources repository
|
9
|
-
class Storage
|
10
|
-
extend Pluggable
|
11
|
-
|
12
|
-
# create a new repository
|
13
|
-
# @param repository [String] the name for the repository
|
14
|
-
def punch(repository)
|
15
|
-
fail "the abstract method must be overriden"
|
16
|
-
end
|
17
|
-
|
18
|
-
# @retrun [Array<String>] array of sources inside the repository
|
19
|
-
def sources
|
20
|
-
fail "the abstract method must be overriden"
|
21
|
-
end
|
22
|
-
|
23
|
-
# @param source [Striing] source to retrieve content
|
24
|
-
# @return [String] content of :source
|
25
|
-
def content(source)
|
26
|
-
fail "the abstract method must be overriden"
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [Artifact] artifact settings
|
30
|
-
def artifact
|
31
|
-
fail "the abstract method must be overriden"
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
data/lib/marko/tree_node.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "forwardable"
|
4
|
-
require_relative "gadgets"
|
5
|
-
|
6
|
-
module Marko
|
7
|
-
|
8
|
-
MustbeString = Sentry.new(:key, "must be String"
|
9
|
-
) {|v| v.is_a? String}
|
10
|
-
|
11
|
-
MustbeTreeNode = Sentry.new(:key, "must be TreeNode"
|
12
|
-
) {|v| v.is_a? TreeNode}
|
13
|
-
|
14
|
-
class TreeNode
|
15
|
-
extend Forwardable
|
16
|
-
include Enumerable
|
17
|
-
|
18
|
-
attr_reader :parent
|
19
|
-
attr_reader :title
|
20
|
-
attr_reader :meta
|
21
|
-
attr_reader :body
|
22
|
-
|
23
|
-
def_delegators :@meta, :[], :[]=
|
24
|
-
def_delegator :@items, :last
|
25
|
-
def_delegator :@items, :delete, :delete_item
|
26
|
-
def_delegator :@meta, :delete, :delete_meta
|
27
|
-
def_delegator :@parent, :id, :parent_id
|
28
|
-
|
29
|
-
def initialize(title = '', body = '', **meta)
|
30
|
-
@parent, @items = nil, []
|
31
|
-
@title = MustbeString.(title, :title)
|
32
|
-
@body = MustbeString.(body, :body)
|
33
|
-
@meta = meta
|
34
|
-
@meta[:id] = '' unless @meta[:id]
|
35
|
-
end
|
36
|
-
|
37
|
-
def <<(node)
|
38
|
-
MustbeTreeNode.(node)
|
39
|
-
node.parent = self
|
40
|
-
@items << node
|
41
|
-
node
|
42
|
-
end
|
43
|
-
|
44
|
-
# see Enumerable#each
|
45
|
-
def each(&block)
|
46
|
-
return to_enum(__callee__) unless block_given?
|
47
|
-
yield(self)
|
48
|
-
items.each{|n| n.each(&block) }
|
49
|
-
end
|
50
|
-
|
51
|
-
# @return [Array<String>]
|
52
|
-
def order_index
|
53
|
-
@meta
|
54
|
-
.fetch(:order_index, '')
|
55
|
-
.strip
|
56
|
-
.split(/\s{1,}/)
|
57
|
-
end
|
58
|
-
|
59
|
-
def id
|
60
|
-
val = @meta.fetch(:id, '')
|
61
|
-
return val unless @parent
|
62
|
-
val.start_with?('.') ? @parent.id + val : val
|
63
|
-
end
|
64
|
-
|
65
|
-
def find_item(ref)
|
66
|
-
@items.find{|n| n.id == ref || n.id.end_with?(ref)}
|
67
|
-
end
|
68
|
-
|
69
|
-
def find_node(ref)
|
70
|
-
return find_item(ref) if ref.start_with?(?.)
|
71
|
-
root.find{|n| n.id == ref}
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [Array<Node>] ordered list of child nodes
|
75
|
-
def items
|
76
|
-
return @items unless order_index.any?
|
77
|
-
[].tap do |ary|
|
78
|
-
src = Array.new(@items)
|
79
|
-
order_index.each do |i|
|
80
|
-
node = find_item(i)
|
81
|
-
ary << src.delete(node) if node
|
82
|
-
end
|
83
|
-
ary.concat(src)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def belongs_to?(ref)
|
88
|
-
owner = root.find{|n| n.id == ref}
|
89
|
-
self == owner&.find{|n| n == self}
|
90
|
-
end
|
91
|
-
|
92
|
-
# @return [Node] the root node in the node hierarchy
|
93
|
-
def root
|
94
|
-
n = self
|
95
|
-
n = n.parent while n.parent
|
96
|
-
n
|
97
|
-
end
|
98
|
-
|
99
|
-
def root?
|
100
|
-
self == root
|
101
|
-
end
|
102
|
-
|
103
|
-
# @return [Integer] the node level in the node hierarchy
|
104
|
-
def nesting_level
|
105
|
-
@parent.nil? ? 0 : @parent.nesting_level + 1
|
106
|
-
end
|
107
|
-
|
108
|
-
# @return [Array<String>] macro links in the node #body IT IS RATHER MACRO FOR WRITER SO TI SHOULD BE PROCESSED APPROPRIATELY
|
109
|
-
def links
|
110
|
-
return [] if @body.empty?
|
111
|
-
@body.scan(/\[\[([\w\.]*)\]\]/).flatten.uniq
|
112
|
-
end
|
113
|
-
|
114
|
-
def orphan!
|
115
|
-
return unless @parent
|
116
|
-
@parent.delete_item(self)
|
117
|
-
@parent = nil
|
118
|
-
end
|
119
|
-
|
120
|
-
protected
|
121
|
-
|
122
|
-
def parent=(node)
|
123
|
-
@parent = MustbeTreeNode.(node)
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
data/lib/marko/validator.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "tree_node"
|
4
|
-
|
5
|
-
module Marko
|
6
|
-
|
7
|
-
# The strategy of tree validation
|
8
|
-
class Validator
|
9
|
-
extend Pluggable
|
10
|
-
|
11
|
-
# @param tree [TreeNode]
|
12
|
-
# @param block [&block] proc {|event, payload|}
|
13
|
-
# @return [Array<String>] errors array
|
14
|
-
def call(tree, &block)
|
15
|
-
fail "the abstract method must be overriden"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
data/marko.gemspec
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/marko/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "marko"
|
7
|
-
spec.version = Marko::VERSION
|
8
|
-
spec.authors = ["Nikolay Voynov"]
|
9
|
-
spec.email = ["nvoynov@gmail.com"]
|
10
|
-
|
11
|
-
spec.summary = "Marko is a markup compiler that builds a tree from separated markup sources and compiles it into a deliverable artifact."
|
12
|
-
|
13
|
-
spec.description = <<~EOF
|
14
|
-
Marko supplies a "docs-as-code" approach for compiling bulky software artifacts by providing source storage, original plain text markup, compiler templates, command-line and Gem interfaces.
|
15
|
-
|
16
|
-
Having the assembled artifact, it can be analyzed, enriched by extra data, served as a source for deriving subdued artifacts, etc.
|
17
|
-
EOF
|
18
|
-
|
19
|
-
spec.homepage = "https://github.com/nvoynov/marko"
|
20
|
-
spec.required_ruby_version = ">= 2.6.0"
|
21
|
-
|
22
|
-
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
23
|
-
|
24
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
25
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
26
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
|
27
|
-
|
28
|
-
# Specify which files should be added to the gem when it is released.
|
29
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
|
-
spec.files = Dir.chdir(__dir__) do
|
31
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
32
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
|
33
|
-
end
|
34
|
-
end
|
35
|
-
spec.bindir = "exe"
|
36
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
37
|
-
spec.require_paths = ["lib"]
|
38
|
-
|
39
|
-
# Uncomment to register a new dependency of your gem
|
40
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
41
|
-
|
42
|
-
# For more information and examples about making a new gem, check out our
|
43
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
44
|
-
end
|