mirror of
https://gitlab.constantvzw.org/osp/tools.cobbled-paths.git
synced 2024-12-22 12:40:32 +01:00
finished the draw tab and factorise functions
This commit is contained in:
parent
3a5061060c
commit
ac08b1c1ff
165
app.py
165
app.py
@ -5,7 +5,8 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import io
|
import io
|
||||||
from svg_to_hpgl import svgToHPGL
|
import requests
|
||||||
|
# from svg_to_hpgl import svgToHPGL
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@ -16,7 +17,32 @@ possible_extensions = [".flf"]
|
|||||||
etherpad = 'https://pad.constantvzw.org/p/'
|
etherpad = 'https://pad.constantvzw.org/p/'
|
||||||
prefix = 'cobbled-pad-'
|
prefix = 'cobbled-pad-'
|
||||||
|
|
||||||
# VARIABLES
|
# VARIABLES 4 CATALOGUE
|
||||||
|
# ------------------------------
|
||||||
|
|
||||||
|
output = {
|
||||||
|
'stroke': { 'ascii': ' | ' , 'fonts': [] },
|
||||||
|
'script': { 'ascii': ' _/' , 'fonts': [] },
|
||||||
|
'block': { 'ascii': '|_|' , 'fonts': [] },
|
||||||
|
'outline': { 'ascii': '/ /' , 'fonts': [] },
|
||||||
|
'effect': { 'ascii': ': :' , 'fonts': [] },
|
||||||
|
'pattern': { 'ascii': ')()' , 'fonts': [] },
|
||||||
|
|
||||||
|
# 'fill': { 'ascii': '_/', 'fonts': {} },
|
||||||
|
|
||||||
|
# 'directions': { 'ascii': '_/', 'fonts': {} },
|
||||||
|
# '3d': { 'ascii': '_/', 'fonts': {} },
|
||||||
|
|
||||||
|
# 'frame': { 'ascii': '_/', 'fonts': {} },
|
||||||
|
# 'code': { 'ascii': '_/', 'fonts': {} },
|
||||||
|
}
|
||||||
|
databases = {
|
||||||
|
'default': 'fonts made by the figlet developpers and given with the program, early 1993',
|
||||||
|
'contributed': 'fonts made by figlet amateurs and submitted to the official figlet ftp, from before 1993 to 2005',
|
||||||
|
'jave': 'figlet font library of JavE (a free Ascii drawing Editor)',
|
||||||
|
}
|
||||||
|
|
||||||
|
# VARIABLES 4 REGEX
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
# all the character that svgbob understand
|
# all the character that svgbob understand
|
||||||
@ -43,13 +69,46 @@ autofix = [
|
|||||||
[re.compile(r_nspec), "#"],
|
[re.compile(r_nspec), "#"],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# FUNCTIONS
|
||||||
|
# ------------------------------
|
||||||
|
|
||||||
def most_common(lst):
|
def most_common(lst):
|
||||||
return max(set(lst), key=lst.count)
|
return max(set(lst), key=lst.count)
|
||||||
|
|
||||||
|
def text2figlet(input, figfont):
|
||||||
|
figlet = subprocess.run(["figlet", input, "-f", figfont, "-w", "160"], stdout = subprocess.PIPE, text=True)
|
||||||
|
return figlet.stdout
|
||||||
|
|
||||||
|
def ascii2svg(ascii_input, weight):
|
||||||
|
svgbob = subprocess.run(["svgbob_cli", '--stroke-width', weight], input = ascii_input, stdout = subprocess.PIPE, text=True)
|
||||||
|
return svgbob.stdout
|
||||||
|
|
||||||
|
def ascii_autofix(ascii):
|
||||||
|
for regex, replace in autofix:
|
||||||
|
ascii = re.sub(regex, replace, ascii)
|
||||||
|
return ascii
|
||||||
|
|
||||||
|
def autofix_indication(ascii):
|
||||||
|
for regex, replace in autofix:
|
||||||
|
# the two markers have to not appear in any regex
|
||||||
|
ascii = re.sub(regex, "$" + replace + "€", ascii)
|
||||||
|
|
||||||
|
ascii = re.sub("[\$]", "<span class='fix'>", ascii)
|
||||||
|
ascii = re.sub("[\€]", "</span>", ascii)
|
||||||
|
return ascii
|
||||||
|
|
||||||
|
|
||||||
# ROUTES
|
# ROUTES
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|
||||||
|
# _ _
|
||||||
|
# (_)_ __ __| | _____ __
|
||||||
|
# | | '_ \ / _` |/ _ \ \/ /
|
||||||
|
# | | | | | (_| | __/> <
|
||||||
|
# |_|_| |_|\__,_|\___/_/\_\
|
||||||
|
#
|
||||||
|
# PRESENT THE TOOL
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
|
||||||
@ -57,6 +116,16 @@ def index():
|
|||||||
'index.html',
|
'index.html',
|
||||||
title = title)
|
title = title)
|
||||||
|
|
||||||
|
# _
|
||||||
|
# __| |_ __ __ ___ __
|
||||||
|
# / _` | '__/ _` \ \ /\ / /
|
||||||
|
# | (_| | | | (_| |\ V V /
|
||||||
|
# \__,_|_| \__,_| \_/\_/
|
||||||
|
#
|
||||||
|
# ETHERPAD 2 SVGBOB INTERFACE
|
||||||
|
# one iframe for the etherpad
|
||||||
|
# another iframe to dump the generated svg
|
||||||
|
|
||||||
@app.route("/draw.html")
|
@app.route("/draw.html")
|
||||||
def draw():
|
def draw():
|
||||||
|
|
||||||
@ -71,6 +140,39 @@ def draw():
|
|||||||
title = title,
|
title = title,
|
||||||
params = params)
|
params = params)
|
||||||
|
|
||||||
|
# this is the route of the iframe where the svg is generated and dumped
|
||||||
|
|
||||||
|
@app.route("/drawing/<id>")
|
||||||
|
def drawing(id):
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'pad': id or 'default',
|
||||||
|
'weight': request.args.get('w') or '3',
|
||||||
|
}
|
||||||
|
params['pad-full'] = etherpad + prefix + params['pad']
|
||||||
|
|
||||||
|
# get pad content
|
||||||
|
print(' getting ' + params['pad-full'])
|
||||||
|
pad_export = requests.get(params['pad-full'] + '/export/txt')
|
||||||
|
ascii_input = pad_export.text
|
||||||
|
|
||||||
|
# to SVG
|
||||||
|
svg = ascii2svg(ascii_input, params['weight']);
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
'drawing.html',
|
||||||
|
title = title,
|
||||||
|
params = params,
|
||||||
|
svg = svg)
|
||||||
|
|
||||||
|
# _ _
|
||||||
|
# ___ __ _| |_ __ _| | ___ __ _ _ _ ___
|
||||||
|
# / __/ _` | __/ _` | |/ _ \ / _` | | | |/ _ \
|
||||||
|
# | (_| (_| | || (_| | | (_) | (_| | |_| | __/
|
||||||
|
# \___\__,_|\__\__,_|_|\___/ \__, |\__,_|\___|
|
||||||
|
# |___/
|
||||||
|
#
|
||||||
|
# FIGLET 2 SVGBOB INTERACTIVE CATALOGUE
|
||||||
|
|
||||||
@app.route("/catalogue.html")
|
@app.route("/catalogue.html")
|
||||||
def catalogue():
|
def catalogue():
|
||||||
@ -80,27 +182,6 @@ def catalogue():
|
|||||||
'text': request.args.get('t') or 'Echoes',
|
'text': request.args.get('t') or 'Echoes',
|
||||||
'weight': request.args.get('w') or '3',
|
'weight': request.args.get('w') or '3',
|
||||||
}
|
}
|
||||||
output = {
|
|
||||||
'stroke': { 'ascii': ' | ' , 'fonts': [] },
|
|
||||||
'script': { 'ascii': ' _/' , 'fonts': [] },
|
|
||||||
'block': { 'ascii': '|_|' , 'fonts': [] },
|
|
||||||
'outline': { 'ascii': '/ /' , 'fonts': [] },
|
|
||||||
'effect': { 'ascii': ': :' , 'fonts': [] },
|
|
||||||
'pattern': { 'ascii': ')()' , 'fonts': [] },
|
|
||||||
|
|
||||||
# 'fill': { 'ascii': '_/', 'fonts': {} },
|
|
||||||
|
|
||||||
# 'directions': { 'ascii': '_/', 'fonts': {} },
|
|
||||||
# '3d': { 'ascii': '_/', 'fonts': {} },
|
|
||||||
|
|
||||||
# 'frame': { 'ascii': '_/', 'fonts': {} },
|
|
||||||
# 'code': { 'ascii': '_/', 'fonts': {} },
|
|
||||||
}
|
|
||||||
databases = {
|
|
||||||
'default': 'fonts made by the figlet developpers and given with the program, early 1993',
|
|
||||||
'contributed': 'fonts made by figlet amateurs and submitted to the official figlet ftp, from before 1993 to 2005',
|
|
||||||
'jave': 'figlet font library of JavE (a free Ascii drawing Editor)',
|
|
||||||
}
|
|
||||||
|
|
||||||
# walk in the figlet font directory
|
# walk in the figlet font directory
|
||||||
for root, dirs, files in os.walk(fonts_directory):
|
for root, dirs, files in os.walk(fonts_directory):
|
||||||
@ -109,8 +190,8 @@ def catalogue():
|
|||||||
(basename, ext) = os.path.splitext(name)
|
(basename, ext) = os.path.splitext(name)
|
||||||
if ext in possible_extensions:
|
if ext in possible_extensions:
|
||||||
|
|
||||||
path = os.path.join(root, name)
|
figfont = os.path.join(root, name)
|
||||||
print(path)
|
print(figfont)
|
||||||
|
|
||||||
# get font category out of last folder
|
# get font category out of last folder
|
||||||
catalogue = root.split('/')[-2]
|
catalogue = root.split('/')[-2]
|
||||||
@ -121,37 +202,16 @@ def catalogue():
|
|||||||
output[type]['fonts'].append(f)
|
output[type]['fonts'].append(f)
|
||||||
f['name'] = name
|
f['name'] = name
|
||||||
f['catalogue'] = catalogue
|
f['catalogue'] = catalogue
|
||||||
|
f['ascii'] = text2figlet(params['text'], figfont)
|
||||||
figlet = subprocess.run(["figlet", params['text'], "-f", path, "-w", "160"], stdout = subprocess.PIPE, text=True)
|
f['svg'] = ascii2svg(f['ascii'], params['weight'])
|
||||||
f['ascii'] = figlet.stdout
|
|
||||||
|
|
||||||
font_info = subprocess.run(["figlet", "-I", path, "-w", "160"], stdout = subprocess.PIPE, text=True)
|
|
||||||
f['info'] = font_info
|
|
||||||
|
|
||||||
svgbob = subprocess.run(["svgbob_cli", '--stroke-width', params['weight']], input = f['ascii'], stdout = subprocess.PIPE, text=True)
|
|
||||||
f['svg'] = svgbob.stdout
|
|
||||||
|
|
||||||
# regex auto_fix
|
# regex auto_fix
|
||||||
fixed = f['ascii']
|
f['ascii_fix'] = ascii_autofix(f['ascii'])
|
||||||
for regex, replace in autofix:
|
|
||||||
fixed = re.sub(regex, replace, fixed)
|
|
||||||
f['ascii_fix'] = fixed
|
|
||||||
|
|
||||||
if f['ascii'] != f['ascii_fix']:
|
if f['ascii'] != f['ascii_fix']:
|
||||||
f['autofix'] = True
|
f['autofix'] = True
|
||||||
|
f['ascii_fix_indication'] = autofix_indication(f['ascii_fix'])
|
||||||
fix_indication = f['ascii']
|
f['svg_fix'] = ascii2svg(f['ascii_fix'], params['weight'])
|
||||||
for regex, replace in autofix:
|
|
||||||
# the two markers have to not appear in any regex
|
|
||||||
fix_indication = re.sub(regex, "$" + replace + "€", fix_indication)
|
|
||||||
fix_indication = re.sub("[\$]", "<span class='fix'>", fix_indication)
|
|
||||||
fix_indication = re.sub("[\€]", "</span>", fix_indication)
|
|
||||||
f['ascii_fix_indication'] = fix_indication
|
|
||||||
|
|
||||||
svgbob_fix = subprocess.run(["svgbob_cli", '--stroke-width', params['weight']], input = f['ascii_fix'], stdout = subprocess.PIPE, text=True)
|
|
||||||
f['svg_fix'] = svgbob_fix.stdout
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'catalogue.html',
|
'catalogue.html',
|
||||||
@ -160,6 +220,9 @@ def catalogue():
|
|||||||
output = output,
|
output = output,
|
||||||
params = params)
|
params = params)
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
|
||||||
def make_svg ():
|
def make_svg ():
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@ -6,57 +6,76 @@
|
|||||||
|
|
||||||
<header class="controls">
|
<header class="controls">
|
||||||
<label>etherpad</label>
|
<label>etherpad</label>
|
||||||
<input class="get-input" type="text" value="{{params['pad']}}" data-name="p"/>
|
<input id="pad-name" type="text" value="{{params['pad']}}" data-name="p"/>
|
||||||
<button>go</button>
|
<button id="button-pad" data-use="pad-name">go</button>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<button onClick="window.location.reload();">generate</button>
|
<button id="button-svg">generate</button>
|
||||||
|
|
||||||
<label>weight</label>
|
<!-- <label>weight</label>
|
||||||
<input class="get-input" type="range" min="1" max="8" value="{{params['weight']}}" data-name="w"/>
|
<input class="get-input" type="range" min="1" max="8" value="{{params['weight']}}" data-name="w"/> -->
|
||||||
|
|
||||||
<label class="text-label" for="text-checkbox"
|
<!-- <label class="text-label" for="text-checkbox"
|
||||||
title="display the remaining text in the svg output in red">
|
title="display the remaining text in the svg output in red">
|
||||||
output text</label>
|
output text</label>
|
||||||
<input id="text-checkbox" type="checkbox"
|
<input id="text-checkbox" type="checkbox"
|
||||||
class="body-class-check" value="check-text" checked/>
|
class="body-class-check" value="check-text" checked/> -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let inputs = document.getElementsByClassName('get-input');
|
function updateGET(frame, param, value){
|
||||||
for(let input of inputs){
|
// object from GET parameters
|
||||||
input.addEventListener('input', function(){
|
let [base_src, params_src] = frame.src.split("?");
|
||||||
const url = new URL(window.location.href);
|
let params = new URLSearchParams(params_src);
|
||||||
url.searchParams.set(input.dataset.name, input.value);
|
// update param
|
||||||
window.history.replaceState(null, null, url);
|
params.set(param, value);
|
||||||
});
|
// reconstituate URL
|
||||||
|
let new_src = base_src + "?" + params.toString();
|
||||||
|
// set and refresh
|
||||||
|
frame.src = new_src;
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
let button_pad = document.getElementById('button-pad');
|
||||||
function toggle_class(classname, val){
|
let button_svg = document.getElementById('button-svg');
|
||||||
if(val){
|
|
||||||
document.body.classList.add(classname);
|
// --- pad go button
|
||||||
}
|
button_pad.addEventListener('click', function(){
|
||||||
else{
|
let svg_iframe = document.getElementById('svg-iframe');
|
||||||
document.body.classList.remove(classname);
|
let pad_iframe = document.getElementById('pad-iframe');
|
||||||
}
|
let input = document.getElementById(button_pad.dataset.use);
|
||||||
}
|
let value = input.value;
|
||||||
let body_class_checkboxes = document.getElementsByClassName("body-class-check");
|
let param = input.dataset.name;
|
||||||
for(let checkbox of body_class_checkboxes){
|
|
||||||
let classname = checkbox.value;
|
let pad_src = pad_iframe.src;
|
||||||
checkbox.addEventListener('input', function(){
|
pad_src = pad_src.split('-');
|
||||||
toggle_class(classname, checkbox.checked);
|
pad_src[pad_src.length-1] = value;
|
||||||
});
|
pad_src = pad_src.join('-');
|
||||||
toggle_class(classname, checkbox.checked);
|
pad_iframe.src = pad_src;
|
||||||
}
|
|
||||||
|
let svg_src = svg_iframe.src;
|
||||||
|
svg_src = svg_src.split('/');
|
||||||
|
svg_src[svg_src.length-1] = value;
|
||||||
|
svg_src = svg_src.join('/');
|
||||||
|
svg_iframe.src = svg_src;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- svg generation button
|
||||||
|
button_svg.addEventListener('click', function(){
|
||||||
|
let svg_iframe = document.getElementById('svg-iframe');
|
||||||
|
svg_iframe.contentWindow.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="font">
|
<div class="font">
|
||||||
<iframe class="f-ascii" src="{{params['pad-full']}}">
|
<iframe class="f-ascii" id="pad-iframe" src="{{params['pad-full']}}">
|
||||||
</iframe>
|
</iframe>
|
||||||
<div class="f-svg"></div>
|
<div class="f-svg">
|
||||||
|
<iframe id="svg-iframe" src="/drawing/{{params['pad']}}">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
<aside class="right">
|
<aside class="right">
|
||||||
<button>> SVG</button>
|
<button>> SVG</button>
|
||||||
<button>> HPGL</button>
|
<button>> HPGL</button>
|
||||||
|
12
templates/drawing.html
Normal file
12
templates/drawing.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="static/css/reset.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="static/css/interface.css" />
|
||||||
|
</head>
|
||||||
|
<body class="">
|
||||||
|
{{ svg|safe }}
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user