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
|
||||
__pycache__
|
||||
|
58
octomode.py
58
octomode.py
@ -2,7 +2,8 @@ import os
|
||||
import json
|
||||
from flask import Flask, request, render_template, redirect, url_for
|
||||
from urllib.request import urlopen
|
||||
from urllib.parse import urlencode
|
||||
from urllib.parse import urlencode, urlparse
|
||||
import subprocess
|
||||
|
||||
# To sanitize Flask input fields
|
||||
from markupsafe import Markup, escape
|
||||
@ -23,9 +24,9 @@ def get_pad_content(pad_name, ext=""):
|
||||
if ext:
|
||||
pad_name = f'{ pad_name }{ ext }'
|
||||
|
||||
print(pad_name)
|
||||
# print(pad_name)
|
||||
|
||||
arguments = {
|
||||
arguments = {
|
||||
'padID' : pad_name,
|
||||
'apikey' : APP.config['PAD_API_KEY']
|
||||
}
|
||||
@ -43,7 +44,7 @@ def get_pad_content(pad_name, ext=""):
|
||||
return content
|
||||
|
||||
def all_pads():
|
||||
arguments = {
|
||||
arguments = {
|
||||
'apikey' : APP.config['PAD_API_KEY'],
|
||||
}
|
||||
api_call = 'listAllPads'
|
||||
@ -62,10 +63,12 @@ def create_pad_on_first_run(name, ext):
|
||||
default_template = 'templates/default.md'
|
||||
elif 'css' in ext:
|
||||
default_template = 'templates/default.css'
|
||||
elif 'template' in ext:
|
||||
default_template = 'templates/default.template.html'
|
||||
default_template = open(default_template).read()
|
||||
|
||||
# Create pad and add the default template
|
||||
arguments = {
|
||||
arguments = {
|
||||
'padID' : pad,
|
||||
'apikey' : APP.config['PAD_API_KEY'],
|
||||
'text' : default_template
|
||||
@ -73,16 +76,22 @@ def create_pad_on_first_run(name, ext):
|
||||
api_call = 'createPad'
|
||||
json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||
|
||||
def md_to_html(md_pad_content):
|
||||
# Convert Markdown to HTML
|
||||
# html = markdown.markdown(md_pad_content, extensions=['meta', 'attr_list']) # attr_list does not work
|
||||
html = pypandoc.convert_text(md_pad_content, 'html', format='md')
|
||||
def md_to_html(md_pad_content, name):
|
||||
# Convert Markdown to HTML, using the template from the NAME.template.html pad
|
||||
protocol = urlparse(request.base_url).scheme + "://"
|
||||
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
|
||||
# html = bleach.clean(html)
|
||||
|
||||
# Another built-in Flask way to sanitize
|
||||
# html = escape(html)
|
||||
# html = escape(html)
|
||||
html = Markup(html)
|
||||
|
||||
return html
|
||||
@ -102,10 +111,10 @@ def index():
|
||||
name = False
|
||||
if request.values.get('name'):
|
||||
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"
|
||||
# The pads are filled with the default templates (pad, stylesheet, template)
|
||||
exts = ['.md', '.css']
|
||||
exts = ['.md', '.css', '.template.html']
|
||||
for ext in exts:
|
||||
create_pad_on_first_run(name, ext)
|
||||
return redirect(url_for("pad", name=name))
|
||||
@ -126,6 +135,11 @@ def stylesheet(name):
|
||||
url = f"{ APP.config['PAD_URL'] }/{ name }.css"
|
||||
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/')
|
||||
def html(name):
|
||||
# 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'])
|
||||
|
||||
# //////////////////
|
||||
# RENDERED RESOURCES
|
||||
# RENDERED RESOURCES
|
||||
# //////////////////
|
||||
# (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'}
|
||||
|
||||
@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')
|
||||
def preview(name):
|
||||
# TO GENERATE THE PREVIEW WEBPAGE
|
||||
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)
|
||||
if metadata:
|
||||
lang = metadata['language'][0]
|
||||
@ -181,7 +209,7 @@ def preview(name):
|
||||
def pagedjs(name):
|
||||
# TO GENERATE THE PAGED.JS WEBPAGE
|
||||
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)
|
||||
lang = metadata['language'][0]
|
||||
title = metadata['title'][0]
|
||||
|
@ -1,14 +1,20 @@
|
||||
@charset "utf-8";
|
||||
@charset "utf-8";
|
||||
|
||||
:root{
|
||||
--highlightcolor: forestgreen;
|
||||
}
|
||||
|
||||
body{
|
||||
min-width: 900px;
|
||||
background-color: darkkhaki;
|
||||
}
|
||||
|
||||
/* GENERAL RULES */
|
||||
|
||||
/* main title element that says "in octomode" */
|
||||
h1 em.octomode{
|
||||
color: darkorchid;
|
||||
color: var(--highlightcolor);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* navigation */
|
||||
@ -31,6 +37,17 @@ div#nav{
|
||||
margin: 0.5em 15px;
|
||||
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{
|
||||
font-size: 16px;
|
||||
line-height: 0;
|
||||
@ -48,7 +65,7 @@ div#nav{
|
||||
div#nav input{
|
||||
min-width: 300px;
|
||||
}
|
||||
/* click logic (CSS only) */
|
||||
/* click logic (CSS only) */
|
||||
span#click_md {
|
||||
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>
|
||||
<div id="buttons">
|
||||
|
||||
<a href="{{ url_for('pad', name=name) }}"><button>pad</button></a>
|
||||
<span id="click_md" class="info" tabindex="1">🌐</span>
|
||||
<div id="show_md" class="hidden"><input type="text" name="pad" value="{{ pad_url }}/{{ name }}.md"></div>
|
||||
<a href="{{ url_for('pad', name=name) }}"><button>pad</button></a>
|
||||
<a class="link" href="{{ pad_url }}/{{ name }}.md" target="_blank">🔗</a>
|
||||
|
||||
<a href="{{ url_for('stylesheet', name=name) }}"><button>stylesheet</button></a>
|
||||
<span id="click_css" class="info" tabindex="1">🌐</span>
|
||||
<div id="show_css" class="hidden"><input type="text" name="pad" value="{{ pad_url }}/{{ name }}.css"></div>
|
||||
<a href="{{ url_for('stylesheet', name=name) }}"><button>stylesheet</button></a>
|
||||
<a class="link" href="{{ pad_url }}/{{ name }}.css" target="_blank">🔗</a>
|
||||
|
||||
<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 class="link" href="{{ url_for('preview', name=name) }}" target="_blank">🔗</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>`;
|
||||
|
||||
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>
|
||||
</head>
|
||||
<body>
|
||||
<section id="cover">
|
||||
<h1 id="cover_title">{{ title }}</h1>
|
||||
<div id="cover_container"></div>
|
||||
</section>
|
||||
|
||||
<section id="main">
|
||||
<div id="wrapper">{{ pad_content }}</div>
|
||||
</section>
|
||||
{{ pad_content }}
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user