prt 0.3.0
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.
- checksums.yaml +7 -0
- data/.githooks/pre-commit +17 -0
- data/.github/workflows/ci.yml +29 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.rubocop.yml +28 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CLAUDE.md +8 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +340 -0
- data/Rakefile +26 -0
- data/bin/setup +11 -0
- data/exe/parrot +12 -0
- data/lib/helpers.rb +19 -0
- data/lib/parrot/commands/build.rb +1274 -0
- data/lib/parrot/commands/new.rb +25 -0
- data/lib/parrot/commands/post.rb +83 -0
- data/lib/parrot/commands/serve.rb +129 -0
- data/lib/parrot/constants.rb +45 -0
- data/lib/parrot/file_cache.rb +45 -0
- data/lib/parrot/logger.rb +23 -0
- data/lib/parrot/metadata.rb +4 -0
- data/lib/parrot/runner.rb +29 -0
- data/lib/parrot/template_handler.rb +19 -0
- data/lib/parrot.rb +120 -0
- data/parrot.gemspec +36 -0
- data/skel/.gitignore +3 -0
- data/skel/config.yaml +68 -0
- data/skel/css/app.scss +189 -0
- data/skel/images/.keep +0 -0
- data/skel/images/apple-touch-icon.png +0 -0
- data/skel/images/favicon.ico +0 -0
- data/skel/images/favicon.svg +40 -0
- data/skel/images/parrot.jpeg +0 -0
- data/skel/javascripts/app.js +37 -0
- data/skel/public/.keep +0 -0
- data/skel/views/404.md +7 -0
- data/skel/views/about.md +17 -0
- data/skel/views/layout.html.erb +72 -0
- data/skel/views/posts/about_parrot.md +63 -0
- data/skel/views/posts/sample.md +37 -0
- data/spec/parrot/commands/build_spec.rb +747 -0
- data/spec/parrot/commands/new_spec.rb +43 -0
- data/spec/parrot/commands/post_spec.rb +80 -0
- data/spec/parrot/commands/serve_spec.rb +66 -0
- data/spec/parrot/logger_spec.rb +39 -0
- data/spec/parrot/metadata_spec.rb +11 -0
- data/spec/parrot/runner_spec.rb +28 -0
- data/spec/parrot_spec.rb +37 -0
- data/spec/spec_helper.rb +7 -0
- metadata +237 -0
data/skel/css/app.scss
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Write your custom css here
|
|
2
|
+
|
|
3
|
+
// Simple.css switches themes only via prefers-color-scheme. These let the
|
|
4
|
+
// header toggle (data-theme on <html>) override the system choice either way.
|
|
5
|
+
// The colors mirror simple.css's own light and dark palettes.
|
|
6
|
+
:root[data-theme="light"] {
|
|
7
|
+
color-scheme: light;
|
|
8
|
+
--bg: #fff;
|
|
9
|
+
--accent-bg: #f5f7ff;
|
|
10
|
+
--text: #212121;
|
|
11
|
+
--text-light: #585858;
|
|
12
|
+
--accent: #0d47a1;
|
|
13
|
+
--accent-hover: #1266e2;
|
|
14
|
+
--code: #d81b60;
|
|
15
|
+
--preformatted: #444;
|
|
16
|
+
--disabled: #efefef;
|
|
17
|
+
|
|
18
|
+
img,
|
|
19
|
+
video {
|
|
20
|
+
opacity: 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:root[data-theme="dark"] {
|
|
25
|
+
color-scheme: dark;
|
|
26
|
+
--bg: #212121;
|
|
27
|
+
--accent-bg: #2b2b2b;
|
|
28
|
+
--text: #dcdcdc;
|
|
29
|
+
--text-light: #ababab;
|
|
30
|
+
--accent: #ffb300;
|
|
31
|
+
--accent-hover: #ffe099;
|
|
32
|
+
--code: #f06292;
|
|
33
|
+
--preformatted: #ccc;
|
|
34
|
+
--disabled: #111;
|
|
35
|
+
|
|
36
|
+
img,
|
|
37
|
+
video {
|
|
38
|
+
opacity: 0.8;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.site-header {
|
|
43
|
+
position: relative;
|
|
44
|
+
text-align: center;
|
|
45
|
+
padding: 2.5rem 1rem 2rem;
|
|
46
|
+
margin-bottom: 2rem;
|
|
47
|
+
border-bottom: 1px solid var(--border);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.theme-toggle {
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: 1rem;
|
|
53
|
+
right: 1rem;
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
padding: 0.4rem;
|
|
56
|
+
border: 1px solid var(--border);
|
|
57
|
+
border-radius: 50%;
|
|
58
|
+
background: transparent;
|
|
59
|
+
color: var(--text-light);
|
|
60
|
+
|
|
61
|
+
&:enabled:hover {
|
|
62
|
+
background: transparent;
|
|
63
|
+
border-color: var(--accent);
|
|
64
|
+
color: var(--accent);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
svg {
|
|
68
|
+
width: 1.1rem;
|
|
69
|
+
height: 1.1rem;
|
|
70
|
+
fill: none;
|
|
71
|
+
stroke: currentColor;
|
|
72
|
+
stroke-width: 2;
|
|
73
|
+
stroke-linecap: round;
|
|
74
|
+
stroke-linejoin: round;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Show the theme you'd switch to: a moon in light mode, a sun in dark mode.
|
|
78
|
+
.icon-sun {
|
|
79
|
+
display: none;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@mixin show-sun {
|
|
84
|
+
.theme-toggle .icon-moon {
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.theme-toggle .icon-sun {
|
|
89
|
+
display: block;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:root[data-theme="dark"] {
|
|
94
|
+
@include show-sun;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@media (prefers-color-scheme: dark) {
|
|
98
|
+
:root:not([data-theme="light"]) {
|
|
99
|
+
@include show-sun;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.site-name {
|
|
104
|
+
display: inline-block;
|
|
105
|
+
font-size: 2rem;
|
|
106
|
+
font-weight: 700;
|
|
107
|
+
letter-spacing: -0.02em;
|
|
108
|
+
text-decoration: none;
|
|
109
|
+
color: var(--text);
|
|
110
|
+
|
|
111
|
+
&:hover {
|
|
112
|
+
color: var(--accent);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.tagline {
|
|
117
|
+
margin: 0.4rem auto 0;
|
|
118
|
+
color: var(--text-light);
|
|
119
|
+
font-size: 1.05rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.site-nav {
|
|
123
|
+
margin-top: 1rem;
|
|
124
|
+
font-size: 0.95rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.back-link {
|
|
128
|
+
margin-top: 0;
|
|
129
|
+
margin-bottom: 1.5rem;
|
|
130
|
+
font-size: 0.9rem;
|
|
131
|
+
|
|
132
|
+
a {
|
|
133
|
+
text-decoration: none;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// The date and category line Parrot adds under a post's title.
|
|
138
|
+
.post-meta {
|
|
139
|
+
margin-top: -0.5rem;
|
|
140
|
+
color: var(--text-light);
|
|
141
|
+
font-size: 0.95rem;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// A post's category, linking to that category's listing: under a post's
|
|
145
|
+
// title, and in listings via list_format's {post_category_tag}.
|
|
146
|
+
.category-tag {
|
|
147
|
+
display: inline-block;
|
|
148
|
+
padding: 0 0.5rem;
|
|
149
|
+
border: 1px solid var(--border);
|
|
150
|
+
border-radius: 1rem;
|
|
151
|
+
font-size: 0.85rem;
|
|
152
|
+
line-height: 1.6;
|
|
153
|
+
text-decoration: none;
|
|
154
|
+
vertical-align: middle;
|
|
155
|
+
|
|
156
|
+
&,
|
|
157
|
+
&:visited {
|
|
158
|
+
color: var(--text-light);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
&:hover {
|
|
162
|
+
border-color: var(--accent);
|
|
163
|
+
color: var(--accent);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.post-tags {
|
|
168
|
+
margin-top: 2rem;
|
|
169
|
+
font-size: 0.9rem;
|
|
170
|
+
color: var(--text-light);
|
|
171
|
+
|
|
172
|
+
.tag {
|
|
173
|
+
display: inline-block;
|
|
174
|
+
padding: 0.1rem 0.5rem;
|
|
175
|
+
border: 1px solid var(--border);
|
|
176
|
+
border-radius: 1rem;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.pagination {
|
|
181
|
+
display: flex;
|
|
182
|
+
justify-content: space-between;
|
|
183
|
+
margin-top: 2rem;
|
|
184
|
+
font-size: 0.9rem;
|
|
185
|
+
|
|
186
|
+
a {
|
|
187
|
+
text-decoration: none;
|
|
188
|
+
}
|
|
189
|
+
}
|
data/skel/images/.keep
ADDED
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="badge" x1="0" y1="0" x2="0" y2="1">
|
|
4
|
+
<stop offset="0%" stop-color="#4bb45f"/>
|
|
5
|
+
<stop offset="100%" stop-color="#2f9e4d"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<rect width="64" height="64" rx="12" fill="url(#badge)"/>
|
|
10
|
+
|
|
11
|
+
<!-- crest -->
|
|
12
|
+
<g fill="#ffd23f" stroke="#e0a91f" stroke-width="1.6" stroke-linejoin="round">
|
|
13
|
+
<path d="M26 13 C24 8 26 5 30 4 C31 9 30 13 28 16 Z"/>
|
|
14
|
+
<path d="M32 11 C32 5 35 3 39 4 C39 9 37 13 35 16 Z"/>
|
|
15
|
+
<path d="M38 13 C40 8 44 6 47 7 C45 12 42 15 40 17 Z"/>
|
|
16
|
+
</g>
|
|
17
|
+
|
|
18
|
+
<!-- head -->
|
|
19
|
+
<circle cx="32" cy="36" r="22.5" fill="#57c06a" stroke="#1f7a3c" stroke-width="2.6"/>
|
|
20
|
+
|
|
21
|
+
<!-- face -->
|
|
22
|
+
<path d="M32 19 C43 19 49 27 49 36 C49 46 42 52 32 52 C23 52 16 46 15 37 C14 27 21 19 32 19 Z" fill="#ffd94a"/>
|
|
23
|
+
|
|
24
|
+
<!-- cheeks -->
|
|
25
|
+
<circle cx="19" cy="40" r="4.2" fill="#ff9fb2" opacity="0.7"/>
|
|
26
|
+
<circle cx="45" cy="40" r="4.2" fill="#ff9fb2" opacity="0.7"/>
|
|
27
|
+
|
|
28
|
+
<!-- eyes (no outline, wide-set so they stay cute, not spectacled, when tiny) -->
|
|
29
|
+
<circle cx="23" cy="33" r="7" fill="#ffffff"/>
|
|
30
|
+
<circle cx="41" cy="33" r="7" fill="#ffffff"/>
|
|
31
|
+
<circle cx="24.4" cy="34" r="4" fill="#2b2b2b"/>
|
|
32
|
+
<circle cx="39.6" cy="34" r="4" fill="#2b2b2b"/>
|
|
33
|
+
<circle cx="22.6" cy="32.2" r="1.5" fill="#ffffff"/>
|
|
34
|
+
<circle cx="37.8" cy="32.2" r="1.5" fill="#ffffff"/>
|
|
35
|
+
|
|
36
|
+
<!-- beak -->
|
|
37
|
+
<path d="M30 41 C28.5 41 27.5 43.5 28.5 46 C29.5 49.5 34 50.5 36.5 47.5 C38.5 45.5 38.5 42 36.5 40.5 C35 39.5 32 41 30 41 Z"
|
|
38
|
+
fill="#ff8f3f" stroke="#d9691f" stroke-width="2" stroke-linejoin="round"/>
|
|
39
|
+
<path d="M29.5 44.5 C30.5 47 32.5 48.5 34.5 47.5 C33 50 30.5 49 29 46.5 Z" fill="#e0641c"/>
|
|
40
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Light/dark toggle. The saved choice is applied early by an inline script in
|
|
2
|
+
// layout.html.erb; this wires up the header button and remembers new choices.
|
|
3
|
+
(function () {
|
|
4
|
+
var root = document.documentElement;
|
|
5
|
+
var button = document.querySelector('.theme-toggle');
|
|
6
|
+
if (!button) return;
|
|
7
|
+
|
|
8
|
+
var systemDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
9
|
+
var themeColors = { light: '#ffffff', dark: '#212121' };
|
|
10
|
+
|
|
11
|
+
function currentTheme() {
|
|
12
|
+
return root.dataset.theme || (systemDark.matches ? 'dark' : 'light');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function render() {
|
|
16
|
+
var theme = currentTheme();
|
|
17
|
+
button.setAttribute('aria-pressed', theme === 'dark');
|
|
18
|
+
button.title = theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode';
|
|
19
|
+
// Only override the browser chrome color once the visitor has picked a theme.
|
|
20
|
+
if (root.dataset.theme) {
|
|
21
|
+
document.querySelectorAll('meta[name="theme-color"]').forEach(function (meta) {
|
|
22
|
+
meta.content = themeColors[theme];
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button.addEventListener('click', function () {
|
|
28
|
+
var theme = currentTheme() === 'dark' ? 'light' : 'dark';
|
|
29
|
+
root.dataset.theme = theme;
|
|
30
|
+
try { localStorage.setItem('theme', theme); } catch (e) {}
|
|
31
|
+
render();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
systemDark.addEventListener('change', render);
|
|
35
|
+
button.hidden = false;
|
|
36
|
+
render();
|
|
37
|
+
})();
|
data/skel/public/.keep
ADDED
|
File without changes
|
data/skel/views/404.md
ADDED
data/skel/views/about.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
title: About
|
|
3
|
+
description: Who writes this blog, and where else to find them.
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# About
|
|
7
|
+
|
|
8
|
+
Write a few lines about yourself and this blog here. This page is built from
|
|
9
|
+
`views/about.md` and linked from the navigation at the top of every page.
|
|
10
|
+
|
|
11
|
+
## Find me elsewhere
|
|
12
|
+
|
|
13
|
+
- [GitHub](https://github.com/your-username)
|
|
14
|
+
- [X](https://x.com/your-username)
|
|
15
|
+
- [LinkedIn](https://www.linkedin.com/in/your-username)
|
|
16
|
+
- [Mastodon](https://mastodon.social/@your-username)
|
|
17
|
+
- [RSS feed](feed.xml)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
7
|
+
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff">
|
|
8
|
+
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#212121">
|
|
9
|
+
<!-- Warm up the connections to the CDNs the page pulls from. Add
|
|
10
|
+
https://www.googletagmanager.com here too if you wire up GTM/Analytics. -->
|
|
11
|
+
<link rel="preconnect" href="https://cdn.simplecss.org" crossorigin>
|
|
12
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
|
13
|
+
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
|
|
14
|
+
<link rel="icon" type="image/x-icon" href="images/favicon.ico" sizes="16x16 32x32 48x48">
|
|
15
|
+
<link rel="icon" type="image/svg+xml" href="images/favicon.svg">
|
|
16
|
+
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
|
|
17
|
+
<!-- Apply a saved light/dark choice before the first paint, so the page
|
|
18
|
+
doesn't flash the system theme first. Without one, the system theme wins. -->
|
|
19
|
+
<script>
|
|
20
|
+
try {
|
|
21
|
+
var theme = localStorage.getItem('theme');
|
|
22
|
+
if (theme === 'light' || theme === 'dark') document.documentElement.dataset.theme = theme;
|
|
23
|
+
} catch (e) {}
|
|
24
|
+
</script>
|
|
25
|
+
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
|
|
26
|
+
<link rel="stylesheet" href="app.css">
|
|
27
|
+
<script src="app.js" defer></script>
|
|
28
|
+
<link rel="alternate" type="application/rss+xml" title="Parrot" href="feed.xml">
|
|
29
|
+
<meta name="generator" content="Parrot">
|
|
30
|
+
<meta name="author" content="Your name">
|
|
31
|
+
<!-- Site-wide fallback description. Each post overrides it from its header
|
|
32
|
+
`description` (or its first paragraph) at build time. -->
|
|
33
|
+
<meta name="description" content="A blog built with Parrot.">
|
|
34
|
+
<!-- Set this to your site's URL. Parrot appends each page's path when building. -->
|
|
35
|
+
<meta property="og:url" content="https://example.com">
|
|
36
|
+
<link rel="canonical" href="https://example.com">
|
|
37
|
+
<meta property="og:type" content="website">
|
|
38
|
+
<meta property="og:site_name" content="Parrot">
|
|
39
|
+
<meta property="og:title" content="Parrot">
|
|
40
|
+
<meta property="og:description" content="A blog built with Parrot.">
|
|
41
|
+
<meta property="og:locale" content="en_US">
|
|
42
|
+
<!-- Link-preview image. A relative images/… path is copied to the build and
|
|
43
|
+
rewritten to an absolute URL; you can also use a full URL. -->
|
|
44
|
+
<meta property="og:image" content="images/parrot.jpeg">
|
|
45
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
46
|
+
<meta name="twitter:description" content="A blog built with Parrot.">
|
|
47
|
+
<title>Parrot</title>
|
|
48
|
+
</head>
|
|
49
|
+
<body>
|
|
50
|
+
<header class="site-header">
|
|
51
|
+
<button class="theme-toggle" type="button" aria-label="Toggle dark mode" hidden>
|
|
52
|
+
<svg class="icon-moon" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
|
|
53
|
+
<svg class="icon-sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
|
|
54
|
+
</button>
|
|
55
|
+
<a class="site-name" href="/">Your name</a>
|
|
56
|
+
<p class="tagline">Your tagline</p>
|
|
57
|
+
<nav class="site-nav">
|
|
58
|
+
<a href="/">Home</a>
|
|
59
|
+
<a href="/categories.html">Categories</a>
|
|
60
|
+
<a href="/about.html">About</a>
|
|
61
|
+
</nav>
|
|
62
|
+
</header>
|
|
63
|
+
|
|
64
|
+
<main>
|
|
65
|
+
<%= yield %>
|
|
66
|
+
</main>
|
|
67
|
+
|
|
68
|
+
<footer>
|
|
69
|
+
Made with love using <a href="https://github.com/deepakkumarnd/parrot">Parrot</a>
|
|
70
|
+
</footer>
|
|
71
|
+
</body>
|
|
72
|
+
</html>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
title: About Parrot
|
|
3
|
+
date: 08/09/2026
|
|
4
|
+
lang: en
|
|
5
|
+
tags: parrot, markdown
|
|
6
|
+
category: Guides
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# About Parrot
|
|
10
|
+
|
|
11
|
+
Parrot turns a folder of Markdown into a static blog. This post is also a
|
|
12
|
+
cheat sheet: it shows the formatting you can use in any `views/posts/*.md`
|
|
13
|
+
file.
|
|
14
|
+
|
|
15
|
+
## Headings and text
|
|
16
|
+
|
|
17
|
+
Use `#` for the post title and `##` / `###` for sections, like the ones on
|
|
18
|
+
this page. Inline styles work too: **bold**, _italic_, and `inline code`.
|
|
19
|
+
|
|
20
|
+
## Code blocks
|
|
21
|
+
|
|
22
|
+
Tag a fenced block with a language and Parrot highlights it (Monokai theme by
|
|
23
|
+
default — change `HIGHLIGHT_THEME` in `lib/parrot/constants.rb`):
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
class Greeter
|
|
27
|
+
def initialize(name)
|
|
28
|
+
@name = name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def greet
|
|
32
|
+
puts "Hello, #{@name}!"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Greeter.new("Parrot").greet
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
parrot new blog
|
|
41
|
+
cd blog
|
|
42
|
+
parrot serve
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
An untagged, indented block renders as plain preformatted text:
|
|
46
|
+
|
|
47
|
+
$ parrot build
|
|
48
|
+
|
|
49
|
+
## Math
|
|
50
|
+
|
|
51
|
+
LaTeX between `$$ … $$` is rendered with MathJax. Inline, it flows with the
|
|
52
|
+
sentence: $$e^{i\pi} + 1 = 0$$.
|
|
53
|
+
|
|
54
|
+
On its own line it becomes a display block:
|
|
55
|
+
|
|
56
|
+
$$
|
|
57
|
+
W = W - \text{lr} \cdot \frac{\partial L}{\partial W}
|
|
58
|
+
$$
|
|
59
|
+
|
|
60
|
+
## Links between posts
|
|
61
|
+
|
|
62
|
+
Link to another post by its Markdown filename and Parrot rewrites it to the
|
|
63
|
+
built page at build time: [read the next post](#post2.md).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
title: Your second post
|
|
3
|
+
date: 08/09/2026
|
|
4
|
+
lang: en
|
|
5
|
+
category: Guides
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
# Your second post
|
|
9
|
+
|
|
10
|
+
This is `views/posts/post2.md`. Edit it, or delete it and drop your own
|
|
11
|
+
`.md` files into `views/posts/` — each one is built into its own page and can
|
|
12
|
+
be listed from `views/index.md`.
|
|
13
|
+
|
|
14
|
+
For headings, code blocks and LaTeX math, see [About Parrot](#post1.md). This
|
|
15
|
+
post covers the rest of the everyday Markdown.
|
|
16
|
+
|
|
17
|
+
## Images
|
|
18
|
+
|
|
19
|
+
Keep image files in `images/` and link them with a relative path. Parrot copies
|
|
20
|
+
the ones a page actually uses into `public/images/`:
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
## Lists, quotes and tables
|
|
25
|
+
|
|
26
|
+
- A bullet list
|
|
27
|
+
- with **bold**, _italic_ and a [link to another site](https://www.ruby-lang.org)
|
|
28
|
+
|
|
29
|
+
1. A numbered list
|
|
30
|
+
2. for steps in order
|
|
31
|
+
|
|
32
|
+
> Blockquotes are good for asides and pull quotes.
|
|
33
|
+
|
|
34
|
+
| Feature | Supported |
|
|
35
|
+
| ------- | --------- |
|
|
36
|
+
| Tables | yes |
|
|
37
|
+
| Footers | yes |
|