opendoc-theme 2.0.2 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -2
- data/_includes/directory.html +1 -1
- data/_includes/toc.html +7 -1
- data/_layouts/print.html +1 -1
- data/_sass/_base.scss +7 -0
- data/_sass/_print.scss +29 -2
- data/assets/js/search.js +3 -3
- data/assets/js/toolbar.js +14 -1
- data/assets/pdfs/empty +0 -0
- data/assets/startup/build.sh +5 -7
- data/assets/startup/docprint.html +1 -1
- data/assets/startup/pdf-gen.js +151 -74
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71f5e69914f38659f102e6567692052bd61896c2c0937ac04e60d5c3fccb21d5
|
4
|
+
data.tar.gz: 92bfa317395e7bc019884a3ca922a433ef315d74ca97e5d3d366e6942b482867
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70f4127b68434caa99d1faf4e89d5a9244dc9ae64c0ccb05510de955e868caffc50c715cc28db9c8e7f38e728814eb878b66dc823738f84316eb5865fe83cb45
|
7
|
+
data.tar.gz: 0f85ce9521b4da81788d0ec43a7438dadf09091a21f643c2d9ec88fd5a4478874fe3c4c38710aa41ab319adb6ee7ccd69c8a5a4b0170fd7bb95bfc1b70e45172
|
data/README.md
CHANGED
@@ -4,8 +4,7 @@ Welcome to your new Jekyll theme! In this directory, you'll find the files you n
|
|
4
4
|
|
5
5
|
# Deployment
|
6
6
|
- Update version number on `opendoc-theme.gemspec`
|
7
|
-
-
|
8
|
-
- Add tag with new version number to commit
|
7
|
+
- Add tag with new version number to commit e.g. `2.0.2`
|
9
8
|
- Push to origin
|
10
9
|
|
11
10
|
## Installation
|
data/_includes/directory.html
CHANGED
@@ -81,7 +81,7 @@ If there is only one folder or documents all at root, dont show back button
|
|
81
81
|
If there is only one folder, show expanded content list
|
82
82
|
{% endcomment %}
|
83
83
|
{% assign toc_id = 'toc_' | append: folder | downcase %}
|
84
|
-
{% if
|
84
|
+
{% if sorted_folders.size == 1 %}
|
85
85
|
<section class="contents lonely" id="{{ toc_id }}">
|
86
86
|
{% elsif include_currdir_decode == folder and include.currdir != '/' %}
|
87
87
|
<section class="contents" id="{{ toc_id }}">
|
data/_includes/toc.html
CHANGED
@@ -86,6 +86,12 @@ Output:
|
|
86
86
|
|
87
87
|
{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
|
88
88
|
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
|
89
|
+
{% comment %}
|
90
|
+
Strips out footnotes links then strips out all other html tags
|
91
|
+
This naively assumes that all footnote links are appended at the end of the header
|
92
|
+
{% endcomment %}
|
93
|
+
{% assign header = header | split: '<sup' | first %}
|
94
|
+
{% assign header = header | strip_html | strip %}
|
89
95
|
|
90
96
|
{% assign space = '' %}
|
91
97
|
{% for i in (1..indentAmount) %}
|
@@ -104,4 +110,4 @@ Output:
|
|
104
110
|
{% capture my_toc %}{:.{{ include.class }}}
|
105
111
|
{{ my_toc | lstrip }}{% endcapture %}
|
106
112
|
{% endif %}
|
107
|
-
{% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }}
|
113
|
+
{% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }}
|
data/_layouts/print.html
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
<link rel="stylesheet" href="./assets/styles/main.css">
|
14
14
|
</head>
|
15
15
|
|
16
|
-
<body
|
16
|
+
<body class="print-content">
|
17
17
|
<section class="description">
|
18
18
|
<img class="description-logo" src="{{ '.' | append: site.styling_options.logo_path }}">
|
19
19
|
<div class="description-title">{{ site.title }}</div>
|
data/_sass/_base.scss
CHANGED
data/_sass/_print.scss
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
/* print styles go here */
|
1
|
+
.print-content {
|
3
2
|
.site-header-text {
|
4
3
|
color: $primary-brand-color;
|
5
4
|
font-family: $header-font-family;
|
@@ -22,6 +21,34 @@
|
|
22
21
|
}
|
23
22
|
}
|
24
23
|
|
24
|
+
.print-content-small {
|
25
|
+
.site-header-text {
|
26
|
+
font-size: 25px;
|
27
|
+
}
|
28
|
+
|
29
|
+
#document-title {
|
30
|
+
font-size: 20px;
|
31
|
+
}
|
32
|
+
|
33
|
+
#main-content {
|
34
|
+
font-size: 13px;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
.print-content-large {
|
39
|
+
.site-header-text {
|
40
|
+
font-size: 40px;
|
41
|
+
}
|
42
|
+
|
43
|
+
#document-title {
|
44
|
+
font-size: 30px;
|
45
|
+
}
|
46
|
+
|
47
|
+
#main-content {
|
48
|
+
font-size: $base-font-size;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
25
52
|
@media print {
|
26
53
|
@page {
|
27
54
|
size: A4;
|
data/assets/js/search.js
CHANGED
@@ -92,7 +92,7 @@
|
|
92
92
|
|
93
93
|
// Load Lunr Index if set
|
94
94
|
// ============================================================================
|
95
|
-
var searchSetOffline = "{{ site.
|
95
|
+
var searchSetOffline = "{{ site.offline }}" === "true" || false
|
96
96
|
|
97
97
|
if (searchSetOffline) {
|
98
98
|
getLunrIndex()
|
@@ -263,7 +263,7 @@
|
|
263
263
|
var generateResultHTML = function (result, i) {
|
264
264
|
var element = document.createElement('a')
|
265
265
|
element.className = 'search-link nav-link'
|
266
|
-
var urlParts =
|
266
|
+
var urlParts = result.url.split('/')
|
267
267
|
urlParts = urlParts.filter(function (part) {
|
268
268
|
return part !== ''
|
269
269
|
})
|
@@ -577,4 +577,4 @@
|
|
577
577
|
}
|
578
578
|
}
|
579
579
|
|
580
|
-
})()
|
580
|
+
})()
|
data/assets/js/toolbar.js
CHANGED
@@ -61,7 +61,20 @@
|
|
61
61
|
|
62
62
|
printButtons.forEach(function (btn) {
|
63
63
|
btn.addEventListener('click', function () {
|
64
|
-
|
64
|
+
// S3 folder name; replace slashes to avoid creating sub-folders
|
65
|
+
var replacedRepoName = '{{ site.repository }}'.replace(/\//g, '-')
|
66
|
+
var pdfUrl = '{{ site.offline }}' === 'true' ?
|
67
|
+
'{{ "/assets/pdfs" | relative_url }}' :
|
68
|
+
'https://opendoc-theme-pdf.s3-ap-southeast-1.amazonaws.com/' + replacedRepoName
|
69
|
+
var page = pageIndex[window.location.pathname]
|
70
|
+
// documentTitle refers to the name of the document folder
|
71
|
+
// If page.dir is slash, that indicates the root directory
|
72
|
+
// PDF at root dir is named export.pdf
|
73
|
+
var documentTitle = page.dir !== '/' ? page.dir : '/export/'
|
74
|
+
if (documentTitle) {
|
75
|
+
pdfUrl += documentTitle.substring(0, documentTitle.length-1) + '.pdf'
|
76
|
+
}
|
77
|
+
window.open(pdfUrl, '_blank')
|
65
78
|
})
|
66
79
|
})
|
67
80
|
|
data/assets/pdfs/empty
ADDED
File without changes
|
data/assets/startup/build.sh
CHANGED
@@ -5,14 +5,12 @@
|
|
5
5
|
echo 'Started script to generate PDFs'
|
6
6
|
echo 'Installing node dependencies'
|
7
7
|
npm i glob jsdom js-yaml p-all
|
8
|
-
if [
|
9
|
-
npm i html-pdf
|
10
|
-
fi
|
11
|
-
node _site/assets/startup/pdf-gen.js
|
12
|
-
if [ "{{ site.offline_search_only }}" == "true" ]; then
|
8
|
+
if [ "{{ site.offline }}" == "true" ]; then
|
13
9
|
node _site/assets/startup/prebuild-lunr-index.js
|
14
|
-
echo 'Generating
|
10
|
+
echo 'Generating lunr index complete'
|
11
|
+
npm i html-pdf
|
15
12
|
else
|
16
|
-
echo 'Skipping
|
13
|
+
echo 'Skipping lunr index'
|
17
14
|
fi
|
15
|
+
node _site/assets/startup/pdf-gen.js
|
18
16
|
echo 'End script'
|
data/assets/startup/pdf-gen.js
CHANGED
@@ -1,28 +1,47 @@
|
|
1
|
+
---
|
2
|
+
---
|
1
3
|
const fs = require('fs')
|
2
|
-
const
|
4
|
+
const crypto = require('crypto')
|
3
5
|
const pAll = require('p-all')
|
4
6
|
const https = require('https')
|
5
7
|
const glob = require('glob')
|
6
8
|
const path = require('path')
|
9
|
+
const URL = require('url').URL;
|
7
10
|
const jsdom = require('jsdom')
|
8
11
|
const jsyaml = require('js-yaml')
|
9
12
|
const sitePath = __dirname + '/../..'
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
let generatingPdfLocally = '{{ site.offline }}' === 'true' || false
|
15
|
+
const S3StorageUrl = new URL('https://opendoc-theme-pdf.s3-ap-southeast-1.amazonaws.com')
|
16
|
+
|
17
|
+
const localPdfFolder = path.join(sitePath, 'assets', 'pdfs') // local folder for pdfs
|
18
|
+
// S3 folder; replace slashes to avoid creating sub-folders
|
19
|
+
const S3PdfFolder = '{{ site.repository }}'.replace(/\//g, '-')
|
20
|
+
|
21
|
+
const bucketName = S3StorageUrl.hostname.split('.')[0]
|
22
|
+
|
23
|
+
// CSS to be applied to the PDFs, this will be inserted in <head>
|
24
|
+
const pathToCss = path.join(sitePath, 'assets', 'styles', 'main.css')
|
25
|
+
|
26
|
+
// Hash is stored as S3 metadata and served as custom header whenever the pdf is requested
|
27
|
+
const serializedHtmlHashHeader = 'x-amz-meta-html-hash'
|
15
28
|
|
16
|
-
|
17
|
-
|
29
|
+
let pdf
|
30
|
+
let pdfGenConcurrency = 1
|
31
|
+
if (generatingPdfLocally) {
|
18
32
|
pdf = require('html-pdf')
|
19
|
-
|
20
|
-
PDF_GEN_CONCURRENCY = 1 // When generating locally make it synchronous
|
33
|
+
console.log('Generating PDFs and storing locally instead.')
|
21
34
|
} else {
|
22
|
-
|
35
|
+
if (process.env.PDF_LAMBDA_KEY === undefined ||
|
36
|
+
process.env.PDF_LAMBDA_SERVER === undefined) {
|
37
|
+
console.log('Environment variables PDF_LAMBDA_KEY or PDF_LAMBDA_SERVER for AWS Lambda not present')
|
38
|
+
process.exit(1)
|
39
|
+
}
|
40
|
+
pdfGenConcurrency = process.env.PDF_GEN_CONCURRENCY !== undefined ?
|
23
41
|
parseInt(process.env.PDF_GEN_CONCURRENCY) :
|
24
42
|
50 // Tuned for Netlify
|
25
|
-
console.log(`
|
43
|
+
console.log(`Generating PDFs on AWS Lambda with concurrency of ${pdfGenConcurrency}.`)
|
44
|
+
console.log(`PDFs will be placed in bucket: ${bucketName} in folder ${S3PdfFolder}.`)
|
26
45
|
}
|
27
46
|
|
28
47
|
// These options are only applied when PDFs are built locally
|
@@ -49,19 +68,19 @@ const printIgnoreFiles = ['export.html', 'index.html']
|
|
49
68
|
|
50
69
|
// Tracking statistics
|
51
70
|
let numPdfsStarted = 0
|
71
|
+
let numPdfsUnchanged = 0
|
52
72
|
let numPdfsError = 0
|
53
73
|
let numPdfsSuccess = 0
|
54
74
|
let numTotalPdfs = 0
|
55
75
|
const TIMER = 'Time to create PDFs'
|
56
76
|
|
57
77
|
const main = async () => {
|
58
|
-
|
59
78
|
// creating exports of individual documents
|
60
79
|
console.time(TIMER)
|
61
80
|
const docFolders = getDocumentFolders(sitePath, printIgnoreFolders)
|
62
81
|
await exportPdfTopLevelDocs(sitePath)
|
63
82
|
await exportPdfDocFolders(sitePath, docFolders)
|
64
|
-
console.log(`PDFs created with success:${numPdfsSuccess} error:${numPdfsError} total:${numTotalPdfs}`)
|
83
|
+
console.log(`PDFs created with success:${numPdfsSuccess} unchanged:${numPdfsUnchanged} error:${numPdfsError} total:${numTotalPdfs}`)
|
65
84
|
console.timeEnd(TIMER)
|
66
85
|
}
|
67
86
|
|
@@ -77,7 +96,7 @@ const exportPdfTopLevelDocs = async (sitePath) => {
|
|
77
96
|
const configYml = yamlToJs(configFilepath)
|
78
97
|
htmlFilePaths = reorderHtmlFilePaths(htmlFilePaths, configYml.order)
|
79
98
|
}
|
80
|
-
await createPdf(htmlFilePaths, sitePath)
|
99
|
+
await createPdf(htmlFilePaths, sitePath, 'export')
|
81
100
|
}
|
82
101
|
|
83
102
|
const exportPdfDocFolders = (sitePath, docFolders) => {
|
@@ -90,7 +109,7 @@ const exportPdfDocFolders = (sitePath, docFolders) => {
|
|
90
109
|
htmlFilePaths = htmlFilePaths.map((filepath) => path.join(folderPath, filepath))
|
91
110
|
|
92
111
|
// Remove folders without HTML files (don't want empty pdfs)
|
93
|
-
if (htmlFilePaths.length === 0)
|
112
|
+
if (htmlFilePaths.length === 0) continue
|
94
113
|
numTotalPdfs++
|
95
114
|
const indexFilepath = path.join(sitePath, '..', folder, 'index.md')
|
96
115
|
if (indexFileHasValidOrdering(indexFilepath)) {
|
@@ -98,16 +117,22 @@ const exportPdfDocFolders = (sitePath, docFolders) => {
|
|
98
117
|
const order = configMd.order
|
99
118
|
htmlFilePaths = reorderHtmlFilePaths(htmlFilePaths, order)
|
100
119
|
}
|
101
|
-
actions.push((() => createPdf(htmlFilePaths, folderPath)))
|
120
|
+
actions.push((() => createPdf(htmlFilePaths, folderPath, folder)))
|
102
121
|
}
|
103
|
-
return pAll(actions, { concurrency:
|
122
|
+
return pAll(actions, { concurrency: pdfGenConcurrency })
|
104
123
|
}
|
105
124
|
|
106
125
|
// Concatenates the contents in .html files, and outputs export.pdf in the specified output folder
|
107
|
-
const createPdf = (htmlFilePaths, outputFolderPath) => {
|
126
|
+
const createPdf = (htmlFilePaths, outputFolderPath, documentName) => {
|
108
127
|
logStartedPdf(outputFolderPath)
|
109
128
|
// docprint.html is our template to build pdf up from.
|
110
129
|
const exportHtmlFile = fs.readFileSync(__dirname + '/docprint.html')
|
130
|
+
let cssFile = ''
|
131
|
+
try {
|
132
|
+
cssFile = fs.readFileSync(pathToCss)
|
133
|
+
} catch(err) {
|
134
|
+
console.log('Failed to read CSS file at ' + pathToCss +', CSS will not be applied')
|
135
|
+
}
|
111
136
|
const exportDom = new jsdom.JSDOM(exportHtmlFile)
|
112
137
|
const exportDomBody = exportDom.window.document.body
|
113
138
|
const exportDomMain = exportDom.window.document.getElementById('main-content')
|
@@ -123,19 +148,7 @@ const createPdf = (htmlFilePaths, outputFolderPath) => {
|
|
123
148
|
// html-pdf can't deal with these
|
124
149
|
removeTagsFromDom(dom, 'script')
|
125
150
|
removeTagsFromDom(dom, 'iframe')
|
126
|
-
|
127
|
-
// If a <img src=...> link src begins with '/', it is a relative link
|
128
|
-
// and needs to be prepended with '.' to show up in the pdf. Does not
|
129
|
-
// work for Lambda functions as the images are not available server side.
|
130
|
-
const imgsrcs = dom.window.document.getElementsByTagName('img')
|
131
|
-
for (let i = 0; i < imgsrcs.length; i++) {
|
132
|
-
const imgsrc = imgsrcs[i]
|
133
|
-
if (imgsrc.src.startsWith('/')) {
|
134
|
-
imgsrc.src = '.' + imgsrc.src
|
135
|
-
} else if (imgsrc.src.startsWith('.')) {
|
136
|
-
imgsrc.src = outputFolderPath + imgsrc.src.substr(1)
|
137
|
-
}
|
138
|
-
}
|
151
|
+
inlineImages(dom, outputFolderPath)
|
139
152
|
|
140
153
|
// Site titles needs only be added once
|
141
154
|
if (!addedTitle) {
|
@@ -169,10 +182,15 @@ const createPdf = (htmlFilePaths, outputFolderPath) => {
|
|
169
182
|
}
|
170
183
|
dom.window.close()
|
171
184
|
})
|
172
|
-
|
173
|
-
|
185
|
+
const serializedHtmlHash = crypto.createHash('md5').update(exportDom.serialize()).digest('base64')
|
186
|
+
exportDom.window.document.head.innerHTML += '<style>' + cssFile + '</style>'
|
187
|
+
console.log('createpdf hash for:' + outputFolderPath + ': ' + serializedHtmlHash)
|
188
|
+
if (generatingPdfLocally) {
|
189
|
+
exportDomBody.className += ' print-content-large'
|
190
|
+
// Generate and store locally
|
174
191
|
return new Promise((resolve, reject) => {
|
175
|
-
|
192
|
+
const url = path.join(localPdfFolder, documentName + '.pdf')
|
193
|
+
pdf.create(exportDom.serialize(), localPdfOptions).toFile(url, (err, res) => {
|
176
194
|
if (err) {
|
177
195
|
logErrorPdf('Creating PDFs locally', err)
|
178
196
|
return reject()
|
@@ -183,51 +201,73 @@ const createPdf = (htmlFilePaths, outputFolderPath) => {
|
|
183
201
|
exportDom.window.close()
|
184
202
|
})
|
185
203
|
} else {
|
204
|
+
// Apply small font sizes because puppeteer tends to print big
|
205
|
+
exportDomBody.className += ' print-content-small'
|
186
206
|
// Code for this API lives at https://github.com/opendocsg/pdf-lambda
|
187
|
-
const
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
}
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
if (res.statusCode < 200 || res.statusCode >= 300) {
|
198
|
-
logErrorPdf('Request status code', res.statusCode)
|
199
|
-
reject()
|
207
|
+
const pdfName = `${documentName}.pdf`
|
208
|
+
return new Promise(function (resolve, reject) {
|
209
|
+
// Promise resolves if PDF is present and hash matches. Else reject.
|
210
|
+
const pdfS3Url = S3StorageUrl.toString() + S3PdfFolder + '/' + pdfName
|
211
|
+
const options = {
|
212
|
+
method: 'HEAD'
|
213
|
+
}
|
214
|
+
const pdfExistsRequest = https.request(pdfS3Url, options, function (res) {
|
215
|
+
if (res.statusCode === 404) {
|
216
|
+
return reject('PDF not present')
|
200
217
|
}
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
218
|
+
if (!(serializedHtmlHashHeader in res.headers)) {
|
219
|
+
return reject('HTML hash header not present')
|
220
|
+
}
|
221
|
+
if (res.headers[serializedHtmlHashHeader] !== serializedHtmlHash) {
|
222
|
+
return reject('PDF hash does not match')
|
223
|
+
}
|
224
|
+
logUnchangedPdf(pdfName, pdfS3Url)
|
225
|
+
resolve()
|
209
226
|
})
|
210
|
-
|
211
|
-
|
212
|
-
reject()
|
227
|
+
pdfExistsRequest.on('error', function (err) {
|
228
|
+
console.log(`pdfExistsRequest encountered error for ${pdfName}:, ${err}`)
|
229
|
+
return reject()
|
213
230
|
})
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
231
|
+
pdfExistsRequest.end()
|
232
|
+
}).then(() => {},
|
233
|
+
function (rejected) {
|
234
|
+
// Rejected: send to lambda function to create PDF
|
235
|
+
const options = {
|
236
|
+
method: 'POST',
|
237
|
+
headers: {
|
238
|
+
'x-api-key': process.env.PDF_LAMBDA_KEY,
|
239
|
+
'content-type': 'application/json',
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
const pdfCreationBody = {
|
244
|
+
'serializedHTML': exportDom.serialize(),
|
245
|
+
'serializedHTMLName': S3PdfFolder + '/' + pdfName,
|
246
|
+
'serializedHTMLHash': serializedHtmlHash,
|
247
|
+
'bucketName': bucketName
|
248
|
+
}
|
249
|
+
return new Promise(function (resolve, reject) {
|
250
|
+
const pdfCreationRequest = https.request(process.env.PDF_LAMBDA_SERVER, options, function (res) {
|
251
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
252
|
+
logErrorPdf(`pdfCreationRequest status code for ${pdfName}: `, res.statusCode)
|
253
|
+
return reject()
|
254
|
+
}
|
255
|
+
logSuccessPdf(pdfName)
|
256
|
+
return resolve()
|
257
|
+
})
|
258
|
+
pdfCreationRequest.on('error', function(err) {
|
259
|
+
logErrorPdf(`pdfCreationRequest encountered error for ${pdfName}:`, err)
|
260
|
+
return reject()
|
261
|
+
})
|
262
|
+
pdfCreationRequest.write(JSON.stringify(pdfCreationBody))
|
263
|
+
pdfCreationRequest.end()
|
264
|
+
}).catch((error) => {
|
265
|
+
logErrorPdf(`pdfCreation promise error for ${pdfName}`, error)
|
266
|
+
}).finally(() => {
|
267
|
+
exportDom.window.close()
|
227
268
|
})
|
228
|
-
|
229
|
-
|
230
|
-
})
|
269
|
+
|
270
|
+
})
|
231
271
|
}
|
232
272
|
}
|
233
273
|
|
@@ -236,6 +276,11 @@ const logStartedPdf = (outputFolderPath) => {
|
|
236
276
|
console.log(`createpdf started for:${outputFolderPath} (${numPdfsStarted}/${numTotalPdfs})`)
|
237
277
|
}
|
238
278
|
|
279
|
+
const logUnchangedPdf = (outputFolderPath, pdfUrl) => {
|
280
|
+
numPdfsUnchanged++
|
281
|
+
console.log(`createpdf unchanged for:${outputFolderPath} at ${pdfUrl} (${numPdfsUnchanged}/${numTotalPdfs})`)
|
282
|
+
}
|
283
|
+
|
239
284
|
const logErrorPdf = (origin, error) => {
|
240
285
|
numPdfsError++
|
241
286
|
console.log(`createpdf error for: ${origin}: ${error}(${numPdfsError}/${numTotalPdfs})`)
|
@@ -246,6 +291,38 @@ const logSuccessPdf = (outputPdfPath) => {
|
|
246
291
|
console.log(`createpdf success for:${outputPdfPath} (${numPdfsSuccess}/${numTotalPdfs})`)
|
247
292
|
}
|
248
293
|
|
294
|
+
const imageType = {
|
295
|
+
'.png':'image/png',
|
296
|
+
'.jpg':'image/jpeg',
|
297
|
+
'.jpeg':'image/jpeg',
|
298
|
+
'.bmp':'image/bmp',
|
299
|
+
'.webp':'image/webp',
|
300
|
+
}
|
301
|
+
|
302
|
+
// Load images and inline them
|
303
|
+
const inlineImages = (dom, outputFolderPath) => {
|
304
|
+
const imgs = dom.window.document.getElementsByTagName('img')
|
305
|
+
for (let i = 0; i < imgs.length; i++) {
|
306
|
+
const img = imgs[i]
|
307
|
+
if (!img.src.startsWith('http')) {
|
308
|
+
// Convert all file paths into absolute file paths
|
309
|
+
const imgPath = img.src.startsWith('/') ?
|
310
|
+
path.join(__dirname, '..', '..', img.src).toString() :
|
311
|
+
path.join(outputFolderPath, img.src).toString()
|
312
|
+
if (fs.existsSync(imgPath)) {
|
313
|
+
const imgRaw = fs.readFileSync(imgPath)
|
314
|
+
if (path.extname(imgPath) === '.svg') { // don't encode svgs in base64, simply insert them
|
315
|
+
img.src = 'data:image/svg+xml;utf8,' + imgRaw.toString('utf-8')
|
316
|
+
} else {
|
317
|
+
const dataType = imageType[path.extname(imgPath)] || 'image/png'
|
318
|
+
const uri = 'data:' + dataType + ';base64,' + imgRaw.toString('base64')
|
319
|
+
img.src = uri
|
320
|
+
}
|
321
|
+
}
|
322
|
+
}
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
249
326
|
// Returns a list of the valid document (i.e. folder) paths
|
250
327
|
const getDocumentFolders = (sitePath, printIgnoreFolders) => {
|
251
328
|
return fs.readdirSync(sitePath).filter(function (filePath) {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opendoc-theme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Opendoc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- assets/js/pre-loader.js
|
117
117
|
- assets/js/search.js
|
118
118
|
- assets/js/toolbar.js
|
119
|
+
- assets/pdfs/empty
|
119
120
|
- assets/siteIndex.json
|
120
121
|
- assets/startup/build.sh
|
121
122
|
- assets/startup/docprint.html
|
@@ -150,7 +151,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
151
|
- !ruby/object:Gem::Version
|
151
152
|
version: '0'
|
152
153
|
requirements: []
|
153
|
-
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.7.7
|
154
156
|
signing_key:
|
155
157
|
specification_version: 4
|
156
158
|
summary: Jekyll theme for Opendoc sites
|