stego-cli 0.4.2 → 0.5.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.
- package/README.md +68 -22
- package/dist/shared/src/domain/frontmatter/validators.js +20 -2
- package/dist/shared/src/domain/images/index.js +1 -0
- package/dist/shared/src/domain/images/style.js +185 -0
- package/dist/shared/src/index.js +1 -0
- package/dist/stego-cli/src/app/command-registry.js +93 -1
- package/dist/stego-cli/src/app/create-cli-app.js +3 -0
- package/dist/stego-cli/src/app/error-boundary.js +11 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-add.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-clear-resolved.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-delete.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-read.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-reply.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-set-status.js +0 -1
- package/dist/stego-cli/src/modules/comments/commands/comments-sync-anchors.js +0 -1
- package/dist/stego-cli/src/modules/compile/application/compile-manuscript.js +12 -1
- package/dist/stego-cli/src/modules/compile/commands/build.js +1 -2
- package/dist/stego-cli/src/modules/compile/domain/compile-structure.js +0 -3
- package/dist/stego-cli/src/modules/compile/domain/image-settings.js +394 -0
- package/dist/stego-cli/src/modules/export/application/run-export.js +22 -1
- package/dist/stego-cli/src/modules/export/commands/export.js +1 -2
- package/dist/stego-cli/src/modules/export/infra/pandoc-exporter.js +29 -2
- package/dist/stego-cli/src/modules/manuscript/commands/new-manuscript.js +1 -1
- package/dist/stego-cli/src/modules/project/application/create-project.js +41 -1
- package/dist/stego-cli/src/modules/project/application/infer-project.js +1 -1
- package/dist/stego-cli/src/modules/project/commands/new-project.js +1 -1
- package/dist/stego-cli/src/modules/quality/application/inspect-project.js +147 -112
- package/dist/stego-cli/src/modules/quality/commands/check-stage.js +1 -2
- package/dist/stego-cli/src/modules/quality/commands/lint.js +1 -2
- package/dist/stego-cli/src/modules/quality/commands/validate.js +1 -2
- package/dist/stego-cli/src/modules/scaffold/commands/init.js +2 -2
- package/dist/stego-cli/src/modules/scaffold/domain/templates.js +15 -14
- package/dist/stego-cli/src/modules/spine/commands/spine-deprecated-aliases.js +2 -2
- package/dist/stego-cli/src/modules/spine/commands/spine-new-category.js +1 -2
- package/dist/stego-cli/src/modules/spine/commands/spine-new-entry.js +1 -2
- package/dist/stego-cli/src/modules/spine/commands/spine-read.js +1 -2
- package/filters/image-layout.css +23 -0
- package/filters/image-layout.lua +170 -0
- package/package.json +4 -2
- package/projects/fiction-example/assets/README.md +31 -0
- package/projects/stego-docs/assets/README.md +31 -0
- package/projects/stego-docs/manuscript/500-project-configuration.md +37 -0
- package/projects/stego-docs/manuscript/800-build-export-and-release-outputs.md +4 -0
- package/dist/stego-cli/src/modules/manuscript/domain/manuscript.js +0 -1
- package/dist/stego-cli/src/modules/project/domain/project.js +0 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
local function get_image_attr(img, key)
|
|
2
|
+
if not img or not img.attributes then
|
|
3
|
+
return nil
|
|
4
|
+
end
|
|
5
|
+
local value = img.attributes[key]
|
|
6
|
+
if value == nil or value == "" then
|
|
7
|
+
return nil
|
|
8
|
+
end
|
|
9
|
+
return value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
local function get_layout(img)
|
|
13
|
+
local layout = get_image_attr(img, "layout") or get_image_attr(img, "data-layout")
|
|
14
|
+
if layout == "block" or layout == "inline" then
|
|
15
|
+
return layout
|
|
16
|
+
end
|
|
17
|
+
return nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
local function get_align(img)
|
|
21
|
+
local align = get_image_attr(img, "align") or get_image_attr(img, "data-align")
|
|
22
|
+
if align == "left" or align == "center" or align == "right" then
|
|
23
|
+
return align
|
|
24
|
+
end
|
|
25
|
+
return nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
local function extract_single_image(block)
|
|
29
|
+
if not block or not (block.t == "Para" or block.t == "Plain") then
|
|
30
|
+
return nil
|
|
31
|
+
end
|
|
32
|
+
if #block.content ~= 1 then
|
|
33
|
+
return nil
|
|
34
|
+
end
|
|
35
|
+
local img = block.content[1]
|
|
36
|
+
if not img or img.t ~= "Image" then
|
|
37
|
+
return nil
|
|
38
|
+
end
|
|
39
|
+
return img
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
local function append_css_rule(existing, rule)
|
|
43
|
+
if not rule or rule == "" then
|
|
44
|
+
return existing
|
|
45
|
+
end
|
|
46
|
+
if not existing or existing == "" then
|
|
47
|
+
return rule
|
|
48
|
+
end
|
|
49
|
+
if existing:match(rule, 1, true) then
|
|
50
|
+
return existing
|
|
51
|
+
end
|
|
52
|
+
return existing .. " " .. rule
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
local function apply_html_layout_alignment(img)
|
|
56
|
+
local layout = get_layout(img)
|
|
57
|
+
local align = get_align(img)
|
|
58
|
+
if not layout and not align then
|
|
59
|
+
return img
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
local effective_layout = layout
|
|
63
|
+
if not effective_layout and align then
|
|
64
|
+
effective_layout = "block"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
local style = get_image_attr(img, "style") or ""
|
|
68
|
+
|
|
69
|
+
if effective_layout == "block" then
|
|
70
|
+
style = append_css_rule(style, "display:block;")
|
|
71
|
+
elseif effective_layout == "inline" then
|
|
72
|
+
style = append_css_rule(style, "display:inline;")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if effective_layout ~= "inline" then
|
|
76
|
+
if align == "left" then
|
|
77
|
+
style = append_css_rule(style, "margin-left:0; margin-right:auto;")
|
|
78
|
+
elseif align == "right" then
|
|
79
|
+
style = append_css_rule(style, "margin-left:auto; margin-right:0;")
|
|
80
|
+
elseif align == "center" then
|
|
81
|
+
style = append_css_rule(style, "margin-left:auto; margin-right:auto;")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
if style ~= "" then
|
|
86
|
+
img.attributes["style"] = style
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
return img
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
local function wrap_latex_image_alignment(block, align)
|
|
93
|
+
if not align then
|
|
94
|
+
return block
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
local code = nil
|
|
98
|
+
if align == "left" then
|
|
99
|
+
code = "l"
|
|
100
|
+
elseif align == "center" then
|
|
101
|
+
code = "c"
|
|
102
|
+
elseif align == "right" then
|
|
103
|
+
code = "r"
|
|
104
|
+
end
|
|
105
|
+
if not code then
|
|
106
|
+
return block
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
table.insert(block.content, 1, pandoc.RawInline("latex", "\\makebox[\\linewidth][" .. code .. "]{"))
|
|
110
|
+
table.insert(block.content, pandoc.RawInline("latex", "}"))
|
|
111
|
+
return block
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
function Image(img)
|
|
115
|
+
if FORMAT:match("html") or FORMAT:match("epub") or FORMAT:match("revealjs") then
|
|
116
|
+
return apply_html_layout_alignment(img)
|
|
117
|
+
end
|
|
118
|
+
return img
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
function Figure(fig)
|
|
122
|
+
if not FORMAT:match("latex") then
|
|
123
|
+
return nil
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if #fig.content ~= 1 then
|
|
127
|
+
return nil
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
local block = fig.content[1]
|
|
131
|
+
local img = extract_single_image(block)
|
|
132
|
+
if not img then
|
|
133
|
+
return nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
local layout = get_layout(img)
|
|
137
|
+
local align = get_align(img)
|
|
138
|
+
if not layout and not align then
|
|
139
|
+
return nil
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if layout == "inline" then
|
|
143
|
+
return pandoc.Para({ img })
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
fig.content[1] = wrap_latex_image_alignment(block, align)
|
|
147
|
+
return fig
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
function Para(para)
|
|
151
|
+
if not FORMAT:match("latex") then
|
|
152
|
+
return nil
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
local img = extract_single_image(para)
|
|
156
|
+
if not img then
|
|
157
|
+
return nil
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
local layout = get_layout(img)
|
|
161
|
+
local align = get_align(img)
|
|
162
|
+
if layout == "inline" then
|
|
163
|
+
return nil
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if align then
|
|
167
|
+
return wrap_latex_image_alignment(para, align)
|
|
168
|
+
end
|
|
169
|
+
return nil
|
|
170
|
+
end
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stego-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Installable CLI for the Stego writing monorepo workflow.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"dist/**",
|
|
24
|
+
"filters/**",
|
|
24
25
|
"projects/**",
|
|
25
26
|
"!projects/local-only/**",
|
|
26
27
|
"!projects/*/dist/*.md",
|
|
@@ -52,9 +53,10 @@
|
|
|
52
53
|
"test:compile-structure": "node --test tools/test/compile-structure.test.mjs",
|
|
53
54
|
"test:comments": "node --test tools/test/comments-add.test.mjs",
|
|
54
55
|
"test:cli-core": "node --test tools/test/cli-core.test.mjs",
|
|
56
|
+
"test:image-support": "node --test tools/test/image-support.test.mjs",
|
|
55
57
|
"test:spine-v2": "node --test tools/test/spine-v2.test.mjs",
|
|
56
58
|
"test:workspace-project": "node --test tools/test/workspace-project.test.mjs",
|
|
57
|
-
"test": "npm run test:compile-structure && npm run test:comments && npm run test:cli-core && npm run test:spine-v2 && npm run test:workspace-project && npm run check:module-apis && npm run check:boundaries",
|
|
59
|
+
"test": "npm run test:compile-structure && npm run test:comments && npm run test:cli-core && npm run test:image-support && npm run test:spine-v2 && npm run test:workspace-project && npm run check:module-apis && npm run check:boundaries",
|
|
58
60
|
"check:boundaries": "node scripts/check-module-boundaries.mjs",
|
|
59
61
|
"check:module-apis": "node scripts/check-module-apis.mjs"
|
|
60
62
|
},
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Assets
|
|
2
|
+
|
|
3
|
+
Store manuscript images in this directory (or nested subdirectories).
|
|
4
|
+
|
|
5
|
+
Reference them from manuscript files with Markdown image syntax, for example:
|
|
6
|
+
|
|
7
|
+
```md
|
|
8
|
+

|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Set global image defaults in `stego-project.json`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"images": {
|
|
16
|
+
"layout": "block",
|
|
17
|
+
"align": "center",
|
|
18
|
+
"width": "50%"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Use manuscript frontmatter `images` only for per-path overrides:
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
images:
|
|
27
|
+
assets/maps/city-plan.png:
|
|
28
|
+
layout: inline
|
|
29
|
+
align: left
|
|
30
|
+
width: 100%
|
|
31
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Assets
|
|
2
|
+
|
|
3
|
+
Store manuscript images in this directory (or nested subdirectories).
|
|
4
|
+
|
|
5
|
+
Reference them from manuscript files with Markdown image syntax, for example:
|
|
6
|
+
|
|
7
|
+
```md
|
|
8
|
+

|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Set global image defaults in `stego-project.json`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"images": {
|
|
16
|
+
"layout": "block",
|
|
17
|
+
"align": "center",
|
|
18
|
+
"width": "60%"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Use manuscript frontmatter `images` only for per-path overrides:
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
images:
|
|
27
|
+
assets/diagrams/system-overview.png:
|
|
28
|
+
layout: inline
|
|
29
|
+
align: left
|
|
30
|
+
width: 100%
|
|
31
|
+
```
|
|
@@ -41,6 +41,43 @@ Stego reports missing keys as warnings so teams can standardize frontmatter with
|
|
|
41
41
|
|
|
42
42
|
Common keys include `status`, grouping fields such as `chapter`, and project-specific metadata such as point of view or timeline.
|
|
43
43
|
|
|
44
|
+
## Manuscript image settings
|
|
45
|
+
|
|
46
|
+
Stego projects use `assets/` for local manuscript images.
|
|
47
|
+
|
|
48
|
+
Project-level image defaults belong in `stego-project.json`:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"images": {
|
|
53
|
+
"layout": "block",
|
|
54
|
+
"align": "center",
|
|
55
|
+
"width": "50%",
|
|
56
|
+
"classes": ["illustration"]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Manuscript files can define per-path overrides with `images` frontmatter:
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
images:
|
|
65
|
+
assets/maps/city-plan.png:
|
|
66
|
+
layout: inline
|
|
67
|
+
align: left
|
|
68
|
+
width: 100%
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Global keys are `width`, `height`, `classes`, `id`, `attrs`, `layout`, and `align`, but those defaults should be set in project config.
|
|
72
|
+
|
|
73
|
+
All manuscript-frontmatter keys under `images` are treated as per-image overrides by project-relative asset path.
|
|
74
|
+
|
|
75
|
+
`layout` and `align` are emitted in compiled markdown as `data-layout` and `data-align` image attrs.
|
|
76
|
+
|
|
77
|
+
When the same image also has inline Pandoc attrs in markdown, inline attrs win.
|
|
78
|
+
|
|
79
|
+
Validation warns if a local image target is outside `assets/`.
|
|
80
|
+
|
|
44
81
|
## Compile structure
|
|
45
82
|
|
|
46
83
|
Projects can define `compileStructure.levels` to group manuscript files during build.
|
|
@@ -36,6 +36,10 @@ Generated files in `dist/` should not be hand-edited.
|
|
|
36
36
|
|
|
37
37
|
`stego export` supports markdown output directly and optional richer formats through Pandoc, including docx, pdf, and epub.
|
|
38
38
|
|
|
39
|
+
For local manuscript images, keep files in `assets/`. Stego exports with project-aware resource paths so image references in compiled markdown can resolve during Pandoc conversion.
|
|
40
|
+
|
|
41
|
+
EPUB exports include a default stylesheet for image layout metadata (`data-layout` and `data-align`), so block/inline and left/center/right image alignment rules apply without extra setup.
|
|
42
|
+
|
|
39
43
|
If you export pdf through Pandoc, you also need a compatible PDF engine installed on your machine.
|
|
40
44
|
|
|
41
45
|
## Recommended release sequence
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|