mirror of
https://github.com/twirl/The-API-Book.git
synced 2025-01-05 10:20:22 +02:00
covers added
This commit is contained in:
parent
397b5d3557
commit
3dc0a64e59
40
build.js
40
build.js
@ -6,8 +6,6 @@ const builders = require('./src/lib/builders');
|
||||
const mdHtml = require('./src/lib/md-html');
|
||||
const htmlProcess = require('./src/lib/html-process');
|
||||
|
||||
const css = fs.readFileSync('./src/style.css', 'utf-8');
|
||||
|
||||
const l10n = {
|
||||
en: require('./src/en/l10n.json'),
|
||||
ru: require('./src/ru/l10n.json')
|
||||
@ -66,20 +64,20 @@ async function buildDoc (lang, targets, l10n) {
|
||||
}, [templates.sectionTitle(section)]).join(''))
|
||||
];
|
||||
|
||||
const html = targets.html || targets.pdf ? (await htmlProcess(
|
||||
templates.html(htmlContent.join(''), css, l10n), {
|
||||
base: __dirname
|
||||
}
|
||||
)).contents : '';
|
||||
|
||||
return Promise.all(['html', 'pdf', 'epub'].map((target) => {
|
||||
return targets[target] ? builders[target]({
|
||||
lang,
|
||||
structure,
|
||||
html,
|
||||
l10n,
|
||||
path: path.join(__dirname, 'docs', `API.${lang}.${target}`)
|
||||
}) : Promise.resolve();
|
||||
if (targets[target]) {
|
||||
return prepareHtml(htmlContent.join(''), l10n, target).then((html) => {
|
||||
return builders[target]({
|
||||
lang,
|
||||
structure,
|
||||
html,
|
||||
l10n,
|
||||
path: path.join(__dirname, 'docs', `API.${lang}.${target}`)
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@ -129,4 +127,16 @@ async function getStructure ({ path, l10n, pageBreak}) {
|
||||
|
||||
|
||||
return structure;
|
||||
}
|
||||
|
||||
async function prepareHtml (content, l10n, target) {
|
||||
if (target == 'epub') {
|
||||
return '';
|
||||
} else {
|
||||
return (await htmlProcess(
|
||||
templates[target == 'html' ? 'screenHtml' : 'printHtml'](content, l10n), {
|
||||
base: __dirname
|
||||
}
|
||||
)).contents;
|
||||
}
|
||||
}
|
11
package.json
11
package.json
@ -5,14 +5,15 @@
|
||||
"author": "Sergey Konstantinov <twirl-team@yandex.ru>",
|
||||
"repository": "github.com:twirl/The-API-Book",
|
||||
"devDependencies": {
|
||||
"puppeteer": "^5.5.0",
|
||||
"css": "^3.0.0",
|
||||
"epub-gen": "^0.1.0",
|
||||
"unified": "^9.2.0",
|
||||
"remark-parse": "^8.0.3",
|
||||
"remark-rehype": "^7.0.0",
|
||||
"image-data-uri": "^2.0.1",
|
||||
"puppeteer": "^5.5.0",
|
||||
"rehype-parse": "^7.0.1",
|
||||
"rehype-stringify": "^8.0.0",
|
||||
"image-data-uri": "^2.0.1"
|
||||
"remark-parse": "^8.0.3",
|
||||
"remark-rehype": "^7.0.0",
|
||||
"unified": "^9.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build.js"
|
||||
|
BIN
src/cover_300dpi.png
Normal file
BIN
src/cover_300dpi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
BIN
src/cover_96dpi.png
Normal file
BIN
src/cover_96dpi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 288 KiB |
@ -58,6 +58,10 @@ h3 {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
h3 a, h5 a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h4, h5 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
@ -1,22 +1,17 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const fsPath = require('path');
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
const Epub = require('epub-gen');
|
||||
|
||||
const css = fs.readFileSync(path.resolve(__dirname, '..', 'epub.css'), 'utf-8');
|
||||
const css = fs.readFileSync(fsPath.resolve(__dirname, '..', 'epub.css'), 'utf-8');
|
||||
|
||||
module.exports = {
|
||||
html: function ({ html, path }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(path, html, (e) => {
|
||||
if (e) {
|
||||
reject(e);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
fs.writeFileSync(path, html);
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
pdf: async function ({ path, html }) {
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
|
22
src/lib/css-process.js
Normal file
22
src/lib/css-process.js
Normal file
@ -0,0 +1,22 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const imageDataUri = require('image-data-uri');
|
||||
const reworkCss = require('css');
|
||||
|
||||
module.exports = (css) => {
|
||||
const ast = reworkCss.parse(css);
|
||||
|
||||
(ast.stylesheet.rules || []).forEach((rule) => {
|
||||
(rule.declarations || []).forEach((declaration) => {
|
||||
if (declaration.property == 'background-image') {
|
||||
const file = declaration.value.match(/url\((.+)\)/)[1];
|
||||
const data = fs.readFileSync(path.resolve(__dirname, '../..', file));
|
||||
const uri = imageDataUri.encode(data, 'image/png');
|
||||
declaration.value = `url(${uri})`;
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
return reworkCss.stringify(ast);
|
||||
}
|
@ -27,11 +27,41 @@ const chapterProcessor = () => {
|
||||
}
|
||||
}
|
||||
|
||||
let h5counter = 0;
|
||||
tree.children.slice().forEach((node, index) => {
|
||||
switch (node.tagName) {
|
||||
case 'h3':
|
||||
title.push(node.children[0].value);
|
||||
tree.children.splice(index, 1);
|
||||
h5counter = 0;
|
||||
break;
|
||||
case 'h5':
|
||||
let value = node.children[0].value;
|
||||
let number;
|
||||
const match = value.match(/^\d+/);
|
||||
if (!match) {
|
||||
number = ++h5counter;
|
||||
value = `${number}. ${value}`;
|
||||
} else {
|
||||
number = match[0];
|
||||
}
|
||||
const anchor = `chapter-${counter}-paragraph-${number}`;
|
||||
|
||||
node.children[0] = {
|
||||
type: 'element',
|
||||
tagName: 'a',
|
||||
properties: {
|
||||
href: '#' + anchor,
|
||||
name: anchor,
|
||||
className: ['anchor']
|
||||
},
|
||||
children: [{
|
||||
type: 'text',
|
||||
value
|
||||
}],
|
||||
position: node.children[0].position
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
imageProcess(node);
|
||||
|
58
src/print.css
Normal file
58
src/print.css
Normal file
@ -0,0 +1,58 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.github-corner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
pre, img {
|
||||
margin-right: 0.1em;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
:root {
|
||||
--main-font: 'PT Serif';
|
||||
--alt-font: 'PT Serif';
|
||||
--code-font: Inconsolata;
|
||||
}
|
||||
|
||||
.cover {
|
||||
background-image: url(./src/cover_300dpi.png);
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 100%;
|
||||
width: 100%;
|
||||
height: 10.05in;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.annotation {
|
||||
padding-top: 6in;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 1in 0.5in;
|
||||
font-size: 40pt;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p, ul, ol {
|
||||
orphans: 4;
|
||||
}
|
||||
|
||||
@page {
|
||||
margin: 0.5in;
|
||||
size: 8.5in 11in;
|
||||
}
|
||||
|
||||
@page:first {
|
||||
margin: 0;
|
||||
size: 7.5in 10in;
|
||||
}
|
12
src/screen.css
Normal file
12
src/screen.css
Normal file
@ -0,0 +1,12 @@
|
||||
h1 {
|
||||
font-size: 48px;
|
||||
background-image: url(./src/cover_96dpi.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 100%;
|
||||
height: 1056px;
|
||||
min-width: 300px;
|
||||
max-width: 816px;
|
||||
margin: 0 auto;
|
||||
padding-top: 4em;
|
||||
padding-left: 2em;
|
||||
}
|
@ -108,6 +108,10 @@ h4, h5 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.annotation {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.table-of-contents {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
@ -130,17 +134,6 @@ a.anchor {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: 8.5in 11in;
|
||||
margin: 0.5in;
|
||||
}
|
||||
|
||||
:root {
|
||||
--main-font: 'PT Serif';
|
||||
--alt-font: 'PT Serif';
|
||||
--code-font: Inconsolata;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
body {
|
||||
margin: 2em auto;
|
||||
@ -155,14 +148,19 @@ a.anchor {
|
||||
content: '¶';
|
||||
width: 0.8em;
|
||||
color: lightgray;
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
h5 a.anchor:before {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
a.anchor:hover:before {
|
||||
color: black;
|
||||
}
|
||||
|
||||
h2:not(.toc), h3 {
|
||||
margin-left: -0.8em;
|
||||
h2:not(.toc), h3, h5 {
|
||||
text-indent: -0.8em;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
@ -181,19 +179,6 @@ a.anchor {
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
h1 {
|
||||
margin: 4in 0 4in 0;
|
||||
}
|
||||
body {
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.github-corner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
body {
|
||||
padding: 2em;
|
||||
|
@ -1,5 +1,13 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const css = fs.readFileSync(path.resolve(__dirname, 'style.css'), 'utf-8');
|
||||
|
||||
const cssProcess = require('./lib/css-process');
|
||||
const printCss = cssProcess(fs.readFileSync(path.resolve(__dirname, 'print.css'), 'utf-8'));
|
||||
const screenCss = cssProcess(fs.readFileSync(path.resolve(__dirname, 'screen.css'), 'utf-8'));
|
||||
|
||||
const templates = module.exports = {
|
||||
html: (html, css, l10n) => {
|
||||
screenHtml: (html, l10n) => {
|
||||
return `<html><head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>${l10n.author}. ${l10n.title}</title>
|
||||
@ -12,6 +20,28 @@ const templates = module.exports = {
|
||||
<meta property="og:locale" content="${l10n.locale}"/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=PT+Serif&family=PT+Sans&family=Inconsolata"/>
|
||||
<style>${css}</style>
|
||||
<style>${screenCss}</style>
|
||||
</head><body>
|
||||
<article>
|
||||
${html}
|
||||
</article>
|
||||
</body></html>`;
|
||||
},
|
||||
|
||||
printHtml: (html, l10n) => {
|
||||
return `<html><head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>${l10n.author}. ${l10n.title}</title>
|
||||
<meta name="author" content="${l10n.author}"/>
|
||||
<meta name="description" content="${l10n.description}"/>
|
||||
<meta property="og:title" content="${l10n.author}. ${l10n.title}"/>
|
||||
<meta property="og:url" content="${l10n.url}"/>
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta property="og:description" content="${l10n.description}"/>
|
||||
<meta property="og:locale" content="${l10n.locale}"/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=PT+Serif&family=PT+Sans&family=Inconsolata"/>
|
||||
<style>${css}</style>
|
||||
<style>${printCss}</style>
|
||||
</head><body>
|
||||
<article>
|
||||
${html}
|
||||
|
Loading…
Reference in New Issue
Block a user