├── .appcast.xml
├── .gitignore
├── README.md
├── assets
└── icon.png
├── data-from-clipboard.sketchplugin.zip
├── démo data from clipboard.gif
├── package-lock.json
├── package.json
└── src
├── manifest.json
└── my-command.js
/.appcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 | -
8 |
9 |
10 | -
11 |
12 |
13 | -
14 |
15 |
16 | -
17 |
18 |
19 | -
20 |
21 |
22 | -
23 |
24 |
25 | -
26 |
27 |
28 | -
29 |
30 |
31 | -
32 |
33 |
34 | -
35 |
36 |
37 | -
38 |
39 |
40 | -
41 |
42 |
43 | -
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # build artefacts
2 | *.sketchplugin
3 |
4 | # npm
5 | node_modules
6 | .npm
7 | npm-debug.log
8 |
9 | # mac
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Copy data from the clipboard (look Ma, no file)
2 |
3 | [The latest release is here](https://github.com/Saint-loup/data-from-clipboard/releases/latest/download/data-from-clipboard.sketchplugin.zip). Download, unzip and double-click on the .sketchplugin file. Bug reports and feedbacks are welcome.
4 |
5 |
6 | ### How it works
7 |
8 | Copy a list of text in your clipboard, paste it into text layers or symbols overrides. That's it. There's also a command to shuffle the order.
9 |
10 | 
11 |
12 | Some of the code is adapted from [Automate-Sketch](https://github.com/Ashung/Automate-Sketch/blob/master/automate-sketch.sketchplugin/Contents/Sketch/Data/Supply_Data.js)
13 |
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baptiste-roullin/data-from-clipboard/fd415b794e59dd93a53849ea7a57186489d3814b/assets/icon.png
--------------------------------------------------------------------------------
/data-from-clipboard.sketchplugin.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baptiste-roullin/data-from-clipboard/fd415b794e59dd93a53849ea7a57186489d3814b/data-from-clipboard.sketchplugin.zip
--------------------------------------------------------------------------------
/démo data from clipboard.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baptiste-roullin/data-from-clipboard/fd415b794e59dd93a53849ea7a57186489d3814b/démo data from clipboard.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "data-from-clipboard",
3 | "repository": "https://github.com/baptiste-roullin/data-from-clipboard",
4 | "description": "Populate a bunch of layers from a list of text in the clipboard",
5 | "version": "0.6.1",
6 | "engines": {
7 | "sketch": ">=49.0"
8 | },
9 | "skpm": {
10 | "name": "data-from-clipboard",
11 | "manifest": "src/manifest.json",
12 | "main": "data-from-clipboard.sketchplugin",
13 | "assets": [
14 | "assets/**/*"
15 | ],
16 | "sketch-assets-file": "sketch-assets/icons.sketch"
17 | },
18 | "scripts": {
19 | "build": "skpm-build",
20 | "watch": "skpm-build --watch",
21 | "start": "skpm-build --watch --run",
22 | "postinstall": "npm run build && skpm-link"
23 | },
24 | "devDependencies": {
25 | "@skpm/builder": "^0.8.0",
26 | "sketch-utils": "^0.2.10"
27 | },
28 | "author": "Baptiste "
29 | }
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/sketch-hq/SketchAPI/develop/docs/sketch-plugin-manifest-schema.json",
3 | "name": "Data from clipboard",
4 | "compatibleVersion": "94.1",
5 | "version": "0.6.1",
6 | "author": "Baptiste Roullin",
7 | "authorEmail": "baptiste@roullin.net",
8 | "homepage": "https://github.com/baptiste-roullin/data-from-clipboard",
9 | "suppliesData": true,
10 | "icon": "icon.png",
11 | "commands": [
12 | {
13 | "script": "my-command.js",
14 | "identifier": "supply-data-from-clipboard",
15 | "handlers": {
16 | "actions": {
17 | "Startup": "onStartup",
18 | "Shutdown": "onShutdown",
19 | "SupplyTextFromClipboard": "onSupplyTextFromClipboard",
20 | "SupplyRandomTextFromClipboard": "onSupplyRandomTextFromClipboard"
21 | }
22 | }
23 | }
24 | ],
25 | "menu": {
26 | "isRoot": false,
27 | "title": "Data from clipboard",
28 | "items": [
29 | "SupplyRandomTextFromClipboard",
30 | "SupplyTextFromClipboard"
31 | ]
32 | }
33 | }
--------------------------------------------------------------------------------
/src/my-command.js:
--------------------------------------------------------------------------------
1 | // documentation: https://developer.sketchapp.com/reference/api/
2 |
3 |
4 | //import { log } from 'console'
5 | const sketch = require('sketch')
6 | const { DataSupplier } = sketch
7 | const UI = require('sketch/ui')
8 | const util = require('util')
9 | var utils = require('sketch-utils')
10 |
11 | export function onStartup() {
12 | DataSupplier.registerDataSupplier("public.text", "Text from clipboard", "SupplyTextFromClipboard")
13 | DataSupplier.registerDataSupplier("public.text", "Random text from clipboard", "SupplyRandomTextFromClipboard")
14 |
15 | }
16 |
17 | export function onShutdown() {
18 | // Deregister the plugin
19 | DataSupplier.deregisterDataSuppliers()
20 | }
21 |
22 | function shuffleArray(array) {
23 | for (let i = array.length - 1; i > 0; i--) {
24 | const j = Math.floor(Math.random() * i)
25 | const temp = array[i]
26 | array[i] = array[j]
27 | array[j] = temp
28 | }
29 | return array
30 | }
31 |
32 | export function onSupplyTextFromClipboard(context) {
33 | supplyOrderedData(context, getPasteBoardData(context))
34 | };
35 |
36 | export function onSupplyRandomTextFromClipboard(context) {
37 | supplyRandomData(context, getPasteBoardData(context))
38 | };
39 |
40 | function getPasteBoardData(context) {
41 | let pasteboard = NSPasteboard.generalPasteboard()
42 | let supportedPasteboardTypes = [
43 | "public.rtf",
44 | "public.string",
45 | "public.plain-text",
46 | "public.utf8-plain-text",
47 | "public.multipleTextSelection",
48 | "public.html",
49 | "com.apple.traditional-mac-plain-text",
50 | "org.mozilla.custom-clipdata",
51 | "org.chromium.web-custom-data",
52 | "NSStringPboardType",
53 | "public.utf16-external-plain-text",
54 | "public.utf16-plain-text",
55 | "com.apple.iWork.TSPNativeData",
56 | "public.text",
57 | "com.apple.webarchive",
58 | "com.adobe.pdf",
59 | "com.microsoft.word.doc",
60 | "com.microsoft.excel.xls",
61 | "com.microsoft.powerpoint.ppt"
62 | ]
63 |
64 | // test wether pasteboard not empty
65 | if (pasteboard.pasteboardItems().count() > 0) {
66 | let pasteboardType = pasteboard.pasteboardItems().firstObject().types().firstObject()
67 | //console.log(pasteboardType, supportedPasteboardTypes.indexOf(String(pasteboardType)))
68 |
69 | // test wether content is text
70 | if (supportedPasteboardTypes.indexOf(String(pasteboardType)) > -1) {
71 |
72 | let clipboardString = pasteboard.pasteboardItems().firstObject().stringForType(NSPasteboardTypeString)
73 | //console.log(/\n\n/.test(clipboardString));
74 | let clipboardArray = clipboardString.replace(/\n+/, "\n").split(/\n/g)
75 | return clipboardArray
76 | }
77 | else {
78 | UI.message("Content in clipboard is not text")
79 | //console.log(pasteboard.pasteboardItems().firstObject().stringForType(NSPasteboardTypeString))
80 | return false
81 | }
82 | }
83 | else {
84 | UI.message("Clipboard is empty")
85 | return false
86 | }
87 | }
88 |
89 | function replaceSelection(context, newData, mode) {
90 | for (var i = 0; i < context.data.requestedCount; i++) {
91 | console.log(utils.prepareValue(context.data.items[0]).type)
92 | if (utils.prepareValue(context.data.items[i]).type == 'MSSelectionItem' && mode != 'random') {
93 | UI.message("Please select a text layer.")
94 | }
95 | else {
96 | DataSupplier.supplyData(context.data.key, newData)
97 | }
98 | }
99 | }
100 |
101 | function supplyOrderedData(context, newData) {
102 | if (!newData) {
103 | return
104 | }
105 | replaceSelection(context, newData)
106 | }
107 |
108 | function supplyRandomData(context, newData) {
109 | if (!newData) {
110 | return
111 | }
112 | let shufflednewData = shuffleArray(newData)
113 | replaceSelection(context, shufflednewData, "random")
114 | }
--------------------------------------------------------------------------------