Support any amount of figures, with arbitrary positioning/size/colours/sources
This commit is contained in:
@@ -2,13 +2,15 @@
|
|||||||
import glob, os
|
import glob, os
|
||||||
from yaml import load, dump
|
from yaml import load, dump
|
||||||
from common import Model
|
from common import Model
|
||||||
|
from figure import Figure
|
||||||
import config
|
import config
|
||||||
|
|
||||||
class Card(Model):
|
class Card(Model):
|
||||||
filename = ""#filename without extentions
|
filename = ""#filename without extentions
|
||||||
title = "title"
|
title = "title"
|
||||||
figure = "code"
|
figure = ["code"]
|
||||||
figure_source = "material-icons"
|
figure_source = "material-icons"
|
||||||
|
figure_parsed = []
|
||||||
#material-icons = https://material.io/icons/
|
#material-icons = https://material.io/icons/
|
||||||
#mdi = https://materialdesignicons.com/
|
#mdi = https://materialdesignicons.com/
|
||||||
#fa = http://fontawesome.io/icons/
|
#fa = http://fontawesome.io/icons/
|
||||||
@@ -54,12 +56,13 @@ def from_yaml(data, filename="from_yaml"):
|
|||||||
card.filename = filename
|
card.filename = filename
|
||||||
for key, val in load(data).items():
|
for key, val in load(data).items():
|
||||||
setattr(card, key, val)
|
setattr(card, key, val)
|
||||||
|
setattr(card, "figure_parsed", [Figure(line, getattr(card, "figure_source")) for line in getattr(card, "figure")])
|
||||||
return card
|
return card
|
||||||
|
|
||||||
def to_yaml(card):
|
def to_yaml(card):
|
||||||
out = {}
|
out = {}
|
||||||
for key in dir(card):
|
for key in dir(card):
|
||||||
if "_" not in key[0] and key not in ("filename","has_flag"):
|
if "_" not in key[0] and key not in ("filename","has_flag","figure_parsed"):
|
||||||
val = getattr(card, key)
|
val = getattr(card, key)
|
||||||
if (val or val==0) and val != getattr(Card, key):
|
if (val or val==0) and val != getattr(Card, key):
|
||||||
out[key] = val
|
out[key] = val
|
||||||
@@ -80,6 +83,7 @@ def from_form(form):#sanic's request.form
|
|||||||
setattr(card, key, val)
|
setattr(card, key, val)
|
||||||
else:
|
else:
|
||||||
setattr(card, key, val[0].strip().replace("\r\n", "\n"))
|
setattr(card, key, val[0].strip().replace("\r\n", "\n"))
|
||||||
|
setattr(card, "figure_parsed", [Figure(line, getattr(card, "figure_source")) for line in getattr(card, "figure")])
|
||||||
return card
|
return card
|
||||||
|
|
||||||
def is_filename_vacant(filename, in_carddir=True):
|
def is_filename_vacant(filename, in_carddir=True):
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
from common import Model
|
||||||
|
|
||||||
|
class Figure(Model):
|
||||||
|
filename = ""
|
||||||
|
source = ""
|
||||||
|
# material-icons = https://material.io/icons/
|
||||||
|
# mdi = https://materialdesignicons.com/
|
||||||
|
# fa = http://fontawesome.io/icons/
|
||||||
|
# svg = the svgs/ folder
|
||||||
|
color = ""
|
||||||
|
top = 0
|
||||||
|
bottom = 0
|
||||||
|
left = 0
|
||||||
|
right = 0
|
||||||
|
size = 0
|
||||||
|
autoscale = True
|
||||||
|
scale = 100.
|
||||||
|
width = 0
|
||||||
|
height = 0
|
||||||
|
rotate = 0
|
||||||
|
|
||||||
|
def __init__(self, line, source = ""):
|
||||||
|
data = line.split(",")
|
||||||
|
self.filename = data[0].strip()
|
||||||
|
if len(data) > 1:
|
||||||
|
for key, val in [[y.strip() for y in x.split(":")] for x in data[1:]]:
|
||||||
|
if key in ("width", "height", "size", "autoscale"):
|
||||||
|
continue
|
||||||
|
elif key in ("top", "bottom", "left", "right", "scale"):
|
||||||
|
if key == "scale" and val != "auto":
|
||||||
|
self.autoscale = False
|
||||||
|
val = float(val)
|
||||||
|
elif key in ("rotate"):
|
||||||
|
val = int(val)
|
||||||
|
if key:
|
||||||
|
setattr(self, key, val)
|
||||||
|
|
||||||
|
if not self.source:
|
||||||
|
self.source = source
|
||||||
|
|
||||||
|
if self.autoscale and self.top + self.bottom + self.left + self.right > 0:
|
||||||
|
l = 0
|
||||||
|
r = 0
|
||||||
|
t = 0
|
||||||
|
b = 0
|
||||||
|
s = 0
|
||||||
|
|
||||||
|
if self.top + self.bottom > self.left + self.right:
|
||||||
|
s = self.top + self.bottom
|
||||||
|
l += (self.top + self.bottom) / 2
|
||||||
|
r += (self.top + self.bottom) / 2
|
||||||
|
ratio_t = self.top / s
|
||||||
|
ratio_b = self.bottom / s
|
||||||
|
|
||||||
|
if self.left <= r:
|
||||||
|
r -= self.left
|
||||||
|
else:
|
||||||
|
temp = self.left - r
|
||||||
|
r = 0
|
||||||
|
s += temp
|
||||||
|
t += temp * ratio_t
|
||||||
|
b += temp * ratio_b
|
||||||
|
|
||||||
|
if self.right <= l:
|
||||||
|
l -= self.right
|
||||||
|
else:
|
||||||
|
temp = self.right - l
|
||||||
|
l = 0
|
||||||
|
s += temp
|
||||||
|
t += temp / 2
|
||||||
|
b += temp / 2
|
||||||
|
else:
|
||||||
|
s = self.left + self.right
|
||||||
|
t += (self.left + self.right) / 2
|
||||||
|
b += (self.left + self.right) / 2
|
||||||
|
ratio_l = self.left / s
|
||||||
|
ratio_r = self.right / s
|
||||||
|
|
||||||
|
if self.top <= b:
|
||||||
|
b -= self.top
|
||||||
|
else:
|
||||||
|
temp = self.top - b
|
||||||
|
b = 0
|
||||||
|
s += temp
|
||||||
|
l += temp * ratio_l
|
||||||
|
r += temp * ratio_r
|
||||||
|
|
||||||
|
if self.bottom <= t:
|
||||||
|
t -= self.bottom
|
||||||
|
else:
|
||||||
|
temp = self.bottom - t
|
||||||
|
t = 0
|
||||||
|
s += temp
|
||||||
|
l += temp * ratio_l
|
||||||
|
r += temp * ratio_r
|
||||||
|
|
||||||
|
self.top += t
|
||||||
|
self.bottom += b
|
||||||
|
self.left += l
|
||||||
|
self.right += r
|
||||||
|
self.size = s
|
||||||
@@ -111,12 +111,8 @@ article figure >* {
|
|||||||
color: var(--color-figure);
|
color: var(--color-figure);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:0;right:0;left:0;bottom:0;
|
top:0;right:0;left:0;bottom:0;
|
||||||
}
|
|
||||||
article figure img {
|
|
||||||
padding: 1mm 0;
|
|
||||||
display: block;
|
|
||||||
height: calc(100% - 2mm);
|
|
||||||
margin: auto auto;
|
margin: auto auto;
|
||||||
|
height:100%;
|
||||||
}
|
}
|
||||||
article figure img.svg_filter{
|
article figure img.svg_filter{
|
||||||
/*causes DPI issues when printing*/
|
/*causes DPI issues when printing*/
|
||||||
|
|||||||
+37
-19
@@ -5,29 +5,47 @@
|
|||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
#macro(figure $card)
|
#macro(figure $card)
|
||||||
#if($card.figure.__contains__(","))
|
#foreach($figure in $card.figure_parsed)
|
||||||
#figure_embed($card.figure.split(",").get(1).strip(), $card.figure_source, "111")
|
#figure_embed($figure)
|
||||||
#figure_embed($card.figure.split(",").get(0).strip(), $card.figure_source, "aaa")
|
|
||||||
#else
|
|
||||||
#figure_embed($card.figure, $card.figure_source, "aaa")
|
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#macro(figure_embed $figure $source $color)
|
#macro(figure_embed $fig)
|
||||||
#if($source == "material-icons")
|
#if($fig.source == "material-icons")
|
||||||
<!--https://material.io/icons/-->
|
<!--https://material.io/icons/-->
|
||||||
<i class="material-icons figure">$escape_html($label)</i>
|
<i class="material-icons figure" #figure_style($fig)>$escape_html($label)</i>
|
||||||
#elseif($source == "mdi")
|
#elseif($fig.source == "mdi")
|
||||||
<!--https://materialdesignicons.com/-->
|
<!--https://materialdesignicons.com/-->
|
||||||
<i class="mdi mdi-$escape_html($figure)"></i>
|
<i class="mdi mdi-$escape_html($fig.filename)" #figure_style($fig)></i>
|
||||||
#elseif($source == "fa")
|
#elseif($fig.source == "fa")
|
||||||
<!--http://fontawesome.io/icons/-->
|
<!--http://fontawesome.io/icons/-->
|
||||||
<i class="fa fa-$escape_html($figure)"></i>
|
<i class="fa fa-$escape_html($fig.filename)" #figure_style($fig)></i>
|
||||||
#elseif($source == "svg")
|
#elseif($fig.source == "svg")
|
||||||
<!--/cards/svg-->
|
<!--/cards/svg-->
|
||||||
<!--<img class="svg_filter" src="/svg/${escape_html($figure)}.svg">-->
|
<!--<img class="svg_filter" src="/svg/${escape_html($figure)}.svg">-->
|
||||||
<img src="/svg/${escape_html($figure)}.svg?color=$color">
|
#set($color = "")
|
||||||
|
#if($fig.color)
|
||||||
|
#set($color = "?color=${fig.color}")
|
||||||
|
#end
|
||||||
|
<img src="/svg/${escape_html($fig.filename)}.svg$color" #figure_style($fig)>
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
#macro(figure_style $fig)
|
||||||
|
style="
|
||||||
|
#if($fig.source == "svg") ## Unsupported with other sources due to being fonts, not images **
|
||||||
|
#if($fig.autoscale)
|
||||||
|
top:${fig.top}px;
|
||||||
|
right:${fig.right}px;
|
||||||
|
bottom:${fig.bottom}px;
|
||||||
|
left:${fig.left}px;
|
||||||
|
height:calc(100% - ${fig.size}px);
|
||||||
|
#else
|
||||||
|
top:calc(${fig.top}px - ${fig.bottom}px);
|
||||||
|
left:calc(${fig.left}px - ${fig.right}px);
|
||||||
|
height:${fig.scale}%;
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
transform:rotate(${fig.rotate}deg)"
|
||||||
|
#end
|
||||||
#macro(specialFlags $card)
|
#macro(specialFlags $card)
|
||||||
#if($card.has_flag("mastery"))
|
#if($card.has_flag("mastery"))
|
||||||
<big>
|
<big>
|
||||||
|
|||||||
@@ -41,3 +41,37 @@ ul li input[type=text][name=tag],
|
|||||||
ul li input[type=text][name=filename] {
|
ul li input[type=text][name=filename] {
|
||||||
width: 3.8cm;
|
width: 3.8cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltiptext {
|
||||||
|
visibility: hidden;
|
||||||
|
width: 160px;
|
||||||
|
background-color: #292A30;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.6em;
|
||||||
|
font-family:sans-serif;
|
||||||
|
font-style:normal;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip .tooltiptext {
|
||||||
|
top: -5px;
|
||||||
|
left: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip:hover .tooltiptext {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+47
-31
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<link rel="stylesheet" href="creator.css">
|
<link rel="stylesheet" href="creator.css">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/2.0.46/css/materialdesignicons.min.css">
|
||||||
<script src="creator.js"></script>
|
<script src="creator.js"></script>
|
||||||
|
|
||||||
#macro(update_preview)onkeyup="submit_preview(this.form)" onchange="submit_preview(this.form)"#end
|
#macro(update_preview)onkeyup="submit_preview(this.form)" onchange="submit_preview(this.form)"#end
|
||||||
@@ -19,37 +20,52 @@
|
|||||||
<input type="text" name="title" value="$escape_html($card.title)" #update_preview()>
|
<input type="text" name="title" value="$escape_html($card.title)" #update_preview()>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Figure:<br>
|
Figures:
|
||||||
<input type="text" name="figure" value="$escape_html($card.figure)" #update_preview()><br>
|
<i class="tooltip mdi mdi-help-circle">
|
||||||
|
<div class="tooltiptext">
|
||||||
Source:
|
figure, attribute:value, ...
|
||||||
#if($card.figure_source=="material-icons")
|
<br><br><big>Possible attributes:</big>
|
||||||
<input checked type="radio" name="figure_source" value="material-icons" #update_preview()>
|
<br>Top, left, bottom, right: x px
|
||||||
#else
|
<br>Colour: xxxxxxxx
|
||||||
<input type="radio" name="figure_source" value="material-icons" #update_preview()>
|
<br>Rotation: x deg
|
||||||
#end
|
<br>Scale: x % <small>(Leave blank for auto)</small>
|
||||||
<a href="https://material.io/icons/">material-icons</a>
|
<br>Source: svg, mdi...
|
||||||
|
<br><br><small>NOTE: svg source required for attributes other than rotation!</small>
|
||||||
#if($card.figure_source=="mdi")
|
|
||||||
<input checked type="radio" name="figure_source" value="mdi" #update_preview()>
|
</div>
|
||||||
#else
|
</i>
|
||||||
<input type="radio" name="figure_source" value="mdi" #update_preview()>
|
<textarea name="figure" rows="5" #update_preview()>$escape_html($card.figure, False)</textarea>
|
||||||
#end
|
|
||||||
<a href="https://materialdesignicons.com/">mdi</a>
|
<small>
|
||||||
|
Default Source:
|
||||||
#if($card.figure_source=="fa")
|
#if($card.figure_source=="material-icons")
|
||||||
<input checked type="radio" name="figure_source" value="fa" #update_preview()>
|
<input checked type="radio" name="figure_source" value="material-icons" #update_preview()>
|
||||||
#else
|
#else
|
||||||
<input type="radio" name="figure_source" value="fa" #update_preview()>
|
<input type="radio" name="figure_source" value="material-icons" #update_preview()>
|
||||||
#end
|
#end
|
||||||
<a href="http://fontawesome.io/icons/">fa</a>
|
<a href="https://material.io/icons/">material-icons</a>
|
||||||
|
|
||||||
#if($card.figure_source=="svg")
|
#if($card.figure_source=="mdi")
|
||||||
<input checked type="radio" name="figure_source" value="svg" #update_preview()>
|
<input checked type="radio" name="figure_source" value="mdi" #update_preview()>
|
||||||
#else
|
#else
|
||||||
<input type="radio" name="figure_source" value="svg" #update_preview()>
|
<input type="radio" name="figure_source" value="mdi" #update_preview()>
|
||||||
#end
|
#end
|
||||||
<a href="svg">svg</a>
|
<a href="https://materialdesignicons.com/">mdi</a>
|
||||||
|
|
||||||
|
#if($card.figure_source=="fa")
|
||||||
|
<input checked type="radio" name="figure_source" value="fa" #update_preview()>
|
||||||
|
#else
|
||||||
|
<input type="radio" name="figure_source" value="fa" #update_preview()>
|
||||||
|
#end
|
||||||
|
<a href="http://fontawesome.io/icons/">fa</a>
|
||||||
|
|
||||||
|
#if($card.figure_source=="svg")
|
||||||
|
<input checked type="radio" name="figure_source" value="svg" #update_preview()>
|
||||||
|
#else
|
||||||
|
<input type="radio" name="figure_source" value="svg" #update_preview()>
|
||||||
|
#end
|
||||||
|
<a href="svg">svg</a>
|
||||||
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Description:<br>
|
Description:<br>
|
||||||
|
|||||||
Reference in New Issue
Block a user