Browse Source

finished the draw tab and factorise functions

master
Doriane 8 months ago
parent
commit
ac08b1c1ff
  1. 165
      app.py
  2. 87
      templates/draw.html
  3. 12
      templates/drawing.html

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,35 +140,47 @@ 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("/catalogue.html") @app.route("/drawing/<id>")
def catalogue(): def drawing(id):
# text and weight as get parameter
params = { params = {
'text': request.args.get('t') or 'Echoes', 'pad': id or 'default',
'weight': request.args.get('w') or '3', 'weight': request.args.get('w') or '3',
} }
output = { params['pad-full'] = etherpad + prefix + params['pad']
'stroke': { 'ascii': ' | ' , 'fonts': [] },
'script': { 'ascii': ' _/' , 'fonts': [] },
'block': { 'ascii': '|_|' , 'fonts': [] },
'outline': { 'ascii': '/ /' , 'fonts': [] },
'effect': { 'ascii': ': :' , 'fonts': [] },
'pattern': { 'ascii': ')()' , 'fonts': [] },
# 'fill': { 'ascii': '_/', 'fonts': {} }, # get pad content
print(' getting ' + params['pad-full'])
pad_export = requests.get(params['pad-full'] + '/export/txt')
ascii_input = pad_export.text
# 'directions': { 'ascii': '_/', 'fonts': {} }, # to SVG
# '3d': { 'ascii': '_/', 'fonts': {} }, svg = ascii2svg(ascii_input, params['weight']);
# 'frame': { 'ascii': '_/', 'fonts': {} }, return render_template(
# 'code': { 'ascii': '_/', 'fonts': {} }, 'drawing.html',
} title = title,
databases = { params = params,
'default': 'fonts made by the figlet developpers and given with the program, early 1993', svg = svg)
'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)', # _ _
# ___ __ _| |_ __ _| | ___ __ _ _ _ ___
# / __/ _` | __/ _` | |/ _ \ / _` | | | |/ _ \
# | (_| (_| | || (_| | | (_) | (_| | |_| | __/
# \___\__,_|\__\__,_|_|\___/ \__, |\__,_|\___|
# |___/
#
# FIGLET 2 SVGBOB INTERACTIVE CATALOGUE
@app.route("/catalogue.html")
def catalogue():
# text and weight as get parameter
params = {
'text': request.args.get('t') or 'Echoes',
'weight': request.args.get('w') or '3',
} }
# walk in the figlet font directory # walk in the figlet font 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 ''

87
templates/draw.html

@ -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

@ -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…
Cancel
Save