init project
This commit is contained in:
commit
0f5ec5fd9c
17 changed files with 1651 additions and 0 deletions
23
.github/workflows/test.yml
vendored
Normal file
23
.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: erlef/setup-beam@v1
|
||||
with:
|
||||
otp-version: "27.1.2"
|
||||
gleam-version: "1.6.0"
|
||||
rebar3-version: "3"
|
||||
# elixir-version: "1.15.4"
|
||||
- run: gleam deps download
|
||||
- run: gleam test
|
||||
- run: gleam format --check src test
|
||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
*.beam
|
||||
*.ez
|
||||
/build
|
||||
erl_crash.dump
|
||||
/dist
|
||||
node_modules
|
||||
24
README.md
Normal file
24
README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# promptbox
|
||||
|
||||
[](https://hex.pm/packages/promptbox)
|
||||
[](https://hexdocs.pm/promptbox/)
|
||||
|
||||
```sh
|
||||
gleam add promptbox@1
|
||||
```
|
||||
```gleam
|
||||
import promptbox
|
||||
|
||||
pub fn main() {
|
||||
// TODO: An example of the project in use
|
||||
}
|
||||
```
|
||||
|
||||
Further documentation can be found at <https://hexdocs.pm/promptbox>.
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
gleam run # Run the project
|
||||
gleam test # Run the tests
|
||||
```
|
||||
23
gleam.toml
Normal file
23
gleam.toml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name = "promptbox"
|
||||
version = "1.0.0"
|
||||
|
||||
# Fill out these fields if you intend to generate HTML documentation or publish
|
||||
# your project to the Hex package manager.
|
||||
#
|
||||
# description = ""
|
||||
# licences = ["Apache-2.0"]
|
||||
# repository = { type = "github", user = "", repo = "" }
|
||||
# links = [{ title = "Website", href = "" }]
|
||||
#
|
||||
# For a full reference of all the available options, you can have a look at
|
||||
# https://gleam.run/writing-gleam/gleam-toml/.
|
||||
|
||||
[dependencies]
|
||||
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
|
||||
jot = ">= 2.0.0 and < 3.0.0"
|
||||
simplifile = ">= 2.2.0 and < 3.0.0"
|
||||
lustre = ">= 4.6.3 and < 5.0.0"
|
||||
birl = ">= 1.8.0 and < 2.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
gleeunit = ">= 1.0.0 and < 2.0.0"
|
||||
26
manifest.toml
Normal file
26
manifest.toml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# This file was generated by Gleam
|
||||
# You typically do not need to edit this file
|
||||
|
||||
packages = [
|
||||
{ name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
|
||||
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
|
||||
{ name = "gleam_erlang", version = "0.33.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "A1D26B80F01901B59AABEE3475DD4C18D27D58FA5C897D922FCB9B099749C064" },
|
||||
{ name = "gleam_json", version = "2.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "C55C5C2B318533A8072D221C5E06E5A75711C129E420DD1CE463342106012E5D" },
|
||||
{ name = "gleam_otp", version = "0.16.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "FA0EB761339749B4E82D63016C6A18C4E6662DA05BAB6F1346F9AF2E679E301A" },
|
||||
{ name = "gleam_regexp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "A3655FDD288571E90EE9C4009B719FEF59FA16AFCDF3952A76A125AF23CF1592" },
|
||||
{ name = "gleam_stdlib", version = "0.52.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "50703862DF26453B277688FFCDBE9DD4AC45B3BD9742C0B370DB62BC1629A07D" },
|
||||
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
|
||||
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
|
||||
{ name = "jot", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "jot", source = "hex", outer_checksum = "81E61DA896901BFC0522DCFB14C661B6C70F0664C01D8B461F5F9B1A9E965FD4" },
|
||||
{ name = "lustre", version = "4.6.3", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "BDF833368F6C8F152F948D5B6A79866E9881CB80CB66C0685B3327E7DCBFB12F" },
|
||||
{ name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
|
||||
{ name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
|
||||
]
|
||||
|
||||
[requirements]
|
||||
birl = { version = ">= 1.8.0 and < 2.0.0" }
|
||||
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
|
||||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
||||
jot = { version = ">= 2.0.0 and < 3.0.0" }
|
||||
lustre = { version = ">= 4.6.3 and < 5.0.0" }
|
||||
simplifile = { version = ">= 2.2.0 and < 3.0.0" }
|
||||
1271
package-lock.json
generated
Normal file
1271
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
18
package.json
Normal file
18
package.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "promptbox",
|
||||
"version": "1.0.0",
|
||||
"description": "[](https://hex.pm/packages/promptbox) [](https://hexdocs.pm/promptbox/)",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"tailwindcss": "^3.4.17"
|
||||
}
|
||||
}
|
||||
9
priv/assets/input.css
Normal file
9
priv/assets/input.css
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
@import url(https://fonts.bunny.net/css?family=alegreya:400,400i,700,700i);
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
font-family: 'Alegreya', serif;
|
||||
}
|
||||
38
priv/posts/ebb_and_flow.md
Normal file
38
priv/posts/ebb_and_flow.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
title: Ebb and Flow
|
||||
week: 1
|
||||
date: 2024-01-01
|
||||
---
|
||||
The two natural states of any changing being. As we all are, between them or reaching, life seldom finds stillness. When tides recede, we must work harder to be ourselves - don't disrupt our friendships, carry on our routines, push ourselves through it. Or rest. Allow healing, and comfort - risking the costs in connections, health, responsibilities.
|
||||
|
||||
When the pendulum swings back the challenges differ. Goodness and effort come easy. There is plenty of zest and fervour to light each day. We relish these hours, and come to expect them, though these joys can never go on forever. Even the richest - in any and all measures - experience hardship and lows. A lost opportunity; no welcome relief, a broken relationship; painful and seething. Unanticipated death knocking an unfair door. All the preventative factors in the world couldn't prepare a person for these things, nor make them easy.
|
||||
|
||||
In the flow, recall ebb, its bitterness and dark. Let it creep in just a little. That piece who finds warmth or kindness during abundance may resurface again, between thrashing waves - a small piece of light bringing hope for the end of the tunnel.
|
||||
+++
|
||||
would you like to meet up sometime quite soon
|
||||
|
||||
that was so fun, can't wait to hang again
|
||||
|
||||
let's meet up if your free this afternoon
|
||||
|
||||
no problem, dont stress, just let me know when
|
||||
|
||||
I'm so glad I spotted you at that tree
|
||||
|
||||
I love getting to spend time together
|
||||
|
||||
I'm keen, I'll let you know next time i'm free
|
||||
|
||||
I'm so sorry, I cant with this weather
|
||||
|
||||
I'm glad you called, I've been thinking of you
|
||||
|
||||
I need to say, you mean so much to me
|
||||
|
||||
can't wait to meet again, it's over due
|
||||
|
||||
no family first, I dont disagree
|
||||
|
||||
I've been missing you so much as of late
|
||||
|
||||
An ebb I pray ends, the flow I await
|
||||
38
priv/posts/second.md
Normal file
38
priv/posts/second.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
title: second one
|
||||
week: 2
|
||||
date: 2024-01-08
|
||||
---
|
||||
The two natural states of any changing being. As we all are, between them or reaching, life seldom finds stillness. When tides recede, we must work harder to be ourselves - don't disrupt our friendships, carry on our routines, push ourselves through it. Or rest. Allow healing, and comfort - risking the costs in connections, health, responsibilities.
|
||||
|
||||
When the pendulum swings back the challenges differ. Goodness and effort come easy. There is plenty of zest and fervour to light each day. We relish these hours, and come to expect them, though these joys can never go on forever. Even the richest - in any and all measures - experience hardship and lows. A lost opportunity; no welcome relief, a broken relationship; painful and seething. Unanticipated death knocking an unfair door. All the preventative factors in the world couldn't prepare a person for these things, nor make them easy.
|
||||
|
||||
In the flow, recall ebb, its bitterness and dark. Let it creep in just a little. That piece who finds warmth or kindness during abundance may resurface again, between thrashing waves - a small piece of light bringing hope for the end of the tunnel.
|
||||
+++
|
||||
would you like to meet up sometime quite soon
|
||||
|
||||
that was so fun, can't wait to hang again
|
||||
|
||||
let's meet up if your free this afternoon
|
||||
|
||||
no problem, dont stress, just let me know when
|
||||
|
||||
I'm so glad I spotted you at that tree
|
||||
|
||||
I love getting to spend time together
|
||||
|
||||
I'm keen, I'll let you know next time i'm free
|
||||
|
||||
I'm so sorry, I cant with this weather
|
||||
|
||||
I'm glad you called, I've been thinking of you
|
||||
|
||||
I need to say, you mean so much to me
|
||||
|
||||
can't wait to meet again, it's over due
|
||||
|
||||
no family first, I dont disagree
|
||||
|
||||
I've been missing you so much as of late
|
||||
|
||||
An ebb I pray ends, the flow I await
|
||||
5
src/promptbox.gleam
Normal file
5
src/promptbox.gleam
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import gleam/io
|
||||
|
||||
pub fn main() {
|
||||
io.println("Hello from promptbox!")
|
||||
}
|
||||
19
src/promptbox/files.gleam
Normal file
19
src/promptbox/files.gleam
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import gleam/order
|
||||
import promptbox/parser
|
||||
import gleam/list
|
||||
import simplifile
|
||||
|
||||
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)
|
||||
})
|
||||
use a, b <- list.sort(posts)
|
||||
|
||||
case a.week >= b.week {
|
||||
True -> order.Gt
|
||||
_ -> order.Lt
|
||||
}
|
||||
}
|
||||
6
src/promptbox/gen.gleam
Normal file
6
src/promptbox/gen.gleam
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import promptbox/web
|
||||
import promptbox/parser
|
||||
|
||||
pub fn generate_posts(posts: List(parser.Post)) {
|
||||
web.home(posts)
|
||||
}
|
||||
55
src/promptbox/parser.gleam
Normal file
55
src/promptbox/parser.gleam
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import birl
|
||||
import gleam/dict
|
||||
import gleam/int
|
||||
import gleam/list
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
import jot
|
||||
|
||||
pub type Post {
|
||||
Post(
|
||||
title: String,
|
||||
week: Int,
|
||||
date: birl.Time,
|
||||
post_p: String,
|
||||
post_j: String,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_post(content: String) -> Post {
|
||||
let assert [_, frontmatter, posts] = string.split(content, "---\n")
|
||||
let frontmatter =
|
||||
frontmatter
|
||||
|> string.split("\n")
|
||||
|> list.filter_map(fn(entry) {
|
||||
case string.contains(entry, ":") {
|
||||
False -> Error(Nil)
|
||||
True -> {
|
||||
let assert [key, value] =
|
||||
string.split(entry, ":") |> list.map(string.trim)
|
||||
|
||||
Ok(#(key, value))
|
||||
}
|
||||
}
|
||||
})
|
||||
|> dict.from_list
|
||||
|
||||
let assert [post_p, post_j] =
|
||||
string.split(posts, "\n+++\n")
|
||||
|> list.map(jot.to_html)
|
||||
|
||||
Post(
|
||||
title: result.unwrap(
|
||||
dict.get(frontmatter, "title"),
|
||||
"Title failed to parse",
|
||||
),
|
||||
week: dict.get(frontmatter, "week")
|
||||
|> result.try(int.parse)
|
||||
|> result.unwrap(-1),
|
||||
date: dict.get(frontmatter, "date")
|
||||
|> result.try(birl.parse)
|
||||
|> result.unwrap(birl.now()),
|
||||
post_p:,
|
||||
post_j:,
|
||||
)
|
||||
}
|
||||
42
src/promptbox/web.gleam
Normal file
42
src/promptbox/web.gleam
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import gleam/list
|
||||
import lustre/attribute.{attribute}
|
||||
import lustre/element/html
|
||||
import promptbox/parser
|
||||
|
||||
fn layout(contents, title) {
|
||||
html.html([attribute("lang", "en")], [
|
||||
html.head([], [
|
||||
html.meta([attribute("charset", "utf-8")]),
|
||||
html.meta([
|
||||
attribute("content", "width=device-width, initial-scale=1"),
|
||||
attribute.name("viewport"),
|
||||
]),
|
||||
html.title([], title),
|
||||
html.link([attribute.href("styles.css"), attribute.rel("stylesheet")]),
|
||||
]),
|
||||
html.body(
|
||||
[],
|
||||
list.append(contents, [html.script([attribute.src("scripts.js")], "")]),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fn prompt_element(post: parser.Post) {
|
||||
html.article([attribute.class("post")], [
|
||||
html.h3([attribute.class("post_title")], [html.text(post.title)]),
|
||||
html.div([attribute.class("grid lg:grid-cols-2 gap-6")], [
|
||||
html.div([attribute("dangerous-unescaped-html", post.post_p)], []),
|
||||
html.div([attribute("dangerous-unescaped-html", post.post_j)], []),
|
||||
])
|
||||
])
|
||||
}
|
||||
9
tailwind.config.js
Normal file
9
tailwind.config.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.gleam'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
39
test/promptbox_test.gleam
Normal file
39
test/promptbox_test.gleam
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import lustre/element
|
||||
import promptbox/gen
|
||||
import promptbox/files
|
||||
import birl
|
||||
import gleam/io
|
||||
import gleam/result
|
||||
import gleeunit
|
||||
import gleeunit/should
|
||||
import promptbox/parser
|
||||
import simplifile
|
||||
|
||||
pub fn main() {
|
||||
gleeunit.main()
|
||||
}
|
||||
|
||||
// gleeunit test functions end in `_test`
|
||||
pub fn hello_world_test() {
|
||||
let post = simplifile.read("./priv/posts/ebb_and_flow.md")
|
||||
|> result.unwrap("")
|
||||
|> parser.parse_post
|
||||
|> io.debug
|
||||
|
||||
io.debug(birl.to_date_string(post.date))
|
||||
|
||||
files.read_all_posts()
|
||||
|> io.debug
|
||||
|
||||
1
|
||||
|> should.equal(1)
|
||||
}
|
||||
|
||||
pub fn generate_test() {
|
||||
let _ = simplifile.create_directory("./dist")
|
||||
|
||||
files.read_all_posts()
|
||||
|> gen.generate_posts
|
||||
|> element.to_document_string
|
||||
|> simplifile.write(to: "./dist/index.html")
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue