Pull template out to global.

This commit is contained in:
voussoir 2023-09-17 12:53:19 -07:00
parent 6e3fea4160
commit 86692904a3

View file

@ -10,22 +10,17 @@ from voussoirkit import vlogging
log = vlogging.getLogger(__name__, 'imagegallery') log = vlogging.getLogger(__name__, 'imagegallery')
def imagegallery_argparse(args): TEMPLATE = jinja2.Template('''
patterns = pipeable.input_many(args.patterns) <html>
files = list(pathclass.glob_many_files(patterns)) <head>
files.sort() {% if title %}
<title>{{title}}</title>
html = jinja2.Template(textwrap.dedent(''' {% endif %}
<html> <meta charset="UTF-8">
<head> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
{% if title %} <style>
<title>{{title}}</title> :root
{% endif %} {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
:root
{
--color_bodybg: #272822; --color_bodybg: #272822;
--color_codebg: rgba(255, 255, 255, 0.05); --color_codebg: rgba(255, 255, 255, 0.05);
--color_codeborder: rgba(255, 255, 255, 0.2); --color_codeborder: rgba(255, 255, 255, 0.2);
@ -36,15 +31,15 @@ def imagegallery_argparse(args):
--color_inlinecodebg: rgba(255, 255, 255, 0.1); --color_inlinecodebg: rgba(255, 255, 255, 0.1);
--color_link: #ae81ff; --color_link: #ae81ff;
--color_maintext: #ddd; --color_maintext: #ddd;
} }
*, *:before, *:after *, *:before, *:after
{ {
box-sizing: inherit; box-sizing: inherit;
} }
html html
{ {
height: 100vh; height: 100vh;
box-sizing: border-box; box-sizing: border-box;
@ -54,10 +49,10 @@ def imagegallery_argparse(args):
font-family: Verdana, sans-serif; font-family: Verdana, sans-serif;
font-size: 10pt; font-size: 10pt;
margin: 0; margin: 0;
} }
body body
{ {
min-height: 100%; min-height: 100%;
width: fit-content; width: fit-content;
margin-left: auto; margin-left: auto;
@ -65,62 +60,62 @@ def imagegallery_argparse(args):
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
padding: 8px; padding: 8px;
} }
body.noscrollbar::-webkit-scrollbar body.noscrollbar::-webkit-scrollbar
{ {
display: none; display: none;
} }
body.noscrollbar body.noscrollbar
{ {
scrollbar-width: none; scrollbar-width: none;
} }
header header
{ {
width: 100%; width: 100%;
max-width: 120em; max-width: 120em;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
text-align: end; text-align: end;
} }
header > * header > *
{ {
display: inline-block; display: inline-block;
padding: 16px; padding: 16px;
background-color: var(--color_bodybg); background-color: var(--color_bodybg);
} }
.album, .album,
.photograph .photograph
{ {
position: relative; position: relative;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
margin-top: 8vh; margin-top: 8vh;
margin-bottom: 8vh; margin-bottom: 8vh;
} }
.photograph .photograph
{ {
padding: 2vh; padding: 2vh;
background-color: var(--color_bodybg); background-color: var(--color_bodybg);
border-radius: 16px; border-radius: 16px;
} }
article .photograph:first-of-type article .photograph:first-of-type
{ {
margin-top: 0; margin-top: 0;
} }
article .photograph:last-of-type article .photograph:last-of-type
{ {
margin-bottom: 0; margin-bottom: 0;
} }
.photograph img .photograph img
{ {
max-height: 92vh; max-height: 92vh;
border-radius: 8px; border-radius: 8px;
} }
.photograph .download_link .photograph .download_link
{ {
position: absolute; position: absolute;
bottom: 8px; bottom: 8px;
right: 8px; right: 8px;
@ -133,98 +128,98 @@ def imagegallery_argparse(args):
border-radius: 4px; border-radius: 4px;
font-weight: bold; font-weight: bold;
opacity: 80%; opacity: 80%;
} }
article .morelink article .morelink
{ {
font-size: 2em; font-size: 2em;
text-align: center; text-align: center;
margin-top: 0; margin-top: 0;
} }
@media not print @media not print
{ {
.photograph .photograph
{ {
box-shadow: #000 0px 0px 40px -10px; box-shadow: #000 0px 0px 40px -10px;
} }
} }
@media screen and (min-width: 600px) @media screen and (min-width: 600px)
{ {
article article
{ {
width: fit-content; width: fit-content;
} }
} }
@media screen and (max-width: 600px) @media screen and (max-width: 600px)
{ {
.photograph .photograph
{ {
box-shadow: none; box-shadow: none;
} }
} }
@media not all and (pointer: fine) @media not all and (pointer: fine)
{ {
#keyboardhint, #keyboardhint,
#scrollbartoggle #scrollbartoggle
{ {
display: none; display: none;
} }
} }
h1, h2, h3, h4, h5 h1, h2, h3, h4, h5
{ {
margin-bottom: 0; margin-bottom: 0;
} }
h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child
{ {
margin-top: 0; margin-top: 0;
} }
h2, h3, h4, h5 h2, h3, h4, h5
{ {
border-bottom: 1px solid var(--color_maintext); border-bottom: 1px solid var(--color_maintext);
/*background-color: var(--color_h1bg);*/ /*background-color: var(--color_h1bg);*/
} }
p:last-child p:last-child
{ {
margin-bottom: 0; margin-bottom: 0;
} }
h1 {font-size: 2.00em;} h1 * {font-size: inherit;} h1 {font-size: 2.00em;} h1 * {font-size: inherit;}
h2 {font-size: 1.75em;} h2 * {font-size: inherit;} h2 {font-size: 1.75em;} h2 * {font-size: inherit;}
h3 {font-size: 1.50em;} h3 * {font-size: inherit;} h3 {font-size: 1.50em;} h3 * {font-size: inherit;}
h4 {font-size: 1.25em;} h4 * {font-size: inherit;} h4 {font-size: 1.25em;} h4 * {font-size: inherit;}
h5 {font-size: 1.00em;} h5 * {font-size: inherit;} h5 {font-size: 1.00em;} h5 * {font-size: inherit;}
.header_anchor_link {display: none; font-size: 1.0em; text-decoration: none} .header_anchor_link {display: none; font-size: 1.0em; text-decoration: none}
h1:hover > .header_anchor_link {display: initial;} h1:hover > .header_anchor_link {display: initial;}
h2:hover > .header_anchor_link {display: initial;} h2:hover > .header_anchor_link {display: initial;}
h3:hover > .header_anchor_link {display: initial;} h3:hover > .header_anchor_link {display: initial;}
h4:hover > .header_anchor_link {display: initial;} h4:hover > .header_anchor_link {display: initial;}
h5:hover > .header_anchor_link {display: initial;} h5:hover > .header_anchor_link {display: initial;}
a a
{ {
color: var(--color_link); color: var(--color_link);
cursor: pointer; cursor: pointer;
} }
article * article *
{ {
max-width: 100%; max-width: 100%;
word-wrap: break-word; word-wrap: break-word;
} }
#table_of_contents #table_of_contents
{ {
border: 1px solid var(--color_blockquoteedge); border: 1px solid var(--color_blockquoteedge);
padding-top: 8px; padding-top: 8px;
padding-bottom: 8px; padding-bottom: 8px;
border-radius: 8px; border-radius: 8px;
} }
blockquote blockquote
{ {
background-color: var(--color_blockquotebg); background-color: var(--color_blockquotebg);
margin-inline-start: 0; margin-inline-start: 0;
margin-inline-end: 0; margin-inline-end: 0;
@ -233,54 +228,54 @@ def imagegallery_argparse(args):
padding: 8px; padding: 8px;
padding-inline-start: 20px; padding-inline-start: 20px;
padding-inline-end: 20px; padding-inline-end: 20px;
} }
table table
{ {
border-collapse: collapse; border-collapse: collapse;
font-size: 1em; font-size: 1em;
} }
table, table th, table td table, table th, table td
{ {
border: 1px solid var(--color_maintext); border: 1px solid var(--color_maintext);
} }
table th, table td table th, table td
{ {
padding: 4px; padding: 4px;
} }
ol ol, ul ul, ol ul, ul ol ol ol, ul ul, ol ul, ul ol
{ {
padding-inline-start: 20px; padding-inline-start: 20px;
} }
*:not(pre) > code *:not(pre) > code
{ {
background-color: var(--color_inlinecodebg); background-color: var(--color_inlinecodebg);
border-radius: 4px; border-radius: 4px;
line-height: 1.5; line-height: 1.5;
padding-left: 4px; padding-left: 4px;
padding-right: 4px; padding-right: 4px;
} }
pre pre
{ {
padding: 8px; padding: 8px;
border: 1px solid var(--color_codeborder); border: 1px solid var(--color_codeborder);
background-color: var(--color_codebg); background-color: var(--color_codebg);
overflow-x: auto; overflow-x: auto;
} }
code, code,
pre, pre,
.highlight * .highlight *
{ {
font-family: monospace; font-family: monospace;
} }
</style> </style>
</head> </head>
<body> <body>
<header> <header>
<a id="scrollbartoggle" onclick="return toggle_scrollbar();">scrollbar on/off</a> <a id="scrollbartoggle" onclick="return toggle_scrollbar();">scrollbar on/off</a>
</header> </header>
@ -293,16 +288,18 @@ def imagegallery_argparse(args):
{% for file in files %} {% for file in files %}
<article class="photograph"> <article class="photograph">
<a target="_blank" href="{{urlroot}}{{file.relative_to('.', simple=True)}}"><img loading="lazy" src="{{urlroot}}thumbs/small_{{file.relative_to('.', simple=True)}}"/></a> <a target="_blank" href="{{urlroot}}{{file.relative_to('.', simple=True)}}"><img loading="lazy" src="{{urlroot}}thumbs/small_{{file.relative_to('.', simple=True)}}"/></a>
{% if with_download_links %}
<a class="download_link" download="{{file.basename}}" href="{{urlroot}}{{file.relative_to('.', simple=True)}}">#{{loop.index}}/{{files|length}}</a> <a class="download_link" download="{{file.basename}}" href="{{urlroot}}{{file.relative_to('.', simple=True)}}">#{{loop.index}}/{{files|length}}</a>
{% endif %}
</article> </article>
{% endfor %} {% endfor %}
</body> </body>
<script type="text/javascript"> <script type="text/javascript">
let desired_scroll_position = null; let desired_scroll_position = null;
function toggle_scrollbar() function toggle_scrollbar()
{ {
if (document.body.classList.contains("noscrollbar")) if (document.body.classList.contains("noscrollbar"))
{ {
document.body.classList.remove("noscrollbar"); document.body.classList.remove("noscrollbar");
@ -313,10 +310,10 @@ def imagegallery_argparse(args):
document.body.classList.add("noscrollbar"); document.body.classList.add("noscrollbar");
localStorage.setItem("show_scrollbar", "no"); localStorage.setItem("show_scrollbar", "no");
} }
} }
function load_scrollbar_setting() function load_scrollbar_setting()
{ {
if (localStorage.getItem("show_scrollbar") === "no") if (localStorage.getItem("show_scrollbar") === "no")
{ {
document.body.classList.add("noscrollbar"); document.body.classList.add("noscrollbar");
@ -325,10 +322,10 @@ def imagegallery_argparse(args):
{ {
document.body.classList.remove("noscrollbar"); document.body.classList.remove("noscrollbar");
} }
} }
function get_center_img() function get_center_img()
{ {
let center_x = window.innerWidth / 2; let center_x = window.innerWidth / 2;
let center_y = window.innerHeight / 2; let center_y = window.innerHeight / 2;
while (true) while (true)
@ -345,9 +342,9 @@ def imagegallery_argparse(args):
return null; return null;
} }
} }
} }
function next_img(img) function next_img(img)
{ {
const images = Array.from(document.images); const images = Array.from(document.images);
const this_index = images.indexOf(img); const this_index = images.indexOf(img);
if (this_index === images.length-1) if (this_index === images.length-1)
@ -355,9 +352,9 @@ def imagegallery_argparse(args):
return img; return img;
} }
return images[this_index + 1]; return images[this_index + 1];
} }
function previous_img(img) function previous_img(img)
{ {
const images = Array.from(document.images); const images = Array.from(document.images);
const this_index = images.indexOf(img); const this_index = images.indexOf(img);
if (this_index === 0) if (this_index === 0)
@ -365,9 +362,9 @@ def imagegallery_argparse(args):
return img; return img;
} }
return images[this_index - 1]; return images[this_index - 1];
} }
function scroll_step() function scroll_step()
{ {
const distance = desired_scroll_position - document.body.scrollTop; const distance = desired_scroll_position - document.body.scrollTop;
const jump = (distance * 0.25) + (document.body.scrollTop < desired_scroll_position ? 1 : -1); const jump = (distance * 0.25) + (document.body.scrollTop < desired_scroll_position ? 1 : -1);
document.body.scrollTop = document.body.scrollTop + jump; document.body.scrollTop = document.body.scrollTop + jump;
@ -377,24 +374,24 @@ def imagegallery_argparse(args):
{ {
window.requestAnimationFrame(scroll_step); window.requestAnimationFrame(scroll_step);
} }
} }
function scroll_to_img(img) function scroll_to_img(img)
{ {
const img_centerline = img.offsetParent.offsetTop + img.offsetTop + (img.offsetHeight / 2); const img_centerline = img.offsetParent.offsetTop + img.offsetTop + (img.offsetHeight / 2);
// document.body.scrollTop = img_centerline - (window.innerHeight / 2); // document.body.scrollTop = img_centerline - (window.innerHeight / 2);
desired_scroll_position = Math.round(img_centerline - (window.innerHeight / 2)); desired_scroll_position = Math.round(img_centerline - (window.innerHeight / 2));
scroll_step(); scroll_step();
} }
function scroll_to_next_img() function scroll_to_next_img()
{ {
scroll_to_img(next_img(get_center_img())); scroll_to_img(next_img(get_center_img()));
} }
function scroll_to_previous_img() function scroll_to_previous_img()
{ {
scroll_to_img(previous_img(get_center_img())); scroll_to_img(previous_img(get_center_img()));
} }
function arrowkey_listener(event) function arrowkey_listener(event)
{ {
if (event.keyCode === 37) if (event.keyCode === 37)
{ {
scroll_to_previous_img(); scroll_to_previous_img();
@ -403,37 +400,54 @@ def imagegallery_argparse(args):
{ {
scroll_to_next_img(); scroll_to_next_img();
} }
} }
let hide_cursor_timeout = null; let hide_cursor_timeout = null;
function hide_cursor() function hide_cursor()
{ {
document.documentElement.style.cursor = "none"; document.documentElement.style.cursor = "none";
} }
function show_cursor() function show_cursor()
{ {
document.documentElement.style.cursor = ""; document.documentElement.style.cursor = "";
} }
function mousemove_handler() function mousemove_handler()
{ {
show_cursor(); show_cursor();
clearTimeout(hide_cursor_timeout); clearTimeout(hide_cursor_timeout);
hide_cursor_timeout = setTimeout(hide_cursor, 3000); hide_cursor_timeout = setTimeout(hide_cursor, 3000);
} }
function on_pageload() function on_pageload()
{ {
document.documentElement.addEventListener("keydown", arrowkey_listener); document.documentElement.addEventListener("keydown", arrowkey_listener);
document.documentElement.addEventListener("mousemove", mousemove_handler); document.documentElement.addEventListener("mousemove", mousemove_handler);
mousemove_handler(); mousemove_handler();
load_scrollbar_setting(); load_scrollbar_setting();
} }
document.addEventListener("DOMContentLoaded", on_pageload); document.addEventListener("DOMContentLoaded", on_pageload);
</script> </script>
</html> </html>
''')).render( ''')
def imagegallery(files, title, urlroot, with_download_links):
html = TEMPLATE.render(
files=files,
title=title,
urlroot=urlroot,
with_download_links=with_download_links,
)
return html
def imagegallery_argparse(args):
patterns = pipeable.input_many(args.patterns)
files = list(pathclass.glob_many_files(patterns))
files.sort()
html = imagegallery(
files=files, files=files,
title=args.title, title=args.title,
urlroot=args.urlroot or '', urlroot=args.urlroot or '',
with_download_links=True,
) )
pathclass.Path('gallery.html').open('w', encoding='utf-8').write(html) pathclass.Path('gallery.html').open('w', encoding='utf-8').write(html)
return 0 return 0