Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F96080342
myTpPlugin.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Dec 22, 10:13
Size
7 KB
Mime Type
text/x-c++
Expires
Tue, Dec 24, 10:13 (2 d)
Engine
blob
Format
Raw Data
Handle
23115141
Attached To
rTPELEVENTY tei-publisher-eleventy-plugin
myTpPlugin.js
View Options
const { JSDOM } = require("jsdom");
const axios = require("axios");
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
const chalk = require("chalk");
const debug = require("debug")("tei-publisher");
const { DateTime } = require("luxon");
const { AssetCache } = require("@11ty/eleventy-fetch");
const { TpPlugin } = require("@teipublisher/pb-eleventy-plugin/plugin");
function log(input, ...messages) {
console.log(`${chalk.cyan('[nietzsche-dm]')} ${input}`, ...messages);
}
function warn(input, ...messages) {
console.warn(`${chalk.red('[tei-publisher]')} ${input}`, ...messages);
}
function computeKey(params) {
const encParams = [];
Object.keys(params).sort().forEach((key) => {
encParams.push(`${key}=${params[key]}`);
});
//log('Compute key %s with params %s', JSON.stringify(encParams), JSON.stringify(params))
return encParams.join('&');
}
function getAttributes(elem, attributes, properties) {
attributes.forEach((attr) => {
if (elem.hasAttribute(attr)) {
if (attr === 'odd') {
properties[attr] = `${elem.getAttribute(attr)}.odd`;
} else {
properties[attr] = elem.getAttribute(attr);
}
}
});
return properties;
}
function getParameters(elem, properties) {
const params = elem.querySelectorAll('pb-param');
params.forEach((param) => {
properties[`user.${param.getAttribute('name')}`] = param.getAttribute('value');
});
return properties;
}
function createOutputDir(context) {
const outputDir = path.dirname(context.outputPath);
if (!fs.existsSync(outputDir)) {
mkdirp.sync(outputDir);
}
return {...context, ...{ outputDir }};
}
class MyPlugin extends TpPlugin {
constructor(config) {
super(config);
}
async post(url, data) {
log(`Posting data %s to %s`, chalk.white(JSON.stringify(data)), chalk.magenta(url))
const response = await this.client.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
}).catch(function (error) {
const err = error.toJSON();
debug('Failed to post data %s from %s: %s', chalk.bgRed(url), err.config.url, err.message);
});
if (!response) {
return `Failed to post ${url}`;
}
return response.data;
}
/**
*
* @param {string} content HTML content as string
* @param {Context} context context of the current request
* @returns
*/
async transform(content, context) {
const dom = JSDOM.fragment(content);
const views = [...dom.querySelectorAll('pb-view')];
if (views.length > 0) {
debug('Found %s views in page %s', chalk.blue(views.length), context.outputPath);
context = createOutputDir(context);
let componentsChanged = false;
const mapping = {};
const mapFile = path.resolve(context.outputDir, 'index.json');
let oldMap = {};
if (fs.existsSync(mapFile)) {
oldMap = JSON.parse(fs.readFileSync(mapFile));
}
for (let i = 0; i < views.length; i++) {
const component = views[i].id || `_v${1 + i}`;
let params = {};
const srcDoc = views[i].getAttribute('src');
let docPath = '';
if (!srcDoc) {
debug('No src attribute set for component %s in %s', chalk.blue(component), chalk.green(context.inputPath));
continue;
}
const doc = dom.getElementById(srcDoc);
docPath = doc.getAttribute('path');
const meta = await this._loadMeta(docPath);
if (!meta) {
throw new Error(`Failed to load metadata for ${docPath}`);
}
const lastModified = DateTime.fromISO(meta.lastModified);
const firstPageData = path.join(context.outputDir, `${component}-1.json`);
if (fs.existsSync(firstPageData)) {
const fileStat = fs.statSync(firstPageData);
if (lastModified < DateTime.fromMillis(fileStat.mtimeMs)) {
debug('Skipping component %s for %s as it is unchanged', chalk.blue(component), chalk.magenta(docPath));
const testRegex = new RegExp(`^${component}-`);
for (const [key, value] of Object.entries(oldMap)) {
if (testRegex.test(value)) {
mapping[key] = value;
}
}
continue;
}
}
if (meta.odd) {
params.odd = meta.odd;
}
if (meta.view) {
params.view = meta.view;
}
getAttributes(doc, ['view', 'map', 'view'], params);
getParameters(views[i], getAttributes(views[i], ['view', 'map', 'xpath'], params));
this._checkCSS(params, context);
log('Retrieving %s for %s', chalk.blue(component), chalk.magenta(docPath));
let next = null;
let counter = 1;
const images = [];
do {
next = await this._retrieve(component, docPath, params, context, mapping, next, counter, images);
counter += 1;
if (this.config.limit && counter > this.config.limit) {
break;
}
} while(next);
await this._loadImages(images, context.outputDir, `${this.config.remote}${docPath}`);
componentsChanged = true;
}
fs.writeFileSync(mapFile, JSON.stringify(mapping, null, 4));
if (componentsChanged) {
this._index(context);
}
}
return content; // no change done.
}
async _checkCSS(params, context) {
let odd = (params['user.odd']) ? params['user.odd'] : params.odd
log('Checking css %s for %s', chalk.blue(odd), chalk.magenta(JSON.stringify(params)));
if (odd) {
if (!fs.existsSync(context.baseDir)) {
mkdirp.sync(context.baseDir)
}
const file = `${odd.substring(0, odd.length - 4)}.css`;
const url = `transform/${file}`;
const outDir = path.resolve(context.baseDir, 'css');
mkdirp.sync(outDir);
const outFile = path.resolve(outDir, file);
if (!fs.existsSync(outFile)) {
this.client.request({
url,
method: 'get'
})
.then((response) => {
fs.writeFileSync(outFile, response.data);
})
.catch(function (error) {
const err = error.toJSON();
debug('Failed to load CSS from %s: %s', chalk.bgRed(err.config.url), err.message);
});
}
}
}
}
module.exports = { MyPlugin };
Event Timeline
Log In to Comment