diff --git a/.eleventy.js b/.eleventy.js new file mode 100644 index 000000000..350dc7b3a --- /dev/null +++ b/.eleventy.js @@ -0,0 +1,42 @@ +const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); +const inclusiveLangPlugin = require("@11ty/eleventy-plugin-inclusive-language"); + +module.exports = function(eleventyConfig) { + eleventyConfig.addPlugin(pluginSyntaxHighlight); + eleventyConfig.addPlugin(inclusiveLangPlugin); + + let markdownIt = require("markdown-it"); + let markdownItAnchor = require("markdown-it-anchor"); + let markdownItReplaceLink = require("markdown-it-replace-link"); + + let markdownItOptions = { + html: true, + breaks: false, + linkify: true, + // Replace links to .md files with links to directories. This allows unparsed Markdown links + // to work on GitHub, while rendered links elsewhere also work. Also replaced dotted + // relative links for the same reason. + replaceLink: function (link, env) { + return link.replace(/\.md$/, '/').replace('../..', '../../..'); + } + }; + let markdownItAnchorOptions = { + permalink: true, + permalinkClass: "direct-link" + }; + + eleventyConfig.setLibrary( + "md", + markdownIt(markdownItOptions) + .use(markdownItAnchor, markdownItAnchorOptions) + .use(markdownItReplaceLink) + ); + + return { + templateFormats: [ + "md", + "txt" + ] + } +}; + diff --git a/.gitignore b/.gitignore index 340aeed56..245129e97 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ .coverage .pytest_cache .tox -build -dist +build/ +dist/ diff --git a/NEWS b/NEWS index 344584293..d51e88026 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ * Remove Python cache files before each Tox run. * Add #borgmatic Freenode IRC channel to documentation. * Add Borg/borgmatic hosting providers section to documentation. + * Add files for building documentation into a Docker image for web serving. 1.3.5 * #153: Support for various Borg directory environment variables (BORG_CONFIG_DIR, BORG_CACHE_DIR, diff --git a/README.md b/README.md index 7db9b88d4..3445ecb62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ --- title: borgmatic -permalink: borgmatic/index.html +permalink: index.html --- ![Build Status](https://build.torsion.org/api/badges/witten/borgmatic/status.svg) diff --git a/docs/Dockerfile b/docs/Dockerfile new file mode 100644 index 000000000..b7a3d9f83 --- /dev/null +++ b/docs/Dockerfile @@ -0,0 +1,26 @@ +FROM python:3.7.3-alpine3.9 as borgmatic + +COPY . /app +RUN pip install --no-cache /app && generate-borgmatic-config && chmod +r /etc/borgmatic/config.yaml +RUN borgmatic --help > /command-line.txt + +FROM node:11.15.0-alpine as html + +WORKDIR /source + +RUN npm install @11ty/eleventy \ + @11ty/eleventy-plugin-syntaxhighlight \ + @11ty/eleventy-plugin-inclusive-language \ + markdown-it \ + markdown-it-anchor \ + markdown-it-replace-link +COPY --from=borgmatic /etc/borgmatic/config.yaml /source/docs/_includes/borgmatic/config.yaml +COPY --from=borgmatic /command-line.txt /source/docs/_includes/borgmatic/command-line.txt +COPY . /source +RUN npx eleventy --input=/source/docs --output=/output/docs \ + && mv /output/docs/index.html /output/index.html + +FROM nginx:1.16.0-alpine + +COPY --from=html /output /usr/share/nginx/html +COPY --from=borgmatic /etc/borgmatic/config.yaml /usr/share/nginx/html/docs/reference/config.yaml diff --git a/docs/README.md b/docs/README.md new file mode 120000 index 000000000..32d46ee88 --- /dev/null +++ b/docs/README.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/docs/_data/layout.json b/docs/_data/layout.json new file mode 100644 index 000000000..56bc0a9b1 --- /dev/null +++ b/docs/_data/layout.json @@ -0,0 +1 @@ +"layouts/main.njk" diff --git a/docs/_includes/asciinema.css b/docs/_includes/asciinema.css new file mode 100644 index 000000000..b2ddcffdf --- /dev/null +++ b/docs/_includes/asciinema.css @@ -0,0 +1,3 @@ +.asciicast > iframe { + width: 100% !important; +} diff --git a/docs/_includes/components/external-links.css b/docs/_includes/components/external-links.css new file mode 100644 index 000000000..f84537106 --- /dev/null +++ b/docs/_includes/components/external-links.css @@ -0,0 +1,12 @@ +/* External links */ +a[href^="http://"]:not(.minilink):not(.elv-externalexempt), +a[href^="https://"]:not(.minilink):not(.elv-externalexempt), +a[href^="//"]:not(.minilink):not(.elv-externalexempt) { + text-decoration-color: inherit; +} +/* External link hovers */ +a[href^="http://"]:not(.minilink):not(.elv-externalexempt):hover, +a[href^="https://"]:not(.minilink):not(.elv-externalexempt):hover, +a[href^="//"]:not(.minilink):not(.elv-externalexempt):hover { + text-decoration-color: #00bcd4; +} diff --git a/docs/_includes/components/info-blocks.css b/docs/_includes/components/info-blocks.css new file mode 100644 index 000000000..7642ef6a0 --- /dev/null +++ b/docs/_includes/components/info-blocks.css @@ -0,0 +1,34 @@ +/* Warning */ +.elv-info { + line-height: 1.5; + padding: 0.8125em 1em 0.75em; /* 13px 16px 12px /16 */ + margin-left: -1rem; + margin-right: -1rem; + margin-bottom: 2em; + background-color: #dff7ff; +} +.elv-info:before { + content: "ℹ️ "; +} +.elv-info-warn { + background-color: #ffa; +} +.elv-info-warn:before { + content: "⚠️ "; +} +.elv-info:first-child { + margin-top: 0; +} +body > .elv-info { + margin-left: 0; + margin-right: 0; + padding: .5rem 1rem; +} +@media (min-width: 37.5em) and (min-height: 25em) { /* 600px / 400px */ + body > .elv-info-sticky { + position: sticky; + top: 0; + z-index: 2; + box-shadow: 0 3px 0 0 rgba(0,0,0,.08); + } +} \ No newline at end of file diff --git a/docs/_includes/components/lists.css b/docs/_includes/components/lists.css new file mode 100644 index 000000000..202e711a5 --- /dev/null +++ b/docs/_includes/components/lists.css @@ -0,0 +1,126 @@ +/* Buzzwords */ +@keyframes rainbow { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} +.buzzword-list, +.inlinelist { + padding: 0; +} +.inlinelist:first-child:last-child { + margin: 0; +} +.buzzword, +.buzzword-list li, +.inlinelist .inlinelist-item { + display: inline; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + font-family: Georgia, serif; + font-size: 116%; + white-space: normal; + line-height: 1.85; + padding: .2em .5em; + margin: 4px 4px 4px 0; + transition: .15s linear outline; +} +.inlinelist .inlinelist-item.active { + background-color: #222; + color: #fff; + font-weight: inherit; +} +.inlinelist .inlinelist-item.active :link, +.inlinelist .inlinelist-item.active :visited { + color: #fff; +} +.inlinelist .inlinelist-item code { + background-color: transparent; +} +a.buzzword { + text-decoration: underline; +} +.buzzword-list a, +.inlinelist a { + text-decoration: none; +} +.inlinelist .inlinelist-item { + font-size: 100%; + line-height: 2; +} +@supports not(-webkit-box-decoration-break: clone) { + .buzzword, + .buzzword-list li, + .inlinelist .inlinelist-item { + display: inline-block; + } +} +.buzzword-list li, +.buzzword { + background-color: #f7f7f7; +} +.inlinelist .inlinelist-item { + background-color: #e9e9e9; +} +.inlinelist .inlinelist-item:hover, +.inlinelist .inlinelist-item:focus, +.buzzword-list li:hover, +.buzzword-list li:focus, +.buzzword:hover, +.buzzword:focus { + position: relative; + background-image: linear-gradient(238deg, #ff0000, #ff8000, #ffff00, #80ff00, #00ff00, #00ff80, #00ffff, #0080ff, #0000ff, #8000ff, #ff0080); + background-size: 1200% 1200%; + color: #fff; + text-shadow: 0 0 2px rgba(0,0,0,.9); + animation: rainbow 1.6s infinite; +} +.inlinelist .inlinelist-item:hover a, +.inlinelist .inlinelist-item:focus a, +.buzzword-list li:hover a, +.buzzword-list li:focus a, +a.buzzword:hover, +a.buzzword:focus { + color: #fff; + text-decoration: none; +} +/* +I wish there were a PE friendly way to do this but media queries don’t work work with @supports +@media (prefers-reduced-motion: no-preference) { + .buzzword:hover, + .buzzword:focus { + animation: rainbow 1s infinite; + } +}*/ +.buzzword-list li:hover:after, +.buzzword-list li:focus:after, +.buzzword:hover:after, +.buzzword:focus:after { + font-family: system-ui, sans-serif; + content: "Buzzword alert!!!"; + position: absolute; + left: 0; + top: 0; + max-width: 8em; + color: #f00; + font-weight: 700; + text-transform: uppercase; + transform: rotate(-10deg) translate(-25%, -125%); + text-shadow: 1px 1px 5px rgba(0,0,0,.6); + line-height: 1.2; + pointer-events: none; +} +main h2 .buzzword, +main h3 .buzzword, +main p .buzzword { + padding: 0px 7px; + font-size: 1em; /* 18px /18 */ + margin: 0; + line-height: 1.444444444444; /* 26px /18 */ + font-family: inherit; +} +main h2 a.buzzword, +main h3 a.buzzword, +main p a.buzzword { + text-decoration: underline; +} \ No newline at end of file diff --git a/docs/_includes/components/minilink.css b/docs/_includes/components/minilink.css new file mode 100644 index 000000000..916a4de02 --- /dev/null +++ b/docs/_includes/components/minilink.css @@ -0,0 +1,40 @@ +/* Mini link */ +.minilink { + display: inline-block; + padding: .125em .375em; + text-transform: uppercase; + font-size: 0.875rem; /* 14px /16 */ + text-decoration: none; + background-color: #ddd; + border-radius: 0.1875em; /* 3px /16 */ + font-weight: 500; + margin: 0 0.4285714285714em 0.07142857142857em 0; /* 0 6px 1px 0 /14 */ + line-height: 1.285714285714; /* 18px /14 */ + font-family: system-ui, sans-serif; +} +.minilink[href] { + box-shadow: 0 1px 1px 0 rgba(0,0,0,.5); +} +.minilink[href]:hover, +.minilink[href]:focus { + background-color: #bbb; +} +pre + .minilink { + color: #fff; + border-radius: 0 0 0.2857142857143em 0.2857142857143em; /* 4px /14 */ + float: right; + background-color: #444; + color: #fff; +} +pre[class*=language-] + .minilink { + position: relative; + top: -0.7142857142857em; /* -10px /14 */ +} +p.minilink { + float: right; + margin-left: 2em; + margin-bottom: 2em; +} +.minilink + pre[class*=language-] { + clear: both; +} \ No newline at end of file diff --git a/docs/_includes/components/toc.css b/docs/_includes/components/toc.css new file mode 100644 index 000000000..c70a08b09 --- /dev/null +++ b/docs/_includes/components/toc.css @@ -0,0 +1,63 @@ +.elv-toc { + font-size: 1rem; /* Reset */ +} +@media (min-width: 64em) { /* 1024px */ + .elv-toc { + position: absolute; + left: -17rem; + width: 16rem; + } +} + + +.elv-toc-list { + padding-left: 0; + padding-right: 0; + list-style: none; +} +/* Nested lists */ +.elv-toc-list ul { + padding: 0; + display: none; + margin-bottom: 1.5em; + list-style: none; +} +.elv-toc-list ul li { + padding-left: 0.875em; /* 14px /16 */ +} +@media (min-width: 64em) and (min-height: 48em) { /* 1024 x 768px */ + .elv-toc-list ul { + display: block; + } +} + +/* List items */ +.elv-toc-list a:not(:hover) { + text-decoration: none; +} +.elv-toc-list li { + padding-top: 0; + padding-bottom: 0; + margin: .1em 0 .5em; +} +/* Top level links */ +.elv-toc-list > li > a { + font-weight: 400; + font-size: 1.0625em; /* 17px /16 */ + color: #222; +} + +/* Active links */ +.elv-toc-list li.elv-toc-active > a { + font-weight: 700; + text-decoration: underline; +} +.elv-toc-active > a:after { + content: " ⬅"; + line-height: .5; +} +/* Show only active nested lists */ +.elv-toc-list ul.elv-toc-active, +.elv-toc-list li.elv-toc-active > ul { + display: block; +} \ No newline at end of file diff --git a/docs/_includes/header.njk b/docs/_includes/header.njk new file mode 100644 index 000000000..77c6da70c --- /dev/null +++ b/docs/_includes/header.njk @@ -0,0 +1,3 @@ +
+

{{ title | safe }}

+
diff --git a/docs/_includes/index.css b/docs/_includes/index.css new file mode 100644 index 000000000..a40dc90b0 --- /dev/null +++ b/docs/_includes/index.css @@ -0,0 +1,486 @@ +@font-face { + font-family: BenchNine; + src: url("data:font/woff2;charset=utf-8;base64,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") format("woff2"); + font-weight: 700; + font-display: swap; + unicode-range: U+20-7E,U+2014,U+2019; +} + +* { + box-sizing: border-box; +} +body { + font-family: system-ui, sans-serif; + margin: 0; + color: #222; +} +img { + border: 0; +} +a, +a:visited, +a[href] { + color: #222; +} + +strong, +b { + font-weight: 600; +} +hr { + margin: 3em 0; + border: none; + border-top: 1px solid #ddd; +} +p { + max-width: 42em; + line-height: 1.5; +} + +/* Blockquotes */ +blockquote { + font-family: Georgia, serif; + font-size: 1.1875em; /* 19px /16 */ + color: #666; + margin: 1.5em 0; + padding: 0 1em; + max-width: 31.57894736842em; /* 600px /19 */ + border-left: 6px solid #ddd; + /*text-indent: -0.3684210526316em;*/ /* 7px /19 */ +} +blockquote + blockquote { + margin-top: 2em; +} +blockquote img { + height: 1.3em; + width: 1.3em; + border-radius: 50%; + vertical-align: text-top; + margin-left: 2px; + margin-right: 6px; +} + +/* Main */ +main { + font-size: 1.125em; /* 18px /16 */ +} +main:not(:empty) { + padding-bottom: 3em; + margin-bottom: 3em; +} + +/* Tables */ +table { + border-collapse: collapse; + margin-bottom: 2em; +} +table th, +table td { + text-align: left; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + padding: .4em; + font-size: 0.8125em; /* 13px /16 */ +} +table th:first-child, +table td:first-child { + padding-left: 0; +} +table th { + border-color: #ddd; +} +h2 + table { + margin-top: -0.625em; /* -10px /16 */ +} + +@media (min-width: 37.5em) { /* 600px */ + table th, + table td { + padding: .4em .8em; + font-size: 1em; /* 16px /16 */ + } +} + + +/* Headings */ +h1, +h2, +h3, +h4, +h5 { + font-family: BenchNine, system-ui, sans-serif; +} +h1 { + font-size: 2.666666666667em; /* 48px /18 */ + margin: 0 0 .5em; +} +main .elv-toc + h1 { + margin-top: 1em; +} +main h1:first-child, +main .elv-toc + h1 { + border-bottom: 2px dotted #666; +} +@media (min-width: 64em) { /* 1024px */ + main .elv-toc + h1, + main .elv-toc + h2 { + margin-top: 0; + } + +} +h2 { + font-size: 2.222222222222em; /* 40px /18 */ + border-bottom: 1px solid #ddd; + margin: 1em 0 .25em; +} +h3 { + font-size: 1.666666666667em; /* 30px /18 */ + margin-bottom: .5em; +} +h4 { + font-size: 1.444444444444em; /* 26px /18 */ + margin-bottom: .5em; +} +h5 { + font-size: 1.277777777778em; /* 23px /18 */ + margin-bottom: .5em; +} +main h1, +main h2, +main h3 { + text-transform: uppercase; +} +h1 code, +h2 code, +h3 code, +h4 code, +h5 code { + font-family: inherit; + text-transform: none; +} + +/* Lists */ +ul { + padding: 0 1em; +} +li { + padding: .25em 0; +} +li ul { + margin: .5em 0; + padding-left: 1em; +} +li li { + padding-top: .1em; + padding-bottom: .1em; +} + +/* Syntax highlighting and Code blocks */ +pre { + display: block; + padding: .5em; + margin: 1em -.5em 2em -.5em; + overflow-x: auto; + background-color: #eee; + font-size: 0.75em; /* 12px /16 */ +} +pre, +code { + font-family: Monaco, monospace; +} +code { + -ms-word-break: break-all; + word-break: break-word; + -webkit-hyphens: manual; + -moz-hyphens: manual; + hyphens: manual; + background-color: #efefef; +} +pre + pre[class*="language-"] { + margin-top: 1em; +} +pre + .note { + font-size: 0.6666666666667em; /* 16px /24 */ + margin-top: -2.875em; /* 46px /16 */ + margin-bottom: 2.5em; /* 40px /16 */ + text-align: right; +} +@media (min-width: 37.5em) { /* 600px */ + pre { + font-size: 0.75em; /* 16px /16 */ + } +} + + +#quick-start ~ .language-text { + border-top: 2px solid #666; + border-bottom: 2px solid #666; +} +@media (min-width: 42em) { /* 672px */ + #quick-start ~ .language-text { + border: 2px solid #666; + } +} +#quick-start ~ .language-text, +#quick-start ~ .language-text code { + background-color: #fafafa; + color: #222; +} + +/* Layout */ +.elv-layout { + padding: 1rem; + margin: 0 auto; + max-width: 42rem; + clear: both; +} +footer.elv-layout { + margin-bottom: 5em; +} +.elv-layout-full { + max-width: none; +} +@media (min-width: 64em) { /* 1024px */ + .elv-layout-toc { + margin-left: 18rem; + max-width: 60rem; + margin-right: 1rem; + position: relative; + } +} +/*.elv-layout-wider { + max-width: 60rem; +}*/ + +/* Header */ +.elv-header { + color: #222; + position: relative; +} +.elv-header-default { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.elv-header-docs:before, +.elv-header-docs:after { + content: " "; + display: table; +} +.elv-header-docs:after { + clear: both; +} +/* Header Hero */ +.elv-hero img { + max-width: 80vw; + max-height: 60vh; +} +.elv-header-docs .elv-hero { + float: left; + margin-right: 1.5em; +} +.elv-header-docs .elv-hero img { + height: 3em; +} +@media (min-width: 37.5em) { /* 600px */ + .elv-header-docs .elv-hero img { + width: 4.303125em; /* 68.85px /16 */ + height: 6em; + } +} +/* Header Possum */ +.elv-possum { + display: none; + position: absolute; + right: 1em; + top: 1em; + width: 16vmin; +} +@media (min-width: 31.25em) { /* 500px */ + .elv-possum { + display: block; + } +} + +/* Header Heading */ +.elv-hed { + font-size: 3em; + margin-top: 1.5em; + margin-bottom: .25em; + text-align: center; + text-transform: none; +} +.elv-header-docs .elv-hed { + font-size: 2.3em; + margin: 0; + text-align: left; +} +@media (min-width: 37.5em) { /* 600px */ + .elv-header-docs .elv-hed { + font-size: 3em; + } +} + +/* Navigation */ +.elv-nav { + padding: 0; + margin: 1em 0 0 0; + clear: both; + list-style: none; +} +.elv-nav-item { + float: left; + padding-left: .25em; + padding-right: .25em; + font-size: 0.8125rem; /* 13px /16 */ +} +.elv-nav-item:first-child { + padding-left: 0; +} +.elv-nav-item:last-child { + padding-right: 0; +} +.elv-nav-item a { + font-weight: 600; + } +.elv-nav-item .elv-nav-light { + font-weight: 300; +} +@media (min-width: 20em) { /* 320px */ + .elv-nav-item { + font-size: 4vw; + } +} +@media (min-width: 25em) { /* 400px */ + .elv-nav-item { + font-size: 1rem; /* 16px /16 */ + padding-left: .45em; + padding-right: .45em; + } +} +@media (min-width: 35.625em) { /* 570px */ + .elv-nav { + clear: none; + width: auto; + margin-top: 0; + } + .elv-nav-item { + float: left; + padding-left: 0; + padding-right: 0; + } + .elv-nav-item a:not(:hover) { + text-decoration: none; + } + .elv-nav-item:not(:first-child):before { + content: ""; + border-left: 1px solid #ccc; + padding: 0 0 0 .75em; + margin-left: .75em; + } +} + +/* Version */ +.latestversion { + font-size: 2em; + margin-top: 0; +} +.latestversion code { + font-size: 0.75em; /* 24px /32 */ +} +.latestversion { + font-family: BenchNine, system-ui, sans-serif; +} +.tmpl-docs .latestversion { + position: absolute; + top: 1rem; + right: 1rem; + margin: 0; +} + +/* News */ +.news { + text-align: center; +} + +/* Direct Links / Markdown Headers */ +.direct-link { + font-family: sans-serif; + text-decoration: none; + font-style: normal; + margin-left: .1em; +} +a[href].direct-link, +a[href].direct-link:visited { + color: transparent; +} +a[href].direct-link:focus, +a[href].direct-link:focus:visited, +:hover > a[href].direct-link, +:hover > a[href].direct-link:visited, +:focus > a[href].direct-link, +:focus > a[href].direct-link:visited { + color: #aaa; +} +/* don’t use a direct link, should be a link to the page */ +main .elv-toc + h1 .direct-link { + display: none; +} + +/* Style Guide */ +.elv-sg-component { + background-color: #f9f9f9; + border-top: 1px dotted #ddd; + border-bottom: 1px dotted #ddd; + margin: 2rem 0; +} + +/* Screen readers only */ +.sr-only { + position: absolute; + height: 1px; + width: 1px; + overflow: hidden; + clip: rect(1px, 1px, 1px, 1px); +} + +/* Language List */ +.elv-langlist { + font-size: 0.8333333333333em; /* 15px /18 */ + background-color: #f7f7f7; + padding: .5rem; + margin: 2em 0; +} +.elv-langlist-hed { + margin: 0; + float: left; + border: none; + font-size: 1.4em; /* 21px /15 */ +} +.elv-langlist > .inlinelist { + display: inline; + margin-left: 1em; +} + +@media (min-width: 37.5em) { /* 600px */ + .quicktipstoc { + margin: 0 0 3% 3%; + float: right; + width: 32%; + border-radius: .25em; + font-size: 0.8125em; /* 13px /16 */ + } +} + +/* Breakpoint Overrides */ +@media (max-width: 37.4375em) { /* 599px */ + .bp-notsm.bp-notsm.bp-notsm.bp-notsm { + display: none; + } +} +@media (min-width: 37.5em) { /* 600px */ + .bp-sm.bp-sm.bp-sm.bp-sm { + display: none ; + } +} diff --git a/docs/_includes/layouts/base.njk b/docs/_includes/layouts/base.njk new file mode 100644 index 000000000..361967c5f --- /dev/null +++ b/docs/_includes/layouts/base.njk @@ -0,0 +1,27 @@ + + + + + + {{ subtitle + ' - ' if subtitle}}{{ title }} +{%- set css %} +{% include 'index.css' %} +{% include 'components/lists.css' %} +{% include 'components/external-links.css' %} +{% include 'components/minilink.css' %} +{% include 'components/toc.css' %} +{% include 'components/info-blocks.css' %} +{% include 'prism-theme.css' %} +{% include 'asciinema.css' %} +{% endset %} + +{% if feedTitle and feedUrl %} + +{% endif %} + + + + {{ content | safe }} + + + diff --git a/docs/_includes/layouts/main.njk b/docs/_includes/layouts/main.njk new file mode 100644 index 000000000..25e7ac0f4 --- /dev/null +++ b/docs/_includes/layouts/main.njk @@ -0,0 +1,12 @@ +--- +layout: layouts/base.njk +templateClass: elv-default +headerClass: elv-header-default +--- +{% include "header.njk" %} + +
+
+ {{ content | safe }} +
+
diff --git a/docs/_includes/prism-theme.css b/docs/_includes/prism-theme.css new file mode 100644 index 000000000..4aed4d42f --- /dev/null +++ b/docs/_includes/prism-theme.css @@ -0,0 +1,172 @@ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ +code[class*="language-"], +pre[class*="language-"] { + color: #ABB2BF; + background: none; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #383e49; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #9aa2b1; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #282c34; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #5C6370; +} + +.token.punctuation { + color: #abb2bf; +} + +.token.selector, +.token.tag { + color: #e06c75; +} + +.token.property, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.attr-name, +.token.deleted { + color: #d19a66; +} + +.token.string, +.token.char, +.token.attr-value, +.token.builtin, +.token.inserted { + color: #98c379; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #56b6c2; +} + +.token.atrule, +.token.keyword { + color: #e06c75; +} + +.token.function { + color: #61afef; +} + +.token.regex, +.token.important, +.token.variable { + color: #c678dd; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +pre.line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre.line-numbers > code { + position: relative; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 0; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + +.line-numbers-rows > span { + pointer-events: none; + display: block; + counter-increment: linenumber; +} + +.line-numbers-rows > span:before { + content: counter(linenumber); + color: #5C6370; + display: block; + padding-right: 0.8em; + text-align: right; +} diff --git a/scripts/docs/build b/scripts/docs/build new file mode 100755 index 000000000..d34c8a20e --- /dev/null +++ b/scripts/docs/build @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +docker build --tag witten/borgmatic-docs --file docs/Dockerfile . diff --git a/scripts/docs/push b/scripts/docs/push new file mode 100755 index 000000000..a60dfbe7e --- /dev/null +++ b/scripts/docs/push @@ -0,0 +1,6 @@ +#!/bin/bash + +set -e + +. scripts/docs/build +docker push witten/borgmatic-docs