working? demo
This commit is contained in:
parent
617771d89a
commit
39b2e47ec7
16 changed files with 1755 additions and 1084 deletions
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
12
index.html
Normal file
12
index.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>writing</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="./priv/static/vite.ts" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
2647
package-lock.json
generated
2647
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"name": "promptbox",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "[](https://hex.pm/packages/promptbox) [](https://hexdocs.pm/promptbox/)",
|
||||
"main": "index.js",
|
||||
|
|
@ -13,6 +14,10 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"tailwindcss": "^3.4.17"
|
||||
"@tailwindcss/postcss": "^4.0.1",
|
||||
"@tailwindcss/vite": "^4.0.1",
|
||||
"tailwindcss": "^4.0.1",
|
||||
"vite": "^6.0.11",
|
||||
"vite-gleam": "^0.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
@import url(https://fonts.bunny.net/css?family=alegreya:400,400i,700,700i);
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
|
||||
body {
|
||||
font-family: 'Alegreya', serif;
|
||||
|
|
|
|||
6
priv/static/vite.ts
Normal file
6
priv/static/vite.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import '../assets/input.css'
|
||||
import lustre_main from '../../src/promptbox/devserver.gleam'
|
||||
|
||||
console.log('hello world')
|
||||
|
||||
lustre_main()
|
||||
|
|
@ -1,10 +1,50 @@
|
|||
import promptbox/postcss
|
||||
import argv
|
||||
import gleam/io
|
||||
import gleam/list
|
||||
import lustre/element
|
||||
import promptbox/devserver
|
||||
import promptbox/files
|
||||
import promptbox/web
|
||||
|
||||
pub fn main() {
|
||||
case argv.load().arguments {
|
||||
["serve"] -> Nil
|
||||
["build"] -> Nil
|
||||
["serve"] -> {
|
||||
// postcss.compile_css()
|
||||
devserver.run_vite_server()
|
||||
}
|
||||
["build"] -> {
|
||||
// Parse all posts
|
||||
let posts = files.read_all_posts()
|
||||
// Generate HTML
|
||||
let index =
|
||||
posts
|
||||
|> web.home
|
||||
|> web.layout("All Posts")
|
||||
|> element.to_document_string
|
||||
|
||||
// Clear and/or create the dist directory
|
||||
let _ = files.freshen_dist_dir()
|
||||
|
||||
// Write the index page
|
||||
let _ = files.write_built_file("index.html", index)
|
||||
|
||||
// Write individual prompt pages
|
||||
list.each(posts, fn(post) {
|
||||
let _ =
|
||||
files.write_built_file(
|
||||
"prompts/" <> post.slug <> ".html",
|
||||
web.layout([web.individual(post)], post.title)
|
||||
|> element.to_document_string,
|
||||
)
|
||||
})
|
||||
|
||||
// Move assets over, and create the asset folder
|
||||
postcss.compile_css()
|
||||
|
||||
// Finish
|
||||
Nil
|
||||
}
|
||||
_ -> io.println("usage: gleam run <serve|build>")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
src/promptbox/devserver.gleam
Normal file
39
src/promptbox/devserver.gleam
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import birl
|
||||
import lustre
|
||||
import lustre/element/html
|
||||
import promptbox/parser
|
||||
import promptbox/web
|
||||
|
||||
@external(javascript, "./devserver_ffi.js", "run_vite_server")
|
||||
pub fn run_vite_server() -> Nil
|
||||
|
||||
pub fn lustre_main() {
|
||||
let app = lustre.simple(init, update, view)
|
||||
let assert Ok(_) = lustre.start(app, "#app", Nil)
|
||||
|
||||
Nil
|
||||
}
|
||||
|
||||
fn init(_flags) {
|
||||
0
|
||||
}
|
||||
|
||||
fn update(model, _msg) {
|
||||
model
|
||||
}
|
||||
|
||||
fn view(_model) {
|
||||
html.div(
|
||||
[],
|
||||
web.home([
|
||||
parser.Post(
|
||||
slug: "ebben-flow",
|
||||
title: "ebben flow",
|
||||
week: 1,
|
||||
date: birl.now(),
|
||||
post_p: "No",
|
||||
post_j: "OK",
|
||||
),
|
||||
]),
|
||||
)
|
||||
}
|
||||
22
src/promptbox/devserver_ffi.js
Normal file
22
src/promptbox/devserver_ffi.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { createServer } from 'vite'
|
||||
import gleam from 'vite-gleam'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
export async function run_vite_server() {
|
||||
const server = await createServer({
|
||||
configFile: false,
|
||||
root: './',
|
||||
server: {
|
||||
port: 1337,
|
||||
},
|
||||
plugins: [
|
||||
gleam(),
|
||||
tailwindcss()
|
||||
]
|
||||
})
|
||||
|
||||
await server.listen()
|
||||
|
||||
server.printUrls()
|
||||
server.bindCLIShortcuts()
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
import gleam/list
|
||||
import gleam/order
|
||||
import gleam/pair
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
import promptbox/parser
|
||||
import simplifile
|
||||
|
||||
|
|
@ -7,9 +10,15 @@ pub fn read_all_posts() {
|
|||
let assert Ok(posts) = simplifile.read_directory("./priv/posts")
|
||||
|
||||
let posts =
|
||||
list.map(posts, fn(p) {
|
||||
let assert Ok(content) = simplifile.read("./priv/posts/" <> p)
|
||||
parser.parse_post(content)
|
||||
list.map(posts, fn(prompt_file) {
|
||||
let assert Ok(content) = simplifile.read("./priv/posts/" <> prompt_file)
|
||||
let post_slug =
|
||||
prompt_file
|
||||
|> string.split_once(".md")
|
||||
|> result.unwrap(#("", ""))
|
||||
|> pair.first
|
||||
|
||||
parser.parse_post(post_slug, content)
|
||||
})
|
||||
use a, b <- list.sort(posts)
|
||||
|
||||
|
|
@ -20,10 +29,10 @@ pub fn read_all_posts() {
|
|||
}
|
||||
|
||||
pub fn freshen_dist_dir() {
|
||||
// void this result since we dont care if it cant be deleted / doesn't exist
|
||||
// void this results since we dont care if it cant be deleted / doesn't exist, or can't be created.
|
||||
let _ = simplifile.delete("./dist")
|
||||
|
||||
simplifile.create_directory("./dist")
|
||||
let _ = simplifile.create_directory("./dist")
|
||||
let _ = simplifile.create_directory("./dist/prompts")
|
||||
}
|
||||
|
||||
pub fn write_built_file(name: String, contents: String) {
|
||||
|
|
|
|||
|
|
@ -2,5 +2,7 @@ import promptbox/parser
|
|||
import promptbox/web
|
||||
|
||||
pub fn generate_posts(posts: List(parser.Post)) {
|
||||
web.home(posts)
|
||||
posts
|
||||
|> web.home
|
||||
|> web.layout("all writing")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import jot
|
|||
|
||||
pub type Post {
|
||||
Post(
|
||||
slug: String,
|
||||
title: String,
|
||||
week: Int,
|
||||
date: birl.Time,
|
||||
|
|
@ -16,7 +17,7 @@ pub type Post {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn parse_post(content: String) -> Post {
|
||||
pub fn parse_post(slug: String, content: String) -> Post {
|
||||
let assert [_, frontmatter, posts] = string.split(content, "---\n")
|
||||
let frontmatter =
|
||||
frontmatter
|
||||
|
|
@ -39,6 +40,7 @@ pub fn parse_post(content: String) -> Post {
|
|||
|> list.map(jot.to_html)
|
||||
|
||||
Post(
|
||||
slug:,
|
||||
title: result.unwrap(
|
||||
dict.get(frontmatter, "title"),
|
||||
"Title failed to parse",
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
@external(javascript, "./promptbox/postcss_ffi.js", "compile_css")
|
||||
@external(javascript, "./postcss_ffi.js", "compile_css")
|
||||
pub fn compile_css() -> Nil
|
||||
|
|
|
|||
|
|
@ -1,3 +1,17 @@
|
|||
export function compile_css() {
|
||||
import tailwindcss from '@tailwindcss/postcss'
|
||||
import postcss from 'postcss'
|
||||
import fs from 'node:fs'
|
||||
|
||||
export function compile_css() {
|
||||
const css = fs.readFileSync('./priv/assets/input.css').toString()
|
||||
postcss([tailwindcss])
|
||||
.process(css, { from: './priv/assets/input.css', to: './dist/assets/main.css' })
|
||||
.then(result => {
|
||||
fs.mkdir('./dist/assets/', { recursive: true }, () => true)
|
||||
|
||||
fs.writeFile('./dist/assets/main.css', result.css, () => true)
|
||||
if (result.map) {
|
||||
fs.writeFile('./dist/assets/main.css.map', result.map.toString(), () => true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import lustre/attribute.{attribute}
|
|||
import lustre/element/html
|
||||
import promptbox/parser
|
||||
|
||||
fn layout(contents, title) {
|
||||
pub fn layout(contents, title) {
|
||||
html.html([attribute("lang", "en")], [
|
||||
html.head([], [
|
||||
html.meta([attribute("charset", "utf-8")]),
|
||||
|
|
@ -12,7 +12,7 @@ fn layout(contents, title) {
|
|||
attribute.name("viewport"),
|
||||
]),
|
||||
html.title([], title),
|
||||
html.link([attribute.href("styles.css"), attribute.rel("stylesheet")]),
|
||||
html.link([attribute.href("/assets/main.css"), attribute.rel("stylesheet")]),
|
||||
]),
|
||||
html.body(
|
||||
[],
|
||||
|
|
@ -23,12 +23,10 @@ fn layout(contents, title) {
|
|||
|
||||
pub fn home(posts: List(parser.Post)) {
|
||||
list.map(posts, prompt_element)
|
||||
|> layout("all writing")
|
||||
}
|
||||
|
||||
pub fn individual(post: parser.Post) {
|
||||
[prompt_element(post)]
|
||||
|> layout(post.title)
|
||||
prompt_element(post)
|
||||
}
|
||||
|
||||
fn prompt_element(post: parser.Post) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub fn hello_world_test() {
|
|||
let post =
|
||||
simplifile.read("./priv/posts/ebb_and_flow.md")
|
||||
|> result.unwrap("")
|
||||
|> parser.parse_post
|
||||
|> parser.parse_post("ebb_and_flow")
|
||||
|> io.debug
|
||||
|
||||
io.debug(birl.to_date_string(post.date))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue