Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,35 @@ The following arguments are passed into your middleware function:
- suffix: The symbol name suffix (e.g. `/Desktop`)
- RESIZING_CONSTRAINTS: Object containing constants for the `setResizingConstraint` API

#### Text Middleware

This middleware is executed for every text layer within a document.

```js
module.exports = {
textMiddleware: args => { ... }
};
```

The following arguments are passed into your middleware function:

- layer: The current symbol layer
- node: The source HTML node

Example for preserving text across library updates (by hardcoding an ID):

```js
textMiddleware: ({ layer, node }) => {
const parentNode = node.parentNode;
if (parentNode && parentNode.dataset) {
const { sketchId } = parentNode.dataset;

if (sketchId) {
layer.setObjectID(`text:${sketchId}`);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't use arbitrary strings as ObjectId, it's going to break Sketch in very subtle ways. Sketch expect IDs to be UUID.

You can generate a fixed UUID from a seed if you want:

import * as seedrandom from 'seedrandom';

const lut = [];
for (let i = 0; i < 256; i += 1) {
  lut[i] = (i < 16 ? '0' : '') + i.toString(16);
}
// Hack (http://stackoverflow.com/a/21963136)
function e7(seed?: ?string) {
  const random = seed ? seedrandom(`${seed}0`) : Math.random;
  const d0 = (random() * 0xffffffff) | 0;
  const d1 = (random() * 0xffffffff) | 0;
  const d2 = (random() * 0xffffffff) | 0;
  const d3 = (random() * 0xffffffff) | 0;
  return `${lut[d0 & 0xff] +
    lut[(d0 >> 8) & 0xff] +
    lut[(d0 >> 16) & 0xff] +
    lut[(d0 >> 24) & 0xff]}-${lut[d1 & 0xff]}${lut[(d1 >> 8) & 0xff]}-${
    lut[((d1 >> 16) & 0x0f) | 0x40]
  }${lut[(d1 >> 24) & 0xff]}-${lut[(d2 & 0x3f) | 0x80]}${lut[(d2 >> 8) & 0xff]}-${
    lut[(d2 >> 16) & 0xff]
  }${lut[(d2 >> 24) & 0xff]}${lut[d3 & 0xff]}${lut[(d3 >> 8) & 0xff]}${lut[(d3 >> 16) & 0xff]}${
    lut[(d3 >> 24) & 0xff]
  }`;
}

// Keep track of previous seeds
const previousSeeds = {};

export function generateID(seed) {
  let _seed;

  if (seed) {
    if (!previousSeeds[seed]) {
      previousSeeds[seed] = 0;
    }
    previousSeeds[seed] += 1;

    _seed = `${seed}${previousSeeds[seed]}`;
  }

  return e7(_seed);
}

}
}
}
```

#### Symbol Instance Middleware

Expand Down
9 changes: 5 additions & 4 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ require('yargs')
const symbolLayerMiddleware = resolveMiddleware(argv.symbolLayerMiddleware);
const symbolMiddleware = resolveMiddleware(argv.symbolMiddleware);
const symbolInstanceMiddleware = resolveMiddleware(argv.symbolInstanceMiddleware);
const textMiddleware = resolveMiddleware(argv.textMiddleware);

const launchArgs = {
args: argv.puppeteerArgs ? argv.puppeteerArgs.split(' ') : [],
Expand Down Expand Up @@ -129,7 +130,7 @@ require('yargs')

await page.addScriptTag({ content: code });

await page.evaluate('generateAlmostSketch.setupSymbols({ name: "html-sketchapp symbols" })');
await page.evaluate(`generateAlmostSketch.setupSymbols({ ${argv.name ? `id: '${argv.name}', ` : ''}name: "html-sketchapp symbols" })`);

await page.evaluate('generateAlmostSketch.snapshotColorStyles()');

Expand All @@ -142,12 +143,12 @@ require('yargs')
const [ width, height ] = size.split('x').map(x => parseInt(x, 10));
const deviceScaleFactor = typeof scale === 'undefined' ? 1 : parseFloat(scale);
await page.setViewport({ width, height, deviceScaleFactor });
await page.evaluate(`generateAlmostSketch.snapshotTextStyles({ suffix: "${hasViewports ? `/${viewportName}` : ''}" })`);
await page.evaluate(`generateAlmostSketch.snapshotSymbols({ suffix: "${hasViewports ? `/${viewportName}` : ''}", symbolLayerMiddleware: ${symbolLayerMiddleware}, symbolMiddleware: ${symbolMiddleware}, symbolInstanceMiddleware: ${symbolInstanceMiddleware} })`);
await page.evaluate(`generateAlmostSketch.snapshotTextStyles({ ${argv.customIds ? 'customIds: true, ' : ''}suffix: "${hasViewports ? `/${viewportName}` : ''}" })`);
await page.evaluate(`generateAlmostSketch.snapshotSymbols({ suffix: "${hasViewports ? `/${viewportName}` : ''}", symbolLayerMiddleware: ${symbolLayerMiddleware}, symbolMiddleware: ${symbolMiddleware}, symbolInstanceMiddleware: ${symbolInstanceMiddleware}, textMiddleware: ${textMiddleware} })`);
}
}

const asketchDocumentJSON = await page.evaluate('generateAlmostSketch.getDocumentJSON()');
const asketchDocumentJSON = await page.evaluate(`generateAlmostSketch.getDocumentJSON('${argv.name || ''}')`);
const asketchPageJSON = await page.evaluate('generateAlmostSketch.getPageJSON()');

const outputPath = path.resolve(process.cwd(), argv.outDir);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"homepage": "https://github.com/seek-oss/html-sketchapp-cli#readme",
"dependencies": {
"@brainly/html-sketchapp": "^4.0.0",
"@brainly/html-sketchapp": "^4.1.0",
"axios": "^0.18.0",
"decompress": "^4.2.0",
"es6-promisify": "^6.0.0",
Expand Down
33 changes: 23 additions & 10 deletions script/generateAlmostSketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const {
ShapeGroup
} = htmlSketchapp;

const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddleware = {}) => {
const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddleware = {}, textMiddleware = null) => {
const rootNodeAndChildren = [rootNode, ...rootNode.querySelectorAll('*')];

const symbolInstanceChildren = new Set([
Expand Down Expand Up @@ -42,7 +42,9 @@ const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddlewa
return [];
}

return nodeToSketchLayers(node);
return nodeToSketchLayers(node, {
onTextGenerate: textMiddleware,
});
});

return layers.reduce((prev, current) => prev.concat(current), []);
Expand All @@ -59,21 +61,29 @@ export function snapshotColorStyles() {
});
}

export function snapshotTextStyles({ suffix = '' }) {
export function snapshotTextStyles({ suffix = '', customIds }) {
Array.from(document.querySelectorAll('[data-sketch-text]'))
.forEach(node => {
getAllLayers(node)
.filter(layer => layer instanceof Text)
.forEach(layer => {
const name = node.dataset.sketchText;

layer.setName(`${name}${suffix}`);
doc.addTextStyle(layer);
const id = `${name}${suffix}`;
layer.setName(id);
if (customIds) {
doc.addTextStyle(layer, id);
} else {
doc.addTextStyle(layer);
}
});
});
}

export function getDocumentJSON() {
export function getDocumentJSON(name) {
if (name) {
doc.setObjectID(name);
}
return JSON.stringify(doc.toJSON());
}

Expand All @@ -82,11 +92,14 @@ const page = new Page({
height: document.body.offsetHeight
});

export function setupSymbols({ name }) {
export function setupSymbols({ name, id }) {
if (id) {
page.setObjectID(id);
}
page.setName(name);
}

export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {}, symbolMiddleware = () => {}, symbolInstanceMiddleware = () => {} },) {
export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {}, symbolMiddleware = () => {}, symbolInstanceMiddleware = () => {}, textMiddleware },) {
const nodes = Array.from(document.querySelectorAll('[data-sketch-symbol]'));

const symbolMastersByName = nodes.reduce((obj, node) => {
Expand All @@ -105,12 +118,12 @@ export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {},
const name = node.dataset.sketchSymbol;
const symbol = symbolMastersByName[name];

const layers = getAllLayers(node, symbolMastersByName, symbolInstanceMiddleware);
const layers = getAllLayers(node, symbolMastersByName, symbolInstanceMiddleware, textMiddleware);

layers
.filter(layer => layer !== null)
.forEach(layer => {
symbolLayerMiddleware({layer, SVG, Text, ShapeGroup, Rectangle, RESIZING_CONSTRAINTS});
symbolLayerMiddleware({layer, node, SVG, Text, ShapeGroup, Rectangle, RESIZING_CONSTRAINTS});
symbol.addLayer(layer);
});

Expand Down