JavaScript и Keynote
Переходим на новый уровень взаимодействия с OS X.
Эта статья об автоматизации решения следующих задач:
- Пакетный экспорт презентаций в PDF/HTML/Power Point;
- Извлечение данных из презентаций;
- Создание презентации из электронной таблицы;
- Создание презентации из группы картинок;
- Изменение оформления нескольких презентаций одновременно.
Есть два способа извлечь пользу из этого материала:
- Скопировать готовый код, прочитать краткую инструкцию и пользоваться им;
- Дочитать статью до конца, узнать как устроено приложение и изучить множество полезных приемов создания автоматизаций под Mac на JavaScript. Эти знания помогут переделать «под себя» код из статьи или создавать свои собственные скрипты.
Краткая инструкция
1. Берем Mac с операционной системой OS X Yosemite или OS X El Capitain;
2. Запускаем Keynote;
3. Открываем Программы → Утилиты → Редактор скриптов;
4. Копируем туда код c этой страницы:
5. Нажимаем на черный треугольник, чтобы выполнить его:
Дальнейшие действия зависят от поставленной задачи.
Экспорт презентаций
Когда бывает нужно: если надо по-быстрому выложить несколько презентаций на сайт в виде html-страничек, послать их по почте приятелям с Windows (во избежании вопросов: «А это что еще за key-файлы?») или сохранить в PDF, чтобы смотреть в iBooks.
1. Выбираем пункт меню Экспортировать презентации и нажимаем ОК:
2. Выбираем один или несколько файлов для экспорта:
3. Выбираем один или несколько форматов экспорта:
4. Если появилось такое окно, значит все готово (надо нажать ОК):
5. Смотрим результаты экспорта на iCloud Drive в папке Keynote:
Извлечение данных
Когда бывает нужно: когда какая-то какая то полезная информация в интернете существует только в виде презентации или когда коллега сделал презентацию в таком жутком виде, что ее надо полностью переделать, а текстовое содержимое сочинялось по ходу создания и переписывать его/копировать руками времени нет.
1. Выбираем пункт меню Экспортировать презентации и нажимаем ОК:
2. Выбираем один или несколько файлов, из которых будем извлекать данные:
3. Дожидаемся появления индикатора готовности:
4. На iCloud Drive в папке TextEdit находим файл с данными:
Создание презентации из электронной таблицы
Когда бывает нужно: когда есть необходимость или желание сократить на треть время создании презентации.
Программы для создания презентации, включая Keynote, очень неудобны для ввода текста. Много времени тратиться впустую на переходы между слайдами и переключение активных зон. Чтобы ускорить процесс создания слайдов, можно набрать их содержимое в текстовом редакторе, скопировать в Numbers и скриптом сгенерировать презентацию.
1. Перед запуском скрипта следует создать электронную таблицу. В ячейки первого столбца поместить заголовки слайдов, а в ячейки второго основной текст:
Сохранить таблицу следует в папку Numbers на iCloud Drive.
2. Запускаем скрипт, выбираем пункт меню Создать презентацию из файла и нажимаем ОК:
3. Выбираем электронную таблицу с данными для создания презентации:
4. Выбираем файл-шаблон для презентации:
5. Указываем, сколько строк файла надо использовать для создания слайдов презентации:
6. Указываем имя для сохранения новой презентации:
7. Дожидаемся появления индикатора готовности:
8. Ищем новую презентацию на iCloud Drive и смотрим, что получилось:
Создание презентации из картинок
Когда бывает нужно: когда есть папка со схемами/графиками/фотографиями, а сил вставлять их в презентацию по одной нет. Примечание: Как мгновенно сохранить все графики из электронной таблицы в картинки будет рассказано в одной из следующих статей.
1. Запускаем скрипт, выбираем пункт меню Создать презентацию из картинок и нажимаем ОК:
2. Выбираем картинки:
3. Указываем имя новой презентации:
4. Дожидаемся появления индикатора готовности:
5. Ищем результат на iCloud Drive:
Изменение оформления презентации
Когда бывает нужно: когда перед конференцией неожиданно обнаружилось, что у слайдов ко всем докладам мелкий шрифт.
1. Запускаем скрипт, выбираем пункт меню Изменить оформление презентации и нажимаем ОК:
2. Выбираем одну или несколько презентаций для редактирования:
3. Выбираем часть презентации, которую будем редактировать:
4. Выбираем цвет текста:
5. Указываем размер шрифта:
6. Указываем угол поворота текста:
7. Дожидаемся появления индикатора готовности:
8. Смотрим обработанный файл:
Кстати, отличная первоапрельская шутка: пока коллега вышла на чай, взять все ее презентации и перевернуть в них вверх дном текст заголовков.
А теперь перейдем к подробному разбору кода.
Меню с выбором функции
// Сокращаем обращение к приложению, чтобы дальнейший код было легче читать Keynote = Application("Keynote"); // Включаем возможность использования UI-элементов Keynote.includeStandardAdditions = true; // Отображаем listbox с выбором действия currentAction=Keynote.chooseFromList(["Экспортировать презентации","Извлечь данные из презентаций", "Создать презентацию из файла", "Создать презентацию из картинок","Изменить оформление презентаций"],{withPrompt:"Что надо сделать?"}); // В зависимости от выбранного действия запускаем нужную функцию if(currentAction=="Экспортировать презентации") { exportKeynote(); } if(currentAction=="Извлечь данные из презентаций") { extractKeynote(); } if(currentAction=="Создать презентацию из файла") { createKeynote(); } if(currentAction=="Создать презентацию из картинок") { createKeynoteFromImages() } if(currentAction=="Изменить оформление презентаций") { editKeynote() }
Начинается выполнение скрипта с выпадающего списка для выбора нужного действия, которые создается с помощью метода chooseFromList. Иногда, при использовании этого метода возникает такая ошибка:
Чтобы ее не возникало, необходимо перед запуском скрипта запускать Keynote, как это сказано в краткой инструкции.
Обратите внимание также на эту строчку:
Keynote.includeStandardAdditions = true;
Перед тем как использовать элементы графического интерфейса в любом приложении (Keynote, Pages, Mail и т.д.), необходимо включить для него доступ к стандартным расширениям.
Экспорт презентаций
function exportKeynote() { // Отображаем панель Finder для выбора файлов с презентациями pathKeynote=Keynote.chooseFile({withPrompt:"Какие презетации нужно конвертировать?", multipleSelectionsAllowed:true}); // Отображаем listbox с выбором форматов для экспорта listFormats=new Array(); listFormats=Keynote.chooseFromList(["PDF","Microsoft PowerPoint","HTML"],{withPrompt:"В какие форматы нужно конвертировать?", multipleSelectionsAllowed:true}); // Объявляем служебный массив с расширениями, соответствующими каждому формату var extensions=new Array(); extensions['PDF']=".pdf"; extensions['HTML']=".html"; extensions['Microsoft PowerPoint']=".pptx"; // Открываем выбранные файлы с презентациями var sourceKeynote =Keynote.open(pathKeynote); // Перебираем все файлы for(i=0;i<=sourceKeynote.length-1;i++) { // Текущий файл экспортируем во все выбранные форматы поочередно for(j=0;j<=listFormats.length-1;j++) { sourceKeynote[i].export({to:"/Users/irina/Library/Mobile Documents/com~apple~Keynote/Documents/"+sourceKeynote[i].name().replace(".key","")+extensions[listFormats[j]],as:listFormats[j]}); } // Закрываем текущий файл sourceKeynote[i].close(); } }
Выбор презентации производится с помощью метода chooseFile. Мы указали параметр multipleSelectionsAllowed равный true и можем выбирать несколько файлов для обработки. Если бы мы его не указывали, то могли бы выбрать только один файл.
Для выбора целой папки для обработки следовало бы использовать метод chooseFolder.
В нашем скрипте используется только три формата для экспорта. Но еще существует возможность сохранить презентацию в виде видео, папки с картинками или файла с расширением .ppt (для неистребимых любителей MS Office 2003 и Windows XP).
Извлечение данных
function extractKeynote() { TextEdit = Application("TextEdit"); // Отображаем панель Finder для выбора презентаций, из которых будем извлекать данные pathKeynote=Keynote.chooseFile({withPrompt:"Из каких презентаций нужно извлечь данные?", multipleSelectionsAllowed:true}); // Открываем выбранные файлы var sourceKeynote = Keynote.open(pathKeynote); // Перебираем файлы с презентациями for(i=0;i<=sourceKeynote.length-1;i++) { // Создаем пустой текстовый файл var extractData=TextEdit.Document().make(); content=""; // Перебираем слайды презентации for (j=0;j<=sourceKeynote[i].slides().length-1;j++) { // Добавляем текст заголовка и тела слайда к переменной "content" titleText=sourceKeynote[i].slides()[j].defaultTitleItem().objectText() bodyText=sourceKeynote[i].slides()[j].defaultBodyItem().objectText(); var content = content +titleText+": "+bodyText+"\n"; } // Вставляем заголовки и тексты всех слайдов в текстовый файл extractData.text = content; // Сохраняем текстовый файл с извлеченными данными (на iCloud!) extractData.save({in:"/Users/irina/Library/Mobile Documents/com~apple~TextEdit/Documents/"+sourceKeynote[i].name().replace(".key","")+".txt"}); // Закрываем все файлы extractData.close({saving:"no"}); sourceKeynote[i].close({saving:"no"}); } }
Сохранять извлеченные данные можно не только в текстовый файл, но и в электронную таблицу, документ Pages или черновик письма.
Создание презентации из таблицы
function createKeynote() { Numbers = Application("Numbers"); // Отображаем панели Finder для выбора файла с данными и шаблона для презентации pathNumbers=Keynote.chooseFile({withPrompt:"Выберите файл с данными"}); pathKeynote=Keynote.chooseFile({withPrompt:"Выберите шаблон для презентации"}); // Создаем презентацию var newKeynote = Keynote.open(pathKeynote); // Открываем файл с данными var sourceTable = Numbers.open(pathNumbers); // Кладем в переменную таблицу из которой будем брать данные (самая верхняя таблица на первом листе) var name = sourceTable.name(); var sheet = sourceTable.sheets[0]; var table = sheet.tables[0]; // Отображаем окно с вопросом о количестве используемых строк countRows=Keynote.displayDialog("Из скольких строк с данными будем делать слайды?",{defaultAnswer:"5"}).textReturned; // Перебираем первые пять строк for (i=1;i<=countRows;i++) { // Создаем пустой слайд (на основе самого первого) newKeynote.slides[0].duplicate(); // Кладем последний слайд в переменную slide = newKeynote.slides[i]; // Значение из первого столбца пишем в заголовок слайда slide.defaultTitleItem().objectText=table.cells["A"+i].value(); // Значение из второго столбца пишем в тело слайда slide.defaultBodyItem().objectText=table.cells["B"+i].value(); } // Спрашиваем у пользователя имя под которым будем сохранять презентацию keynoteName=Keynote.displayDialog("Как назовем презентацию?",{defaultAnswer:"Презентация из таблицы"}).textReturned; // Сохраняем готовую презентацию newKeynote.save({in:"/Users/irina/Library/Mobile Documents/com~apple~Keynote/Documents/"+keynoteName+".key"},{as:"Keynote"}); // Закрываем презентацию и электронную таблицу newKeynote.close({saving:"no"}); sourceTable.close({saving:"no"}); }
В качестве источника данных мы могли бы использовать текстовый файл, документ Pages, письмо или веб-страницу.
Создание презентации из картинок
function createKeynoteFromImages() { // Отображаем панель Finder для выбора картинок var pathImages=new Array(); pathImages=Keynote.chooseFile({withPrompt:"Выберите картинки для вставки в презентацию", multipleSelectionsAllowed:true}); // Создаем пустую презентацию var newKeynote = Keynote.Document().make(); // Добавляем в презентацию слайды с выбранными картинками newKeynote.makeImageSlides({files:pathImages}); // Спрашиваем у пользователя имя под которым сохраним презентацию keynoteName=Keynote.displayDialog("Как назовем презентацию?",{defaultAnswer:"Презентация из картинок"}).textReturned; // Сохраняем готовую презентацию newKeynote.save({in:"/Users/irina/Library/Mobile Documents/com~apple~Keynote/Documents/"+keynoteName+".key"},{as:"Keynote"}); // Закрываем презентацию newKeynote.close({saving:"no"}); }
Редактирование презентаций
function editKeynote() { // Отображаем панель Finder с выбором презентаций для редактирования pathKeynote=Keynote.chooseFile({withPrompt:"У каких презентаций нужно изменить оформление?", multipleSelectionsAllowed:true}); // Отображаем listbox с выбором части презентации, оформление которой будем менять editPart=Keynote.chooseFromList(["Заголовок","Основной текст"],{withPrompt:"Какую часть слайда будем менять?"}); // Отображаем панель для выбора цвета текста choosedColor=Keynote.chooseColor(); // Преобразуем полученный цвет в нужный формат choosedColor[0]=Math.round(choosedColor[0]*65255); choosedColor[1]=Math.round(choosedColor[1]*65255); choosedColor[2]=Math.round(choosedColor[2]*65255); // Спрашиваем у пользователя размер шрифта fontSize=Keynote.displayDialog("Какого размера будем делать шрифт?",{defaultAnswer:"35"}).textReturned; // И угол поворота надписи textRotaion=Keynote.displayDialog("На какой угол повернем текст?",{defaultAnswer:"180"}).textReturned; // Открываем выбранные файлы var sourceKeynote = Keynote.open(pathKeynote); // Перебираем их for(i=0;i<=sourceKeynote.length-1;i++) { // Перебираем все слайды for (j=0;j<=sourceKeynote[i].slides().length-1;j++) { // Кладем в переменную нужную часть для редактирования if(editPart=="Заголовок") { editText = sourceKeynote[i].slides[j].defaultTitleItem(); } if(editPart=="Основной текст") { editText = sourceKeynote[i].slides[j].defaultBodyItem(); } // Красим текст нужным цветом editText.objectText.color=choosedColor; // Меняем размер editText.objectText.size=fontSize; // И угол поворота editText.rotation=textRotaion; } } }
Если какое-то свойство текста вам редактировать не нужно, то просто закомментируйте участок кода, где оно изменяется.
Уведомление о завершении скрипта
// Отображаем текст с уведомлением для пользователя Keynote.displayAlert('Подробнее об этом скрипте и найти другие полезные автоматизации можно на iPhones.ru');
Мы закончили разбирать код нашего примера. Немного дополнительной информации напоследок.
Автоматизируем показ презентаций
Вот набор команд, который поможет вам написать проограмму для реализации собственного алгоритма показа презентации. Подобный скрипт + несколько репетиций позволят отказаться от необходимости держать в руках пульт/смартфон во время доклада:
Keynote = Application("Keynote"); // Открываем файл для показа var newKeynote = Keynote.open("/Users/irina/Library/Mobile Documents/com~apple~Keynote/Documents/example.key"); // Переходим на 6-ой слайд newKeynote.slides[6].show(); // Ждем 20 секунд delay(20); // Идем на пятый слайд newKeynote.slides[5].show(); // Ждем десять секунд delay(10); // Делаем так, чтобы пятый слайд больше не учавствовал в слайд-шоу newKeynote.slides[5].skipped="true"; // Начинаем слайд-шоу с третьего слайда newKeynote.start({from: doc.slides[3]}); // Включаем автоповтор newKeynote.autoLoop = true;
Закрытие приложений
Во всех вышеприведенных скриптах, Keynote остается открытым после выполнения всех команд. Но читателю следует знать, что выход из приложения тоже можно автоматизировать:
// Закрываем приложение без сохранения Keynote.quit({saving:"no"}); // Закрываем приложение с вопросом о сохранении Keynote.quit({saving:"ask"}); // Закрываем приложение с сохранением открытых файлов Keynote.quit({saving:"yes"});
На основе этих простых примеров можно создавать сложные автоматизации, которые принесут реальную пользу конкретно вам. Естественно, понадобится необходима дополнительная информация.
Справка по всем методам и классам, которые можно использовать в скриптах доступна из пункта меню Окно → Библиотека:
Подробнее об основных принципах создания автоматизаций на JavaScript можно прочитать на сайте Applе в статье OS X 10.10 Release Notes.
P.S. В комментариях к моим прошлым статьям на тему автоматизаций для OS X некоторые читатели просили сделать статьи, посвященные AppleScript. Но вместо них будут статьи про JavaScript. Почему?
На этом языке можно делать все тоже самое, что и на Apple Script, но у создания автоматизаций для OS X на JavaScript есть ряд преимуществ:
- JavaScript — это новшество, которое приходит на смену Apple Script (начиная с OS X Yosemite). Зачем нам тратить время на вчерашний день?
- На AppleScript можно писать автоматизации только для OS X, а на JavaScript пользовательские скрипты для браузеров, макросы с использованием Java Script API для Microsoft Office, скрипты для LibreOffice и т.д. Не говоря уже о веб-разработке. Вкладываясь в изучение этого языка, вы открываете себе дверь в мир автоматизаций под самые разные платформы;
- JavaScript, в отличие от Apple Script прекрасно умеет работать с регулярными выражениями! А в деле автоматизации рутины без них некуда!
По моему мнению, самое весомое преимущество Apple Script перед JavaScript — это огромная база готовых скриптов на этом языке, накопленная за десяток с лишним лет его активного применения пользователями OS X.
В обозримом будущем выпустим статью о самых полезных готовых скриптах на Apple Script. Но детально рассматривать применение этого языка не будем, чтобы не тратить зря время читателя. А учиться писать автоматизации будем на JavaScript.
P.S. S. Совсем недавно у нас вышло несколько статей про Automator:
Читателю следует знать, что автоматизации на JavaScript (Apple Script/Shell Script) отлично комбинируется с этим инструментом. Надо просто перетащить на основное поле действие Запустить JavaScript и вставить в него нужный код: