Skip to content

Instantly share code, notes, and snippets.

@fhur
Created July 3, 2020 13:12
Show Gist options
  • Save fhur/ac21df28e005a5990ef0d96ceace9610 to your computer and use it in GitHub Desktop.
Save fhur/ac21df28e005a5990ef0d96ceace9610 to your computer and use it in GitHub Desktop.
function mapRecursively(tree, f) {
return {
...f(tree),
children: (tree.children || []).map((child) => mapRecursively(child, f)),
}
}
const FrameNode = {
aspectRatio: null,
blendingEnabled: 0,
blendingMode: "normal",
bottom: null,
centerAnchorX: 0,
centerAnchorY: 0,
children: [],
clip: true,
codeOverrideEnabled: false,
constraintsLocked: false,
duplicatedFrom: null,
exportOptions: [],
fillColor: "white",
fillEnabled: true,
fillImage: null,
fillImageOriginalName: null,
fillImagePixelHeight: null,
fillImagePixelWidth: null,
fillImageResize: "fill",
fillType: "color",
framePreset: null,
guidesX: [],
guidesY: [],
heightType: 0,
intrinsicHeight: null,
intrinsicWidth: null,
isExternalMaster: null,
isMaster: false,
isTarget: false,
left: 0,
locked: false,
name: null,
opacity: 1,
originalid: null,
previewSettings: null,
radius: 0,
radiusBottomLeft: 0,
radiusBottomRight: 0,
radiusIsRelative: false,
radiusPerCorner: false,
radiusTopLeft: 0,
radiusTopRight: 0,
replicaInfo: null,
right: null,
rotation: 0,
top: 0,
visible: true,
widthType: 0,
}
const TextNode = {
autoSize: true,
bottom: null,
centerAnchorX: 0,
centerAnchorY: 0,
clip: true,
codeOverrideEnabled: false,
constraintsLocked: false,
duplicatedFrom: null,
exportOptions: [],
heightType: 0,
isTarget: false,
left: 0,
locked: false,
name: null,
opacity: 1,
originalid: null,
right: null,
rotation: 0,
textVerticalAlignment: "top",
top: 0,
visible: true,
widthType: 0,
}
const RectangleShapeNode = {
aspectRatio: null,
duplicatedFrom: null,
exportOptions: [],
fillColor: "#CCC",
fillEnabled: true,
fillImage: null,
fillImageOriginalName: null,
fillImagePixelHeight: null,
fillImagePixelWidth: null,
fillImageResize: "fill",
fillType: "color",
locked: false,
name: null,
opacity: 1,
originalid: null,
radius: 0,
radiusBottomLeft: 0,
radiusBottomRight: 0,
radiusPerCorner: false,
radiusTopLeft: 0,
radiusTopRight: 0,
rotation: 0,
visible: true,
}
const ShapeContainerNode = {
autoSize: true,
bottom: null,
centerAnchorX: 0,
centerAnchorY: 0,
children: [],
constraintsLocked: false,
duplicatedFrom: null,
exportIncludesBackground: false,
exportOptions: [],
fillColor: "#FFF",
fillEnabled: false,
fillImage: null,
fillImageOriginalName: null,
fillImagePixelHeight: null,
fillImagePixelWidth: null,
fillImageResize: "fill",
fillType: "color",
heightType: 0,
left: 0,
locked: false,
name: null,
opacity: 1,
originalid: null,
previewSettings: null,
radius: 0,
radiusBottomLeft: 0,
radiusBottomRight: 0,
radiusPerCorner: false,
radiusTopLeft: 0,
radiusTopRight: 0,
right: null,
sizeToFit: false,
top: 0,
visible: true,
widthType: 0,
}
const PathNode = {
aspectRatio: null,
duplicatedFrom: null,
exportOptions: [],
fillColor: "rgba(0,170,255,0.5)",
fillEnabled: false,
fillImage: null,
fillImageOriginalName: null,
fillImagePixelHeight: null,
fillImagePixelWidth: null,
fillImageResize: "fill",
fillType: "color",
lineCap: "butt",
lineJoin: "miter",
locked: false,
name: null,
opacity: 1,
originalid: null,
pathClosed: false,
rotation: 0,
strokeAlignment: "center",
strokeColor: "#AAA",
strokeDashArray: "0",
strokeDashOffset: 0,
strokeEnabled: 1,
strokeMiterLimit: 4,
strokeWidth: 1,
visible: true,
}
const CodeComponentNode = {
aspectRatio: null,
bottom: null,
centerAnchorX: 0,
centerAnchorY: 0,
clip: true,
codeOverrideEnabled: false,
constraintsLocked: false,
exportOptions: [],
fillColor: "rgba(255,255,255,1)",
fillEnabled: false,
fillImage: null,
fillImageOriginalName: null,
fillImagePixelHeight: null,
fillImagePixelWidth: null,
fillImageResize: "fill",
fillType: "color",
heightType: 0,
left: 0,
locked: false,
name: null,
opacity: 1,
originalid: null,
previewSettings: null,
radius: 0,
radiusBottomLeft: 0,
radiusBottomRight: 0,
radiusIsRelative: false,
radiusPerCorner: false,
radiusTopLeft: 0,
radiusTopRight: 0,
right: null,
rotation: 0,
top: 0,
visible: true,
widthType: 0,
}
const defaultsByType = {
FrameNode,
TextNode,
RectangleShapeNode,
ShapeContainerNode,
PathNode,
CodeComponentNode,
}
function dropDefaults(node) {
const defaults = defaultsByType[node.__class]
if (!defaults) {
return node
}
const nodeWithoutDefaults = {}
for ([key, value] in Object.entries(node)) {
if (defaults[key] !== value) {
nodeWithoutDefaults[key] = value
}
}
return nodeWithoutDefaults
}
const fs = require("fs")
const files = fs.readdirSync("./").filter((f) => f.endsWith(".json"))
function analyzeDocument(file) {
const document = JSON.parse(fs.readFileSync(file).toString())
const tree = document.root
const countByClass = {}
mapRecursively(tree, (x) => {
const count = countByClass[x.__class] || 0
countByClass[x.__class] = count + 1
return x
})
const cleanedUpTree = mapRecursively(tree, dropDefaults)
fs.writeFileSync(file + ".smaller", JSON.stringify(cleanedUpTree))
}
for (const file of files) {
analyzeDocument(file)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment