Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The Ebook Developer's Toolbox - ebookcraft 2016 - Sanders Kleinfeld

471 views

Published on

"The Ebook Developer's Toolbox" by Sanders Kleinfeld (O’Reilly Media) for ebookcraft 2016, presented by BookNet Canada and eBOUND Canada - March 31, 2016

Published in: Education
  • Be the first to comment

The Ebook Developer's Toolbox - ebookcraft 2016 - Sanders Kleinfeld

  1. 1. The Ebook Developer's Toolbox Sanders Kleinfeld O’Reilly Media, Inc. Twitter: @sandersk ebookcraft 2016
  2. 2. An Inconvenient Truth…
  3. 3. Ebooks are made of CODE!!!
  4. 4. Technologies of the Trade:
  5. 5. (X)HTML CSS JS XSLT regexRDF NCX ONIX MOBI EPUB PDF MathML SVG XPath OPFOTF WOFF LATE X WTF?!
  6. 6. Tools/Techniques of the Trade:
  7. 7. InDesign Media QueriesKindlegen oXygen MathML Cloud “View Source” CSSLint Readium jQuery Sass Acrobat Kindle Previewer iBooks Author epubcheck ADE FontForge FileFormat.info BISG EPUB 3 Support Grid
  8. 8. “What’s in my Toolbox?”
  9. 9. Three Indispensable Tools for my Workflow 1.XSLT 2.Responsive Ebook Design Techniques 3.Equation Processing with MathML Cloud
  10. 10. XSLT 101
  11. 11. Pop Quiz #1: XSLT is… A: An acronym for “Extensible Stylesheet Language Transformations” B: A programming language written in XML syntax C: An official W3C Specification D: All of the above
  12. 12. Pop Quiz #1: XSLT is… A: An acronym for “Extensible Stylesheet Language Transformations” B: A programming language written in XML syntax C: An official W3C Specification D: All of the above (http://www.w3.org/TR/xs
  13. 13. XSLT is a tool for global, programmatic markup manipulation
  14. 14. <body> <div class="section"> <p><b>Chapter 1</b></p> HTML5 is really great, because there are lots of new elements to facilitate meaningful tagging of content. <br/><br/> Also, they deprecated a lot of yucky <font color="green">non-semantic stuff.</font> </div> </body> <body> <section> <h1>Chapter 1<h1> <p>HTML5 is really great, because there are lots of new elements to facilitate meaningful tagging of content.</p> <p>Also, they deprecated a lot of yucky <span style="color: green;">non- semantic stuff.</span></p> </section> </body> XSLT ? ?
  15. 15. Rhetorical Question #1: “Um, can’t I just use regular expressions for this?”
  16. 16. Example: Converting <b> to <em> with regex your_markup.replace(/<b>/, '<em>')
  17. 17. But what about: •Closing tags (</b>) •Attributes (<b class="term">) •Extra Whitespace (<b >) your_markup.replace(/<(/)?b(s*[^>]*)>/g, '<$1em$2>')
  18. 18. A Stack Overflow Classic: “You can’t parse [X]HTML with regex” (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags)
  19. 19. XSLT leverages a functional* paradigm * Many folks have salient objections to calling XSLT a functional programming language (e.g., http://www.snoyman.com/blog/2012/04/xslt-rant.html), but document processing with XSLT still embodies the spirit of functional programming, and it feels pedantic to me to deny that.
  20. 20. <markup> <!--Input--> </markup> Functional Paradigm in XSLT <markup> <!--Output--> </markup> <xsl:stylesheet> <xsl:template match="..."> <!—Stuff happens here--> </xsl:template> <xsl:template match="..."> <!—Stuff happens here--> </xsl:template> </xsl:stylesheet>
  21. 21. f(x) = 1 * x Identity Function* in Algebra * Output of function is identical to input
  22. 22. Identity Stylesheet* in XSLT * Output of stylesheet is identical to input <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
  23. 23. Rhetorical Question #2: “Say What?”
  24. 24. Identity Stylesheet in XSLT: Explained <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> BEGIN stylesheet END stylesheet BEGIN matching function Match any node (element, attribute, text) BEGIN copy matched node (OPEN elem) END Copy matched node (CLOSE elem) Select any node END matching function Run stylesheet against specified children of
  25. 25. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML
  26. 26. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML
  27. 27. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  28. 28. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  29. 29. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  30. 30. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p> </p> </body>
  31. 31. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p> </p> </body>
  32. 32. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p> </p> </body>
  33. 33. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p class="greet"> </p> </body>
  34. 34. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p class="greet"> </p> </body>
  35. 35. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p class="greet"> </p> </body>
  36. 36. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p class="greet"> Hello World </p> </body>
  37. 37. Identity Stylesheet in XSLT: How it Works <xsl:stylesheet xmlns:xsl="http://www .w3.org/1999/XSL/Tran sform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> </body> Stylesheet Input XHTML Output XHTML <body> <p class="greet"> Hello World </p> </body>
  38. 38. Rhetorical Question #5: “OK, so how do you actually transform the output”
  39. 39. You can override the identity templates with other, more specific matching templates (just as you override rules with other rules in CSS) CSS XSLT * { font-size: 10px; } h1 { /* Custom Handling */ font-size: 20px; } <xsl:template match="@*| node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="h1"> <xsl:copy> <!--Custom handling--> <xsl:apply-templates/> </xsl:copy> </xsl:template>
  40. 40. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="p[@class='greet']"> <h1> <xsl:apply-templates select="@*|node()"/> </h1> </xsl:template> </xsl:stylesheet> XPath matching all p elements with a clas
  41. 41. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML
  42. 42. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML
  43. 43. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  44. 44. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  45. 45. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> </body>
  46. 46. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1> </h1> </body>
  47. 47. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1> </h1> </body>
  48. 48. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1> </h1> </body>
  49. 49. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> </h1> </body>
  50. 50. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> </h1> </body>
  51. 51. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> </h1> </body>
  52. 52. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> </body>
  53. 53. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> </body>
  54. 54. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> </body>
  55. 55. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> <p></p> </body>
  56. 56. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> <p></p> </body>
  57. 57. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> <p></p> </body>
  58. 58. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> <p>What’s up?</p> </body>
  59. 59. Our first transform: Convert all <p class="greet"> elements to <h1>s <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match=“p[@class=‘greet’] ”> <h1> <xsl:apply- templates select=“@*| node()"/> </h1> </xsl:template> </xsl:stylesheet> <body> <p class="greet"> Hello World </p> <p>What’s up?</p> </body> Stylesheet Input XHTML Output XHTML <body> <h1 class="greet"> Hello World </h1> <p>What’s up?</p> </body>
  60. 60. Pop Quiz #2: What does this transform do? XSLT INPUT XHTML <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/ XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p>
  61. 61. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML
  62. 62. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML
  63. 63. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p></p>
  64. 64. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p></p>
  65. 65. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p></p>
  66. 66. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning</p>
  67. 67. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning</p>
  68. 68. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning</p>
  69. 69. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning</p>
  70. 70. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning is awesome!</p>
  71. 71. Pop Quiz #2 Solution <xsl:stylesheet xmlns:xsl="http://www.w3 .org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply- templates select="@*| node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"/> </xsl:stylesheet> <p>Learning <strong>XSLT</strong> is awesome!</p> Stylesheet Input XHTML Output XHTML <p>Learning is awesome!</p>
  72. 72. Pop Quiz #3: Write XSLT that drops <strong> tags from the HTML below, but preserves the text content inside the tags INPUT XHTML <p>Learning <strong>XSLT</strong> is awesome!</p> DESIRED OUTPUT XHTML <p>Learning XSLT is awesome!</p>
  73. 73. Pop Quiz #3 Solution <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="strong"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> BEGIN match “strong” element Select child nodes (except attributes) of matched “strong” element End match “strong” element
  74. 74. Intermediate Topics •XPath expressions •Conditionals (xsl:if, xsl:choose/xsl:when/xsl:otherwise) •Looping/Grouping (xsl:for-each, xsl:for-each-group) •Numbering/Labeling (xsl:number) •Includes/Imports (xsl:include/xsl:import)
  75. 75. My Favorite XSLT Reference Book
  76. 76. Responsive Ebook Design
  77. 77. What do we mean by responsive design?
  78. 78. “Rather than tailoring disconnected designs to each of an ever-increasing number of web devices, we can treat them as facets of the same experience. We can design for an optimal viewing experience, but embed standards-based technologies into our designs to make them not only more flexible, but more adaptive to the media that renders them.” — Ethan Marcotte “Responsive Web Design” http://alistapart.com/article/responsive-web-design
  79. 79. Responsive Ebook Design: Four Principles
  80. 80. 1. Content is split into pages (Safari for Mac) (iBooks for Mac)
  81. 81. 2. Content reflows from page to page (iBooks for iPhone) (iBooks for iPad)
  82. 82. 3. Content settings are user-configurable User #1’s settings User #2’s settings
  83. 83. 4. Single ebook archive for all platforms (iBooks) (NOOK) (Google Play) (Kobo) (Kindle)* (Universal Ebook) * Either converted to MOBI via KindleGen, or submitted to Amazon for conversio
  84. 84. Responsive Ebook Design Toolbox: CSS Media Queries
  85. 85. Media Queries encapsulate CSS rules to be applied only when certain display conditions are satisfied, such as: •Screen dimensions fall within a given width/height range •Screen is monochrome or color •Screen orientation is portrait or landscape
  86. 86. Media Query Syntax* @media media-type and (media-feature) { /* CSS Rules to be applied */ } al media type, followed by zero or more media featu
  87. 87. Some Key W3C-Specified Media Types: •all - applied on any device •print - applied to output for printers •speech - applied on screen readers •screen - applied to any display that is not print or speech, which encompasses most Web browsers and readers
  88. 88. Kindle’s Custom Media Types*: •amzn-kf8 - applied on any Kindle device or app that supports Amazon’s Kindle Format 8 specification •amzn-mobi - applied to Kindle devices or apps that support only the legacy MOBI 7 format. * See Chapter 8 of Kindle Publisher Guidelines
  89. 89. Example #1: Kindle’s Recommended Media Queries for table handling* @media amzn-mobi { table.complex { /* Suppress display of complex tables on MOBI and use fallback image instead */ display: none; } } @media amzn-kf8 { img.table_fallback { /* Suppress display of table fallback images on KF8, which can support complex tables */ display: none; } } * See Chapter 8 of Kindle Publisher Guidelines
  90. 90. Some Key W3C-Specified Media Features: •(min-|max-)width - query the width of the current display window. •(min-|max-)device-width* - query the screen width of the device •(min-|max-)height - query the height of the current display window •(min-|max-)device-height* - query the screen height of the device •orientation - query whether orientation is currently portrait or landscape •color - query whether the display is color •monochrome - query whether the display is monochrome * Deprecated in Media Queries Level 4
  91. 91. Example #2: Media Query for iBooks for iPad @media (min-device-width:768px) and (max-device-width:1024px) { #usernote::before { content: “You are reading this on iBooks for iPad"; } }
  92. 92. iBooks Ereader Detector https://github.com/sandersk/ibooks_ereader_detector
  93. 93. Example #3: Media query to target both iBooks + KF8-enabled Kindle* @media not amzn-mobi { /* Styling for everything that _is not_ a MOBI 7 platform */ } Queries for formatting Poetry on Kindle and EPUB”
  94. 94. Responsive Ebook Design Toolbox: CSS Fragmentation
  95. 95. Some Key W3C-Specified Fragmentation Properties:* •page-break-before - configure page breaking rules before specified element(s) •page-break-after - configure page breaking rules after specified element(s) •page-break-inside - configure page breaking rules within specified element(s) nger mandates “page-” prefix on these properties, but it’s a good id
  96. 96. page-break- properties accept the following values •auto - Defer to browser/ereader on pagebreak here (default) •avoid - Avoid pagebreak here •always - Always pagebreak here •left - Add one or two pagebreaks to make next page a left page •right - Add one or two pagebreaks to make next page a right page •inherit - Inherit pagebreak rules from parent element* * “page-break” rules are not inherited by default
  97. 97. Example #1: Force pagebreaks before top-level headings h1 { page-break-before: always }
  98. 98. Example #2: Avoid pagebreaks within figures figure { page-break-inside: avoid }
  99. 99. Some More Key W3C-Specified Fragmentation Properties:* •orphans - specify minimum number of lines within an element that must be preserved before a page boundary (at bottom of page) •widows - specify minimum number of lines within an element that must be preserved after a page boundary (at top of page) * Default value is 2 for both properties
  100. 100. Example #3: Require three paragraph lines to “stay together” at both the bottom and top of pages p { orphans: 3 widows: 3 }
  101. 101. For more, read my article “Responsive Ebook D
  102. 102. Accessible Math with MathML Cloud (MathJax)
  103. 103. The Publisher’s Challenge: How to produce high-quality, accessible mathematical content across ereader platforms
  104. 104. Option #1: Embedded MathML (http://www.w3.org/Math/)
  105. 105. MathML in EPUB (iBooks)
  106. 106. MathML in EPUB (NOOK)
  107. 107. MathML in Mobi (Kindle Fire)
  108. 108. Option #2: SVG (http://www.w3.org/TR/SVG)
  109. 109. SVG in EPUB (iBooks)
  110. 110. SVG in Mobi (Kindle Voyage)
  111. 111. SVG in Mobi (Kindle “classic”)
  112. 112. The only reliable, universal choice is bitmap images
  113. 113. But how can we automate creation of equation images…
  114. 114. …And what about accessibility?
  115. 115. MathML Cloud provides a solution for automation and accessibility http://mathmlcloud.org
  116. 116. MathML Cloud API http://benetech.github.io/mmlc-api/
  117. 117. MathML Cloud is open source, built on mathjax-node https://github.com/benetech/mmlc-api/
  118. 118. “What’s in YOUR Toolbox?”
  119. 119. Thank You! ? ?☺ Contact Me: @sandersk

×