You've already forked The-API-Book
mirror of
https://github.com/twirl/The-API-Book.git
synced 2025-08-10 21:51:42 +02:00
various build improvements
This commit is contained in:
BIN
docs/API.en.epub
BIN
docs/API.en.epub
Binary file not shown.
120
docs/API.en.html
120
docs/API.en.html
@@ -346,6 +346,7 @@ ul.references li a.back-anchor {
|
||||
text-align: right;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
body > article {
|
||||
position: relative;
|
||||
}
|
||||
@@ -545,11 +546,6 @@ article ul.share {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body > article {
|
||||
margin: 2em auto;
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
a.anchor:before {
|
||||
display: inline-block;
|
||||
content: '¶';
|
||||
@@ -582,11 +578,6 @@ ul.references li p a.back-anchor {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
a.anchor:before {
|
||||
display: inline-block;
|
||||
content: '¶';
|
||||
@@ -609,18 +600,10 @@ ul.references li p a.back-anchor {
|
||||
text-indent: -0.8em;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%, 100% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
20%, 60% {
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
40%, 80% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
@media screen {
|
||||
body > article {
|
||||
margin: 2em auto;
|
||||
max-width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +647,98 @@ ul.references li p a.back-anchor {
|
||||
.cover {
|
||||
font-size: 2.8vw;
|
||||
}
|
||||
}</style>
|
||||
}
|
||||
|
||||
@media print {
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.toc a,
|
||||
ul li,
|
||||
ol li {
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0 0 1em 0;
|
||||
width: calc(100% - 2px);
|
||||
line-height: 0.8em !important;
|
||||
}
|
||||
|
||||
p code,
|
||||
pre code {
|
||||
font-size: 12pt !important;
|
||||
}
|
||||
|
||||
img {
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
img.cc-by-nc-img {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
break-after: avoid;
|
||||
line-height: 1.2em;
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
h6 {
|
||||
break-before: avoid;
|
||||
}
|
||||
|
||||
p,
|
||||
li {
|
||||
orphans: 5;
|
||||
widows: 5;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-top: 1em;
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
.cover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toc ul li ul li + li,
|
||||
h4 + ul,
|
||||
h4 + p {
|
||||
break-inside: avoid;
|
||||
break-before: avoid;
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
break-after: page;
|
||||
}
|
||||
|
||||
.no-page-break {
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
nav.page-main {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
@page {
|
||||
margin: 28mm 25mm 30mm 25mm;
|
||||
padding: 0;
|
||||
size: A4;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head><body><div class="fade display-none"></div>
|
||||
<aside class="side-panel display-none">
|
||||
<h3 class="title">Sergey Konstantinov. The API</h3>
|
||||
|
BIN
docs/API.en.pdf
BIN
docs/API.en.pdf
Binary file not shown.
Binary file not shown.
BIN
docs/API.ru.epub
BIN
docs/API.ru.epub
Binary file not shown.
396
docs/API.ru.html
396
docs/API.ru.html
File diff suppressed because one or more lines are too long
BIN
docs/API.ru.pdf
BIN
docs/API.ru.pdf
Binary file not shown.
BIN
docs/API.ru.sample.epub
Normal file
BIN
docs/API.ru.sample.epub
Normal file
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
"version": "2.0.0",
|
||||
"devDependencies": {
|
||||
"@jest/globals": "^29.6.4",
|
||||
"@twirl/book-builder": "0.0.27",
|
||||
"@twirl/book-builder": "0.0.28",
|
||||
"@types/jest": "^29.5.4",
|
||||
"express": "^4.18.2",
|
||||
"jest": "^29.6.4",
|
||||
@@ -22,9 +22,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node scripts/build.mjs",
|
||||
"build-samples": "node scripts/build.mjs en,ru epub 21-22 --sample",
|
||||
"build-v1": "node scripts/build-v1.mjs",
|
||||
"build-graphs": "node scripts/build-graphs.mjs",
|
||||
"build-clean": "node scripts/build.mjs --clean",
|
||||
"build-examples": "node scripts/build-examples.js \"docs/examples/01. Decomposing UI Components\"",
|
||||
"docs-server": "node scripts/docs-server 3000",
|
||||
"test": "jest"
|
||||
|
@@ -11,6 +11,8 @@ const { flags, args } = process.argv.slice(2).reduce(
|
||||
case '--no-cache':
|
||||
flags.noCache = true;
|
||||
break;
|
||||
case '--sample':
|
||||
flags.sample = true;
|
||||
}
|
||||
if (!v.startsWith('--')) {
|
||||
args.push(v);
|
||||
@@ -28,6 +30,24 @@ const l10n = {
|
||||
ru: JSON.parse(readFileSync('./src/ru/l10n.json', 'utf-8'))
|
||||
};
|
||||
|
||||
const css = ['fonts', 'common', 'screen', 'print', 'page', 'epub'].reduce(
|
||||
(css, file) => {
|
||||
css[file] = readFileSync(`src/css/${file}.css`).toString('utf-8');
|
||||
return css;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const targetCss = {
|
||||
html: [css.fonts, css.common, css.screen, css.print],
|
||||
pdf: [css.fonts, css.common, css.print],
|
||||
epub: [css.common, css.epub]
|
||||
};
|
||||
const extraCss = {
|
||||
html: css.page,
|
||||
pdf: css.page
|
||||
};
|
||||
|
||||
const langsToBuild = (args[0] && args[0].split(',').map((s) => s.trim())) || [
|
||||
'ru',
|
||||
'en'
|
||||
@@ -51,6 +71,7 @@ console.log(`Building langs: ${langsToBuild.join(', ')}…`);
|
||||
(async () => {
|
||||
for (const lang of langsToBuild) {
|
||||
await init({
|
||||
lang,
|
||||
l10n: l10n[lang],
|
||||
basePath: pathResolve(`src`),
|
||||
path: pathResolve(`src/${lang}/clean-copy`),
|
||||
@@ -94,6 +115,7 @@ console.log(`Building langs: ${langsToBuild.join(', ')}…`);
|
||||
},
|
||||
chapters,
|
||||
noCache,
|
||||
sample: flags.sample,
|
||||
cover: 'src/cover_embed.png'
|
||||
}).then(async (builder) => {
|
||||
for (const target of Object.keys(targets)) {
|
||||
@@ -102,8 +124,14 @@ console.log(`Building langs: ${langsToBuild.join(', ')}…`);
|
||||
target,
|
||||
pathResolve(
|
||||
'docs',
|
||||
`${l10n[lang].file}.${lang}.${target}`
|
||||
)
|
||||
`${l10n[lang].file}.${lang}${
|
||||
flags.sample ? '.sample' : ''
|
||||
}.${target}`
|
||||
),
|
||||
{
|
||||
css: targetCss[target],
|
||||
extraCss: extraCss[target]
|
||||
}
|
||||
);
|
||||
console.log(
|
||||
`Finished lang=${lang} target=${target}\n${Object.entries(
|
||||
|
@@ -1,61 +1,3 @@
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-VariableFont_wght.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-Italic-VariableFont_wght.ttf);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-Italic-VariableFont_wght.ttf);
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Regular.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Bold.ttf);
|
||||
font-weight: bold;
|
||||
}
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Italic.ttf);
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Italic.ttf);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-BoldItalic.ttf);
|
||||
font-style: oblique;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-BoldItalic.ttf);
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-monospace;
|
||||
src: url(/fonts/RobotoMono-VariableFont_wght.ttf);
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
@@ -1,5 +1,5 @@
|
||||
body {
|
||||
font-family: serif;
|
||||
font-family: 'Vollkorn', serif;
|
||||
font-size: 14pt;
|
||||
text-align: justify;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ h3,
|
||||
h4,
|
||||
h5 {
|
||||
text-align: left;
|
||||
font-family: sans-serif;
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
font-weight: bold;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
@@ -52,3 +52,8 @@ div {
|
||||
widows: 2;
|
||||
orphans: 2;
|
||||
}
|
||||
|
||||
pre,
|
||||
code {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
57
src/css/fonts.css
Normal file
57
src/css/fonts.css
Normal file
@@ -0,0 +1,57 @@
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-VariableFont_wght.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-Italic-VariableFont_wght.ttf);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-serif;
|
||||
src: url(/fonts/Vollkorn-Italic-VariableFont_wght.ttf);
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Regular.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Bold.ttf);
|
||||
font-weight: bold;
|
||||
}
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Italic.ttf);
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-Italic.ttf);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-BoldItalic.ttf);
|
||||
font-style: oblique;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-sans;
|
||||
src: url(/fonts/PTSans-BoldItalic.ttf);
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: local-monospace;
|
||||
src: url(/fonts/RobotoMono-VariableFont_wght.ttf);
|
||||
}
|
7
src/css/page.css
Normal file
7
src/css/page.css
Normal file
@@ -0,0 +1,7 @@
|
||||
@media print {
|
||||
@page {
|
||||
margin: 28mm 25mm 30mm 25mm;
|
||||
padding: 0;
|
||||
size: A4;
|
||||
}
|
||||
}
|
@@ -1,9 +1,4 @@
|
||||
@media print {
|
||||
@page {
|
||||
margin: 20mm 18mm 27mm 25mm;
|
||||
size: letter;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -50,7 +45,8 @@
|
||||
break-before: avoid;
|
||||
}
|
||||
|
||||
p {
|
||||
p,
|
||||
li {
|
||||
orphans: 5;
|
||||
widows: 5;
|
||||
}
|
||||
|
@@ -197,11 +197,6 @@ article ul.share {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body > article {
|
||||
margin: 2em auto;
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
a.anchor:before {
|
||||
display: inline-block;
|
||||
content: '¶';
|
||||
@@ -234,11 +229,6 @@ ul.references li p a.back-anchor {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
a.anchor:before {
|
||||
display: inline-block;
|
||||
content: '¶';
|
||||
@@ -261,19 +251,10 @@ ul.references li p a.back-anchor {
|
||||
text-indent: -0.8em;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
20%,
|
||||
60% {
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
40%,
|
||||
80% {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
@media screen {
|
||||
body > article {
|
||||
margin: 2em auto;
|
||||
max-width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -88,6 +88,11 @@
|
||||
"<p class=\"cc-by-nc\">This book is distributed under the <a href=\"https://creativecommons.org/licenses/by-nc/4.0/\">Creative Commons Attribution-NonCommercial 4.0 International licence</a>.</p>"
|
||||
]
|
||||
},
|
||||
"samplePage": {
|
||||
"contents": [
|
||||
"<p>This is a sample fragment comprising chapters 21 and 22 of the Section II: The API Patterns.</p>"
|
||||
]
|
||||
},
|
||||
"landing": {
|
||||
"subTitle": "Free e-book",
|
||||
"subscribeOn": "Subscribe for updates on",
|
||||
|
@@ -90,6 +90,11 @@
|
||||
"<p class=\"cc-by-nc\">Это произведение доступно по <a href=\"https://creativecommons.org/licenses/by-nc/4.0/\">лицензии Creative Commons «Attribution-NonCommercial» («Атрибуция — Некоммерческое использование») 4.0 Всемирная</a>.</p>"
|
||||
]
|
||||
},
|
||||
"samplePage": {
|
||||
"contents": [
|
||||
"<p>Этот ознакомительный фрагмент содержит главы 21 и 22 раздела «Паттерны API».</p>"
|
||||
]
|
||||
},
|
||||
"landing": {
|
||||
"subTitle": "Бесплатная электронная книга",
|
||||
"subscribeOn": "Подпишитесь на обновления на",
|
||||
|
@@ -30,6 +30,31 @@ export const templates = {
|
||||
}" href="https://isbnsearch.org/isbn/${isbn}">${l10n.isbn} ${isbn}</a>`;
|
||||
},
|
||||
|
||||
footerTemplate: (l10n) => {
|
||||
return `<html><head><style>
|
||||
.content {
|
||||
width: 100%;
|
||||
font-size: 12pt;
|
||||
font-family: local-serif, Vollkorn;
|
||||
text-align: right;
|
||||
margin: 0 25mm 18mm 25mm;
|
||||
border-top: 1px solid black;
|
||||
padding-top: 2mm;
|
||||
}
|
||||
.pageNumber {
|
||||
display: inline-block;
|
||||
border-left: 1px solid black;
|
||||
width: 30pt;
|
||||
}
|
||||
.title {
|
||||
padding-right: 4pt;
|
||||
}
|
||||
</style></head><body>
|
||||
<div class="content"><span class="title">${l10n.author}. ${l10n.title}</span>
|
||||
<span class="pageNumber"></span></div>
|
||||
</body></html>`;
|
||||
},
|
||||
|
||||
sidePanel: ({
|
||||
structure,
|
||||
l10n,
|
||||
@@ -99,6 +124,26 @@ export const templates = {
|
||||
templates
|
||||
})}</p><div class="page-break"></div>`,
|
||||
|
||||
samplePage: ({ l10n }) => `
|
||||
<div class="cover">
|
||||
<h1>
|
||||
<span class="author">${l10n.author}</span><br /><span class="title"
|
||||
>${l10n.frontPage.title}</span
|
||||
>
|
||||
</h1>
|
||||
</div><div class="annotation"><p class="text-align-left">
|
||||
<strong>${l10n.author}. ${l10n.title}.</strong><br />
|
||||
<a target="_blank" href="mailto:${l10n.links.email}">${
|
||||
l10n.links.emailString
|
||||
}</a> · <a target="_blank" href="${l10n.links.linkedinHref}">${
|
||||
l10n.links.linkedinString
|
||||
}</a> · <a target="_blank" href="${l10n.links.substackHref}">${
|
||||
l10n.links.substackString
|
||||
}</a></p>
|
||||
${l10n.samplePage.contents.join('\n')}
|
||||
<div class="page-break"></div>
|
||||
</div>`,
|
||||
|
||||
shareLink: (link, parameters) => {
|
||||
let result = link;
|
||||
for (const [key, value] of Object.entries(parameters)) {
|
||||
|
Reference in New Issue
Block a user