Add support for rendering furigana

main
Oystein Kristoffer Tveit 2022-03-19 00:59:36 +01:00
parent 9854cfd60f
commit 1030977dfd
11 changed files with 189 additions and 59 deletions

View File

@ -36,7 +36,7 @@
packages = p: [ p.ssg ]; packages = p: [ p.ssg ];
buildInputs = with pkgs.myHaskellPackages; [ buildInputs = with pkgs.myHaskellPackages; [
ssg # ssg
# Helpful tools for `nix develop` shells # Helpful tools for `nix develop` shells
ghcid # https://github.com/ndmitchell/ghcid ghcid # https://github.com/ndmitchell/ghcid

View File

@ -1,13 +1,13 @@
--- ---
desc: "This is me saying hello to the world" desc: "Nani.wtf homepage"
image: "./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg" image: "./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg"
lang: "en" lang: "en"
stylesheet: "default" stylesheet: "default"
title: "Hello, world!" title: "Nani"
--- ---
<header class="header"> <header class="header">
<h1>Hello, world!</h1> <h1>Welcome to nani.wtf</h1>
<img <img
alt="A woman sitting on a bench amongst trees at the end of a boardwalk leading to a pond with mountains in the background" alt="A woman sitting on a bench amongst trees at the end of a boardwalk leading to a pond with mountains in the background"
src="./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg" src="./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg"
@ -16,14 +16,27 @@ title: "Hello, world!"
</header> </header>
<main> <main>
<section class="content"> <section class="content">
<h2>Blog Posts</h2> <div class="pure-g">
<ul> <div class="pure-u-1-2 pure-u-md-1-2">
$for(posts)$ <h2>Posts</h2>
<li> <ul>
<div><a href=".$url$">$title$</a></div> $for(posts)$
<small>$date$</small> <li>
</li> <div><a href=".$url$">$title$</a></div>
$endfor$ <small>$date$</small>
</ul> </li>
$endfor$
</ul>
</div>
<div class="pure-u-1-2 pure-u-md-1-2">
<h2>成り立ち</h2>
<ul>
$for(naritachi)$
<li>
<div><a href=".$url$">$title$</a></div>
</li>
$endfor$
</ul>
</div>
</section> </section>
</main> </main>

9
src/naritachi/suru.md Normal file
View File

@ -0,0 +1,9 @@
---
desc: "I announce myself to the world"
keywords: "japanese, naritachi, grammar"
lang: "en"
updated: "2020-09-22T12:00:00Z"
title: "[為](す)る"
---
suru

View File

@ -6,42 +6,48 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="$desc$"> <meta name="description" content="$desc$">
$if(author)$ $if(author)$
<meta name="author" content="$author$"> <meta name="author" content="$author$">
$endif$ $endif$
$if(keywords)$ $if(keywords)$
<meta name="keywords" content="$keywords$"> <meta name="keywords" content="$keywords$">
$endif$ $endif$
<meta property="og:site_name" content="$siteName$"> <meta property="og:site_name" content="$siteName$">
<meta property="og:title" content="$title$"> <meta property="og:title" content="$title$">
<meta property="og:url" content="$root$$url$"> <meta property="og:url" content="$root$$url$">
<meta property="og:description" content="$desc$"> <meta property="og:description" content="$desc$">
$if(image)$ $if(image)$
<meta property="og:image" content="$root$$image$"> <meta property="og:image" content="$root$$image$">
$endif$ $endif$
$if(type)$ $if(type)$
<meta property="og:type" content="$type$"> <meta property="og:type" content="$type$">
$else$ $else$
<meta property="og:type" content="website"> <meta property="og:type" content="website">
$endif$ $endif$
<meta property="twitter:card" content="summary_large_image"> <meta property="twitter:card" content="summary_large_image">
<meta property="twitter:site" content="$siteName$"> <meta property="twitter:site" content="$siteName$">
<meta property="twitter:title" content="$title$"> <meta property="twitter:title" content="$title$">
<meta property="twitter:description" content="$desc$"> <meta property="twitter:description" content="$desc$">
$if(image)$ $if(image)$
<meta property="twitter:image" content="$root$$image$"> <meta property="twitter:image" content="$root$$image$">
$endif$
$if(authorTwitter)$
<meta property="twitter:creator" content="$authorTwitter$">
$endif$ $endif$
<link rel="shortcut icon" href="/favicon.ico"> <!-- $if(authorTwitter)$ -->
<!-- <meta property="twitter:creator" content="$authorTwitter$"> -->
<!-- $endif$ -->
<link rel="shortcut icon" href="$root$favicon.ico">
<link rel="canonical" href="$root$$url$"> <link rel="canonical" href="$root$$url$">
<link rel="stylesheet" href="./css/default.css" /> <link rel="stylesheet" href="$root$css/default.css" />
<link rel="stylesheet" href="./css/styles.css" /> <link rel="stylesheet" href="$root$css/styles.css" />
<link rel="stylesheet" href="./css/code.css" /> <link rel="stylesheet" href="$root$css/code.css" />
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous"> <link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous">
</head> </head>
<body> <body>
@ -56,14 +62,16 @@
<a class="pure-menu-heading" href="$root$">$siteName$</a> <a class="pure-menu-heading" href="$root$">$siteName$</a>
<ul class="pure-menu-list"> <ul class="pure-menu-list">
<li class="pure-menu-item"><a href="#home" class="pure-menu-link">Home</a></li> <li class="pure-menu-item"><a href="$root$" class="pure-menu-link">Posts</a></li>
<li class="pure-menu-item"><a href="#about" class="pure-menu-link">About</a></li> <li class="pure-menu-item"><a href="$root$" class="pure-menu-link">成り立ち</a></li>
<li class="pure-menu-item menu-item-divided pure-menu-selected">
<a href="#" class="pure-menu-link">Services</a>
</li>
<!-- <li class="pure-menu-item menu-item-divided pure-menu-selected"> -->
<!-- <a href="#" class="pure-menu-link">Services</a> -->
<!-- </li> -->
<li class="pure-menu-item"><a href="#contact" class="pure-menu-link">Contact</a></li> <li class="pure-menu-item"><a href="#contact" class="pure-menu-link">Contact</a></li>
<li class="pure-menu-item menu-item-divided"><a href="https://git.nani.wtf" class="pure-menu-link">Git</a></li>
<li class="pure-menu-item"><a href="https://git.nani.wtf/h7x4/nani.wtf" class="pure-menu-link">Site source</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -81,7 +89,9 @@
<!-- </p> --> <!-- </p> -->
</div> </div>
</div> </div>
$body$
$body$
<script async src="./js/script.js"></script> <script async src="./js/script.js"></script>
<script src="./js/ui.js"></script> <script src="./js/ui.js"></script>
</body> </body>

View File

@ -0,0 +1,20 @@
<main>
<article>
<header class="header">
<h1>$titleHtml$</h1>
<div>
$if(updated)$
<small>(updated: $updated$)</small>
$endif$
</div>
$if(alternative_writings)$
<div>
$alternative_writings$
</div>
$endif$
</header>
<section class="content">
$body$
</section>
</article>
</main>

View File

@ -1,17 +1,15 @@
<main> <main>
<article> <article>
<header> <header class="header">
<h1> <h1>$title$</h1>
<a href=".$url$">$title$</a>
</h1>
<div> <div>
<small>$date$</small> <small>$date$</small>
$if(updated)$ $if(updated)$
<small>(updated: $updated$)</small> <small>(updated: $updated$)</small>
$endif$ $endif$
</div> </div>
</header> </header>
<section> <section class="content">
$body$ $body$
</section> </section>
</article> </article>

View File

@ -0,0 +1,51 @@
{-# LANGUAGE QuasiQuotes, FlexibleContexts #-}
module Formats.Naritachi (
convertFuriganaTitle,
convertFuriganaTitleHtml
) where
import Hakyll (Item, Metadata, Compiler, itemIdentifier, getMetadata, lookupString)
import Debug.Trace (traceId)
import Data.Maybe (fromMaybe)
import Text.Regex.PCRE.Heavy
--------------------------------------------------------------------------------
-- FURIGANA CONVERSION
type FuriganaTemplate = String
convertTitle = updateFieldWith "title" "???"
convertFuriganaTitle :: Item a -> Compiler String
convertFuriganaTitle = convertTitle replaceFuriganaWithKanji
convertFuriganaTitleHtml :: Item a -> Compiler String
convertFuriganaTitleHtml = convertTitle replaceFuriganaWithHtml
updateFieldWith :: String -> String -> (String -> String) -> Item a -> Compiler String
updateFieldWith field defaultPreviousValue f =
fmap updateField . getMetadata . itemIdentifier
where
updateField :: Metadata -> String
updateField = traceId . f . fromMaybe defaultPreviousValue . lookupString field
replaceFuriganaWithKanji :: FuriganaTemplate -> String
replaceFuriganaWithKanji = gsub [re|\[(.*?)\]\((.*?)\)|] (\(kanji:kana:_) -> kanji :: String)
replaceFuriganaWithHtml :: FuriganaTemplate -> String
replaceFuriganaWithHtml = between "<ruby>" "</ruby>" . gsub [re|\[(.*?)\]\((.*?)\)|] (\(kanji:kana:_) -> "<rb>" ++ kanji ++"</rb> <rp>(</rp><rt> " ++ kana ++ "</rt><rp>)</rp>" :: String)
where
between x y s = x ++ s ++ y
-- toHtml :: FuriganaTemplate -> String
-- toHtml input =
-- "<ruby>"
-- <> subRegex (mkRegex "[(.*?)]\\((.*?)\\)") input "<rb>\1</rb> <rp>(</rp><rt>\2</rt><rp>)</rp>"
-- <> "</ruby>"
-- <!-- <ruby> -->
-- <!-- <rb>す</rb> <rp>(</rp><rt>為</rt><rp>)</rp> -->
-- <!-- <rb>る</rb> -->
-- <!-- </ruby> -->
-- <!-- " -->

1
ssg/src/Formats/Posts.hs Normal file
View File

@ -0,0 +1 @@
module Formats.Posts where

View File

@ -3,7 +3,6 @@
import Control.Monad (forM_) import Control.Monad (forM_)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Hakyll import Hakyll
import Debug.Trace (trace)
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Slugger as Slugger import qualified Data.Text.Slugger as Slugger
import Text.Pandoc import Text.Pandoc
@ -18,6 +17,11 @@ import Text.Pandoc
) )
import Text.Pandoc.Highlighting (Style, breezeDark, styleToCss) import Text.Pandoc.Highlighting (Style, breezeDark, styleToCss)
-- ---------
import Formats.Naritachi
import Util.Routes
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- CONFIG -- CONFIG
@ -76,13 +80,31 @@ main = hakyllWith config $ do
>>= saveSnapshot "content" >>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/default.html" ctx >>= loadAndApplyTemplate "templates/default.html" ctx
match "naritachi/*" $ do
let ctx =
constField "type" "article"
<> field "title" convertFuriganaTitle
<> field "titleHtml" convertFuriganaTitleHtml
<> postCtx
route $ setExtension ".html"
compile $ do
pandocCompilerCustom
>>= loadAndApplyTemplate "templates/naritachi.html" ctx
>>= saveSnapshot "content"
>>= loadAndApplyTemplate "templates/default.html" ctx
match "index.html" $ do match "index.html" $ do
route idRoute route idRoute
compile $ do compile $ do
-- posts :: Compiler
posts <- recentFirst =<< loadAll "posts/*" posts <- recentFirst =<< loadAll "posts/*"
naritachi <- loadAll "naritachi/*"
let indexCtx = let indexCtx =
listField "posts" postCtx (return posts) listField "posts" postCtx (return posts)
<> listField "naritachi" postCtx (return naritachi)
<> constField "root" root <> constField "root" root
<> constField "siteName" siteName <> constField "siteName" siteName
<> defaultContext <> defaultContext
@ -225,21 +247,3 @@ feedConfiguration =
, feedAuthorEmail = "h7x4@protonmail.com" , feedAuthorEmail = "h7x4@protonmail.com"
, feedRoot = root , feedRoot = root
} }
--------------------------------------------------------------------------------
-- CUSTOM ROUTE
getTitleFromMeta :: Metadata -> String
getTitleFromMeta =
fromMaybe "no title" . lookupString "title"
fileNameFromTitle :: Metadata -> FilePath
fileNameFromTitle =
T.unpack . (`T.append` ".html") . Slugger.toSlug . T.pack . getTitleFromMeta
titleRoute :: Metadata -> Routes
titleRoute =
constRoute . fileNameFromTitle
prefixRoute :: FilePath -> Routes
prefixRoute p = customRoute $ \id -> p ++ (toFilePath id)

23
ssg/src/Util/Routes.hs Normal file
View File

@ -0,0 +1,23 @@
{-# LANGUAGE OverloadedStrings #-}
module Util.Routes where
import Hakyll
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import qualified Data.Text.Slugger as Slugger
prefixRoute :: FilePath -> Routes
prefixRoute p = customRoute $ \id' -> p ++ (toFilePath id')
titleRoute :: Metadata -> Routes
titleRoute = constRoute . fileNameFromTitle
where
getTitleFromMeta :: Metadata -> String
getTitleFromMeta =
fromMaybe "no title" . lookupString "title"
fileNameFromTitle :: Metadata -> FilePath
fileNameFromTitle =
T.unpack . (`T.append` ".html") . Slugger.toSlug . T.pack . getTitleFromMeta

View File

@ -14,5 +14,6 @@ executable hakyll-site
, pandoc == 2.14.* , pandoc == 2.14.*
, slugger >= 0.1.0.1 , slugger >= 0.1.0.1
, text >= 1.2 , text >= 1.2
, pcre-heavy >= 1.0.0.2
ghc-options: -Wall -threaded ghc-options: -Wall -threaded
default-language: Haskell2010 default-language: Haskell2010