From f004f1913faf5ee2dea071ee41373e7d5379bc39 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Wed, 30 Dec 2020 23:55:29 +0100 Subject: [PATCH 1/3] adding pasteInto() - student duo tried to export text as a png, then import to create a clipping mask. this is akin to the GUI right-click 'pasteInto', which opens gates for wild clipping masks and within clipping masks inception! --- basil.js | 59 ++++++++++++++++++++++++++++++++++++++++ changelog.txt | 1 + src/includes/document.js | 59 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/basil.js b/basil.js index f0d4b3d..e06fdbf 100644 --- a/basil.js +++ b/basil.js @@ -4009,6 +4009,65 @@ pub.objectStyle = function(itemOrName, props) { return style; }; +/** + * @summary Paste one page item into another. + * @description Paste the source page item into the destination item, which then acts like a clipping mask. Optionally, set to a variable, to immediately access the new page item inside your destination. + * + * @cat Document + * @subcat Page Items + * @method pasteInto + * + * @param {PageItem} source The page item to copy. + * @param {PageItem} destination The page item to paste the source into. + * @return {Object} The new page item inside the destination. + * + * @example Use ellipse as clipping mask for textframe. + * noStroke(); + * textSize(50); + * + * fill(0); + * var myText = text(LOREM, 0, 0, width, height); + * + * noFill(); + * var myMask = ellipse(width / 2, height / 2, width / 2, height / 2); + * + * myMaskItem = pasteInto(myText, myMask); + * + * property(myMaskItem, 'fillColor', color(0, 255, 0)); + * + * @example Use ellipse as clipping mask for rect. + * noStroke(); + * + * fill(255, 0, 0); + * var myRect = rect(0, 0, width / 2, height / 2); + * + * fill(0, 0, 255); + * var myMask = ellipse(width / 2, height / 2, width / 2, height / 2); + * + * myMaskItem = pasteInto(myRect, myMask); + * + * property(myMaskItem, 'fillColor', color(255, 0, 255)); + */ +pub.pasteInto = function(source, destination) { + checkNull(source); + checkNull(destination); + + // set source to app clipboard + app.selection = source; + app.copy(); + + // paste source into destination + app.selection = destination; + app.pasteInto(); + + // return new pageItem inside destination + if(destination.pageItems[0].hasOwnProperty('texts')){ + return destination.pageItems[0].texts[0]; + }else{ + return destination.pageItems[0]; + } +}; + /** * @summary Returns the first selected object or selects an object. * @description If no argument is given, returns the first currently selected object. If a page item is given as argument, the page item will be selected. diff --git a/changelog.txt b/changelog.txt index 32b812a..3e4ce4d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -60,6 +60,7 @@ basil.js x.x.x DAY MONTH YEAR + Added saveCSV() to stringify data and save it as CSV file in one step + Added CSV.parse() and CSV.stringify() to replace CSV.decode() and CSV.encode() parse and stringify accept optional 2nd parameter for custom delimiter. ++ Added pasteInto() enabling using page items as clipping masks * translate(), rotate() and scale() now behave like they do in Processing and change the current matrix * basil scripts will by default use the user's default units or the current units of the document, diff --git a/src/includes/document.js b/src/includes/document.js index 7805264..c1564ba 100644 --- a/src/includes/document.js +++ b/src/includes/document.js @@ -1218,6 +1218,65 @@ pub.objectStyle = function(itemOrName, props) { return style; }; +/** + * @summary Paste one page item into another. + * @description Paste the source page item into the destination item, which then acts like a clipping mask. Optionally, set to a variable, to immediately access the new page item inside your destination. + * + * @cat Document + * @subcat Page Items + * @method pasteInto + * + * @param {PageItem} source The page item to copy. + * @param {PageItem} destination The page item to paste the source into. + * @return {Object} The new page item inside the destination. + * + * @example Use ellipse as clipping mask for textframe. + * noStroke(); + * textSize(50); + * + * fill(0); + * var myText = text(LOREM, 0, 0, width, height); + * + * noFill(); + * var myMask = ellipse(width / 2, height / 2, width / 2, height / 2); + * + * myMaskItem = pasteInto(myText, myMask); + * + * property(myMaskItem, 'fillColor', color(0, 255, 0)); + * + * @example Use ellipse as clipping mask for rect. + * noStroke(); + * + * fill(255, 0, 0); + * var myRect = rect(0, 0, width / 2, height / 2); + * + * fill(0, 0, 255); + * var myMask = ellipse(width / 2, height / 2, width / 2, height / 2); + * + * myMaskItem = pasteInto(myRect, myMask); + * + * property(myMaskItem, 'fillColor', color(255, 0, 255)); + */ +pub.pasteInto = function(source, destination) { + checkNull(source); + checkNull(destination); + + // set source to app clipboard + app.selection = source; + app.copy(); + + // paste source into destination + app.selection = destination; + app.pasteInto(); + + // return new pageItem inside destination + if(destination.pageItems[0].hasOwnProperty('texts')){ + return destination.pageItems[0].texts[0]; + }else{ + return destination.pageItems[0]; + } +}; + /** * @summary Returns the first selected object or selects an object. * @description If no argument is given, returns the first currently selected object. If a page item is given as argument, the page item will be selected. From fca847ab087fbc7fcf74e95fb5d117f827478978 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Thu, 31 Dec 2020 17:13:40 +0100 Subject: [PATCH 2/3] small typo of isText fixing small typo --- basil.js | 2 +- src/includes/data.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/basil.js b/basil.js index e06fdbf..7f3a3aa 100644 --- a/basil.js +++ b/basil.js @@ -2663,7 +2663,7 @@ var isString = pub.isString = function(str) { }; /** - * @summary Checks wether a var is an InDesign text object. + * @summary Checks whether a var is an InDesign text object. * @description Checks whether a var is an InDesign text object, returns `true` if this is the case. * NB: a InDesign text frame will return `false` as it is just a container holding text. So you could say that `isText()` refers to all the things inside a text frame. * diff --git a/src/includes/data.js b/src/includes/data.js index 7d93c46..63d423a 100644 --- a/src/includes/data.js +++ b/src/includes/data.js @@ -1200,7 +1200,7 @@ var isString = pub.isString = function(str) { }; /** - * @summary Checks wether a var is an InDesign text object. + * @summary Checks whether a var is an InDesign text object. * @description Checks whether a var is an InDesign text object, returns `true` if this is the case. * NB: a InDesign text frame will return `false` as it is just a container holding text. So you could say that `isText()` refers to all the things inside a text frame. * From 93af8e8a7c47da9835c84522cc3feed5817390a8 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Mon, 4 Jan 2021 18:44:59 +0100 Subject: [PATCH 3/3] store and return current selection - fixing as per review suggestion --- basil.js | 6 ++++++ src/includes/document.js | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/basil.js b/basil.js index 7f3a3aa..dc320ee 100644 --- a/basil.js +++ b/basil.js @@ -4052,6 +4052,9 @@ pub.pasteInto = function(source, destination) { checkNull(source); checkNull(destination); + // temp store previous selection + var tempSelection = app.selection; + // set source to app clipboard app.selection = source; app.copy(); @@ -4060,6 +4063,9 @@ pub.pasteInto = function(source, destination) { app.selection = destination; app.pasteInto(); + // return selection + app.selection = tempSelection; + // return new pageItem inside destination if(destination.pageItems[0].hasOwnProperty('texts')){ return destination.pageItems[0].texts[0]; diff --git a/src/includes/document.js b/src/includes/document.js index c1564ba..8d57b67 100644 --- a/src/includes/document.js +++ b/src/includes/document.js @@ -1261,6 +1261,9 @@ pub.pasteInto = function(source, destination) { checkNull(source); checkNull(destination); + // temp store previous selection + var tempSelection = app.selection; + // set source to app clipboard app.selection = source; app.copy(); @@ -1269,6 +1272,9 @@ pub.pasteInto = function(source, destination) { app.selection = destination; app.pasteInto(); + // return selection + app.selection = tempSelection; + // return new pageItem inside destination if(destination.pageItems[0].hasOwnProperty('texts')){ return destination.pageItems[0].texts[0];