Skip to content
4 changes: 2 additions & 2 deletions .codebuddy/skills/pagx/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: >-
ones for size and rendering performance. Use when user asks to create, write, or
design PAGX content, optimize or simplify a .pagx file, review PAGX structure, run
pagx CLI commands (render, validate, format, optimize, bounds, font info/embed,
convert), or look up PAGX element attributes and syntax.
import, export), or look up PAGX element attributes and syntax.
---

# PAGX Skill
Expand Down Expand Up @@ -44,4 +44,4 @@ generation or optimization task.
| `spec-essentials.md` | Node types, Layer rendering pipeline, painter scope, text system, masking, resources |
| `design-patterns.md` | Structure decisions (Layer vs Group), text layout patterns, practical pitfall patterns |
| `attributes.md` | Attribute defaults, enumerations, required attributes |
| `cli.md` | CLI commands — `render`, `validate`, `optimize`, `format`, `bounds`, `font info`, `font embed`, `convert` |
| `cli.md` | CLI commands — `render`, `validate`, `optimize`, `format`, `bounds`, `font info`, `font embed`, `import`, `export` |
65 changes: 43 additions & 22 deletions .codebuddy/skills/pagx/references/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,32 +220,53 @@ primary font. System fallback fonts are always appended after user-specified fal

---

## pagx convert
## pagx import

Convert between PAGX and other formats. The conversion direction is inferred from file
extensions (e.g., `.pagx` → `.svg` or `.svg` → `.pagx`). Loads the input, converts the
document, and writes the result. Import warnings are printed but do not prevent conversion.
Import a file from another format (e.g. SVG) and convert it to PAGX. The input format is
inferred from the file extension unless `--format` is specified. Import warnings are printed
but do not prevent conversion.

```bash
pagx convert input.pagx output.svg # PAGX to SVG
pagx convert input.svg output.pagx # SVG to PAGX
pagx convert --indent 4 input.pagx output.svg # PAGX to SVG with 4-space indent
pagx convert --no-xml-declaration input.pagx out.svg
pagx convert --no-convert-text-to-path input.pagx out.svg # keep <text> elements
pagx convert --format svg input.pagx output # specify SVG output format
pagx convert --no-expand-use input.svg output.pagx # SVG to PAGX without expanding <use>
pagx import --input icon.svg # SVG to icon.pagx
pagx import --input icon.svg --output out.pagx # SVG to out.pagx
pagx import --format svg --input drawing.xml # force treating drawing.xml as SVG format
```

| Option | Description |
|--------|-------------|
| `--format <format>` | Override output format (`svg`, `pagx`; default: inferred from output extension) |
| `--indent <n>` | SVG indentation spaces (default: 2, valid range: 0–16) |
| `--no-xml-declaration` | Omit the `<?xml ...?>` declaration (SVG output only) |
| `--no-convert-text-to-path` | Keep text as `<text>` elements instead of converting to `<path>` (SVG output only) |
| `--no-expand-use` | Do not expand `<use>` references (SVG input only) |
| `--flatten-transforms` | Flatten nested transforms into single matrices (SVG input only) |
| `--preserve-unknown` | Preserve unsupported SVG elements as Unknown nodes (SVG input only) |

The command takes two positional arguments: `<input>` and `<output>`. Use `--format` when the
output extension does not make the format unambiguous. On success the command prints
`pagx convert: wrote <path>` and exits 0; on failure it prints an error and exits 1.
| `--input <file>` | Input file to import (required) |
| `--output <file>` | Output PAGX file (default: `<input>.pagx`) |
Comment thread
OnionsYu marked this conversation as resolved.
| `--format <format>` | Force input format (`svg`; default: inferred from input extension) |
| `--svg-no-expand-use` | Do not expand `<use>` references |
| `--svg-flatten-transforms` | Flatten nested transforms into single matrices |
| `--svg-preserve-unknown` | Preserve unsupported SVG elements as Unknown nodes |

On success the command prints `pagx import: wrote <path>` and exits 0; on failure it prints
an error and exits 1.

---

## pagx export

Export a PAGX file to another format (e.g. SVG). The output format is inferred from the
output file extension. If neither `--format` nor a recognizable output extension is provided,
the command reports an error.

```bash
pagx export --input icon.pagx # PAGX to icon.svg
pagx export --input icon.pagx --output out.svg # PAGX to out.svg
pagx export --format svg --input icon.pagx # force SVG output format
pagx export --input icon.pagx --svg-indent 4 # 4-space indent
```

| Option | Description |
|--------|-------------|
| `--input <file>` | Input PAGX file (required) |
| `--output <file>` | Output file (default: `<input>.<format>`) |
| `--format <format>` | Output format (`svg`; inferred from output extension). Required if output has no extension |
| `--svg-indent <n>` | Indentation spaces (default: 2, valid range: 0–16) |
| `--svg-no-xml-declaration` | Omit the `<?xml ...?>` declaration |
| `--svg-no-convert-text-to-path` | Keep text as `<text>` elements instead of `<path>` |

On success the command prints `pagx export: wrote <path>` and exits 0; on failure it prints
an error and exits 1.
28 changes: 28 additions & 0 deletions src/cli/CliUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,34 @@ inline std::shared_ptr<tgfx::Typeface> ResolveFallbackTypeface(const std::string
return ResolveSystemTypeface(family, style);
}

/**
* Extracts the file extension from a path (without the dot) in lowercase, or returns an empty
* string if none.
*/
inline std::string GetFileExtension(const std::string& path) {
auto dot = path.rfind('.');
if (dot != std::string::npos) {
auto ext = path.substr(dot + 1);
for (auto& ch : ext) {
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}
return ext;
}
return {};
}

/**
* Replaces the file extension in a path with a new extension. If the path has no extension, appends
* the new extension.
*/
inline std::string ReplaceExtension(const std::string& path, const std::string& newExt) {
auto dot = path.rfind('.');
if (dot != std::string::npos) {
return path.substr(0, dot + 1) + newExt;
}
return path + "." + newExt;
}

inline std::string EscapeJson(const std::string& input) {
std::string result = {};
result.reserve(input.size() + 16);
Expand Down
235 changes: 0 additions & 235 deletions src/cli/CommandConvert.cpp

This file was deleted.

Loading
Loading