a lot of stylin and a little scriptin
This commit is contained in:
parent
3635f04e8f
commit
64e00f83f1
16 changed files with 555 additions and 82 deletions
30
Makefile
30
Makefile
|
@ -5,30 +5,44 @@ INFONAME = info.yaml
|
||||||
|
|
||||||
# SMALL = thumbnails, MED = single pages (link to full size)
|
# SMALL = thumbnails, MED = single pages (link to full size)
|
||||||
SMALL := 200
|
SMALL := 200
|
||||||
MED := 1200
|
MED := 1000
|
||||||
|
|
||||||
MAKEPAGES = $(TMPDIR)/make-pages
|
MAKEPAGES = $(TMPDIR)/make-pages
|
||||||
|
|
||||||
YAMLS != find $(DATADIR) -iname "*.yaml"
|
YAMLS != find $(DATADIR) -name $(INFONAME)
|
||||||
|
|
||||||
all: make-pages $(BUILDDIR)/index.html
|
SCRIPTS := $(wildcard script/*.js)
|
||||||
|
STYLES := $(wildcard style/*.css style/*.png)
|
||||||
|
FONTS := $(shell find fonts \
|
||||||
|
-iname '*.eot' -or -iname '*.svg' -or \
|
||||||
|
-iname '*.ttf' -or -iname '*.woff' -or \
|
||||||
|
-iname '*.woff2' -or -iname '*.css')
|
||||||
|
STATIC := $(SCRIPTS) $(STYLES) $(FONTS)
|
||||||
|
BSTATIC := $(patsubst %,$(BUILDDIR)/%,$(STATIC))
|
||||||
|
|
||||||
|
all: make-pages $(BUILDDIR)/index.html $(BSTATIC)
|
||||||
|
|
||||||
|
$(BUILDDIR)/%: %
|
||||||
|
echo "[copy] "$@
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
cp $< $@
|
||||||
|
|
||||||
$(BUILDDIR)/index.html: $(DATADIR)/galleries.yaml $(MAKEPAGES)
|
$(BUILDDIR)/index.html: $(DATADIR)/galleries.yaml $(MAKEPAGES)
|
||||||
echo "[index]"
|
echo "[index]"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(MAKEPAGES) index $< -o $@
|
$(MAKEPAGES) $(MPFLAGS) index $< -o $@
|
||||||
|
|
||||||
$(MAKEPAGES): make-pages
|
$(MAKEPAGES): make-pages/*.hs make-pages/make-pages.cabal
|
||||||
echo "[make-pages]"
|
echo "[make-pages]"
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
cabal v2-build all -O0
|
cabal v2-build all -O0 -j
|
||||||
find dist-newstyle -name make-pages -executable -type f \
|
find dist-newstyle -name make-pages -executable -type f \
|
||||||
-exec cp {} $@ \;
|
-exec cp {} $@ \;
|
||||||
|
|
||||||
$(TMPDIR)/galleries.d: $(DATADIR)/galleries.yaml $(MAKEPAGES)
|
$(TMPDIR)/galleries.d: $(DATADIR)/galleries.yaml $(MAKEPAGES)
|
||||||
echo "[gallery-deps] "$@
|
echo "[deps] "$@
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(MAKEPAGES) depend-gallery $< -o $@ \
|
$(MAKEPAGES) $(MPFLAGS) depend-gallery $< -o $@ \
|
||||||
-B $(BUILDDIR) -D $(DATADIR) -T $(TMPDIR) -I $(INFONAME)
|
-B $(BUILDDIR) -D $(DATADIR) -T $(TMPDIR) -I $(INFONAME)
|
||||||
|
|
||||||
-include $(TMPDIR)/galleries.d
|
-include $(TMPDIR)/galleries.d
|
||||||
|
|
|
@ -64,7 +64,8 @@ dependGallery' (GalleryInfo {title, prefix, filters}) infos' build data_ tmp =
|
||||||
$@path: $@files'
|
$@path: $@files'
|
||||||
echo "[gallery] "$$@
|
echo "[gallery] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
$$(MAKEPAGES) gallery -t "$*title" -o "$$@" $$<
|
$$(MAKEPAGES) $$(MPFLAGS) gallery -t "$*title" -o "$$@" \
|
||||||
|
$$(filter $$(DATADIR)/%/$$(INFONAME),$$^)
|
||||||
|
|
||||||
$rules
|
$rules
|
||||||
|
|
||||||
|
@ -79,29 +80,29 @@ makeRules :: FilePath -- ^ prefix
|
||||||
-> Builder
|
-> Builder
|
||||||
makeRules prefix filters build data_ tmp = [b|@0
|
makeRules prefix filters build data_ tmp = [b|@0
|
||||||
$@buildPrefix/%/index.html: $@data_/%/info.yaml
|
$@buildPrefix/%/index.html: $@data_/%/info.yaml
|
||||||
echo "[single] "$$@
|
echo "[single] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
$$(MAKEPAGES) single "$$<" -o "$$@" $flags
|
$$(MAKEPAGES) $$(MPFLAGS) single "$$<" -o "$$@" $flags
|
||||||
|
|
||||||
$@tmpPrefix/%.d: $@data_/%/info.yaml
|
$@tmpPrefix/%.d: $@data_/%/info.yaml
|
||||||
echo "[deps] "$$@
|
echo "[deps] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
$$(MAKEPAGES) depend-single $flags \
|
$$(MAKEPAGES) $$(MPFLAGS) depend-single $flags \
|
||||||
-o "$$@" -p "$@prefix" -B "$@build" -D "$@data_" $$<
|
-o "$$@" -p "$@prefix" -B "$@build" -D "$@data_" $$<
|
||||||
|
|
||||||
$@buildPrefix/%: $@data_/%
|
$@buildPrefix/%: $@data_/%
|
||||||
echo "[copy] "$$@
|
echo "[copy] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
cp "$$<" "$$@"
|
cp "$$<" "$$@"
|
||||||
|
|
||||||
$@buildPrefix/%_small.png: $@data_/%.png
|
$@buildPrefix/%_small.png: $@data_/%.png
|
||||||
echo "[resize] "$$@
|
echo "[resize] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
convert -resize '$$(SMALL)x$$(SMALL)^' \
|
convert -resize '$$(SMALL)x$$(SMALL)^' \
|
||||||
-gravity center -crop 1:1+0 "$$<" "$$@"
|
-gravity center -crop 1:1+0 "$$<" "$$@"
|
||||||
|
|
||||||
$@buildPrefix/%_med.png: $@data_/%.png
|
$@buildPrefix/%_med.png: $@data_/%.png
|
||||||
echo "[resize] "$$@
|
echo "[resize] "$$@
|
||||||
mkdir -p $$(dir $$@)
|
mkdir -p $$(dir $$@)
|
||||||
convert -resize '$$(MED)x$$(MED)>' "$$<" "$$@"
|
convert -resize '$$(MED)x$$(MED)>' "$$<" "$$@"
|
||||||
|]
|
|]
|
||||||
|
|
|
@ -21,6 +21,7 @@ make' title infos = [b|@0
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang=en>
|
<html lang=en>
|
||||||
<meta charset=utf-8>
|
<meta charset=utf-8>
|
||||||
|
<link rel=stylesheet href=/style/gallery.css>
|
||||||
|
|
||||||
<title>$*title</title>
|
<title>$*title</title>
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ make' ginfos = [b|@0
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang=en>
|
<html lang=en>
|
||||||
<meta charset=utf-8>
|
<meta charset=utf-8>
|
||||||
|
<link rel=stylesheet href=/style/index.css>
|
||||||
|
|
||||||
<title>gallery list</title>
|
<title>gallery list</title>
|
||||||
|
|
||||||
|
@ -31,9 +32,11 @@ make' ginfos = [b|@0
|
||||||
items = map makeItem ginfos
|
items = map makeItem ginfos
|
||||||
|
|
||||||
makeItem :: GalleryInfo -> Builder
|
makeItem :: GalleryInfo -> Builder
|
||||||
makeItem (GalleryInfo {title, prefix}) = [b|@4
|
makeItem (GalleryInfo {title, prefix, filters}) = [b|@4
|
||||||
<li>
|
<li$nsfw><a href=$@prefix>$*title</a>
|
||||||
<a href="$@prefix">
|
|
||||||
$*title
|
|
||||||
</a>
|
|
||||||
|]
|
|]
|
||||||
|
where
|
||||||
|
nsfw = if hasNsfw filters then " class=nsfw" else ""
|
||||||
|
|
||||||
|
hasNsfw :: GalleryFilters -> Bool
|
||||||
|
hasNsfw (GalleryFilters {nsfw}) = nsfw /= Just False
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{-# OPTIONS_GHC -fdefer-typed-holes #-}
|
||||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||||
module Info
|
module Info
|
||||||
(Info (..), Artist (..), Image (..), Link (..),
|
(Info (..), Artist (..), Image (..), Link (..),
|
||||||
|
@ -27,11 +28,11 @@ data Info =
|
||||||
date :: !Day,
|
date :: !Day,
|
||||||
title :: !(Maybe Text),
|
title :: !(Maybe Text),
|
||||||
artist :: !(Maybe Artist), -- nothing = me, obv
|
artist :: !(Maybe Artist), -- nothing = me, obv
|
||||||
warning :: !(Maybe Text),
|
|
||||||
tags :: ![Text],
|
tags :: ![Text],
|
||||||
nsfwTags :: ![Text],
|
nsfwTags :: ![Text],
|
||||||
description :: !(Maybe Text),
|
description :: !(Maybe Text),
|
||||||
images :: ![Image],
|
images :: ![Image],
|
||||||
|
background :: !(Maybe Text),
|
||||||
thumb' :: !(Maybe FilePath),
|
thumb' :: !(Maybe FilePath),
|
||||||
links :: ![Link]
|
links :: ![Link]
|
||||||
}
|
}
|
||||||
|
@ -46,9 +47,10 @@ data Artist =
|
||||||
|
|
||||||
data Image =
|
data Image =
|
||||||
Image {
|
Image {
|
||||||
label :: !Text,
|
label :: !Text,
|
||||||
path :: !FilePath,
|
path :: !FilePath,
|
||||||
nsfw :: !Bool
|
nsfw :: !Bool,
|
||||||
|
warning :: !(Maybe Text)
|
||||||
}
|
}
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
@ -80,11 +82,11 @@ instance FromYAML Info where
|
||||||
Info <$> m .: "date"
|
Info <$> m .: "date"
|
||||||
<*> m .:? "title"
|
<*> m .:? "title"
|
||||||
<*> m .:? "artist"
|
<*> m .:? "artist"
|
||||||
<*> m .:? "warning"
|
|
||||||
<*> m .:? "tags" .!= []
|
<*> m .:? "tags" .!= []
|
||||||
<*> m .:? "nsfw-tags" .!= []
|
<*> m .:? "nsfw-tags" .!= []
|
||||||
<*> m .:? "description"
|
<*> m .:? "description"
|
||||||
<*> m .: "images"
|
<*> m .: "images"
|
||||||
|
<*> m .:? "background"
|
||||||
<*> m .:? "thumb"
|
<*> m .:? "thumb"
|
||||||
<*> m .:? "links" .!= []
|
<*> m .:? "links" .!= []
|
||||||
|
|
||||||
|
@ -95,10 +97,29 @@ instance FromYAML Artist where
|
||||||
Artist <$> m .: "name" <*> m .:? "url"
|
Artist <$> m .: "name" <*> m .:? "url"
|
||||||
|
|
||||||
instance FromYAML Image where
|
instance FromYAML Image where
|
||||||
parseYAML = labelledOptNsfw Image "path" "path"
|
parseYAML y = do
|
||||||
|
Pair label rest <- parseYAML y
|
||||||
|
asStr label rest <|> asObj label rest
|
||||||
|
where
|
||||||
|
asStr label = YAML.withStr "path" \(Text.unpack -> path) ->
|
||||||
|
pure $ Image {label, path, nsfw = False, warning = Nothing}
|
||||||
|
asObj label = YAML.withMap "image info" \m -> do
|
||||||
|
path <- m .: "path"
|
||||||
|
nsfw <- m .:? "nsfw" .!= False
|
||||||
|
warning <- m .:? "warning"
|
||||||
|
pure $ Image {label, path, nsfw, warning}
|
||||||
|
|
||||||
instance FromYAML Link where
|
instance FromYAML Link where
|
||||||
parseYAML = labelledOptNsfw Link "url" "url"
|
parseYAML y = do
|
||||||
|
Pair title rest <- parseYAML y
|
||||||
|
asStr title rest <|> asObj title rest
|
||||||
|
where
|
||||||
|
asStr title = YAML.withStr "url" \url ->
|
||||||
|
pure $ Link {title, url, nsfw = False}
|
||||||
|
asObj title = YAML.withMap "link info" \m -> do
|
||||||
|
url <- m .: "url"
|
||||||
|
nsfw <- m .:? "nsfw" .!= False
|
||||||
|
pure $ Link {title, url, nsfw}
|
||||||
|
|
||||||
|
|
||||||
data GalleryInfo =
|
data GalleryInfo =
|
||||||
|
@ -166,33 +187,6 @@ instance (FromYAML a, FromYAML b) => FromYAML (Pair a b) where
|
||||||
_ -> fail "expected exactly one pair"
|
_ -> fail "expected exactly one pair"
|
||||||
|
|
||||||
|
|
||||||
data OptNsfw a = NoNsfw !a | WithNsfw !a !Bool
|
|
||||||
|
|
||||||
appOptNsfw :: (a -> Bool -> b) -> OptNsfw a -> b
|
|
||||||
appOptNsfw f (NoNsfw x) = f x False
|
|
||||||
appOptNsfw f (WithNsfw x n) = f x n
|
|
||||||
|
|
||||||
labelledOptNsfw :: FromYAML a
|
|
||||||
=> (Text -> a -> Bool -> b)
|
|
||||||
-> String -- ^ name in \"expected\" message
|
|
||||||
-> Text -- ^ field name
|
|
||||||
-> YAML.Node YAML.Pos -> YAML.Parser b
|
|
||||||
labelledOptNsfw f name field y = do
|
|
||||||
Pair l n' <- parseYAML y
|
|
||||||
n <- parseOptNsfw name field n'
|
|
||||||
pure $ appOptNsfw (f l) n
|
|
||||||
|
|
||||||
parseOptNsfw :: FromYAML a
|
|
||||||
=> String -- ^ name in \"expected\" message
|
|
||||||
-> Text -- ^ field name
|
|
||||||
-> YAML.Node YAML.Pos -> YAML.Parser (OptNsfw a)
|
|
||||||
parseOptNsfw name field y = yes y <|> no y where
|
|
||||||
yes = YAML.withMap (name <> " & nsfw") \m ->
|
|
||||||
WithNsfw <$> m .: field
|
|
||||||
<*> m .:? "nsfw" .!= False
|
|
||||||
no = fmap NoNsfw . parseYAML
|
|
||||||
|
|
||||||
|
|
||||||
instance FromYAML Day where
|
instance FromYAML Day where
|
||||||
parseYAML = YAML.withStr "date" \str ->
|
parseYAML = YAML.withStr "date" \str ->
|
||||||
case readMaybe $ Text.unpack str of
|
case readMaybe $ Text.unpack str of
|
||||||
|
|
|
@ -30,29 +30,38 @@ make nsfw = toLazyText . make' nsfw
|
||||||
|
|
||||||
make' :: Bool -> Info -> Builder
|
make' :: Bool -> Info -> Builder
|
||||||
make' nsfw (Info {date, title, artist, tags, nsfwTags,
|
make' nsfw (Info {date, title, artist, tags, nsfwTags,
|
||||||
description, images, links}) = [b|@0
|
description, images, background, links}) = [b|@0
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang=en>
|
<html lang=en>
|
||||||
<meta charset=utf-8>
|
<meta charset=utf-8>
|
||||||
|
<link rel=stylesheet href=/style/single.css>
|
||||||
|
|
||||||
$titleTag
|
$titleTag
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
$titleHeader
|
$titleHeader
|
||||||
$artistTag
|
$artistTag
|
||||||
<h2 class=date>$formattedDate</date>
|
<h2 class=date>$formattedDate</h2>
|
||||||
$buttonBar
|
$buttonBar
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<script async src=/script/single.js></script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<a href="$@path0">
|
<figure id=mainfig$dataBg>
|
||||||
<img id=it src="$@path0'">
|
$warning'
|
||||||
</a>
|
<a id=mainlink href="$@path0">
|
||||||
|
<img id=mainimg src="$@path0'">
|
||||||
|
</a>
|
||||||
|
</figure>
|
||||||
|
|
||||||
$descSection
|
<section class=info>
|
||||||
|
$descSection
|
||||||
|
|
||||||
$tagsList
|
$tagsList
|
||||||
|
|
||||||
$linksList
|
$linksList
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -70,13 +79,21 @@ make' nsfw (Info {date, title, artist, tags, nsfwTags,
|
||||||
formattedDate = formatDate date
|
formattedDate = formatDate date
|
||||||
|
|
||||||
buttonBar = makeButtonBar (fromMaybe (Strict.pack path0) title) nsfw images
|
buttonBar = makeButtonBar (fromMaybe (Strict.pack path0) title) nsfw images
|
||||||
path0 = #path $ head images
|
image0 = head images
|
||||||
|
path0 = #path image0
|
||||||
path0' = pageFile path0
|
path0' = pageFile path0
|
||||||
|
|
||||||
descSection = ifJust description makeDesc
|
descSection = ifJust description makeDesc
|
||||||
tagsList = makeTags nsfw tags nsfwTags
|
tagsList = makeTags nsfw tags nsfwTags
|
||||||
linksList = extLinks nsfw links
|
linksList = extLinks nsfw links
|
||||||
|
|
||||||
|
dataBg = ifJust background \bg -> [b| data-bg="$*bg"|]
|
||||||
|
warning' = ifJust (#warning image0) \w -> [b|@4
|
||||||
|
<figcaption id=cw>
|
||||||
|
$*w
|
||||||
|
</figcaption>
|
||||||
|
|]
|
||||||
|
|
||||||
makeArtist :: Artist -> Builder
|
makeArtist :: Artist -> Builder
|
||||||
makeArtist (Artist {name, url}) =
|
makeArtist (Artist {name, url}) =
|
||||||
[b|<h2 class=artist>by $artistLink</h2>|]
|
[b|<h2 class=artist>by $artistLink</h2>|]
|
||||||
|
@ -86,11 +103,13 @@ makeArtist (Artist {name, url}) =
|
||||||
Nothing -> [b|$*name|]
|
Nothing -> [b|$*name|]
|
||||||
|
|
||||||
makeDesc :: Strict.Text -> Builder
|
makeDesc :: Strict.Text -> Builder
|
||||||
makeDesc desc = [b|@2
|
makeDesc desc = [b|@4
|
||||||
<div class=desc>
|
<section class=desc>
|
||||||
<h2>description</h2>
|
<h2>about</h2>
|
||||||
$4*desc
|
<div>
|
||||||
</div>
|
$8*desc
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|]
|
|]
|
||||||
|
|
||||||
ifJust :: Monoid b => Maybe a -> (a -> b) -> b
|
ifJust :: Monoid b => Maybe a -> (a -> b) -> b
|
||||||
|
@ -106,9 +125,8 @@ makeButtonBar title nsfw allImages =
|
||||||
0 -> throw $ NoEligibleImages title
|
0 -> throw $ NoEligibleImages title
|
||||||
1 -> ""
|
1 -> ""
|
||||||
_ -> [b|@2
|
_ -> [b|@2
|
||||||
<nav id=variants class=buttonbar>
|
<nav class=alts>
|
||||||
<h2>alts</h2>
|
<ul id=altlist>
|
||||||
<ul id=variantlist>
|
|
||||||
$6.alts
|
$6.alts
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -119,10 +137,11 @@ makeButtonBar title nsfw allImages =
|
||||||
alts = map (uncurry altButton) $ zip [0..] images
|
alts = map (uncurry altButton) $ zip [0..] images
|
||||||
|
|
||||||
altButton :: Int -> Image -> Builder
|
altButton :: Int -> Image -> Builder
|
||||||
altButton i (Image {label, path, nsfw}) = [b|@6
|
altButton i (Image {label, path, nsfw, warning}) = [b|@6
|
||||||
<li$nsfwClass>
|
<li$nsfwClass>
|
||||||
<input type=radio$checked id="$idLabel" name=variant
|
<input type=radio$checked id="$idLabel" name=variant
|
||||||
autocomplete=off value="$@path'">
|
autocomplete=off value="$@path'"
|
||||||
|
data-link="$@path"$warning'>
|
||||||
<label for="$idLabel">$*label</label>
|
<label for="$idLabel">$*label</label>
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
|
@ -130,6 +149,7 @@ altButton i (Image {label, path, nsfw}) = [b|@6
|
||||||
checked = if i == 0 then " checked" else ""
|
checked = if i == 0 then " checked" else ""
|
||||||
idLabel = escId label
|
idLabel = escId label
|
||||||
path' = pageFile path
|
path' = pageFile path
|
||||||
|
warning' = ifJust warning \w -> [b| data-warning="$*w"|]
|
||||||
|
|
||||||
escId :: Strict.Text -> Builder
|
escId :: Strict.Text -> Builder
|
||||||
escId = foldMap esc1 . Strict.unpack where
|
escId = foldMap esc1 . Strict.unpack where
|
||||||
|
@ -140,13 +160,13 @@ escId = foldMap esc1 . Strict.unpack where
|
||||||
|
|
||||||
makeTags :: Bool -> [Strict.Text] -> [Strict.Text] -> Builder
|
makeTags :: Bool -> [Strict.Text] -> [Strict.Text] -> Builder
|
||||||
makeTags nsfw sfwTags nsfwTags =
|
makeTags nsfw sfwTags nsfwTags =
|
||||||
if null tags then "" else [b|@2
|
if null tags then "" else [b|@4
|
||||||
<div class=tags>
|
<section class=tags>
|
||||||
<h2>tags</h2>
|
<h2>tags</h2>
|
||||||
<ul>
|
<ul>
|
||||||
$6.tagList
|
$8.tagList
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</section>
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
tagList = map makeTag tags
|
tagList = map makeTag tags
|
||||||
|
@ -155,13 +175,13 @@ makeTags nsfw sfwTags nsfwTags =
|
||||||
|
|
||||||
extLinks :: Bool -> [Link] -> Builder
|
extLinks :: Bool -> [Link] -> Builder
|
||||||
extLinks nsfw allLinks =
|
extLinks nsfw allLinks =
|
||||||
if null links then "" else [b|@2
|
if null links then "" else [b|@4
|
||||||
<div class=links>
|
<section class=links>
|
||||||
<h2>links</h2>
|
<h2>links</h2>
|
||||||
<ul>
|
<ul>
|
||||||
$6.linkList
|
$8.linkList
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</section>
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
links = if nsfw then allLinks else filter #sfw allLinks
|
links = if nsfw then allLinks else filter #sfw allLinks
|
||||||
|
|
55
script/single.js
Normal file
55
script/single.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
function defined(x) {
|
||||||
|
return x !== null && typeof x !== 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getById(id) { return document.getElementById(id); }
|
||||||
|
|
||||||
|
function setImage(src, href, cw) {
|
||||||
|
let mainfig = getById('mainfig');
|
||||||
|
let mainimg = getById('mainimg');
|
||||||
|
let mainlink = getById('mainlink');
|
||||||
|
let caption = getById('cw');
|
||||||
|
|
||||||
|
if (defined(caption) && defined(cw)) {
|
||||||
|
caption.innerHTML = cw;
|
||||||
|
} else if (defined(caption)) {
|
||||||
|
mainfig.removeChild(caption);
|
||||||
|
} else if (defined(cw)) {
|
||||||
|
let newCaption = document.createElement('figcaption');
|
||||||
|
newCaption.id = 'cw';
|
||||||
|
newCaption.innerHTML = cw;
|
||||||
|
newCaption.onclick = openCW;
|
||||||
|
mainfig.insertBefore(newCaption, mainlink);
|
||||||
|
}
|
||||||
|
|
||||||
|
mainimg.src = src;
|
||||||
|
mainlink.href= href;
|
||||||
|
}
|
||||||
|
|
||||||
|
function activateButton(button) {
|
||||||
|
setImage(button.value, button.dataset.link, button.dataset.warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCW() {
|
||||||
|
let mainfig = getById('mainfig');
|
||||||
|
let caption = getById('cw');
|
||||||
|
if (defined(caption)) {
|
||||||
|
mainfig.removeChild(caption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
for (let button of document.querySelectorAll('#altlist input')) {
|
||||||
|
button.onchange = function(e) {
|
||||||
|
if (button.checked) activateButton(button);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let caption = getById('cw');
|
||||||
|
if (defined(caption)) {
|
||||||
|
caption.onclick = openCW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = setup;
|
BIN
style/18_plus.png
(Stored with Git LFS)
Normal file
BIN
style/18_plus.png
(Stored with Git LFS)
Normal file
Binary file not shown.
1
style/18_plus.svg
Normal file
1
style/18_plus.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.41421" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path clip-rule="evenodd" d="m0 0h32v32h-32z"/></clipPath><metadata/><path d="m0 0h32v32h-32z" fill="none"/><g clip-path="url(#a)"><circle cx="16" cy="16" r="16"/><circle cx="16" cy="16" fill="#e02a33" r="14"/><circle cx="16" cy="16" r="12"/><g fill="#fff" fill-rule="nonzero"><path d="m8.523 12.595-1.975 1.43v-2.418l1.975-1.481h2.23v11.748h-2.23z"/><path d="m16.321 22.061c-.693 0-1.311-.139-1.856-.417s-.974-.678-1.286-1.2-.468-1.124-.468-1.805v-.392c0-.533.125-1.024.375-1.472.249-.449.601-.803 1.055-1.064-.363-.216-.655-.52-.877-.911-.221-.392-.332-.843-.332-1.354v-.306c0-.579.139-1.113.418-1.601.278-.488.672-.877 1.183-1.166.511-.29 1.112-.434 1.805-.434.692 0 1.297.144 1.813.434.516.289.911.678 1.183 1.166.273.488.409 1.022.409 1.601v.306c0 .499-.114.948-.341 1.345s-.516.704-.868.92c.454.272.803.632 1.047 1.081.244.448.366.928.366 1.438v.392c0 .692-.156 1.3-.468 1.822s-.743.922-1.294 1.2c-.55.278-1.172.417-1.864.417zm.017-7.236c.386 0 .692-.128.919-.383s.341-.582.341-.979v-.323c0-.375-.117-.687-.349-.937-.233-.25-.537-.374-.911-.374-.375 0-.679.124-.911.374-.233.25-.349.562-.349.937v.323c0 .409.113.738.34.988.227.249.534.374.92.374zm0 5.346c.442 0 .797-.141 1.064-.425s.4-.664.4-1.141v-.409c0-.454-.133-.823-.4-1.106-.267-.284-.622-.426-1.064-.426-.432 0-.784.142-1.056.426-.272.283-.409.652-.409 1.106v.409c0 .465.131.843.392 1.132.261.29.619.434 1.073.434z"/><path d="m22.834 16.943h-2.073v-1.886h2.073v-2.073h1.886v2.073h2.073v1.886h-2.073v2.073h-1.886z"/></g></g></svg>
|
After Width: | Height: | Size: 1.7 KiB |
BIN
style/18_plus_small.png
(Stored with Git LFS)
Normal file
BIN
style/18_plus_small.png
(Stored with Git LFS)
Normal file
Binary file not shown.
109
style/base.css
Normal file
109
style/base.css
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
@import url(../fonts/muller/muller.css);
|
||||||
|
|
||||||
|
html {
|
||||||
|
--thumb-size: 200px;
|
||||||
|
--page-size: 1000px;
|
||||||
|
|
||||||
|
--back-dark: hsl(129, 54%, 54%);
|
||||||
|
--back-light: hsl(119, 69%, 69%);
|
||||||
|
--dark-tum: hsl(41, 41%, 79%);
|
||||||
|
--light-tum: hsl(47, 59%, 85%);
|
||||||
|
--lighter-tum: hsl(47, 74%, 89%);
|
||||||
|
--text-hue: 42;
|
||||||
|
--text: hsl(var(--text-hue), 25%, 24%);
|
||||||
|
--text-link: hsl(111, 30%, 42%);
|
||||||
|
--shadow: hsla(42, 25%, 24%, 40%);
|
||||||
|
--bheight: 121px;
|
||||||
|
--bplacement: 60vh;
|
||||||
|
|
||||||
|
background:
|
||||||
|
url(border.png) left 0% bottom calc(var(--bplacement) - var(--bheight))
|
||||||
|
repeat-x fixed,
|
||||||
|
linear-gradient(to top,
|
||||||
|
transparent var(--bplacement),
|
||||||
|
var(--back-light) var(--bplacement),
|
||||||
|
var(--back-dark))
|
||||||
|
fixed,
|
||||||
|
url(spots.png) repeat fixed,
|
||||||
|
linear-gradient(to top,
|
||||||
|
var(--dark-tum) 0vh,
|
||||||
|
var(--lighter-tum) var(--bplacement))
|
||||||
|
fixed;
|
||||||
|
|
||||||
|
color: var(--text);
|
||||||
|
font-family: Muller;
|
||||||
|
font-size: 16pt;
|
||||||
|
|
||||||
|
--red: hsla(340, 100%, 70%, 60%);
|
||||||
|
--green: hsla(93, 100%, 63%, 60%);
|
||||||
|
--yellow: hsla(60, 100%, 70%, 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 2rem auto;
|
||||||
|
padding: 1em 1em 1.5em 1em;
|
||||||
|
border: 5px solid var(--dark-tum);
|
||||||
|
box-shadow: 0px 0px 50px var(--shadow);
|
||||||
|
background: var(--lighter-tum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
b { font-weight: 600; }
|
||||||
|
b b { font-weight: 900; }
|
||||||
|
|
||||||
|
h1, h2, h3 { font-weight: 900; }
|
||||||
|
h1 { font-size: 150%; }
|
||||||
|
h2 { font-size: 130%; }
|
||||||
|
h3 { font-size: 100%; }
|
||||||
|
h4 { font-size: 100%; font-weight: 600; }
|
||||||
|
|
||||||
|
header {
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 0 1em 0;
|
||||||
|
--small: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 300%;
|
||||||
|
font-weight: 100;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-link);
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li {
|
||||||
|
list-style: '— ';
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section + section { margin-top: 1em; }
|
||||||
|
section > section + section { margin-top: 0.75em; }
|
||||||
|
|
||||||
|
h1[id] a, h2[id] a, h3[id] a, h4[id] a, h5[id] a {
|
||||||
|
color: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1[id]:hover::after,
|
||||||
|
h2[id]:hover::after,
|
||||||
|
h3[id]:hover::after,
|
||||||
|
h4[id]:hover::after,
|
||||||
|
h5[id]:hover::after {
|
||||||
|
content: ' §';
|
||||||
|
opacity: 60%;
|
||||||
|
}
|
BIN
style/border.png
(Stored with Git LFS)
Normal file
BIN
style/border.png
(Stored with Git LFS)
Normal file
Binary file not shown.
65
style/gallery.css
Normal file
65
style/gallery.css
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
@import url(base.css);
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-width: 50em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, var(--image-size));
|
||||||
|
grid-gap: 1.5em;
|
||||||
|
justify-content: center;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
--image-size: 200px;
|
||||||
|
--border-thickness: 2px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
width: calc(var(--image-size) + 2 * var(--border-thickness));
|
||||||
|
height: calc(var(--image-size) + 2 * var(--border-thickness));
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item * {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item img {
|
||||||
|
border: 2px solid var(--text);
|
||||||
|
box-shadow: 0 0 10px var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item figcaption {
|
||||||
|
width: calc(100% - 4 * var(--border-thickness));
|
||||||
|
margin: 0;
|
||||||
|
padding: var(--border-thickness);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
|
||||||
|
background: hsl(0, 0%, 100%, 75%);
|
||||||
|
text-shadow: 0 0 2px white;
|
||||||
|
border: 2px solid var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item:hover img {
|
||||||
|
filter: contrast(120%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item:hover figcaption {
|
||||||
|
opacity: 20%;
|
||||||
|
transform: translate(-5%, 80%) rotateZ(7deg);
|
||||||
|
}
|
57
style/index.css
Normal file
57
style/index.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
@import url(base.css);
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 40em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 50%);
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
font-size: 150%;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list a {
|
||||||
|
display: block;
|
||||||
|
font-weight: inherit;
|
||||||
|
color: var(--text);
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
|
transition: all 0.25s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list a:hover {
|
||||||
|
transform: scale(110%);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list li {
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
background: var(--green);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list li:nth-child(2n) {
|
||||||
|
border-left: 2px solid hsla(0, 0%, 100%, 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-list li:nth-child(2n+1) {
|
||||||
|
border-right: 2px solid hsla(0, 0%, 100%, 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.gallery-list .nsfw {
|
||||||
|
background: var(--red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nsfw a:after {
|
||||||
|
content: url(18_plus.png);
|
||||||
|
padding-left: 0.15em;
|
||||||
|
vertical-align: middle;
|
||||||
|
opacity: 75%;
|
||||||
|
}
|
141
style/single.css
Normal file
141
style/single.css
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
@import url(base.css);
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-width: calc(var(--page-size) + 200px);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date, .artist {
|
||||||
|
font-weight: 400;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.1em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font-style: oblique;
|
||||||
|
}
|
||||||
|
.date { right: 0.1em; }
|
||||||
|
.artist { left: 0.1em; }
|
||||||
|
|
||||||
|
#mainfig {
|
||||||
|
justify-content: center;
|
||||||
|
border: 2px solid var(--text);
|
||||||
|
margin: auto;
|
||||||
|
height: min-content;
|
||||||
|
width: min-content;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainimg {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
font-size: 250%;
|
||||||
|
font-weight: 900;
|
||||||
|
color: white;
|
||||||
|
background: hsla(var(--text-hue), 35%, 15%, 80%);
|
||||||
|
mix-blend-mode: multiply;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw::before {
|
||||||
|
content: 'cw:\A0'; /* nsbp */
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cw + * img {
|
||||||
|
filter: blur(50px);
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
margin: 1em auto;
|
||||||
|
width: var(--page-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info > section {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 1em;
|
||||||
|
grid-template-columns: 10em calc(var(--page-size) - 11em);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: baseline;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info h2 {
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info ul, .alts ul {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alts ul {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alts [type=checkbox], .alts [type=radio] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alts :checked + label {
|
||||||
|
background: var(--yellow);
|
||||||
|
border-color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alts .nsfw label::after {
|
||||||
|
content: url(18_plus_small.png);
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-left: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info ul {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info li, .alts li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info li, .alts label {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
margin: 0 0.25em;
|
||||||
|
background: var(--light-tum);
|
||||||
|
border: 1px solid var(--dark-tum);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info p {
|
||||||
|
margin: 0.25em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
font-size: 90%;
|
||||||
|
font-style: oblique;
|
||||||
|
text-align: center;
|
||||||
|
}
|
BIN
style/spots.png
(Stored with Git LFS)
Normal file
BIN
style/spots.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
Reference in a new issue