Created
October 12, 2022 23:02
-
-
Save indiscripts/144e800818b830e979498940114adf5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// InDesign script (DRAFT.) | |
//---------------------------------- | |
// Apply some text conversion routine on consistent | |
// style ranges *while preserving special characters* | |
// (anchored objects, tables, footnotes...) | |
function myConverter(/*str*/text) | |
//---------------------------------- | |
// Change a string into something else... | |
// Put your ascii-to-unicode routine here | |
{ | |
return 'x' + text.split('').reverse().join(''); | |
} | |
(function( doc,pp,ptn,src,rng,a,i,tx,t,x,b,j,z) | |
//---------------------------------- | |
{ | |
if( !(doc=app.properties.activeDocument) ) { alert("No document."); return; } | |
// Special characters that MUST be skipped. | |
// Footnote refs, tables, anchored objects... | |
// --- | |
const RE_SKIP = /[\u0004\u0016\uFFFC]/; | |
// YOUR SETTINGS | |
// --- | |
const TARGET_FAMILY_LOWER = ("Minion Pro").toLowerCase(); // E.g "nudi"; | |
const DEST_FONT_NAME = "Myriad Pro\tItalic" // E.g "Tunga"; | |
// Check dest font and set properties. | |
// --- | |
if( !(t=app.fonts.item(DEST_FONT_NAME)).isValid ) | |
{ alert("The font " + DEST_FONT_NAME + " is missing."); return; } | |
pp = | |
{ | |
contents: '', | |
appliedFont: t.getElements()[0], | |
composer: "$ID/HL Composer Optyca", // Adobe World-Ready Composer | |
// etc | |
}; | |
// Pattern formatter. | |
// --- | |
const __ = $.global.localize; | |
// Array of consistently styled Text items. | |
// --- | |
a = doc.stories.everyItem().textStyleRanges.everyItem().getElements().slice(); | |
for( i=a.length ; i-- ; ) | |
{ | |
// [REM] Forcing resolve is important! | |
// --- | |
tx = a[i].getElements()[0]; // tx :: Text ; consistent text range | |
// Filter based on font family. | |
// --- | |
t = (tx.properties.appliedFont||0).fontFamily||''; | |
if( -1 == t.toLowerCase().indexOf(TARGET_FAMILY_LOWER) ) continue; | |
// Get the last character index (x) and create a specifier | |
// pattern for accessing character ranges from %1 to %2. | |
// --- | |
ptn = tx.toSpecifier().split('%').join('%%'); // Safer (in case the spec contains `%`, change into `%%` for the pattern.) | |
ptn = ptn.split('/character['); // E.g `(/document[@id=4]//story[@id=222]`, `12] to /document[@id=4]//story[@id=222]`, `34])` | |
if( 3 != ptn.length || isNaN(x=parseInt(ptn[2],10)) ) continue; // Shouldn't happen. | |
ptn = ptn[0]+'/character[%1] to '+ptn[0].slice(1)+'/character[%2])'; // Pattern for characterRange(%1,%2) | |
// Split text contents w.r.t SPLIT_CHARS (U+0016, U+FFFC, etc) | |
// in order to preserve anchored objects and so. | |
// --- | |
t = tx.texts[0].contents + '\x01'; // [HACK] Help prevent the split(RegExp) bug (last char issue.) | |
b = t.split(RE_SKIP); | |
( t=b.length-1, b[t]=b[t].slice(0,-1) ); // [HACK] Remove \x01 suffix. | |
for( j=b.length ; j-- ; x-=(1+z) ) // b :: [src1, src2, src3...] ; tx.contents == `src1•src2•src3•...` where • is any INDD mark. | |
{ | |
z = (src=b[j]).length; // src :: original substring ; z :: length | |
if( !z ) continue; // Empty -> simply jump over the mark. | |
rng = resolve( __(ptn, ''+(x-z+1), ''+x) ); // rng :: character range of the source (Text object.) | |
pp.contents = myConverter(src)||''; // Converted substring. | |
rng.properties = pp; // Replace. | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment