Compare commits

..

No commits in common. "main" and "v1" have entirely different histories.
main ... v1

16 changed files with 157 additions and 578 deletions

View file

@ -1,3 +1,2 @@
dist-newstyle dist-newstyle
.shake .shake
Dockerfile

View file

@ -1,56 +0,0 @@
name: Build container
on:
push:
branches:
- main
# copied everything below this line from https://docs.github.com/en/actions/publishing-packages/publishing-docker-images
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: true
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image (versioned)
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ghcr.io/pagwin2/psb:v1
labels: ${{ steps.meta.outputs.labels }}
- name: Build and push Docker image (latest)
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ghcr.io/pagwin2/psb:latest
labels: ${{ steps.meta.outputs.labels }}

View file

@ -14,6 +14,4 @@ RUN cabal build
WORKDIR /github/workspace WORKDIR /github/workspace
RUN export folder=$(ls /mnt/dist-newstyle/build/x86_64-linux) && mv /mnt/dist-newstyle/build/x86_64-linux/"$folder"/psb-0.1.0.0/x/psb/build/psb/psb /mnt/psb ENTRYPOINT ["/mnt/dist-newstyle/build/x86_64-linux/ghc-9.4.8/psb-0.1.0.0/x/psb/build/psb/psb", "build", "-p2"]
ENTRYPOINT ["/mnt/psb", "build"]

23
TODO Normal file
View file

@ -0,0 +1,23 @@
github action for deploy to github pages
minify js and css when copying over instead of just copying
make typst dependant on yaml?
add rst support so I'm not dependant on typst not breaking
add a cli flag to send webmentions and track the ones sent/acked in some file, probably a simple csv with path and what got linked to (https://indieweb.org/Webmention) (https://indieweb.org/Webmention-developer)
make it so typst citation section has a header and/or is a div elem instead of a section element
process source code blocks with tree sitter https://hackage.haskell.org/package/tree-sitter
Check to see if pandoc html output can be changed somehow (for header anchor links)
https://hackage.haskell.org/package/pandoc-3.5/docs/Text-Pandoc-Writers.html#t:Writer
HXT on the generated html is an option
https://pandoc.org/MANUAL.html#custom-readers-and-writers might be an option https://pandoc.org/lua-filters.html
most likely will be a generic lua filter though https://pandoc.org/lua-filters.html
see if performance can be improved (it isn't slow atm but it definitely feels like there's a bottleneck)

View file

@ -1,9 +0,0 @@
- add rst support and convert markdown handling to custom parser instead of pandoc
- process source code blocks with tree sitter https://hackage.haskell.org/package/tree-sitter
- minify js and css when copying over instead of just copying
- look into adding postcss support perhaps
- see if performance can be improved (it isn't slow atm but it definitely feels like there's a bottleneck)

View file

@ -3,4 +3,4 @@ name: 'psb'
description: 'Use PSB to build static a static site' description: 'Use PSB to build static a static site'
runs: runs:
using: 'docker' using: 'docker'
image: 'docker://ghcr.io/pagwin2/psb:v1' image: 'Dockerfile'

View file

@ -4,11 +4,11 @@ outputDir :: String
outputDir = "publish" outputDir = "publish"
assetGlobs :: [String] assetGlobs :: [String]
assetGlobs = ["static//*", "robots.txt", "sw.js", "favicon.ico"] assetGlobs = ["static//*", "robots.txt"]
-- CAN ONLY BE TYPST DOCS UNLESS YOU CHANGE THINGS AT THE `pages` RULE in `Main.hs -- CAN ONLY BE TYPST DOCS UNLESS YOU CHANGE THINGS AT THE `pages` RULE in `Main.hs
pagePaths :: [String] pagePaths :: [String]
pagePaths = [] pagePaths = []
postGlobs :: [String] postGlobs :: [String]
postGlobs = ["posts/*.md"] postGlobs = ["posts/*.typ", "posts/*.md"]

View file

@ -1,18 +0,0 @@
module IR where
import Data.Text
-- Html and Math tags come with their data because they are leaves for us
-- We aren't parsing that if we can avoid it
data Tag = Heading {level :: Int} | Paragraph | Blockquote | Code | Html {html :: Text} | Anchor | Italic | Bold | Math {mathML :: Text}
data Data = Ast {ast :: AST} | Text {text :: Text}
data AST = AST {tag :: Tag, child :: [Data]}
-- for processing math
-- https://hackage.haskell.org/package/typst-0.6.1/docs/Typst-Parse.html#v:parseTypst
-- and
-- https://hackage.haskell.org/package/typst-symbols-0.1.7/docs/Typst-Symbols.html
-- are going to be used for handling typst and
-- texmath for latex handling

View file

@ -11,6 +11,7 @@ import Config
import Control.Monad (forM, when) import Control.Monad (forM, when)
import qualified Data.HashMap.Strict as HM import qualified Data.HashMap.Strict as HM
import Data.List (sortOn) import Data.List (sortOn)
import Data.Maybe (fromJust)
import qualified Data.Ord as Ord import qualified Data.Ord as Ord
import qualified Data.Text as T import qualified Data.Text as T
import Deriving.Aeson import Deriving.Aeson
@ -19,6 +20,7 @@ import Development.Shake (Action, Rules, (%>), (|%>), (~>))
import qualified Development.Shake as Shake import qualified Development.Shake as Shake
import Development.Shake.FilePath ((</>)) import Development.Shake.FilePath ((</>))
import qualified Development.Shake.FilePath as FP import qualified Development.Shake.FilePath as FP
import qualified Development.Shake.FilePath as Shake
import Templates import Templates
import Types import Types
import Utilities import Utilities
@ -57,6 +59,7 @@ buildRules :: Rules ()
buildRules = do buildRules = do
home home
assets assets
pages
postsRule postsRule
rss rss
@ -67,6 +70,28 @@ assets =
let src = FP.dropDirectory1 target let src = FP.dropDirectory1 target
Shake.copyFileChanged src target Shake.copyFileChanged src target
-- Shake.putInfo $ "Copied " <> target <> " from " <> src
-- handling typst only because pages should only be typst no reason for backwards compat on that
pages :: Rules ()
pages =
map indexHtmlOutputPath pagePaths |%> \target -> do
let src = indexHtmlTypstSourcePath target
let metaSrc = indexHtmlTypstMetaPath target
html <- typstToHtml src
meta <- yamlToPost metaSrc
time <- Utilities.now
let page =
Page
{ pageTitle = postTitle meta,
pageContent = html,
pageNow = time,
pageSection = T.pack $ fromJust $ Shake.stripExtension "html" target
}
applyTemplateAndWrite "default.html" page target
-- Shake.putInfo $ "Built " <> target <> " from " <> src
-- there's probably a better way of doing this that allows for the target's origin file extension to get passed in but for now we're doing brute force -- there's probably a better way of doing this that allows for the target's origin file extension to get passed in but for now we're doing brute force
postsRule :: Rules () postsRule :: Rules ()
postsRule = postsRule =
@ -80,12 +105,33 @@ postsRule =
when when
should should
( case FP.takeExtension path of ( case FP.takeExtension path of
".typ" -> typstPost path
".md" -> markdownPost path ".md" -> markdownPost path
_ -> error $ "invalid file extension for post " <> target _ -> error $ "invalid file extension for post " <> target
) )
) )
return () return ()
typstPost :: FP.FilePath -> Action ()
typstPost src = do
Shake.need [src]
let target = indexHtmlOutputPath src
post <- readTypstPost src
let rPost = fromPost post
postHtml <- applyTemplate "post.html" rPost
time <- Utilities.now
let page =
Page
{ pageTitle = rPostTitle rPost,
pageContent = postHtml,
pageNow = time,
pageSection = T.pack $ fromJust $ Shake.stripExtension "html" target
}
applyTemplateAndWrite "default.html" page target
-- Shake.putInfo $ "Built " <> target <> " from " <> src
markdownPost :: FP.FilePath -> Action () markdownPost :: FP.FilePath -> Action ()
markdownPost src = do markdownPost src = do
Shake.need [src] Shake.need [src]
@ -93,16 +139,16 @@ markdownPost src = do
post <- readMarkdownPost src post <- readMarkdownPost src
let rPost = fromPost post let rPost = fromPost post
-- Shake.putInfo $ show . toJSON $ rPost
postHtml <- applyTemplate "post.html" rPost postHtml <- applyTemplate "post.html" rPost
time <- Utilities.now time <- Utilities.now
-- Shake.putInfo $ T.unpack $ urlConvert target
let page = let page =
Page Page
{ pageTitle = rPostTitle rPost, { pageTitle = rPostTitle rPost,
pageContent = postHtml, pageContent = postHtml,
pageNow = time, pageNow = time,
pageUrl = urlConvert target pageSection = T.pack $ fromJust $ Shake.stripExtension "html" target
} }
applyTemplateAndWrite "default.html" page target applyTemplateAndWrite "default.html" page target
@ -118,13 +164,12 @@ home =
let posts' = map fromPost posts let posts' = map fromPost posts
html <- applyTemplate "home.html" $ HM.singleton "posts" posts' html <- applyTemplate "home.html" $ HM.singleton "posts" posts'
time <- Utilities.now time <- Utilities.now
-- Shake.putInfo $ T.unpack $ urlConvert target
let page = let page =
Page Page
{ pageTitle = T.pack "Home", { pageTitle = T.pack "Home",
pageContent = html, pageContent = html,
pageNow = time, pageNow = time,
pageUrl = urlConvert target pageSection = T.pack $ fromJust $ Shake.stripExtension "html" target
} }
applyTemplateAndWrite "default.html" page target applyTemplateAndWrite "default.html" page target
@ -150,9 +195,21 @@ rss =
readPost :: FilePath -> Action Post readPost :: FilePath -> Action Post
readPost postPath = do readPost postPath = do
case FP.takeExtension postPath of case FP.takeExtension postPath of
".typ" -> readTypstPost postPath
".md" -> readMarkdownPost postPath ".md" -> readMarkdownPost postPath
_ -> error $ "unknown file extension for file" <> postPath _ -> error $ "unknown file extension for file" <> postPath
readTypstPost :: FilePath -> Action Post
readTypstPost postPath = do
html <- typstToHtml postPath
post <- yamlToPost $ typstMetaPath postPath
-- Shake.putInfo $ "Read " <> postPath
return $
post
{ postContent = Just html,
postLink = Just . T.pack $ "/" <> FP.dropExtension postPath <> "/"
}
readMarkdownPost :: FilePath -> Action Post readMarkdownPost :: FilePath -> Action Post
readMarkdownPost postPath = do readMarkdownPost postPath = do
(post, html) <- markdownToHtml postPath (post, html) <- markdownToHtml postPath

View file

@ -1,5 +0,0 @@
{-# LANGUAGE OverloadedStrings #-}
module Markdown () where
import CMark

View file

@ -1,35 +0,0 @@
module Restruct where
-- https://docutils.sourceforge.io/rst.html
-- https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
-- https://hackage.haskell.org/package/parsec-3.1.18.0/docs/doc-index-All.html
import Data.Text (Text)
import Data.Void (Void)
import Text.Parsec as P
data RestElement
= RBody RestBody
| RTransition
| -- list of integers is the location in the section heirachy it is, Text is the title
-- NOTE: future me don't bother with proper restext convention do header depth via #n prefix to the title
RSection [Int] Text RestBody
data RestBody
= RParagraph [RInlineText]
| RBulletList Void
| REnumList Void
| RDefinitionList Void
| RFieldList Void
| ROptionList Void
| RLiteralBlock Void
| RLineBlock Void
| RBlockQuote Void
| -- skipping doctest blocks because no I'll just use a literal block thanks
RTable Void
| RExplicit Void
data MarkupModifier = Underline | Bold | Italic
data RInlineText = RInLineText {text :: Text, modifiers :: [MarkupModifier]}

View file

@ -10,8 +10,8 @@ data Page = Page
pageContent :: Text, pageContent :: Text,
-- build time -- build time
pageNow :: Text, pageNow :: Text,
-- -- css class for page section
pageUrl :: Text pageSection :: Text
} }
deriving (Show, Generic) deriving (Show, Generic)
deriving (ToJSON) via PrefixedSnake "page" Page deriving (ToJSON) via PrefixedSnake "page" Page

View file

@ -25,7 +25,14 @@ indexHtmlOutputPath srcPath =
-- were applicative shenanigans necessary? no -- were applicative shenanigans necessary? no
-- but using them felt cool -- but using them felt cool
indexHtmlSourcePaths :: FilePath -> [FilePath] indexHtmlSourcePaths :: FilePath -> [FilePath]
indexHtmlSourcePaths path = [indexHtmlMarkdownSourcePath] <*> [path] indexHtmlSourcePaths path = [indexHtmlTypstSourcePath, indexHtmlMarkdownSourcePath] <*> [path]
indexHtmlTypstSourcePath :: FilePath -> FilePath
indexHtmlTypstSourcePath =
FP.dropDirectory1
. (<.> "typ")
. FP.dropTrailingPathSeparator
. FP.dropFileName
indexHtmlMarkdownSourcePath :: FilePath -> FilePath indexHtmlMarkdownSourcePath :: FilePath -> FilePath
indexHtmlMarkdownSourcePath = indexHtmlMarkdownSourcePath =
@ -34,6 +41,25 @@ indexHtmlMarkdownSourcePath =
. FP.dropTrailingPathSeparator . FP.dropTrailingPathSeparator
. FP.dropFileName . FP.dropFileName
indexHtmlTypstMetaPath :: FilePath -> FilePath
indexHtmlTypstMetaPath = typstMetaPath . indexHtmlTypstSourcePath
typstMetaPath :: FilePath -> FilePath
typstMetaPath typstPath = FP.dropExtension typstPath <.> "yaml"
typstToHtml :: FilePath -> Action Text
typstToHtml filePath = do
content <- Shake.readFile' filePath
Shake.quietly . Shake.traced "Typst to HTML" $ do
doc <- runPandoc . Pandoc.readTypst readerOptions . T.pack $ content
html <- runPandoc . Pandoc.writeHtml5String writerOptions $ doc
return html
where
readerOptions =
Pandoc.def {Pandoc.readerExtensions = Pandoc.pandocExtensions}
writerOptions =
Pandoc.def {Pandoc.writerExtensions = Pandoc.pandocExtensions}
markdownToHtml :: (FromJSON a) => FilePath -> Action (a, Text) markdownToHtml :: (FromJSON a) => FilePath -> Action (a, Text)
markdownToHtml filePath = do markdownToHtml filePath = do
content <- Shake.readFile' filePath content <- Shake.readFile' filePath
@ -111,11 +137,14 @@ yamlToPost path = do
-- let post' = dateTransform post -- let post' = dateTransform post
return post return post
isTypstPost :: FilePath -> Bool
isTypstPost path = FP.takeExtension path == ".typ"
isMarkdownPost :: FilePath -> Bool isMarkdownPost :: FilePath -> Bool
isMarkdownPost path = FP.takeExtension path == ".md" isMarkdownPost path = FP.takeExtension path == ".md"
postHandles :: [(FilePath -> Bool, FilePath -> Action Post)] postHandles :: [(FilePath -> Bool, FilePath -> Action Post)]
postHandles = [(isMarkdownPost, markdownToPost)] postHandles = [(isTypstPost, yamlToPost . typstMetaPath), (isMarkdownPost, markdownToPost)]
isDraft :: FilePath -> Action Bool isDraft :: FilePath -> Action Bool
isDraft path = do isDraft path = do
@ -138,6 +167,3 @@ parseDate str = do
date <- parseTimeM False defaultTimeLocale "%Y-%-m-%-d" $ T.unpack str date <- parseTimeM False defaultTimeLocale "%Y-%-m-%-d" $ T.unpack str
-- need to append the time to avoid potential issues -- need to append the time to avoid potential issues
return $ T.pack $ formatTime @UTCTime defaultTimeLocale "%Y-%m-%dT00:00:00Z" date return $ T.pack $ formatTime @UTCTime defaultTimeLocale "%Y-%m-%dT00:00:00Z" date
urlConvert :: FilePath -> Text
urlConvert = T.pack . FP.dropFileName . flip FP.replaceDirectory1 "https://pagwin.xyz"

View file

@ -1,148 +0,0 @@
(* Markdown EBNF Grammar *)
document = { block } ;
block = heading
| horizontal_rule
| code_block
| quote_block
| list
| table
| paragraph
| blank_line ;
(* Headings *)
heading = atx_heading | setext_heading ;
atx_heading = "#" { "#" } [ " " ] inline_text newline ;
setext_heading = inline_text newline
( ( "=" { "=" } ) | ( "-" { "-" } ) ) newline ;
(* Horizontal Rule *)
horizontal_rule = ( ( "*" [ " " ] "*" [ " " ] "*" { [ " " ] "*" } )
| ( "-" [ " " ] "-" [ " " ] "-" { [ " " ] "-" } )
| ( "_" [ " " ] "_" [ " " ] "_" { [ " " ] "_" } ) ) newline ;
(* Code Blocks *)
code_block = fenced_code_block | indented_code_block ;
fenced_code_block = "```" [ language_identifier ] newline
{ code_line }
"```" newline ;
indented_code_block = { " " code_line } ;
code_line = { character - newline } newline ;
language_identifier = { letter | digit | "-" | "+" } ;
(* Quote Blocks *)
quote_block = { ">" [ " " ] ( inline_text | "" ) newline } ;
(* Lists *)
list = unordered_list | ordered_list ;
unordered_list = { unordered_list_item } ;
ordered_list = { ordered_list_item } ;
unordered_list_item = [ " " { " " } ] ( "*" | "+" | "-" ) " " inline_text newline
{ continuation_line } ;
ordered_list_item = [ " " { " " } ] digit { digit } "." " " inline_text newline
{ continuation_line } ;
continuation_line = " " inline_text newline ;
(* Tables *)
table = table_header table_separator { table_row } ;
table_header = "|" { table_cell "|" } newline ;
table_separator = "|" { table_align_spec "|" } newline ;
table_row = "|" { table_cell "|" } newline ;
table_cell = { character - ( "|" | newline ) } ;
table_align_spec = [ ":" ] "-" { "-" } [ ":" ] ;
(* Paragraphs *)
paragraph = inline_text { newline inline_text } newline ;
(* Inline Elements *)
inline_text = { inline_element } ;
inline_element = emphasis
| strong
| code_span
| link
| image
| autolink
| line_break
| plain_text ;
emphasis = ( "*" non_asterisk_text "*" )
| ( "_" non_underscore_text "_" ) ;
strong = ( "**" non_asterisk_text "**" )
| ( "__" non_underscore_text "__" ) ;
code_span = "`" { "`" } non_backtick_text { "`" } "`" ;
link = "[" link_text "]" "(" link_url [ " " link_title ] ")" ;
image = "!" "[" alt_text "]" "(" image_url [ " " image_title ] ")" ;
autolink = "<" ( url | email ) ">" ;
line_break = " " newline | "\\" newline ;
(* Text Content *)
plain_text = { character - special_char } ;
non_asterisk_text = { character - "*" } ;
non_underscore_text = { character - "_" } ;
non_backtick_text = { character - "`" } ;
link_text = { character - ( "[" | "]" ) } ;
alt_text = { character - ( "[" | "]" ) } ;
link_url = { character - ( "(" | ")" | " " ) } ;
image_url = { character - ( "(" | ")" | " " ) } ;
link_title = quote_string ;
image_title = quote_string ;
quote_string = ( '"' { character - '"' } '"' )
| ( "'" { character - "'" } "'" ) ;
url = "http" [ "s" ] "://" { character - ">" } ;
email = { character - ( "@" | ">" ) } "@" { character - ">" } ;
(* Utilities *)
blank_line = newline ;
special_char = "*" | "_" | "`" | "[" | "]" | "(" | ")" | "#" | ">" | "|" | "!" | "\\" ;
newline = "\n" | "\r\n" ;
character = letter | digit | symbol | " " ;
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
symbol = "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "="
| "+" | "[" | "]" | "{" | "}" | "\\" | "|" | ";" | ":" | "'" | '"' | "," | "."
| "<" | ">" | "/" | "?" | "~" | "`" ;

View file

@ -1,4 +1,16 @@
cabal-version: 3.4 cabal-version: 3.4
-- The cabal-version field refers to the version of the .cabal specification,
-- and can be different from the cabal-install (the tool) version and the
-- Cabal (the library) version you are using. As such, the Cabal (the library)
-- version used must be equal or greater than the version stated in this field.
-- Starting from the specification version 2.2, the cabal-version field must be
-- the first thing in the cabal file.
-- Initial package description 'psb' generated by
-- 'cabal init'. For further documentation, see:
-- http://haskell.org/cabal/users-guide/
--
-- The name of the package.
name: psb name: psb
-- The package version. -- The package version.
@ -10,15 +22,35 @@ name: psb
-- | | | +--- code changes with no API change -- | | | +--- code changes with no API change
version: 0.1.0.0 version: 0.1.0.0
-- A short (one-line) description of the package.
-- synopsis:
-- A longer description of the package.
-- description:
-- The license under which the package is released.
license: MIT license: MIT
-- The file containing the license text.
license-file: LICENSE license-file: LICENSE
-- The package author(s).
author: Pagwin author: Pagwin
-- An email address to which users can send suggestions, bug reports, and patches.
maintainer: dev@pagwin.xyz maintainer: dev@pagwin.xyz
-- A copyright notice.
-- copyright:
category: Web category: Web
build-type: Simple build-type: Simple
-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.
extra-doc-files: CHANGELOG.md
-- Extra source files to be distributed with the package, such as examples, or a tutorial module.
-- extra-source-files:
common warnings common warnings
ghc-options: -Wall ghc-options: -Wall
@ -29,14 +61,14 @@ executable psb
-- .hs or .lhs file containing the Main module. -- .hs or .lhs file containing the Main module.
main-is: Main.hs main-is: Main.hs
other-modules: Config Utilities Templates Types IR Markdown Restruct -- Modules included in this executable, other than Main.
other-modules: Config Utilities Templates Types
-- LANGUAGE extensions used by modules in this package.
default-extensions: ApplicativeDo DataKinds NamedFieldPuns DerivingVia LambdaCase TypeApplications DeriveGeneric default-extensions: ApplicativeDo DataKinds NamedFieldPuns DerivingVia LambdaCase TypeApplications DeriveGeneric
-- Other library packages from which modules are imported. -- Other library packages from which modules are imported.
-- https://hackage.haskell.org/package/texmath build-depends: base >=4.17.2.1, mustache >=2.4.2, pandoc >=3.2.1, shake >= 0.19.8, deriving-aeson >= 0.2.9, aeson, text, time, unordered-containers, yaml
-- cmark is pinned because I don't want to touch it unless I rewrite to my own code
build-depends: base >=4.17.2.1, mustache >=2.4.2, pandoc >=3.2.1, shake >= 0.19.8, deriving-aeson >= 0.2.9, aeson, text, time, unordered-containers, yaml, parsec >= 3.1.18.0, typst >= 0.6.1, typst-symbols >= 0.1.7, cmark == 0.6.1
-- Directories containing source files. -- Directories containing source files.
hs-source-dirs: app hs-source-dirs: app

View file

@ -1,285 +0,0 @@
(* reStructuredText EBNF Grammar *)
document = { block } ;
block = section
| transition
| paragraph
| literal_block
| line_block
| block_quote
| doctest_block
| table
| bullet_list
| enumerated_list
| definition_list
| field_list
| option_list
| directive
| comment
| substitution_definition
| target
| blank_line ;
(* Sections *)
section = section_title section_underline [ section_overline ] ;
section_title = inline_text newline ;
section_underline = section_adornment newline ;
section_overline = section_adornment newline ;
section_adornment = adornment_char { adornment_char } ;
adornment_char = "!" | '"' | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<" | "=" | ">" | "?" | "@" | "[" | "\\" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~" ;
(* Transitions *)
transition = transition_marker newline ;
transition_marker = transition_char { transition_char } ;
transition_char = adornment_char ;
(* Paragraphs *)
paragraph = inline_text { newline inline_text } newline ;
(* Literal Blocks *)
literal_block = literal_block_marker newline { indented_line } ;
literal_block_marker = "::" | paragraph "::" ;
indented_line = indent line_content newline ;
indent = " " | "\t" ;
line_content = { character - newline } ;
(* Line Blocks *)
line_block = { line_block_line } ;
line_block_line = "|" [ " " ] inline_text newline ;
(* Block Quotes *)
block_quote = { indented_paragraph } [ attribution ] ;
indented_paragraph = indent inline_text { newline indent inline_text } newline ;
attribution = indent "-- " inline_text newline ;
(* Doctest Blocks *)
doctest_block = { doctest_line } ;
doctest_line = ">>>" " " line_content newline
| "..." " " line_content newline ;
(* Tables *)
table = simple_table | grid_table ;
simple_table = simple_table_row { simple_table_row } simple_table_separator { simple_table_row } ;
simple_table_row = { table_cell } newline ;
simple_table_separator = "=" { ( "=" | " " ) } newline ;
grid_table = grid_table_border { grid_table_row grid_table_border } ;
grid_table_border = "+" { ( "-" | "+" ) } newline ;
grid_table_row = "|" { table_cell "|" } newline ;
table_cell = { character - ( "|" | newline ) } ;
(* Lists *)
bullet_list = { bullet_list_item } ;
bullet_list_item = bullet_marker " " list_item_content ;
bullet_marker = "*" | "+" | "-" | "•" | "‣" | "" ;
enumerated_list = { enumerated_list_item } ;
enumerated_list_item = enumeration_marker " " list_item_content ;
enumeration_marker = ( digit { digit } "." )
| ( digit { digit } ")" )
| ( "(" digit { digit } ")" )
| ( letter "." )
| ( letter ")" )
| ( "(" letter ")" )
| ( roman "." )
| ( roman ")" )
| ( "(" roman ")" )
| "#." | "#)" | "(#)" ;
list_item_content = inline_text { newline [ indent ] inline_text } newline ;
definition_list = { definition_list_item } ;
definition_list_item = term newline indent definition newline ;
term = inline_text ;
definition = inline_text { newline indent inline_text } ;
(* Field Lists *)
field_list = { field_list_item } ;
field_list_item = ":" field_name ":" " " field_body newline ;
field_name = { letter | digit | " " | "-" | "_" } ;
field_body = inline_text { newline indent inline_text } ;
(* Option Lists *)
option_list = { option_list_item } ;
option_list_item = option_group " " option_description newline ;
option_group = option { ", " option } ;
option = short_option | long_option ;
short_option = "-" letter [ " " option_argument ] ;
long_option = "--" { letter | digit | "-" } [ "=" option_argument ] ;
option_argument = { letter | digit | "-" | "_" } ;
option_description = inline_text { newline indent inline_text } ;
(* Directives *)
directive = ".." " " directive_name "::" [ " " directive_arguments ] newline
[ directive_options ]
[ blank_line ]
[ directive_content ] ;
directive_name = { letter | digit | "-" | "_" } ;
directive_arguments = { character - newline } ;
directive_options = { directive_option } ;
directive_option = indent ":" option_name ":" [ " " option_value ] newline ;
option_name = { letter | digit | "-" | "_" } ;
option_value = { character - newline } ;
directive_content = { indented_line } ;
(* Comments *)
comment = ".." [ " " comment_text ] newline { indented_line } ;
comment_text = { character - newline } ;
(* Substitution Definitions *)
substitution_definition = ".." " " "|" substitution_name "|" " " directive_name "::" [ " " directive_arguments ] newline
[ directive_options ]
[ directive_content ] ;
substitution_name = { character - ( "|" | newline ) } ;
(* Targets *)
target = internal_target | external_target ;
internal_target = ".." " " "_" target_name ":" newline ;
external_target = ".." " " "_" target_name ":" " " target_url newline ;
target_name = { character - ( ":" | newline ) } ;
target_url = { character - newline } ;
(* Inline Elements *)
inline_text = { inline_element } ;
inline_element = emphasis
| strong
| literal
| interpreted_text
| phrase_reference
| substitution_reference
| inline_internal_target
| hyperlink_reference
| footnote_reference
| citation_reference
| inline_literal
| plain_text ;
emphasis = "*" emphasis_text "*" ;
strong = "**" strong_text "**" ;
literal = "``" literal_text "``" ;
interpreted_text = "`" interpreted_text_content "`" [ role_suffix ]
| role_prefix "`" interpreted_text_content "`" ;
role_prefix = ":" role_name ":" ;
role_suffix = ":" role_name ":" ;
role_name = { letter | digit | "-" | "_" | "." } ;
interpreted_text_content = { character - "`" } ;
phrase_reference = "`" phrase_reference_text "`_" [ "_" ] ;
phrase_reference_text = { character - ( "`" | "<" ) } [ " " "<" target_url ">" ] ;
substitution_reference = "|" substitution_name "|" [ "_" [ "_" ] ] ;
inline_internal_target = "_`" target_text "`" ;
target_text = { character - "`" } ;
hyperlink_reference = reference_name "_" [ "_" ] ;
reference_name = { letter | digit | "-" | "_" | "." } ;
footnote_reference = "[" footnote_label "]_" ;
footnote_label = digit { digit } | "#" [ footnote_name ] | "*" ;
footnote_name = { letter | digit | "-" | "_" } ;
citation_reference = "[" citation_label "]_" ;
citation_label = { letter | digit | "-" | "_" | "." } ;
inline_literal = "`" "`" literal_content "`" "`" ;
literal_content = { character - "`" } ;
(* Text Content *)
plain_text = { character - markup_char } ;
emphasis_text = { character - ( "*" | newline ) } ;
strong_text = { character - ( "*" | newline ) } ;
literal_text = { character - ( "`" | newline ) } ;
markup_char = "*" | "`" | "_" | "|" | "[" | "]" | ":" | "." | ">" | "<" ;
(* Utilities *)
blank_line = newline ;
roman = "i" | "ii" | "iii" | "iv" | "v" | "vi" | "vii" | "viii" | "ix" | "x"
| "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X" ;
newline = "\n" | "\r\n" ;
character = letter | digit | symbol | " " ;
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
symbol = "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "="
| "+" | "[" | "]" | "{" | "}" | "\\" | "|" | ";" | ":" | "'" | '"' | "," | "."
| "<" | ">" | "/" | "?" | "~" | "`" ;