asciidoctor-diagram-layout 1.1.0 → 1.2.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/lib/asciidoctor-diagram-layout.rb +2 -0
- data/lib/asciidoctor_diagram_layout/asciidoc/layout_block_processor.rb +11 -0
- data/lib/asciidoctor_diagram_layout/parser.rb +43 -7
- data/lib/asciidoctor_diagram_layout/renderer/color_palette.rb +23 -7
- data/lib/asciidoctor_diagram_layout/renderer/html_renderer.rb +9 -0
- data/lib/asciidoctor_diagram_layout/renderer/render_options.rb +16 -1
- data/lib/asciidoctor_diagram_layout/renderer/scheme/analogous_scheme.rb +18 -3
- data/lib/asciidoctor_diagram_layout/renderer/scheme/bw_scheme.rb +30 -0
- data/lib/asciidoctor_diagram_layout/renderer/scheme/cell_color_scheme_factory.rb +31 -15
- data/lib/asciidoctor_diagram_layout/renderer/scheme/color_scheme.rb +54 -0
- data/lib/asciidoctor_diagram_layout/renderer/scheme/golden_ratio_scheme.rb +16 -3
- data/lib/asciidoctor_diagram_layout/renderer/scheme/monochromatic_scheme.rb +18 -5
- data/lib/asciidoctor_diagram_layout/renderer/svg_renderer.rb +12 -3
- data/lib/asciidoctor_diagram_layout/version.rb +5 -1
- metadata +20 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d1ea430987d03ed145426e4c655e84179d60300b6e1734bf8dcfecc35ee51123
|
|
4
|
+
data.tar.gz: 1ae0abee9dcc542e84dfbcb67616e96e3906e6c1543344e70791c58ce0780e12
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e019f7be1760dfee233a0802f58b4dce5e97a381b277b5b5f27f7360281a270cce364e50def7f347e47eb3231e6f411635ab0c721798def09dd405779f13e52
|
|
7
|
+
data.tar.gz: a894479dadb8409da37f565b46ea22ea0fce4748ba3ef86d7b669582c581639e0e412d6c0c4a88b2efc73d53e207425dedc049ef37e15bfd6f970c86c511aacb
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
require_relative "asciidoctor_diagram_layout/version"
|
|
2
2
|
require_relative "asciidoctor_diagram_layout/parser"
|
|
3
3
|
require_relative "asciidoctor_diagram_layout/renderer/color_palette"
|
|
4
|
+
require_relative "asciidoctor_diagram_layout/renderer/scheme/color_scheme"
|
|
4
5
|
require_relative "asciidoctor_diagram_layout/renderer/scheme/golden_ratio_scheme"
|
|
5
6
|
require_relative "asciidoctor_diagram_layout/renderer/scheme/analogous_scheme"
|
|
6
7
|
require_relative "asciidoctor_diagram_layout/renderer/scheme/monochromatic_scheme"
|
|
8
|
+
require_relative "asciidoctor_diagram_layout/renderer/scheme/bw_scheme"
|
|
7
9
|
require_relative "asciidoctor_diagram_layout/renderer/scheme/cell_color_scheme_factory"
|
|
8
10
|
require_relative "asciidoctor_diagram_layout/renderer/render_options"
|
|
9
11
|
require_relative "asciidoctor_diagram_layout/renderer/html_renderer"
|
|
@@ -2,13 +2,24 @@ require "asciidoctor"
|
|
|
2
2
|
require "asciidoctor/extensions"
|
|
3
3
|
|
|
4
4
|
module AsciidoctorDiagramLayout
|
|
5
|
+
|
|
6
|
+
# Asciidoctor integration — block processor and extension registration.
|
|
7
|
+
#
|
|
5
8
|
module Asciidoc
|
|
9
|
+
# Asciidoctor block processor for the +[layout]+ block.
|
|
10
|
+
#
|
|
11
|
+
# Parses a DSL body into a layout tree and renders it as inline HTML
|
|
12
|
+
# (HTML backend) or standalone SVG (all other backends).
|
|
6
13
|
class LayoutBlockProcessor < Asciidoctor::Extensions::BlockProcessor
|
|
7
14
|
use_dsl
|
|
8
15
|
named :"layout-rowcol"
|
|
9
16
|
on_contexts :listing, :literal
|
|
10
17
|
name_positional_attributes "target"
|
|
11
18
|
|
|
19
|
+
# @param parent [Asciidoctor::Block] parent block
|
|
20
|
+
# @param reader [Asciidoctor::Reader] DSL source reader
|
|
21
|
+
# @param attrs [Hash] block attributes
|
|
22
|
+
# @return [Asciidoctor::Block] rendered block
|
|
12
23
|
def process(parent, reader, attrs)
|
|
13
24
|
dsl = reader.read
|
|
14
25
|
implicit_dir = attrs["direction"] == "cols" ? :cols : :rows
|
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
|
+
|
|
3
|
+
# Raised when the DSL input is malformed.
|
|
2
4
|
class ParseError < StandardError; end
|
|
3
5
|
|
|
4
|
-
# Parses
|
|
6
|
+
# Parses rowcol layout DSL text into a node tree.
|
|
7
|
+
#
|
|
8
|
+
# Format: one directive per line. Containers (cols, rows) declare
|
|
9
|
+
# a nested block via indentation. Leaf zones use +cell+.
|
|
5
10
|
#
|
|
6
|
-
# Format: one directive per line. Containers (cols, rows) declare
|
|
7
|
-
# a nested block via indentation. Leaf zones use cell.
|
|
8
11
|
# An optional size in parentheses sets a fixed percentage:
|
|
9
|
-
# cell(30): Name
|
|
12
|
+
# cell(30): Name
|
|
13
|
+
# cols(40):
|
|
14
|
+
#
|
|
15
|
+
# @example Two-column layout
|
|
16
|
+
# Parser.new.parse("cols:\n cell: Sidebar\n cell: Content\n")
|
|
17
|
+
#
|
|
10
18
|
class Parser
|
|
11
|
-
LINE_PATTERN = /\A(?<keyword>cols|rows|cell)(?:\((?<size>\d+)\))?:(?<rest>.*)\z/i
|
|
12
|
-
TAB_WIDTH = 4
|
|
19
|
+
LINE_PATTERN = /\A(?<keyword>cols|rows|cell)(?:\((?<size>\d+)\))?:(?<rest>.*)\z/i # :nodoc:
|
|
20
|
+
TAB_WIDTH = 4 # :nodoc:
|
|
13
21
|
|
|
22
|
+
# Parses a DSL string and returns a {ContainerNode} tree root.
|
|
23
|
+
#
|
|
24
|
+
# @param dsl [String] layout DSL
|
|
25
|
+
# @param implicit_direction [Symbol] +:rows+ or +:cols+ — fallback
|
|
26
|
+
# direction when the top-level is a bare cell
|
|
27
|
+
# @return [ContainerNode]
|
|
28
|
+
# @raise [ParseError] on syntax errors or empty input
|
|
14
29
|
def parse(dsl, implicit_direction = :rows)
|
|
15
30
|
lines = dsl.split("\n", -1)
|
|
16
31
|
state = ParseState.new(lines)
|
|
@@ -101,7 +116,11 @@ module AsciidoctorDiagramLayout
|
|
|
101
116
|
end
|
|
102
117
|
end
|
|
103
118
|
|
|
119
|
+
# Internal parser position tracker.
|
|
120
|
+
#
|
|
121
|
+
# @!visibility private
|
|
104
122
|
ParseState = Struct.new(:lines, :index) do
|
|
123
|
+
# :nodoc:
|
|
105
124
|
def initialize(lines)
|
|
106
125
|
super(lines, 0)
|
|
107
126
|
end
|
|
@@ -110,15 +129,32 @@ module AsciidoctorDiagramLayout
|
|
|
110
129
|
index < lines.size
|
|
111
130
|
end
|
|
112
131
|
|
|
132
|
+
# @!visibility private
|
|
113
133
|
def peek
|
|
114
134
|
lines[index]
|
|
115
135
|
end
|
|
116
136
|
|
|
137
|
+
# @!visibility private
|
|
117
138
|
def advance
|
|
118
139
|
self.index += 1
|
|
119
140
|
end
|
|
120
141
|
end
|
|
121
142
|
|
|
143
|
+
# A container node holding child nodes in a row or column direction.
|
|
144
|
+
#
|
|
145
|
+
# @!attribute direction
|
|
146
|
+
# @return [:cols, :rows] flex direction
|
|
147
|
+
# @!attribute size
|
|
148
|
+
# @return [Integer, :auto] percentage of parent or +:auto+ for flex grow
|
|
149
|
+
# @!attribute children
|
|
150
|
+
# @return [Array<ContainerNode, CellNode>]
|
|
122
151
|
ContainerNode = Struct.new(:direction, :size, :children)
|
|
123
|
-
|
|
152
|
+
|
|
153
|
+
# A leaf node representing a named cell.
|
|
154
|
+
#
|
|
155
|
+
# @!attribute size
|
|
156
|
+
# @return [Integer, :auto] percentage of parent or +:auto+ for flex grow
|
|
157
|
+
# @!attribute name
|
|
158
|
+
# @return [String] cell name, may contain AsciiDoc inline macros
|
|
159
|
+
CellNode = Struct.new(:size, :name)
|
|
124
160
|
end
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
|
+
|
|
3
|
+
# Renderer subsystem (HTML and SVG backends).
|
|
4
|
+
#
|
|
2
5
|
module Renderer
|
|
6
|
+
# Utility module for HSL-to-hex conversion and Java-compatible hashing.
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
3
9
|
module ColorPalette
|
|
4
|
-
STROKE_COLOR = "#d0d0d0"
|
|
5
|
-
GOLDEN_RATIO = 0.618033988749895
|
|
6
|
-
HUE_RANGE = 360
|
|
10
|
+
STROKE_COLOR = "#d0d0d0" # :nodoc:
|
|
11
|
+
GOLDEN_RATIO = 0.618033988749895 # :nodoc:
|
|
12
|
+
HUE_RANGE = 360 # :nodoc:
|
|
7
13
|
|
|
8
|
-
# Converts HSL to a hex color string
|
|
14
|
+
# Converts HSL values to a hex color string.
|
|
15
|
+
#
|
|
16
|
+
# @param hue [Integer] hue angle (0..359)
|
|
17
|
+
# @param saturation [Integer] saturation (0..100)
|
|
18
|
+
# @param lightness [Integer] lightness (0..100)
|
|
19
|
+
# @return [String] hex color (e.g. "#d4d4d4")
|
|
9
20
|
def self.hsl_to_hex(hue, saturation, lightness)
|
|
10
21
|
s = saturation / 100.0
|
|
11
22
|
l = lightness / 100.0
|
|
@@ -31,15 +42,20 @@ module AsciidoctorDiagramLayout
|
|
|
31
42
|
format("#%02x%02x%02x", ri.round, gi.round, bi.round)
|
|
32
43
|
end
|
|
33
44
|
|
|
34
|
-
# Java String.
|
|
35
|
-
#
|
|
45
|
+
# Java-compatible String#hashCode.
|
|
46
|
+
#
|
|
47
|
+
# Uses 32-bit signed overflow semantics, identical to the algorithm
|
|
48
|
+
# defined in the Java Language Specification:
|
|
49
|
+
# s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
|
|
50
|
+
#
|
|
51
|
+
# @param str [String]
|
|
52
|
+
# @return [Integer] signed 32-bit hash code
|
|
36
53
|
def self.java_hash(str)
|
|
37
54
|
return 0 if str.nil? || str.empty?
|
|
38
55
|
h = 0
|
|
39
56
|
str.each_char do |c|
|
|
40
57
|
h = (31 * h + c.ord) & 0xffffffff
|
|
41
58
|
end
|
|
42
|
-
# convert to signed 32-bit
|
|
43
59
|
h >= 0x80000000 ? h - 0x100000000 : h
|
|
44
60
|
end
|
|
45
61
|
end
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
|
+
|
|
4
|
+
# Renders a layout node tree to inline HTML (a nested +<div>+ structure).
|
|
5
|
+
#
|
|
6
|
+
# Each cell is a flex item with a CSS linear gradient background.
|
|
7
|
+
#
|
|
3
8
|
class HtmlRenderer
|
|
9
|
+
# :nodoc:
|
|
4
10
|
CELL_BASE = "display:flex; align-items:center; justify-content:center;" \
|
|
5
11
|
" padding:8px; font-weight:bold; font-family:sans-serif;" \
|
|
6
12
|
" min-height:60px; box-sizing:border-box; color:#333;"
|
|
7
13
|
|
|
14
|
+
# @param root [ContainerNode] parsed layout tree
|
|
15
|
+
# @param options [RenderOptions]
|
|
16
|
+
# @return [String] HTML fragment
|
|
8
17
|
def render(root, options = RenderOptions.new)
|
|
9
18
|
sb = +""
|
|
10
19
|
height_style = options.height ? " min-height:#{options.height};" : ""
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
|
+
|
|
4
|
+
# Configuration for a single render pass.
|
|
5
|
+
#
|
|
6
|
+
# @example Custom palette and dimensions
|
|
7
|
+
# RenderOptions.new(width: "800px", height: "400px", palette: "pastel", title: "My Layout")
|
|
8
|
+
#
|
|
3
9
|
class RenderOptions
|
|
4
10
|
attr_reader :width, :height, :title, :color_scheme, :name_converter
|
|
5
11
|
|
|
12
|
+
# @param width [String] CSS width (e.g. "100%", "600px")
|
|
13
|
+
# @param height [String, nil] CSS height or +nil+
|
|
14
|
+
# @param title [String, nil] diagram caption
|
|
15
|
+
# @param palette [String] palette name passed to {Scheme::CellColorSchemeFactory.resolve}
|
|
16
|
+
# @param pdf [Boolean] whether the output backend is PDF
|
|
17
|
+
# @param color_scheme [Scheme::ColorScheme, nil] pre-resolved scheme, skips factory
|
|
18
|
+
# @param name_converter [Proc, nil] Callable receiving a cell name and returning a rendered
|
|
19
|
+
# label. Defaults to XML-escaping.
|
|
20
|
+
#
|
|
6
21
|
def initialize(width: "100%", height: nil, title: nil, palette: "rainbow", pdf: false,
|
|
7
22
|
color_scheme: nil, name_converter: nil)
|
|
8
23
|
@width = width
|
|
9
24
|
@height = height
|
|
10
25
|
@title = title
|
|
11
26
|
@color_scheme = color_scheme || Scheme::CellColorSchemeFactory.resolve(palette, pdf: pdf)
|
|
12
|
-
@name_converter = name_converter ||
|
|
27
|
+
@name_converter = name_converter || ->(text) { escape(text) }
|
|
13
28
|
end
|
|
14
29
|
|
|
15
30
|
private
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
3
|
module Scheme
|
|
4
|
+
|
|
5
|
+
# Varies hue within a limited range around a base hue.
|
|
6
|
+
#
|
|
7
|
+
# Produces visually harmonious palettes (warm or cool) where colors
|
|
8
|
+
# are adjacent on the color wheel.
|
|
9
|
+
#
|
|
4
10
|
class AnalogousScheme
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
include ColorScheme
|
|
12
|
+
|
|
13
|
+
GRADIENT_HUE_SHIFT = 15 # :nodoc:
|
|
14
|
+
STROKE_LIGHTNESS = 65 # :nodoc:
|
|
15
|
+
STROKE_SATURATION = 25 # :nodoc:
|
|
8
16
|
|
|
17
|
+
# @param base_hue [Integer] center hue (0..359)
|
|
18
|
+
# @param hue_range [Integer] total spread in degrees
|
|
19
|
+
# @param saturation [Integer] HSL saturation (0..100)
|
|
20
|
+
# @param lightness [Integer] HSL lightness (0..100)
|
|
9
21
|
def initialize(base_hue, hue_range, saturation, lightness)
|
|
10
22
|
@base_hue = base_hue
|
|
11
23
|
@hue_range = hue_range
|
|
@@ -13,15 +25,18 @@ module AsciidoctorDiagramLayout
|
|
|
13
25
|
@lightness = lightness
|
|
14
26
|
end
|
|
15
27
|
|
|
28
|
+
# :nodoc:
|
|
16
29
|
def fill_color(name)
|
|
17
30
|
ColorPalette.hsl_to_hex(hue(name), @saturation, @lightness)
|
|
18
31
|
end
|
|
19
32
|
|
|
33
|
+
# :nodoc:
|
|
20
34
|
def gradient_end(name)
|
|
21
35
|
ColorPalette.hsl_to_hex((hue(name) + GRADIENT_HUE_SHIFT) % ColorPalette::HUE_RANGE,
|
|
22
36
|
@saturation, @lightness)
|
|
23
37
|
end
|
|
24
38
|
|
|
39
|
+
# :nodoc:
|
|
25
40
|
def stroke_color(name)
|
|
26
41
|
ColorPalette.hsl_to_hex(hue(name), STROKE_SATURATION, STROKE_LIGHTNESS)
|
|
27
42
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module AsciidoctorDiagramLayout
|
|
2
|
+
module Renderer
|
|
3
|
+
module Scheme
|
|
4
|
+
|
|
5
|
+
# Black-and-white scheme — solid white fill, black stroke, no visible gradient.
|
|
6
|
+
#
|
|
7
|
+
class BwScheme
|
|
8
|
+
include ColorScheme
|
|
9
|
+
|
|
10
|
+
FILL_COLOR = "#ffffff" # :nodoc:
|
|
11
|
+
STROKE_COLOR = "#000000" # :nodoc:
|
|
12
|
+
|
|
13
|
+
# :nodoc:
|
|
14
|
+
def fill_color(_name)
|
|
15
|
+
FILL_COLOR
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# :nodoc:
|
|
19
|
+
def gradient_end(name)
|
|
20
|
+
fill_color(name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# :nodoc:
|
|
24
|
+
def stroke_color(_name)
|
|
25
|
+
STROKE_COLOR
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
3
|
module Scheme
|
|
4
|
+
|
|
5
|
+
# Creates a {ColorScheme} instance by palette name.
|
|
6
|
+
#
|
|
4
7
|
module CellColorSchemeFactory
|
|
5
|
-
WARM_BASE_HUE = 30
|
|
6
|
-
COOL_BASE_HUE = 210
|
|
7
|
-
ANALOGOUS_HUE_RANGE = 60
|
|
8
|
-
ANALOGOUS_SATURATION = 25
|
|
9
|
-
ANALOGOUS_LIGHTNESS = 86
|
|
10
|
-
MONO_HUE = 210
|
|
11
|
-
MONO_SATURATION = 20
|
|
12
|
-
DEFAULT_SATURATION = 22
|
|
13
|
-
DEFAULT_LIGHTNESS = 88
|
|
14
|
-
PDF_SATURATION = 15
|
|
15
|
-
PDF_LIGHTNESS = 90
|
|
16
|
-
PASTEL_SATURATION = 18
|
|
17
|
-
PASTEL_LIGHTNESS = 93
|
|
8
|
+
WARM_BASE_HUE = 30 # :nodoc:
|
|
9
|
+
COOL_BASE_HUE = 210 # :nodoc:
|
|
10
|
+
ANALOGOUS_HUE_RANGE = 60 # :nodoc:
|
|
11
|
+
ANALOGOUS_SATURATION = 25 # :nodoc:
|
|
12
|
+
ANALOGOUS_LIGHTNESS = 86 # :nodoc:
|
|
13
|
+
MONO_HUE = 210 # :nodoc:
|
|
14
|
+
MONO_SATURATION = 20 # :nodoc:
|
|
15
|
+
DEFAULT_SATURATION = 22 # :nodoc:
|
|
16
|
+
DEFAULT_LIGHTNESS = 88 # :nodoc:
|
|
17
|
+
PDF_SATURATION = 15 # :nodoc:
|
|
18
|
+
PDF_LIGHTNESS = 90 # :nodoc:
|
|
19
|
+
PASTEL_SATURATION = 18 # :nodoc:
|
|
20
|
+
PASTEL_LIGHTNESS = 93 # :nodoc:
|
|
18
21
|
|
|
22
|
+
# Resolves a palette name to a concrete {ColorScheme} instance.
|
|
23
|
+
#
|
|
24
|
+
# @param name [String] palette name:
|
|
25
|
+
# "rainbow", "pastel", "warm", "cool", "mono", "bw"
|
|
26
|
+
# @param pdf [Boolean] when +true+ and name is "rainbow", uses
|
|
27
|
+
# PDF-optimized saturation and lightness
|
|
28
|
+
# @return [ColorScheme]
|
|
29
|
+
# @raise [ArgumentError] if the name is unknown
|
|
19
30
|
def self.resolve(name, pdf: false)
|
|
20
31
|
key = name.to_s.downcase
|
|
21
32
|
case key
|
|
@@ -27,9 +38,14 @@ module AsciidoctorDiagramLayout
|
|
|
27
38
|
AnalogousScheme.new(COOL_BASE_HUE, ANALOGOUS_HUE_RANGE, ANALOGOUS_SATURATION, ANALOGOUS_LIGHTNESS)
|
|
28
39
|
when "mono"
|
|
29
40
|
MonochromaticScheme.new(MONO_HUE, MONO_SATURATION)
|
|
41
|
+
when "bw"
|
|
42
|
+
BwScheme.new
|
|
43
|
+
when "rainbow"
|
|
44
|
+
saturation = pdf ? PDF_SATURATION : DEFAULT_SATURATION
|
|
45
|
+
lightness = pdf ? PDF_LIGHTNESS : DEFAULT_LIGHTNESS
|
|
46
|
+
GoldenRatioScheme.new(saturation, lightness)
|
|
30
47
|
else
|
|
31
|
-
|
|
32
|
-
: GoldenRatioScheme.new(DEFAULT_SATURATION, DEFAULT_LIGHTNESS)
|
|
48
|
+
raise ArgumentError, "Unknown palette: #{key.inspect}"
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module AsciidoctorDiagramLayout
|
|
2
|
+
module Renderer
|
|
3
|
+
|
|
4
|
+
# Color scheme DSL and implementations.
|
|
5
|
+
#
|
|
6
|
+
module Scheme
|
|
7
|
+
# Defines the duck-type contract for color scheme objects.
|
|
8
|
+
#
|
|
9
|
+
# Every concrete scheme must include this module and override all three
|
|
10
|
+
# methods. Calling an unimplemented method raises +NotImplementedError+
|
|
11
|
+
# with the name of the offending class.
|
|
12
|
+
#
|
|
13
|
+
# @example Minimal implementation (black-and-white)
|
|
14
|
+
# class BwScheme
|
|
15
|
+
# include ColorScheme
|
|
16
|
+
#
|
|
17
|
+
# FILL_COLOR = "#ffffff"
|
|
18
|
+
#
|
|
19
|
+
# def fill_color(_name) = FILL_COLOR
|
|
20
|
+
# def gradient_end(name) = fill_color(name)
|
|
21
|
+
# def stroke_color(_name) = "#000000"
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
module ColorScheme
|
|
25
|
+
# Returns the base fill color for a named cell.
|
|
26
|
+
#
|
|
27
|
+
# @param name [String] cell name, used to derive a color from its hash
|
|
28
|
+
# @return [String] hex color string (e.g. "#d4d4d4")
|
|
29
|
+
def fill_color(name)
|
|
30
|
+
raise NotImplementedError, "#{self.class} must implement #fill_color"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Returns the gradient endpoint color for a named cell.
|
|
34
|
+
#
|
|
35
|
+
# When this equals +#fill_color+ the gradient is imperceptible,
|
|
36
|
+
# producing a visually flat fill.
|
|
37
|
+
#
|
|
38
|
+
# @param name [String] cell name
|
|
39
|
+
# @return [String] hex color string
|
|
40
|
+
def gradient_end(name)
|
|
41
|
+
raise NotImplementedError, "#{self.class} must implement #gradient_end"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the stroke (border) color for a named cell.
|
|
45
|
+
#
|
|
46
|
+
# @param name [String] cell name
|
|
47
|
+
# @return [String] hex color string
|
|
48
|
+
def stroke_color(name)
|
|
49
|
+
raise NotImplementedError, "#{self.class} must implement #stroke_color"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
3
|
module Scheme
|
|
4
|
+
|
|
5
|
+
# Spreads hues across the full 360-degree range using the golden ratio.
|
|
6
|
+
#
|
|
7
|
+
# Each cell name's Java hash determines its position on the hue circle,
|
|
8
|
+
# ensuring visually distinct colors for adjacent names.
|
|
9
|
+
#
|
|
4
10
|
class GoldenRatioScheme
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
include ColorScheme
|
|
12
|
+
|
|
13
|
+
GRADIENT_HUE_SHIFT = 20 # :nodoc:
|
|
14
|
+
STROKE_LIGHTNESS = 65 # :nodoc:
|
|
15
|
+
STROKE_SATURATION = 30 # :nodoc:
|
|
8
16
|
|
|
17
|
+
# @param saturation [Integer] HSL saturation (0..100)
|
|
18
|
+
# @param lightness [Integer] HSL lightness (0..100)
|
|
9
19
|
def initialize(saturation, lightness)
|
|
10
20
|
@saturation = saturation
|
|
11
21
|
@lightness = lightness
|
|
12
22
|
end
|
|
13
23
|
|
|
24
|
+
# :nodoc:
|
|
14
25
|
def fill_color(name)
|
|
15
26
|
ColorPalette.hsl_to_hex(hue(name), @saturation, @lightness)
|
|
16
27
|
end
|
|
17
28
|
|
|
29
|
+
# :nodoc:
|
|
18
30
|
def gradient_end(name)
|
|
19
31
|
ColorPalette.hsl_to_hex((hue(name) + GRADIENT_HUE_SHIFT) % ColorPalette::HUE_RANGE,
|
|
20
32
|
@saturation, @lightness)
|
|
21
33
|
end
|
|
22
34
|
|
|
35
|
+
# :nodoc:
|
|
23
36
|
def stroke_color(name)
|
|
24
37
|
ColorPalette.hsl_to_hex(hue(name), STROKE_SATURATION, STROKE_LIGHTNESS)
|
|
25
38
|
end
|
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
3
|
module Scheme
|
|
4
|
+
|
|
5
|
+
# Varies only lightness while keeping hue and saturation fixed.
|
|
6
|
+
#
|
|
7
|
+
# Produces a single-color palette with subtle brightness differences
|
|
8
|
+
# between cells.
|
|
9
|
+
#
|
|
4
10
|
class MonochromaticScheme
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
include ColorScheme
|
|
12
|
+
|
|
13
|
+
LIGHTNESS_MIN = 75 # :nodoc:
|
|
14
|
+
LIGHTNESS_MAX = 95 # :nodoc:
|
|
15
|
+
GRADIENT_SHIFT = 5 # :nodoc:
|
|
16
|
+
STROKE_LIGHTNESS = 60 # :nodoc:
|
|
17
|
+
STROKE_SATURATION = 20 # :nodoc:
|
|
10
18
|
|
|
19
|
+
# @param hue [Integer] fixed hue (0..359)
|
|
20
|
+
# @param saturation [Integer] HSL saturation (0..100)
|
|
11
21
|
def initialize(hue, saturation)
|
|
12
22
|
@hue = hue
|
|
13
23
|
@saturation = saturation
|
|
14
24
|
end
|
|
15
25
|
|
|
26
|
+
# :nodoc:
|
|
16
27
|
def fill_color(name)
|
|
17
28
|
ColorPalette.hsl_to_hex(@hue, @saturation, lightness(name))
|
|
18
29
|
end
|
|
19
30
|
|
|
31
|
+
# :nodoc:
|
|
20
32
|
def gradient_end(name)
|
|
21
33
|
l = [lightness(name) + GRADIENT_SHIFT, 98].min
|
|
22
34
|
ColorPalette.hsl_to_hex(@hue, @saturation, l)
|
|
23
35
|
end
|
|
24
36
|
|
|
37
|
+
# :nodoc:
|
|
25
38
|
def stroke_color(name)
|
|
26
39
|
ColorPalette.hsl_to_hex(@hue, STROKE_SATURATION, STROKE_LIGHTNESS)
|
|
27
40
|
end
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
module AsciidoctorDiagramLayout
|
|
2
2
|
module Renderer
|
|
3
|
+
|
|
4
|
+
# Renders a layout node tree to SVG.
|
|
5
|
+
#
|
|
6
|
+
# Each cell produces a +<rect>+ with a linear gradient fill and centered
|
|
7
|
+
# bold text.
|
|
8
|
+
#
|
|
3
9
|
class SvgRenderer
|
|
4
|
-
DEFAULT_WIDTH = 600
|
|
5
|
-
DEFAULT_HEIGHT = 300
|
|
6
|
-
FONT_SIZE = 14
|
|
10
|
+
DEFAULT_WIDTH = 600 # :nodoc:
|
|
11
|
+
DEFAULT_HEIGHT = 300 # :nodoc:
|
|
12
|
+
FONT_SIZE = 14 # :nodoc:
|
|
7
13
|
|
|
14
|
+
# @param root [ContainerNode] parsed layout tree
|
|
15
|
+
# @param options [RenderOptions]
|
|
16
|
+
# @return [String] SVG document
|
|
8
17
|
def render(root, options = RenderOptions.new)
|
|
9
18
|
w = parse_px(options.width, DEFAULT_WIDTH)
|
|
10
19
|
h = parse_px(options.height, DEFAULT_HEIGHT)
|
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.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Pechinsky
|
|
@@ -65,8 +65,22 @@ dependencies:
|
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: yard
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.9'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.9'
|
|
82
|
+
description: Provides a [layout] block for Asciidoctor that renders rowcol layout
|
|
83
|
+
diagrams as HTML or SVG.
|
|
70
84
|
email: anton@pechinsky.com
|
|
71
85
|
executables: []
|
|
72
86
|
extensions: []
|
|
@@ -81,7 +95,9 @@ files:
|
|
|
81
95
|
- lib/asciidoctor_diagram_layout/renderer/html_renderer.rb
|
|
82
96
|
- lib/asciidoctor_diagram_layout/renderer/render_options.rb
|
|
83
97
|
- lib/asciidoctor_diagram_layout/renderer/scheme/analogous_scheme.rb
|
|
98
|
+
- lib/asciidoctor_diagram_layout/renderer/scheme/bw_scheme.rb
|
|
84
99
|
- lib/asciidoctor_diagram_layout/renderer/scheme/cell_color_scheme_factory.rb
|
|
100
|
+
- lib/asciidoctor_diagram_layout/renderer/scheme/color_scheme.rb
|
|
85
101
|
- lib/asciidoctor_diagram_layout/renderer/scheme/golden_ratio_scheme.rb
|
|
86
102
|
- lib/asciidoctor_diagram_layout/renderer/scheme/monochromatic_scheme.rb
|
|
87
103
|
- lib/asciidoctor_diagram_layout/renderer/svg_renderer.rb
|
|
@@ -106,5 +122,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
106
122
|
requirements: []
|
|
107
123
|
rubygems_version: 3.6.9
|
|
108
124
|
specification_version: 4
|
|
109
|
-
summary: Asciidoctor extension for rendering
|
|
125
|
+
summary: Asciidoctor extension for rendering rowcol layout diagrams
|
|
110
126
|
test_files: []
|