init command now adds default stylesheet and asks for confirmation to overwrite config
This commit is contained in:
parent
c875adb18c
commit
245919cb73
4 changed files with 272 additions and 13 deletions
|
@ -8,7 +8,7 @@ def find_config(start: Path | None = None) -> Path | None:
|
|||
current = (start or Path.cwd()).resolve()
|
||||
|
||||
for parent in [current, *current.parents]:
|
||||
candidate = parent / "zona.yml"
|
||||
candidate = parent / "config.yml"
|
||||
if candidate.is_file():
|
||||
return candidate
|
||||
return None
|
||||
|
|
236
src/zona/data/content/static/style.css
Normal file
236
src/zona/data/content/static/style.css
Normal file
|
@ -0,0 +1,236 @@
|
|||
:root {
|
||||
--main-text-color: #b4b4b4;
|
||||
--main-bg-color: #121212;
|
||||
--main-link-color: #df6464;
|
||||
--main-heading-color: #df6464;
|
||||
--main-bullet-color: #d87c4a;
|
||||
--main-transparent: rgba(255, 255, 255, 0.15);
|
||||
--main-small-text-color: rgba(255, 255, 255, 0.45);
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1.6;
|
||||
font-size: 18px;
|
||||
font-family: sans-serif;
|
||||
background: var(--main-bg-color);
|
||||
color: var(--main-text-color);
|
||||
padding-left: calc(100vw - 100%);
|
||||
}
|
||||
|
||||
/* h1, */
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--main-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-block-start: 0.67rem;
|
||||
margin-block-end: 0.67rem;
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
article h1:first-of-type {
|
||||
margin-block-start: 1.67rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-block-start: 0.83rem;
|
||||
margin-block-end: 0.83rem;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-block-start: 1rem;
|
||||
margin-block-end: 1rem;
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-block-start: 1.33rem;
|
||||
margin-block-end: 1.33rem;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
article h1+h4:first-of-type {
|
||||
margin-block-start: 0rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-block-start: 1.67rem;
|
||||
margin-block-end: 1.67rem;
|
||||
font-size: 0.83rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin-block-start: 2.33rem;
|
||||
margin-block-end: 2.33rem;
|
||||
font-size: 0.67rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
/* or any other list style */
|
||||
}
|
||||
|
||||
li::marker {
|
||||
color: var(--main-bullet-color);
|
||||
/* Change this to your desired color */
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--main-link-color);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background: var(--main-transparent);
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
color: var(--main-small-text-color);
|
||||
border-left: 3px solid var(--main-transparent);
|
||||
padding: 0 1rem;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: var(--main-small-text-color);
|
||||
}
|
||||
|
||||
code {
|
||||
background: var(--main-transparent);
|
||||
border-radius: 0.1875rem;
|
||||
/* padding: .0625rem .1875rem; */
|
||||
/* margin: 0 .1875rem; */
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
font-family: 'Fira Code', 'Consolas', 'Courier New', monospace;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #1d1d1d;
|
||||
color: #d5d5d5;
|
||||
padding: 1em;
|
||||
border-radius: 5px;
|
||||
line-height: 1.5;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #1d1d1d;
|
||||
color: #d5d5d5;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
||||
small {
|
||||
font-size: 0.95rem;
|
||||
color: var(--main-small-text-color);
|
||||
}
|
||||
|
||||
small a {
|
||||
color: inherit;
|
||||
/* Inherit the color of the surrounding <small> text */
|
||||
text-decoration: underline;
|
||||
/* Optional: Keep the underline to indicate a link */
|
||||
}
|
||||
|
||||
.title-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title-container h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
/* Optional: add some spacing around the image container */
|
||||
}
|
||||
|
||||
.image-container img {
|
||||
/* max-width: 308px; */
|
||||
max-height: 308px;
|
||||
}
|
||||
|
||||
.image-container small {
|
||||
display: block;
|
||||
/* Ensure the caption is on a new line */
|
||||
margin-top: 5px;
|
||||
/* Optional: adjust spacing between image and caption */
|
||||
}
|
||||
|
||||
.image-container small a {
|
||||
color: inherit;
|
||||
/* Ensure the link color matches the small text */
|
||||
text-decoration: underline;
|
||||
/* Optional: underline to indicate a link */
|
||||
}
|
||||
|
||||
#header ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#header li {
|
||||
display: inline;
|
||||
font-size: 1.2rem;
|
||||
margin-right: 1.2rem;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin: 2.5rem auto;
|
||||
width: 90%;
|
||||
max-width: 60ch;
|
||||
}
|
||||
|
||||
#postlistdiv ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.moreposts {
|
||||
font-size: 0.95rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
#nextprev {
|
||||
text-align: center;
|
||||
margin-top: 1.4rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
#footer {
|
||||
color: var(--main-small-text-color);
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
from pathlib import Path
|
||||
from rich import print
|
||||
import typer
|
||||
from dataclasses import dataclass, asdict
|
||||
from zona.config import ZonaConfig, find_config
|
||||
from zona import util
|
||||
|
@ -24,7 +26,9 @@ class Layout:
|
|||
)
|
||||
if validate:
|
||||
if not layout.content.is_dir():
|
||||
raise FileNotFoundError("Missing required content directory!")
|
||||
raise FileNotFoundError(
|
||||
"Missing required content directory!"
|
||||
)
|
||||
if not layout.templates.is_dir():
|
||||
# use the included defaults
|
||||
layout.templates = util.get_resource_dir("templates")
|
||||
|
@ -53,21 +57,29 @@ def initialize_site(root: Path | None = None):
|
|||
root = root.absolute().resolve()
|
||||
config = find_config(root)
|
||||
if config is not None:
|
||||
raise FileExistsError(f"Config file already exists at {config}")
|
||||
ans = typer.confirm(
|
||||
text=(
|
||||
f"A config file already exists at {config}.\n"
|
||||
f"Delete it and restore defaults?"
|
||||
)
|
||||
)
|
||||
if ans:
|
||||
config.unlink()
|
||||
# create requires layout
|
||||
layout = Layout.from_input(root=root, validate=False)
|
||||
# load template resources
|
||||
templates = util.get_resources("templates")
|
||||
static = util.get_resources("content")
|
||||
for dir, resources in [
|
||||
(layout.root, None),
|
||||
(layout.content, None),
|
||||
(layout.content, static),
|
||||
(layout.templates, templates),
|
||||
]:
|
||||
if not dir.is_dir():
|
||||
dir.mkdir()
|
||||
if resources is not None:
|
||||
for r in resources:
|
||||
Path(r.name).write_text(r.contents)
|
||||
(root / Path(r.name)).write_text(r.contents)
|
||||
|
||||
config_path = layout.root / "config.yml"
|
||||
config = ZonaConfig()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from importlib.resources.abc import Traversable
|
||||
from typing import NamedTuple
|
||||
from rich import print
|
||||
from importlib import resources
|
||||
|
@ -15,13 +16,21 @@ class ZonaResource(NamedTuple):
|
|||
def get_resources(subdir: str) -> list[ZonaResource]:
|
||||
"""Load the packaged resources in data/subdir"""
|
||||
out: list[ZonaResource] = []
|
||||
for resource in (
|
||||
resources.files("zona").joinpath(f"data/{subdir}").iterdir()
|
||||
):
|
||||
out.append(
|
||||
ZonaResource(f"{subdir}/{resource.name}", resource.read_text())
|
||||
)
|
||||
print(out)
|
||||
base = resources.files("zona").joinpath("data", subdir)
|
||||
|
||||
def walk(trav: Traversable, prefix: str = ""):
|
||||
for item in trav.iterdir():
|
||||
path = f"{prefix}{item.name}"
|
||||
if item.is_dir():
|
||||
walk(item, prefix=f"{path}/")
|
||||
else:
|
||||
out.append(
|
||||
ZonaResource(
|
||||
name=f"{subdir}/{path}", contents=item.read_text()
|
||||
)
|
||||
)
|
||||
|
||||
walk(base)
|
||||
return out
|
||||
|
||||
|
||||
|
@ -58,4 +67,6 @@ def normalize_url(url: str) -> str:
|
|||
|
||||
def should_ignore(path: Path, patterns: list[str], base: Path) -> bool:
|
||||
rel_path = path.relative_to(base)
|
||||
return any(fnmatch.fnmatch(str(rel_path), pattern) for pattern in patterns)
|
||||
return any(
|
||||
fnmatch.fnmatch(str(rel_path), pattern) for pattern in patterns
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue