質問

I want to code a script (in Javascript/Extendscript) that copies cell styles from a source document to one or more target documents. The functionality should be much like the existing 'Load cell styles' option in InDesign, except it should be able to do this on a batch folder instead of one document at a time.

Questions:

1)

The code below works:

cStyle_source = app.documents[0].cellStyles[1]
cStyle_target = app.documents[0].cellStyles[2]

value = cStyle_source.basedOn
cStyle_target.basedOn = value

It correctly copies the cell style chosen under 'Based on' in the source cell style to the target style.

I now try to copy the basedOn property to a target style in another open document:

cStyle_source = app.documents[0].cellStyles[1]
cStyle_target = app.documents[1].cellStyles[2]

value = cStyle_source.basedOn
cStyle_target.basedOn = value

The new document is a copy of the first one, and it contains all the same styles. However, running this code gives me the error message:

Invalid value for set property 'basedOn'. Expected CellStyle or string, but received CellStyle.

Is it me, or does that message not make sense? Why does this work when applying the property value to a style in the same document, but not to another document?

2)

Why does the example code below work for paragraph styles and character styles, but not for object styles and cell styles?

myProperties = app.activeDocument.paragraphStyles[1].properties
app.activeDocument.paragraphStyles[2].properties = myProperties

This very handily copies all properties from style 1 to style 2, and it even works across documents. Easy peasy.

Why are cell styles (and object styles) different in this regard?

It seems I will need to loop through each property to copy a complete cell style, and it is therefore that my problem in 1) above appeared.


UPDATE:

I wanted to add my solution to copying the entire cell style, including the 'other ID' objects like basedOn, appliedParagraphStyle and swatches.

function AddCStyles() {
    var cStyles_source = app.documents[1].cellStyles;
    var cStyles_target = app.activeDocument.cellStyles;
    var loopLength = cStyles_target.length
    for (var i in selectedCStyles) {
        var myProperties = cStyles_source.item(selectedCStyles[i]).properties;
        var incomingName = selectedCStyles[i];
        for (var j=0; j < loopLength; j++) {
            if (incomingName === cStyles_target[j].name) { // Checks if cell style already exists. If yes, loop through properties and overwrite
                for (var k in myProperties) {
                    try {
                    if (myProperties[k] == "[object CellStyle]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        cStyles_target[j][k] =  app.documents[0].cellStyles.item(value);
                        continue
                        }
                    if (myProperties[k] == "[object ParagraphStyle]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        cStyles_target[j][k] =  app.documents[0].paragraphStyles.item(value);
                        continue
                        }
                    if (myProperties[k] == "[object StrokeStyle]" || myProperties[k] == "[object Color]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        cStyles_target[j][k] = value;
                        continue
                        }
                    cStyles_target[j][k] = myProperties[k];
                    }
                    catch (e) {}
                    }
                }
            if (j === loopLength - 1 && cStyles_target.item(incomingName).isValid === false) {  // If cell style doesn't exist, create new and loop through properties
                var newCStyle = cStyles_target.add();               
                for (var k in myProperties) {
                    try {
                    if (myProperties[k] == "[object CellStyle]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        newCStyle[k] =  app.documents[0].cellStyles.item(value);
                        continue
                        }
                    if (myProperties[k] == "[object ParagraphStyle]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        newCStyle[k] =  app.documents[0].paragraphStyles.item(value);
                        continue
                        }
                    if (myProperties[k] == "[object StrokeStyle]" || myProperties[k] == "[object Color]") {
                        value = cStyles_source.item(selectedCStyles[i]).properties[k].name;
                        newCStyle[k] = value;
                        continue
                        }
                    newCStyle[k] = myProperties[k];
                        }
                    catch (e) {}
                    }
                }
            }                
        }
    }
役に立ちましたか?

解決

On (1): Cell styles (and everything else) are identified not by name or by index in the styles array, but by a document-wide unique identifier -- the id element, which can be found in all of InDesign's native base objects. This is guaranteed to be a unique number throughout the entire document; it's one of the building blocks of ID itself.

Although the basedOn property appears to point to a cell style, in reality it contains a number: the id number of the basedOn cell style.

Even though the names of the cell styles can be the same in two documents, that is not true of their respective id's. id's are created on a first-served base while constructing new objects, but even if you constructed the two documents in the same way, at the same time, I would really not count on having the same id's then.

You do know, though, the name of the basedOn cell style; and if there is a cell style in the other document with that same name, you can work around it using this:

value = cStyle_source.basedOn.name;
cStyle_target.basedOn = app.documents[1].cellStyles.item(value);

On (2): Strangely enough, the obvious approach copies only the cell style name, and it needs a bit of copying to get the other elements over as well:

alert (app.activeDocument.cellStyles[2].name);
myProperties = app.activeDocument.cellStyles[2].properties;
cs = app.documents[1].cellStyles.add();
for (i in myProperties)
try {
    cs[i] = myProperties[i];
} catch (e)
{
    // ..
}

It needs a try..catch because not all properties are read/write; it would fail on a read-only property such as id. In addition, all properties that refer to other ID objects cannot be copied as well (basedOn, colors, line styles..). But it works well for what remains -- line thickness, for one.


What does this mean?

The functionality should be much like the existing 'Load cell styles' option in InDesign, except it should be able to do this on a batch folder instead of one document at a time.

You can loop over the files in your folder and do an app.activeDocument.import (ImportFormat.CELL_STYLES_FORMAT, from, globalStrategy) for each of them.

See #importStyles for the full explanation of parameters.

Only thing is, there seem to be no way to import some styles -- you must set up your source file with all, and only, cell styles you want in the target files.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top