very wip: adding template pad + links next to buttons + different background color for this branch to see the difference
This commit is contained in:
parent
29d269e9b4
commit
7601797445
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
|
.venv
|
||||||
.env
|
.env
|
||||||
|
__pycache__
|
||||||
|
58
octomode.py
58
octomode.py
@ -2,7 +2,8 @@ import os
|
|||||||
import json
|
import json
|
||||||
from flask import Flask, request, render_template, redirect, url_for
|
from flask import Flask, request, render_template, redirect, url_for
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode, urlparse
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# To sanitize Flask input fields
|
# To sanitize Flask input fields
|
||||||
from markupsafe import Markup, escape
|
from markupsafe import Markup, escape
|
||||||
@ -23,9 +24,9 @@ def get_pad_content(pad_name, ext=""):
|
|||||||
if ext:
|
if ext:
|
||||||
pad_name = f'{ pad_name }{ ext }'
|
pad_name = f'{ pad_name }{ ext }'
|
||||||
|
|
||||||
print(pad_name)
|
# print(pad_name)
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
'padID' : pad_name,
|
'padID' : pad_name,
|
||||||
'apikey' : APP.config['PAD_API_KEY']
|
'apikey' : APP.config['PAD_API_KEY']
|
||||||
}
|
}
|
||||||
@ -43,7 +44,7 @@ def get_pad_content(pad_name, ext=""):
|
|||||||
return content
|
return content
|
||||||
|
|
||||||
def all_pads():
|
def all_pads():
|
||||||
arguments = {
|
arguments = {
|
||||||
'apikey' : APP.config['PAD_API_KEY'],
|
'apikey' : APP.config['PAD_API_KEY'],
|
||||||
}
|
}
|
||||||
api_call = 'listAllPads'
|
api_call = 'listAllPads'
|
||||||
@ -62,10 +63,12 @@ def create_pad_on_first_run(name, ext):
|
|||||||
default_template = 'templates/default.md'
|
default_template = 'templates/default.md'
|
||||||
elif 'css' in ext:
|
elif 'css' in ext:
|
||||||
default_template = 'templates/default.css'
|
default_template = 'templates/default.css'
|
||||||
|
elif 'template' in ext:
|
||||||
|
default_template = 'templates/default.template.html'
|
||||||
default_template = open(default_template).read()
|
default_template = open(default_template).read()
|
||||||
|
|
||||||
# Create pad and add the default template
|
# Create pad and add the default template
|
||||||
arguments = {
|
arguments = {
|
||||||
'padID' : pad,
|
'padID' : pad,
|
||||||
'apikey' : APP.config['PAD_API_KEY'],
|
'apikey' : APP.config['PAD_API_KEY'],
|
||||||
'text' : default_template
|
'text' : default_template
|
||||||
@ -73,16 +76,22 @@ def create_pad_on_first_run(name, ext):
|
|||||||
api_call = 'createPad'
|
api_call = 'createPad'
|
||||||
json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||||
|
|
||||||
def md_to_html(md_pad_content):
|
def md_to_html(md_pad_content, name):
|
||||||
# Convert Markdown to HTML
|
# Convert Markdown to HTML, using the template from the NAME.template.html pad
|
||||||
# html = markdown.markdown(md_pad_content, extensions=['meta', 'attr_list']) # attr_list does not work
|
protocol = urlparse(request.base_url).scheme + "://"
|
||||||
html = pypandoc.convert_text(md_pad_content, 'html', format='md')
|
hostname = urlparse(request.base_url).netloc
|
||||||
|
domain = protocol + hostname
|
||||||
|
template_url = f"{ domain }{ APP.config['APPLICATION_ROOT'] }{ name }/template.html"
|
||||||
|
md_url = f"{ domain }{ APP.config['APPLICATION_ROOT'] }{ name }/pad.md"
|
||||||
|
# html = pypandoc.convert_text(md_pad_content, 'html', format='md', extra_args=[f'--template={ template_url }', '--standalone'])
|
||||||
|
result = subprocess.run(["pandoc", "--from", "markdown", "--to", "html", "--template", f"{ template_url }", md_url], capture_output=True, text=True)
|
||||||
|
html = result.stdout
|
||||||
|
|
||||||
# Sanitize the Markdown
|
# Sanitize the Markdown
|
||||||
# html = bleach.clean(html)
|
# html = bleach.clean(html)
|
||||||
|
|
||||||
# Another built-in Flask way to sanitize
|
# Another built-in Flask way to sanitize
|
||||||
# html = escape(html)
|
# html = escape(html)
|
||||||
html = Markup(html)
|
html = Markup(html)
|
||||||
|
|
||||||
return html
|
return html
|
||||||
@ -102,10 +111,10 @@ def index():
|
|||||||
name = False
|
name = False
|
||||||
if request.values.get('name'):
|
if request.values.get('name'):
|
||||||
name = escape(request.values.get('name')) # Returns a Markup() object, which is "None" when False
|
name = escape(request.values.get('name')) # Returns a Markup() object, which is "None" when False
|
||||||
if name:
|
if name:
|
||||||
# This is when the environment is "created"
|
# This is when the environment is "created"
|
||||||
# The pads are filled with the default templates (pad, stylesheet, template)
|
# The pads are filled with the default templates (pad, stylesheet, template)
|
||||||
exts = ['.md', '.css']
|
exts = ['.md', '.css', '.template.html']
|
||||||
for ext in exts:
|
for ext in exts:
|
||||||
create_pad_on_first_run(name, ext)
|
create_pad_on_first_run(name, ext)
|
||||||
return redirect(url_for("pad", name=name))
|
return redirect(url_for("pad", name=name))
|
||||||
@ -126,6 +135,11 @@ def stylesheet(name):
|
|||||||
url = f"{ APP.config['PAD_URL'] }/{ name }.css"
|
url = f"{ APP.config['PAD_URL'] }/{ name }.css"
|
||||||
return render_template('iframe.html', url=url, name=name.strip(), pad_url=APP.config['PAD_URL'])
|
return render_template('iframe.html', url=url, name=name.strip(), pad_url=APP.config['PAD_URL'])
|
||||||
|
|
||||||
|
@APP.route('/<name>/template/')
|
||||||
|
def template(name):
|
||||||
|
url = f"{ APP.config['PAD_URL'] }/{ name }.template.html"
|
||||||
|
return render_template('iframe.html', url=url, name=name.strip(), pad_url=APP.config['PAD_URL'])
|
||||||
|
|
||||||
@APP.route('/<name>/html/')
|
@APP.route('/<name>/html/')
|
||||||
def html(name):
|
def html(name):
|
||||||
# only here we need application root to make all the URLs work.....
|
# only here we need application root to make all the URLs work.....
|
||||||
@ -151,7 +165,7 @@ def pdf(name):
|
|||||||
return render_template('pdf.html', url=url, name=name.strip(), pad_url=APP.config['PAD_URL'])
|
return render_template('pdf.html', url=url, name=name.strip(), pad_url=APP.config['PAD_URL'])
|
||||||
|
|
||||||
# //////////////////
|
# //////////////////
|
||||||
# RENDERED RESOURCES
|
# RENDERED RESOURCES
|
||||||
# //////////////////
|
# //////////////////
|
||||||
# (These are not saved as a file on the server)
|
# (These are not saved as a file on the server)
|
||||||
|
|
||||||
@ -162,11 +176,25 @@ def css(name):
|
|||||||
|
|
||||||
return css, 200, {'Content-Type': 'text/css; charset=utf-8'}
|
return css, 200, {'Content-Type': 'text/css; charset=utf-8'}
|
||||||
|
|
||||||
|
@APP.route('/<name>/pad.md')
|
||||||
|
def md(name):
|
||||||
|
# TO GENERATE THE CONTENT IN MARKDOWN
|
||||||
|
template_pad_content = get_pad_content(name, ext='.md')
|
||||||
|
|
||||||
|
return template_pad_content, 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
|
@APP.route('/<name>/template.html')
|
||||||
|
def pandoctemplate(name):
|
||||||
|
# TO GENERATE THE PANDOC TEMPLATE
|
||||||
|
template_pad_content = get_pad_content(name, ext='.template.html')
|
||||||
|
|
||||||
|
return template_pad_content, 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
||||||
|
|
||||||
@APP.route('/<name>/preview.html')
|
@APP.route('/<name>/preview.html')
|
||||||
def preview(name):
|
def preview(name):
|
||||||
# TO GENERATE THE PREVIEW WEBPAGE
|
# TO GENERATE THE PREVIEW WEBPAGE
|
||||||
md_pad_content = get_pad_content(name, ext='.md')
|
md_pad_content = get_pad_content(name, ext='.md')
|
||||||
html = md_to_html(md_pad_content)
|
html = md_to_html(md_pad_content, name)
|
||||||
metadata = get_md_metadata(md_pad_content)
|
metadata = get_md_metadata(md_pad_content)
|
||||||
if metadata:
|
if metadata:
|
||||||
lang = metadata['language'][0]
|
lang = metadata['language'][0]
|
||||||
@ -181,7 +209,7 @@ def preview(name):
|
|||||||
def pagedjs(name):
|
def pagedjs(name):
|
||||||
# TO GENERATE THE PAGED.JS WEBPAGE
|
# TO GENERATE THE PAGED.JS WEBPAGE
|
||||||
md_pad_content = get_pad_content(name, ext='.md')
|
md_pad_content = get_pad_content(name, ext='.md')
|
||||||
html = md_to_html(md_pad_content)
|
html = md_to_html(md_pad_content, name)
|
||||||
metadata = get_md_metadata(md_pad_content)
|
metadata = get_md_metadata(md_pad_content)
|
||||||
lang = metadata['language'][0]
|
lang = metadata['language'][0]
|
||||||
title = metadata['title'][0]
|
title = metadata['title'][0]
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
@charset "utf-8";
|
@charset "utf-8";
|
||||||
|
|
||||||
|
:root{
|
||||||
|
--highlightcolor: forestgreen;
|
||||||
|
}
|
||||||
|
|
||||||
body{
|
body{
|
||||||
min-width: 900px;
|
min-width: 900px;
|
||||||
|
background-color: darkkhaki;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GENERAL RULES */
|
/* GENERAL RULES */
|
||||||
|
|
||||||
/* main title element that says "in octomode" */
|
/* main title element that says "in octomode" */
|
||||||
h1 em.octomode{
|
h1 em.octomode{
|
||||||
color: darkorchid;
|
color: var(--highlightcolor);
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* navigation */
|
/* navigation */
|
||||||
@ -31,6 +37,17 @@ div#nav{
|
|||||||
margin: 0.5em 15px;
|
margin: 0.5em 15px;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
div#nav div#buttons a.link{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
div#nav div#buttons button{
|
||||||
|
border: 2px groove var(--highlightcolor);
|
||||||
|
padding: 0.2em 1em 0.3em;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
button:hover{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
div#nav span.info{
|
div#nav span.info{
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
@ -48,7 +65,7 @@ div#nav{
|
|||||||
div#nav input{
|
div#nav input{
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
/* click logic (CSS only) */
|
/* click logic (CSS only) */
|
||||||
span#click_md {
|
span#click_md {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,20 @@ window.addEventListener('load', function () {
|
|||||||
<h1>{{ name }} <a href="{{ url_for('index') }}"><em class="octomode">in octomode</em></a></h1>
|
<h1>{{ name }} <a href="{{ url_for('index') }}"><em class="octomode">in octomode</em></a></h1>
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
|
|
||||||
<a href="{{ url_for('pad', name=name) }}"><button>pad</button></a>
|
<a href="{{ url_for('pad', name=name) }}"><button>pad</button></a>
|
||||||
<span id="click_md" class="info" tabindex="1">🌐</span>
|
<a class="link" href="{{ pad_url }}/{{ name }}.md" target="_blank">🔗</a>
|
||||||
<div id="show_md" class="hidden"><input type="text" name="pad" value="{{ pad_url }}/{{ name }}.md"></div>
|
|
||||||
|
|
||||||
<a href="{{ url_for('stylesheet', name=name) }}"><button>stylesheet</button></a>
|
<a href="{{ url_for('stylesheet', name=name) }}"><button>stylesheet</button></a>
|
||||||
<span id="click_css" class="info" tabindex="1">🌐</span>
|
<a class="link" href="{{ pad_url }}/{{ name }}.css" target="_blank">🔗</a>
|
||||||
<div id="show_css" class="hidden"><input type="text" name="pad" value="{{ pad_url }}/{{ name }}.css"></div>
|
|
||||||
|
<a href="{{ url_for('template', name=name) }}"><button>template</button></a>
|
||||||
|
<a class="link" href="{{ pad_url }}/{{ name }}.template.html" target="_blank">🔗</a>
|
||||||
|
|
||||||
<a href="{{ url_for('html', name=name) }}"><button>html</button></a>
|
<a href="{{ url_for('html', name=name) }}"><button>html</button></a>
|
||||||
|
<a class="link" href="{{ url_for('preview', name=name) }}" target="_blank">🔗</a>
|
||||||
|
|
||||||
<a href="{{ url_for('pdf', name=name) }}"><button>pdf</button></a>
|
<a href="{{ url_for('pdf', name=name) }}"><button>pdf</button></a>
|
||||||
|
<a class="link" href="{{ url_for('pagedjs', name=name) }}" target="_blank">🔗</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
document.body.insertBefore(nav, document.body.firstChild);
|
document.body.insertBefore(nav, document.body.firstChild);
|
||||||
|
76
templates/default.template.html
Normal file
76
templates/default.template.html
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="generator" content="pandoc" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||||
|
$for(author-meta)$
|
||||||
|
<meta name="author" content="$author-meta$" />
|
||||||
|
$endfor$
|
||||||
|
$if(date-meta)$
|
||||||
|
<meta name="dcterms.date" content="$date-meta$" />
|
||||||
|
$endif$
|
||||||
|
$if(keywords)$
|
||||||
|
<meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" />
|
||||||
|
$endif$
|
||||||
|
$if(description-meta)$
|
||||||
|
<meta name="description" content="$description-meta$" />
|
||||||
|
$endif$
|
||||||
|
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
|
||||||
|
<style>
|
||||||
|
$styles.html()$
|
||||||
|
</style>
|
||||||
|
$for(css)$
|
||||||
|
<link rel="stylesheet" href="$css$" />
|
||||||
|
$endfor$
|
||||||
|
$for(header-includes)$
|
||||||
|
$header-includes$
|
||||||
|
$endfor$
|
||||||
|
$if(math)$
|
||||||
|
$if(mathjax)$
|
||||||
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||||
|
$endif$
|
||||||
|
$math$
|
||||||
|
$endif$
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
$for(include-before)$
|
||||||
|
$include-before$
|
||||||
|
$endfor$
|
||||||
|
$if(title)$
|
||||||
|
<header id="title-block-header">
|
||||||
|
<h1 class="title">$title$</h1>
|
||||||
|
$if(subtitle)$
|
||||||
|
<p class="subtitle">$subtitle$</p>
|
||||||
|
$endif$
|
||||||
|
$for(author)$
|
||||||
|
<p class="author">$author$</p>
|
||||||
|
$endfor$
|
||||||
|
$if(date)$
|
||||||
|
<p class="date">$date$</p>
|
||||||
|
$endif$
|
||||||
|
$if(abstract)$
|
||||||
|
<div class="abstract">
|
||||||
|
<div class="abstract-title">$abstract-title$</div>
|
||||||
|
$abstract$
|
||||||
|
</div>
|
||||||
|
$endif$
|
||||||
|
</header>
|
||||||
|
$endif$
|
||||||
|
$if(toc)$
|
||||||
|
<nav id="$idprefix$TOC" role="doc-toc">
|
||||||
|
$if(toc-title)$
|
||||||
|
<h2 id="$idprefix$toc-title">$toc-title$</h2>
|
||||||
|
$endif$
|
||||||
|
$table-of-contents$
|
||||||
|
</nav>
|
||||||
|
$endif$
|
||||||
|
$body$
|
||||||
|
$for(include-after)$
|
||||||
|
$include-after$
|
||||||
|
$endfor$
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -7,13 +7,6 @@
|
|||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section id="cover">
|
{{ pad_content }}
|
||||||
<h1 id="cover_title">{{ title }}</h1>
|
|
||||||
<div id="cover_container"></div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="main">
|
|
||||||
<div id="wrapper">{{ pad_content }}</div>
|
|
||||||
</section>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user