Поиск/замена отсутствующих шрифтов при помощи скрипта
Вам знакомо это изображение? Да, такое можно увидеть, когда открываешь файл Индизайна, сделанный где-то в другом месте. Светло-красная подсветка информирует, что в системе отсутствуют требуемые шрифты.
Сейчас мы подробно рассмотрим как при помощи программирования можно заменить отсутствующий шрифт. Итак, начнем! Во первых, получим все используемые шрифты в документе
1 | var usedFonts = app.activeDocument.fonts; |
Каждый шрифт имеет свойство status и мы можем циклом просмотреть все шрифты для обнаружения тех, которые не имеют свойства ‘FontStatus.INSTALLED’:
1 2 3 4 5 | var missingFonts = Array(); for(var i = 0; i < usedFonts.length; i++){ if(usedFonts[i].status != FontStatus.INSTALLED) missingFonts.push(usedFonts[i]); } |
Теперь массив ‘missingFonts’ содержит все объекты шрифтов, которые отсутствуют в документе. Что мы можем сделать сейчас? Мы можем просто использовать Найти / Заменить, чтобы заменить отсутствующий шрифт на шрифты, доступные в нашей системе. Давайте сначала посмотрим простой пример:
1 2 3 | app.findTextPreferences = NothingEnum.nothing; app.findTextPreferences.appliedFont = missingFonts[0]; var missingFind = app.activeDocument.findText(); |
Затем примерно так будем производить замену
1 2 3 4 5 | app.findTextPreferences = NothingEnum.nothing; app.changeTextPreferences = NothingEnum.nothing; app.findTextPreferences.appliedFont = missingFonts[0]; app.changeTextPreferences.appliedFont = "Myriad Pro"; app.activeDocument.changeText(); |
Итак, вот и все, быстро и просто. Конечно, можно, например, найти / заменить только в отдельных фреймах, материалах (Story), страницах или где угодно. Это зависит от ваших потребностей.
Теперь рассмотрим полный скрипт. Диалоговое окно немного напоминает окно поиска шрифтов в InDesign (меню Type > Find Font). Запустив скрипт вы увидите:
Здесь надо выбрать шрифт для замены и нажать OK
Ну вот, красноты на странице стало меньше. И при повторном запуске скрипта в списке уменьшилось число недоступных шрифтов.
А теперь полный текст скрипта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | //get unique Array elements Array.prototype.unique = function (){ var r = new Array(); o:for(var i = 0, n = this.length; i < n; i++){ for(var x = 0, y = r.length; x < y; x++){ if(r[x]==this[i]) continue o;} r[r.length] = this[i];} return r; } //search inside array Array.prototype.findIn = function(search){ var r = Array(); for (var i=0; i<this.length; i++) if (this[i].indexOf(search) != -1){ r.push(this[i].substr(this[i].indexOf("\t") + 1, this[i].length)); } return r; } var usedFonts = app.activeDocument.fonts; var sysFonts = app.fonts.everyItem(); sysFontsList = sysFonts.fontFamily.unique(); sysFontsList.unshift("- Select Font Family -"); var fontsWin = new Window('dialog', 'Document Fonts'); fontsWin.alignChildren = 'center'; var allFonts = fontsWin.add('listbox', undefined, undefined, {numberOfColumns: 5, showHeaders: true, columnTitles: ['Font Name', 'Font Style', 'Font PS Name', 'Font Type', 'Chr count']}); allFonts.minimumSize = [600,150]; var myGrp = fontsWin.add('group'); myGrp.alignChildren = 'center'; var availableFonts = myGrp.add('dropdownlist',undefined,sysFontsList); var availableStyles = myGrp.add('dropdownlist'); var okButton = myGrp.add('button',undefined,'OK'); var okButton = myGrp.add('button',undefined,'Cancel'); availableStyles.minimumSize = [180,25]; availableFonts.selection = 0; availableFonts.onChange = function(){ availableStyles.removeAll(); var sysFontAvailableStyles = sysFonts.name.findIn(availableFonts.selection); for(var i = 0; i < sysFontAvailableStyles.length; i++)availableStyles.add('item',sysFontAvailableStyles[i]); availableStyles.selection = 0; } //// SHOW JUST MISSING FONTS //// [START] for(var i = 0; i < usedFonts.length; i++){ if(usedFonts[i].status != FontStatus.INSTALLED){ allFonts.add('item',usedFonts[i].fontFamily); allFonts.items[allFonts.items.length-1].image = File('/l/alert_icon.png'); allFonts.items[allFonts.items.length-1].subItems[3].text = findCharacters(usedFonts[i].name); allFonts.items[allFonts.items.length-1].subItems[0].text = usedFonts[i].fontStyleName; allFonts.items[allFonts.items.length-1].subItems[1].text = usedFonts[i].postscriptName; allFonts.items[allFonts.items.length-1].subItems[2].text = usedFonts[i].fontType; } } //// SHOW JUST MISSING FONTS //// [END] allFonts.selection = 0; fontsWin.center(); var fontAnswer = fontsWin.show(); if(fontAnswer == true && availableFonts.selection != 0){ var sourceFont = allFonts.selection.text + "\t" + allFonts.selection.subItems[0].text; var destFont = availableFonts.selection.text + "\t" + availableStyles.selection.text; changeFont(sourceFont,destFont); }else{ alert('No Actions taken!'); } function findCharacters(findFont){ app.findGrepPreferences = NothingEnum.nothing; app.changeGrepPreferences = NothingEnum.nothing; app.findGrepPreferences.findWhat = "."; app.findGrepPreferences.appliedFont = findFont; var result = Number(app.activeDocument.findGrep().length); return result; } function changeFont(sourceFont, destinationFont){ app.findTextPreferences = NothingEnum.nothing; app.changeTextPreferences = NothingEnum.nothing; app.findTextPreferences.appliedFont = sourceFont; app.changeTextPreferences.appliedFont = destinationFont; app.activeDocument.changeText(); } |
Также, если вы хотите увидеть все шрифты документа в диалоговом окне скрипта, то используйте этот код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //// SHOW ALL FONTS //// [START] for(var i = 0; i < usedFonts.length; i++){ if(usedFonts[i].status == FontStatus.INSTALLED){ allFonts.add('item',usedFonts[i].fontFamily); }else{ allFonts.add('item',usedFonts[i].fontFamily); allFonts.items[i].image = File('/m/alert_icon.png'); allFonts.items[i].subItems[3].text = findCharacters(usedFonts[i].name); } allFonts.items[i].subItems[0].text = usedFonts[i].fontStyleName; allFonts.items[i].subItems[1].text = usedFonts[i].postscriptName; allFonts.items[i].subItems[2].text = usedFonts[i].fontType; } //// SHOW ALL FONTS //// [END] |
На этом всё. Мы перевели этот материал для вас с сайта InDesign Snippets: http://indisnip.wordpress.com/2010/08/24/findchange-missing-font-with-scripting/.
Примечание: для использования скрипта необходимо иметь на диске графическое изображение треугольника с восклицательным знаком и в строке 56 задать его местоположение.
сразу вопрос: зачем заменять отсутствующий шрифт на другой? Обычно надо установить такой же, с помощью программы для установки шрифтов.
Сразу ответ: в файле, сделанном на MAC может не оказаться аналога шрифта под Windows и наоборот. Другой вопрос — зачем скрипт, если есть стандартное средство в Индизайне? Думаю, что это чем-то поможет скриптописателям, и они это дело куда-нибудь пристроят при необходимости.
В документе 8 фонтов, 4 из них missing
var usedFonts = app.activeDocument.fonts;
for(var i = 0; i < usedFonts.length; i++){
alert (usedFonts[i].status);}
Alert говорит что у всех 8 статус 1718831470, то есть FontStatus.INSTALLED
Что я делаю не так?
Mac OS 10.4.11, InDesign 5.0.4
Есть еще одна проблема, штатного решения которой, к сожалению, в индюке нет: поиск отсутствующих в шрифте глифов. В скриптовой объектной модели для этого нет ни одной зацепки. Может кто-нибудь встечал плагин?