Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How to check that two textStyleRange have same formatting attributes

Contributor ,
Dec 22, 2018 Dec 22, 2018

Hi All,

In the below sample text snippet I have used two variants of same font i.e normal and bold

"Hello World have A nice Day"

and when I called below API then returns 6 textStyleRange objects

var textStyleRanges = story.textStyleRanges;

but textStyleRangeObject at index 1,3,5 have same formatting attribute i.e bold

So how can I identify same using script code.?

Regards,

Alam

TOPICS
Scripting
1.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , Dec 23, 2018 Dec 23, 2018

You can use following code using your logic and get the index of all word with bold style,

var myFrame = app.selection[0];

var para = myFrame.paragraphs[0];

var words = para.words;

var myIndices = [];

for(var i = 0; i < words.length; i++){

    if(words.appliedFont.fontStyleName.toString().toLowerCase() == "bold"){

        myIndices.push(i);

        }

    }

$.writeln(myIndices);

Translate
Engaged ,
Dec 23, 2018 Dec 23, 2018

What's the endgame here? It'd be easy enough to check each text style range to see if it's using bold or not. But there could be other text attributes that are different. And there are a lot of attributes.

Here's an odd idea: create a separate  text frame and duplicate two of the TSRs into it. Then get the length of the text style ranges in the frame. If the answer is 1, the two ranges are identical.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 23, 2018 Dec 23, 2018

Correct you got my points and thanks me to go in right direction

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Dec 25, 2018 Dec 25, 2018

Here's another approach, depends exactly on what you are looking to do.

/**

* [matchesCharacterProperties]                 matches textStyleRanges with a sample style

* @param  {DOM TextStyleRange}                 sampleTextStyleRange    Sample character, textStyleRange

* @param  {DOM Collection of TextStyleRange}   textStyleRanges         Collection of ranges that uses .everyItem() or itemByRange()

* @param  {Array}                              properties              [Optional defaults to set list] properties you want to match the sample

* @return {Array}                                                      Array of matching textStyleRanges

* By Trevor http://creative-scripts.com 25 Dec 18

* Not Optimized Uses toSource which will probably be dumped sometime

*/

function matchesCharacterProperties(sampleTextStyleRange, textStyleRanges, properties) {

    if (!properties) {

        properties = [

            'appliedFont',

            'appliedLanguage',

            'appliedCharacterStyle',

            'fillColor',

            'strokeColor',

            'baseline',

            'underline',

            'capitalization'

            // etc. etc. etc.....

        ];

    }

    if (typeof properties !== 'object') {

        properties = [properties];

    }

    var n, propertiesCount, sampleProperties, textStyleRangeProperties, textStyleCount, match, c, matches, textStyleRangeArray, propertiesCache;

    var resolveProperties = function(properties) {

        if (typeof properties !== 'object') {

            properties = [properties];

        }

        return properties.toSource().replace(/^\[/, '').replace(/]$/, '').split(', ');

    };

    propertiesCount = properties.length;

    sampleProperties = [];

    propertiesCache = [];

    matches = [];

    // cache the properties

    for (n = 0; n < propertiesCount; n++) {

        // resolveProperties returns an array and we only want the values hence the [0]

        sampleProperties.push(resolveProperties(sampleTextStyleRange[properties])[0]);

        // For the propertiesCache we want the Array of results for the whole collection

        propertiesCache.push(resolveProperties(textStyleRanges[properties]));

    }

    textStyleRangeArray = textStyleRanges.getElements();

    textStyleCount = textStyleRangeArray.length;

    for (c = 0; c < textStyleCount; c++) {

        match = true;

        for (n = 0; n < propertiesCount; n++) {

            textStyleRangeProperties = propertiesCache;

            if (textStyleRangeProperties !== sampleProperties) {

                match = false;

                break;

            }

        }

        if (match) {

            matches.push(textStyleRangeArray);

            // matches.push(c); // if you just want the indexes use this line instead of the above one

        }

    }

    sampleTextStyleRange = textStyleRanges = properties =

        n = propertiesCount = sampleProperties = propertiesCache =

        textStyleRangeProperties = textStyleCount = match =

        c = textStyleRangeArray = resolveProperties = null;

    return matches;

}

alert(

    matchesCharacterProperties(

        app.selection[0] || app.activeDocument.stories[0].characters[0], // The sample range you want to match

        app.activeDocument.stories[0].textStyleRanges.everyItem(), // the COLLECTION you want to check

        ['appliedFont', 'pointSize', 'fillColor', 'underline'] // [Optional] the properties you want to match

    ).toSource()

);

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Dec 25, 2018 Dec 25, 2018
LATEST

It's going to be a lot more efficient than Robert's method if ones scanning a document but you need to add the properties you want to check, which actually is not such a big deal as long as you know how to either copy and paste or sampleTextStyleRange.reflect.properties and then filter out the undesirable ones.

That said it would be interesting to see some timings on real life documents and not just 5 line test documents.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 23, 2018 Dec 23, 2018

You can use following code using your logic and get the index of all word with bold style,

var myFrame = app.selection[0];

var para = myFrame.paragraphs[0];

var words = para.words;

var myIndices = [];

for(var i = 0; i < words.length; i++){

    if(words.appliedFont.fontStyleName.toString().toLowerCase() == "bold"){

        myIndices.push(i);

        }

    }

$.writeln(myIndices);

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines