mtg_card_maker 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/LICENSE.txt +59 -14
- data/README.md +251 -69
- data/lib/mtg_card_maker/base_card.rb +24 -1
- data/lib/mtg_card_maker/cli.rb +44 -41
- data/lib/mtg_card_maker/color_scheme.rb +18 -23
- data/lib/mtg_card_maker/css_service.rb +72 -0
- data/lib/mtg_card_maker/fonts/GoudyBookletter1911.ttf +0 -0
- data/lib/mtg_card_maker/fonts/OFL.txt +92 -0
- data/lib/mtg_card_maker/fonts/goudy_bookletter_base64.txt +1 -0
- data/lib/mtg_card_maker/icon_filename_service.rb +118 -0
- data/lib/mtg_card_maker/icon_service.rb +87 -25
- data/lib/mtg_card_maker/icons/black.svg +6 -1
- data/lib/mtg_card_maker/icons/blue.svg +6 -1
- data/lib/mtg_card_maker/icons/colorless.svg +6 -1
- data/lib/mtg_card_maker/icons/double-digit.svg +6 -0
- data/lib/mtg_card_maker/icons/energy.svg +26 -0
- data/lib/mtg_card_maker/icons/green.svg +6 -1
- data/lib/mtg_card_maker/icons/hybrid/2-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/2-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/2-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/2-red.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/2-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/black-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/black-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/black-red.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/black-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/blue-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/blue-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/blue-red.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/blue-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/colorless-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/colorless-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/colorless-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/colorless-red.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/colorless-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/green-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/green-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/green-red.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/green-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/red-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/red-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/red-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/red-white.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/white-black.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/white-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/white-green.svg +19 -0
- data/lib/mtg_card_maker/icons/hybrid/white-red.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/black-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/black-green.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/black-red.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/black-white.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/black.svg +6 -0
- data/lib/mtg_card_maker/icons/phyrexian/blue-black.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/blue-green.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/blue-red.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/blue-white.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/blue.svg +6 -0
- data/lib/mtg_card_maker/icons/phyrexian/colorless.svg +6 -0
- data/lib/mtg_card_maker/icons/phyrexian/green-black.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/green-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/green-red.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/green-white.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/green.svg +6 -0
- data/lib/mtg_card_maker/icons/phyrexian/red-black.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/red-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/red-green.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/red-white.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/red.svg +6 -0
- data/lib/mtg_card_maker/icons/phyrexian/white-black.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/white-blue.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/white-green.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/white-red.svg +19 -0
- data/lib/mtg_card_maker/icons/phyrexian/white.svg +6 -0
- data/lib/mtg_card_maker/icons/red.svg +6 -1
- data/lib/mtg_card_maker/icons/single-digit.svg +6 -0
- data/lib/mtg_card_maker/icons/snow.svg +24 -0
- data/lib/mtg_card_maker/icons/tap.svg +1 -0
- data/lib/mtg_card_maker/icons/tap_legacy.svg +45 -0
- data/lib/mtg_card_maker/icons/untap.svg +1 -0
- data/lib/mtg_card_maker/icons/white.svg +6 -1
- data/lib/mtg_card_maker/icons/x.svg +6 -0
- data/lib/mtg_card_maker/layer_config.rb +21 -46
- data/lib/mtg_card_maker/layers/border_layer.rb +4 -5
- data/lib/mtg_card_maker/layers/frame_layer.rb +1 -1
- data/lib/mtg_card_maker/layers/name_layer.rb +16 -8
- data/lib/mtg_card_maker/layers/power_layer.rb +1 -3
- data/lib/mtg_card_maker/layers/text_box_layer.rb +205 -51
- data/lib/mtg_card_maker/layers/type_line_layer.rb +2 -4
- data/lib/mtg_card_maker/logger.rb +62 -0
- data/lib/mtg_card_maker/mana_cost.rb +59 -128
- data/lib/mtg_card_maker/sprite_sheet_assets.rb +10 -55
- data/lib/mtg_card_maker/sprite_sheet_builder.rb +20 -8
- data/lib/mtg_card_maker/sprite_sheet_service.rb +22 -9
- data/lib/mtg_card_maker/svg_gradient_service.rb +11 -11
- data/lib/mtg_card_maker/symbol_replacement_service.rb +102 -0
- data/lib/mtg_card_maker/text_rendering_service.rb +7 -3
- data/lib/mtg_card_maker/version.rb +1 -1
- data/lib/mtg_card_maker.rb +9 -78
- metadata +79 -12
- data/lib/mtg_card_maker/fonts/Goudy Mediaeval DemiBold.ttf +0 -0
- data/lib/mtg_card_maker/fonts/goudy_base64.txt +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7fa254f0344ffc52479fb2be5aae9a6f0486b9ebff42b684156260bfe4814879
|
|
4
|
+
data.tar.gz: 34cdc3ed5192c5e89e7a4e0d58260f5276fbfa920a48e286c9638757e301342c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf7b3b64a9c76fcb695571a3320cc5fdf9746c7719f411eb3ebaaa9d64573aec3862990f99b0818b754ed6b62191ff40b73d7997536328fc85e35f2b9a286626
|
|
7
|
+
data.tar.gz: ebc7ed18847e53e800e9fe2b7156e82ad470ac22984c2f418a8e662680f63a1bd46693808f804295408c185014760e05a3a0e7898517ae7fa07dbd29777591a7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-10-11
|
|
4
|
+
|
|
5
|
+
### 📜 License
|
|
6
|
+
- **Relicensed from CC BY-NC-ND 4.0 to the MIT License.** Version 0.1.0 remains available under its original license.
|
|
7
|
+
- Wizards of the Coast materials and the bundled Goudy Bookletter 1911 font (SIL OFL 1.1) are explicitly excluded from the MIT grant and keep their own terms (see `LICENSE.txt`).
|
|
8
|
+
- Generated cards no longer carry "Some rights reserved"; the footer now reads "MTG Card Maker by Joe Sharp". Cards and their content belong to their creators.
|
|
9
|
+
- Replaced the bundled Goudy Mediaeval DemiBold font, which is licensed for personal use only, with Goudy Bookletter 1911. Embedded card text renders slightly differently, and SVGs with embedded fonts are about 38 KB larger.
|
|
10
|
+
|
|
11
|
+
### ⚠️ Breaking Changes
|
|
12
|
+
- **Dropped support for Ruby 3.2.** Ruby 3.3 or higher is now required (Ruby 3.2 reached end of life in March 2026).
|
|
13
|
+
|
|
14
|
+
### ✨ Features
|
|
15
|
+
- Hybrid and Phyrexian mana symbol support, with a new `IconFilenameService` for symbol mapping
|
|
16
|
+
- SVG to WebP conversion script (experimental)
|
|
17
|
+
- Italicized flavor text
|
|
18
|
+
- Improved SVG initialization and viewBox scaling in card rendering
|
|
19
|
+
|
|
20
|
+
### 📚 Documentation
|
|
21
|
+
- README updated with new symbols and Markdown docs support; YARD documentation refreshed
|
|
22
|
+
|
|
3
23
|
## [0.1.0] - 2025-07-12
|
|
4
24
|
|
|
5
25
|
### 🎯 Initial Release
|
data/LICENSE.txt
CHANGED
|
@@ -1,20 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025
|
|
3
|
+
Copyright (c) 2025 Joe Sharp
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
--------------------------------------------------------------------------------
|
|
24
|
+
Materials NOT covered by the MIT License above
|
|
25
|
+
--------------------------------------------------------------------------------
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
The MIT License applies only to the original code and original assets created
|
|
28
|
+
by Joe Sharp. The following materials are owned by third parties, are not
|
|
29
|
+
licensed to you by this project, and are excluded from the grant above:
|
|
30
|
+
|
|
31
|
+
1. Wizards of the Coast materials
|
|
32
|
+
|
|
33
|
+
Magic: The Gathering, its name, mana symbols, set symbols, card frame and
|
|
34
|
+
layout designs, and related marks are property of Wizards of the Coast LLC.
|
|
35
|
+
MTG Card Maker is unofficial Fan Content permitted under the Fan Content
|
|
36
|
+
Policy (https://company.wizards.com/en/legal/fancontentpolicy). It is not
|
|
37
|
+
approved or endorsed by Wizards. Portions of the materials used are
|
|
38
|
+
property of Wizards of the Coast. (c) Wizards of the Coast LLC.
|
|
39
|
+
|
|
40
|
+
Use of these materials, including cards generated with this software, is
|
|
41
|
+
governed by the Fan Content Policy, which does not permit commercial use.
|
|
42
|
+
Nothing in the MIT License grants you any rights in them.
|
|
43
|
+
|
|
44
|
+
2. Goudy Bookletter 1911 font
|
|
45
|
+
|
|
46
|
+
lib/mtg_card_maker/fonts/GoudyBookletter1911.ttf, its base64 copy
|
|
47
|
+
(goudy_bookletter_base64.txt), and the font as embedded in generated SVG
|
|
48
|
+
files are Copyright (c) 2010, Barry Schwartz (crudfactory.com), licensed
|
|
49
|
+
under the SIL Open Font License, Version 1.1. The license text is in
|
|
50
|
+
lib/mtg_card_maker/fonts/OFL.txt. The font remains under that license,
|
|
51
|
+
not the MIT License.
|
|
52
|
+
|
|
53
|
+
3. Sample artwork
|
|
54
|
+
|
|
55
|
+
The card artwork and finished sample cards in the images/ directory of the
|
|
56
|
+
source repository (which are not part of the published gem) are
|
|
57
|
+
AI-generated and are included for illustration only. They are not covered
|
|
58
|
+
by the MIT License, and no rights in them are granted.
|
|
59
|
+
|
|
60
|
+
Cards you generate belong to you: the MIT License says nothing about the
|
|
61
|
+
text, artwork, or other content you put on them. The jsharp.svg and
|
|
62
|
+
qrcode.svg icons bundled in lib/mtg_card_maker/icons/ are original to this
|
|
63
|
+
project and are covered by the MIT License.
|
|
64
|
+
|
|
65
|
+
Questions about the author's own original assets: joesharp13@gmail.com
|
data/README.md
CHANGED
|
@@ -1,69 +1,75 @@
|
|
|
1
1
|
# MTG Card Maker
|
|
2
2
|
|
|
3
3
|
<p align=center>
|
|
4
|
-
<img src="images/mtgcm_card.
|
|
4
|
+
<img src="images/mtgcm_card.webp"
|
|
5
|
+
alt="A card featuring artwork of a fiery dragon and anvil"
|
|
6
|
+
width="300" />
|
|
5
7
|
</p>
|
|
6
8
|
|
|
7
|
-
A Ruby gem for creating fan-made Magic: The Gathering cards. This tool
|
|
9
|
+
A Ruby gem for creating high quality fan-made Magic: The Gathering cards. This tool generates custom MTG cards with authentic formatting, comprehensive mana cost support, and precise card layouts. Perfect for game designers, content creators, and MTG enthusiasts.
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
|
|
12
|
+
Please note this gem is for fan content creation only. **Wizards of the Coast's Fan Content Policy does not permit commercial use of cards made with Magic: The Gathering materials.** If you have ideas for improvements, please create a feature request after reviewing the open issues here: https://github.com/joe-sharp/mtg_card_maker/issues
|
|
10
13
|
|
|
11
14
|
## Features
|
|
12
15
|
#### 🎨 Card Customization
|
|
13
16
|
|
|
14
17
|
**Core Card Properties:**
|
|
15
|
-
- **Card Name**: Customizable card titles with
|
|
16
|
-
- **Mana Cost**:
|
|
17
|
-
- **Type Line**: Customizable
|
|
18
|
-
- **
|
|
19
|
-
- **Flavor Text**: Optional italicized flavor text
|
|
20
|
-
- **Power/Toughness**:
|
|
18
|
+
- **Card Name**: Customizable card titles with embedded font support
|
|
19
|
+
- **Mana Cost**: Complete MTG symbol support including hybrid, Phyrexian, and numeric costs
|
|
20
|
+
- **Type Line**: Customizable card types and subtypes (Creature, Instant, Sorcery, etc.)
|
|
21
|
+
- **Rules Text**: Rich text with automatic word wrapping and symbol replacement
|
|
22
|
+
- **Flavor Text**: Optional italicized flavor text with proper formatting
|
|
23
|
+
- **Power/Toughness**: Dynamic power/toughness display
|
|
21
24
|
|
|
22
25
|
**Visual Customization:**
|
|
23
|
-
- **Color Schemes**: 8
|
|
24
|
-
- **Border
|
|
25
|
-
- **Art Integration**:
|
|
26
|
+
- **Color Schemes**: 8 card colors (white, blue, black, red, green, colorless, gold, artifact)
|
|
27
|
+
- **Border Colors**: Customizable borders (white, black, gold, silver)
|
|
28
|
+
- **Art Integration**: Flexible artwork support via URLs or local paths
|
|
29
|
+
- **Font Embedding**: Base64 font embedding for portability
|
|
26
30
|
|
|
27
|
-
#### 🖼️ Sprite Sheet Features
|
|
31
|
+
#### 🖼️ Advanced Sprite Sheet Features
|
|
28
32
|
|
|
29
|
-
**
|
|
33
|
+
**Performance Optimizations:**
|
|
30
34
|
- **Shared Assets**: Fonts, gradients, and masks defined once per sprite sheet
|
|
31
|
-
- **
|
|
32
|
-
- **Layout Optimization**: Ideal for web applications, printing
|
|
35
|
+
- **File Size Reduction**: Significantly smaller than individual card files
|
|
36
|
+
- **Layout Optimization**: Ideal for web applications, printing
|
|
37
|
+
and digital displays
|
|
33
38
|
|
|
34
39
|
**Layout Control:**
|
|
35
|
-
- **Cards Per Row**: Configurable
|
|
36
|
-
- **Spacing Control**:
|
|
37
|
-
- **
|
|
40
|
+
- **Cards Per Row**: Configurable grid layout (default: 4)
|
|
41
|
+
- **Spacing Control**: Pixel-perfect spacing between cards (default: 30px)
|
|
42
|
+
- **Dynamic Sizing**: Automatic sprite sheet dimensions based on card count
|
|
38
43
|
|
|
39
44
|
**Batch Processing:**
|
|
40
|
-
- **YAML Configuration**:
|
|
41
|
-
- **CLI Integration**:
|
|
42
|
-
- **Error Handling**: Robust
|
|
45
|
+
- **YAML Configuration**: Structured card definitions with validation
|
|
46
|
+
- **CLI Integration**: Streamlined command-line workflow
|
|
47
|
+
- **Error Handling**: Robust validation and helpful error messages
|
|
43
48
|
|
|
44
|
-
#### 🛠️ Technical
|
|
49
|
+
#### 🛠️ Technical Excellence
|
|
45
50
|
|
|
46
51
|
**SVG Generation:**
|
|
47
|
-
- **Vector Graphics**: High-quality SVG output suitable for any
|
|
52
|
+
- **Vector Graphics**: High-quality SVG output suitable for any scale
|
|
48
53
|
- **Print Ready**: Optimized for both digital and print applications
|
|
49
54
|
- **Cross-Platform**: Compatible with all modern browsers and design software
|
|
55
|
+
- NOTE: inline symbols in rule text may not render in some design software
|
|
50
56
|
|
|
51
|
-
**Development
|
|
52
|
-
- **Guard Integration**: Automated testing and
|
|
53
|
-
- **Status Summary**: Real-time development
|
|
54
|
-
- **Comprehensive Testing**:
|
|
55
|
-
- **Code Quality**: RuboCop
|
|
57
|
+
**Development Infrastructure:**
|
|
58
|
+
- **Guard Integration**: Automated testing and quality monitoring
|
|
59
|
+
- **Status Summary**: Real-time development feedback with integrity checks
|
|
60
|
+
- **Comprehensive Testing**: 480+ tests with fixtures and helpers
|
|
61
|
+
- **Code Quality**: Zero RuboCop violations, consistent style
|
|
56
62
|
|
|
57
63
|
**Documentation:**
|
|
58
|
-
- **YARD Documentation**:
|
|
59
|
-
- **CLI Help**:
|
|
60
|
-
- **Examples**: Multiple
|
|
64
|
+
- **YARD Documentation**: 96.30% documented with local server
|
|
65
|
+
- **CLI Help**: Comprehensive command-line help and examples
|
|
66
|
+
- **Examples**: Multiple configuration examples and use cases
|
|
61
67
|
|
|
62
|
-
## Installation
|
|
68
|
+
## 💽 Installation
|
|
63
69
|
|
|
64
70
|
### Prerequisites
|
|
65
71
|
|
|
66
|
-
This gem requires Ruby 3.
|
|
72
|
+
This gem requires Ruby 3.3 or higher. The version of Ruby included with macOS is typically outdated and won't work. You can install a newer version of Ruby using tools like [asdf](https://asdf-vm.com/) (with the [Ruby plugin](https://github.com/asdf-vm/asdf-ruby)), [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/). Note: This gem seems to work just fine on Ruby 3.5.0 but cannot be tested in CI currently.
|
|
67
73
|
|
|
68
74
|
Install the gem:
|
|
69
75
|
```bash
|
|
@@ -85,8 +91,9 @@ flavor_text: "Flavor text" # Optional
|
|
|
85
91
|
power: 4 # Optional
|
|
86
92
|
toughness: 4 # Optional
|
|
87
93
|
color: red # Optional (default: colorless)
|
|
88
|
-
border_color: gold
|
|
89
|
-
art: path/to/art.jpg
|
|
94
|
+
border_color: gold # Optional (default: white)
|
|
95
|
+
art: path/to/art.jpg # Optional
|
|
96
|
+
embed_font: false # Optional (default: true)
|
|
90
97
|
```
|
|
91
98
|
|
|
92
99
|
**Color Schemes Available:**
|
|
@@ -101,7 +108,116 @@ art: path/to/art.jpg # Optional
|
|
|
101
108
|
`white` => White cards
|
|
102
109
|
```
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
**Symbols Available for Mana Cost:**
|
|
112
|
+
|
|
113
|
+
**Mana Symbols:**
|
|
114
|
+
- `W` - White mana <img src="images/icons/white.svg" width="16" valign="middle" />
|
|
115
|
+
- `B` - Black mana <img src="images/icons/black.svg" width="16" valign="middle" />
|
|
116
|
+
- `R` - Red mana <img src="images/icons/red.svg" width="16" valign="middle" />
|
|
117
|
+
- `G` - Green mana <img src="images/icons/green.svg" width="16" valign="middle" />
|
|
118
|
+
- `U` - Blue mana <img src="images/icons/blue.svg" width="16" valign="middle" />
|
|
119
|
+
- `C` - Colorless mana <img src="images/icons/colorless.svg" width="16" valign="middle" />
|
|
120
|
+
- `S` - Snow mana <img src="images/icons/snow.svg" width="16" valign="middle" />
|
|
121
|
+
- `{C/P}` - Colorless Phyrexian mana <img src="images/icons/phyrexian/colorless.svg" width="20" valign="middle" />
|
|
122
|
+
- `{R/P}` - Red Phyrexian mana <img src="images/icons/phyrexian/red.svg" width="20" valign="middle" />
|
|
123
|
+
- `{G/P}` - Green Phyrexian mana <img src="images/icons/phyrexian/green.svg" width="20" valign="middle" />
|
|
124
|
+
- `{U/P}` - Blue Phyrexian mana <img src="images/icons/phyrexian/blue.svg" width="20" valign="middle" />
|
|
125
|
+
- `{B/P}` - Black Phyrexian mana <img src="images/icons/phyrexian/black.svg" width="20" valign="middle" />
|
|
126
|
+
- `{W/P}` - White Phyrexian mana <img src="images/icons/phyrexian/white.svg" width="20" valign="middle" />
|
|
127
|
+
|
|
128
|
+
**Advanced Mana Support:**
|
|
129
|
+
Hybrid and Phyrexian mana are now fully supported! See all the
|
|
130
|
+
notations below in the rule text section. The notation uses curly braces for complex symbols:
|
|
131
|
+
- `{R/G}` Red / Green Mana <img src="images/icons/hybrid/red-green.svg" width="20" valign="middle" />
|
|
132
|
+
- `{G/W/P}` Green / White Phyrexian Mana <img src="images/icons/phyrexian/green-white.svg" width="20" valign="middle" />
|
|
133
|
+
|
|
134
|
+
**Numeric Symbols:**
|
|
135
|
+
- `0` through `99` - Generic mana costs (0-99) <img src="images/icons/single-digit.svg" width="16" valign="middle" />
|
|
136
|
+
- `X` - X symbol <img src="images/icons/x.svg" width="16" valign="middle" />
|
|
137
|
+
|
|
138
|
+
**Combination Examples:**
|
|
139
|
+
- `16US` - 16 generic + 1 blue + 1 snow <img src="images/icons/double-digit.svg" width="16" valign="middle" /> <img src="images/icons/blue.svg" width="16" valign="middle" /> <img src="images/icons/snow.svg" width="16" valign="middle" />
|
|
140
|
+
- `XG` - X generic + 1 green <img src="images/icons/x.svg" width="16" valign="middle" /> <img src="images/icons/green.svg" width="16" valign="middle" />
|
|
141
|
+
- `X3R` - X generic + 3 generic + 1 red <img src="images/icons/x.svg" width="16" valign="middle" /> <img src="images/icons/single-digit.svg" width="16" valign="middle" /> <img src="images/icons/red.svg" width="16" valign="middle" />
|
|
142
|
+
- `3WU` - 3 generic + 1 white + 1 blue <img src="images/icons/single-digit.svg" width="16" valign="middle" /> <img src="images/icons/white.svg" width="16" valign="middle" /> <img src="images/icons/blue.svg" width="16" valign="middle" />
|
|
143
|
+
- `WU{B/P}RG` White, Blue, Phyrexian Black, Red, Green <img src="images/icons/white.svg" width="16" valign="middle" /> <img src="images/icons/blue.svg" width="16" valign="middle" /> <img src="images/icons/phyrexian/black.svg" width="20" valign="middle" /> <img src="images/icons/red.svg" width="16" valign="middle" /> <img src="images/icons/green.svg" width="16" valign="middle" />
|
|
144
|
+
- `X` - X generic only <img src="images/icons/x.svg" width="16" valign="middle" />
|
|
145
|
+
- `3` - 3 generic only <img src="images/icons/single-digit.svg" width="16" valign="middle" />
|
|
146
|
+
- `B` - black only <img src="images/icons/black.svg" width="16" valign="middle" />
|
|
147
|
+
|
|
148
|
+
**Symbols Available in Rules Text:**
|
|
149
|
+
|
|
150
|
+
You can use MTG symbols in your rules text by wrapping them in curly braces "{C}". The following symbols are supported:
|
|
151
|
+
|
|
152
|
+
**Mana Symbols:**
|
|
153
|
+
- `{W}` - White mana <img src="images/icons/white.svg" width="16" valign="middle" />
|
|
154
|
+
- `{B}` - Black mana <img src="images/icons/black.svg" width="16" valign="middle" />
|
|
155
|
+
- `{R}` - Red mana <img src="images/icons/red.svg" width="16" valign="middle" />
|
|
156
|
+
- `{G}` - Green mana <img src="images/icons/green.svg" width="16" valign="middle" />
|
|
157
|
+
- `{U}` - Blue mana <img src="images/icons/blue.svg" width="16" valign="middle" />
|
|
158
|
+
- `{C}` - Colorless mana <img src="images/icons/colorless.svg" width="16" valign="middle" />
|
|
159
|
+
- `{S}` - Snow mana symbol <img src="images/icons/snow.svg" width="16" valign="middle" />
|
|
160
|
+
- `{C/P}` - Colorless Phyrexian mana <img src="images/icons/phyrexian/colorless.svg" width="20" valign="middle" />
|
|
161
|
+
- `{R/P}` - Red Phyrexian mana <img src="images/icons/phyrexian/red.svg" width="20" valign="middle" />
|
|
162
|
+
- `{G/P}` - Green Phyrexian mana <img src="images/icons/phyrexian/green.svg" width="20" valign="middle" />
|
|
163
|
+
- `{U/P}` - Blue Phyrexian mana <img src="images/icons/phyrexian/blue.svg" width="20" valign="middle" />
|
|
164
|
+
- `{B/P}` - Black Phyrexian mana <img src="images/icons/phyrexian/black.svg" width="20" valign="middle" />
|
|
165
|
+
- `{W/P}` - White Phyrexian mana <img src="images/icons/phyrexian/white.svg" width="20" valign="middle" />
|
|
166
|
+
|
|
167
|
+
**Hybrid Mana Symbols:**
|
|
168
|
+
|
|
169
|
+
**White hybrid:** `{W/B}` `{W/R}` `{W/G}` `{W/U}` - <img src="images/icons/hybrid/white-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/white-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/white-green.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/white-blue.svg" width="20" valign="middle" />
|
|
170
|
+
|
|
171
|
+
**Black hybrid:** `{B/W}` `{B/R}` `{B/G}` `{B/U}` - <img src="images/icons/hybrid/black-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/black-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/black-green.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/black-blue.svg" width="20" valign="middle" />
|
|
172
|
+
|
|
173
|
+
**Red hybrid:** `{R/W}` `{R/B}` `{R/G}` `{R/U}` - <img src="images/icons/hybrid/red-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/red-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/red-green.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/red-blue.svg" width="20" valign="middle" />
|
|
174
|
+
|
|
175
|
+
**Green hybrid:** `{G/W}` `{G/B}` `{G/R}` `{G/U}` - <img src="images/icons/hybrid/green-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/green-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/green-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/green-blue.svg" width="20" valign="middle" />
|
|
176
|
+
|
|
177
|
+
**Blue hybrid:** `{U/W}` `{U/B}` `{U/R}` `{U/G}` - <img src="images/icons/hybrid/blue-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/blue-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/blue-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/blue-green.svg" width="20" valign="middle" />
|
|
178
|
+
|
|
179
|
+
**"Two-brids":** `{2/W}` `{2/B}` `{2/R}` `{2/G}` `{2/U}` - <img src="images/icons/hybrid/2-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/2-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/2-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/2-green.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/2-blue.svg" width="20" valign="middle" />
|
|
180
|
+
|
|
181
|
+
**Colorless hybrid:** `{C/W}` `{C/B}` `{C/R}` `{C/G}` `{C/U}` - <img src="images/icons/hybrid/colorless-white.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/colorless-black.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/colorless-red.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/colorless-green.svg" width="20" valign="middle" /> <img src="images/icons/hybrid/colorless-blue.svg" width="20" valign="middle" />
|
|
182
|
+
|
|
183
|
+
**Phyrexian Hybrid Mana Symbols:**
|
|
184
|
+
|
|
185
|
+
**White Phyrexian hybrid:** `{W/B/P}` `{W/R/P}` `{W/G/P}` `{W/U/P}` - <img src="images/icons/phyrexian/white-black.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/white-red.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/white-green.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/white-blue.svg" width="20" valign="middle" />
|
|
186
|
+
|
|
187
|
+
**Black Phyrexian hybrid:** `{B/W/P}` `{B/R/P}` `{B/G/P}` `{B/U/P}` - <img src="images/icons/phyrexian/black-white.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/black-red.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/black-green.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/black-blue.svg" width="20" valign="middle" />
|
|
188
|
+
|
|
189
|
+
**Red Phyrexian hybrid:** `{R/W/P}` `{R/B/P}` `{R/G/P}` `{R/U/P}` - <img src="images/icons/phyrexian/red-white.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/red-black.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/red-green.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/red-blue.svg" width="20" valign="middle" />
|
|
190
|
+
|
|
191
|
+
**Green Phyrexian hybrid:** `{G/W/P}` `{G/B/P}` `{G/R/P}` `{G/U/P}` - <img src="images/icons/phyrexian/green-white.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/green-black.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/green-red.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/green-blue.svg" width="20" valign="middle" />
|
|
192
|
+
|
|
193
|
+
**Blue Phyrexian hybrid:** `{U/W/P}` `{U/B/P}` `{U/R/P}` `{U/G/P}` - <img src="images/icons/phyrexian/blue-white.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/blue-black.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/blue-red.svg" width="20" valign="middle" /> <img src="images/icons/phyrexian/blue-green.svg" width="20" valign="middle" />
|
|
194
|
+
|
|
195
|
+
**Numeric Symbols:**
|
|
196
|
+
- `{0}` through `{99}` - Generic mana costs (0-99) <img src="images/icons/single-digit.svg" width="16" valign="middle" />
|
|
197
|
+
- `{X}` - X symbol <img src="images/icons/x.svg" width="16" valign="middle" />
|
|
198
|
+
|
|
199
|
+
**Special Symbols:**
|
|
200
|
+
- `{T}` - Tap symbol <img src="images/icons/tap.svg" width="16" valign="middle" />
|
|
201
|
+
- `{Q}` - Untap symbol <img src="images/icons/untap.svg" width="16" valign="middle" />
|
|
202
|
+
- `{E}` - Energy symbol <img src="images/icons/energy.svg" width="16" valign="middle" />
|
|
203
|
+
|
|
204
|
+
**Example Usage:**
|
|
205
|
+
```yaml
|
|
206
|
+
rules_text: "{T}: Add {W} or {U} to your mana pool."
|
|
207
|
+
```
|
|
208
|
+
<p align=center>
|
|
209
|
+
<img src="images/icons/tap.svg"
|
|
210
|
+
alt="{T}" width="16" valign="middle" />
|
|
211
|
+
: Add
|
|
212
|
+
<img src="images/icons/white.svg"
|
|
213
|
+
alt="{W}" width="16" valign="middle" />
|
|
214
|
+
or
|
|
215
|
+
<img src="images/icons/blue.svg"
|
|
216
|
+
alt="{U}" width="16" valign="middle" />
|
|
217
|
+
to your mana pool
|
|
218
|
+
</p>
|
|
219
|
+
|
|
220
|
+
## 🧪 Basic Examples
|
|
105
221
|
|
|
106
222
|
### Single Card
|
|
107
223
|
|
|
@@ -110,8 +226,8 @@ art: path/to/art.jpg # Optional
|
|
|
110
226
|
mtg_card_maker generate_card \
|
|
111
227
|
--name="Lightning Bolt" \
|
|
112
228
|
--mana-cost=R \
|
|
113
|
-
--type-
|
|
114
|
-
--
|
|
229
|
+
--type-line=Instant \
|
|
230
|
+
--rules-text="Deal 3 damage to any target." \
|
|
115
231
|
--color=red
|
|
116
232
|
```
|
|
117
233
|
|
|
@@ -120,8 +236,8 @@ mtg_card_maker generate_card \
|
|
|
120
236
|
mtg_card_maker add_card deck.yml \
|
|
121
237
|
--name="Counterspell" \
|
|
122
238
|
--mana-cost="UU" \
|
|
123
|
-
--type-
|
|
124
|
-
--
|
|
239
|
+
--type-line="Instant" \
|
|
240
|
+
--rules-text="Counter target spell." \
|
|
125
241
|
--color="blue"
|
|
126
242
|
```
|
|
127
243
|
*Shortcuts:*
|
|
@@ -149,32 +265,76 @@ mtg_card_maker generate_sprite deck.yml sprite_sheet.svg \
|
|
|
149
265
|
*Shortcuts:*
|
|
150
266
|
- `gs` or `gcs` for `generate_sprite`
|
|
151
267
|
|
|
152
|
-
###
|
|
268
|
+
### 🖼️ Experimental WebP Conversion
|
|
269
|
+
|
|
270
|
+
**⚠️ Experimental Feature - Mac Only**
|
|
271
|
+
|
|
272
|
+
The gem includes experimental support for converting SVG cards to WebP format using Chrome's headless mode. This feature is currently **Mac-only** and requires specific dependencies.
|
|
273
|
+
|
|
274
|
+
**Why?:**
|
|
275
|
+
It seems a lot more user-friendly for use in things like this README.md file. The file size is bigger and it can't scale so I wouldn't use this option unless something in the SVG isn't working with whatever you are trying to do. You should also report that at https://github.com/joe-sharp/mtg_card_maker/issues . Thanks in advance!
|
|
276
|
+
|
|
277
|
+
**Prerequisites:**
|
|
278
|
+
- **macOS**: Chrome must be installed at `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
|
|
279
|
+
- **cwebp**: Google's WebP encoder must be installed (install via Homebrew: `brew install webp`)
|
|
280
|
+
|
|
281
|
+
**Usage:**
|
|
282
|
+
```bash
|
|
283
|
+
# Convert a single SVG card to WebP
|
|
284
|
+
bin/svg_to_webp output_card.svg
|
|
285
|
+
|
|
286
|
+
# Convert any SVG file to WebP
|
|
287
|
+
bin/svg_to_webp path/to/your/card.svg
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Features:**
|
|
291
|
+
- **Lossless Conversion**: High-quality WebP output with transparency support
|
|
292
|
+
- **Automatic Cropping**: Removes Chrome's window chrome for clean card output
|
|
293
|
+
- **Optimized Dimensions**: Outputs at 630x880 pixels (standard MTG card ratio)
|
|
294
|
+
- **Transparent Background**: Preserves transparency for web and design use
|
|
295
|
+
|
|
296
|
+
**Caveats:**
|
|
297
|
+
- **Platform Limitation**: Currently only works on macOS with Chrome installed
|
|
298
|
+
- **Dependency Required**: Requires `cwebp` command-line tool for final processing
|
|
299
|
+
- **Experimental Status**: May have issues with complex SVG content or Chrome updates
|
|
300
|
+
- **File Size**: WebP files may be larger than optimized SVGs for simple cards
|
|
301
|
+
|
|
302
|
+
**Future Plans:**
|
|
303
|
+
- Cross-platform support (Windows, Linux)
|
|
304
|
+
- Integration with main CLI commands
|
|
305
|
+
|
|
306
|
+
## 🔮 Examples
|
|
153
307
|
|
|
154
308
|
<p>
|
|
155
|
-
<img align=right
|
|
309
|
+
<img align=right
|
|
310
|
+
src="images/joe-sharp_card.webp"
|
|
311
|
+
alt="A card featuring artwork of a bearded man writing on a magical scroll with a feather pen"
|
|
312
|
+
width="300" />
|
|
156
313
|
</p>
|
|
157
314
|
|
|
158
|
-
**Generate a
|
|
315
|
+
**Generate a creature card:**
|
|
159
316
|
|
|
160
317
|
```bash
|
|
161
318
|
mtg_card_maker generate_card \
|
|
162
319
|
--name="Joe Sharp" \
|
|
163
|
-
--mana-cost=
|
|
164
|
-
--type-
|
|
165
|
-
--
|
|
166
|
-
--flavor-text='"
|
|
320
|
+
--mana-cost=3UR \
|
|
321
|
+
--type-line="Engineer - Fullstack" \
|
|
322
|
+
--rules-text='When Joe Sharp enters the battlefield, all malfunctioning computers begin working.\nWhenever you cast a Red spell, draw a card.\n\n{E}: Debug program. Ignore this cost, if a Coffee token is in play.\n\n' \
|
|
323
|
+
--flavor-text='\"Nothing is true, everything is a string.\"\n\t\t\t\t- The ENV Creed' \
|
|
167
324
|
--power=3 \
|
|
168
325
|
--toughness=3 \
|
|
169
326
|
--border-color=gold \
|
|
170
|
-
--color=blue
|
|
327
|
+
--color=blue \
|
|
328
|
+
--art=images/joe.webp
|
|
171
329
|
```
|
|
172
330
|
|
|
331
|
+
|
|
332
|
+
|
|
173
333
|
**Add multiple cards to a YAML file:**
|
|
174
334
|
```bash
|
|
175
|
-
mtg_card_maker add_card deck.yml --name="Lightning Bolt" --mana-cost="R" --type-
|
|
335
|
+
mtg_card_maker add_card deck.yml --name="Lightning Bolt" --mana-cost="R" --type-line="Instant" --rules-text="Deal 3 damage to any target." --color="red"
|
|
176
336
|
|
|
177
|
-
mtg_card_maker add_card deck.yml --name="Counterspell" --mana-cost="UU" --type-
|
|
337
|
+
mtg_card_maker add_card deck.yml --name="Counterspell" --mana-cost="UU" --type-line="Instant" --rules-text="Counter target spell." --color="blue"
|
|
178
338
|
```
|
|
179
339
|
|
|
180
340
|
**Generate a sprite sheet from YAML:**
|
|
@@ -182,7 +342,7 @@ mtg_card_maker add_card deck.yml --name="Counterspell" --mana-cost="UU" --type-t
|
|
|
182
342
|
mtg_card_maker generate_sprite deck.yml sprite_sheet.svg --cards-per-row=3 --spacing=20
|
|
183
343
|
```
|
|
184
344
|
|
|
185
|
-
## Development
|
|
345
|
+
## 🚧 Development
|
|
186
346
|
|
|
187
347
|
### Setup
|
|
188
348
|
|
|
@@ -207,6 +367,12 @@ bundle exec guard
|
|
|
207
367
|
- RSpec results are saved to `tmp/rspec_status.txt`
|
|
208
368
|
- Status summary provides real-time feedback on code quality and card generation
|
|
209
369
|
|
|
370
|
+
**Development Benefits:**
|
|
371
|
+
- **Zero Configuration**: Just run `bundle exec guard` and start coding
|
|
372
|
+
- **Instant Feedback**: See test results and code quality status immediately
|
|
373
|
+
- **Regression Prevention**: Automatic integrity checks prevent breaking changes
|
|
374
|
+
- **Productivity Boost**: Focus on coding while Guard handles quality assurance
|
|
375
|
+
|
|
210
376
|
### Status Summary Script
|
|
211
377
|
|
|
212
378
|
The `bin/status_summary` script provides a comprehensive development status overview, it is meant to only be run by guard.
|
|
@@ -252,7 +418,23 @@ bundle exec rubocop
|
|
|
252
418
|
# Or run `bundle exec guard` and monitor output_card.svg and color_cards_sprite.svg for changes, it is far better, really.
|
|
253
419
|
```
|
|
254
420
|
|
|
255
|
-
##
|
|
421
|
+
## 🏗️ Technical Architecture
|
|
422
|
+
|
|
423
|
+
**Design Patterns & Best Practices:**
|
|
424
|
+
- **Layered Architecture**: Clean separation between card components (art, text, frame, border)
|
|
425
|
+
- **Factory Pattern**: `LayerFactory` provides flexible layer creation
|
|
426
|
+
- **Service-Oriented Design**: Dedicated services for icons, sprites, gradients, and text rendering
|
|
427
|
+
- **Single Responsibility**: Each class has a focused, well-defined purpose
|
|
428
|
+
- **Dependency Injection**: Clean interfaces and testable components
|
|
429
|
+
|
|
430
|
+
**Advanced Features:**
|
|
431
|
+
- **Symbol Replacement Engine**: Sophisticated parsing of MTG notation with regex optimization
|
|
432
|
+
- **Dynamic Gradient Generation**: Real-time SVG gradient creation for card colors
|
|
433
|
+
- **Font Embedding System**: Base64 font embedding for portable SVG files
|
|
434
|
+
- **Sprite Sheet Optimization**: Shared asset management reducing file sizes considerably
|
|
435
|
+
- **Comprehensive Validation**: Robust error handling and input validation throughout
|
|
436
|
+
|
|
437
|
+
## 📰 Documentation
|
|
256
438
|
|
|
257
439
|
### API Documentation
|
|
258
440
|
|
|
@@ -269,37 +451,37 @@ bundle exec yard server
|
|
|
269
451
|
```
|
|
270
452
|
Then visit `http://localhost:8808` to browse the documentation.
|
|
271
453
|
|
|
272
|
-
### Key Classes
|
|
273
454
|
|
|
274
|
-
- **MtgCardMaker**: Main module with card generation examples
|
|
275
|
-
- **BaseCard**: High-level card creation interface
|
|
276
|
-
- **Template**: SVG canvas and layer management
|
|
277
|
-
- **BaseLayer**: Abstract base class for all card layers
|
|
278
|
-
- **ColorScheme**: Unified color system for all MTG colors
|
|
279
|
-
- **LayerFactory**: Factory pattern for creating card layers
|
|
280
|
-
- **CLI**: Command-line interface with Thor integration
|
|
281
455
|
|
|
282
456
|
### Installation and Release
|
|
283
457
|
|
|
284
458
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
285
459
|
|
|
286
|
-
## Contributing
|
|
460
|
+
## 🤝🏻 Contributing
|
|
287
461
|
|
|
288
462
|
Bug reports and pull requests are welcome on GitHub at https://github.com/joe-sharp/mtg_card_maker. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/joe-sharp/mtg_card_maker/blob/main/CODE_OF_CONDUCT.md).
|
|
289
463
|
|
|
290
|
-
## License
|
|
464
|
+
## 🪪 License
|
|
465
|
+
|
|
466
|
+
The code in this gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
467
|
+
|
|
468
|
+
The MIT License does **not** cover:
|
|
469
|
+
|
|
470
|
+
- **Wizards of the Coast materials** (the Magic: The Gathering name, mana and set symbols, card frame and layout designs). These are property of Wizards of the Coast and are used under the Fan Content Policy, which does not permit commercial use.
|
|
471
|
+
- **The Goudy Bookletter 1911 font**, © 2010 Barry Schwartz, licensed under the [SIL Open Font License 1.1](lib/mtg_card_maker/fonts/OFL.txt).
|
|
472
|
+
- **The sample artwork and sample cards in `images/`**, which are AI-generated, are for illustration only and are not licensed for reuse. They are not part of the gem.
|
|
291
473
|
|
|
292
|
-
|
|
474
|
+
Cards you generate, including their text and artwork, belong to you.
|
|
293
475
|
|
|
294
|
-
|
|
476
|
+
See [LICENSE.txt](LICENSE.txt) for details.
|
|
295
477
|
|
|
296
|
-
## Copyright
|
|
478
|
+
## ©️ Copyright
|
|
297
479
|
|
|
298
|
-
© 2025 Joe Sharp.
|
|
480
|
+
© 2025 Joe Sharp. Released under the MIT License.
|
|
299
481
|
MTG Card Maker is unofficial Fan Content permitted under the [Fan Content Policy.](https://company.wizards.com/en/legal/fancontentpolicy) Not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. © Wizards of the Coast LLC.
|
|
300
482
|
|
|
301
|
-
|
|
483
|
+
Please keep the copyright notices, attributions, and QR code on generated cards intact.
|
|
302
484
|
|
|
303
|
-
## Code of Conduct
|
|
485
|
+
## 🧙🏻 Code of Conduct
|
|
304
486
|
|
|
305
487
|
Everyone interacting in the MTG Card Maker project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/joe-sharp/mtg_card_maker/blob/main/CODE_OF_CONDUCT.md).
|
|
@@ -121,9 +121,11 @@ module MtgCardMaker
|
|
|
121
121
|
# @option config [String] :border_color the border color
|
|
122
122
|
# @option config [Symbol, String] :color the color scheme
|
|
123
123
|
# @option config [String] :art the URL or path for card artwork
|
|
124
|
+
# @option config [Boolean] :embed_font whether to embed the font as base64 (default: true)
|
|
124
125
|
def initialize(config)
|
|
125
126
|
assign_attributes(config)
|
|
126
|
-
|
|
127
|
+
validate_required_fields
|
|
128
|
+
@template = Template.new(embed_font: config.fetch(:embed_font, true))
|
|
127
129
|
add_layers
|
|
128
130
|
end
|
|
129
131
|
|
|
@@ -185,6 +187,15 @@ module MtgCardMaker
|
|
|
185
187
|
@art = config[:art]
|
|
186
188
|
end
|
|
187
189
|
|
|
190
|
+
def validate_required_fields
|
|
191
|
+
required_fields = %i[name type_line rules_text]
|
|
192
|
+
missing_fields = required_fields.select { |field| send(field).nil? || send(field).to_s.strip.empty? }
|
|
193
|
+
|
|
194
|
+
return if missing_fields.empty?
|
|
195
|
+
|
|
196
|
+
raise ArgumentError, "Missing required fields: #{missing_fields.join(', ')}"
|
|
197
|
+
end
|
|
198
|
+
|
|
188
199
|
def define_art_window_mask
|
|
189
200
|
svg = @template.instance_variable_get(:@svg)
|
|
190
201
|
svg.defs do
|
|
@@ -200,8 +211,20 @@ module MtgCardMaker
|
|
|
200
211
|
end
|
|
201
212
|
end
|
|
202
213
|
|
|
214
|
+
def define_gradients_for_card
|
|
215
|
+
svg = @template.instance_variable_get(:@svg)
|
|
216
|
+
SvgGradientService.define_all_gradients(svg, @color_scheme)
|
|
217
|
+
|
|
218
|
+
# Also define gradients for border layer
|
|
219
|
+
return unless @border_color
|
|
220
|
+
|
|
221
|
+
border_color_scheme = ColorScheme.new(@border_color.to_sym)
|
|
222
|
+
SvgGradientService.define_all_gradients(svg, border_color_scheme)
|
|
223
|
+
end
|
|
224
|
+
|
|
203
225
|
def add_layers
|
|
204
226
|
define_art_window_mask
|
|
227
|
+
define_gradients_for_card
|
|
205
228
|
# Use LayerFactory to create layers in order
|
|
206
229
|
layers = LayerFactory.create_layers_for_card(self, DEFAULTS[:mask_id], self)
|
|
207
230
|
layers.each { |layer| @template.add_layer(layer) }
|