basiljs / basil.js

An attempt to port the spirit of the Processing visualization language to Adobe Indesign.
http://basiljs.ch/
Other
246 stars 30 forks source link

fast method to remove all pages (except 1) #299

Closed ffd8 closed 5 years ago

ffd8 commented 5 years ago

When showing students how to make a multi-page generative doc using addPage() (ie. headlines from NYT per page), it quickly becomes annoying to always hit 'undo' after running the script to remove any created pages and start over from page 1. Unless I'm forgetting about a function, nothing clears everything except the single first page. I always imagined that clear(doc()) should have this functionality, so I'd propose adding the following if the doc() is passed into it:

for (var i = pageCount(); i > 1; i--) {
    removePage(i);
}

Whatcha'all think?

trych commented 5 years ago

That's what we introduced revert() for. :wink:

(unless I am misunderstanding something here)

ff6347 commented 5 years ago

Another thing that is not basil but works well in ID is saving before executing the script and use the File > Revert to last state command

trych commented 5 years ago

That is what revert() is doing (minus the saving, if the document is not saved it reopens a fresh document).

trych commented 5 years ago

One thing that is really annoying about the current implementation of revert() though, is that it resets the size of the window, to the app default. Which is super annoying in class when I put my InDesign window side-by-side with my coding window. Each time I call revert(), it resizes my InDesign window to full screen again, which is why I never use revert anymore in class. We should build in some function that restores the current window size and position.

ffd8 commented 5 years ago

I quickly tested out revert() and while great to completely start everything over, doing just that is more than desired for issue above (since it also erases all layers, colors, .. everything, beyond the pageItems). Would people mind if the specific case of clear(doc()) also removed pages beyond the 1st one? Otherwise, I don't quite know how/why one would use clear(doc()) and want 30+ blank pages.

trych commented 5 years ago

doing just that is more than desired for issue above (since it also erases all layers, colors, .. everything, beyond the pageItems)

Yes, this was also discussed in some earlier issues, and we implemented the use of pageCount() as a setter for scenarios, where you want to keep all your stuff, but reset page count to just 1. 😃 For the former discussion on revert, check out #133.

Basically, we currently have all cases covered:

  1. You want to clear the document of all page items, but keep everything else?
    clear(doc());
  2. You want to completely start over (or revert to last saved state)?
    revert();
  3. You want to clear all page items, start with one page only, but keep colors and styles?
    pageCount(1);
    clear(doc());

Having said that, the implementation of the last one seems to be currently buggy, and throws an error. Not sure what causes it, it worked, when this was initially implemented, we need to investigate and fix this, then we have all the functionality we need I think.

ffd8 commented 5 years ago

pageCount(1);

Ahaaaa! I forgot this function got modified to force number of pages (adding if more than current, removing if less) = that's enough for me! Also didn't throw any errors.

Was testing revert() with a student today, which was pretty frustrating, since it kept un-doing their setting for no Facing Pages, probably because they hadn't saved the document after setting it. Anyways, will just suggest putting a pageCount(1) at the top of code when experimenting with addPage() within a loop. Cheers!

trych commented 5 years ago

Wait, it did not throw an error? It always has been throwing an error for me recently.

Did you do

pageCount(1);
clear(doc());

or did you by any chance do

clear(doc());
pageCount(1);

?

I need to investigate, because both of them need to work, but I always get an error, at least on the first version.

And yes, the revert() with unsaved docs always reverts to a fresh document with your default settings. If you want to keep facing pages, you can just save your document and then use revert(), then it keeps these settings.

Having said that, I feel we should introduce a function to set facing / non-facing pages. This comes up a lot in class.

ffd8 commented 5 years ago

Yeah, no errors (in function both orders), here's what I was testing with:

// @includepath ~/Documents/;%USERPROFILE%Documents; 
// @include basiljs/basil.js; 

function draw() { 
    var output = layer("output");
    clear(output);

    for (var i = 0; i < 25; i++) {
        rect(random(width), random(height), 50, 50);
        addPage();
    }

    pageCount(1);
    clear(doc());
} 

Yeah, will have to remember to just save doc before using revert. Facing pages function could be useful, but haven't run into need to set it programmatically very often.. perhaps it could be part of a general docSettings() function? Higher on my wishlist is the issue with words()/characters()/etc throwing errors when text gets outside of textframe from playing with fontsize.. 🤬

trych commented 5 years ago

Higher on my wishlist is the issue with words()/characters()/etc throwing errors when text gets outside of textframe from playing with fontsize.. 🤬

Could this not be handled by using parentStory (which admittedly is not very basil-y)?

var tf = text(mySuperLongText, 50, 50, 100, 100);
var myWords = tf.parentStory;
ffd8 commented 5 years ago

Hijacked my own thread... but yeah, was just exploring the parentStory too last week while encouraging everyone to inspect everything. Indeed, it works like I would sometimes experience when first selecting text within the textFrame rather than the textFrame itself:

// @includepath ~/Documents/;%USERPROFILE%Documents; 
// @include basiljs/basil.js; 

function draw() { 
    var output = layer("output");
    clear(output);
    units(MM);

    textSize(100);
    var tf = text(LOREM, 0, 0, width, height);
    words(tf.parentStory, function(obj){
        typo(obj, "pointSize", 110);
    });
} 

This probably works for most changes except grabbing the bounds/outlines, since of course things will be out of view. Nevertheless, this changing of pointSize on all characters/words is a super common error that using the parentStory could solve. Question is does it make sense to have it be default or specially added (which indeed is very un-basiljs'y). Curious if/how/when it shouldn't be taking the paragraphs/words/characters from the story vs the textframe...

trych commented 5 years ago

The .parentStory behaviour should not be default, as sometimes you have lots of linked textframes, but only need to treat the first text frame for example.

One basil'y way to do the above would be:

// @include ~/Documents/basiljs/basil.js;

function draw() {
  clear(doc());

  textSize(100);
  var tf = text(LOREM, 0, 0, width, height);
  words(stories(tf)[0], function(obj){
    typo(obj, "pointSize", 110);
  });

}

Or, if you need to set the property for the entire story anyways, you can of course skip words():

// @include ~/Documents/basiljs/basil.js;

function draw() {
  clear(doc());

  textSize(100);
  var tf = text(LOREM, 0, 0, width, height);

  typo(stories(tf)[0], "pointSize", 110);
}

(Also, btw., in basil 2.0 you don't need to set units to mm anymore if your default units are mm anyways, but might be that your InDesign is not set to mm?)