vowel 0.1.46 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +82 -20
  2. package/bin.js +2 -78
  3. package/docs-source/$features/cards.md +7 -0
  4. package/docs-source/$features/editing.md +7 -0
  5. package/docs-source/$features/emoji.md +7 -0
  6. package/docs-source/$features/frontmatter.md +7 -0
  7. package/docs-source/$features/lists.md +7 -0
  8. package/docs-source/$features/navigation.md +7 -0
  9. package/docs-source/$features/rich-previews.md +7 -0
  10. package/docs-source/$features/robots.md +7 -0
  11. package/docs-source/$features/rss.md +7 -0
  12. package/docs-source/$features/sitemap.md +7 -0
  13. package/docs-source/$features/speed.md +7 -0
  14. package/docs-source/$features/static.md +7 -0
  15. package/docs-source/$features/taxonomies.md +7 -0
  16. package/docs-source/.cache.json +9 -0
  17. package/docs-source/.obsidian/app.json +3 -0
  18. package/docs-source/.obsidian/appearance.json +3 -0
  19. package/docs-source/.obsidian/core-plugins-migration.json +30 -0
  20. package/docs-source/.obsidian/core-plugins.json +20 -0
  21. package/docs-source/.obsidian/workspace.json +168 -0
  22. package/docs-source/.stackblitzrc +3 -0
  23. package/docs-source/.vercel/README.txt +11 -0
  24. package/docs-source/.vercel/project.json +1 -0
  25. package/docs-source/about.md +3 -0
  26. package/docs-source/assets/styles.css +51 -0
  27. package/docs-source/blog/home.md +5 -0
  28. package/docs-source/blog/url-ui.md +21 -0
  29. package/docs-source/docs/.votive.db +0 -0
  30. package/docs-source/docs/deploy.md +67 -0
  31. package/docs-source/docs/file-structure.md +31 -0
  32. package/docs-source/docs/folder-settings.md +23 -0
  33. package/docs-source/docs/home.md +55 -0
  34. package/docs-source/docs/images.md +10 -0
  35. package/docs-source/docs/items.md +13 -0
  36. package/docs-source/docs/pages.md +141 -0
  37. package/docs-source/docs/settings.md +4 -0
  38. package/docs-source/docs/styling.md +34 -0
  39. package/docs-source/docs/taxonomies.md +37 -0
  40. package/docs-source/home.md +42 -0
  41. package/docs-source/roadmap.md +98 -0
  42. package/docs-source/settings.md +12 -0
  43. package/extractDate.js +83 -0
  44. package/getMetadata.js +41 -0
  45. package/index.js +669 -0
  46. package/jsconfig.json +9 -17
  47. package/package.json +61 -63
  48. package/regex.js +36 -0
  49. package/{src/lib/components → stylesheets}/DefaultStyles.css +5 -5
  50. package/utils.js +10 -0
  51. package/.cache.json +0 -1
  52. package/.prettierrc +0 -8
  53. package/.vscode/settings.json +0 -3
  54. package/CHANGELOG.md +0 -79
  55. package/server.js +0 -87
  56. package/src/app.d.ts +0 -12
  57. package/src/app.html +0 -13
  58. package/src/lib/components/Breadcrumbs.svelte +0 -19
  59. package/src/lib/components/ConditionalWrapper.svelte +0 -10
  60. package/src/lib/components/DefaultStyles.svelte +0 -11
  61. package/src/lib/components/FrontMatterTaxonomy.svelte +0 -48
  62. package/src/lib/components/Frontmatter.svelte +0 -56
  63. package/src/lib/components/FrontmatterProperty.svelte +0 -78
  64. package/src/lib/components/Markdown/Image.svelte +0 -50
  65. package/src/lib/components/Markdown/Link.svelte +0 -19
  66. package/src/lib/components/Markdown/LinkPreview.svelte +0 -45
  67. package/src/lib/components/Markdown/Text.svelte +0 -6
  68. package/src/lib/components/Markdown/index.svelte +0 -147
  69. package/src/lib/components/Markdown/validators.js +0 -29
  70. package/src/lib/components/Nav.svelte +0 -40
  71. package/src/lib/components/NoStyles.svelte +0 -5
  72. package/src/lib/components/Page.svelte +0 -90
  73. package/src/lib/components/ResetStyles.svelte +0 -7
  74. package/src/lib/components/Sitemap.svelte +0 -38
  75. package/src/lib/components/TypographyStyles.svelte +0 -10
  76. package/src/lib/components/index.js +0 -12
  77. package/src/lib/index.js +0 -1
  78. package/src/lib/utilities/buildURL.js +0 -18
  79. package/src/lib/utilities/checkFileExists.js +0 -16
  80. package/src/lib/utilities/createFolderClass.js +0 -4
  81. package/src/lib/utilities/createPageClass.js +0 -6
  82. package/src/lib/utilities/getFileLabel.js +0 -35
  83. package/src/lib/utilities/getFolder.js +0 -16
  84. package/src/lib/utilities/getFolderLabel.js +0 -12
  85. package/src/lib/utilities/getMetadata.js +0 -46
  86. package/src/lib/utilities/getPage.js +0 -25
  87. package/src/lib/utilities/getPagesByFolder.js +0 -95
  88. package/src/lib/utilities/index.js +0 -22
  89. package/src/lib/utilities/isActiveLink.js +0 -12
  90. package/src/lib/utilities/isObject.js +0 -8
  91. package/src/lib/utilities/loadCache.js +0 -28
  92. package/src/lib/utilities/mutateMarkdownAST.js +0 -68
  93. package/src/lib/utilities/mutateMarkdownFrontmatter.js +0 -113
  94. package/src/lib/utilities/parseDate.js +0 -43
  95. package/src/lib/utilities/processMarkdownFiles.js +0 -243
  96. package/src/lib/utilities/readMarkdownFile.js +0 -188
  97. package/src/lib/utilities/regexPatterns.js +0 -12
  98. package/src/lib/utilities/resolveHomeDirPath.js +0 -5
  99. package/src/lib/utilities/sendWebmention.js +0 -34
  100. package/src/lib/utilities/writeCache.js +0 -14
  101. package/src/routes/$vowel/published.json/+server.js +0 -54
  102. package/src/routes/+error.svelte +0 -110
  103. package/src/routes/[...path]/+layout.server.js +0 -78
  104. package/src/routes/[...path]/+page.server.js +0 -42
  105. package/src/routes/[...path]/+page.svelte +0 -186
  106. package/src/routes/feed.xml/+server.js +0 -120
  107. package/src/routes/robots.txt/+server.js +0 -54
  108. package/src/routes/sitemap.xml/+server.js +0 -68
  109. package/static/favicon.png +0 -0
  110. package/static/styles.css +0 -0
  111. package/svelte.config.js +0 -30
  112. package/vercel.json +0 -5
  113. package/vite.config.js +0 -84
  114. /package/{src/lib/components → stylesheets}/ResetStyles.css +0 -0
  115. /package/{src/lib/components → stylesheets}/TypographyStyles.css +0 -0
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: Deploy
3
+ description: Get going.
4
+ ---
5
+
6
+ See the [quickstart](/docs/quickstart) for instructions on how to use npm.
7
+
8
+ **Note on URLs:** This guide includes instructions for Vercel, which specify a deploy option called `cleanUrls`. This will trim the `.html` extension from your deployment URLs. If you configure your own deploy, ensure you use clean URLs or your links will not work.
9
+
10
+ # GitHub
11
+
12
+ If you have a GitHub repository of Markdown files, you can deploy them on Vercel automatically on changes.
13
+
14
+ Add a `vercel.json` file to the root of your project with the following contents:
15
+
16
+ ```js
17
+ {
18
+ "cleanUrls": true,
19
+ "outputDirectory": ".output",
20
+ "buildCommand": "npx -p svelte@next -p vowel@latest npx vowel build"
21
+ }
22
+ ```
23
+
24
+ Then create a new Vercel project and connect your GitHub repository.
25
+
26
+ When you push changes to your repository, your Vercel project will automatically rebuild.
27
+
28
+ # npx
29
+
30
+ You can manually build your project with `npx`. Run this command:
31
+
32
+ ```
33
+ npx -y -p svelte@next -p vowel@latest npx vowel build
34
+ ```
35
+
36
+ The build command will create a `vercel.json` file at the root of your project with the necessary configuration for a Vercel deploy. Now deploy to Vercel:
37
+
38
+ ```
39
+ npx vercel --prod
40
+ ```
41
+
42
+ (The `--prod` flag will deploy to production.)
43
+
44
+ If you don't want to use the Vercel CLI, you can deploy the `.output` directory to any server that supports static HTML.
45
+
46
+ # npm
47
+
48
+ If you set up your project with npm, you can include a `build` command in your `package.json`:
49
+
50
+ ```diff
51
+ "scripts": {
52
+ "dev": "vowel",
53
+ + "build": "vowel build"
54
+ },
55
+ ```
56
+
57
+ Run `npm run build` (`vowel build`) to build your website.
58
+
59
+ Now you can deploy to Vercel:
60
+
61
+ ```
62
+ npx vercel --prod
63
+ ```
64
+
65
+ (The `--prod` flag will deploy to production.)
66
+
67
+ If you don't want to use the Vercel CLI, you can deploy the `.output` directory to any server that supports static HTML.
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: File structure
3
+ breadcrumb: Files
4
+ description: Organize your files.
5
+ ---
6
+
7
+ Your website is made of folders and markdown files. Every folder should have a `home.md` file. Every folder can also have a `settings.md` file to apply folder-level settings, such as the `breadcrumb`.
8
+
9
+ Almost every file and folder represents a page on your website:
10
+
11
+ - `home.md` is your homepage, `/`
12
+ - `about.md` would be your about page, `/about`
13
+ - `blog/home.md` would be your blog homepage, `/blog`
14
+ - `blog/hello-world.md` would be a blog post, `/blog/hello-world`
15
+
16
+ (File names like `Hello World.md` also seem to work fine so far.))
17
+
18
+ Even if a folder doesn't have a `home.md` file, it will still generate a page, so long as it contains any markdown files. So, if you have a `blog` folder with posts inside it, Vowel will generate a `/blog` homepage even if you don't have a `/blog/home.md` file.
19
+
20
+ There are a few special files and folders:
21
+
22
+ - `assets/` contains some static files
23
+ - `assets/styles.css` contains your stylesheet, which will be automatically applied if present
24
+ - `assets/favicon.png` is your favicon
25
+ - `templates/` is a commonly-used directory in Obsidian projects, so it will be ignored
26
+ - A `settings.md` file will not generate a page. If you want a page called `settings`, you can create a `/settings/home.md` file.
27
+ - `.cache.json`
28
+ - `.output/`
29
+ - `vercel.json`
30
+
31
+ Any files prefixed with a period will be ignored, as will any files that are not markdown.
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: Folder settings
3
+ breadcrumb: Folders
4
+ description: Configure your project.
5
+ ---
6
+
7
+ Every folder should have a `settings.md` file with one property:
8
+
9
+ - `breadcrumb`: A navigation label
10
+
11
+ At the root of the project, there should be a global settings file with the `breadcrumb` property and any of the following properties:
12
+
13
+ - All folder settings, plus
14
+ - `title`: Website title
15
+ - `robots`
16
+ - `google`: Allow Google Search indexing (`true`/`false`)
17
+ - `google_images`: Allow Google Image indexing (`true`/`false`)
18
+ - `ai`: Allow AI training (`true`/`false`)
19
+ - `domain`: Full root URL for the website domain (e.g. `https://example.com`)
20
+ - `author`: Website author credit for RSS and copyright
21
+ - `icon`: An emoji to use as the site favicon
22
+ - `slogan`: The website slogan
23
+ - `logo`: The website logo
@@ -0,0 +1,55 @@
1
+ ---
2
+ title: Documentation
3
+ description: Learn how to use Vowel.
4
+ ---
5
+
6
+ Let's get started.
7
+
8
+
9
+ ## npx
10
+
11
+ npx is the easiest way to use vowel:
12
+
13
+ ```
14
+ npx -y -p svelte@next -p vowel@latest npx vowel
15
+ ```
16
+
17
+ Vowel will attempt to generate a website based on the contents of your file.
18
+
19
+ ## npm
20
+
21
+ Create a directory. Then, open that directory and run these commands in your terminal:
22
+
23
+ ```bash
24
+ npm init --y && npm i vowel svelte@next
25
+ ```
26
+
27
+ Edit your `package.json` to add these `scripts`:
28
+
29
+ ```json
30
+ {
31
+ "dev": "vowel",
32
+ "build": "vowel build"
33
+ }
34
+ ```
35
+
36
+ Now run `npm run dev`.
37
+
38
+ ## Starter files
39
+
40
+ Create `home.md` and enter some basic information
41
+
42
+ ```md
43
+ # Your website
44
+
45
+ Lorem ipsum...
46
+ ```
47
+
48
+ Create `settings.md` and enter some basic information in the frontmatter:
49
+
50
+ ```
51
+ ---
52
+ breadcrumb: Home
53
+ domain: https://example.com
54
+ ---
55
+ ```
@@ -0,0 +1,10 @@
1
+ ---
2
+ title: Images
3
+ description: How to host images.
4
+ ---
5
+
6
+ You can put images in the `assets` folder, but this is discouraged, as it could result in a large bandwidth bill from your hosting provider.
7
+
8
+ We recommend hosting images elsewhere.
9
+
10
+ Images hosted on imgix will automatically be optimized, compressed, and formatted.
@@ -0,0 +1,13 @@
1
+ # Items
2
+
3
+ With Vowel, you can create reusable pieces of content and embed them throughout your website.
4
+
5
+ To create one, prefix a file or folder with a `$`, such as `$faqs`. The file or folder will not produce a page, but the content can be displayed on other pages, like so:
6
+
7
+ ```md
8
+ Here are answers to common questions:
9
+
10
+ /$faqs?count=10
11
+ ```
12
+
13
+ This also allows richer content, as the item will be displayed with frontmatter.
@@ -0,0 +1,141 @@
1
+ ---
2
+ title: Pages
3
+ description: Create content.
4
+ ---
5
+
6
+ The `body` element on each page has a class representing the current page. The homepage has classes `"page home"`, while a blog post might have `"page blog-hello-world"`.
7
+
8
+ Vowel attempts to construct a logical semantic HTML structure based on the files and folders in your website.
9
+
10
+ To do this, Vowel distinguishes between evergreen pages and ephemeral pages. A page with a `date` property is considered ephemeral, so it is excluded from the navigation and sitemap.
11
+
12
+ Vowel will automatically create a multi-level nav, with one level for each parent folder for the current page.
13
+
14
+ Vowel will create a full side navigation that displays all evergreen pages.
15
+
16
+ # Frontmatter
17
+
18
+ Reserved properties
19
+
20
+ - `title`: Page title
21
+ - `image`: Page image
22
+ - `description`: Page description
23
+ - `date`: Date published
24
+ - `breadcrumb`: Short identifier for the page
25
+ - `toc`: Optionally display a table of contents
26
+
27
+ Vowel will attempt to impute the type of each frontmatter property. Imputed types include:
28
+
29
+ - Links (Will generate a link preview)
30
+ - Images (will display the image)
31
+ - Date (will render a pretty date in a `time` element)
32
+
33
+ You can also use lists and objects in frontmatter.
34
+
35
+ # Markdown
36
+
37
+ Vowel comes loaded with GFM (Github-flavored Markdown):
38
+
39
+ ```
40
+ ## Autolink literals
41
+
42
+ www.example.com, https://example.com, and contact@example.com.
43
+
44
+ ## Footnote
45
+
46
+ A note[^1]
47
+
48
+ [^1]: Big note.
49
+
50
+ ## Strikethrough
51
+
52
+ ~one~ or ~~two~~ tildes.
53
+
54
+ ## Table
55
+
56
+ | a | b | c | d |
57
+ | - | :- | -: | :-: |
58
+
59
+ ## Tasklist
60
+
61
+ * [ ] to do
62
+ * [x] done
63
+
64
+ ```
65
+
66
+ Along with all standard Markdown, Vowel also allows the following special elements:
67
+
68
+ ## Rich link previews
69
+
70
+ Paste a URL on its own line (e.g. `https://example.com`).
71
+
72
+ ## Internal link previews
73
+
74
+ Paste a relative path to a page (e.g. `/about`).
75
+
76
+ The link will be rendered as an `article` element with a class representing the linked path (e.g. `page-blog-hello-world`).
77
+
78
+ ## Page lists
79
+
80
+ A relative path to a folder with a `count` parameter (e.g. `/blog?count=2`). This will exclude the `home.md` file for the folder. In this example, it would return the `/blog/hello-world.md` file but not `/blog/home.md`.
81
+
82
+ The page list will order pages first by date in reverse chronology (newest to oldest) and then alphabetically (a to z).
83
+
84
+ The list will be rendered as `article` elements (see above) in a `section` element. The `section` element will have a class representing the folder path (e.g. `folder-blog`).
85
+
86
+ ## Headings
87
+
88
+ If your document starts with an `h1` (`#`) and has no `title` property, the `h1` will be used as the meta title.
89
+
90
+ If your document includes `h1`s after the title, all headings will be demoted one level (`#` to `h2`, `##` to `h3`).
91
+
92
+ ## Description
93
+
94
+ If your document doesn't include a `description`, a meta description will be extracted from the text.
95
+
96
+ ## Notes
97
+
98
+ Highlight information with note boxes:
99
+
100
+ ```
101
+ :::tip
102
+ Use `tip` for power-ups.
103
+ :::
104
+
105
+ :::note
106
+ Use `note` for good-to-know information.
107
+ :::
108
+
109
+ :::important
110
+ Use `important` to help guide your user down the right path.
111
+ :::
112
+
113
+ :::warning
114
+ Use `warning` to help your user avoid the wrong path.
115
+ :::
116
+
117
+ :::caution
118
+ Use `caution` to alert the user before they perform a destructive action.
119
+ :::
120
+
121
+ ```
122
+
123
+ :::tip
124
+ Use `tip` for power-ups.
125
+ :::
126
+
127
+ :::note
128
+ Use `note` for good-to-know information.
129
+ :::
130
+
131
+ :::important
132
+ Use `important` to help guide your user down the right path.
133
+ :::
134
+
135
+ :::warning
136
+ Use `warning` to help your user avoid the wrong path.
137
+ :::
138
+
139
+ :::caution
140
+ Use `caution` to alert the user before they perform a destructive action.
141
+ :::
@@ -0,0 +1,4 @@
1
+ ---
2
+ title: Documentation
3
+ breadcrumb: Docs
4
+ ---
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Styling
3
+ description: Add styles to your website.
4
+ ---
5
+
6
+ Vowel allows styling through themes and vanilla CSS.
7
+
8
+ ## Themes
9
+
10
+ Vowel includes a default theme, but you can disable this in your root `settings.md` file:
11
+ ```
12
+ theme: none
13
+ ```
14
+ You also have two other themes available:
15
+ - `reset`: A classic CSS reset
16
+ - `typography`: A classic CSS reset, plus some basic text styling
17
+
18
+ ## CSS
19
+
20
+ Create an `assets/styles.css` file for your styling. We recommend using a style framework like Pico or Open Props. You can simply download their stylesheet and either copy-paste it into your own or include it in `assets/` and `import` it into `assets/styles.css`.
21
+
22
+ For some inspiration on how to style semantic HTML, check out Swyx's [Spark Joy repository](https://github.com/swyxio/spark-joy).
23
+
24
+ :::tip
25
+
26
+ You can combine a theme with your own CSS. Feel free to use the `reset` or `typography` theme as a starting point and build from there.
27
+
28
+ :::
29
+
30
+ :::warning
31
+
32
+ This project is still in development, so the generated markup is likely to change quickly and without warning, which will likely affect your styles.
33
+
34
+ :::
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: Taxonomies
3
+ description: Create tags, categories, and authors.
4
+ ---
5
+
6
+ If the key for a frontmatter property matches a folder at the root of your project, Vowel will attempt to treat it as a taxonomy and link to the respective page.
7
+
8
+ For instance, in this folder structure:
9
+
10
+ ```
11
+ .
12
+ ├── home.md
13
+ ├── design.md
14
+ ├── recipes.md
15
+ └── category/
16
+ ├── inspiration.md
17
+ └── lifestyle.md
18
+ ```
19
+
20
+ You can write the following frontmatter in `design.md`:
21
+
22
+ ```
23
+ ---
24
+ title: Design
25
+ category: inspiration
26
+ ---
27
+ ```
28
+
29
+ Vowel will render the property as a link to `/category/inspiration`.
30
+
31
+ Then, in `category/inspiration.md` (or anywhere) you can display all inspiration posts with a post list:
32
+
33
+ ```
34
+ /?property=category.inspiration
35
+ ```
36
+
37
+ This allows you to create author pages, category pages.
@@ -0,0 +1,42 @@
1
+ # Home
2
+
3
+ Vowel is a very simple Markdown- and CSS-based website generator.
4
+
5
+ :::tip
6
+
7
+ Start editing this page with one click by [opening it on StackBlitz](https://stackblitz.com/~/github.com/samlfair/vowel-site?file=home.md).
8
+
9
+ :::
10
+
11
+ To try Vowel out on your own computer, `cd` into a directory of markdown files and run:
12
+
13
+ ```
14
+ npx -y -p svelte@next -p vowel@latest npx vowel
15
+ ```
16
+
17
+ (This `npx` command forces the Svelte 5 peer depedency, without which the app will throw an error.)
18
+
19
+ ![A woman dancing](https://littlefair.imgix.net/florence-tango.jpeg?width=2048&auto=format%2Ccompress) Here's a photo
20
+
21
+ Vowel is a minimal website framework for developers who love to write CSS and read RSS.
22
+
23
+ > Here's a lovely block quote.
24
+
25
+ Vowel will generate a feature-rich HTML website from a directory of markdown files. The output is plain HTML. You can style it however you want with your own CSS.
26
+
27
+ :::warning
28
+
29
+ This project is still in early development. There are many bugs and the API is changing quickly.
30
+
31
+ :::
32
+
33
+ Vowel is created by Sam Littlefair. If you have questions or comments, [reach out to me on Twitter](https://twitter.com/samlfair).
34
+
35
+
36
+ # Features
37
+
38
+ /$features?count=25
39
+
40
+ # Try it
41
+
42
+ /docs
@@ -0,0 +1,98 @@
1
+ ---
2
+ description: What's planned.
3
+ ---
4
+
5
+ # Roadmap
6
+
7
+ ## MVP
8
+
9
+ - [x] Add all element types supported in Obsidian to markdown
10
+ - [x] Add rich link previews
11
+ - [x] Add RSS
12
+ - [x] Add robots.txt
13
+ - [x] AI
14
+ - [x] Search
15
+ - [x] Image
16
+ - [x] Typing
17
+ - [x] Add sitemap
18
+ - [x] Make taxonomies linkable in frontmatter (if a corresponding folder exists)
19
+ - [x] Add header metadata (meta tags)
20
+ - [x] CSS handling
21
+ - [x] Favicon handling
22
+ - [x] Docs
23
+ - [x] Build action
24
+
25
+ ## V2
26
+
27
+ - [x] Images as `<figure>`s
28
+ - [x] Frontmatter interpolation (title and description)
29
+ - [x] CSS default
30
+ - [x] Better favicon and styles handling
31
+ - [x] Ignore README files
32
+ - [x] Include breadcrumbs in page titles
33
+ - [x] Add hidden routes (`$`)
34
+ - [x] Image alt text
35
+ - [x] Deploy action (Vercel)
36
+ - [x] Add anchor links for headings
37
+ - [x] Figure out how to stop components from remounting on every change
38
+ - [x] Demote headings global option (headings are now demoted intelligently)
39
+ - [x] Taxonomy lists
40
+ - [x] ~~Strikethrough~~
41
+ - [x] Checklists
42
+ - [x] GitHub-style notes
43
+ - [x] Footnotes
44
+ - [x] Better create/delete handling in HMR
45
+ - [x] Disable default styles option
46
+ - [x] Better theme CSS handling
47
+ - [x] Create style reset theme
48
+ - [x] Debug settings page HMR (temporary fix with full-page refresh)
49
+ - [x] Fix checklist boxes
50
+ - [x] Handle SVGs properly
51
+ - [x] Slogan in homepage `<title>`
52
+ - [x] Prioritize `title` and `h1` for meta title
53
+ - [x] Prioritize `title` over `h1` for thumbnails
54
+ - [x] Tables of contents
55
+ - [x] Add a default 404 page
56
+
57
+ ## V3
58
+
59
+ - [ ] Fallback homepages
60
+ - [ ] Date format customizing
61
+ - [ ] Init CLI
62
+ - Option for destructive actions
63
+ - Create homepage
64
+ - Create CSS file
65
+ - [ ] ::Mark::
66
+ - [ ] Frontmatter interpolation (image)
67
+ - [ ] Add more header metadata?
68
+ - [ ] Define folder settings
69
+ - [ ] Title
70
+ - [ ] Breadrumb
71
+ - [x] Define special page properties
72
+ - [x] Title
73
+ - [x] Description
74
+ - [x] Meta image
75
+ - [x] Date
76
+ - [ ] Modified date
77
+ - [ ] Tags
78
+ - [ ] Author/Authors
79
+ - [ ] Make file names kebab-cased for URLs and links
80
+ - [ ] Code highlighter
81
+ - [ ] Add in-browser search
82
+ - [ ] Make RSS optional
83
+ - [ ] Pagination
84
+
85
+ ## Wish list
86
+
87
+ - [ ] Automatic file creation
88
+ - [ ] Image serving and optimization
89
+ - [ ] GUI
90
+ - [ ] More deploy actions
91
+ - [ ] Optional JSON interactivity (ratings, comments, SubPubHub)
92
+ - [ ] Redirects
93
+ - [ ] Advanced markdown
94
+ - [ ] Highlight
95
+ - [ ] Sanitize
96
+ - [ ] Mermaid
97
+ - [ ] Math
98
+ - [ ] Wikilinks
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Vowel
3
+ slogan: The easiest way to code a website
4
+ breadcrumb: Home
5
+ domain: 'https://getvowel.com'
6
+ author: Sam Littlefair
7
+ icon: 🔥
8
+ robots:
9
+ google: true
10
+ google_images: true
11
+ ai: true
12
+ ---
package/extractDate.js ADDED
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @param {string} text
3
+ */
4
+ function extractDate(text) {
5
+ const dateRegex = /(?:\b(?<first_segment>(?<first_MMM_or_MMMM>January|February|March|April|May|June|July|August|September|October|November|December|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec)|(?<first_YYYY>\d\d\d\d)|(?<first_do>(?:\d|[0-3]\d)(?:st|nd|rd|th))|(?<first_dd_or_MM_or_yy>[0-3]\d)|(?<first_d_or_M>\d))(?<first_delimiter>\.| |, |\/|-)?)(?:\b(?<second_segment>(?<second_MMM_or_MMMM>January|February|March|April|May|June|July|August|September|October|November|December|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec)|(?<second_YYYY>\d\d\d\d)|(?<second_do>(\d\d)(:?st|nd|rd|th))|(?<second_dd_or_MM_or_yy>[0-3]\d)|(?<second_d_or_M>\d))(?<second_delimiter>\.| |, |\/|-)?)(?:\b(?<third_segment>(?<third_MMM_or_MMMM>January|February|March|April|May|June|July|August|September|October|November|December|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec)|(?<third_YYYY>\d\d\d\d)|(?<third_do>(\d\d)(?:st|nd|rd|th))|(?<third_dd_or_MM_or_yy>[0-3]\d)|(?<third_d_or_M>\d)))(?<time>(?<time_delimiter>T|\ | at )(?<H_or_HH>[0-2]?\d):(?<MM>[0-6]\d)(?::(?<SS>00))?(?:\.(?<SSS>\d\d\d))?(?<Z>Z|(?:\+(\d\d):(\d\d)))?(?<meridiam_indicator>am|pm)?)?/i
6
+
7
+ const dateMatch = dateRegex.exec(text)
8
+ if(!dateMatch) return
9
+
10
+ const data = {
11
+ rawDate: dateMatch[0],
12
+ year: null,
13
+ month: null,
14
+ day: null,
15
+ hours: null,
16
+ minutes: null,
17
+ seconds: null,
18
+ meridiam_indicator: null,
19
+ timezone: null
20
+ }
21
+
22
+ const { groups } = dateMatch
23
+
24
+ const knownYear = groups.first_YYYY || groups.second_YYYY || groups.third_YYYY
25
+ const knownMonth = groups.first_MMM_or_MMMM || groups.second_MMM_or_MMMM || groups.third_MMM_or_MMMM
26
+ const knownDay = groups.first_do || groups.second_do || groups.third_do
27
+ const firstUnknowns = groups.first_dd_or_MM_or_yy || groups.first_d_or_M
28
+ const secondUnknowns = groups.second_dd_or_MM_or_yy || groups.second_d_or_M
29
+ const thirdUnknowns = groups.third_dd_or_MM_or_yy || groups.third_d_or_M
30
+ const allUnknowns = firstUnknowns || secondUnknowns || thirdUnknowns
31
+
32
+ if (knownYear) {
33
+ data.year = knownYear
34
+ if (knownMonth) {
35
+ data.month = knownMonth
36
+ data.day = knownDay || allUnknowns
37
+ } else if (knownDay) {
38
+ data.month = allUnknowns
39
+ data.day = knownDay
40
+ } else {
41
+ if (firstUnknowns) {
42
+ data.day = firstUnknowns
43
+ data.month = secondUnknowns
44
+ } else if (thirdUnknowns) {
45
+ data.month = secondUnknowns
46
+ data.day = thirdUnknowns
47
+ } else {
48
+ return false
49
+ }
50
+ }
51
+ } else if (knownMonth) {
52
+ data.month = knownMonth
53
+ if (knownDay) {
54
+ data.day = knownDay
55
+ data.year = allUnknowns
56
+ } else {
57
+ console.warn("The date parser has encountered a ambiguous date with a long month and a short year (e.g. `2 June 13`). Rewrite the date in a standard format.")
58
+ return false
59
+ }
60
+ } else if (knownDay) {
61
+ console.warn("The date parser has encountered an ambigous date format with an ordinal date, a short month, and a short year (e.g. 5th 06/24). Rewrite the date in a standard format.")
62
+ return false
63
+ } else {
64
+ data.year = "20" + groups.first_dd_or_MM_or_yy
65
+ data.month = groups.second_dd_or_MM_or_yy || groups.second_d_or_M
66
+ data.day = groups.third_dd_or_MM_or_yy || groups.third_d_or_M
67
+ }
68
+ if (groups.time) {
69
+ const isPM = /pm/i.test(groups.meridiam_indicator)
70
+ data.hours = isPM ? Number(groups.H_or_HH) + 12 : groups.H_or_HH
71
+ data.minutes = groups.MM
72
+ data.seconds = groups.SS || 0
73
+ data.timezone = groups.Z
74
+ }
75
+
76
+ const time = groups.time ? `${data.hours}:${data.minutes}:${data.seconds}${data.timezone || ""}` : null
77
+ const dateString = `${data.year} ${data.month} ${data.day}${time ? " " + time : ""}`
78
+
79
+ return new Date(dateString)
80
+ }
81
+
82
+ export default extractDate
83
+