Fix image .margin positioning where caption and image got that layout instead of the figure wrapper getting it.
This commit is contained in:
@@ -847,7 +847,7 @@ article.multicol {
|
|||||||
|
|
||||||
article.multicol .margin,
|
article.multicol .margin,
|
||||||
article.multicol .aside,
|
article.multicol .aside,
|
||||||
article.multicol figure:has(.margin) {
|
article.multicol figure.margin {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 14rem;
|
width: 14rem;
|
||||||
@@ -898,7 +898,7 @@ article.multicol {
|
|||||||
|
|
||||||
body:has(#sidebar):has(.multicol):not(.editing) article.multicol .margin,
|
body:has(#sidebar):has(.multicol):not(.editing) article.multicol .margin,
|
||||||
body:has(#sidebar):has(.multicol):not(.editing) article.multicol .aside,
|
body:has(#sidebar):has(.multicol):not(.editing) article.multicol .aside,
|
||||||
body:has(#sidebar):has(.multicol):not(.editing) article.multicol figure:has(.margin) {
|
body:has(#sidebar):has(.multicol):not(.editing) article.multicol figure.margin {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
/* Attached to the article's left border (1.25rem gap), hanging into
|
/* Attached to the article's left border (1.25rem gap), hanging into
|
||||||
the left lane and growing leftward with it: 12rem when the lane is
|
the left lane and growing leftward with it: 12rem when the lane is
|
||||||
@@ -916,7 +916,7 @@ article.multicol {
|
|||||||
/* A shrink-wrapped figure (explicit image width) centers in the plain
|
/* A shrink-wrapped figure (explicit image width) centers in the plain
|
||||||
layout; inside a column the centering looks adrift — left-align.
|
layout; inside a column the centering looks adrift — left-align.
|
||||||
Floated figures keep their own margins (the text gap). */
|
Floated figures keep their own margins (the text gap). */
|
||||||
.multicol .colseg.cols figure:has(img[width]):not(:has(.left), :has(.right), :has(.margin)) {
|
.multicol .colseg.cols figure:has(img[width]):not(:has(.left), :has(.right), .margin) {
|
||||||
margin-inline: 0;
|
margin-inline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1094,7 +1094,8 @@ blockquote p + p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Side boxes: ::: aside is a muted floated box; {.margin} / ::: margin
|
/* Side boxes: ::: aside is a muted floated box; {.margin} / ::: margin
|
||||||
is a plainer margin note, and figures take {.margin} like {.left}.
|
is a plainer margin note, and figures take the class directly on the
|
||||||
|
<figure> (the renderer moves it off the img), floating like {.left}.
|
||||||
Where the layout has room for a side zone — multicol pages, the
|
Where the layout has room for a side zone — multicol pages, the
|
||||||
sidebar's track, the wide single-column gutter (see the article
|
sidebar's track, the wide single-column gutter (see the article
|
||||||
section and the figure rules below) — the boxes are taken out of flow
|
section and the figure rules below) — the boxes are taken out of flow
|
||||||
@@ -1287,7 +1288,8 @@ dd {
|
|||||||
Markdown images standing alone in a paragraph render as a block
|
Markdown images standing alone in a paragraph render as a block
|
||||||
<figure> (with <figcaption> when the image has a title); the
|
<figure> (with <figcaption> when the image has a title); the
|
||||||
brace-attribute positioning class ({.left}, {.right}, {.wide}) lives
|
brace-attribute positioning class ({.left}, {.right}, {.wide}) lives
|
||||||
on the img inside, but only the figure is ever positioned, so the
|
on the img inside — except {.margin}, which the renderer moves onto
|
||||||
|
the figure itself — but only the figure is ever positioned, so the
|
||||||
caption stays below the image. Raw <img> HTML written by the author
|
caption stays below the image. Raw <img> HTML written by the author
|
||||||
stays inline and unstyled beyond these defaults. */
|
stays inline and unstyled beyond these defaults. */
|
||||||
img {
|
img {
|
||||||
@@ -1353,9 +1355,10 @@ figure:has(img[width]) {
|
|||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* {.margin} figures float left like {.left} ones — until they fall into
|
/* {.margin} figures (the class moves onto the figure wrapper at render —
|
||||||
|
see markdown.py) float left like {.left} ones — until they fall into
|
||||||
the side zone (see the composition rules up in the article section). */
|
the side zone (see the composition rules up in the article section). */
|
||||||
figure:has(.margin) {
|
figure.margin {
|
||||||
float: left;
|
float: left;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
@@ -1445,7 +1448,7 @@ article figure img {
|
|||||||
@media (min-width: 104rem) {
|
@media (min-width: 104rem) {
|
||||||
body:not(.editing):not(:has(.multicol)) article .margin,
|
body:not(.editing):not(:has(.multicol)) article .margin,
|
||||||
body:not(.editing):not(:has(.multicol)) article .aside,
|
body:not(.editing):not(:has(.multicol)) article .aside,
|
||||||
body:not(.editing):not(:has(.multicol)) article figure:has(.margin) {
|
body:not(.editing):not(:has(.multicol)) article figure.margin {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
--box-w: min(18rem, (100vw - 78rem) / 2 - 1.25rem);
|
--box-w: min(18rem, (100vw - 78rem) / 2 - 1.25rem);
|
||||||
width: var(--box-w);
|
width: var(--box-w);
|
||||||
@@ -1668,7 +1671,7 @@ article h2 {
|
|||||||
|
|
||||||
figure:has(.right),
|
figure:has(.right),
|
||||||
figure:has(.left),
|
figure:has(.left),
|
||||||
figure:has(.margin) {
|
figure.margin {
|
||||||
float: none;
|
float: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
|
|||||||
+3
-2
@@ -30,6 +30,7 @@ walking the tree (``resolve``), moves are slot detach/attach
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
from collections.abc import AsyncIterator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
@@ -39,12 +40,12 @@ from pagerite import api, files, pages, tracking, translate
|
|||||||
from pagerite.__main__ import DEVMODE
|
from pagerite.__main__ import DEVMODE
|
||||||
from pagerite.files import file_store
|
from pagerite.files import file_store
|
||||||
from pagerite.state import HOSTNAME, analytics_store, data, frontend, kanta
|
from pagerite.state import HOSTNAME, analytics_store, data, frontend, kanta
|
||||||
|
from collections.abc import AsyncGenerator
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(_app: FastAPI):
|
async def lifespan(_app: FastAPI) -> AsyncGenerator:
|
||||||
"""Open the database (migrations run inside kanta.open), load assets, load GeoIP."""
|
"""Open the database (migrations run inside kanta.open), load assets, load GeoIP."""
|
||||||
async with kanta:
|
async with kanta:
|
||||||
translate.log_service_urls(data.translate_keys, HOSTNAME)
|
translate.log_service_urls(data.translate_keys, HOSTNAME)
|
||||||
|
|||||||
+16
-3
@@ -156,14 +156,27 @@ def _image_rule(
|
|||||||
page = env.get("page_path", "")
|
page = env.get("page_path", "")
|
||||||
token.attrs["src"] = f"/{page}/{src}" if page else f"/{src}"
|
token.attrs["src"] = f"/{page}/{src}" if page else f"/{src}"
|
||||||
token.attrs["alt"] = self.renderInlineAsText(token.children, options, env)
|
token.attrs["alt"] = self.renderInlineAsText(token.children, options, env)
|
||||||
img = self.renderToken(tokens, idx, options, env)
|
|
||||||
if len(tokens) == 1:
|
if len(tokens) == 1:
|
||||||
# The only inline content of its paragraph: render as a block
|
# The only inline content of its paragraph: render as a block
|
||||||
# figure, captioned when titled. (The <p> wrapper is dropped by
|
# figure, captioned when titled. (The <p> wrapper is dropped by
|
||||||
# _unwrap_lone_figures below.)
|
# _unwrap_lone_figures below.) {.margin} positions the whole
|
||||||
|
# figure, so it moves from the img onto the figure wrapper — left
|
||||||
|
# on the img, the margin-breakout CSS would pull the image out of
|
||||||
|
# the figure (and mostly off-screen), leaving the caption behind.
|
||||||
|
classes = (token.attrs.get("class") or "").split()
|
||||||
|
figure_class = ""
|
||||||
|
if "margin" in classes:
|
||||||
|
classes.remove("margin")
|
||||||
|
if classes:
|
||||||
|
token.attrs["class"] = " ".join(classes)
|
||||||
|
else:
|
||||||
|
del token.attrs["class"]
|
||||||
|
figure_class = ' class="margin"'
|
||||||
|
img = self.renderToken(tokens, idx, options, env)
|
||||||
title = token.attrs.get("title")
|
title = token.attrs.get("title")
|
||||||
caption = f"<figcaption>{escapeHtml(title)}</figcaption>" if title else ""
|
caption = f"<figcaption>{escapeHtml(title)}</figcaption>" if title else ""
|
||||||
return f"<figure>{img}{caption}</figure>"
|
return f"<figure{figure_class}>{img}{caption}</figure>"
|
||||||
|
img = self.renderToken(tokens, idx, options, env)
|
||||||
# Inline with other content: a plain inline image.
|
# Inline with other content: a plain inline image.
|
||||||
return img
|
return img
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user