Tutorial: Переделываем скрипт в плагин

  • Автор темы Автор темы tonych
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

tonych

Moderator
Топикстартер
Сообщения
6
Реакции
1
В качестве исходного материала возьмём скрипт на JavaScript, преобразующий абзацы, заданные стилем «ramka» и «inv», в таблицу.

Код:
const ramka = "ramka";
const inv = "inv";
with(app)
{
  var myDoc = activeDocument;
  var myStory = myDoc.selection[0].parentStory;
  var myParagraphs = myStory.paragraphs;
  var paperColor = myDoc.swatches.item("Paper");
  var blackColor = myDoc.swatches.item("Black");
  for(var myCount=0; myCount < myStory.paragraphs.length; myCount ++)
  {
    var myStyle = myParagraphs[myCount].appliedParagraphStyle.name;
    var myParagraph = myParagraphs[myCount];
    if(myStyle == ramka)
    {
      var myStart = myParagraph.characters[0].index;
      var myEnd = myParagraph.characters[-2].index;
      var myText = myStory.characters.itemByRange(myStart, myEnd);
      var myTable = myText.convertToTable();
      var myCell = myTable.cells[0];
      myCell.fillColor = paperColor;
      myCell.paragraphs[0].fillColor = blackColor;
    }
    else if(myStyle == inv)
    {
      var myStart = myParagraph.characters[0].index;
      var myEnd = myParagraph.characters[-2].index;
      var myText = myStory.characters.itemByRange(myStart, myEnd);
      var myTable = myText.convertToTable();
      var myCell = myTable.cells[0];
      myCell.fillColor = blackColor;
      myCell.paragraphs[0].fillColor = paperColor;
    }
  }
}
alert("ok");

Необходимый инструментарий: MS Visual C++ .NET 2003 (далее MSVC), Adobe InDesign/InCopy CS SDK (далее SDK). SDK я установил в каталог С:\Adobe\InDesignCSAndInCopyCSSDK (далее <SDK>). Adobe InDesign CS я установил в каталог С:\Adobe\InDesignCS (далее <ID>).

Первым делом нам необходимо сделать «скелет» плагина. Для этого воспользуемся программой DollyXS, входящей в состав SDK (<SDK>\devtools\sdktools\dollyxs). Запустим на выполнение файл dollyxsgui.bat и в появившемся окне заполним следующие поля:

Generate Windows project to the folder below: C:\Adobe\InDesignCSAndInCopyCSSDK/build/win/sdkprj
Output folder for the generated code below: C:\Adobe\InDesignCSAndInCopyCSSDK/source/sdksamples
Plug-in long name: border
Plug-in short name: Brdr
Plug-in prefix ID: 0x78470​
В итоге в каталоге <SDK>\source\border мы получим набор файлов-исходников для «скелета» плагина. Откомпилируем их с целью получения двоичного образа плагина (файл с расширением pln). Для этого загрузим среду разработки MSVC, откроем проект нашего плагина (меню «File/Open solution»), выберем релизную конфигурацию (меню «Build/Configuration Manager…, Active Solution Configuration: Release») и запустим процесс компиляции (меню «Project/Build solution»). В результате в каталоге <SKD>\build\win\release\sdk мы получим файл border.pln. Скопируем его в каталог <ID>\Plug-Ins. Загрузим InDesign.

Теперь самое время приступить к наполнению нашего плагина необходимой функциональностью.

1. Изменим название пункта меню вызывающего наш плагин: откроем файл «Brdr_enUS.fr» (содержит строки, которые подлежат локализации на другие языки) и изменим строку

Код:
kBrdrMenuItem1MenuItemKey,  "MenuItem1[US]",
на

Код:
kBrdrMenuItem1MenuItemKey,  "Start bordering",

2. Добавим код предназначенный для взаимодействия с «selection» (подробнее см. <SDK>\docs\guides\selection.pdf, стр. 35-46).

2.1. Добавим в наш проект файлы IBrdrSuite.h и BrdrSuiteASB.cpp (меню «Project/Add Existing Item…»).

2.2. В раздел «ClassDescriptionTable» файла «Brdr.fr» добавим строки

Код:
 AddIn
    {
        kIntegratorSuiteBoss,
        kInvalidClass,
        {
            IID_IBORDERSUITE, kBorderSuiteASBImpl,
        }
    },
  AddIn
    {
        kLayoutSuiteBoss,
        kInvalidClass,
        {
            IID_IBORDERSUITE, kBorderSuiteLayoutCSBImpl,
        }
    },
    CAlert::InformationAlert(kBrdrMenuItem1StringKey);

2.3. В файле «BrdrActionComponent.cpp» содержимое метода

Код:
void BrdrActionComponent::DoMenuItem1(IActiveContext* ac)

заменим на
Код:
do
  {
    TESTNIL(IActiveContext, ac)

    InterfacePtr<IBorderSuite> borderSuite(ac->GetContextSelection(), UseDefaultIID());
    TESTNIL(IBorderSuite, borderSuite)

    if(borderSuite->CanBordering()) borderSuite->DoBordering();
  }
  while(kFalse);

2.4. В файл «BrdrFactoryList.h» добавим

Код:
REGISTER_PMINTERFACE(BorderSuiteASB, kBorderSuiteASBImpl)
REGISTER_PMINTERFACE(BorderSuiteLayoutCSB, kBorderSuiteLayoutCSBImpl)

2.5. В файл «BrdrID.h» добавим

Код:
// InterfaceIDs:
DECLARE_PMID(kInterfaceIDSpace, IID_IBORDERSUITE, kBrdrPrefix + 0)

// ImplementationIDs:
DECLARE_PMID(kImplementationIDSpace, kBorderSuiteASBImpl, kBrdrPrefix + 1)
DECLARE_PMID(kImplementationIDSpace, kBorderSuiteLayoutCSBImpl, kBrdrPrefix + 2)

3. Теперь приступим к рассмотрению реализации алгоритма замены абзаца на таблицу (файл «BrdrSuiteLayoutCSB.cpp» приведён с сокращениями).

Код:
ErrorCode BorderSuiteLayoutCSB::DoBordering()
{
  ErrorCode status = kFailure;
  do
  {

Получим указатель на «text model» - объект, управляющий символами и форматированием текстовых блоков

(<SDK>\docs\guides\programmingguide.pdf, стр. 359):

Код:
const UIDRef textModelUIDRef = GetTextModelUIDRef();
    InterfacePtr<ITextModel> textModel(textModelUIDRef, UseDefaultIID());
    IDocument* document = gSession->GetActiveContext()->GetContextDocument();
    IDataBase* database = ::GetDataBase(textModel);
    Utils<ITableUtils> tableUtils;

Получим указатель на интерфейс атрибутов объекта содержащего форматирование абзаца (<SDK>\docs\guides\programmingguide.pdf, стр. 369):

Код:
InterfacePtr<IAttributeStrand> paraAttributeStrand(static_cast<IAttributeStrand*>(textModel->QueryStrand(kParaAttrStrandBoss, IID_IATTRIBUTESTRAND)));
    InterfacePtr<IStrand> paraStrand(paraAttributeStrand, UseDefaultIID());

Получим указатель на интерфейс таблицы стилей текущего документа:

Код:
InterfacePtr<const IStyleNameTable> styleNameTable(document->GetDocWorkSpace(), IID_IPARASTYLENAMETABLE);

Получим UID (уникальный идентификатор) объекта представляющего стиль параграфа в базе данных документа:

Код:
const UID paraStyle1UID = styleNameTable->FindByName(PMString("ramka"));

Получим UID объекта представляющего цвет в базе данных документа:

Код:
const UID swatch1UID = Utils<ISwatchUtils>()->GetNamedSwatch(PMString("Black"), database);
    TextIndex position = 0;
    int32 length = 0;

Найдём длину содержимого текстового блока:

Код:
const int32 totalLength = textModel->TotalLength();
    while(length < totalLength)
    {
      bool paraChanged = false;

Найдём длину абзаца:

Код:
const int32 paraLength = paraStrand->GetRunLength(position);

Получим UID объекта представляющего стиль параграфа в текущей позиции:

Код:
 int32 tmp = 0;
      const UID paraStyleUID = paraAttributeStrand->GetStyleUID(position, &tmp);
      if(paraStyleUID != kInvalidUID)
      {
        const Text::StoryRange textRange(position, position + paraLength - 1);
        if(paraStyleUID == paraStyle1UID)
        {

Зададим цвет текста абзаца:

Код:
SetTextColor(textModel, position, paraLength, swatch1UID);

Преобразуем абзац в таблицу:

Код:
const UIDRef tableUIDRef = tableUtils->ConvertTextToTable(textModel, textRange);

Получим указатель на «table model» - объект, управляющий таблицами (<SDK>\docs\guides\tables.pdf, стр. 29):

Код:
InterfacePtr<ITableModel> tableModel(tableUIDRef, UseDefaultIID());

Зададим цвет фона таблицы:

Код:
const GridArea cell(0, 0, 1, 1);
          SetFillColor(tableModel, cell, swatch2UID);
          paraChanged = true;
        }
      }
      position += paraChanged ? 2 : paraLength;
      length += paraLength;
    }
    status = kSuccess;
  }
  while(kFalse);
  return(status);
}


В приложенном файле находятся:
- версия этого туториала в формате Word;
- откомпилированный плагин;
- исходные тексты плагина (расположены в каталоге plugin).
 

Вложения

  • Спасибо
Реакции: dumbm1
Ответ: Tutorial: Переделываем скрипт в плагин

А можно сделать так, чтобы данный плагин (или его аналог) заработал в CS-2 ?
В СS он работал очень аккуратно и быстро (хвала автору и почтение!!!)
А тут не хочет :(
 
Статус
Закрыто для дальнейших ответов.