New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@jsreport/jsreport-pptx

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jsreport/jsreport-pptx - npm Package Compare versions

Comparing version 4.0.1 to 4.1.0

lib/postprocess/chart.js

6

lib/postprocess/postprocess.js
const slides = require('./slides')
const style = require('./style')
const image = require('./image')
const chart = require('./chart')
const clearOriginalSlideNumber = require('./clearOriginalSlideNumber')
module.exports = async (files) => {
slides(files)
style(files)
await image(files)
await chart(files)
clearOriginalSlideNumber(files)
}

8

lib/postprocess/slides.js

@@ -39,5 +39,11 @@ const { nodeListToArray } = require('../utils')

slideNumber++
const newSlideDoc = new DOMParser().parseFromString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n${slides[i].toString()}`)
// this attribute is going to be removed later as some of the last steps of postprocess
newSlideDoc.documentElement.setAttribute('originalSlideNumber', originalSlideNumber)
files.push({
path: `ppt/slides/slide${slideNumber}.xml`,
doc: slides[i]
doc: newSlideDoc
})

@@ -44,0 +50,0 @@

@@ -5,2 +5,4 @@ const concatTags = require('./concatTags')

const table = require('./table')
const chart = require('./chart')
const style = require('./style')

@@ -10,4 +12,6 @@ module.exports = (files) => {

slides(files)
chart(files)
list(files)
table(files)
style(files)
}

14

lib/processPptx.js

@@ -10,3 +10,3 @@ const { DOMParser, XMLSerializer } = require('@xmldom/xmldom')

module.exports = (reporter) => async (inputs, req) => {
module.exports = async (reporter, inputs, req) => {
const { pptxTemplateContent, outputPath } = inputs

@@ -84,11 +84,15 @@

for (const f of files) {
let isXML = false
let shouldSerializeFromDoc
if (f.data == null) {
isXML = f.path.includes('.xml')
shouldSerializeFromDoc = f.path.includes('.xml')
} else {
isXML = contentIsXML(f.data)
shouldSerializeFromDoc = contentIsXML(f.data)
}
if (isXML) {
if (f.serializeFromDoc != null) {
shouldSerializeFromDoc = f.serializeFromDoc === true
}
if (shouldSerializeFromDoc) {
f.data = Buffer.from(new XMLSerializer().serializeToString(f.doc))

@@ -95,0 +99,0 @@ }

@@ -1,2 +0,1 @@

const fs = require('fs')
const { response } = require('@jsreport/office')

@@ -38,3 +37,3 @@ const processPptx = require('./processPptx')

const result = await processPptx(reporter)({
const result = await processPptx(reporter, {
pptxTemplateContent: templateAsset.content,

@@ -46,10 +45,8 @@ outputPath

res.stream = fs.createReadStream(result.pptxFilePath)
await response({
previewOptions: definition.options.preview,
officeDocumentType: 'pptx',
stream: res.stream,
filePath: result.pptxFilePath,
logger: reporter.logger
}, req, res)
}

@@ -0,2 +1,11 @@

const { XMLSerializer } = require('@xmldom/xmldom')
function nodeListToArray (nodes) {
const arr = []
for (let i = 0; i < nodes.length; i++) {
arr.push(nodes[i])
}
return arr
}
function pxToEMU (val) {

@@ -14,2 +23,329 @@ return Math.round(val * 914400 / 96)

function getNewRelIdFromBaseId (relsDoc, itemsMap, baseId) {
const relationsNodes = nodeListToArray(relsDoc.getElementsByTagName('Relationship'))
const getId = (id) => {
const regExp = /^rId(\d+)$/
const match = regExp.exec(id)
if (!match || !match[1]) {
return null
}
return parseInt(match[1], 10)
}
const maxId = relationsNodes.reduce((lastId, node) => {
const nodeId = node.getAttribute('Id')
const num = getId(nodeId)
if (num == null) {
return lastId
}
if (num > lastId) {
return num
}
return lastId
}, 0)
const baseIdNum = getId(baseId)
if (baseIdNum == null) {
throw new Error(`Unable to get numeric id from rel id "${baseId}"`)
}
let newId = getNewIdFromBaseId(itemsMap, baseIdNum, maxId)
newId = `rId${newId}`
return newId
}
function getNewIdFromBaseId (itemsMap, baseId, maxId) {
const counter = itemsMap.get(baseId) || 0
itemsMap.set(baseId, counter + 1)
if (counter === 0) {
return baseId
}
return maxId + 1
}
function getCNvPrEl (graphicFrameEl) {
const containerEl = nodeListToArray(graphicFrameEl.childNodes).find((node) => node.nodeName === 'p:nvGraphicFramePr')
if (!containerEl) {
return
}
const cNvPrEl = nodeListToArray(containerEl.childNodes).find((node) => node.nodeName === 'p:cNvPr')
return cNvPrEl
}
function getChartEl (graphicFrameEl) {
let parentEl = graphicFrameEl.parentNode
const graphicEl = nodeListToArray(graphicFrameEl.childNodes).find((node) => node.nodeName === 'a:graphic')
if (!graphicEl) {
return
}
const graphicDataEl = nodeListToArray(graphicEl.childNodes).find((node) => node.nodeName === 'a:graphicData')
if (!graphicDataEl) {
return
}
let chartDrawingEl = nodeListToArray(graphicDataEl.childNodes).find((node) => (
node.nodeName === 'c:chart' || node.nodeName === 'cx:chart'
))
if (!chartDrawingEl) {
return
}
while (parentEl != null) {
// ignore charts that are part of Fallback tag
if (parentEl.nodeName === 'mc:Fallback') {
chartDrawingEl = null
break
}
parentEl = parentEl.parentNode
}
return chartDrawingEl
}
function getClosestEl (el, targetNodeNameOrFn, targetType = 'parent') {
let currentEl = el
let parentEl
const nodeTest = (n) => {
if (typeof targetNodeNameOrFn === 'string') {
return n.nodeName === targetNodeNameOrFn
} else {
return targetNodeNameOrFn(n)
}
}
if (targetType !== 'parent' && targetType !== 'previous') {
throw new Error(`Invalid target type "${targetType}"`)
}
do {
if (targetType === 'parent') {
currentEl = currentEl.parentNode
} else if (targetType === 'previous') {
currentEl = currentEl.previousSibling
}
if (currentEl != null && nodeTest(currentEl)) {
parentEl = currentEl
}
} while (currentEl != null && !nodeTest(currentEl))
return parentEl
}
function clearEl (el, filterFn) {
// by default we clear all children
const testFn = filterFn || (() => false)
const childEls = nodeListToArray(el.childNodes)
for (const childEl of childEls) {
const result = testFn(childEl)
if (result === true) {
continue
}
childEl.parentNode.removeChild(childEl)
}
}
function findOrCreateChildNode (docNode, nodeName, targetNode) {
let result
const existingNode = findChildNode(nodeName, targetNode)
if (!existingNode) {
result = docNode.createElement(nodeName)
targetNode.appendChild(result)
} else {
result = existingNode
}
return result
}
function findChildNode (nodeNameOrFn, targetNode, allNodes = false) {
const result = []
let testFn
if (typeof nodeNameOrFn === 'string') {
testFn = (n) => n.nodeName === nodeNameOrFn
} else {
testFn = nodeNameOrFn
}
for (let i = 0; i < targetNode.childNodes.length; i++) {
let found = false
const childNode = targetNode.childNodes[i]
const testResult = testFn(childNode)
if (testResult) {
found = true
result.push(childNode)
}
if (found && !allNodes) {
break
}
}
return allNodes ? result : result[0]
}
function createNewRAndTextNode (textOrOptions, templateRNode, doc) {
const text = typeof textOrOptions === 'string' ? textOrOptions : textOrOptions.text
const attributes = typeof textOrOptions === 'string' ? {} : (textOrOptions.attributes || {})
const newRNode = templateRNode.cloneNode(true)
const textEl = doc.createElement('a:t')
textEl.setAttribute('xml:space', 'preserve')
for (const [attrName, attrValue] of Object.entries(attributes)) {
textEl.setAttribute(attrName, attrValue)
}
textEl.textContent = text
newRNode.appendChild(textEl)
return [newRNode, textEl]
}
module.exports.normalizeSingleTextElInRun = (textEl, doc) => {
const rEl = getClosestEl(textEl, 'a:r')
if (rEl == null) {
return
}
const textElements = nodeListToArray(rEl.childNodes).filter((n) => n.nodeName === 'a:t')
const leftTextNodes = []
const rightTextNodes = []
let found = false
for (const tEl of textElements) {
if (tEl === textEl) {
found = true
} else if (found) {
rightTextNodes.push(tEl)
} else {
leftTextNodes.push(tEl)
}
}
const templateRNode = rEl.cloneNode(true)
// remove text elements and inherit the rest
clearEl(templateRNode, (c) => c.nodeName !== 'a:t')
const results = []
for (const tNode of leftTextNodes) {
const [newRNode, newTextNode] = createNewRAndTextNode(tNode.textContent, templateRNode, doc)
rEl.removeChild(tNode)
rEl.parentNode.insertBefore(newRNode, rEl)
results.push(newTextNode)
}
results.push(textEl)
for (const tNode of [...rightTextNodes].reverse()) {
const [newRNode, newTextNode] = createNewRAndTextNode(tNode.textContent, templateRNode, doc)
rEl.removeChild(tNode)
rEl.parentNode.insertBefore(newRNode, rEl.nextSibling)
results.push(newTextNode)
}
return results
}
module.exports.normalizeSingleContentInText = (textEl, getMatchRegexp, doc) => {
const rEl = getClosestEl(textEl, 'a:r')
const paragraphEl = getClosestEl(textEl, 'a:p')
if (rEl == null || paragraphEl == null) {
return
}
let newContent = textEl.textContent
const textParts = []
const matchParts = []
let match
do {
match = newContent.match(getMatchRegexp())
if (match != null) {
const leftContent = newContent.slice(0, match.index)
if (leftContent !== '') {
textParts.push(leftContent)
}
const matchInfo = {
content: match[0],
rest: match.slice(1)
}
textParts.push(matchInfo)
matchParts.push(matchInfo)
newContent = newContent.slice(match.index + match[0].length)
}
} while (match != null)
if (newContent !== '') {
textParts.push(newContent)
}
const templateRNode = rEl.cloneNode(true)
// remove text elements and inherit the rest
clearEl(templateRNode, (c) => c.nodeName !== 'a:t')
const results = []
for (const item of textParts) {
const isMatchInfo = typeof item !== 'string'
const textContent = isMatchInfo ? item.content : item
const [newRNode, newTextNode] = createNewRAndTextNode(textContent, templateRNode, doc)
rEl.parentNode.insertBefore(newRNode, rEl)
const result = {
tEl: newTextNode
}
if (isMatchInfo) {
result.match = item
}
results.push(result)
}
rEl.parentNode.removeChild(rEl)
return results
}
module.exports.contentIsXML = (content) => {

@@ -25,11 +361,13 @@ if (!Buffer.isBuffer(content) && typeof content !== 'string') {

module.exports.nodeListToArray = (nodes) => {
const arr = []
for (let i = 0; i < nodes.length; i++) {
arr.push(nodes[i])
}
return arr
}
module.exports.serializeXml = (doc) => new XMLSerializer().serializeToString(doc).replace(/ xmlns(:[a-z0-9]+)?=""/g, '')
module.exports.nodeListToArray = nodeListToArray
module.exports.pxToEMU = pxToEMU
module.exports.cmToEMU = cmToEMU
module.exports.getNewRelIdFromBaseId = getNewRelIdFromBaseId
module.exports.getNewIdFromBaseId = getNewIdFromBaseId
module.exports.getCNvPrEl = getCNvPrEl
module.exports.getChartEl = getChartEl
module.exports.clearEl = clearEl
module.exports.findOrCreateChildNode = findOrCreateChildNode
module.exports.findChildNode = findChildNode
{
"name": "@jsreport/jsreport-pptx",
"version": "4.0.1",
"version": "4.1.0",
"description": "jsreport recipe rendering pptx files",

@@ -36,12 +36,14 @@ "keywords": [

"dependencies": {
"@jsreport/office": "3.0.0",
"@jsreport/office": "4.0.0",
"@xmldom/xmldom": "0.8.6",
"axios": "0.24.0",
"axios": "1.6.2",
"html-entities": "2.4.0",
"image-size": "0.7.4"
"image-size": "0.7.4",
"js-excel-date-convert": "1.0.2",
"moment": "2.29.4"
},
"devDependencies": {
"@jsreport/jsreport-assets": "4.0.1",
"@jsreport/jsreport-core": "4.0.1",
"@jsreport/jsreport-handlebars": "4.0.0",
"@jsreport/jsreport-assets": "4.0.2",
"@jsreport/jsreport-core": "4.1.0",
"@jsreport/jsreport-handlebars": "4.0.1",
"@jsreport/studio-dev": "4.0.0",

@@ -48,0 +50,0 @@ "handlebars": "4.7.7",

@@ -10,2 +10,7 @@ # @jsreport/jsreport-pptx

### 4.1.0
- add pptxStyle support
- add pptxChart support
### 4.0.1

@@ -46,3 +51,1 @@

Adaptations for the v3 APIs

@@ -225,2 +225,13 @@ /* eslint no-unused-vars: 0 */

function pptxStyle (options) {
const Handlebars = require('handlebars')
const textColor = options.hash.textColor || ''
const backgroundColor = options.hash.backgroundColor || ''
return new Handlebars.SafeString(
`<pptxStyle id="${options.hash.id}" textColor="${textColor}" backgroundColor="${backgroundColor}" />`
)
}
function pptxSlides (data, options) {

@@ -290,1 +301,29 @@ const Handlebars = require('handlebars')

}
function pptxChart (options) {
const Handlebars = require('handlebars')
if (options.hash.data == null) {
throw new Error('pptxChart helper requires data parameter to be set')
}
if (!Array.isArray(options.hash.data.labels) || options.hash.data.labels.length === 0) {
throw new Error('pptxChart helper requires data parameter with labels to be set, data.labels must be an array with items')
}
if (!Array.isArray(options.hash.data.datasets) || options.hash.data.datasets.length === 0) {
throw new Error('pptxChart helper requires data parameter with datasets to be set, data.datasets must be an array with items')
}
if (
options.hash.options != null &&
(
typeof options.hash.options !== 'object' ||
Array.isArray(options.hash.options)
)
) {
throw new Error('pptxChart helper when options parameter is set, it should be an object')
}
return new Handlebars.SafeString('$pptxChart' + Buffer.from(JSON.stringify(options.hash)).toString('base64') + '$')
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc