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/
|
||||
*.bak
|
||||
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 —
|
||||
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
|
||||
|
||||
```bash
|
||||
|
|
@ -14,7 +34,21 @@ cd illuscape
|
|||
./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
|
||||
|
||||
|
|
@ -22,8 +56,46 @@ Follow the prompt to select your Illustrator era (CC or CS6), then open Inkscape
|
|||
./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
|
||||
|
||||
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)
|
||||
_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:
|
||||
|
|
|
|||
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 ""
|
||||