@@ -1,6 +1,7 @@ | |||
target | |||
.idea/ | |||
components/site/test_site/public | |||
docs/public | |||
small-blog | |||
medium-blog | |||
@@ -304,10 +304,14 @@ impl Site { | |||
/// Find out the direct subsections of each subsection if there are some | |||
/// as well as the pages for each section | |||
pub fn populate_sections(&mut self) { | |||
let mut grandparent_paths = HashMap::new(); | |||
let mut grandparent_paths: HashMap<PathBuf, Vec<PathBuf>> = HashMap::new(); | |||
for section in self.sections.values_mut() { | |||
if let Some(ref grand_parent) = section.file.grand_parent { | |||
grandparent_paths.entry(grand_parent.to_path_buf()).or_insert_with(|| vec![]).push(section.clone()); | |||
grandparent_paths | |||
.entry(grand_parent.to_path_buf()) | |||
.or_insert_with(|| vec![]) | |||
.push(section.file.path.clone()); | |||
} | |||
// Make sure the pages of a section are empty since we can call that many times on `serve` | |||
section.pages = vec![]; | |||
@@ -321,14 +325,20 @@ impl Site { | |||
} | |||
} | |||
self.sort_sections_pages(None); | |||
// TODO: remove this clone | |||
let sections = self.sections.clone(); | |||
for section in self.sections.values_mut() { | |||
match grandparent_paths.get(§ion.file.parent) { | |||
Some(paths) => section.subsections.extend(paths.clone()), | |||
Some(paths) => { | |||
for p in paths { | |||
section.subsections.push(sections[p].clone()); | |||
} | |||
}, | |||
None => continue, | |||
}; | |||
} | |||
self.sort_sections_pages(None); | |||
} | |||
/// Sorts the pages of the section at the given path | |||
@@ -6,5 +6,6 @@ | |||
{% endfor %} | |||
{% for subsection in section.subsections %} | |||
{{subsection.title}} | |||
Sub-pages: {{subsection.pages | length}} | |||
{% endfor %} | |||
{% endblock content %} |
@@ -115,6 +115,8 @@ fn can_build_site_without_live_reload() { | |||
assert!(file_exists!(public, "posts/tutorials/index.html")); | |||
assert!(file_exists!(public, "posts/tutorials/devops/index.html")); | |||
assert!(file_exists!(public, "posts/tutorials/programming/index.html")); | |||
// Ensure subsection pages are correctly filled | |||
assert!(file_contains!(public, "posts/tutorials/index.html", "Sub-pages: 2")); | |||
// TODO: add assertion for syntax highlighting | |||
// aliases work | |||
@@ -0,0 +1,9 @@ | |||
base_url = "https://example.com" | |||
title = "Gutenberg - your one-stop static site engine" | |||
description = "Everything you need to make a static site engine in one binary. And it's fast" | |||
compile_sass = true | |||
highlight_code = true | |||
[extra] | |||
author = "Vincent Prouillet" |
@@ -0,0 +1,34 @@ | |||
+++ | |||
template = "documentation.html" | |||
+++ | |||
Getting started | |||
- Installation | |||
- CLI usage | |||
- Directory structure | |||
- config.toml | |||
Content | |||
- Organisation | |||
- Pages | |||
- Sections | |||
- Shortcodes | |||
- Internal links | |||
- Table of contents | |||
- Deep linking (# links) | |||
- Syntax highlighting | |||
- Pagination | |||
- Tag & categories | |||
- RSS | |||
- Sitemap | |||
Templates | |||
- Intro | |||
- Each kind of page and the variables available | |||
- Built-in global functions | |||
- Built-in filters | |||
- Debugging | |||
Theme | |||
- Installing & customising a theme | |||
- Creating a theme |
@@ -0,0 +1,4 @@ | |||
+++ | |||
title = "Getting Started" | |||
sort_by = "order" | |||
+++ |
@@ -0,0 +1,6 @@ | |||
+++ | |||
title = "CLI usage" | |||
order = 2 | |||
+++ | |||
Hey |
@@ -0,0 +1,6 @@ | |||
+++ | |||
title = "Configuration" | |||
order = 4 | |||
+++ | |||
Hey |
@@ -0,0 +1,6 @@ | |||
+++ | |||
title = "Directory structure" | |||
order = 3 | |||
+++ | |||
Hey |
@@ -0,0 +1,6 @@ | |||
+++ | |||
title = "Installation" | |||
order = 1 | |||
+++ | |||
Hey |
@@ -0,0 +1,67 @@ | |||
html, body { | |||
font-size: 16px; | |||
height: 100%; | |||
} | |||
body { | |||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; | |||
line-height: 1.6; | |||
background-color: $background; | |||
color: $foreground; | |||
// for sticky footer | |||
display: flex; | |||
flex-direction: column; | |||
min-height: 100vh; | |||
} | |||
a { | |||
color: white; | |||
text-decoration: none; | |||
cursor: pointer; | |||
&:hover { | |||
text-decoration: underline; | |||
} | |||
&:visited { | |||
color: white; | |||
} | |||
// totally taken from stripe | |||
&.button { | |||
outline: none; | |||
white-space: nowrap; | |||
display: inline-block; | |||
height: 40px; | |||
line-height: 40px; | |||
padding: 0 14px; | |||
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08); | |||
background: #fff; | |||
border-radius: 4px; | |||
font-size: 15px; | |||
font-weight: 600; | |||
text-transform: uppercase; | |||
letter-spacing: .025em; | |||
color: #191919; | |||
text-decoration: none; | |||
transition: all .15s ease; | |||
&:hover { | |||
transform: translateY(-1px); | |||
text-decoration: none; | |||
box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08); | |||
} | |||
&:active { | |||
background-color: #f6f9fc; | |||
transform: translateY(1px); | |||
// box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, .08); | |||
} | |||
} | |||
} | |||
pre { | |||
padding: 1rem; | |||
overflow: auto; | |||
} |
@@ -0,0 +1,3 @@ | |||
.documentation { | |||
padding: 3rem; | |||
} |
@@ -0,0 +1,14 @@ | |||
header { | |||
nav a { | |||
margin-right: 1rem; | |||
} | |||
.header__logo { | |||
font-size: 2rem; | |||
font-weight: bold; | |||
&:hover { | |||
text-decoration: none; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
.hero { | |||
width: 60%; | |||
margin: 0 auto; | |||
margin-top: 3rem; | |||
margin-bottom: 6rem; | |||
text-align: center; | |||
&__tagline { | |||
margin-bottom: 2rem; | |||
} | |||
} | |||
.selling-points { | |||
background: $foreground; | |||
color: $background; | |||
padding: 3rem; | |||
&__content { | |||
display: flex; | |||
flex-wrap: wrap; | |||
} | |||
} | |||
.selling-point { | |||
// 2 selling points per row on desktop | |||
width: 50%; | |||
padding: 2rem; | |||
} |
@@ -0,0 +1,29 @@ | |||
header { | |||
padding: 2rem 0; | |||
} | |||
.container { | |||
max-width: 1000px; | |||
margin: 0 auto; | |||
} | |||
@media only screen and (max-width: 1000px) { | |||
.container { | |||
max-width: 90%; | |||
} | |||
} | |||
.content { | |||
flex-grow: 1; | |||
&--reversed { | |||
background: $foreground; | |||
color: $background; | |||
} | |||
} | |||
footer { | |||
text-align: center; | |||
padding: 2rem 0; | |||
} |
@@ -0,0 +1,447 @@ | |||
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ | |||
/* Document | |||
========================================================================== */ | |||
/** | |||
* 1. Correct the line height in all browsers. | |||
* 2. Prevent adjustments of font size after orientation changes in | |||
* IE on Windows Phone and in iOS. | |||
*/ | |||
html { | |||
line-height: 1.15; /* 1 */ | |||
-ms-text-size-adjust: 100%; /* 2 */ | |||
-webkit-text-size-adjust: 100%; /* 2 */ | |||
} | |||
/* Sections | |||
========================================================================== */ | |||
/** | |||
* Remove the margin in all browsers (opinionated). | |||
*/ | |||
body { | |||
margin: 0; | |||
} | |||
/** | |||
* Add the correct display in IE 9-. | |||
*/ | |||
article, | |||
aside, | |||
footer, | |||
header, | |||
nav, | |||
section { | |||
display: block; | |||
} | |||
/** | |||
* Correct the font size and margin on `h1` elements within `section` and | |||
* `article` contexts in Chrome, Firefox, and Safari. | |||
*/ | |||
h1 { | |||
font-size: 2em; | |||
margin: 0.67em 0; | |||
} | |||
/* Grouping content | |||
========================================================================== */ | |||
/** | |||
* Add the correct display in IE 9-. | |||
* 1. Add the correct display in IE. | |||
*/ | |||
figcaption, | |||
figure, | |||
main { /* 1 */ | |||
display: block; | |||
} | |||
/** | |||
* Add the correct margin in IE 8. | |||
*/ | |||
figure { | |||
margin: 1em 40px; | |||
} | |||
/** | |||
* 1. Add the correct box sizing in Firefox. | |||
* 2. Show the overflow in Edge and IE. | |||
*/ | |||
hr { | |||
box-sizing: content-box; /* 1 */ | |||
height: 0; /* 1 */ | |||
overflow: visible; /* 2 */ | |||
} | |||
/** | |||
* 1. Correct the inheritance and scaling of font size in all browsers. | |||
* 2. Correct the odd `em` font sizing in all browsers. | |||
*/ | |||
pre { | |||
font-family: monospace, monospace; /* 1 */ | |||
font-size: 1em; /* 2 */ | |||
} | |||
/* Text-level semantics | |||
========================================================================== */ | |||
/** | |||
* 1. Remove the gray background on active links in IE 10. | |||
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+. | |||
*/ | |||
a { | |||
background-color: transparent; /* 1 */ | |||
-webkit-text-decoration-skip: objects; /* 2 */ | |||
} | |||
/** | |||
* 1. Remove the bottom border in Chrome 57- and Firefox 39-. | |||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. | |||
*/ | |||
abbr[title] { | |||
border-bottom: none; /* 1 */ | |||
text-decoration: underline; /* 2 */ | |||
text-decoration: underline dotted; /* 2 */ | |||
} | |||
/** | |||
* Prevent the duplicate application of `bolder` by the next rule in Safari 6. | |||
*/ | |||
b, | |||
strong { | |||
font-weight: inherit; | |||
} | |||
/** | |||
* Add the correct font weight in Chrome, Edge, and Safari. | |||
*/ | |||
b, | |||
strong { | |||
font-weight: bolder; | |||
} | |||
/** | |||
* 1. Correct the inheritance and scaling of font size in all browsers. | |||
* 2. Correct the odd `em` font sizing in all browsers. | |||
*/ | |||
code, | |||
kbd, | |||
samp { | |||
font-family: monospace, monospace; /* 1 */ | |||
font-size: 1em; /* 2 */ | |||
} | |||
/** | |||
* Add the correct font style in Android 4.3-. | |||
*/ | |||
dfn { | |||
font-style: italic; | |||
} | |||
/** | |||
* Add the correct background and color in IE 9-. | |||
*/ | |||
mark { | |||
background-color: #ff0; | |||
color: #000; | |||
} | |||
/** | |||
* Add the correct font size in all browsers. | |||
*/ | |||
small { | |||
font-size: 80%; | |||
} | |||
/** | |||
* Prevent `sub` and `sup` elements from affecting the line height in | |||
* all browsers. | |||
*/ | |||
sub, | |||
sup { | |||
font-size: 75%; | |||
line-height: 0; | |||
position: relative; | |||
vertical-align: baseline; | |||
} | |||
sub { | |||
bottom: -0.25em; | |||
} | |||
sup { | |||
top: -0.5em; | |||
} | |||
/* Embedded content | |||
========================================================================== */ | |||
/** | |||
* Add the correct display in IE 9-. | |||
*/ | |||
audio, | |||
video { | |||
display: inline-block; | |||
} | |||
/** | |||
* Add the correct display in iOS 4-7. | |||
*/ | |||
audio:not([controls]) { | |||
display: none; | |||
height: 0; | |||
} | |||
/** | |||
* Remove the border on images inside links in IE 10-. | |||
*/ | |||
img { | |||
border-style: none; | |||
} | |||
/** | |||
* Hide the overflow in IE. | |||
*/ | |||
svg:not(:root) { | |||
overflow: hidden; | |||
} | |||
/* Forms | |||
========================================================================== */ | |||
/** | |||
* 1. Change the font styles in all browsers (opinionated). | |||
* 2. Remove the margin in Firefox and Safari. | |||
*/ | |||
button, | |||
input, | |||
optgroup, | |||
select, | |||
textarea { | |||
font-family: sans-serif; /* 1 */ | |||
font-size: 100%; /* 1 */ | |||
line-height: 1.15; /* 1 */ | |||
margin: 0; /* 2 */ | |||
} | |||
/** | |||
* Show the overflow in IE. | |||
* 1. Show the overflow in Edge. | |||
*/ | |||
button, | |||
input { /* 1 */ | |||
overflow: visible; | |||
} | |||
/** | |||
* Remove the inheritance of text transform in Edge, Firefox, and IE. | |||
* 1. Remove the inheritance of text transform in Firefox. | |||
*/ | |||
button, | |||
select { /* 1 */ | |||
text-transform: none; | |||
} | |||
/** | |||
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` | |||
* controls in Android 4. | |||
* 2. Correct the inability to style clickable types in iOS and Safari. | |||
*/ | |||
button, | |||
html [type="button"], /* 1 */ | |||
[type="reset"], | |||
[type="submit"] { | |||
-webkit-appearance: button; /* 2 */ | |||
} | |||
/** | |||
* Remove the inner border and padding in Firefox. | |||
*/ | |||
button::-moz-focus-inner, | |||
[type="button"]::-moz-focus-inner, | |||
[type="reset"]::-moz-focus-inner, | |||
[type="submit"]::-moz-focus-inner { | |||
border-style: none; | |||
padding: 0; | |||
} | |||
/** | |||
* Restore the focus styles unset by the previous rule. | |||
*/ | |||
button:-moz-focusring, | |||
[type="button"]:-moz-focusring, | |||
[type="reset"]:-moz-focusring, | |||
[type="submit"]:-moz-focusring { | |||
outline: 1px dotted ButtonText; | |||
} | |||
/** | |||
* Correct the padding in Firefox. | |||
*/ | |||
fieldset { | |||
padding: 0.35em 0.75em 0.625em; | |||
} | |||
/** | |||
* 1. Correct the text wrapping in Edge and IE. | |||
* 2. Correct the color inheritance from `fieldset` elements in IE. | |||
* 3. Remove the padding so developers are not caught out when they zero out | |||
* `fieldset` elements in all browsers. | |||
*/ | |||
legend { | |||
box-sizing: border-box; /* 1 */ | |||
color: inherit; /* 2 */ | |||
display: table; /* 1 */ | |||
max-width: 100%; /* 1 */ | |||
padding: 0; /* 3 */ | |||
white-space: normal; /* 1 */ | |||
} | |||
/** | |||
* 1. Add the correct display in IE 9-. | |||
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. | |||
*/ | |||
progress { | |||
display: inline-block; /* 1 */ | |||
vertical-align: baseline; /* 2 */ | |||
} | |||
/** | |||
* Remove the default vertical scrollbar in IE. | |||
*/ | |||
textarea { | |||
overflow: auto; | |||
} | |||
/** | |||
* 1. Add the correct box sizing in IE 10-. | |||
* 2. Remove the padding in IE 10-. | |||
*/ | |||
[type="checkbox"], | |||
[type="radio"] { | |||
box-sizing: border-box; /* 1 */ | |||
padding: 0; /* 2 */ | |||
} | |||
/** | |||
* Correct the cursor style of increment and decrement buttons in Chrome. | |||
*/ | |||
[type="number"]::-webkit-inner-spin-button, | |||
[type="number"]::-webkit-outer-spin-button { | |||
height: auto; | |||
} | |||
/** | |||
* 1. Correct the odd appearance in Chrome and Safari. | |||
* 2. Correct the outline style in Safari. | |||
*/ | |||
[type="search"] { | |||
-webkit-appearance: textfield; /* 1 */ | |||
outline-offset: -2px; /* 2 */ | |||
} | |||
/** | |||
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS. | |||
*/ | |||
[type="search"]::-webkit-search-cancel-button, | |||
[type="search"]::-webkit-search-decoration { | |||
-webkit-appearance: none; | |||
} | |||
/** | |||
* 1. Correct the inability to style clickable types in iOS and Safari. | |||
* 2. Change font properties to `inherit` in Safari. | |||
*/ | |||
::-webkit-file-upload-button { | |||
-webkit-appearance: button; /* 1 */ | |||
font: inherit; /* 2 */ | |||
} | |||
/* Interactive | |||
========================================================================== */ | |||
/* | |||
* Add the correct display in IE 9-. | |||
* 1. Add the correct display in Edge, IE, and Firefox. | |||
*/ | |||
details, /* 1 */ | |||
menu { | |||
display: block; | |||
} | |||
/* | |||
* Add the correct display in all browsers. | |||
*/ | |||
summary { | |||
display: list-item; | |||
} | |||
/* Scripting | |||
========================================================================== */ | |||
/** | |||
* Add the correct display in IE 9-. | |||
*/ | |||
canvas { | |||
display: inline-block; | |||
} | |||
/** | |||
* Add the correct display in IE. | |||
*/ | |||
template { | |||
display: none; | |||
} | |||
/* Hidden | |||
========================================================================== */ | |||
/** | |||
* Add the correct display in IE 10-. | |||
*/ | |||
[hidden] { | |||
display: none; | |||
} |
@@ -0,0 +1,16 @@ | |||
@charset "utf-8"; | |||
@import "normalize"; | |||
*, *:before, *:after { | |||
box-sizing: border-box; | |||
} | |||
$background: #191919; | |||
$foreground: white; | |||
@import "base"; | |||
@import "layout"; | |||
@import "header"; | |||
@import "index"; | |||
@import "docs"; |
@@ -0,0 +1,26 @@ | |||
{% extends "index.html" %} | |||
{% block title %}{{ super() }} - Documentation {% endblock title %} | |||
{% block extra_content_class %}content--reversed{% endblock extra_content_class %} | |||
{% block content %} | |||
{% set section = get_section(path="documentation/_index.md") %} | |||
<div class="documentation container"> | |||
<aside class="documentation__sidebar"> | |||
{% for subsection in section.subsections %} | |||
<li> | |||
{{ subsection.title }} | |||
<ul> | |||
{% for page in subsection.pages | reverse %} | |||
<li>{{page.title}}</li> | |||
{% endfor %} | |||
</ul> | |||
</li> | |||
{% endfor %} | |||
</aside> | |||
<div class="documentation__content"> | |||
hey | |||
</div> | |||
</div> | |||
{% endblock content %} |
@@ -0,0 +1,78 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-gb"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<meta name="apple-mobile-web-app-capable" content="yes"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<meta name="description" content="{% block description %}{{ config.description }}{% endblock description %}"> | |||
<meta name="author" content="{{ config.extra.author }}"> | |||
<title>{% block title %}{{ config.title }}{% endblock title %}</title> | |||
<link rel="stylesheet" href="{{ get_url(path="site.css", cachebust=true) }}"/> | |||
</head> | |||
<body> | |||
<header> | |||
<nav class="container"> | |||
<a class="header__logo" href="{{ config.base_url }}">Gutenberg</a> | |||
<a href="/documentation" class="nav-link">Documentation</a> | |||
<a href="" class="nav-link">Themes</a> | |||
<a href="https://github.com/Keats/gutenberg" class="nav-link">Github</a> | |||
</nav> | |||
</header> | |||
<div class="content {% block extra_content_class %}{% endblock extra_content_class %}"> | |||
{% block content %} | |||
<div class="hero"> | |||
<h1>Your damn fast one-stop static site engine</h1> | |||
<p class="hero__tagline"> | |||
Forget dependencies. Everything you need in one binary. | |||
</p> | |||
<a href="" class="button">Get started</a> | |||
</div> | |||
<div class="selling-points"> | |||
<div class="selling-points__content container"> | |||
<div class="selling-point"> | |||
<h2>Everything built-in</h2> | |||
<p> | |||
Gutenberg comes with Sass compilation, syntax highlighting and | |||
a other features that usually require using additional tools | |||
or use JavaScript libraries on your site. | |||
</p> | |||
</div> | |||
<div class="selling-point"> | |||
<h2>Fast</h2> | |||
<p> | |||
Your site will be generated in milliseconds, not seconds. | |||
That includes Sass compilation and syntax highlighting. | |||
</p> | |||
</div> | |||
<div class="selling-point"> | |||
<h2>Flexible</h2> | |||
<p> | |||
You can build anything you want with Gutenberg: blogs, landing pages, knowledge bases... | |||
</p> | |||
</div> | |||
<div class="selling-point"> | |||
<h2>Easy to use</h2> | |||
<p> | |||
Gutenberg strives for good UX and being productive instantly. | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
{% endblock content %} | |||
</div> | |||
<footer> | |||
<div class="container"> | |||
© 2017 Vincent Prouillet | |||
</div> | |||
</footer> | |||
</body> | |||
</html> |
@@ -160,7 +160,7 @@ pub fn serve(interface: &str, port: &str, config_file: &str) -> Result<()> { | |||
Write(path) | | |||
Remove(path) | | |||
Rename(_, path) => { | |||
if is_temp_file(&path) { | |||
if is_temp_file(&path) || path.is_dir() { | |||
continue; | |||
} | |||
@@ -98,6 +98,11 @@ pub fn after_content_change(site: &mut Site, path: &Path) -> Result<()> { | |||
// A page or section got deleted | |||
if !path.exists() { | |||
// A folder got deleted, ignore this event | |||
if !site.sections.contains_key(path) && !site.pages.contains_key(path) { | |||
return Ok(()); | |||
} | |||
if is_section { | |||
// A section was deleted, many things can be impacted: | |||
// - the pages of the section are becoming orphans | |||