middleman-mdocs 0.1.0.62562 → 0.1.1.75132
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -4
- data/Gemfile.lock +11 -11
- data/README.md +15 -1
- data/bin/console +3 -1
- data/lib/middleman-mdocs/controller.rb +108 -29
- data/lib/middleman-mdocs/deps.rb +12 -0
- data/lib/middleman-mdocs/extension.rb +81 -27
- data/lib/middleman-mdocs/navigation.rb +34 -11
- data/lib/middleman-mdocs/resource.rb +177 -33
- data/lib/middleman-mdocs/tilt_template.rb +1 -1
- data/lib/middleman-mdocs/toc.rb +4 -1
- data/lib/middleman-mdocs/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af19925233fb69d9d19cfbe262c89297ff40c6a8e39aa1ae539169f51d6bca44
|
4
|
+
data.tar.gz: 01afb1fc1310d5d8c079d7867148c6d63379576ed3eda72570204b25ce6125fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb2973c1d9f864587bec83396145c3a14b5df05d11b8478b84ec5d5e8d5cedafe0ba2e643cea6286cbf7e4a1a93d4affefa007dba8012bf7e486e2613daf43bd
|
7
|
+
data.tar.gz: 05a90cf5c51a1b2f29967755082a80e2b5fe2be299724ce322adb172c97cd070b98936fa586db37745535dbb01544760abe3c6398f99b6cf4130d53c4eb5136e
|
data/Gemfile
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in mdocs.gemspec
|
6
|
-
gemspec
|
7
|
-
|
8
5
|
gem 'rake', '~> 13.0'
|
9
|
-
gem 'simplecov', '~> 0.21'
|
10
6
|
gem 'rspec', '~> 3.10'
|
11
7
|
gem 'rspec_junit_formatter', '~> 0.4'
|
8
|
+
gem 'simplecov', '~> 0.21'
|
12
9
|
gem 'simplecov-console'
|
13
10
|
|
14
11
|
gem 'rubocop', require: false
|
12
|
+
|
13
|
+
# Specify your gem's dependencies in mdocs.gemspec
|
14
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
middleman-mdocs (0.1.
|
4
|
+
middleman-mdocs (0.1.1.75132)
|
5
5
|
activesupport
|
6
6
|
awesome_print
|
7
7
|
kramdown
|
@@ -26,12 +26,12 @@ GEM
|
|
26
26
|
addressable (2.8.0)
|
27
27
|
public_suffix (>= 2.0.2, < 5.0)
|
28
28
|
ansi (1.5.0)
|
29
|
-
asciidoctor (2.0.
|
29
|
+
asciidoctor (2.0.17)
|
30
30
|
asciidoctor-plantuml (0.0.12)
|
31
31
|
asciidoctor (>= 1.5.6, < 3.0.0)
|
32
32
|
ast (2.4.2)
|
33
33
|
awesome_print (1.9.2)
|
34
|
-
backports (3.
|
34
|
+
backports (3.23.0)
|
35
35
|
coffee-script (2.4.1)
|
36
36
|
coffee-script-source
|
37
37
|
execjs
|
@@ -45,8 +45,8 @@ GEM
|
|
45
45
|
execjs (2.8.1)
|
46
46
|
exifr (1.3.9)
|
47
47
|
fast_blank (1.0.1)
|
48
|
-
fastimage (2.2.
|
49
|
-
ffi (1.15.
|
48
|
+
fastimage (2.2.6)
|
49
|
+
ffi (1.15.5)
|
50
50
|
fspath (3.1.2)
|
51
51
|
gitlab_kramdown (0.10.0)
|
52
52
|
asciidoctor-plantuml (= 0.0.12)
|
@@ -71,14 +71,14 @@ GEM
|
|
71
71
|
fspath (>= 2.1, < 4)
|
72
72
|
image_optim (~> 0.19)
|
73
73
|
image_size (1.5.0)
|
74
|
-
in_threads (1.
|
74
|
+
in_threads (1.6.0)
|
75
75
|
kramdown (2.3.1)
|
76
76
|
rexml
|
77
77
|
libv8 (3.16.14.19-x86_64-linux)
|
78
78
|
listen (3.0.8)
|
79
79
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
80
80
|
rb-inotify (~> 0.9, >= 0.9.7)
|
81
|
-
mdocs_kramdown (0.1.
|
81
|
+
mdocs_kramdown (0.1.2.70482)
|
82
82
|
gitlab_kramdown (~> 0)
|
83
83
|
memoist (0.16.2)
|
84
84
|
middleman (4.3.11)
|
@@ -122,7 +122,7 @@ GEM
|
|
122
122
|
nokogiri (~> 1.6)
|
123
123
|
therubyracer (~> 0.12.2)
|
124
124
|
mini_portile2 (2.4.0)
|
125
|
-
minitest (5.
|
125
|
+
minitest (5.15.0)
|
126
126
|
nokogiri (1.10.10)
|
127
127
|
mini_portile2 (~> 2.4.0)
|
128
128
|
padrino-helpers (0.13.3.4)
|
@@ -146,7 +146,7 @@ GEM
|
|
146
146
|
ref (2.0.0)
|
147
147
|
regexp_parser (2.1.1)
|
148
148
|
rexml (3.2.5)
|
149
|
-
rouge (3.
|
149
|
+
rouge (3.27.0)
|
150
150
|
rspec (3.10.0)
|
151
151
|
rspec-core (~> 3.10.0)
|
152
152
|
rspec-expectations (~> 3.10.0)
|
@@ -199,7 +199,7 @@ GEM
|
|
199
199
|
therubyracer (0.12.3)
|
200
200
|
libv8 (~> 3.16.14.15)
|
201
201
|
ref
|
202
|
-
thor (1.1
|
202
|
+
thor (1.2.1)
|
203
203
|
thread_safe (0.3.6)
|
204
204
|
tilt (2.0.10)
|
205
205
|
tzinfo (1.2.9)
|
@@ -221,4 +221,4 @@ DEPENDENCIES
|
|
221
221
|
simplecov-console
|
222
222
|
|
223
223
|
BUNDLED WITH
|
224
|
-
2.2.
|
224
|
+
2.2.28
|
data/README.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
1
|
# MiddlemanMdocs
|
2
2
|
|
3
|
-
|
3
|
+
Это шаблон для генерации статической документации. Он является расширением для проекта [Middleman](https://middlemanapp.com/) и включает некоторые улучшения и исправления.
|
4
|
+
|
5
|
+
## Запуск
|
6
|
+
|
7
|
+
В папке [template](./template) находится шаблон рабочего проекта. Фичи:
|
8
|
+
|
9
|
+
* поддержка `UTF-8`
|
10
|
+
* полнотекстовый поиск `lunr.js`
|
11
|
+
* Динамическое оглавление страницы
|
12
|
+
* `sitemap.txt` `robots.txt` `turbo.tss`
|
13
|
+
* `Yandex Metrika`
|
14
|
+
* `Open Graph` разметка
|
15
|
+
* метаданные `tags` и `keywords` для каждой страницы
|
16
|
+
* расширемые стили `bootstrap` с двумя темами
|
17
|
+
|
data/bin/console
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'bundler/setup'
|
5
|
-
require 'mdocs'
|
5
|
+
require 'middleman-mdocs'
|
6
|
+
require 'middleman-mdocs/extension'
|
7
|
+
require 'middleman-mdocs/deps'
|
6
8
|
|
7
9
|
# You can add fixtures and/or initialization code here to make experimenting
|
8
10
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -1,38 +1,101 @@
|
|
1
1
|
module MiddlemanMdocs
|
2
2
|
class Controller
|
3
|
-
attr_reader :nav, :sitemap, :app
|
3
|
+
attr_reader :nav, :extension, :sitemap, :app, :ready
|
4
|
+
|
5
|
+
include(::MiddlemanMdocs::TOC)
|
6
|
+
|
7
|
+
def initialize(extension)
|
8
|
+
@extension = extension
|
9
|
+
|
10
|
+
@app = extension.app
|
11
|
+
@sitemap = app.sitemap
|
4
12
|
|
5
|
-
def initialize(sitemap)
|
6
|
-
@sitemap = sitemap
|
7
|
-
@app = sitemap.app
|
8
13
|
@guards = {}
|
14
|
+
@dependencies = {}
|
15
|
+
@metadata = {}
|
16
|
+
@updated = SecureRandom.hex
|
17
|
+
@resources = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def register(resource)
|
21
|
+
if (old = @resources[resource.page_id])
|
22
|
+
resource.copy_from(old)
|
23
|
+
else
|
24
|
+
resource.copy_from(resource)
|
25
|
+
end
|
26
|
+
|
27
|
+
@resources[resource.page_id] = resource
|
28
|
+
end
|
29
|
+
|
30
|
+
def refresh
|
31
|
+
@updated = SecureRandom.hex
|
32
|
+
@ready = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def nav
|
36
|
+
with_cache(:nav) do
|
37
|
+
::MiddlemanMdocs::Navigation.parse(app.data.mdocs['nav'])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def ready?
|
42
|
+
@ready
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_dependency(resource, child)
|
46
|
+
@dependencies[resource.page_id] ||= {}
|
47
|
+
@dependencies[resource.page_id][child.page_id] = child
|
48
|
+
end
|
49
|
+
|
50
|
+
def dependencies(resource)
|
51
|
+
@dependencies[resource.page_id]&.values || []
|
52
|
+
end
|
53
|
+
|
54
|
+
def metadata(resource, key, default)
|
55
|
+
@metadata[resource.page_id] ||= {}
|
56
|
+
@metadata[resource.page_id][key] ||= default
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_metadata(resource, key, data)
|
60
|
+
@metadata[resource.page_id] ||= {}
|
61
|
+
@metadata[resource.page_id][key] = data
|
62
|
+
end
|
63
|
+
|
64
|
+
def page_id
|
65
|
+
self.class.to_s
|
9
66
|
end
|
10
67
|
|
11
|
-
def
|
12
|
-
|
68
|
+
def init_resource(resource)
|
69
|
+
resource.extend(::MiddlemanMdocs::Resource) unless resource.is_a?(::MiddlemanMdocs::Resource)
|
70
|
+
resource.extension = extension
|
71
|
+
resource.mdocs = self
|
13
72
|
end
|
14
73
|
|
15
74
|
def tags
|
16
|
-
|
17
|
-
|
75
|
+
with_cache(:tags, dependencies(self).map(&:timestamp).max) do
|
76
|
+
sitemap.resources.select do |r|
|
77
|
+
r.is_a?(::MiddlemanMdocs::Resource) && !r.metadata[:ignore] && r.html?
|
78
|
+
end.map do |r|
|
79
|
+
add_dependency(self, r)
|
80
|
+
# r.options[:tags]
|
18
81
|
r.tags
|
19
|
-
end
|
20
|
-
end
|
82
|
+
end.flatten.compact.map(&:to_s).uniq.sort
|
83
|
+
end
|
21
84
|
end
|
22
85
|
|
23
86
|
def has_tag?(tag)
|
24
|
-
tags.include?(tag.
|
87
|
+
tags.include?(tag.to_s)
|
25
88
|
end
|
26
89
|
|
27
90
|
def select_by_meta(meta)
|
28
91
|
with_ensure_resource do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
92
|
+
sitemap.resources.select do |r|
|
93
|
+
next false unless r.is_a?(::MiddlemanMdocs::Resource) && !r.metadata[:ignore] && r.template?
|
94
|
+
|
95
|
+
if meta.is_a? Hash
|
96
|
+
r.meta_match?(meta)
|
97
|
+
else
|
98
|
+
r.has_meta?(*meta)
|
36
99
|
end
|
37
100
|
end
|
38
101
|
end
|
@@ -40,29 +103,35 @@ module MiddlemanMdocs
|
|
40
103
|
|
41
104
|
def select_by_meta_force(meta)
|
42
105
|
with_ensure_resource do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
106
|
+
sitemap.resources.select do |r|
|
107
|
+
next false unless r.is_a?(::MiddlemanMdocs::Resource) && !r.metadata[:ignore]
|
108
|
+
|
109
|
+
if meta.is_a? Hash
|
110
|
+
r.meta_match?(meta)
|
111
|
+
else
|
112
|
+
r.has_meta?(*meta)
|
50
113
|
end
|
51
114
|
end
|
52
115
|
end
|
53
116
|
end
|
54
117
|
|
55
118
|
def select_by_tags(*tags)
|
119
|
+
tags = [tags].flatten.compact.uniq
|
120
|
+
|
56
121
|
with_ensure_resource do
|
57
|
-
sitemap.resources.select do |
|
58
|
-
|
122
|
+
sitemap.resources.select do |r|
|
123
|
+
next false unless r.is_a?(::MiddlemanMdocs::Resource) && !r.metadata[:ignore] && r.template?
|
124
|
+
|
125
|
+
r.has_tags?(*tags)
|
59
126
|
end
|
60
127
|
end
|
61
128
|
end
|
62
129
|
|
63
130
|
def select(tags, *meta)
|
64
|
-
|
65
|
-
|
131
|
+
tags = [tags].flatten.compact.uniq
|
132
|
+
|
133
|
+
select_by_meta(*meta).select do |r|
|
134
|
+
r.has_tags?(*tags)
|
66
135
|
end
|
67
136
|
end
|
68
137
|
|
@@ -76,10 +145,20 @@ module MiddlemanMdocs
|
|
76
145
|
end
|
77
146
|
|
78
147
|
def tr(tag, scope: :tags)
|
148
|
+
::MiddlemanMdocs::Controller.tr(tag, scope: scope)
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.tr(tag, scope: :tags)
|
79
152
|
I18n.t(tag.to_s.upcase.presence, scope: [:mdocs, scope],
|
80
153
|
default: I18n.t(tag.to_s.downcase.presence, scope: [:mdocs, scope], default: tag.to_s).presence)
|
81
154
|
end
|
82
155
|
|
156
|
+
private
|
157
|
+
|
158
|
+
def with_cache(*key, &block)
|
159
|
+
extension.cache.fetch([:controller, @updated, *key], &block)
|
160
|
+
end
|
161
|
+
|
83
162
|
def guard_recursive(name, key, default = nil)
|
84
163
|
guard = @guards[name] ||= {}
|
85
164
|
return guard[key] if guard.has_key?(key)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'kramdown/parser'
|
2
|
+
require 'kramdown/converter'
|
3
|
+
|
4
|
+
require 'mdocs_kramdown'
|
5
|
+
require 'kramdown/parser/mdocs_kramdown'
|
6
|
+
|
7
|
+
require_relative 'resource'
|
8
|
+
require_relative 'toc'
|
9
|
+
require_relative 'tilt_template'
|
10
|
+
require_relative 'navigation'
|
11
|
+
require_relative 'controller'
|
12
|
+
require_relative 'sitemap'
|
@@ -1,37 +1,57 @@
|
|
1
|
+
require 'active_support/cache'
|
2
|
+
require 'active_support/cache/memory_store'
|
3
|
+
|
4
|
+
require 'middleman-core/util'
|
5
|
+
require 'middleman-core/util/files'
|
6
|
+
|
7
|
+
module Middleman
|
8
|
+
module Util
|
9
|
+
include Contracts
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
# Finds files which should also be considered to be dirty when
|
14
|
+
# the given file(s) are touched.
|
15
|
+
#
|
16
|
+
# @param [Middleman::Application] app The app.
|
17
|
+
# @param [Pathname] files The original touched file paths.
|
18
|
+
# @return [Middleman::SourceFile] All related file paths, not including the source file paths.
|
19
|
+
Contract ::Middleman::Application, ArrayOf[Pathname] => ArrayOf[::Middleman::SourceFile]
|
20
|
+
def find_related_files(_app, _files)
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
1
26
|
module MiddlemanMdocs
|
2
27
|
class Extension < Middleman::Extension
|
3
28
|
attr_reader :mdocs, :mdocsnav, :mdocsmeta
|
4
29
|
|
30
|
+
cattr_reader :cache
|
31
|
+
|
5
32
|
expose_to_application :mdocs, :mdocsnav
|
6
33
|
expose_to_template :mdocs, :mdocsnav
|
34
|
+
|
7
35
|
expose_to_config :mdocs, :enrich_metadata
|
36
|
+
expose_to_config :mdocs, :static_sitemap
|
8
37
|
|
9
38
|
def initialize(*args, **_kwargs, &block)
|
10
39
|
super
|
11
40
|
|
12
41
|
# Only require dependency on activation
|
13
|
-
|
14
|
-
require 'kramdown/converter'
|
15
|
-
|
16
|
-
require 'mdocs_kramdown'
|
17
|
-
require 'kramdown/parser/mdocs_kramdown'
|
42
|
+
require_relative 'deps'
|
18
43
|
|
19
|
-
|
20
|
-
|
21
|
-
require_relative 'tilt_template'
|
22
|
-
require_relative 'navigation'
|
23
|
-
require_relative 'controller'
|
24
|
-
require_relative 'sitemap'
|
44
|
+
# @@cache ||= ActiveSupport::Cache::MemoryStore.new(size: 100.megabytes)
|
45
|
+
@@cache ||= ActiveSupport::Cache::FileStore.new('tmp/mdocs/cache')
|
25
46
|
|
26
|
-
|
47
|
+
register_helpers(::MiddlemanMdocs::Navigation)
|
27
48
|
|
28
49
|
configure_application
|
29
50
|
|
30
|
-
register_helpers(::MiddlemanMdocs::TOC)
|
31
|
-
register_helpers(::MiddlemanMdocs::Navigation)
|
32
|
-
|
33
51
|
@mdocsmeta = {}
|
34
52
|
|
53
|
+
@mdocs = Controller.new(self)
|
54
|
+
|
35
55
|
::ActiveSupport::Notifications.subscribe('sitemap.update.middleman') do
|
36
56
|
lookup = @mdocs.sitemap.instance_variable_get('@_lookup_by_destination_path')
|
37
57
|
@mdocs.sitemap.resources.each do |resource|
|
@@ -41,7 +61,7 @@ module MiddlemanMdocs
|
|
41
61
|
end
|
42
62
|
|
43
63
|
def configure_application
|
44
|
-
|
64
|
+
Middleman::Sitemap::Store.include(::MiddlemanMdocs::Sitemap)
|
45
65
|
|
46
66
|
app.config[:markdown_engine] = :kramdown
|
47
67
|
app.config[:markdown] = {
|
@@ -67,9 +87,34 @@ module MiddlemanMdocs
|
|
67
87
|
end
|
68
88
|
end
|
69
89
|
|
90
|
+
def after_build
|
91
|
+
$app = app
|
92
|
+
if @sitemap_opts && @sitemap_block
|
93
|
+
interpreter = SitemapGenerator::Interpreter.new(@sitemap_opts.merge(compress: true))
|
94
|
+
interpreter.instance_eval(&@sitemap_block)
|
95
|
+
|
96
|
+
interpreter = SitemapGenerator::Interpreter.new(@sitemap_opts.merge(compress: false))
|
97
|
+
interpreter.instance_eval(&@sitemap_block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
70
101
|
def after_configuration
|
71
102
|
markdown_exts = %w[markdown mdown md mkd mkdn]
|
72
|
-
::Tilt.register ::MiddlemanMdocs::
|
103
|
+
::Tilt.register ::MiddlemanMdocs::TiltTemplate, *markdown_exts
|
104
|
+
|
105
|
+
app.files.on_change :source do |changed, _deleted|
|
106
|
+
resources = changed.map do |_ch|
|
107
|
+
full = changed.first.full_path.to_s
|
108
|
+
app.sitemap.resources.find { |r| r.source_file == full }
|
109
|
+
end.flatten
|
110
|
+
|
111
|
+
resources.compact.each(&:refresh)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def static_sitemap(opts = {}, &block)
|
116
|
+
@sitemap_opts = opts = opts.dup
|
117
|
+
@sitemap_block = block
|
73
118
|
end
|
74
119
|
|
75
120
|
def enrich_metadata(rx, &block)
|
@@ -77,18 +122,17 @@ module MiddlemanMdocs
|
|
77
122
|
@enrichers.push([rx, block])
|
78
123
|
end
|
79
124
|
|
80
|
-
|
81
|
-
mdocs.load(app.data.mdocs)
|
125
|
+
helpers do
|
82
126
|
end
|
83
127
|
|
84
|
-
|
128
|
+
def log(text)
|
129
|
+
logger.debug "[MDOCS] #{Time.now}: #{text}"
|
85
130
|
end
|
86
131
|
|
87
132
|
def manipulate_resource_list(resources)
|
133
|
+
logger.debug '== [MDOCS] enrich resources...'
|
88
134
|
resources.each do |resource|
|
89
|
-
|
90
|
-
resource.extend(::MiddlemanMdocs::Resource) unless resource.is_a?(::MiddlemanMdocs::Resource)
|
91
|
-
resource.mdocs_extention = self
|
135
|
+
mdocs.init_resource(resource)
|
92
136
|
|
93
137
|
next if resource.metadata[:ignore]
|
94
138
|
|
@@ -98,8 +142,15 @@ module MiddlemanMdocs
|
|
98
142
|
resource.destination_path << '.html' unless resource.destination_path.end_with?('.html')
|
99
143
|
end
|
100
144
|
|
101
|
-
|
102
|
-
|
145
|
+
mdocs.register(resource)
|
146
|
+
|
147
|
+
nonce = SecureRandom.hex
|
148
|
+
|
149
|
+
state = cache.fetch([resource.cache_key, :manipulate_resource_list]) do
|
150
|
+
nonce
|
151
|
+
end
|
152
|
+
|
153
|
+
next if mdocs.ready? && nonce != state
|
103
154
|
|
104
155
|
# enrich recursive metadata from metadata.yml in each folder
|
105
156
|
metadata = get_metadata(resource.source_file)
|
@@ -111,21 +162,24 @@ module MiddlemanMdocs
|
|
111
162
|
block.call(resource, md)
|
112
163
|
end
|
113
164
|
end
|
165
|
+
|
166
|
+
resource.refresh
|
114
167
|
end
|
115
168
|
|
169
|
+
mdocs.refresh
|
116
170
|
resources
|
117
171
|
end
|
118
172
|
|
119
173
|
def get_metadata(path)
|
120
174
|
return {} unless path[app.source_dir.to_s]
|
121
175
|
|
122
|
-
path =
|
176
|
+
path = Pathname.new(path)
|
123
177
|
current_dir = path.dirname.relative_path_from(app.source_dir).to_s
|
124
178
|
|
125
179
|
@mdocsmeta[current_dir] || begin
|
126
180
|
tokens = current_dir.split('/')
|
127
181
|
|
128
|
-
([''] + tokens).reduce(
|
182
|
+
([''] + tokens).reduce(Pathname('')) do |parent, token|
|
129
183
|
return {} if ['.', ','].include?(token)
|
130
184
|
|
131
185
|
current = parent.join(token)
|
@@ -76,7 +76,7 @@ module MiddlemanMdocs
|
|
76
76
|
if block_given?
|
77
77
|
link_to("/tags/#{tag}", *args, &block)
|
78
78
|
else
|
79
|
-
link_to(I18n.t(tag, scope: %i[mdocs tags], default: tag.to_s), "/tags/#{tag}
|
79
|
+
link_to(I18n.t(tag, scope: %i[mdocs tags], default: tag.to_s), "/tags/#{tag}", *args, &block)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -85,28 +85,42 @@ module MiddlemanMdocs
|
|
85
85
|
url.try(:source_file)
|
86
86
|
elsif url.start_with?('/')
|
87
87
|
app.source_dir.join(url[1..-1]).to_s
|
88
|
+
elsif current_page
|
89
|
+
Pathname.new(current_page.source_file).dirname.join(url).to_s
|
88
90
|
else
|
89
|
-
|
91
|
+
url
|
90
92
|
end
|
91
93
|
app.sitemap.resources.find { |r| r.source_file == source_file }
|
92
94
|
end
|
93
95
|
|
94
96
|
def merge(url)
|
95
|
-
resource = fuzzy_find_resource(url)
|
97
|
+
resource = fuzzy_find_resource(url) || sitemap.find_resource_by_page_id(url)
|
96
98
|
raise "unable to find resource by #{url}" unless resource
|
97
99
|
|
98
|
-
|
99
|
-
current_page
|
100
|
+
mdocs.init_resource(resource) unless resource.is_a?(::MiddlemanMdocs::Resource)
|
101
|
+
if current_page
|
102
|
+
current_page.add_tags(resource.tags)
|
103
|
+
current_page.add_keywords(resource.keywords)
|
104
|
+
current_page.data.reverse_merge!(resource.data)
|
105
|
+
end
|
100
106
|
end
|
101
107
|
|
102
108
|
def include(page_id_or_path, merge: true, render: true)
|
103
|
-
merge(page_id_or_path) if merge
|
104
109
|
resource = fuzzy_find_resource(page_id_or_path) || sitemap.find_resource_by_page_id(page_id_or_path)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
+
mdocs.add_dependency(current_page, resource)
|
111
|
+
|
112
|
+
mdocs.init_resource(resource) unless resource.is_a?(::MiddlemanMdocs::Resource)
|
113
|
+
result = if render
|
114
|
+
resource.force_render
|
115
|
+
else
|
116
|
+
::File.read(resource.try(:source_file) || page_id_or_path)
|
117
|
+
end
|
118
|
+
|
119
|
+
merge(page_id_or_path) if merge
|
120
|
+
result
|
121
|
+
rescue StandardError => e
|
122
|
+
puts "Error on including #{page_id_or_path.inspect} to #{current_page.inspect}: #{e.inspect}"
|
123
|
+
raise
|
110
124
|
end
|
111
125
|
|
112
126
|
# some custom magic to find result path to generated resource
|
@@ -121,6 +135,15 @@ module MiddlemanMdocs
|
|
121
135
|
end
|
122
136
|
end
|
123
137
|
|
138
|
+
def current_page
|
139
|
+
r = super
|
140
|
+
if r.nil?
|
141
|
+
@locs&.fetch(:force_current_page, nil)
|
142
|
+
else
|
143
|
+
r
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
124
147
|
# is this is url for current page
|
125
148
|
def active_url?(url)
|
126
149
|
translated = translate_to_destination(url)
|
@@ -1,57 +1,150 @@
|
|
1
1
|
module MiddlemanMdocs
|
2
2
|
module Resource
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :extension, :mdocs, :updated
|
4
|
+
|
5
|
+
def self.normalize_tags(*args)
|
6
|
+
args.flatten.compact.map(&:to_s).map do |tag|
|
7
|
+
::MiddlemanMdocs::Controller.tr(tag)
|
8
|
+
end.map(&:upcase).uniq.sort
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.normalize_keywords(*args)
|
12
|
+
raw = args.flatten.compact.map(&:to_s)
|
13
|
+
normalized = normalize_tags(raw)
|
14
|
+
(raw + normalized).uniq.sort
|
15
|
+
end
|
4
16
|
|
5
17
|
def markdown?
|
6
|
-
|
18
|
+
metadata[:markdown]
|
7
19
|
end
|
8
20
|
|
9
|
-
def
|
10
|
-
|
21
|
+
def html?
|
22
|
+
@html ||= destination_path.end_with?('.html')
|
11
23
|
end
|
12
24
|
|
13
|
-
def
|
14
|
-
|
25
|
+
def ready?
|
26
|
+
mdocs.ready?
|
15
27
|
end
|
16
28
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
29
|
+
def copy_from(other)
|
30
|
+
resource = self
|
31
|
+
unless @patched
|
32
|
+
data.define_singleton_method(:title) do
|
33
|
+
resource.title
|
34
|
+
end
|
22
35
|
|
23
|
-
|
24
|
-
|
36
|
+
data.define_singleton_method(:keywords) do
|
37
|
+
resource.keywords
|
38
|
+
end
|
39
|
+
|
40
|
+
data.define_singleton_method(:text) do
|
41
|
+
resource.text
|
42
|
+
end
|
43
|
+
|
44
|
+
@patched = true
|
45
|
+
end
|
46
|
+
|
47
|
+
custom_deep_merge!(data, other.data)
|
48
|
+
custom_deep_merge!(metadata, other.metadata)
|
49
|
+
|
50
|
+
self.updated = other.updated
|
25
51
|
end
|
26
52
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
53
|
+
def updated_at
|
54
|
+
@updated_at ||= begin
|
55
|
+
ts = data[:updated_at] || metadata[:updated_at] || timestamp
|
56
|
+
ts = DateTime.parse(ts) if ts.is_a?(String)
|
57
|
+
ts
|
58
|
+
end
|
31
59
|
end
|
32
60
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
rescue StandardError
|
39
|
-
nil
|
40
|
-
end
|
41
|
-
end
|
42
|
-
@rendered = true
|
61
|
+
def created_at
|
62
|
+
@created_at ||= begin
|
63
|
+
ts = data[:created_at] || metadata[:created_at] || File.ctime(source_file)
|
64
|
+
ts = DateTime.parse(ts) if ts.is_a?(String)
|
65
|
+
[ts, updated_at].min
|
43
66
|
end
|
44
|
-
|
67
|
+
end
|
68
|
+
|
69
|
+
def timestamp
|
70
|
+
(mdocs.dependencies(self).map(&:timestamp) + [File.mtime(source_file)]).max
|
71
|
+
end
|
72
|
+
|
73
|
+
def cache_key
|
74
|
+
"#{page_id}/#{timestamp}/"
|
45
75
|
end
|
46
76
|
|
47
77
|
def title
|
48
|
-
|
78
|
+
with_cache(:title, @updated) do
|
79
|
+
data[:title] || metadata[:title] || toc&.children&.first&.raw_text
|
80
|
+
end
|
81
|
+
end
|
49
82
|
|
50
|
-
|
83
|
+
def refresh
|
84
|
+
@guards ||= {}
|
85
|
+
|
86
|
+
# @updated = SecureRandom.hex
|
87
|
+
end
|
88
|
+
|
89
|
+
def text
|
90
|
+
force_render if !metadata[:ignore] && html?
|
91
|
+
end
|
92
|
+
|
93
|
+
def tags
|
94
|
+
with_cache(:tags, @updated) do
|
95
|
+
guard_recursive('tags', page_id, []) do |_key|
|
96
|
+
text
|
97
|
+
end
|
98
|
+
|
99
|
+
options[:tags] = ::MiddlemanMdocs::Resource.normalize_tags(options[:tags], data[:tags], metadata[:tags])
|
100
|
+
end
|
51
101
|
end
|
52
102
|
|
53
103
|
def keywords
|
54
|
-
(
|
104
|
+
with_cache(:keywords, @updated) do
|
105
|
+
options[:keywords] =
|
106
|
+
::MiddlemanMdocs::Resource.normalize_keywords(tags, options[:keywords], data[:keywords], metadata[:keywords])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def toc
|
111
|
+
with_cache(:toc, @updated) do
|
112
|
+
if metadata[:ignore] || !html?
|
113
|
+
nil
|
114
|
+
else
|
115
|
+
mdocs.table_of_contents(self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_options(opts)
|
121
|
+
options.deep_merge!(opts)
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_meta(opts)
|
125
|
+
metadata.deep_merge!(opts)
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_tags(*args)
|
129
|
+
return unless args.flatten.any?
|
130
|
+
|
131
|
+
added = ::MiddlemanMdocs::Resource.normalize_tags(args)
|
132
|
+
return if (added - (options[:tags] || [])).empty?
|
133
|
+
|
134
|
+
@updated = SecureRandom.hex
|
135
|
+
options[:tags] = ::MiddlemanMdocs::Resource.normalize_tags(options[:tags], data[:tags], metadata[:tags], added)
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_keywords(*args)
|
139
|
+
return unless args.flatten.any?
|
140
|
+
|
141
|
+
added = ::MiddlemanMdocs::Resource.normalize_keywords(args)
|
142
|
+
return if (added - (options[:keywords] || [])).empty?
|
143
|
+
|
144
|
+
@updated = SecureRandom.hex
|
145
|
+
options[:keywords] =
|
146
|
+
::MiddlemanMdocs::Resource.normalize_keywords(options[:tags], options[:keywords], data[:keywords], metadata[:keywords],
|
147
|
+
added)
|
55
148
|
end
|
56
149
|
|
57
150
|
def meta_match?(meta)
|
@@ -67,9 +160,60 @@ module MiddlemanMdocs
|
|
67
160
|
end
|
68
161
|
|
69
162
|
def has_tags?(*keys)
|
70
|
-
keys.compact!
|
71
|
-
keys.uniq!
|
72
163
|
(tags & keys).size == keys.size
|
73
164
|
end
|
165
|
+
|
166
|
+
def destination_path(*args)
|
167
|
+
super.force_encoding(Encoding.default_external)
|
168
|
+
end
|
169
|
+
|
170
|
+
def force_render
|
171
|
+
render({ layout: false }, { current_path: path, force_current_page: self })
|
172
|
+
end
|
173
|
+
|
174
|
+
def render(opts = {}, locs = {})
|
175
|
+
return super if nocache? || locs.has_key?('rack') || locs.has_key?(:rack)
|
176
|
+
|
177
|
+
with_cache(Digest::MD5.hexdigest(opts.to_json + locs.to_json) + 'render') do
|
178
|
+
# puts "REFRESH: #{binary?} #{page_id}: #{opts.to_json + locs.to_json}"
|
179
|
+
super
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def nocache?
|
186
|
+
binary? || metadata[:ignore] || metadata[:nocache] || data[:nocache]
|
187
|
+
end
|
188
|
+
|
189
|
+
def with_cache(*key, &block)
|
190
|
+
extension.cache.fetch([cache_key, *key], &block)
|
191
|
+
end
|
192
|
+
|
193
|
+
def custom_deep_merge!(left, right)
|
194
|
+
left.merge!(right) do |_key, this_val, other_val|
|
195
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
196
|
+
custom_deep_merge!(this_val, other_val)
|
197
|
+
elsif this_val.is_a?(Array) && other_val.is_a?(Array)
|
198
|
+
this_val.concat(other_val).uniq!
|
199
|
+
else
|
200
|
+
other_val.nil? ? this_val : other_val
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def guard_recursive(name, key, default = nil)
|
206
|
+
@guards ||= {}
|
207
|
+
|
208
|
+
guard = @guards[name] ||= {}
|
209
|
+
return guard[key] if guard.has_key?(key)
|
210
|
+
|
211
|
+
begin
|
212
|
+
guard[key] = default
|
213
|
+
guard[key] = yield(key)
|
214
|
+
ensure
|
215
|
+
guard.delete(key)
|
216
|
+
end
|
217
|
+
end
|
74
218
|
end
|
75
219
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'middleman-core/renderers/kramdown'
|
2
2
|
|
3
3
|
module MiddlemanMdocs
|
4
|
-
class
|
4
|
+
class TiltTemplate < ::Middleman::Renderers::KramdownTemplate
|
5
5
|
def render(*args)
|
6
6
|
erb = Middleman::Renderers::ERb::Template.new(file, line, options) { data }
|
7
7
|
@data = erb.render(*args)
|
data/lib/middleman-mdocs/toc.rb
CHANGED
@@ -50,10 +50,13 @@ module MiddlemanMdocs
|
|
50
50
|
## Generate TOC object tree for current page or source file
|
51
51
|
#
|
52
52
|
def table_of_contents(page_or_source, input: 'markdown')
|
53
|
+
# puts "#{Process.pid} =>>>> GENERATE TOC: #{page_or_source.try(:page_id) || page_or_source}"
|
54
|
+
# byebug if page_or_source.page_id.force_encoding('UTF-8') == 'docs/services/gis-gmp/import-refunds'
|
55
|
+
|
53
56
|
begin
|
54
57
|
return nil if page_or_source.metadata[:ignore]
|
55
58
|
|
56
|
-
content = page_or_source.
|
59
|
+
content = page_or_source.text
|
57
60
|
toc = Kramdown::Document.new(content, app.config[:markdown].merge(input: 'html')).to_toc
|
58
61
|
|
59
62
|
return Item.parse_kramdown_toc(toc)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-mdocs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1.75132
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samoylenko Yuri
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- bin/setup
|
195
195
|
- lib/middleman-mdocs.rb
|
196
196
|
- lib/middleman-mdocs/controller.rb
|
197
|
+
- lib/middleman-mdocs/deps.rb
|
197
198
|
- lib/middleman-mdocs/extension.rb
|
198
199
|
- lib/middleman-mdocs/navigation.rb
|
199
200
|
- lib/middleman-mdocs/resource.rb
|