JavaScript и Keynote

Переходим на новый уровень взаимодействия с OS X.

Эта статья об автоматизации решения следующих задач:

  • Пакетный экспорт презентаций в PDF/HTML/Power Point;
  • Извлечение данных из презентаций;
  • Создание презентации из электронной таблицы;
  • Создание презентации из группы картинок;
  • Изменение оформления нескольких презентаций одновременно.

Есть два способа извлечь пользу из этого материала:

  • Скопировать готовый код, прочитать краткую инструкцию и пользоваться им;
  • Дочитать статью до конца, узнать как устроено приложение и изучить множество полезных приемов создания автоматизаций под Mac на JavaScript. Эти знания помогут переделать «под себя» код из статьи или создавать свои собственные скрипты.

Краткая инструкция

1. Берем Mac с операционной системой OS X Yosemite или OS X El Capitain;
2. Запускаем Keynote;
3. Открываем ПрограммыУтилитыРедактор скриптов;
4. Копируем туда код c этой страницы:
start_with_code
5. Нажимаем на черный треугольник, чтобы выполнить его:
start_automation

Дальнейшие действия зависят от поставленной задачи.

Экспорт презентаций

Когда бывает нужно: если надо по-быстрому выложить несколько презентаций на сайт в виде html-страничек, послать их по почте приятелям с Windows (во избежании вопросов: «А это что еще за key-файлы?») или сохранить в PDF, чтобы смотреть в iBooks.

1. Выбираем пункт меню Экспортировать презентации и нажимаем ОК:
choose_export_keynote
2. Выбираем один или несколько файлов для экспорта:
choose_file_for_export
3. Выбираем один или несколько форматов экспорта:
choose_format
4. Если появилось такое окно, значит все готово (надо нажать ОК):
export_is_ready
5. Смотрим результаты экспорта на iCloud Drive в папке Keynote:

exported_files

Извлечение данных

Когда бывает нужно: когда какая-то какая то полезная информация в интернете существует только в виде презентации или когда коллега сделал презентацию в таком жутком виде, что ее надо полностью переделать, а текстовое содержимое сочинялось по ходу создания и переписывать его/копировать руками времени нет.

1. Выбираем пункт меню Экспортировать презентации и нажимаем ОК:
start_extract_data
2. Выбираем один или несколько файлов, из которых будем извлекать данные:
choose_presentation
3. Дожидаемся появления индикатора готовности:
export_is_ready
4. На iCloud Drive в папке TextEdit находим файл с данными:
extracted_data

Создание презентации из электронной таблицы

Когда бывает нужно: когда есть необходимость или желание сократить на треть время создании презентации.

Программы для создания презентации, включая Keynote, очень неудобны для ввода текста. Много времени тратиться впустую на переходы между слайдами и переключение активных зон. Чтобы ускорить процесс создания слайдов, можно набрать их содержимое в текстовом редакторе, скопировать в Numbers и скриптом сгенерировать презентацию.

1. Перед запуском скрипта следует создать электронную таблицу. В ячейки первого столбца поместить заголовки слайдов, а в ячейки второго основной текст:

numbers_for_keynote

Сохранить таблицу следует в папку Numbers на iCloud Drive.

2. Запускаем скрипт, выбираем пункт меню Создать презентацию из файла и нажимаем ОК:
create_from_file

3. Выбираем электронную таблицу с данными для создания презентации:
choose_numbers_for_keynote

4. Выбираем файл-шаблон для презентации:
choose_file_template

5. Указываем, сколько строк файла надо использовать для создания слайдов презентации:

numbers_of_rows

6. Указываем имя для сохранения новой презентации:

name_of_keynote

7. Дожидаемся появления индикатора готовности:
export_is_ready

8. Ищем новую презентацию на iCloud Drive и смотрим, что получилось:

from_file_result

Создание презентации из картинок

Когда бывает нужно: когда есть папка со схемами/графиками/фотографиями, а сил вставлять их в презентацию по одной нет. Примечание: Как мгновенно сохранить все графики из электронной таблицы в картинки будет рассказано в одной из следующих статей.

1. Запускаем скрипт, выбираем пункт меню Создать презентацию из картинок и нажимаем ОК:

from_file_result

2. Выбираем картинки:

select_images

3. Указываем имя новой презентации:
keynote_pictures_name

4. Дожидаемся появления индикатора готовности:
export_is_ready

5. Ищем результат на iCloud Drive:

images_keynote

Изменение оформления презентации

Когда бывает нужно: когда перед конференцией неожиданно обнаружилось, что у слайдов ко всем докладам мелкий шрифт.

1. Запускаем скрипт, выбираем пункт меню Изменить оформление презентации и нажимаем ОК:
edit_keynote_start

2. Выбираем одну или несколько презентаций для редактирования:

choose_presentation_for_editing

3. Выбираем часть презентации, которую будем редактировать:

choose_slide_part

4. Выбираем цвет текста:
choose_color_editing

5. Указываем размер шрифта:

ask_font_size

6. Указываем угол поворота текста:

insert_rotation

7. Дожидаемся появления индикатора готовности:
export_is_ready

8. Смотрим обработанный файл:

keynote_edit_is_ready

Кстати, отличная первоапрельская шутка: пока коллега вышла на чай, взять все ее презентации и перевернуть в них вверх дном текст заголовков.

А теперь перейдем к подробному разбору кода.

Меню с выбором функции

// Сокращаем обращение к приложению, чтобы дальнейший код было легче читать
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. Иногда, при использовании этого метода возникает такая ошибка:

user_interaction_error

Чтобы ее не возникало, необходимо перед запуском скрипта запускать 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_library

Подробнее об основных принципах создания автоматизаций на 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 и вставить в него нужный код:

java_script_in_automator

©  iphones.ru