{"id":25965444,"url":"https://github.com/starou/simpleidml","last_synced_at":"2025-05-15T21:07:54.072Z","repository":{"id":14340869,"uuid":"17050443","full_name":"Starou/SimpleIDML","owner":"Starou","description":"Manipulate Adobe® InDesign® IDML files","archived":false,"fork":false,"pushed_at":"2025-01-23T16:53:54.000Z","size":6156,"stargazers_count":214,"open_issues_count":9,"forks_count":36,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-05-15T21:07:07.480Z","etag":null,"topics":["idml","indd","indesign","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Starou.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-02-21T08:48:27.000Z","updated_at":"2025-05-13T01:35:47.000Z","dependencies_parsed_at":"2023-01-14T08:15:11.074Z","dependency_job_id":"42f4747a-670b-437b-bd89-b5e1a84ee315","html_url":"https://github.com/Starou/SimpleIDML","commit_stats":{"total_commits":517,"total_committers":7,"mean_commits":73.85714285714286,"dds":0.2727272727272727,"last_synced_commit":"6d16d977f723dc512682b4c3bd63ec0fa8d91f82"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Starou%2FSimpleIDML","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Starou%2FSimpleIDML/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Starou%2FSimpleIDML/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Starou%2FSimpleIDML/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Starou","download_url":"https://codeload.github.com/Starou/SimpleIDML/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254422791,"owners_count":22068680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["idml","indd","indesign","python"],"created_at":"2025-03-04T21:46:21.094Z","updated_at":"2025-05-15T21:07:51.557Z","avatar_url":"https://github.com/Starou.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"==========\nSimpleIDML\n==========\n\n.. image:: https://img.shields.io/pypi/v/simpleidml.svg\n  :target: https://pypi.python.org/pypi/SimpleIDML\n\n.. image:: https://img.shields.io/pypi/pyversions/simpleidml.svg\n    :target: https://pypi.python.org/pypi/SimpleIDML/\n    :alt: Supported Python versions\n\n.. image:: https://img.shields.io/pypi/l/simpleidml.svg\n    :target: https://pypi.python.org/pypi/SimpleIDML/\n    :alt: License\n\n.. image:: https://coveralls.io/repos/github/Starou/SimpleIDML/badge.svg?branch=master\n    :target: https://coveralls.io/github/Starou/SimpleIDML?branch=master\n\n\nInstallation\n============\n\nUse ``pip``:\n\n.. code-block:: bash\n\n    pip install SimpleIDML\n\nOr:\n\n.. code-block:: bash\n\n    python setup.py build\n    sudo python setup.py install\n\nPython support\n--------------\n\n- Python 3: 3.6+\n\nAny questions?\n--------------\n\nhttps://groups.google.com/forum/#!forum/simpleidml-users\n\nDevelopers\n----------\n\n.. code-block:: bash\n\n    vagrant up\n    vagrant ssh\n    cd tests\n    python runtests.py\n\nWhat is SimpleIDML?\n===================\n\nSimpleIDML is a Python library to manipulate Adobe® InDesign® IDML files. The main purpose being\nthe ability to compose IDML files together and produce complex documents from simple pieces and\nto separate the data from the structure.\n\nThe philosophy behind SimpleIDML is to keep the content and structure separated and to use XML\nfiles to feed your documents by using the XML Structure in InDesign.\nKeeping this isolation is important to ease the debugging and to keep track of what is going on.\n\nI urge you to take a look in the *regressiontests* directory for real-world examples.\n\nUses cases - success story(ies)\n===============================\n\nLe Figaro - FigaroClassifieds\n-----------------------------\n\nSimpleIDML is used in production at *Le Figaro* aside in-house tools managing the content of\nClassifieds Ads magazines like *Propriétés de France* or *Belles Maisons à louer*.\nThese tools produces XML files describing the page layout (which IDML templates and sub-templates\nto use) and the page content.\nThe XML files feed another tool - the one using SimpleIDML - that compose the final page.\n\nThe steps of the (simplified) process of composition are:\n\n1. Get the main IDML template (the page) ;\n2. Ad the sub-templates (the ads) into the page template ;\n3. Import the content into the final IDML file ;\n4. Edit the file in InDesign ;\n5. Push the changesets back to the content management application and update the database.\n\nThere is a lot of cool features in this application. You can update a part of a page already or\npartially composed for example.\n\nArchitecture\n''''''''''''\n\nThese applications are web-applications. The communication is done by web-services feeding a task\nqueue (RabbitMQ/Celery).\n\nThe performances are quite good. Composing a document requires a fraction of a second.\n\nWhat are IDML files?\n====================\n\nIDML (*InDesign Markup Language*) files are a Zip archives (Adobe calls them packages) storing\nessentially XML files. Adobe made a descent job because those files can completely express the\ncontent of the native (binary) documents.\nThis is a small revolution in the print world when it comes to automatically processing files both\nfrom templates and database (Round-trip) without using the proprietary server-edition of\nPublishing Software.\n\nWhat does SimpleIDML do?\n========================\n\nPackage exploration\n-------------------\n\nYou can discover the structure of your IDML files:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from simple_idml import idml\n    \u003e\u003e\u003e my_idml_package = idml.IDMLPackage(\"/path/to/my_main_document.idml\")\n    \u003e\u003e\u003e my_idml_package.spreads\n    [u'Spreads/Spread_ub6.xml', u'Spreads/Spread_ubc.xml', u'Spreads/Spread_uc3.xml']\n    \u003e\u003e\u003e my_idml_package.stories\n    [u'Stories/Story_u139.xml', u'Stories/Story_u11b.xml',\n     u'Stories/Story_u102.xml', u'Stories/Story_ue4.xml']\n\nSome attributes are *lxml.etree* Elements or Documents:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e my_package.font_families\n    [\u003cElement FontFamily at 0x1010048c0\u003e,\n     \u003cElement FontFamily at 0x101004a50\u003e,\n     \u003cElement FontFamily at 0x101004aa0\u003e,\n        \u003cElement FontFamily at 0x101004af0\u003e]\n    \u003e\u003e\u003e [e.get(\"Name\") for e in my_package.font_families]\n    ['Minion Pro', 'Myriad Pro', 'Kozuka Mincho Pro', 'Vollkorn']\n\n    \u003e\u003e\u003e my_package.xml_structure\n    \u003cElement Root at 0x101004910\u003e\n    \u003e\u003e\u003e from lxml import etree\n    \u003e\u003e\u003e # print my_package.xml_structure_pretty() is a shortcut for:\n    \u003e\u003e\u003e print etree.tostring(my_package.xml_structure, pretty_print=True)\n    \u003cRoot Self=\"di2\"\u003e\n      \u003carticle XMLContent=\"u102\" Self=\"di2i3\"\u003e\n        \u003cStory XMLContent=\"ue4\" Self=\"di2i3i1\"\u003e\n          \u003ctitle Self=\"di2i3i1i1\"/\u003e\n          \u003csubtitle Self=\"di2i3i1i2\"/\u003e\n        \u003c/Story\u003e\n        \u003ccontent XMLContent=\"u11b\" Self=\"di2i3i2\"/\u003e\n        \u003cillustration XMLContent=\"u135\" Self=\"di2i3i3\"/\u003e\n        \u003cdescription XMLContent=\"u139\" Self=\"di2i3i4\"/\u003e\n      \u003c/article\u003e\n      \u003carticle XMLContent=\"udb\" Self=\"di2i4\"/\u003e\n      \u003carticle XMLContent=\"udd\" Self=\"di2i5\"/\u003e\n      \u003cadvertise XMLContent=\"udf\" Self=\"di2i6\"/\u003e\n    \u003c/Root\u003e\n\n\n``xml_structure`` attribute is a representation of the XML Structure of your InDesign XML-ready\ndocument (The one you want to use to populate the content with data from an external XML file\nhaving the same structure).\n\n\nBuild package\n-------------\n\nThere is a convenient script to create an IDML package from a flat directory called\n*simpleidml_create_package_from_dir.py* which should be in your PATH.\n\n\nCompose document\n----------------\n\n**Important**: You should always use a ``with`` context when using side-effect methods on\n``IDMLPackage`` instances returning new instances.\n\n\nFor example, the following is bad because ``my_doc`` initial instance reference is lost and\nthe associated file cannot be properly closed. This may raise an exception on Windows platform\nif you try to ``os.unlink()`` an unclosed file.\n\n.. code-block:: python\n\n    from simple_idml import idml\n    my_doc = idml.IDMLPackage(\"/path/to/my_main_document.idml\")\n    my_doc = my_doc.prefix(\"main\")\n\nInstead, use:\n\n.. code-block:: python\n\n    from simple_idml import idml\n    my_doc = idml.IDMLPackage(\"/path/to/my_main_document.idml\")\n    with my_doc.prefix(\"main\") as f:\n        # some code.\n\nInsert elements\n'''''''''''''''\n\nUsing the XML Structure, SimpleIDML can insert the content of an XML tag from one document into an\nXML tag of another document. The tag paths are expressed using XPath_ syntax.\nNote that you should always make a copy of your idml files before altering them with\n``shutil.copy2(src, dst)`` for instance and prefix your document before using ``insert_idml()``\nto avoid reference collisions.\n\n.. code-block:: python\n\n    \u003e\u003e\u003e from simple_idml import idml\n    \u003e\u003e\u003e idml_main = idml.IDMLPackage(\"/path/to/my_main_document.idml\")\n    \u003e\u003e\u003e idml_module = idml.IDMLPackage(\"/path/to/my_small_document.idml\")\n\n    \u003e\u003e\u003e with idml_main.prefix(\"main\") as p_idml_main, \\\n    \u003e\u003e\u003e      idml_module.prefix(\"article\") as p_idml_article:\n\n    \u003e\u003e\u003e     with p_idml_main.insert_idml(p_idml_article, at=\"/Root/article[3]\",\n                                         only=\"/Root/module[1]\") as f:\n    \u003e\u003e\u003e         f.stories\n    ['Stories/Story_article1u188.xml', 'Stories/Story_article1u19f.xml',\n     'Stories/Story_article1u1db.xml', 'Stories/Story_mainu102.xml',\n     'Stories/Story_mainu11b.xml', 'Stories/Story_mainu139.xml',\n     'Stories/Story_mainue4.xml']\n\n\n    \u003e\u003e\u003e         print f.xml_structure_pretty()\n    \u003cRoot Self=\"maindi2\"\u003e\n      \u003carticle XMLContent=\"mainu102\" Self=\"maindi2i3\"\u003e\n        \u003cStory XMLContent=\"mainue4\" Self=\"maindi2i3i1\"\u003e\n          \u003ctitle Self=\"maindi2i3i1i1\"/\u003e\n          \u003csubtitle Self=\"maindi2i3i1i2\"/\u003e\n        \u003c/Story\u003e\n        \u003ccontent XMLContent=\"mainu11b\" Self=\"maindi2i3i2\"/\u003e\n        \u003cillustration XMLContent=\"mainu135\" Self=\"maindi2i3i3\"/\u003e\n        \u003cdescription XMLContent=\"mainu139\" Self=\"maindi2i3i4\"/\u003e\n      \u003c/article\u003e\n      \u003carticle XMLContent=\"mainudb\" Self=\"maindi2i4\"/\u003e\n      \u003carticle Self=\"maindi2i5\"\u003e\n        \u003cmodule XMLContent=\"article1u1db\" Self=\"article1di3i12\"\u003e\n          \u003cmain_picture XMLContent=\"article1u182\" Self=\"article1di3i12i1\"/\u003e\n          \u003cheadline XMLContent=\"article1u188\" Self=\"article1di3i12i2\"/\u003e\n          \u003cStory XMLContent=\"article1u19f\" Self=\"article1di3i12i3\"\u003e\n            \u003carticle Self=\"article1di3i12i3i2\"/\u003e\n            \u003cinformations Self=\"article1di3i12i3i1\"/\u003e\n          \u003c/Story\u003e\n        \u003c/module\u003e\n      \u003c/article\u003e\n      \u003cadvertise XMLContent=\"mainudf\" Self=\"maindi2i6\"/\u003e\n    \u003c/Root\u003e\n\n\nCombine pages\n'''''''''''''\n\nYou may need to gather pages from severals documents into a single one:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e edito_idml_file = IDMLPackage(\"magazineA-edito.idml\")\n    \u003e\u003e\u003e courrier_idml_file = IDMLPackage(\"magazineA-courrier-des-lecteurs.idml\")\n\n    \u003e\u003e\u003e # Always start by prefixing packages to avoid collision.\n    \u003e\u003e\u003e with edito_idml_file.prefix(\"edito\") as p_edito,\\\n    \u003e\u003e\u003e      courrier_idml_file.prefix(\"courrier\") as p_courrier:\n    \u003e\u003e\u003e     len(edito_idml_file.pages)\n    2\n\n    \u003e\u003e\u003e     new_idml = p_edito.add_page_from_idml(p_courrier,\n    ...                                           page_number=1,\n    ...                                           at=\"/Root\",\n    ...                                           only=\"/Root/page[1]\")\n    \u003e\u003e\u003e     len(new_idml.pages)\n    3\n\n    # The XML Structure has integrated the new file.\n    \u003e\u003e\u003e     print etree.tostring(new_idml.xml_structure, pretty_print=True)\n    \u003cRoot Self=\"editodi2\"\u003e\n      \u003cpage Self=\"editodi2ib\"\u003e\n        \u003carticle Self=\"editodi2ibif\"\u003e\n          \u003cStory XMLContent=\"editoue4\" Self=\"editodi2ibifi1f\"\u003e\n            \u003ctitle Self=\"editodi2ibifi1fi1\"/\u003e\n            \u003csubtitle Self=\"editodi2ibifi1fi2\"/\u003e\n          \u003c/Story\u003e\n          \u003ccontent XMLContent=\"editou11b\" Self=\"editodi2ibifi1e\"/\u003e\n        \u003c/article\u003e\n      \u003c/page\u003e\n      \u003cpage Self=\"editodi2i10\"\u003e\n        \u003cadvertise XMLContent=\"editou1de\" Self=\"editodi2i10i23\"/\u003e\n      \u003c/page\u003e\n      \u003cpage Self=\"courrierdi2ib\"\u003e\n        \u003ctitle XMLContent=\"courrieru1b2\" Self=\"courrierdi2ibi34\"/\u003e\n        \u003carticle XMLContent=\"courrieru1c9\" Self=\"courrierdi2ibi33\"/\u003e\n        \u003carticle XMLContent=\"courrieru1e0\" Self=\"courrierdi2ibi32\"/\u003e\n        \u003carticle XMLContent=\"courrieru1fb\" Self=\"courrierdi2ibi31\"/\u003e\n        \u003carticle XMLContent=\"courrieru212\" Self=\"courrierdi2ibi30\"/\u003e\n      \u003c/page\u003e\n    \u003c/Root\u003e\n\n\nThere is a convenient method to add several pages at once:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e edito_idml_file = IDMLPackage(\"magazineA-edito.idml\")\n    \u003e\u003e\u003e courrier_idml_file = IDMLPackage(\"magazineA-courrier-des-lecteurs.idml\")\n    \u003e\u003e\u003e bloc_notes_idml_file = IDMLPackage(\"magazineA-bloc-notes.idml\")\n\n    \u003e\u003e\u003e with edito_idml_file.prefix(\"edito\") as p_edito,\\\n    \u003e\u003e\u003e      courrier_idml_file.prefix(\"courrier\") as p_courrier,\\\n    \u003e\u003e\u003e      bloc_notes_idml_file.prefix(\"blocnotes\") as p_bloc_notes:\n\n    \u003e\u003e\u003e     packages_to_add = [\n    ...         (p_courrier, 1, \"/Root\", \"/Root/page[1]\"),\n    ...         (p_bloc_notes, 1, \"/Root\", \"/Root/page[1]\"),\n    ...     ]\n\n    \u003e\u003e\u003e     new_idml = p_edito.add_pages_from_idml(packages_to_add)\n    \u003e\u003e\u003e     len(new_idml.pages)\n    4\n    \u003e\u003e\u003e     new_idml.spreads\n    ['Spreads/Spread_editoub6.xml',\n     'Spreads/Spread_editoubc.xml',\n     'Spreads/Spread_editoubd.xml']\n\n\nImport/Export XML\n-----------------\n\nExporting as XML:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e idml_file = IDMLPackage(\"path/to/file.idml\")\n    \u003e\u003e\u003e print idml_file.export_xml()\n    \u003cRoot\u003e\n        \u003cmodule\u003e\n            \u003cmain_picture/\u003e\n            \u003cheadline\u003eHello world!\u003c/headline\u003e\n            \u003cStory\u003e\n                \u003carticle\u003eLorem ipsum dolor sit amet, ...\u003c/article\u003e\n                \u003cinformations\u003eLorem ipsum dolor sit amet,\u003c/informations\u003e\n            \u003c/Story\u003e\n        \u003c/module\u003e\n    \u003c/Root\u003e\n\nYou can also import XML files into your InDesign® documents. The following rules applies:\n\n- A node having the attribute ``simpleidml-setcontent=\"false\"`` will not update the content of the\n  corresponding element into the idml document (but its children will be updated).\n- A node having the attribute ``simpleidml-ignorecontent=\"true\"`` will not update the content of the\n  corresponding element into the idml document **and** its children.\n- A node having the attribute ``simpleidml-setcontent=\"delete\"`` will remove the corresponding\n  element into the idml document (Story and Spread elements).\n- A node having the attribute ``simpleidml-setcontent=\"clear\"`` will clear the text in the\n  element.\n- A node having the attribute ``simpleidml-setcontent=\"remove-previous-br\"`` will remove the new-line\n  characters before the element.\n- You can mix several flags using a comma (i.e.: ``simpleidml-setcontent=\"delete,remove-previous-br\"``)\n- In a *ignorecontent* context the content of a child node can be turned on with the\n  ``simpleidml-forcecontent=\"true\"`` flag.\n- Image references are passed by the *href* attribute. An empty value will remove the\n  corresponding page items into the document.\n- A nested tag will be created if mapped with a *character-style*.\n- The style applied to the newly created tag is a combination of the parent character-style and\n  the mapped one.\n\nPlease take a look into the tests for in-depth examples.\n\nImport PDF\n----------\n\nA block can be used as a placeholder for a PDF file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e with IDMLPackage(\"my_package.idml\") as idml_file:\n    \u003e\u003e\u003e     with idml_file.import_pdf(\"file:/path/to/file.pdf\", at=\"/Root/modules/module[2]\", crop=\"PDFCrop\") as f:\n    \u003e\u003e\u003e         f.export_xml()\n\nThe ``crop`` parameter should be one of the ``PDFCrop_EnumValue`` from the IDML Specification\n(``\"CropArt\"``, ``\"CropPDF\"``, ``\"CropTrim\"``, ``\"CropBleed\"``, ``\"CropMedia\"``,\n``\"CropContentVisibleLayers\"``, ``\"CropContentAllLayers\"``, ``\"CropContent\"``).\nIt defaults to ``CropContentVisibleLayers````\n\nUse InDesign server SOAP interface to convert a file\n----------------------------------------------------\n\nThis require an *InDesign Server* and a readable/writable working directory.\nThe same directory must be accessible by the client either by the filesystem or\nover FTP.\n\nThe ``formats`` parameter is a list (of dicts) of formats and parameters you want\nyour file to be exported into.\nThe supported output formats are ``jpeg``, ``idml``, ``pdf``, ``indd`` and\n``zip`` (a zipped InDesign Package).\n\nExport parameters are provided using the ``params`` key. Use\n``simpleidml_indesign_save_as.py --help`` for a list of supported parameters.\n\nThe response is a list of binary strings matching ``formats`` provided:\n\n.. code-block:: python\n\n    from simple_idml.indesign import indesign\n\n    response = indesign.save_as(\"/path_to_file.idml\", [{\"fmt\": \"indd\"}],\n                                \"http://url-to-indesign-server:port\",\n                                \"/path/to/client/workdir\",\n                                \"/path/to/indesign-server/workdir\")[0]\n    with open(\"my_file.indd\", \"wb+\") as f:\n        f.write(response)\n\n    response = indesign.save_as(\"/path_to_file.indd\", [{\"fmt\": \"idml\"}],\n                                \"http://url-to-indesign-server:port\",\n                                \"/path/to/client/workdir\",\n                                \"/path/to/indesign-server/workdir\")[0]\n    with open(\"my_file.idml\", \"wb+\") as f:\n        f.write(response)\n\n    response = indesign.save_as(\"/path_to_file.indd\", [{\n                                    \"fmt\": \"pdf\",\n                                    \"params\": {\"colorSpace\": \"CMYK\"},\n                                }],\n                                \"http://url-to-indesign-server:port\",\n                                \"/path/to/client/workdir\",\n                                \"/path/to/indesign-server/workdir\")[0]\n    with open(\"my_file.pdf\", \"wb+\") as f:\n        f.write(response)\n\n    pdf_response, jpeg_response, zip_response = indesign.save_as(\n                                    \"/path_to_file.indd\",\n                                    [{\"fmt\": \"pdf\"}, {\"fmt\": \"jpeg\"}, {\"fmt\": \"zip\"}],\n                                    \"http://url-to-indesign-server:port\",\n                                    \"/path/to/client/workdir\",\n                                    \"/path/to/indesign-server/workdir\")\n\nTo convert an InDesign Package, use ``indesign.export_package_as()`` instead.\n\nIf the InDesign Server instance is running on a Windows machine, set the\n``indesign_server_path_style`` parameter to ``\"windows\"``.\n\nIf the client accesses the working directory *via* FTP, you must specify that\nin the ``ftp_params`` parameter:\n\n.. code-block:: python\n\n    {\n        'auth': (\"ftp://ftp.foo.org\", \"user_account\", \"s3cret-pa55word\"),\n        'passive': False,\n        'keepalive': True,         # False by default (optional)\n        'keepalive_interval': 30,  # set socket.TCP_KEEPINTVL (optional)\n        'keepalive_idle': 45,      # set socket.TCP_KEEPIDLE  (optional)\n        'polite': False,           # Unilaterally close ftp connection (optional)\n    }\n\nA script (``simpleidml_indesign_save_as.py``) that wraps these functions is\ninstalled in your PATH.\n\nRevisions\n=========\n\n1.2.0\n-----\n\n- Add flag ``simpleidml-setcontent=\"clear\"`` to import XML.\n\n1.1.8\n-----\n\n- Bugfix (issue #73).\n\n1.1.7\n-----\n\n- Manage border color in styles when composing documents.\n\n1.1.5\n-----\n\n- Add a ``page_number`` parameter to ``IDMLPackage.import_pdf()`` so that you\n  can choose which page from the PDF file to display.\n\n1.1.4\n-----\n\n- PyLint refactorisation.\n\n1.1.3\n-----\n\n- Catch and log exceptions to the InDesign Server when setting options in\n  export.jsx. Thanks to @kylehodgson for the contribution.\n\n1.1.2\n-----\n\nNew features\n''''''''''''\n\n- Add ``indesign.export_package_as()`` to convert an InDesign Package.\n\n1.1.1\n-----\n\nNew features\n''''''''''''\n\n- Add the possiblity to remove new-line characters when importing XML by using the flag\n  ``simpleidml-setcontent=\"remove-previous-br\"``.\n\n1.1.0\n-----\n\nRemoved Python 2 support.\n\nNew features\n''''''''''''\n\n- Add the possiblity to remove elements when importing XML by using the flag\n  ``simpleidml-setcontent=\"delete\"``.\n- The ``PDFCrop`` attribute is now parametrable when using ``import_pdf()``.\n- ``IDMLPackage.add_note(note, author, at=path)`` added.\n\n1.0.5\n-----\n\nBug fixes\n'''''''''\n\n- Fixed ``indesign.save_as()`` in Python 3 where the jsx file was opened\n  in text mode instead of binary.\n\n1.0.3\n-----\n\n- Use setuptools instead of distutils for a better integration with Pypi.\n\n1.0.0\n-----\n\nNew features\n''''''''''''\n\n- Added support for Python 3\n\nBackward incompatibilities\n''''''''''''''''''''''''''\n\n- Removed support for Python 2.6\n\n0.92.9\n------\n\nNew features\n''''''''''''\n\n- Added ``simpleidml_indesign_profiles.py`` script to list the available joboptions\n  files on the InDesign Server using the SOAP interface.\n\nBug fixes\n'''''''''\n\n- Fix working directory cleaning of the SOAP server when an exception is raised.\n  ``indesign.save_as()`` may be backward incompatible since the returned list\n  may contains some ``None`` (instead of raising an exception before returning\n  anything).\n- Give the list of available profiles (joboptions files) on the InDesign Server\n  if the given 'pdfExportPresetName' is not found.\n\nBackward incompatibilities\n''''''''''''''''''''''''''\n\n- ``indesign.close_all_documents()`` has been replace the ``CloseAllDocuments`` class\n  and its ``.execute()`` method.\n- Some util functions that wrap the basic file manipulations to manage the case of\n  a ftp access to those files have been moved from indesign.py to a new ftp.py module.\n\n0.92.8\n------\n\nNew features\n''''''''''''\n\n- Added ``IDMLPackage.import_pdf()`` method.\n\n\nBug fixes\n'''''''''\n\n- Fix ``bleedMarks`` in export.jsx.\n\n0.92.7\n------\n\nBug fixes\n'''''''''\n\n- FillTint wasn't managed.\n- Force ``lxml \u003c 4`` in dependencies.\n\n0.92.6\n------\n\nBug fixes\n'''''''''\n\n- Catch errors when InDesign SOAP server fails to complete a task and raise\n  an exception.\n\n0.92.5\n------\n\nBug fixes\n'''''''''\n\n- Handle \u003cPDF\u003e in `IDMLPackage._get_item_translation_for_insert()`\n\n0.92.4\n------\n\nBug fixes\n'''''''''\n\n- Fix issue #11: Parent CharacterStyle not applied in import_xml() in some cases.\n\n0.92.2\n------\n\nNew features\n''''''''''''\n\n- More ftp parameters for `indesign.save_as()` function. Hardcoded socket parameters are now\n  modifiable. And you can set the flag `polite` to `False` if you encounter hanging problem\n  on `ftp.quit()` as I do. Being unpolite calls an unilateral and rude `ftp.close()`.\n  Please upgrade your code with explicite values if you rely on the previous default\n  behavior.\n\n0.92.1\n------\n\nBug fixes\n'''''''''\n\n- ``indesign.save_as()`` uses a dedicated temporary working directory to avoid\n  concurrent access on files.\n- Added a logger to ``indesign.save_as()`` ('simpleidml.indesign') and some debug messages.\n- Fixed hanging ``ftp.retrbinary()`` in ``indesign.save_as()`` calls by tuning the socket.\n\n0.91.8\n------\n\nNew features\n''''''''''''\n\n- Added support for PDF export presets in ``indesign.save_as()``.\n\n0.91.7\n------\n\nNew features\n''''''''''''\n\n- Added ``IMDLPackage.merge_layers(with_name)`` (Refs#7).\n- Added a new script ``simpleidml_indesign_close_all_documents.py``.\n\nBug fixes\n'''''''''\n\n- In ``IDMLPackage.insert_idml()``, Elements from the same layer (but not tagged in the structure)\n  are now added in the Spread of the document of destination.\n- Better support for Windows platform.\n- Fixed character style mapping with tag when using insert_idml.\n- Fixed Export XML in some edge case.\n- Added parameters to ``simpleidml_indesign_save_as`` when exporting to PDF.\n\nBackward incompatibilities\n''''''''''''''''''''''''''\n\n- ``indesign.save_as()`` formats parameters is now a list of dictionaries.\n\n0.91.6\n------\n\nNew features\n''''''''''''\n\n- Add the ``simpleidml-ignorecontent`` and ``simpleidml-forcecontent`` tags (XML attributes)\n  allowing one to carefully exclude a node and its children during the import XML process.\n- ``indesign.save_as()`` now works with a client working directory over a FTP.\n  This require ``wget`` to be on your system if you want to create zip packages.\n\n\nBackward incompatibilities\n''''''''''''''''''''''''''\n\n- ``indesign.save_as()`` require both a client workdir and a server workdir parameter.\n\n0.91.5.5\n--------\n\nBugfixes\n''''''''\n\n- \u003cEPS\u003e elements in Spread weren't handled correctly.\n- All spread elements were added in the destination package when using ``insert_idml()``.\n\n\n0.91.3\n------\n\nNew features\n''''''''''''\n\nAdd a SOAP client to call a InDesign server to get INDD file and export in various\nformats.\n\n0.91.2\n------\n\nNew features\n''''''''''''\n\n- Ticket #20 - Suffix layers.\n\nBackward incompatibilities\n''''''''''''''''''''''''''\n\n- Ticket #22 - IDMLPackage.import_xml() parameter is a XML string and not a file object.\n\nBugfixes\n''''''''\n\nTickets #19, #21 (orphan layers), #23 (AssertXMLEqual), #24 (import_xml() failure).\n\n\n.. _XPath: http://en.wikipedia.org/wiki/XPath\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarou%2Fsimpleidml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstarou%2Fsimpleidml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarou%2Fsimpleidml/lists"}