SlideShare a Scribd company logo
1 of 17
Twisted XSLT Tricks:
Making Column Switching Work for
FOP
Eliot Kimber
Contrext
DITA OT Day 2018
About the Author
• Independent consultant focusing on DITA
analysis, design, and implementation
• Doing SGML and XML for cough 30 years cough
• Founding member of the DITA Technical
Committee
• Founding member of the XML Working Group
• Co-editor of HyTime standard (ISO/IEC 10744)
• Primary developer and founder of the DITA for
Publishers project (dita4publishers.org)
• Author of DITA for Practitioners, Vol 1 (XML Press)
DITA OT Day 2018
Agenda
• The trouble with columns in FO
• And also page sequences
• Solution: Split the trees
• Demonstration
DITA OT Day 2018
THE TROUBLE WITH
COLUMNS (AND PAGE
SEQUENCES)
DITA OT Day 2018
Changing Column Counts
• In FO: Can change from multi column to single
column
• Only allowed on direct children of fo:flow
• FOP enforces this rule
• PDF2 transform wraps entire flow in a single
block (more or less)
• How to change column counts then?
DITA OT Day 2018
Page Sequence Switching
• Switch from portrait to landscape within a
chapter.
• PDF2 generates page sequences at high level
• No easy way to switch page sequences with
PDF2 design
DITA OT Day 2018
SOLUTION: SPLIT THE TREES
DITA OT Day 2018
Column Splitting
• Set base column count to 2 then set top-level
fo:block to span="all"
• Put out marker elements to signal start and
end of a column change
• Post-process generated FO to split top-level
blocks at span change boundaries
DITA OT Day 2018
Page Sequence Splitting
• Same approach as for columns
• Put out start/end markers for page sequences
• Post-process FO to split page sequences at
marker boundaries.
DITA OT Day 2018
HOW TO DO THE SPLITTING
DITA OT Day 2018
General Tree-Splitting Algorithm
• Provided by Gerrit Imsieke on the XSL mailing
list
• Uses for-each-group to split original tree on
marker elements:
– Get the nodes before the start marker
– Get the nodes after the start marker
– Nodes not in either group must be between the
markers
– Construct new trees, one for each set of nodes
DITA OT Day 2018
Confession
DITA OT Day 2018
I don’t know how it works
https://getyarn.io/yarn-clip/9c369b08-76b9-4eb8-b00e-432aa1a36977#BJ_HVBSn2Q.copy
Gerrit’s Original Code
<xsl:template match="node() | @*" mode="#default split">
<xsl:copy>
<xsl:apply-templates select="@* | node()”
mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fo:block[empty(ancestor::fo:block)]"
mode="#default">
<xsl:variable name="block-root" as="element(fo:block)”
select="."/>
<xsl:for-each-group
select="descendant::node()[empty(node())]"
group-starting-with="two-column-start">
<xsl:for-each-group select="current-group()"
group-ending-with="two-column-end">
<xsl:apply-templates select="$block-root" mode="split">
<xsl:with-param name="restricted-to" as="node()*"
select="current-group()/ancestor-or-self::node()"
tunnel="yes"/>
<xsl:with-param name="two-col-start" as="xs:boolean"
tunnel="yes"
select="exists(self::two-column-start)"/>
</xsl:apply-templates>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="node()" mode="split" priority="1">
<xsl:param name="restricted-to" tunnel="yes" as="node()+"/>
<xsl:if test="exists(. intersect $restricted-to)">
<xsl:next-match/>
</xsl:if>
</xsl:template>
<xsl:template match="fo:block[empty(ancestor::fo:block)]”
mode="split">
<xsl:param name="restricted-to" tunnel="yes" as="node()*"/>
<xsl:param name="two-col-start" tunnel="yes”
as="xs:boolean"/>
<xsl:copy>
<xsl:apply-templates select="@*" mode="#current"/>
<xsl:if test="$two-col-start">
<xsl:attribute name="span" select="'none'"/>
</xsl:if>
<xsl:apply-templates mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="two-column-start | two-column-end”
mode="split"/>
DITA OT Day 2018
The Key Bit of the Code
<xsl:template match="fo:block[empty(ancestor::fo:block)]"
mode="#default">
<xsl:variable name="block-root" as="element(fo:block)”
select="."/>
<xsl:for-each-group select="descendant::node()[empty(node())]"
group-starting-with="two-column-start">
<xsl:for-each-group select="current-group()"
group-ending-with="two-column-end">
<xsl:apply-templates
select="$block-root" mode="split">
<xsl:with-param name="restricted-to" as="node()*"
select="current-group()/ancestor-or-self::node()"
tunnel="yes"/>
<xsl:with-param name="two-col-start" as="xs:boolean"
tunnel="yes"
select="exists(self::two-column-start)"/>
</xsl:apply-templates>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>
DITA OT Day 2018
Gotchas
• Had to ensure IDs were not duplicated
• Selecting all leaf elements
– No need to look inside blocks or tables, for
instance
– More than just fo:block
DITA OT Day 2018
Demo: Federal Acquisition
Regulations
• Use of FOP is customer requirement
• Mostly one-column but some two-column
tables
• Mostly portrait but some rotated (landscape)
tables
DITA OT Day 2018
Questions?
DITA OT Day 2018

More Related Content

Similar to Twisted XSL Tricks: Column Switching for FOP

University of Applied Science Esslingen @ Scilab Conference 2018
University of Applied Science Esslingen @ Scilab Conference 2018University of Applied Science Esslingen @ Scilab Conference 2018
University of Applied Science Esslingen @ Scilab Conference 2018Scilab
 
XSLT Magic Tricks with DITA and FrameMaker
XSLT Magic Tricks with DITA and FrameMakerXSLT Magic Tricks with DITA and FrameMaker
XSLT Magic Tricks with DITA and FrameMakerContrext Solutions
 
DITA, EPUB, and HTML5: An Update for 2015
DITA, EPUB, and HTML5: An Update for 2015DITA, EPUB, and HTML5: An Update for 2015
DITA, EPUB, and HTML5: An Update for 2015dclsocialmedia
 
The DITA Iceberg, DITA Europe 2016
The DITA Iceberg, DITA Europe 2016The DITA Iceberg, DITA Europe 2016
The DITA Iceberg, DITA Europe 2016IXIASOFT
 
DITA 1.3: What's New and Different
DITA 1.3: What's New and DifferentDITA 1.3: What's New and Different
DITA 1.3: What's New and Differentdclsocialmedia
 
Solving Large Scale Optimization Problems using CPLEX Optimization Studio
Solving Large Scale Optimization Problems using CPLEX Optimization StudioSolving Large Scale Optimization Problems using CPLEX Optimization Studio
Solving Large Scale Optimization Problems using CPLEX Optimization Studiooptimizatiodirectdirect
 
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for KeysManaging Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keysdclsocialmedia
 
DITA on a Shoe String
DITA on a Shoe StringDITA on a Shoe String
DITA on a Shoe StringStan Doherty
 
Using CSS Paging to Render DITA Documents
Using CSS Paging to Render DITA DocumentsUsing CSS Paging to Render DITA Documents
Using CSS Paging to Render DITA DocumentsContrext Solutions
 
Git censored.key
Git censored.keyGit censored.key
Git censored.keymkramer2
 
DITA OT Day 2015 Lightning Talk On The DITA Community Project
DITA OT Day 2015 Lightning Talk On The DITA Community ProjectDITA OT Day 2015 Lightning Talk On The DITA Community Project
DITA OT Day 2015 Lightning Talk On The DITA Community ProjectContrext Solutions
 
Git Is A State Of Mind - The path to becoming a Master of the mystic art of Git
Git Is A State Of Mind - The path to becoming a Master of the mystic art of GitGit Is A State Of Mind - The path to becoming a Master of the mystic art of Git
Git Is A State Of Mind - The path to becoming a Master of the mystic art of GitNicola Costantino
 
Learn Git form Beginners to Master
Learn Git form Beginners to MasterLearn Git form Beginners to Master
Learn Git form Beginners to MasterC. M. Abdullah Khan
 
Content Management on Zero Budget: DITA for Small Teams
Content Management on Zero Budget: DITA for Small TeamsContent Management on Zero Budget: DITA for Small Teams
Content Management on Zero Budget: DITA for Small TeamsContrext Solutions
 
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_SummaryHiram Fleitas León
 

Similar to Twisted XSL Tricks: Column Switching for FOP (20)

University of Applied Science Esslingen @ Scilab Conference 2018
University of Applied Science Esslingen @ Scilab Conference 2018University of Applied Science Esslingen @ Scilab Conference 2018
University of Applied Science Esslingen @ Scilab Conference 2018
 
XSLT Magic Tricks with DITA and FrameMaker
XSLT Magic Tricks with DITA and FrameMakerXSLT Magic Tricks with DITA and FrameMaker
XSLT Magic Tricks with DITA and FrameMaker
 
DITA, EPUB, and HTML5: An Update for 2015
DITA, EPUB, and HTML5: An Update for 2015DITA, EPUB, and HTML5: An Update for 2015
DITA, EPUB, and HTML5: An Update for 2015
 
Multithreading Design Patterns
Multithreading Design PatternsMultithreading Design Patterns
Multithreading Design Patterns
 
The DITA Iceberg, DITA Europe 2016
The DITA Iceberg, DITA Europe 2016The DITA Iceberg, DITA Europe 2016
The DITA Iceberg, DITA Europe 2016
 
DITA 1.3: What's New and Different
DITA 1.3: What's New and DifferentDITA 1.3: What's New and Different
DITA 1.3: What's New and Different
 
Solving Large Scale Optimization Problems using CPLEX Optimization Studio
Solving Large Scale Optimization Problems using CPLEX Optimization StudioSolving Large Scale Optimization Problems using CPLEX Optimization Studio
Solving Large Scale Optimization Problems using CPLEX Optimization Studio
 
GitWorkFlow
GitWorkFlowGitWorkFlow
GitWorkFlow
 
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for KeysManaging Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
 
DITA on a Shoe String
DITA on a Shoe StringDITA on a Shoe String
DITA on a Shoe String
 
Using CSS Paging to Render DITA Documents
Using CSS Paging to Render DITA DocumentsUsing CSS Paging to Render DITA Documents
Using CSS Paging to Render DITA Documents
 
Git censored.key
Git censored.keyGit censored.key
Git censored.key
 
DITA OT Day 2015 Lightning Talk On The DITA Community Project
DITA OT Day 2015 Lightning Talk On The DITA Community ProjectDITA OT Day 2015 Lightning Talk On The DITA Community Project
DITA OT Day 2015 Lightning Talk On The DITA Community Project
 
Git Is A State Of Mind - The path to becoming a Master of the mystic art of Git
Git Is A State Of Mind - The path to becoming a Master of the mystic art of GitGit Is A State Of Mind - The path to becoming a Master of the mystic art of Git
Git Is A State Of Mind - The path to becoming a Master of the mystic art of Git
 
Introduction to birt
Introduction to birtIntroduction to birt
Introduction to birt
 
Learn Git form Beginners to Master
Learn Git form Beginners to MasterLearn Git form Beginners to Master
Learn Git form Beginners to Master
 
Content Management on Zero Budget: DITA for Small Teams
Content Management on Zero Budget: DITA for Small TeamsContent Management on Zero Budget: DITA for Small Teams
Content Management on Zero Budget: DITA for Small Teams
 
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary
[DBA]_HiramFleitas_SQL_PASS_Summit_2017_Summary
 
Git tutorial
Git tutorialGit tutorial
Git tutorial
 
Why Is DITA So Hard?
Why Is DITA So Hard?Why Is DITA So Hard?
Why Is DITA So Hard?
 

More from Contrext Solutions

Loose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
Loose Leaf Publishing Using Antenna House Formatter and CSS for PaginationLoose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
Loose Leaf Publishing Using Antenna House Formatter and CSS for PaginationContrext Solutions
 
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for FreeDefinition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for FreeContrext Solutions
 
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITACan I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITAContrext Solutions
 
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key References
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key ReferencesKi, Qi, Key: The Way of DITA Harmony With Keys and Key References
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key ReferencesContrext Solutions
 
Locale-Aware Sorting and Text Handling in the Open Toolkit
Locale-Aware Sorting and Text Handling in the Open ToolkitLocale-Aware Sorting and Text Handling in the Open Toolkit
Locale-Aware Sorting and Text Handling in the Open ToolkitContrext Solutions
 
DITA for Small Teams Workshop (Tekom 2017)
DITA for Small Teams Workshop (Tekom 2017)DITA for Small Teams Workshop (Tekom 2017)
DITA for Small Teams Workshop (Tekom 2017)Contrext Solutions
 
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITACan I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITAContrext Solutions
 
FrameMaker and the DITA Open Toolkit
FrameMaker and the DITA Open ToolkitFrameMaker and the DITA Open Toolkit
FrameMaker and the DITA Open ToolkitContrext Solutions
 
DITA Reuse Challenges and Response
DITA Reuse Challenges and ResponseDITA Reuse Challenges and Response
DITA Reuse Challenges and ResponseContrext Solutions
 
RELAX NG and DITA: An Almost Perfect Match
RELAX NG and DITA: An Almost Perfect MatchRELAX NG and DITA: An Almost Perfect Match
RELAX NG and DITA: An Almost Perfect MatchContrext Solutions
 
Managing Multiple Open Toolkit Configurations Using git Lightning Talk
Managing Multiple Open Toolkit Configurations Using git Lightning TalkManaging Multiple Open Toolkit Configurations Using git Lightning Talk
Managing Multiple Open Toolkit Configurations Using git Lightning TalkContrext Solutions
 
They Worked Before, What Happened? Understanding DITA Cross-Book Links
They Worked Before, What Happened? Understanding DITA Cross-Book Links They Worked Before, What Happened? Understanding DITA Cross-Book Links
They Worked Before, What Happened? Understanding DITA Cross-Book Links Contrext Solutions
 
No Ki Magic: Managing Complex DITA Hyperdocuments
No Ki Magic: Managing Complex DITA HyperdocumentsNo Ki Magic: Managing Complex DITA Hyperdocuments
No Ki Magic: Managing Complex DITA HyperdocumentsContrext Solutions
 
Poster: Cross-Document Linking in DITA
Poster: Cross-Document Linking in DITAPoster: Cross-Document Linking in DITA
Poster: Cross-Document Linking in DITAContrext Solutions
 
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for KeysManaging Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for KeysContrext Solutions
 
What's New in DITA 1.3 (Tekom, Nov 2014)
What's New in DITA 1.3 (Tekom, Nov 2014)What's New in DITA 1.3 (Tekom, Nov 2014)
What's New in DITA 1.3 (Tekom, Nov 2014)Contrext Solutions
 
Taking Cross References to the Next Level: Reltables for Non-Topic Elements
Taking Cross References to the Next Level: Reltables for Non-Topic ElementsTaking Cross References to the Next Level: Reltables for Non-Topic Elements
Taking Cross References to the Next Level: Reltables for Non-Topic ElementsContrext Solutions
 
RELAX NG to DTD and XSD Using the Open Toolkit
RELAX NG to DTD and XSD Using the Open ToolkitRELAX NG to DTD and XSD Using the Open Toolkit
RELAX NG to DTD and XSD Using the Open ToolkitContrext Solutions
 
DITA 1.3: What's New and Different
DITA 1.3: What's New and DifferentDITA 1.3: What's New and Different
DITA 1.3: What's New and DifferentContrext Solutions
 

More from Contrext Solutions (20)

Loose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
Loose Leaf Publishing Using Antenna House Formatter and CSS for PaginationLoose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
Loose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
 
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for FreeDefinition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
 
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITACan I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
 
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key References
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key ReferencesKi, Qi, Key: The Way of DITA Harmony With Keys and Key References
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key References
 
Locale-Aware Sorting and Text Handling in the Open Toolkit
Locale-Aware Sorting and Text Handling in the Open ToolkitLocale-Aware Sorting and Text Handling in the Open Toolkit
Locale-Aware Sorting and Text Handling in the Open Toolkit
 
DITA for Small Teams Workshop (Tekom 2017)
DITA for Small Teams Workshop (Tekom 2017)DITA for Small Teams Workshop (Tekom 2017)
DITA for Small Teams Workshop (Tekom 2017)
 
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITACan I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
 
FrameMaker and the DITA Open Toolkit
FrameMaker and the DITA Open ToolkitFrameMaker and the DITA Open Toolkit
FrameMaker and the DITA Open Toolkit
 
DITA Reuse Challenges and Response
DITA Reuse Challenges and ResponseDITA Reuse Challenges and Response
DITA Reuse Challenges and Response
 
RELAX NG and DITA: An Almost Perfect Match
RELAX NG and DITA: An Almost Perfect MatchRELAX NG and DITA: An Almost Perfect Match
RELAX NG and DITA: An Almost Perfect Match
 
Managing Multiple Open Toolkit Configurations Using git Lightning Talk
Managing Multiple Open Toolkit Configurations Using git Lightning TalkManaging Multiple Open Toolkit Configurations Using git Lightning Talk
Managing Multiple Open Toolkit Configurations Using git Lightning Talk
 
They Worked Before, What Happened? Understanding DITA Cross-Book Links
They Worked Before, What Happened? Understanding DITA Cross-Book Links They Worked Before, What Happened? Understanding DITA Cross-Book Links
They Worked Before, What Happened? Understanding DITA Cross-Book Links
 
No Ki Magic: Managing Complex DITA Hyperdocuments
No Ki Magic: Managing Complex DITA HyperdocumentsNo Ki Magic: Managing Complex DITA Hyperdocuments
No Ki Magic: Managing Complex DITA Hyperdocuments
 
Poster: Cross-Document Linking in DITA
Poster: Cross-Document Linking in DITAPoster: Cross-Document Linking in DITA
Poster: Cross-Document Linking in DITA
 
DITA for Small Teams
DITA for Small TeamsDITA for Small Teams
DITA for Small Teams
 
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for KeysManaging Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
Managing Deliverable-Specific Link Anchors: New Suggested Best Practice for Keys
 
What's New in DITA 1.3 (Tekom, Nov 2014)
What's New in DITA 1.3 (Tekom, Nov 2014)What's New in DITA 1.3 (Tekom, Nov 2014)
What's New in DITA 1.3 (Tekom, Nov 2014)
 
Taking Cross References to the Next Level: Reltables for Non-Topic Elements
Taking Cross References to the Next Level: Reltables for Non-Topic ElementsTaking Cross References to the Next Level: Reltables for Non-Topic Elements
Taking Cross References to the Next Level: Reltables for Non-Topic Elements
 
RELAX NG to DTD and XSD Using the Open Toolkit
RELAX NG to DTD and XSD Using the Open ToolkitRELAX NG to DTD and XSD Using the Open Toolkit
RELAX NG to DTD and XSD Using the Open Toolkit
 
DITA 1.3: What's New and Different
DITA 1.3: What's New and DifferentDITA 1.3: What's New and Different
DITA 1.3: What's New and Different
 

Recently uploaded

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

Recently uploaded (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Twisted XSL Tricks: Column Switching for FOP

  • 1. Twisted XSLT Tricks: Making Column Switching Work for FOP Eliot Kimber Contrext DITA OT Day 2018
  • 2. About the Author • Independent consultant focusing on DITA analysis, design, and implementation • Doing SGML and XML for cough 30 years cough • Founding member of the DITA Technical Committee • Founding member of the XML Working Group • Co-editor of HyTime standard (ISO/IEC 10744) • Primary developer and founder of the DITA for Publishers project (dita4publishers.org) • Author of DITA for Practitioners, Vol 1 (XML Press) DITA OT Day 2018
  • 3. Agenda • The trouble with columns in FO • And also page sequences • Solution: Split the trees • Demonstration DITA OT Day 2018
  • 4. THE TROUBLE WITH COLUMNS (AND PAGE SEQUENCES) DITA OT Day 2018
  • 5. Changing Column Counts • In FO: Can change from multi column to single column • Only allowed on direct children of fo:flow • FOP enforces this rule • PDF2 transform wraps entire flow in a single block (more or less) • How to change column counts then? DITA OT Day 2018
  • 6. Page Sequence Switching • Switch from portrait to landscape within a chapter. • PDF2 generates page sequences at high level • No easy way to switch page sequences with PDF2 design DITA OT Day 2018
  • 7. SOLUTION: SPLIT THE TREES DITA OT Day 2018
  • 8. Column Splitting • Set base column count to 2 then set top-level fo:block to span="all" • Put out marker elements to signal start and end of a column change • Post-process generated FO to split top-level blocks at span change boundaries DITA OT Day 2018
  • 9. Page Sequence Splitting • Same approach as for columns • Put out start/end markers for page sequences • Post-process FO to split page sequences at marker boundaries. DITA OT Day 2018
  • 10. HOW TO DO THE SPLITTING DITA OT Day 2018
  • 11. General Tree-Splitting Algorithm • Provided by Gerrit Imsieke on the XSL mailing list • Uses for-each-group to split original tree on marker elements: – Get the nodes before the start marker – Get the nodes after the start marker – Nodes not in either group must be between the markers – Construct new trees, one for each set of nodes DITA OT Day 2018
  • 12. Confession DITA OT Day 2018 I don’t know how it works https://getyarn.io/yarn-clip/9c369b08-76b9-4eb8-b00e-432aa1a36977#BJ_HVBSn2Q.copy
  • 13. Gerrit’s Original Code <xsl:template match="node() | @*" mode="#default split"> <xsl:copy> <xsl:apply-templates select="@* | node()” mode="#current"/> </xsl:copy> </xsl:template> <xsl:template match="fo:block[empty(ancestor::fo:block)]" mode="#default"> <xsl:variable name="block-root" as="element(fo:block)” select="."/> <xsl:for-each-group select="descendant::node()[empty(node())]" group-starting-with="two-column-start"> <xsl:for-each-group select="current-group()" group-ending-with="two-column-end"> <xsl:apply-templates select="$block-root" mode="split"> <xsl:with-param name="restricted-to" as="node()*" select="current-group()/ancestor-or-self::node()" tunnel="yes"/> <xsl:with-param name="two-col-start" as="xs:boolean" tunnel="yes" select="exists(self::two-column-start)"/> </xsl:apply-templates> </xsl:for-each-group> </xsl:for-each-group> </xsl:template> <xsl:template match="node()" mode="split" priority="1"> <xsl:param name="restricted-to" tunnel="yes" as="node()+"/> <xsl:if test="exists(. intersect $restricted-to)"> <xsl:next-match/> </xsl:if> </xsl:template> <xsl:template match="fo:block[empty(ancestor::fo:block)]” mode="split"> <xsl:param name="restricted-to" tunnel="yes" as="node()*"/> <xsl:param name="two-col-start" tunnel="yes” as="xs:boolean"/> <xsl:copy> <xsl:apply-templates select="@*" mode="#current"/> <xsl:if test="$two-col-start"> <xsl:attribute name="span" select="'none'"/> </xsl:if> <xsl:apply-templates mode="#current"/> </xsl:copy> </xsl:template> <xsl:template match="two-column-start | two-column-end” mode="split"/> DITA OT Day 2018
  • 14. The Key Bit of the Code <xsl:template match="fo:block[empty(ancestor::fo:block)]" mode="#default"> <xsl:variable name="block-root" as="element(fo:block)” select="."/> <xsl:for-each-group select="descendant::node()[empty(node())]" group-starting-with="two-column-start"> <xsl:for-each-group select="current-group()" group-ending-with="two-column-end"> <xsl:apply-templates select="$block-root" mode="split"> <xsl:with-param name="restricted-to" as="node()*" select="current-group()/ancestor-or-self::node()" tunnel="yes"/> <xsl:with-param name="two-col-start" as="xs:boolean" tunnel="yes" select="exists(self::two-column-start)"/> </xsl:apply-templates> </xsl:for-each-group> </xsl:for-each-group> </xsl:template> DITA OT Day 2018
  • 15. Gotchas • Had to ensure IDs were not duplicated • Selecting all leaf elements – No need to look inside blocks or tables, for instance – More than just fo:block DITA OT Day 2018
  • 16. Demo: Federal Acquisition Regulations • Use of FOP is customer requirement • Mostly one-column but some two-column tables • Mostly portrait but some rotated (landscape) tables DITA OT Day 2018