diff --git a/Makefile b/Makefile index d40e259..f5fb1ea 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ CARDS_DESTS_YAML := $(patsubst cards/%.yaml,cards/build/%.html,$(CARDS)) CARDS_DESTS_XML := $(patsubst cards/%.xml,cards/build/%.x.html,$(CARDS)) CARDS_DESTS := $(CARDS_DESTS_YAML) $(CARDS_DESTS_XML) -.PHONY: all -all: build/test_card.html build/test_card_rendered.html cards/build/all.html +.PHONY: style +style: build/test_card.html build/test_card_rendered.html cards/build/all.html .PHONY: cards cards: $(CARDS_DESTS) cards/build/all.html @@ -17,7 +17,7 @@ style: build/style.xsl .PHONY: dev dev: - git ls-files | entr bash -c "make all" + git ls-files | entr bash -c "make style" .PHONY: dev_all dev_cards: @@ -38,7 +38,7 @@ build/test_card.html: build/test_card.xml build/style.xsl define PYTHON_MAKE_JINJA2_RENDERED_CARD from jinja2 import Environment, FileSystemLoader from markdown import markdown -import yaml, sys, glob +import yaml, sys, glob, traceback import xmltodict with open("build/style.css") as f: css_data = f.read() with open(sys.argv[2], "w") as f: @@ -48,6 +48,9 @@ with open(sys.argv[2], "w") as f: "markdown":markdown, "any":any, "all":all, + "split":str.split, + "startswith":str.startswith, + "tail": lambda x: x[1:], "cull_whitespace":(lambda x: " ".join(x.split())) }) for filename in ([sys.argv[1]] if sys.argv[1] != "ALL" else sorted(glob.glob("cards/*.yaml") + glob.glob("cards/*.xml"))): if sys.argv[1] == "ALL": f.write(f"\n\n

{filename}

\n") @@ -59,22 +62,11 @@ with open(sys.argv[2], "w") as f: xml = xmltodict.parse(f2.read()) xml_data = xml.get("ability_card", {}) yaml_data = yaml.load(xml_data.get("yaml_data", "")) - if xml_data.get("image"): - yaml_data["figures"] = [{ - 'name': xml_data["image"] if (xml_data["image"][:4] == "http") else xml_data["image"].split(":", 1)[1], - 'type': "url" if (xml_data["image"][:4] == "http") else xml_data["image"].split(":", 1)[0], - 'scale': 1.0, - 'flip_x': False, - 'flip_y': False, - 'offset': [0.0, 0.0], - 'opacity': 1, - 'rotation': 0, - }] + yaml_data.get("figures", []) - try: - data = e.get_template('style.html.j2').render(card=yaml_data, xml=xml_data) + data = e.get_template('style.html.j2').render(yaml=yaml_data, xml=xml_data) except Exception as ex: data = f"
{ex}
" + traceback.print_exc() f.write("\n" + data) endef diff --git a/style.html.j2 b/style.html.j2 index 3972f28..c56f52c 100644 --- a/style.html.j2 +++ b/style.html.j2 @@ -1,34 +1,49 @@ {% macro figure_layer(figure) %} {% set figure_style %}{% filter cull_whitespace %} - {% if figure.opacity!=1 %}opacity: {{ figure.opacity }};{% endif %} - {% if figure.color!=1 %}color: {{ figure.color }};{% endif %} + {% if figure.opacity!=1 %} + opacity: {{ figure.opacity }}; + {% endif %} + {% if figure.color!=1 %} + color: {{ figure.color }}; + {% endif %} + transform: - {% if figure.offset|any %}translate({{ figure.offset[0]*100 }}%, {{ figure.offset[1]*100 }}%){% endif %} - {% if figure.rotation %}rotate({{ figure.rotation }}deg){% endif %} - {% if figure.flip_x %}scaleX(-1){% endif %} - {% if figure.flip_y %}scaleY(-1){% endif %} - {% if figure.scale!=1 %}scale({{ figure.scale }}){% endif %} + {% if figure.offset and figure.offset|any %} + translate({{ figure.offset[0]*100 }}%, {{ figure.offset[1]*100 }}%) + {% endif %} + {% if figure.rotation %} + rotate({{ figure.rotation }}deg) + {% endif %} + {% if figure.flip_x %} + scaleX(-1) + {% endif %} + {% if figure.flip_y %} + scaleY(-1) + {% endif %} + {% if figure.scale and figure.scale!=1 %} + scale({{figure.scale | string | replace("[", "") | replace("]", "") }}) + {% endif %} ; {% endfilter %}{% endset %} -
- {% if figure.type == "material-icons" %} +
+ {% if figure.source == "material-icons" %} {# https://material.io/icons/ #} {{ figure.name }} - {% elif figure.type == "mdi" %} + {% elif figure.source == "mdi" %} {# https://materialdesignicons.com/ #} - {% elif figure.type == "fa" %} + {% elif figure.source == "fa" %} {# http://fontawesome.io/icons/ #} - {% elif figure.type == "lnr" %} + {% elif figure.source == "lnr" %} {# https://linearicons.com/free #} - {% elif figure.type == "oi" %} + {% elif figure.source == "oi" %} {# https://useiconic.com/open #} - {% elif figure.type == "svg" %} - {# /cards/svg #} + {% elif figure.source == "svg" %} + {# pvv.ntnu.no/~pederbs/cards/svg #} {% if figure.color == true %} {% elif figure.color %} @@ -36,16 +51,17 @@ {% else %} {% endif %} - {% elif figure.type == "img" %} - {# /cards/img #} + {% elif figure.source in ["img", "emoji"] %} + {# pvv.ntnu.no/~pederbs/cards/img #} + {# /cards/emoji #} {% if figure.color == true %} - + {% elif figure.color %} - + {% else %} - + {% endif %} - {% elif figure.type == "url" %} + {% elif figure.source == "url" %} {% if figure.color == true %} {% elif figure.color %} @@ -57,7 +73,7 @@
{% endmacro %} -{% macro named_icon_to_emoji(name) %} +{% macro named_symbol_to_emoji(name) %} {% if "AIR" in name | upper %} 🌪 {% elif "ALCHEMY" in name | upper %} ⚗️ {% elif "ANIMAL" in name | upper %} 🐾 @@ -83,105 +99,96 @@ {% endif %} {% endmacro %} -
+
- {{ card.title or xml.name }} + {{ yaml.name or xml.name }}
- {% if card.icon %} -
- {% if " " in card.icon %} - {% for icon in card.icon.split(" ") %} - {{ named_icon_to_emoji(icon) }} - {% endfor %} - {% else %} - {{ named_icon_to_emoji(card.icon) }} - {% endif %} -
+ {% if yaml.symbol %} +
+ {% if " " in yaml.symbol %} + {% for symbol in yaml.symbol | split(" ") %} + {{ named_symbol_to_emoji(symbol) }} + {% endfor %} + {% else %} + {{ named_symbol_to_emoji(yaml.symbol) }} + {% endif %} +
{% elif xml.symbol %} -
- {{ xml.symbol }} -
+
+ {{ xml.symbol }} +
{% endif %}
- {% for figure in card.figures %} - {{ figure_layer(figure) }} - {% endfor %} -
- -
- {% for cost in card.costs %} -
- {% if cost.split(" ") | length == 2 and cost.split(" ")[0] | int(-1) != -1 %} - {{ cost.split(" ")[0] }}
- {{ cost.split(" ")[1] }} - {% else %} - {{ cost }} + {% if xml.image %} + {{ figure_layer({ + 'name': xml.image if xml.image | startswith("http") else xml.image | split(":") | tail | join(":"), + 'source': "url" if xml.image | startswith("http") else xml.image | split(":") | first + }) }} + {% endif %} + +
+
    + {% if xml.playcost %} + {% for playcost in xml.playcost.split(",") %} +
  • {{ playcost }}
  • + {% endfor %} {% endif %} + {% if yaml.playcost %} + {% for playcost in yaml.playcost.split(",") %} +
  • {{ playcost }}
  • + {% endfor %} + {% endif %} + {% for playcost in yaml.playcosts %} +
  • {{ playcost }}
  • + {% endfor %} +
+
+
+ {% for cost in yaml.costs %} +
+ {% if cost.split(" ") | length == 2 and cost.split(" ")[0] | int(-1) != -1 %} + {{ cost.split(" ")[0] }}
+ {{ cost.split(" ")[1] }} + {% else %} + {{ cost }} + {% endif %}
{% endfor %} {% for label, data in [ - ["Difficulty", xml.difficulty], - ["Power", xml.power], - ["Range", xml.range], - ["Duration", xml.duration], - ["CP", xml.cp] + ["Difficulty", xml.difficulty or yaml.difficulty], + ["Power", xml.power or yaml.power], + ["Range", xml.range or yaml.range], + ["Duration", xml.duration or yaml.duration], + ["CP", xml.cp or yaml.cp] ] %} {% if data %} -
- {{ data }}
- {{ label }} -
+
+ {{ data }}
+ {{ label }} +
{% endif %} {% endfor %}
- {% if card.flavor %} -
"{{ card.flavor }}"
- {% endif %} - {% if card.description %} -
{{ card.description | markdown | safe }}
- {% elif xml.description %} -
{{ xml.description | markdown | safe }}
- {% endif %} - {% if card.steps %} -
    - {% for step in card.steps %} -
  • {{ step }}
  • - {% endfor %} -
- {% endif %} + {% if yaml.flavor %} +
"{{ yaml.flavor }}"
+ {% endif %} + + {% if yaml.description %} +
{{ yaml.description | markdown | safe }}
+ {% elif xml.description %} +
{{ xml.description | markdown | safe }}
+ {% endif %} + + {% if yaml.steps %} +
    + {% for step in yaml.steps %} +
  • {{ step }}
  • + {% endfor %} +
+ {% endif %}
- -{#
{{ card }}
#} diff --git a/style.js b/style.js index 05a55f4..afb36da 100644 --- a/style.js +++ b/style.js @@ -1,7 +1,7 @@ var md = window.markdownit(); var context = { 'xml' : {}, - 'card' : jsyaml.load(document.getElementById("yaml_data").innerHTML), + 'yaml' : jsyaml.load(document.getElementById("yaml_data").innerHTML), 'alert' : alert, }; @@ -13,28 +13,6 @@ for (var i=0; i < xml_data_items.length; i++) { context.xml[key] = val; } -function is_set(asd) { - return !(typeof asd === 'undefined' || asd.length === 0); -} - -// set the figure by the -if (!is_set(context.card.figures) && context.xml.image ) { - context.card.figures = [{ - 'name': (context.xml.image.substr(0, 4) == "http") - ? context.xml.image - : context.xml.image.split(":").slice(1).join(":"), - 'type': (context.xml.image.substr(0, 4) == "http") - ? "url" - : context.xml.image.split(":")[0], - 'scale': 1.0, - 'flip_x': false, - 'flip_y': false, - 'offset': [0.0, 0.0], - 'opacity': 1, - 'rotation': 0, - }].concat(context.card.figures); -} - var env = new nunjucks.Environment([], { autoescape: true, trimBlocks: true, @@ -58,6 +36,12 @@ env.addFilter('all', function(iterable) { } return true; }); +env.addFilter('startswith', function(string, match) { + return string.slice(0, match.length) === match; +}); +env.addFilter('tail', function(sequence) { + return sequence.slice(1) +}); try { rendered = env.renderString(jinja_template, context); diff --git a/style.scss b/style.scss index 25ca021..6796ed5 100644 --- a/style.scss +++ b/style.scss @@ -3,11 +3,11 @@ width: 2.5in; height: 3.5in; box-sizing: border-box; - border-radius: 2mm; - border-width: 2mm; + border-radius: 0mm; + border-width: 0.3mm; border-color: black; border-style: solid; - background-color: #444; + background-color: #fff; overflow: hidden; font-size: 2.5mm; @@ -17,41 +17,40 @@ grid-template-columns: auto 1fr 0.9in; grid-template-rows: 1.9em var(--figure-size) 2.1em auto; grid-template-areas: - "icon title title" - "figure figure properties" + "symbol title title" + "figure figure playcosts" "costbar costbar costbar" "description description description"; header { grid-area: title; font-size: 1.8em; line-height: 1em; - margin-top: -1mm; margin-left: -1em; border-radius: 1mm 1mm 0 0; text-align: center; - background-color: #222; + background-color: #ddd; border-radius: 0; - color: white; + color: #333; } - .icon { - grid-area: icon; + .symbol { + grid-area: symbol; text-align: center; - background-color: #222; - color: white; + background-color: #ddd; + color: #333; padding-top: 0.6mm; padding-left: 0.8mm; white-space: nowrap; } figure { grid-area: figure; - background-color: #333; + background-color: #fff; overflow: hidden; position: relative; border-radius: 0; margin: 0; - div { - --figure-color: #bbb; + .layer { + --figure-color: #555; color: var(--figure-color); position: absolute; top:0;right:0;left:0;bottom:0; @@ -64,8 +63,8 @@ height: 100%; } img { - width: calc(var(--figure-size) * 0.9); - height: calc(var(--figure-size) * 0.9); + width: calc(var(--figure-size)); + height: calc(var(--figure-size)); object-fit: contain; } img.colored { @@ -79,32 +78,31 @@ font-size: calc(var(--figure-size) * 0.9); line-height: var(--figure-size); } - .lnr{ + .lnr { font-size: calc(var(--figure-size) * 0.8); - line-height: var(--figure-size); + line-height: calc(var(--figure-size) * 0.95); } - } } - aside { - grid-area: properties; - border-left: solid 0.3mm black; - background-color: #aaa; + .playcosts { + grid-area: playcosts; + border-left: solid 0.3mm #ccc; + background-color: #ddd; + color: #444 ; padding: 0.5mm; ul { margin:0; list-style-type: none; padding: 0; - li{ - } + li {} } } .costbar { grid-area: costbar; border-radius: 0; - background-color: black; - color:white; + background-color: #555; + color: white; display: flex; flex-direction: row; flex-wrap: nowrap; @@ -123,7 +121,7 @@ grid-area: description; margin: 1mm; border-radius: 1mm; - background-color: #aaa; + background-color: #ddd; ul, ol { padding-left: 1.5em; @@ -134,51 +132,17 @@ } } -.fjomp_card.white { - border-radius: 0mm; - border-width: 0.3mm; - background-color: #fff; - header { - margin-top: 0; - background-color: #ddd; - color: #333; - } - .icon { - grid-area: icon; - background-color: #ddd; - color: #333; - } - figure { - background-color: #fff; - div { - --figure-color: #555; - } - } - aside { - border-left: solid 0.3mm #ccc; - background-color: #ddd; - color: #444 ; - - } - .costbar { - background-color: #555; - color: white; - } - .description { - background-color: #ddd; - } -} .fjomp_card.item { --figure-size: 1.35in; --figure-size: 1.5in; grid-template-columns: auto 1fr; grid-template-areas: - "icon title" + "symbol title" "figure figure" "costbar costbar" "description description"; - aside { + .playcosts { display: none; } } diff --git a/test_card.yaml b/test_card.yaml index 8c729ce..952988a 100644 --- a/test_card.yaml +++ b/test_card.yaml @@ -1,12 +1,12 @@ -title: Hit enemy -icon: defence -style: white +name: Hit enemy +symbol: defence +style: white item tags: - combat costs: - 2 ACT - 1 COMBO -properties: +playcosts: - 'Element: fire' - BODY+5 POWER flavor: Enemies sure are squishy @@ -16,26 +16,8 @@ steps: - Do A - Do A - Then B -notes: '' figures: -- name: batman - type: svg - color: true - scale: 0.8 - flip_x: false - flip_y: false - offset: - - 0.4 - - 0.2 - opacity: 1 - rotation: 0 -- name: wheelchair - type: fa - scale: 1 - flip_x: false - flip_y: false - offset: - - -0.2 - - 0 - opacity: 1 - rotation: 180 +- name: piuy/chicken + source: img + scale: 2 +notes: ''