IDMLlib 1.1 Release Notes

June 23rd, 2010 by afink

Hier finden Sie die deutsche Version dieses Artikels.

The FHCon GmbH is pleased to announce the release of the IDMLlib 1.1

The IDMLlib is a Java library that makes working with InDesign® IDML files easier than ever.

By providing a simple but powerful interface to all information inside an IDML file, the IDMLlib allows programmers to extract, modify and create new content without the hassle to learn the complete IDML specification but to keep everything compatible with InDesign®

Programmers are now able to to create or compose new IDML documents from existing content, without even seeing any XML, by just using standard Java syntax.

Whether you want to export InDesign® compatible Snippets from your Content Management System, create a custom IDML Marketing Portal or develop a webbased IDML translation workflow, the IDMLlib technology will reduce the expense and allows a shorter time to market for your solution.

Further information about the IDMLlib can be obtained using the following links

The delivery of the IDMLlib 1.1 starts on June 25th, existing customers will be notified how to obtain the new release.

New Features in Version 1.1

Load, Modify and Save IDML files

The IDMLlib 1.1 adds support for modifying and writing of IDML files. This simple example loads a facing pages document with 4 pages (1, 2-3, 4) , creates 2 copies of page 2-3 and appends them after page 2-3, creating a new document with 8 pages (1, 2-3, 4-5, 6-7, 8).

1
2
3
4
5
6
7
// Create an 8-pager from a 4-pager
Idml idml = new Idml("4pager.idml");
Spread spread = DocumentUtil.getSpread(idml.getAbstractDocument(), 1);
for(int i=0;i<2;i++) {
  DocumentUtil.addSpread(idml.getAbstractDocument().getAsDocument(),spread,2);
}
idml.saveAs("8pager.idml");

Support for IDML Snippets

The IDMLlib adds support for IDML Snippet files. Snippets can be loaded the same way you would load an IDML container. You can copy parts of the IDML or the whole spread with all PageItems from the snippet to a container document:

1
2
3
4
5
6
Idml idml = new Idml("Catalog.idml");
Idml idms = new Idml("ProductSnippet.idms");
SpreadIterator spreadIterator = DocumentUtil.getSpreadIterator(idms);
Spread firstSpread = spreadIterator.next();
DocumentUtil.addSpread(idml.getAbstractDocument().getAsDocument(),firstSpread);
idml.saveAs("NewCatalog.idml");

It is even possible to create new Snippets from scratch:

1
2
3
4
5
Idml idml = new Idml("Catalog.idml");
Spread spread = DocumentUtil.getSpreadIterator(idml).next();
Idml snippet = Idml.createEmptySnippet("FirstPage.idms", DocumentPreset.CS4_605_PAGEITEM);
snippet.getAbstractDocument().getAsSnippetDocument().setSpreadList(ListUtil.getAsGenericList(spread));
snippet.save();

The shortest way to import a Snippet on the first spread (index 0):

1
2
3
Idml idml = new Idml("DemoDocuments/EmptyA4.idml");
Idml idms = new Idml("DemoDocuments/ProductSnippet.idms");
DocumentUtil.importSnippet(idml, idms, 0);

Create new IDML objects from scratch

The IDMLlib 1.1 provides the ability to create every IDML object from scratch, for example a Layer :

1
2
3
4
5
6
7
8
9
10
11
Layer layer = new Layer();
layer.setSelf("ILJ12");
layer.setName("My new Layer");
layer.setLayerColor(new InDesignUIColorType(UIColors.Red));
layer.setExpendable(true);
layer.setIgnoreWrap(false);
layer.setLockGuides(false);
layer.setPrintable(true);
layer.setLocked(false);
layer.setShowGuides(true);
layer.setUI(true);

or maybe a more common use case, create PageItems like a Rectangle from scratch:

1
2
3
4
5
6
7
8
9
10
11
12
13
Rectangle rectangle = new Rectangle();
rectangle.setSelf("ILJ1");
rectangle.setFillColor("Color/Magenta");
rectangle.setStrokeWeight(0d);
rectangle.setItemTransform(TransformationMatrixType.getIdentityMatrix());
 
List geometryPathTypeList = PageItemUtil.createPathGeometryList(idml,
    new PathPointType(0, 0), //upperleft point
    new PathPointType(0, 40), //lowerleft point
    new PathPointType(40, 40), //lowerright point
    new PathPointType(40, 0) //upperright point
);
rectangle.setPathGeometryList(geometryPathTypeList);

The IDMLlib Utility Framework

The IDMLlib Utility Framework was requested by our customers to take the complexity out of recurring operations like adding appending and moving PageItems, duplicating Spreads, or importing Snippets into documents. You can find the result of this approach in the de.fhcon.idmllib.api.util package that currently contains the following utility classes:

  • DocumentUtil
  • GraphicUtil
  • GroupUtil
  • IdmlLibUtil
  • LabelUtil
  • ListUtil
  • PageItemUtil
  • SpreadUtil
  • StoryUtil
  • TransformationMatrixUtil
  • UnitConverterUtil

The IDMLlib Utility Framework is a work in progress and will grow as new requirements come in.

Here is a small example how this classes can really help you shorten your code:

Get the first Spread of a document

1
2
Idml idml = new Idml("DemoDocuments/RectanglesAndTextFrames.idml");
Spread spread = DocumentUtil.getSpreadIterator(idml).next();

Getting the first PageItem

1
AbstractIdmlPageItem pageItem = SpreadUtil.getPageItemIterator(spread).next();

Check and get a Label

1
2
3
if(PageItemUtil.hasLabel(pageItem, "Marked")){
   KeyValuePair label = PageItemUtil.getLabel(pageItem, "Marked");
}

Move a PageItem and use UnitConverterUtil to convert millimeter to point values

1
2
3
PageItemUtil.movePageItem(pageItem,100,100);
double pointValue = UnitConverterUtil.mmToPoint(100);
PageItemUtil.movePageItem(pageItem,pointValue,pointValue);

Append all PageItems of the group to the spread and move all appended PageItems by 200 point right and down.
This methods creates automagically new Story files if a TextFrame is appended

1
2
3
4
if(pageItem.isGroup()){
   PageItemIterator pageItemIterator = GroupUtil.getPageItemIterator(pageItem.getAsGroup());
   SpreadUtil.appendPageItems(spread,pageItemIterator,200,200);
}

Extract all content from all document by traversing all ParagraphStyleRanges/CharacterStyleRanges/Content of all Stories

1
2
3
4
5
6
Idml idml = new Idml("DocWithContent.idml");
StoryIterator storyIterator = DocumentUtil.getStoryIterator(idml);
while (storyIterator.hasNext()) {
   String content = StoryUtil.getContent(storyIterator.next());
   System.out.println(content);
}

Powerful PageItem traversing and filtering

Simple traversing of all top level PageItems

1
2
3
4
5
6
7
Idml idml = new Idml("DocWithPageItems.idml");
Spread spread = DocumentUtil.getSpreadIterator(idml).next();
PageItemIterator pageItemIterator = SpreadUtil.getPageItemIterator(spread);
while(pageItemIterator.hasNext()){
  AbstractIdmlPageItem pageItem = pageItemIterator.next();
//do something with the pageitem
}

Traversing with a LabelFilter

1
2
3
4
5
6
7
8
9
10
11
Idml idml = new Idml("DocWithPageItems.idml");
Spread spread = DocumentUtil.getSpreadIterator(idml).next();
 
LabelFilter labelFilter = new LabelFilter("Marked","true");
 
PageItemIterator pageItemIterator = SpreadUtil.getPageItemIterator(spread,labelFilter);
//the iterator only contains PageItems with a Label of: Key "Marked" with value "true"
while(pageItemIterator.hasNext()){
  AbstractIdmlPageItem pageItem = pageItemIterator.next();
  //do something with the pageitem
}

Traversing using a custom filter implemented as inner class that only accepts TextFrames

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Idml idml = new Idml("DocWithPageItems.idml");
Spread spread = DocumentUtil.getSpreadIterator(idml).next();    
 
PageItemIterator pageItemIterator = SpreadUtil.getPageItemIterator(spread,new IPageItemFilter(){
  public boolean accept(AbstractIdmlPageItem pageItem) {
    return pageItem.isTextFrame();
  }
});
 
//the iterator only contains TextFrames
while(pageItemIterator.hasNext()){
  AbstractIdmlPageItem pageItem = pageItemIterator.next();
  assert(pageItem.isTextFrame());
}

Work with different PageItem types

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
switch (pageItem.getPageItemType()) {
 
  case Button:
    Button button = pageItem.getAsButton();
  break;
 
  case EPSText:
    EPSText epsText = pageItem.getAsEPSText();
  break;
 
  case FormField:
    FormField formField = pageItem.getAsFormField();
  break;
 
  case GraphicLine:
    GraphicLine graphicLine = pageItem.getAsGraphicLine();
  break;
 
  case Group:
    Group group = pageItem.getAsGroup();
  break;
 
  case Oval:
    Oval oval = pageItem.getAsOval();
  break;
 
  case Polygon:
    Polygon polygon = pageItem.getAsPolygon();
  break;
 
  case Rectangle:
    Rectangle rectangle = pageItem.getAsRectangle();
  break;
 
  case TextFrame:
    TextFrame textFrame = pageItem.getAsTextFrame();
  break;
}

A plugable IdGenerator to create Self ids your way

It is very important to know that the Self attributes of IDML objects like PageItems need to stay unique for identifying purposes. Because a lot of our utility classes create new PageItems or other IDML object with Self attributes, we needed to create unique Self strings when we add them to the document.

Because we know that our approach to create them is most likely not the same approach you would choose to create unique strings, we made the IdGenerator plugable.

This means you can use our DefaultIdGenerator, but you don’t have to. We have defined an IdGenerator interface which you can implement to create your custom id generator.

1
2
3
4
5
public class MyCustomIdGenerator implements IdGenerator {
  public String getSequence(String existingId) {
    //implement your code here
   }
}

As you can see the the IdGenerator#getSequence() method always gets the Self reference as parameter of the currently processed PageItem. Our classes always give you the self reference, as long as it exists. So you could use the old id in some way.

To make our classes use your custom provided IdGenerator, make the implementation available:

1
2
Idml idml = new Idml("MyDoc.idml");
idml.setIdGenerator(new MyCustomIdGenerator());

If you need to create Self ids on your own, you can obtain the currently active IdGenerator from the Idml instance you are working with:

1
2
Idml idml = new Idml("MyDoc.idml");
IdGenerator generator = idml.getIdGenerator();

15 documented Examples

We added 15 documented examples that show you how to use the IDMLlib most effectively. Almost all examples have been derived from customer requests or show common use cases for the IDMLlib. The library of examples is a work in progress and will grow, when new requirements or questions come in.

Here is a list of examples that are part of the 1.1 release:

  • CopyTextFramesAndManipulatePSR
  • CreateNewStory
  • CreateRectangles
  • CreateRectangleWithImage
  • CreateSimpleTable
  • CreateSpreadsFromScratch
  • CreateTextFrameCopiesOnNewLayers
  • GetStoryContent
  • IdmlLoader
  • ImportSnippet
  • InsertSpread
  • LoadModifySaveIdml
  • PageItemExamples
  • PutPageItemOnDifferentLayers
  • SimpleDatabasePublishing

All examples are tested and come with prepared IDML documents that will be used to demonstrate the example.

One Response to “IDMLlib 1.1 Release Notes”

  1. [...] This post was mentioned on Twitter by peymanman, IDMLlib. IDMLlib said: IDMLlib 1.1 released http://blog.idmllib.com/2010/06/23/idmllib-1-1-release-notes/ [...]

Leave a Reply

You must be logged in to post a comment.