Compare commits
10 commits
b397823fd2
...
788b5c1688
| Author | SHA1 | Date | |
|---|---|---|---|
| 788b5c1688 | |||
| 1739c70f43 | |||
| 14b8e0c2b9 | |||
| 107621b855 | |||
| e41f315b98 | |||
| 41ffaf0268 | |||
| 1d4f41efc5 | |||
| 5303c5da7f | |||
| 94baff6050 | |||
| 23697670f8 |
38
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-${{ matrix.ubuntu }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
ubuntu: ["22.04", "24.04"]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
|
- name: Install test deps
|
||||||
|
run: |
|
||||||
|
pip install pytest
|
||||||
|
sudo apt-get install -y bats shellcheck inkscape
|
||||||
|
|
||||||
|
- name: Python unit tests
|
||||||
|
run: pytest tests/test_merge_prefs.py -v
|
||||||
|
|
||||||
|
- name: Shellcheck
|
||||||
|
run: |
|
||||||
|
shellcheck install.sh
|
||||||
|
shellcheck uninstall.sh
|
||||||
|
shellcheck scripts/detect_platform.sh
|
||||||
|
|
||||||
|
- name: Bats integration tests
|
||||||
|
run: bats tests/test_install.bats
|
||||||
1
.gitignore
vendored
|
|
@ -5,3 +5,4 @@ __pycache__/
|
||||||
.venv/
|
.venv/
|
||||||
*.bak
|
*.bak
|
||||||
tests/fixtures/prefs-missing/.keep
|
tests/fixtures/prefs-missing/.keep
|
||||||
|
.coverage
|
||||||
|
|
|
||||||
82
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Contributing to Illuscape
|
||||||
|
|
||||||
|
Thank you for helping make Inkscape more accessible to Illustrator migrants.
|
||||||
|
|
||||||
|
## How to add a keyboard shortcut
|
||||||
|
|
||||||
|
1. Open `config/keys/illustrator-cc.xml` and/or `config/keys/illustrator-cs6.xml`
|
||||||
|
2. Add a `<bind>` element:
|
||||||
|
```xml
|
||||||
|
<bind key="KEY" action="INKSCAPE_ACTION" modifiers="Primary,Shift" />
|
||||||
|
```
|
||||||
|
Valid modifiers: `Primary` (Ctrl/Cmd), `Shift`, `Alt`. Omit `modifiers=""` for bare keys.
|
||||||
|
3. Find Inkscape action names via `inkscape --action-list` on your system
|
||||||
|
4. Update the shortcut table in `README.md`
|
||||||
|
5. Update the shortcut comparison table in the spec if the shortcut differs between CC and CS6
|
||||||
|
|
||||||
|
## How to add a color palette
|
||||||
|
|
||||||
|
1. Create `config/palettes/YourPalette.gpl` following GPL format:
|
||||||
|
```
|
||||||
|
GIMP Palette
|
||||||
|
Name: Your Palette Name
|
||||||
|
Columns: 8
|
||||||
|
#
|
||||||
|
255 0 0 Red
|
||||||
|
...
|
||||||
|
```
|
||||||
|
2. Add the filename to `uninstall.sh`'s `remove_files()` function so it gets cleaned up
|
||||||
|
3. The palette will be installed automatically by `install.sh` (it copies all `*.gpl` files)
|
||||||
|
|
||||||
|
## How to add a document template
|
||||||
|
|
||||||
|
1. Create an SVG at `config/templates/YourTemplate.svg`
|
||||||
|
2. Include a `sodipodi:namedview` element with appropriate canvas settings
|
||||||
|
3. Add the filename to `uninstall.sh`'s `remove_files()` function
|
||||||
|
4. The template will be installed automatically by `install.sh` (copies all `*.svg` files)
|
||||||
|
|
||||||
|
## How to add a preference
|
||||||
|
|
||||||
|
Preferences live in `config/preferences-patch.xml`. The XML merge algorithm (in
|
||||||
|
`scripts/merge_prefs.py`) does an upsert: it walks the patch tree, matches nodes
|
||||||
|
by their `id` attribute, and sets only the attributes present in the patch. It
|
||||||
|
never deletes nodes or attributes.
|
||||||
|
|
||||||
|
To add a new preference:
|
||||||
|
1. Find the relevant node in Inkscape's `preferences.xml` on a running install
|
||||||
|
2. Add the node/attribute to `config/preferences-patch.xml` with the correct `id` values
|
||||||
|
3. Write a test in `tests/test_merge_prefs.py` that verifies the attribute is set
|
||||||
|
4. Run `conda run -n cf python3 -m pytest tests/test_merge_prefs.py -v` to verify
|
||||||
|
|
||||||
|
## Running tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Python unit tests (merge algorithm)
|
||||||
|
conda run -n cf python3 -m pytest tests/test_merge_prefs.py -v
|
||||||
|
|
||||||
|
# Integration tests (requires bats-core)
|
||||||
|
bats tests/test_install.bats
|
||||||
|
|
||||||
|
# Validate all config files
|
||||||
|
conda run -n cf python3 -c "
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
from pathlib import Path
|
||||||
|
for f in [*Path('config/keys').glob('*.xml'), *Path('config/templates').glob('*.svg'),
|
||||||
|
*Path('config/symbols').glob('*.svg'), Path('config/preferences-patch.xml')]:
|
||||||
|
ET.parse(f)
|
||||||
|
print(f'OK {f}')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commit format
|
||||||
|
|
||||||
|
```
|
||||||
|
feat: add <shortcut/palette/template>
|
||||||
|
fix: correct <behavior>
|
||||||
|
test: add test for <scenario>
|
||||||
|
docs: update <section>
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions are released under the MIT license.
|
||||||
78
README.md
|
|
@ -6,6 +6,26 @@ Illuscape patches Inkscape's config to match Illustrator's keyboard shortcuts,
|
||||||
workspace layout, scroll/zoom behavior, color palettes, and document templates —
|
workspace layout, scroll/zoom behavior, color palettes, and document templates —
|
||||||
without modifying Inkscape itself.
|
without modifying Inkscape itself.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
| Feature | Detail |
|
||||||
|
|---------|--------|
|
||||||
|
| Keyboard shortcuts | Adobe Illustrator CC or CS6 presets — your choice at install |
|
||||||
|
| Scroll/zoom | Mouse wheel pans (not zooms); Ctrl+wheel zooms — matching Illustrator |
|
||||||
|
| Canvas | White background, cyan guides, rubber-band selection (touching, not enclosed) |
|
||||||
|
| Node handles | Square handles, rotation handles hidden until needed |
|
||||||
|
| Palettes | Illustrator Defaults, Grays, and Earth Tones swatches |
|
||||||
|
| Templates | Letter, A4, Web 1920x1080, Web 1280x720, Print CMYK Letter, Print CMYK A4 |
|
||||||
|
| Symbols | Common symbol library (arrows, checkmark, star, cross) |
|
||||||
|
| Recent files | 20 (matching Illustrator; Inkscape default is 4) |
|
||||||
|
| Single-window mode | On by default |
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Inkscape 1.2 or later
|
||||||
|
- Python 3.8+
|
||||||
|
- Bash 4+
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -14,7 +34,21 @@ cd illuscape
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Follow the prompt to select your Illustrator era (CC or CS6), then open Inkscape.
|
Follow the prompt to choose your Illustrator era (CC or CS6), then open Inkscape.
|
||||||
|
|
||||||
|
### Non-interactive (for scripts / MenagerieOS)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./install.sh --preset=cc --yes
|
||||||
|
# or
|
||||||
|
./install.sh --preset=cs6 --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Supported Inkscape installs
|
||||||
|
|
||||||
|
- Native (apt, pacman, etc.)
|
||||||
|
- Flatpak (`org.inkscape.Inkscape`)
|
||||||
|
- Snap
|
||||||
|
|
||||||
## Uninstall
|
## Uninstall
|
||||||
|
|
||||||
|
|
@ -22,8 +56,46 @@ Follow the prompt to select your Illustrator era (CC or CS6), then open Inkscape
|
||||||
./uninstall.sh
|
./uninstall.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Your original Inkscape config is restored from backup.
|
Your original Inkscape config is restored from the backup created at install time.
|
||||||
|
|
||||||
|
## Tool mapping from Illustrator to Inkscape
|
||||||
|
|
||||||
|
| Illustrator tool | Key | Inkscape equivalent |
|
||||||
|
|-----------------|-----|---------------------|
|
||||||
|
| Selection | V | Selection tool |
|
||||||
|
| Direct Selection | A | Node tool |
|
||||||
|
| Pen | P | Pen tool |
|
||||||
|
| Pencil | N | Pencil tool |
|
||||||
|
| Paintbrush | B | Calligraphy tool |
|
||||||
|
| Type | T | Text tool |
|
||||||
|
| Rectangle | M | Rectangle tool |
|
||||||
|
| Ellipse | L | Ellipse tool |
|
||||||
|
| Rotate | R | Transform > Rotate |
|
||||||
|
| Scale | S | Transform > Scale |
|
||||||
|
| Reflect | O | Transform > Flip |
|
||||||
|
| Gradient | G | Gradient tool |
|
||||||
|
| **Mesh** | **U** | **Mesh Gradient tool (direct equivalent)** |
|
||||||
|
| Eyedropper | I | Dropper tool |
|
||||||
|
| Zoom | Z | Zoom tool |
|
||||||
|
| Hand | H / Space | Pan (Space held) |
|
||||||
|
| Scissors | C | Scissors tool |
|
||||||
|
| Eraser | Shift+E | Eraser tool |
|
||||||
|
| Blob Brush | Shift+B | Spray tool (paint mode) |
|
||||||
|
| Symbol Sprayer | Shift+S | Spray tool (clone mode) |
|
||||||
|
| Live Paint | K | Paint Bucket tool |
|
||||||
|
|
||||||
|
## Planned extensions (post-v1)
|
||||||
|
|
||||||
|
- Artboards panel
|
||||||
|
- Character Styles
|
||||||
|
- Recolor Artwork
|
||||||
|
- Object Styles
|
||||||
|
- Export for Screens (1x/2x/3x batch)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT
|
MIT — see [LICENSE](LICENSE).
|
||||||
|
|
|
||||||
9
assets/illuscape.svg
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Illuscape app icon source. Replace with final artwork before v1.0 release. -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||||
|
<rect width="512" height="512" rx="80" fill="#1a1a2e"/>
|
||||||
|
<rect x="200" y="80" width="112" height="24" rx="4" fill="#e8c547"/>
|
||||||
|
<rect x="232" y="104" width="48" height="304" rx="4" fill="#e8c547"/>
|
||||||
|
<rect x="200" y="408" width="112" height="24" rx="4" fill="#e8c547"/>
|
||||||
|
<path d="M320 200 L380 140 L340 180 Z" fill="#4a9eff" opacity="0.8"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 563 B |
12
assets/org.inkscape.Inkscape.desktop
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Illuscape
|
||||||
|
GenericName=Vector Graphics Editor
|
||||||
|
Comment=Inkscape configured for Adobe Illustrator migrants
|
||||||
|
Exec=inkscape %F
|
||||||
|
Icon=illuscape
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
MimeType=image/svg+xml;image/svg+xml-compressed;application/illustrator;
|
||||||
|
Categories=Graphics;VectorGraphics;
|
||||||
|
Keywords=vector;SVG;draw;illustrator;
|
||||||
|
StartupNotify=true
|
||||||
19
assets/splash.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Illuscape splash screen source. Replace with final artwork before v1.0 release. -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" width="600" height="400">
|
||||||
|
<rect width="600" height="400" fill="#1a1a2e"/>
|
||||||
|
<g stroke="#2a2a4e" stroke-width="1">
|
||||||
|
<line x1="0" y1="100" x2="600" y2="100"/>
|
||||||
|
<line x1="0" y1="200" x2="600" y2="200"/>
|
||||||
|
<line x1="0" y1="300" x2="600" y2="300"/>
|
||||||
|
<line x1="150" y1="0" x2="150" y2="400"/>
|
||||||
|
<line x1="300" y1="0" x2="300" y2="400"/>
|
||||||
|
<line x1="450" y1="0" x2="450" y2="400"/>
|
||||||
|
</g>
|
||||||
|
<text x="300" y="200" font-family="sans-serif" font-size="72" font-weight="bold"
|
||||||
|
fill="#e8c547" text-anchor="middle" dominant-baseline="middle">Illuscape</text>
|
||||||
|
<text x="300" y="260" font-family="sans-serif" font-size="20"
|
||||||
|
fill="#8888aa" text-anchor="middle">Inkscape for Illustrator migrants</text>
|
||||||
|
<text x="580" y="385" font-family="monospace" font-size="13"
|
||||||
|
fill="#4a4a6a" text-anchor="end">v0.1.0</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1 KiB |
34
config/palettes/Illustrator-Defaults.gpl
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
GIMP Palette
|
||||||
|
Name: Illustrator Defaults
|
||||||
|
Columns: 8
|
||||||
|
#
|
||||||
|
0 0 0 Registration Black
|
||||||
|
0 0 0 Black
|
||||||
|
255 255 255 White
|
||||||
|
255 0 0 CMYK Red
|
||||||
|
0 0 255 CMYK Blue
|
||||||
|
0 255 0 CMYK Green
|
||||||
|
0 255 255 CMYK Cyan
|
||||||
|
255 0 255 CMYK Magenta
|
||||||
|
255 255 0 CMYK Yellow
|
||||||
|
255 153 0 CMYK Orange
|
||||||
|
128 0 128 CMYK Purple
|
||||||
|
128 64 0 CMYK Brown
|
||||||
|
255 192 203 Pink
|
||||||
|
255 165 0 Orange
|
||||||
|
128 128 0 Olive
|
||||||
|
0 128 128 Teal
|
||||||
|
0 0 128 Navy
|
||||||
|
128 0 0 Maroon
|
||||||
|
128 128 128 50% Gray
|
||||||
|
192 192 192 Silver
|
||||||
|
255 255 153 Light Yellow
|
||||||
|
153 255 153 Light Green
|
||||||
|
153 204 255 Light Blue
|
||||||
|
255 153 153 Light Red
|
||||||
|
204 153 255 Light Purple
|
||||||
|
255 204 153 Light Orange
|
||||||
|
153 255 255 Light Cyan
|
||||||
|
255 153 255 Light Magenta
|
||||||
|
240 240 240 Near White
|
||||||
|
16 16 16 Near Black
|
||||||
24
config/palettes/Illustrator-Earth.gpl
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
GIMP Palette
|
||||||
|
Name: Illustrator Earth Tones
|
||||||
|
Columns: 8
|
||||||
|
#
|
||||||
|
101 67 33 Dark Brown
|
||||||
|
139 90 43 Brown
|
||||||
|
160 120 60 Warm Brown
|
||||||
|
184 148 84 Tan
|
||||||
|
210 180 140 Burlywood
|
||||||
|
222 184 135 Wheat
|
||||||
|
245 222 179 Navajo White
|
||||||
|
255 248 220 Cornsilk
|
||||||
|
188 143 143 Rosy Brown
|
||||||
|
139 119 101 Warm Gray
|
||||||
|
107 84 63 Coffee
|
||||||
|
85 60 42 Espresso
|
||||||
|
156 102 31 Ochre
|
||||||
|
184 134 11 Dark Goldenrod
|
||||||
|
218 165 32 Goldenrod
|
||||||
|
238 203 173 Peach Puff
|
||||||
|
95 117 87 Sage
|
||||||
|
107 142 35 Olive Drab
|
||||||
|
85 107 47 Dark Olive
|
||||||
|
46 79 48 Forest Green
|
||||||
15
config/palettes/Illustrator-Grays.gpl
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
GIMP Palette
|
||||||
|
Name: Illustrator Grays
|
||||||
|
Columns: 10
|
||||||
|
#
|
||||||
|
255 255 255 White
|
||||||
|
230 230 230 10% Gray
|
||||||
|
204 204 204 20% Gray
|
||||||
|
179 179 179 30% Gray
|
||||||
|
153 153 153 40% Gray
|
||||||
|
128 128 128 50% Gray
|
||||||
|
102 102 102 60% Gray
|
||||||
|
77 77 77 70% Gray
|
||||||
|
51 51 51 80% Gray
|
||||||
|
26 26 26 90% Gray
|
||||||
|
0 0 0 Black
|
||||||
43
config/symbols/illuscape-common.svg
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Illuscape common symbols library.
|
||||||
|
Accessible in Inkscape via Object > Symbols > Illuscape Common.
|
||||||
|
-->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
id="illuscape-symbols"
|
||||||
|
style="display:none">
|
||||||
|
<title>Illuscape Common Symbols</title>
|
||||||
|
|
||||||
|
<symbol id="illuscape-arrow-right" viewBox="0 0 24 24" inkscape:label="Arrow Right">
|
||||||
|
<title>Arrow Right</title>
|
||||||
|
<path d="M4 12h16M14 6l6 6-6 6" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="illuscape-arrow-left" viewBox="0 0 24 24" inkscape:label="Arrow Left">
|
||||||
|
<title>Arrow Left</title>
|
||||||
|
<path d="M20 12H4M10 18l-6-6 6-6" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="illuscape-check" viewBox="0 0 24 24" inkscape:label="Checkmark">
|
||||||
|
<title>Checkmark</title>
|
||||||
|
<path d="M4 12l5 5L20 7" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="illuscape-cross" viewBox="0 0 24 24" inkscape:label="Cross">
|
||||||
|
<title>Cross</title>
|
||||||
|
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" fill="none"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="illuscape-star" viewBox="0 0 24 24" inkscape:label="Star">
|
||||||
|
<title>Star</title>
|
||||||
|
<polygon points="12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26"
|
||||||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
33
config/templates/A4.svg
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- A4 portrait -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="793.7008"
|
||||||
|
height="1122.5197"
|
||||||
|
viewBox="0 0 793.7008 1122.5197"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-a4">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="mm">
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>A4</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
33
config/templates/Letter.svg
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- US Letter portrait -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="816.0000"
|
||||||
|
height="1056.0000"
|
||||||
|
viewBox="0 0 816.0000 1056.0000"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-letter">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="in"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="in">
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>Letter</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
37
config/templates/Print-CMYK-A4.svg
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- A4 with 3mm bleed. Note: Inkscape is RGB-native; set CMYK values manually. -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="793.7008"
|
||||||
|
height="1122.5197"
|
||||||
|
viewBox="0 0 793.7008 1122.5197"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-print-cmyk-a4">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="mm">
|
||||||
|
<sodipodi:guide position="-11.3386,11.3386" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="805.0394,11.3386" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="11.3386,-11.3386" orientation="0,1" />
|
||||||
|
<sodipodi:guide position="11.3386,1133.8583" orientation="0,1" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>Print-CMYK-A4</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
37
config/templates/Print-CMYK-Letter.svg
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- US Letter with 3mm bleed. Note: Inkscape is RGB-native; set CMYK values manually. -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="816.0000"
|
||||||
|
height="1056.0000"
|
||||||
|
viewBox="0 0 816.0000 1056.0000"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-print-cmyk-letter">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="in"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="in">
|
||||||
|
<sodipodi:guide position="-11.3386,11.3386" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="827.3386,11.3386" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="11.3386,-11.3386" orientation="0,1" />
|
||||||
|
<sodipodi:guide position="11.3386,1067.3386" orientation="0,1" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>Print-CMYK-Letter</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
33
config/templates/Web-1280x720.svg
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- HD web canvas (smaller) -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="1280.0000"
|
||||||
|
height="720.0000"
|
||||||
|
viewBox="0 0 1280.0000 720.0000"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-web-1280x720">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="px">
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>Web-1280x720</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
33
config/templates/Web-1920x1080.svg
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- HD web canvas -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="1920.0000"
|
||||||
|
height="1080.0000"
|
||||||
|
viewBox="0 0 1920.0000 1080.0000"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-web-1920x1080">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="px">
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>Web-1920x1080</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
185
install.sh
Executable file
|
|
@ -0,0 +1,185 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Illuscape installer
|
||||||
|
# Usage: ./install.sh [--preset=cc|cs6] [--yes]
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PRESET=""
|
||||||
|
AUTO_YES=0
|
||||||
|
|
||||||
|
# ── Parse args ──────────────────────────────────────────────────────────────
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--preset=cc|--preset=cs6) PRESET="${arg#--preset=}" ;;
|
||||||
|
--yes|-y) AUTO_YES=1 ;;
|
||||||
|
--help|-h)
|
||||||
|
echo "Usage: ./install.sh [--preset=cc|cs6] [--yes]"
|
||||||
|
echo " --preset=cc Illustrator CC shortcuts (default)"
|
||||||
|
echo " --preset=cs6 Illustrator CS6 shortcuts"
|
||||||
|
echo " --yes Skip confirmation prompts"
|
||||||
|
exit 0 ;;
|
||||||
|
*) echo "Unknown argument: $arg"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── Check dependencies ───────────────────────────────────────────────────────
|
||||||
|
check_deps() {
|
||||||
|
if ! command -v inkscape &>/dev/null; then
|
||||||
|
echo "✗ Inkscape is not installed. Install Inkscape first, then run Illuscape."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local version
|
||||||
|
version=$(inkscape --version 2>/dev/null | grep -oP '\d+\.\d+' | head -1)
|
||||||
|
local major minor
|
||||||
|
IFS='.' read -r major minor <<< "$version"
|
||||||
|
# Skip version check if regex couldn't match (non-standard version string)
|
||||||
|
if [[ -n "$major" ]] && { (( major < 1 )) || (( major == 1 && minor < 2 )); }; then
|
||||||
|
echo "⚠ Inkscape $version detected. Illuscape targets Inkscape 1.2+."
|
||||||
|
echo " Some settings may not apply correctly. Continue anyway? [y/N]"
|
||||||
|
[[ $AUTO_YES == 1 ]] || { read -r ans; [[ "$ans" =~ ^[Yy]$ ]] || exit 0; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v python3 &>/dev/null; then
|
||||||
|
echo "✗ python3 is required. Install it and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Detect platform ──────────────────────────────────────────────────────────
|
||||||
|
detect_config() {
|
||||||
|
source "$SCRIPT_DIR/scripts/detect_platform.sh"
|
||||||
|
echo "→ Inkscape config: $INKSCAPE_CONFIG ($INKSCAPE_INSTALL_METHOD)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Backup ───────────────────────────────────────────────────────────────────
|
||||||
|
backup_config() {
|
||||||
|
local backup_dir="${INKSCAPE_CONFIG}.bak-illuscape-$(date +%Y%m%d-%H%M%S)"
|
||||||
|
|
||||||
|
# If any illuscape backup already exists, skip (idempotent)
|
||||||
|
if ls "${INKSCAPE_CONFIG}".bak-illuscape-* &>/dev/null; then
|
||||||
|
echo "→ Backup already exists — skipping (idempotent)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$INKSCAPE_CONFIG" ]]; then
|
||||||
|
cp -r "$INKSCAPE_CONFIG" "$backup_dir"
|
||||||
|
echo "→ Backed up to: $backup_dir"
|
||||||
|
else
|
||||||
|
echo "→ No existing config to back up (fresh install)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Prompt for preset ────────────────────────────────────────────────────────
|
||||||
|
choose_preset() {
|
||||||
|
[[ -n "$PRESET" ]] && return 0
|
||||||
|
echo ""
|
||||||
|
echo "Which Illustrator era are you coming from?"
|
||||||
|
echo " [1] CC — current Creative Cloud (default)"
|
||||||
|
echo " [2] CS6 — last perpetual license"
|
||||||
|
printf "Choice [1]: "
|
||||||
|
if [[ $AUTO_YES == 1 ]]; then
|
||||||
|
echo "1 (auto)"
|
||||||
|
PRESET="cc"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
read -r choice
|
||||||
|
case "${choice:-1}" in
|
||||||
|
2) PRESET="cs6" ;;
|
||||||
|
*) PRESET="cc" ;;
|
||||||
|
esac
|
||||||
|
echo "→ Using preset: $PRESET"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Merge preferences ────────────────────────────────────────────────────────
|
||||||
|
merge_prefs() {
|
||||||
|
local prefs_file="$INKSCAPE_CONFIG/preferences.xml"
|
||||||
|
python3 "$SCRIPT_DIR/scripts/merge_prefs.py" \
|
||||||
|
--prefs "$prefs_file" \
|
||||||
|
--patch "$SCRIPT_DIR/config/preferences-patch.xml" \
|
||||||
|
--preset "$PRESET"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Copy config files ────────────────────────────────────────────────────────
|
||||||
|
copy_files() {
|
||||||
|
mkdir -p \
|
||||||
|
"$INKSCAPE_CONFIG/keys" \
|
||||||
|
"$INKSCAPE_CONFIG/palettes" \
|
||||||
|
"$INKSCAPE_CONFIG/templates" \
|
||||||
|
"$INKSCAPE_CONFIG/symbols" \
|
||||||
|
"$INKSCAPE_CONFIG/splashscreens"
|
||||||
|
|
||||||
|
cp "$SCRIPT_DIR/config/keys/illustrator-${PRESET}.xml" \
|
||||||
|
"$INKSCAPE_CONFIG/keys/"
|
||||||
|
|
||||||
|
cp "$SCRIPT_DIR/config/palettes/"*.gpl "$INKSCAPE_CONFIG/palettes/"
|
||||||
|
cp "$SCRIPT_DIR/config/templates/"*.svg "$INKSCAPE_CONFIG/templates/"
|
||||||
|
cp "$SCRIPT_DIR/config/symbols/"*.svg "$INKSCAPE_CONFIG/symbols/"
|
||||||
|
|
||||||
|
echo "→ Config files copied"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Install desktop launcher + icons (Linux native only) ─────────────────────
|
||||||
|
install_desktop() {
|
||||||
|
[[ "$INKSCAPE_INSTALL_METHOD" != "native" ]] && return 0
|
||||||
|
|
||||||
|
local app_dir="$HOME/.local/share/applications"
|
||||||
|
local icon_src="$SCRIPT_DIR/assets/illuscape.svg"
|
||||||
|
local splash_src="$SCRIPT_DIR/assets/splash.svg"
|
||||||
|
local icon_sizes=(16 32 48 64 128 256 512)
|
||||||
|
|
||||||
|
mkdir -p "$app_dir"
|
||||||
|
cp "$SCRIPT_DIR/assets/org.inkscape.Inkscape.desktop" "$app_dir/"
|
||||||
|
|
||||||
|
# Rasterize icon at each size (prefer rsvg-convert, fall back to Inkscape)
|
||||||
|
for size in "${icon_sizes[@]}"; do
|
||||||
|
local icon_dir="$HOME/.local/share/icons/hicolor/${size}x${size}/apps"
|
||||||
|
mkdir -p "$icon_dir"
|
||||||
|
if command -v rsvg-convert &>/dev/null; then
|
||||||
|
rsvg-convert -w "$size" -h "$size" "$icon_src" \
|
||||||
|
-o "$icon_dir/illuscape.png" 2>/dev/null && continue
|
||||||
|
fi
|
||||||
|
if command -v inkscape &>/dev/null; then
|
||||||
|
# Inkscape 1.x uses --export-filename + --export-type (--export-png removed in 1.0)
|
||||||
|
inkscape --export-filename="$icon_dir/illuscape.png" \
|
||||||
|
--export-type=png \
|
||||||
|
--export-width="$size" --export-height="$size" \
|
||||||
|
"$icon_src" 2>/dev/null && continue
|
||||||
|
fi
|
||||||
|
echo "⚠ Could not rasterize icon at ${size}px (install rsvg-convert for icons)"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Splash screen (600x400)
|
||||||
|
if command -v rsvg-convert &>/dev/null; then
|
||||||
|
rsvg-convert -w 600 -h 400 "$splash_src" \
|
||||||
|
-o "$INKSCAPE_CONFIG/splashscreens/illuscape-splash.png" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
update-desktop-database "$app_dir" 2>/dev/null || true
|
||||||
|
echo "→ Desktop launcher installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||||
|
main() {
|
||||||
|
echo "╔══════════════════════════════╗"
|
||||||
|
echo "║ Illuscape Installer ║"
|
||||||
|
echo "╚══════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
check_deps
|
||||||
|
detect_config
|
||||||
|
backup_config
|
||||||
|
choose_preset
|
||||||
|
merge_prefs
|
||||||
|
copy_files
|
||||||
|
install_desktop
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✓ Illuscape installed (preset: $PRESET)"
|
||||||
|
echo ""
|
||||||
|
echo " Open Inkscape to start using your Illustrator-style workspace."
|
||||||
|
echo " To uninstall: ./uninstall.sh"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
72
scripts/gen_templates.py
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate Illuscape document templates."""
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
TEMPLATES_DIR = Path("config/templates")
|
||||||
|
|
||||||
|
def mm_to_px(mm: float) -> float:
|
||||||
|
return mm * 3.7795275591 # 96 dpi
|
||||||
|
|
||||||
|
def in_to_px(inches: float) -> float:
|
||||||
|
return inches * 96.0
|
||||||
|
|
||||||
|
def svg(name: str, width_px: float, height_px: float,
|
||||||
|
units: str, bleed_mm: float = 0.0, note: str = "") -> str:
|
||||||
|
import math
|
||||||
|
bleed_px = mm_to_px(bleed_mm)
|
||||||
|
guides = ""
|
||||||
|
if bleed_mm > 0:
|
||||||
|
guides = f"""
|
||||||
|
<sodipodi:guide position="{-bleed_px:.4f},{bleed_px:.4f}" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="{width_px + bleed_px:.4f},{bleed_px:.4f}" orientation="1,0" />
|
||||||
|
<sodipodi:guide position="{bleed_px:.4f},{-bleed_px:.4f}" orientation="0,1" />
|
||||||
|
<sodipodi:guide position="{bleed_px:.4f},{height_px + bleed_px:.4f}" orientation="0,1" />"""
|
||||||
|
comment = f"<!-- {note} -->" if note else ""
|
||||||
|
return f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
{comment}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="{width_px:.4f}"
|
||||||
|
height="{height_px:.4f}"
|
||||||
|
viewBox="0 0 {width_px:.4f} {height_px:.4f}"
|
||||||
|
version="1.1"
|
||||||
|
id="svg-{name.lower().replace(' ', '-')}">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="1.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="{units}"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:snap-to-guides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
units="{units}">{guides}
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title>{name}</title>
|
||||||
|
<g inkscape:label="Background" inkscape:groupmode="layer" id="layer-background" style="display:inline" />
|
||||||
|
<g inkscape:label="Guides" inkscape:groupmode="layer" id="layer-guides" style="display:inline" />
|
||||||
|
<g inkscape:label="Artwork" inkscape:groupmode="layer" id="layer-artwork" style="display:inline" />
|
||||||
|
</svg>
|
||||||
|
"""
|
||||||
|
|
||||||
|
specs = [
|
||||||
|
("Letter", in_to_px(8.5), in_to_px(11), "in", 0, "US Letter portrait"),
|
||||||
|
("A4", mm_to_px(210), mm_to_px(297), "mm", 0, "A4 portrait"),
|
||||||
|
("Web-1920x1080", 1920, 1080, "px", 0, "HD web canvas"),
|
||||||
|
("Web-1280x720", 1280, 720, "px", 0, "HD web canvas (smaller)"),
|
||||||
|
("Print-CMYK-Letter", in_to_px(8.5), in_to_px(11), "in", 3, "US Letter with 3mm bleed. Note: Inkscape is RGB-native; set CMYK values manually."),
|
||||||
|
("Print-CMYK-A4", mm_to_px(210), mm_to_px(297), "mm", 3, "A4 with 3mm bleed. Note: Inkscape is RGB-native; set CMYK values manually."),
|
||||||
|
]
|
||||||
|
|
||||||
|
for name, w, h, units, bleed, note in specs:
|
||||||
|
path = TEMPLATES_DIR / f"{name}.svg"
|
||||||
|
path.write_text(svg(name, w, h, units, bleed, note))
|
||||||
|
print(f"✓ {path}")
|
||||||
|
|
@ -95,7 +95,7 @@ def merge(prefs_path: Path, patch_path: Path, preset: str) -> None:
|
||||||
_merge_nodes(live_root, patch_root)
|
_merge_nodes(live_root, patch_root)
|
||||||
_apply_preset(live_root, preset)
|
_apply_preset(live_root, preset)
|
||||||
|
|
||||||
live_tree.write(str(prefs_path), encoding="unicode", xml_declaration=True)
|
_atomic_write(live_tree, prefs_path)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
|
|
||||||
135
tests/test_install.bats
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
# Integration tests for install.sh and uninstall.sh
|
||||||
|
# Requires: bats-core (https://github.com/bats-core/bats-core)
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
# Each test gets a fresh temp home directory
|
||||||
|
export TEST_HOME
|
||||||
|
TEST_HOME="$(mktemp -d)"
|
||||||
|
export HOME="$TEST_HOME"
|
||||||
|
export XDG_CONFIG_HOME="$TEST_HOME/.config"
|
||||||
|
|
||||||
|
# Inject a fake inkscape so check_deps passes without the real binary
|
||||||
|
local fake_bin="$TEST_HOME/bin"
|
||||||
|
mkdir -p "$fake_bin"
|
||||||
|
printf '#!/bin/sh\necho "Inkscape 1.3.2"\n' > "$fake_bin/inkscape"
|
||||||
|
chmod +x "$fake_bin/inkscape"
|
||||||
|
export PATH="$fake_bin:$PATH"
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
rm -rf "$TEST_HOME"
|
||||||
|
}
|
||||||
|
|
||||||
|
_run_install() {
|
||||||
|
bash "$REPO_ROOT/install.sh" --preset="${1:-cc}" --yes 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
_config_root() {
|
||||||
|
echo "$TEST_HOME/.config/inkscape"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Backup ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "backup is created on first install" {
|
||||||
|
mkdir -p "$(_config_root)"
|
||||||
|
echo '<inkscape version="1"/>' > "$(_config_root)/preferences.xml"
|
||||||
|
_run_install cc
|
||||||
|
local backup
|
||||||
|
backup=$(ls -1d "$(_config_root)".bak-illuscape-* 2>/dev/null | head -1)
|
||||||
|
[ -n "$backup" ]
|
||||||
|
[ -f "$backup/preferences.xml" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "second install does not overwrite backup" {
|
||||||
|
mkdir -p "$(_config_root)"
|
||||||
|
echo '<inkscape version="1"/>' > "$(_config_root)/preferences.xml"
|
||||||
|
_run_install cc
|
||||||
|
sleep 1
|
||||||
|
_run_install cc
|
||||||
|
local backup_count
|
||||||
|
backup_count=$(ls -1d "$(_config_root)".bak-illuscape-* 2>/dev/null | wc -l)
|
||||||
|
[ "$backup_count" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Keys ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "CC preset installs illustrator-cc.xml" {
|
||||||
|
_run_install cc
|
||||||
|
[ -f "$(_config_root)/keys/illustrator-cc.xml" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "CS6 preset installs illustrator-cs6.xml" {
|
||||||
|
_run_install cs6
|
||||||
|
[ -f "$(_config_root)/keys/illustrator-cs6.xml" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "CC preset does not install cs6 key file" {
|
||||||
|
_run_install cc
|
||||||
|
[ ! -f "$(_config_root)/keys/illustrator-cs6.xml" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Palettes ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "all palette files are installed" {
|
||||||
|
_run_install cc
|
||||||
|
[ -f "$(_config_root)/palettes/Illustrator-Defaults.gpl" ]
|
||||||
|
[ -f "$(_config_root)/palettes/Illustrator-Grays.gpl" ]
|
||||||
|
[ -f "$(_config_root)/palettes/Illustrator-Earth.gpl" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Templates ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "all template files are installed" {
|
||||||
|
_run_install cc
|
||||||
|
[ -f "$(_config_root)/templates/Letter.svg" ]
|
||||||
|
[ -f "$(_config_root)/templates/A4.svg" ]
|
||||||
|
[ -f "$(_config_root)/templates/Web-1920x1080.svg" ]
|
||||||
|
[ -f "$(_config_root)/templates/Web-1280x720.svg" ]
|
||||||
|
[ -f "$(_config_root)/templates/Print-CMYK-Letter.svg" ]
|
||||||
|
[ -f "$(_config_root)/templates/Print-CMYK-A4.svg" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Preferences merge ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "preferences.xml is created when missing" {
|
||||||
|
_run_install cc
|
||||||
|
[ -f "$(_config_root)/preferences.xml" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "CC preset sets px units in preferences.xml" {
|
||||||
|
_run_install cc
|
||||||
|
grep -q 'doc="px"' "$(_config_root)/preferences.xml"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "CS6 preset sets pt units in preferences.xml" {
|
||||||
|
_run_install cs6
|
||||||
|
grep -q 'doc="pt"' "$(_config_root)/preferences.xml"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Noninteractive ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "--preset flag skips interactive prompt" {
|
||||||
|
# If prompt were shown, it would hang — the test itself proves it didn't
|
||||||
|
run bash "$REPO_ROOT/install.sh" --preset=cc --yes
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Uninstall ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@test "uninstall restores preferences.xml from backup" {
|
||||||
|
mkdir -p "$(_config_root)"
|
||||||
|
echo '<inkscape version="1"><group id="original"/></inkscape>' \
|
||||||
|
> "$(_config_root)/preferences.xml"
|
||||||
|
_run_install cc
|
||||||
|
bash "$REPO_ROOT/uninstall.sh"
|
||||||
|
grep -q 'id="original"' "$(_config_root)/preferences.xml"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "uninstall removes palette files" {
|
||||||
|
_run_install cc
|
||||||
|
bash "$REPO_ROOT/uninstall.sh"
|
||||||
|
[ ! -f "$(_config_root)/palettes/Illustrator-Defaults.gpl" ]
|
||||||
|
}
|
||||||
74
uninstall.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Illuscape uninstaller
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/scripts/detect_platform.sh"
|
||||||
|
|
||||||
|
echo "╔══════════════════════════════╗"
|
||||||
|
echo "║ Illuscape Uninstaller ║"
|
||||||
|
echo "╚══════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "→ Inkscape config: $INKSCAPE_CONFIG"
|
||||||
|
|
||||||
|
# ── Find backup ───────────────────────────────────────────────────────────────
|
||||||
|
BACKUP=$(ls -1d "${INKSCAPE_CONFIG}".bak-illuscape-* 2>/dev/null | sort | tail -1 || true)
|
||||||
|
|
||||||
|
if [[ -z "$BACKUP" ]]; then
|
||||||
|
echo "⚠ No Illuscape backup found at ${INKSCAPE_CONFIG}.bak-illuscape-*"
|
||||||
|
echo " Cannot restore original preferences.xml automatically."
|
||||||
|
echo " Removing only Illuscape-installed files."
|
||||||
|
else
|
||||||
|
echo "→ Restoring preferences.xml from: $BACKUP"
|
||||||
|
cp "$BACKUP/preferences.xml" "$INKSCAPE_CONFIG/preferences.xml" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Remove Illuscape-installed files ─────────────────────────────────────────
|
||||||
|
remove_files() {
|
||||||
|
# Keys
|
||||||
|
rm -f "$INKSCAPE_CONFIG/keys/illustrator-cc.xml"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/keys/illustrator-cs6.xml"
|
||||||
|
|
||||||
|
# Palettes
|
||||||
|
rm -f "$INKSCAPE_CONFIG/palettes/Illustrator-Defaults.gpl"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/palettes/Illustrator-Grays.gpl"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/palettes/Illustrator-Earth.gpl"
|
||||||
|
|
||||||
|
# Templates
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/Letter.svg"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/A4.svg"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/Web-1920x1080.svg"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/Web-1280x720.svg"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/Print-CMYK-Letter.svg"
|
||||||
|
rm -f "$INKSCAPE_CONFIG/templates/Print-CMYK-A4.svg"
|
||||||
|
|
||||||
|
# Symbols
|
||||||
|
rm -f "$INKSCAPE_CONFIG/symbols/illuscape-common.svg"
|
||||||
|
|
||||||
|
# Splash
|
||||||
|
rm -f "$INKSCAPE_CONFIG/splashscreens/illuscape-splash.png"
|
||||||
|
|
||||||
|
echo "→ Illuscape config files removed"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_desktop() {
|
||||||
|
[[ "$INKSCAPE_INSTALL_METHOD" != "native" ]] && return 0
|
||||||
|
rm -f "$HOME/.local/share/applications/org.inkscape.Inkscape.desktop"
|
||||||
|
for size in 16 32 48 64 128 256 512; do
|
||||||
|
rm -f "$HOME/.local/share/icons/hicolor/${size}x${size}/apps/illuscape.png"
|
||||||
|
done
|
||||||
|
update-desktop-database "$HOME/.local/share/applications" 2>/dev/null || true
|
||||||
|
echo "→ Desktop launcher removed"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_files
|
||||||
|
remove_desktop
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✓ Illuscape uninstalled."
|
||||||
|
echo ""
|
||||||
|
echo " Note: Your Inkscape preferences may have changed since Illuscape was"
|
||||||
|
echo " installed. If anything looks wrong, review:"
|
||||||
|
echo " $INKSCAPE_CONFIG/preferences.xml"
|
||||||
|
echo ""
|
||||||