mirror of
https://github.com/pezkuwichain/pezkuwi-fellows.git
synced 2026-04-21 23:47:56 +00:00
Introduce RFC mdBook web page (#60)
- Closes https://github.com/polkadot-fellows/RFCs/issues/53 - Preview available [here](https://paritytech.github.io/RFCs/).  --- ### What it does - The workflow gathers the source markdown files of RFCs - approved ones, and proposed ones (from open PRs). - The proposed RFCs are separated into new (<7 days since PR created) and stale (>30 days since PR updated). - The RFCs are extended with a table of contents, and a link to the source. - The RFCs are build into a web page using [mdBook](https://github.com/rust-lang/mdBook). - The built web page gets pushed to `gh-pages` branch - to be published in Github Pages. - The workflow is triggered on merge to `main`, and periodically once a day.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* mdBook relies on the creation of a special SUMMARY.md file
|
||||
* https://rust-lang.github.io/mdBook/format/summary.html
|
||||
* This script constructs the summary out of the available source files.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const summaryPath = "mdbook/src/SUMMARY.md"
|
||||
|
||||
module.exports = async ({github, context}) => {
|
||||
fs.writeFileSync(summaryPath, "# Summary\n\n[Introduction](introduction.md)\n") // Starting point.
|
||||
|
||||
const appendRfcsToSummary = (dirPath) => {
|
||||
for (const filename of fs.readdirSync(dirPath)) {
|
||||
if (!filename.endsWith(".md")) continue;
|
||||
const filePath = dirPath + filename
|
||||
const text = fs.readFileSync(filePath)
|
||||
const title = text.toString().split(/\n/)
|
||||
.find(line => line.startsWith("# ") || line.startsWith(" # "))
|
||||
.replace("# ", "")
|
||||
// Relative path, without the src prefix (format required by mdbook)
|
||||
const relativePath = filePath.replace("mdbook/src/", "")
|
||||
fs.appendFileSync(summaryPath, `- [${title}](${relativePath})\n`)
|
||||
}
|
||||
}
|
||||
|
||||
fs.appendFileSync(summaryPath, "\n---\n\n# Approved\n\n")
|
||||
appendRfcsToSummary("mdbook/src/approved/")
|
||||
|
||||
fs.appendFileSync(summaryPath, "\n---\n\n# Newly Proposed\n\n")
|
||||
appendRfcsToSummary("mdbook/src/new/")
|
||||
|
||||
fs.appendFileSync(summaryPath, "\n---\n\n# Proposed\n\n")
|
||||
appendRfcsToSummary("mdbook/src/proposed/")
|
||||
|
||||
fs.appendFileSync(summaryPath, "\n---\n\n# Stale\n\n")
|
||||
appendRfcsToSummary("mdbook/src/stale/")
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* This scripts gathers source markdown files of approved and proposed RFCS into the mdbook/src directory.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
// The amount of days that an RFC is considered "new".
|
||||
// Counted from the creation of a given PR.
|
||||
const NEW_RFC_PERIOD_DAYS = 7
|
||||
|
||||
// The amount of days that an RFC is considered "stale".
|
||||
// Counted from the last update on a PR.
|
||||
const STALE_RFC_PERIOD_DAYS = 30
|
||||
|
||||
const dateDaysBefore = (daysBefore) => {
|
||||
const result = new Date()
|
||||
result.setDate(result.getDate() - daysBefore)
|
||||
return result
|
||||
}
|
||||
|
||||
[
|
||||
"mdbook/src/approved",
|
||||
"mdbook/src/new",
|
||||
"mdbook/src/stale",
|
||||
"mdbook/src/proposed"
|
||||
].forEach(path => fs.mkdirSync(path, {resursive: true}))
|
||||
|
||||
const TOC = "**Table of Contents**\n\n<\!-- toc -->\n"
|
||||
|
||||
module.exports = async ({github, context}) => {
|
||||
const owner = 'polkadot-fellows'
|
||||
const repo = 'RFCs'
|
||||
const prs = await github.paginate(github.rest.pulls.list, {owner, repo, state: 'open'})
|
||||
|
||||
/*
|
||||
The open PRs are potential proposed RFCs.
|
||||
We iterate over them and filter those that include a new RFC markdown file.
|
||||
*/
|
||||
for (const pr of prs) {
|
||||
const addedMarkdownFiles = (
|
||||
await github.rest.pulls.listFiles({
|
||||
owner, repo,
|
||||
pull_number: pr.number,
|
||||
})
|
||||
).data.filter(
|
||||
(file) => file.status === "added" && file.filename.startsWith("text/") && file.filename.includes(".md"),
|
||||
);
|
||||
if (addedMarkdownFiles.length !== 1) continue;
|
||||
const [rfcFile] = addedMarkdownFiles;
|
||||
const rawText = await (await fetch(rfcFile.raw_url)).text();
|
||||
|
||||
const isNew = new Date(pr.created_at) > dateDaysBefore(NEW_RFC_PERIOD_DAYS)
|
||||
const isStale = new Date(pr.updated_at) < dateDaysBefore(STALE_RFC_PERIOD_DAYS)
|
||||
const status = isNew ? 'new' : (isStale ? 'stale' : 'proposed')
|
||||
|
||||
const filename = rfcFile.filename.replace("text/", "")
|
||||
|
||||
fs.writeFileSync(
|
||||
`mdbook/src/${status}/${filename}`,
|
||||
`[(source)](${pr.html_url})\n\n`
|
||||
+ TOC
|
||||
+ rawText
|
||||
)
|
||||
}
|
||||
|
||||
// Copy the approved (already-merged) RFCs markdown files, first adding a source link at the top and a TOC.
|
||||
for (const file of fs.readdirSync("text/")) {
|
||||
if (!file.endsWith(".md")) continue;
|
||||
const text = `[(source)](https://github.com/polkadot-fellows/RFCs/blob/main/text/${file})\n\n`
|
||||
+ TOC
|
||||
+ fs.readFileSync(`text/${file}`)
|
||||
fs.writeFileSync(`mdbook/src/approved/${file}`, text)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
name: mdBook
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Once a day
|
||||
|
||||
jobs:
|
||||
mdbook:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# For writing to gh-pages branch.
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout this repo
|
||||
uses: actions/checkout@v3
|
||||
# Gather mdbook source files - approved (merged) files, and open PRs.
|
||||
- name: Gather mdbook sources
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const script = require('.github/scripts/gather-mdbook-sources.js')
|
||||
await script({github, context})
|
||||
- name: Build the mdbook SUMMARY.md
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const script = require('.github/scripts/build-mdbook-summary.js')
|
||||
await script({github, context})
|
||||
- name: Setup mdBook binary
|
||||
uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0
|
||||
with:
|
||||
mdbook-version: '0.4.36'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cargo install mdbook-toc@0.14.1
|
||||
- name: Generate the mdbook
|
||||
run: |
|
||||
cd mdbook
|
||||
rm -rf ./book/
|
||||
mdbook build --dest-dir ./book/
|
||||
|
||||
- name: Deploy to github pages
|
||||
uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3
|
||||
with:
|
||||
publish_dir: ./mdbook/book
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Autogenerated
|
||||
book/
|
||||
|
||||
# Generated by the `build-mdbook-summary` script
|
||||
SUMMARY.md
|
||||
|
||||
# Generated by the `gather-mdbook-sources` script
|
||||
src/approved/
|
||||
src/new/
|
||||
src/proposed/
|
||||
src/stale/
|
||||
@@ -0,0 +1,8 @@
|
||||
# RFCs book
|
||||
|
||||
An mdbook-based web page for presenting approved and proposed RFCs.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [mdbook](https://github.com/rust-lang/mdBook)
|
||||
- [mdbook-toc](https://github.com/badboy/mdbook-toc)
|
||||
@@ -0,0 +1,23 @@
|
||||
[book]
|
||||
title = "Polkadot Fellowship RFCs"
|
||||
description = "An online book of RFCs approved or proposed within the Polkadot Fellowship."
|
||||
src = "src"
|
||||
|
||||
[build]
|
||||
create-missing = false
|
||||
|
||||
[output.html]
|
||||
additional-css = ["theme/polkadot.css"]
|
||||
default-theme = "polkadot"
|
||||
preferred-dark-theme = "polkadot"
|
||||
copy-fonts = true
|
||||
no-section-label = true
|
||||
|
||||
[output.html.font]
|
||||
enable = true
|
||||
woff = true
|
||||
|
||||
[preprocessor.toc]
|
||||
command = "mdbook-toc"
|
||||
renderer = ["html"]
|
||||
max-level = 3
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="Content" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 7277.19 2000"><defs><style>.cls-1{fill:#e6007a;}</style></defs><path d="M2384.74,504.19c-77.17,0-151.58,9.65-181.9,17.92-44.09,12.4-55.12,31.69-63.39,71.65l-175,807.52c-2.76,16.54-5.52,30.32-5.52,44.1,0,40,26.19,66.14,68.9,66.14,46.86,0,66.15-30.31,75.8-77.16l49.6-230.13c34.45,4.13,79.93,8.26,144.7,8.26,285.25,0,463-154.33,463-387.22C2760.94,621.32,2619,504.19,2384.74,504.19Zm-93.7,576c-44.1,0-78.55-1.37-110.25-5.51l92.33-428.56c28.94-4.14,71.66-9.65,115.76-9.65,151.58,0,228.75,71.66,228.75,190.17C2617.63,978.23,2507.39,1080.2,2291,1080.2Z"/><path d="M6874.28,1245.57c-23.42,0-38.58,13.78-67.52,45.47-51,52.37-82.68,81.3-122.64,81.3-35.83,0-55.13-28.93-55.13-75.79,0-26.18,5.52-57.87,12.41-92.32l51-239.78h153c48.23,0,77.17-27.56,77.17-77.17,0-27.56-17.91-48.23-59.25-48.23H6719.94l24.81-111.62c2.75-16.53,5.51-31.69,5.51-45.47,0-38.59-26.18-66.15-68.9-66.15-45.48,0-66.15,30.32-75.79,77.17l-31.7,146.07h-64.76c-49.61,0-78.55,27.56-78.55,77.17,0,27.56,19.29,48.23,60.63,48.23h56.5l-51,237c-5.51,26.18-12.4,68.9-12.4,113,0,111.62,57.88,192.92,181.9,192.92,71.66,0,135.05-35.83,183.28-78.55,46.85-41.34,81.3-92.32,81.3-125.4C6930.78,1271.75,6906,1245.57,6874.28,1245.57Z"/><path d="M3704.86,585.5c0-40-27.56-66.15-70.28-66.15-45.47,0-66.14,30.32-75.79,77.17l-172.25,800.63c-4.14,16.54-6.89,30.32-6.89,44.1,0,40,27.56,66.14,68.9,66.14,46.85,0,67.52-30.32,77.17-77.17L3698,629.59C3700.73,613.06,3704.86,599.28,3704.86,585.5Z"/><path d="M6164.6,825.27c-220.48,0-370.69,219.11-370.69,427.19,0,3.9.1,7.75.22,11.59-34.58,52.5-78.76,106.92-109.08,106.92-22.05,0-30.32-20.67-30.32-52.37,0-38.58,11-103.35,23.43-159.85l114.38-529.16c2.75-16.53,5.51-30.31,5.51-44.09,0-40-26.18-66.15-68.9-66.15-46.85,0-66.15,30.32-75.79,77.17l-62,286.63C5558.27,848.7,5510,825.27,5437,825.27c-146.43,0-293.7,112.73-351.1,285.6-63.21,163.42-119.7,260.1-164.27,260.1-16.53,0-26.18-13.78-26.18-37.21,0-68.9,38.58-237,55.12-318.32,5.51-30.32,8.27-42.72,8.27-60.64,0-60.63-100.6-132.29-231.51-132.29-151.37,0-288.48,95.86-357.24,238.35C4268,1241.28,4174.3,1371,4127.91,1371c-20.67,0-27.56-26.19-33.07-51l-34.45-190.17,210.84-172.25c19.29-16.54,44.09-40,44.09-70.28,0-37.2-24.8-62-62-62-27.56,0-51,16.54-74.41,35.83L3862,1122.92l106.11-493.33c2.76-16.53,6.89-30.31,6.89-44.09,0-40-27.56-66.15-70.28-66.15-45.47,0-66.14,30.32-75.79,77.17l-172.25,800.63c-4.13,16.54-6.89,30.32-6.89,44.1,0,40,27.56,66.14,68.9,66.14,46.85,0,67.52-30.32,77.17-77.17l22.05-103.35,129.53-104.73,31.7,159.85c12.4,63.39,45.47,125.4,130.91,125.4,85,0,151.86-77.63,218.85-182.52,20.33,109.86,98.48,182.52,206.95,182.52,108.86,0,183.27-64.77,231.5-151.58v2.75c0,89.58,45.48,148.83,125.4,148.83,72.26,0,132.29-43.57,185.91-136.21,30.41,80.73,98.38,136.21,193,136.21,111.62,0,191.54-67.52,242.53-161.23v8.27c0,99.22,49.61,153,130.91,153,71.78,0,132.82-41.66,184.86-109.53,39.61,67.8,110.59,109.53,206.5,109.53,220.48,0,370.68-219.1,370.68-428.56C6407.13,931.38,6317.56,825.27,6164.6,825.27ZM4790.73,1105c-40,172.25-125.4,270.09-221.86,270.09-64.77,0-100.6-49.61-100.6-124,0-146.07,106.11-303.17,248-303.17,42.71,0,75.79,12.41,104.73,30.32Zm767.54-73c-44.09,202.57-144.69,343.13-254.93,343.13-60.63,0-96.46-46.85-96.46-124,0-147.45,102-300.41,238.4-300.41,52.36,0,92.32,17.91,121.26,41.34ZM6053,1375.1c-79.92,0-113-57.88-113-130.91,0-133.67,92.32-286.63,208.08-286.63,79.92,0,113,57.88,113,130.91C6261.06,1223.52,6168.74,1375.1,6053,1375.1Z"/><path d="M3104.06,825.27c-220.49,0-370.69,219.11-370.69,427.19,0,148.82,89.57,254.93,242.53,254.93,220.48,0,370.69-219.1,370.69-428.56C3346.59,931.38,3257,825.27,3104.06,825.27ZM2992.44,1375.1c-79.93,0-113-57.88-113-130.91,0-133.67,92.33-286.63,208.08-286.63,79.93,0,113,57.88,113,130.91C3200.52,1223.52,3108.19,1375.1,2992.44,1375.1Z"/><ellipse class="cls-1" cx="1000" cy="441.78" rx="254.27" ry="147.95"/><ellipse class="cls-1" cx="1000" cy="1556.15" rx="254.27" ry="147.95"/><ellipse class="cls-1" cx="517.47" cy="720.38" rx="254.27" ry="147.95" transform="translate(-365.13 808.33) rotate(-60)"/><ellipse class="cls-1" cx="1482.53" cy="1277.56" rx="254.27" ry="147.95" transform="translate(-365.13 1922.69) rotate(-60)"/><ellipse class="cls-1" cx="517.47" cy="1277.56" rx="147.95" ry="254.27" transform="translate(-569.45 429.89) rotate(-30)"/><ellipse class="cls-1" cx="1482.53" cy="720.38" rx="147.95" ry="254.27" transform="translate(-161.57 837.78) rotate(-30)"/></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
|
||||
|
After Width: | Height: | Size: 963 B |
@@ -0,0 +1,8 @@
|
||||
<p><img width="30%" src="images/Polkadot_Logo_Horizontal_Pink_Black.svg" alt="Polkadot logo" /></p>
|
||||
|
||||
# Introduction
|
||||
|
||||
This book contains the Polkadot Fellowship Requests for Comments (RFCs)
|
||||
detailing proposed changes to the technical implementation of the Polkadot network.
|
||||
|
||||
<p><img width="2%" src="images/github-mark.svg" alt="GitHub logo" /> <a href="https://github.com/polkadot-fellows/RFCs/">polkadot-fellows/RFCs</a></p>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-ExtraLight.woff2) format("woff2");
|
||||
font-weight:200;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-Light.woff2) format("woff2");
|
||||
font-weight:300;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-Regular.woff2) format("woff2");
|
||||
font-weight:400;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-Medium.woff2) format("woff2");
|
||||
font-weight:500;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-Bold.woff2) format("woff2");
|
||||
font-weight:700;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@font-face {
|
||||
font-family:Unbounded;
|
||||
src:url(./Unbounded-Black.woff2) format("woff2");
|
||||
font-weight:900;
|
||||
font-style:normal;
|
||||
font-display:block
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
{{!--
|
||||
README:
|
||||
As instructed by the docs (https://rust-lang.github.io/mdBook/format/theme/index.html),
|
||||
this file is copied from the source repository and modified as need.
|
||||
|
||||
This file was taken from here: https://github.com/rust-lang/mdBook/blob/208d5ea7abc19ca47b22032ba2a4a4046ffe0902/src/theme/index.hbs,
|
||||
and modified in one place to add Polkadot theme to the theme selection widget.
|
||||
--}}
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="{{ language }}" class="{{ default_theme }}" dir="{{ text_direction }}">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
{{#if is_print }}
|
||||
<meta name="robots" content="noindex">
|
||||
{{/if}}
|
||||
{{#if base_url}}
|
||||
<base href="{{ base_url }}">
|
||||
{{/if}}
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
{{> head}}
|
||||
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
{{#if favicon_svg}}
|
||||
<link rel="icon" href="{{ path_to_root }}favicon.svg">
|
||||
{{/if}}
|
||||
{{#if favicon_png}}
|
||||
<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
|
||||
{{/if}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
|
||||
{{#if print_enable}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
|
||||
{{/if}}
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
|
||||
{{#if copy_fonts}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
|
||||
{{/if}}
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
{{#each additional_css}}
|
||||
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
|
||||
{{/each}}
|
||||
|
||||
{{#if mathjax_support}}
|
||||
<!-- MathJax -->
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
{{/if}}
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "{{ path_to_root }}";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('{{ default_theme }}')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
{{#toc}}{{/toc}}
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
{{> header}}
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="polkadot">Polkadot</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
{{#if search_enabled}}
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">{{ book_title }}</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
{{#if print_enable}}
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_url}}
|
||||
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_edit_url}}
|
||||
<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
|
||||
<i id="git-edit-button" class="fa fa-edit"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if search_enabled}}
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
{{{ content }}}
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/next}}
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
{{/next}}
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
{{#if live_reload_endpoint}}
|
||||
<!-- Livereload script (if served using the cli tool) -->
|
||||
<script>
|
||||
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
|
||||
const socket = new WebSocket(wsAddress);
|
||||
socket.onmessage = function (event) {
|
||||
if (event.data === "reload") {
|
||||
socket.close();
|
||||
location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
window.onbeforeunload = function() {
|
||||
socket.close();
|
||||
}
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if google_analytics}}
|
||||
<!-- Google Analytics Tag -->
|
||||
<script>
|
||||
var localAddrs = ["localhost", "127.0.0.1", ""];
|
||||
|
||||
// make sure we don't activate google analytics if the developer is
|
||||
// inspecting the book locally...
|
||||
if (localAddrs.indexOf(document.location.hostname) === -1) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{google_analytics}}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_line_numbers}}
|
||||
<script>
|
||||
window.playground_line_numbers = true;
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_copyable}}
|
||||
<script>
|
||||
window.playground_copyable = true;
|
||||
</script>
|
||||
{{/if}}
|
||||
|
||||
{{#if playground_js}}
|
||||
<script src="{{ path_to_root }}ace.js"></script>
|
||||
<script src="{{ path_to_root }}editor.js"></script>
|
||||
<script src="{{ path_to_root }}mode-rust.js"></script>
|
||||
<script src="{{ path_to_root }}theme-dawn.js"></script>
|
||||
<script src="{{ path_to_root }}theme-tomorrow_night.js"></script>
|
||||
{{/if}}
|
||||
|
||||
{{#if search_js}}
|
||||
<script src="{{ path_to_root }}elasticlunr.min.js"></script>
|
||||
<script src="{{ path_to_root }}mark.min.js"></script>
|
||||
<script src="{{ path_to_root }}searcher.js"></script>
|
||||
{{/if}}
|
||||
|
||||
<script src="{{ path_to_root }}clipboard.min.js"></script>
|
||||
<script src="{{ path_to_root }}highlight.js"></script>
|
||||
<script src="{{ path_to_root }}book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
{{#each additional_js}}
|
||||
<script src="{{ ../path_to_root }}{{this}}"></script>
|
||||
{{/each}}
|
||||
|
||||
{{#if is_print}}
|
||||
{{#if mathjax_support}}
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
MathJax.Hub.Register.StartupHook('End', function() {
|
||||
window.setTimeout(window.print, 100);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{else}}
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
window.setTimeout(window.print, 100);
|
||||
});
|
||||
</script>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,70 @@
|
||||
html.polkadot {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
}
|
||||
|
||||
.polkadot {
|
||||
--pink500: #E6007A;
|
||||
--purple600: #442299;
|
||||
--purple500: #552BBF;
|
||||
--purple400: #6D3AEE;
|
||||
--cyan700: #0094D4;
|
||||
--cyan600: #00A6ED;
|
||||
--cyan500: #00B2FF;
|
||||
--green700: #48CC81;
|
||||
--green600: #51E591;
|
||||
--green500: #56F39A;
|
||||
--lime700: #A9CC29;
|
||||
--lime600: #BEE52E;
|
||||
--lime500: #D3FF33;
|
||||
|
||||
--purple700: #321D47;
|
||||
--purple800: #28123E;
|
||||
--purple900: #1C0533;
|
||||
|
||||
--purple300: #DAE0F2;
|
||||
--purple200: #E6EAF6;
|
||||
--purple100: #F3F5FB;
|
||||
|
||||
|
||||
--bg: var(--purple100);
|
||||
--fg: #262625;
|
||||
|
||||
--sidebar-bg: var(--purple800);
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: var(--pink500);
|
||||
--sidebar-spacer: var(--purple700);
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #262625;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #6e6b5e;
|
||||
|
||||
--theme-popup-bg: var(--purple200);
|
||||
--theme-popup-border: var(--purple300);
|
||||
--theme-hover: var(--purple200);
|
||||
|
||||
--quote-bg: var(--purple200);
|
||||
--quote-border: var(--purple300);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: var(--purple200);
|
||||
--table-header-bg: var(--purple300);
|
||||
--table-alternate-bg: var(--purple200);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #fafafa;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #dec2a2;
|
||||
--search-mark-bg: var(--cyan500);
|
||||
|
||||
--color-scheme: light;
|
||||
}
|
||||
Reference in New Issue
Block a user