asciidoctor-diagram-layout 1.0.1 → 1.1.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/README.md +220 -42
- data/lib/asciidoctor_diagram_layout/asciidoc/layout_block_processor.rb +27 -23
- data/lib/asciidoctor_diagram_layout/renderer/html_renderer.rb +6 -1
- data/lib/asciidoctor_diagram_layout/renderer/render_options.rb +3 -2
- data/lib/asciidoctor_diagram_layout/renderer/svg_renderer.rb +3 -0
- data/lib/asciidoctor_diagram_layout/version.rb +1 -1
- metadata +32 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c49ff65f5b48299da96077abff591082253d7d235f7d04c376563722b6ef3fdd
|
|
4
|
+
data.tar.gz: 120ad77f8019c03234c9c58e7dfc10fbd6332baebb81f2ba58a83268f3a34d21
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 643df3c7a743cd9f67b7c067c9e19cb251de1e4b2bc3cbdf6457985f7ced4aab41612214d084b050218562b016ffd425346b5e1c705f575cc65233962ac20847
|
|
7
|
+
data.tar.gz: 874427307fe73724a2d47b0f2010280585f10c209348366ffce5d95c5809441f0e195808c7c6a967ff8e2d519e97a0b6bd20ddffc4961a629efec9b2e16df971
|
data/README.md
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
# asciidoctor-diagram-layout
|
|
2
2
|
|
|
3
|
-
An Asciidoctor extension
|
|
4
|
-
|
|
3
|
+
An Asciidoctor extension for documenting UI layouts as diagrams,
|
|
4
|
+
intended for describing the structure of composite views (pages, screens,
|
|
5
|
+
etc.).
|
|
6
|
+
|
|
7
|
+
## The problem
|
|
8
|
+
|
|
9
|
+
When writing software requirements or design documents, you often need
|
|
10
|
+
to describe the layout of a screen or a page: which areas exist, how
|
|
11
|
+
they are positioned relative to each other, and what proportion of
|
|
12
|
+
space each one occupies.
|
|
13
|
+
|
|
14
|
+
The usual alternatives are screenshots, wireframe tools, or hand-drawn
|
|
15
|
+
sketches - none of which live well next to the text, can be diffed in
|
|
16
|
+
version control, or stay in sync as the design evolves.
|
|
17
|
+
|
|
18
|
+
This extension lets you describe a layout directly in AsciiDoc source
|
|
19
|
+
using a simple line-oriented DSL.
|
|
20
|
+
The same source serves as both a human-readable description of the
|
|
21
|
+
structure and a machine-rendered visual diagram - there is no separate
|
|
22
|
+
"source" and "picture" to keep in sync.
|
|
23
|
+
The diagram is rendered as HTML (for web output) or SVG (for PDF and
|
|
24
|
+
other backends) without any external tools.
|
|
5
25
|
|
|
6
26
|
## Installation
|
|
7
27
|
|
|
@@ -19,71 +39,229 @@ gem install asciidoctor-diagram-layout
|
|
|
19
39
|
|
|
20
40
|
## Usage
|
|
21
41
|
|
|
22
|
-
|
|
23
|
-
AsciiDoc documents:
|
|
42
|
+
Pass `-r asciidoctor-diagram-layout` to the Asciidoctor CLI:
|
|
24
43
|
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
44
|
+
```
|
|
45
|
+
asciidoctor -r asciidoctor-diagram-layout doc.adoc
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Running from source
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
bundle exec asciidoctor -r asciidoctor-diagram-layout doc.adoc
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Development
|
|
55
|
+
|
|
56
|
+
Install dependencies:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
bundle install
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Run tests:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
bundle exec rake spec
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Build the gem:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
bundle exec rake build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Releasing a new version
|
|
75
|
+
|
|
76
|
+
1. Update the version in `lib/asciidoctor_diagram_layout/version.rb`
|
|
77
|
+
2. Update `CHANGELOG.md`
|
|
78
|
+
3. Commit: `git commit -m "Release x.y.z"`
|
|
79
|
+
4. Tag: `git tag vx.y.z`
|
|
80
|
+
5. Push: `git push origin vx.y.z`
|
|
81
|
+
|
|
82
|
+
Requires `RUBYGEMS_API_KEY` secret configured in the repository settings.
|
|
83
|
+
|
|
84
|
+
**Locally** - build, tag, and publish in one command:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
bundle exec rake release
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Requires rubygems.org credentials (`gem signin`).
|
|
91
|
+
|
|
92
|
+
## Examples
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### Single column layout
|
|
96
|
+
|
|
97
|
+
The simplest case: a vertical stack of areas.
|
|
98
|
+
Top-level cells without an explicit container are stacked
|
|
99
|
+
vertically by default.
|
|
100
|
+
|
|
101
|
+
```asciidoc
|
|
102
|
+
[layout-rowcol, width="400px", height="200px"]
|
|
103
|
+
----
|
|
104
|
+
cell: Header
|
|
105
|
+
cell: Content
|
|
106
|
+
cell: Footer
|
|
107
|
+
----
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+

|
|
111
|
+
|
|
112
|
+
### Fixed-size header and footer
|
|
113
|
+
|
|
114
|
+
A number in parentheses sets the size as a percentage of the
|
|
115
|
+
parent.
|
|
116
|
+
The remaining space is distributed equally among auto-sized
|
|
117
|
+
cells.
|
|
118
|
+
|
|
119
|
+
```asciidoc
|
|
120
|
+
[layout-rowcol, width="400px", height="200px"]
|
|
121
|
+
----
|
|
122
|
+
cell(20): Header
|
|
123
|
+
cell: Content
|
|
124
|
+
cell(20): Footer
|
|
125
|
+
----
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+

|
|
129
|
+
|
|
130
|
+
### Two-column layout with a sidebar
|
|
28
131
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
132
|
+
```asciidoc
|
|
133
|
+
[layout-rowcol, width="400px", height="200px"]
|
|
134
|
+
----
|
|
135
|
+
cols:
|
|
136
|
+
cell(25): Sidebar
|
|
137
|
+
cell: Content
|
|
138
|
+
----
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+

|
|
142
|
+
|
|
143
|
+
### Classic page layout
|
|
144
|
+
|
|
145
|
+
A header and footer at fixed height, with a sidebar and main
|
|
146
|
+
content area in between.
|
|
147
|
+
|
|
148
|
+
```asciidoc
|
|
149
|
+
[layout-rowcol, width="400px", height="250px"]
|
|
150
|
+
----
|
|
151
|
+
cell(20): Header
|
|
152
|
+
cols:
|
|
153
|
+
cell(25): Sidebar
|
|
154
|
+
cell: Content
|
|
155
|
+
cell(20): Footer
|
|
156
|
+
----
|
|
32
157
|
```
|
|
33
158
|
|
|
34
|
-
|
|
159
|
+

|
|
160
|
+
|
|
161
|
+
### Dashboard with nested sections
|
|
162
|
+
|
|
163
|
+
Nesting `rows:` and `cols:` containers produces complex grids.
|
|
164
|
+
|
|
165
|
+
```asciidoc
|
|
166
|
+
[layout-rowcol, width="600px", height="350px"]
|
|
167
|
+
----
|
|
168
|
+
cell(10): Toolbar
|
|
169
|
+
cols:
|
|
170
|
+
cell(20): Navigation
|
|
171
|
+
rows:
|
|
172
|
+
cell(30): Hero
|
|
173
|
+
cols:
|
|
174
|
+
cell: Features
|
|
175
|
+
cell: Pricing
|
|
176
|
+
cell: Testimonials
|
|
177
|
+
cell: Call to Action
|
|
178
|
+
cell(8): Footer
|
|
179
|
+
----
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+

|
|
183
|
+
|
|
184
|
+
### Referencing document sections
|
|
185
|
+
|
|
186
|
+
Cell names support AsciiDoc `xref:` macros.
|
|
187
|
+
The cross-reference is preserved in HTML output and stripped to the
|
|
188
|
+
display label in SVG output.
|
|
35
189
|
|
|
36
190
|
```asciidoc
|
|
37
191
|
[layout-rowcol]
|
|
38
192
|
----
|
|
193
|
+
cell(10): xref:header[Header]
|
|
39
194
|
cols:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
cell: Content
|
|
195
|
+
cell(25): xref:sidebar[Sidebar]
|
|
196
|
+
cell: xref:content[Content]
|
|
197
|
+
cell(10): xref:footer[Footer]
|
|
44
198
|
----
|
|
45
199
|
```
|
|
46
200
|
|
|
47
|
-
###
|
|
201
|
+
### Color palettes
|
|
48
202
|
|
|
49
|
-
|
|
50
|
-
|
|
203
|
+
The `palette` attribute controls the color scheme.
|
|
204
|
+
Available values: `rainbow` (default), `warm`, `cool`, `mono`, `pastel`.
|
|
51
205
|
|
|
52
|
-
|
|
53
|
-
* `rows:` - container that arranges children vertically
|
|
54
|
-
* `cell: Name` - leaf cell with a visible label
|
|
55
|
-
* `cell(30): Name` - leaf cell with a fixed size of 30% of its parent
|
|
56
|
-
* Containers without an explicit size take equal shares of the remaining
|
|
57
|
-
space
|
|
58
|
-
* Lines starting with `#` are comments
|
|
206
|
+
`warm`:
|
|
59
207
|
|
|
60
|
-
|
|
208
|
+

|
|
61
209
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
210
|
+
`cool`:
|
|
211
|
+
|
|
212
|
+

|
|
213
|
+
|
|
214
|
+
`mono`:
|
|
215
|
+
|
|
216
|
+

|
|
217
|
+
|
|
218
|
+
`pastel`:
|
|
219
|
+
|
|
220
|
+

|
|
71
221
|
|
|
72
222
|
### PDF output
|
|
73
223
|
|
|
74
|
-
When converting to PDF
|
|
75
|
-
|
|
76
|
-
Use the `target` attribute to
|
|
224
|
+
When converting to PDF the diagram is written as an SVG file and
|
|
225
|
+
embedded as an image.
|
|
226
|
+
Use the `target` attribute to set the output file name:
|
|
77
227
|
|
|
78
228
|
```asciidoc
|
|
79
|
-
[layout-rowcol, target="
|
|
229
|
+
[layout-rowcol, target="page-layout"]
|
|
80
230
|
----
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
231
|
+
cell(10): Header
|
|
232
|
+
cell: Content
|
|
233
|
+
cell(10): Footer
|
|
84
234
|
----
|
|
85
235
|
```
|
|
86
236
|
|
|
237
|
+
## DSL syntax
|
|
238
|
+
|
|
239
|
+
Each line declares one node.
|
|
240
|
+
Indentation (4 spaces or one tab) defines nesting.
|
|
241
|
+
|
|
242
|
+
* `rows:` - container that arranges children vertically
|
|
243
|
+
* `cols:` - container that arranges children horizontally
|
|
244
|
+
* `cell: Name` - leaf cell with a visible label
|
|
245
|
+
* `cell(N): Name` - leaf cell with a fixed size of N% of its parent
|
|
246
|
+
* Containers and cells without an explicit size share the remaining
|
|
247
|
+
space equally
|
|
248
|
+
* Top-level nodes without an explicit container are wrapped in a
|
|
249
|
+
vertical (`rows`) container by default
|
|
250
|
+
* Lines starting with `#` are comments
|
|
251
|
+
|
|
252
|
+
## Block attributes
|
|
253
|
+
|
|
254
|
+
* `direction` - implicit direction when no top-level container is
|
|
255
|
+
declared: `rows` (default) or `cols`
|
|
256
|
+
* `renderer` - force output format: `html` or `svg`; defaults to
|
|
257
|
+
`html` for HTML backends and `svg` for all others including PDF
|
|
258
|
+
* `palette` - color scheme: `rainbow` (default), `pastel`, `warm`,
|
|
259
|
+
`cool`, `mono`
|
|
260
|
+
* `width` - diagram width, e.g. `100%` (default) or `800px`
|
|
261
|
+
* `height` - diagram height, e.g. `400px`; not set by default
|
|
262
|
+
* `target` - SVG file name without extension, used when rendering
|
|
263
|
+
to PDF
|
|
264
|
+
|
|
87
265
|
## License
|
|
88
266
|
|
|
89
267
|
Apache License 2.0.
|
|
@@ -7,26 +7,28 @@ module AsciidoctorDiagramLayout
|
|
|
7
7
|
use_dsl
|
|
8
8
|
named :"layout-rowcol"
|
|
9
9
|
on_contexts :listing, :literal
|
|
10
|
+
name_positional_attributes "target"
|
|
10
11
|
|
|
11
12
|
def process(parent, reader, attrs)
|
|
12
|
-
dsl
|
|
13
|
-
implicit_dir
|
|
14
|
-
root
|
|
15
|
-
backend
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
options
|
|
13
|
+
dsl = reader.read
|
|
14
|
+
implicit_dir = attrs["direction"] == "cols" ? :cols : :rows
|
|
15
|
+
root = Parser.new.parse(dsl, implicit_dir)
|
|
16
|
+
backend = parent.document.attr("backend").to_s
|
|
17
|
+
strategy = resolve_strategy(attrs["renderer"], backend)
|
|
18
|
+
palette = attrs.fetch("palette", "rainbow")
|
|
19
|
+
pdf = backend == "pdf"
|
|
20
|
+
title = attrs["title"]
|
|
21
|
+
options = Renderer::RenderOptions.new(
|
|
21
22
|
width: attrs.fetch("width", "100%"),
|
|
22
23
|
height: attrs["height"],
|
|
24
|
+
title: title,
|
|
23
25
|
palette: palette,
|
|
24
26
|
pdf: pdf,
|
|
25
|
-
name_converter:
|
|
27
|
+
name_converter: ->(name) { convert_inline(parent, name) }
|
|
26
28
|
)
|
|
27
29
|
case strategy
|
|
28
30
|
when :html then render_html(parent, root, options)
|
|
29
|
-
when :svg then render_svg(parent, root, backend, options, attrs)
|
|
31
|
+
when :svg then render_svg(parent, root, backend, options, attrs, title)
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
|
@@ -49,16 +51,17 @@ module AsciidoctorDiagramLayout
|
|
|
49
51
|
create_pass_block(parent, html, {}, subs: nil)
|
|
50
52
|
end
|
|
51
53
|
|
|
52
|
-
def render_svg(parent, root, backend, options, attrs)
|
|
53
|
-
svg
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
def render_svg(parent, root, backend, options, attrs, title)
|
|
55
|
+
svg = Renderer::SvgRenderer.new.render(root, options)
|
|
56
|
+
target = attrs["target"]
|
|
57
|
+
outdir = parent.document.attr("outdir").to_s
|
|
58
|
+
path = write_svg(svg, target, outdir)
|
|
59
|
+
filename = File.basename(path)
|
|
60
|
+
parent.document.register(:images, filename)
|
|
61
|
+
img_target = backend == "pdf" ? File.expand_path(path) : filename
|
|
62
|
+
block = create_image_block(parent, { "target" => img_target, "format" => "svg" })
|
|
63
|
+
block.title = title if title && !title.empty?
|
|
64
|
+
block
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
def write_svg(svg, name, outdir)
|
|
@@ -75,8 +78,9 @@ module AsciidoctorDiagramLayout
|
|
|
75
78
|
path
|
|
76
79
|
end
|
|
77
80
|
|
|
78
|
-
def
|
|
79
|
-
text
|
|
81
|
+
def convert_inline(node, text)
|
|
82
|
+
escaped = node.sub_specialchars(text)
|
|
83
|
+
node.sub_macros(escaped)
|
|
80
84
|
end
|
|
81
85
|
end
|
|
82
86
|
end
|
|
@@ -13,7 +13,12 @@ module AsciidoctorDiagramLayout
|
|
|
13
13
|
sb << "<div style=\"#{wrapper_style}\">\n"
|
|
14
14
|
render_node(root, sb, 1, options)
|
|
15
15
|
sb << "</div>\n"
|
|
16
|
-
|
|
16
|
+
if options.title && !options.title.empty?
|
|
17
|
+
"<div class=\"imageblock\">\n<div class=\"content\">\n#{sb}</div>\n" \
|
|
18
|
+
"<div class=\"title\">#{options.title}</div>\n</div>"
|
|
19
|
+
else
|
|
20
|
+
sb
|
|
21
|
+
end
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
private
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
3
|
class RenderOptions
|
|
4
|
-
attr_reader :width, :height, :color_scheme, :name_converter
|
|
4
|
+
attr_reader :width, :height, :title, :color_scheme, :name_converter
|
|
5
5
|
|
|
6
|
-
def initialize(width: "100%", height: nil, palette: "rainbow", pdf: false,
|
|
6
|
+
def initialize(width: "100%", height: nil, title: nil, palette: "rainbow", pdf: false,
|
|
7
7
|
color_scheme: nil, name_converter: nil)
|
|
8
8
|
@width = width
|
|
9
9
|
@height = height
|
|
10
|
+
@title = title
|
|
10
11
|
@color_scheme = color_scheme || Scheme::CellColorSchemeFactory.resolve(palette, pdf: pdf)
|
|
11
12
|
@name_converter = name_converter || method(:escape)
|
|
12
13
|
end
|
|
@@ -17,6 +17,9 @@ module AsciidoctorDiagramLayout
|
|
|
17
17
|
sb << " height=\"#{h}\""
|
|
18
18
|
sb << " style=\"font-family:sans-serif;\""
|
|
19
19
|
sb << ">\n"
|
|
20
|
+
if options.title && !options.title.empty?
|
|
21
|
+
sb << " <title>#{escape_xml(options.title)}</title>\n"
|
|
22
|
+
end
|
|
20
23
|
if defs.length > 0
|
|
21
24
|
sb << " <defs>\n" << defs << " </defs>\n"
|
|
22
25
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: asciidoctor-diagram-layout
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Pechinsky
|
|
@@ -13,14 +13,14 @@ dependencies:
|
|
|
13
13
|
name: asciidoctor
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '2.0'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '2.0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
@@ -37,6 +37,34 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '3.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: erb
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
40
68
|
description: Provides a [layout] block for Asciidoctor that renders layout diagrams
|
|
41
69
|
as HTML or SVG.
|
|
42
70
|
email: anton@pechinsky.com
|
|
@@ -69,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
69
97
|
requirements:
|
|
70
98
|
- - ">="
|
|
71
99
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
100
|
+
version: '2.7'
|
|
73
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
102
|
requirements:
|
|
75
103
|
- - ">="
|