<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Publishing Geekly</title>
	<atom:link href="http://publishinggeekly.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://publishinggeekly.com</link>
	<description>XSLT, EPUB, IDML and other stuff</description>
	<lastBuildDate>Wed, 13 Mar 2013 22:03:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>XProc-based CrossRef DOI lookup for unstructured citations</title>
		<link>http://publishinggeekly.com/2013/03/xproc-crossref-doi-lookup/</link>
		<comments>http://publishinggeekly.com/2013/03/xproc-crossref-doi-lookup/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 23:49:32 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Publishing industry]]></category>
		<category><![CDATA[citations]]></category>
		<category><![CDATA[crossref]]></category>
		<category><![CDATA[doi]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[XProc]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=287</guid>
		<description><![CDATA[CrossRef members may use the XML batch query interface in order to look up DOIs for citations. Here’s an XProc implementation of that interface for JATS-like input. Assuming that there’s a calabash.sh somewhere on your system, a sample invocation looks like this: It takes some BITS/JATS/HoBoTS XML on the source port, and it needs your <a href='http://publishinggeekly.com/2013/03/xproc-crossref-doi-lookup/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>CrossRef members may use the <a href="http://help.crossref.org/#querying-with-formatted-citations">XML batch query interface</a> in order to look up DOIs for citations. Here’s an <a href="https://subversion.le-tex.de/common/crossref/trunk/">XProc implementation</a> of that interface for <a href="http://jats.nlm.nih.gov/">JATS</a>-like input. </p>
<p><span id="more-287"></span></p>
<p>Assuming that there’s a calabash.sh somewhere on your system, a sample invocation looks like this:</p>
<pre class="brush: bash; title: ; notranslate">
calabash.sh \
  -i source=bits.xml \
  -o qb=query_batch.xml \
  crossref/xpl/jats-submit-crossref-query.xpl \
  email=X@Y \
  user=USER pass=PASS \
  xpath='(//sec)[last()]'
</pre>
<p>It takes some <a href="http://jats.nlm.nih.gov/extensions/bits/tag-library/">BITS</a>/<a href="http://jats.nlm.nih.gov/">JATS</a>/<a href="http://hobots.hogrefe.com/schema/hobots.rng">HoBoTS</a> XML on the source port, and it needs your CrossRef credentials and a return email address where the resolved XML will be sent to after batch processing. </p>
<p>If you want to restrict the query to only some citations in your source XML, you can supply an XPath expression. In the example above, only the <code>ref</code> elements below the last <code>sec</code> will be included in the query. In addition, only <code>ref</code>s with an <code>id</code> attribute will be processed, and <code>ref</code>s that already have a DOI (<code>pub-id[@pub-id-type eq 'doi']</code>) will be excluded. Currently, it will only process <code>mixed-citation</code>s. </p>
<p>There is a JATS-specific part (<a href="https://subversion.le-tex.de/common/crossref/trunk/xpl/jats2crossref-query-body.xpl">.xpl</a>, <a href="https://subversion.le-tex.de/common/crossref/trunk/xsl/jats2query-body.xsl">.xsl</a>) for generating a <a href="http://www.crossref.org/qschema/crossref_query_input2.0.xsd">CrossRef Query Input 2.0</a> compliant query body, and there is a <a href="https://subversion.le-tex.de/common/crossref/trunk/xpl/wrap-query.xpl">generic part</a> for wrapping this, together with the return email address and a generated batch ID, in a <code>query_batch</code> element, validating it against the XSD, wrapping it, together with the credentials, in a POST <code>p:http-request</code> and finally submitting the query to CrossRef.</p>
<p>If other input formats were to be supported, it would be nice if there was only one front-end script that selects and executes the format-specific query generation pipeline dynamically, with <code>cx:eval</code>.</p>
<p>The main obstacles that had to be overcome were all related to the HTTP POST request in <a href="https://subversion.le-tex.de/common/crossref/trunk/xpl/wrap-query.xpl">wrap-query.xpl</a>:</p>
<pre class="brush: xml; first-line: 69; title: ; notranslate">
  &lt;p:template&gt;
    &lt;p:input port=&quot;template&quot;&gt;
      &lt;p:inline&gt;
        &lt;c:request 
          method=&quot;POST&quot; 
          href=&quot;http://doi.crossref.org/servlet/deposit?operation=doQueryUpload&amp;amp;login_id={$user}&amp;amp;login_passwd={$pass}&quot;&gt;
          &lt;c:multipart content-type=&quot;multipart/form-data&quot; boundary=&quot;=-=-=-=-=&quot;&gt;
            &lt;c:body content-type=&quot;application/xml&quot; disposition='form-data; name=&quot;fname&quot;; filename=&quot;hobots-refs.xml&quot;'&gt;
              {/*}
            &lt;/c:body&gt;
          &lt;/c:multipart&gt;
        &lt;/c:request&gt;
      &lt;/p:inline&gt;
    &lt;/p:input&gt;
    &lt;p:input port=&quot;source&quot;&gt;
      &lt;p:pipe step=&quot;wrap&quot; port=&quot;result&quot;/&gt;
    &lt;/p:input&gt;
    &lt;p:input port=&quot;parameters&quot;&gt;
      &lt;p:pipe step=&quot;vars&quot; port=&quot;result&quot;/&gt;
    &lt;/p:input&gt;
  &lt;/p:template&gt;
  
  &lt;p:http-request omit-xml-declaration=&quot;false&quot; encoding=&quot;US-ASCII&quot;/&gt;
</pre>
<p>In line 74, there’s a spurious GET-like URL – but it seems to work alongside the POSTed payload. This has to be in a multipart chunk, and it’s important that it has <code>name="fname"</code> in its Content-Disposition field. The filename is static at this point, but it’s obvious how to dynamicize it using some curly braces expression. Well, it could be difficult if there were single quotes in the expression because the whole disposition attribute is enclosed in single quotes already – I avoided this problem for the time being.</p>
<p>Other important attributes are the <code>p:http-request</code> attributes in line 91. Without omit-xml-declaration=&#8221;false&#8221;, the posted data won’t be interpreted as XML. It was hard for me to find out that this serialization option belongs to <code>p:http-request</code> itself, rather than <code>p:body</code>. </p>
<p>After I had successfully posted my first batch, I saw that nothing was recognized. I quickly discovered that en dashes and other “special characters” had been converted to plain question marks when sending the query batch as UTF-8. So I switched the serialization to US-ASCII, hoping that everything beyond ASCII will be transmitted as numerical entity references, and there you go.</p>
<p>Another problem that I discovered later: although <code>i</code> and <code>b</code> formatting is allowed in an <code>unstructured_citation</code>, virtually no citation would resolve. I noticed that all these formatting elements were missing in the returned, unresolved query. So they probably didn’t resolve because essential text was discarded prior to resolution. I dissolved all markup within <code>unstructured_citation</code>, and the results were much better.  </p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2013/03/xproc-crossref-doi-lookup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open-Sourcing for Impact and Profit</title>
		<link>http://publishinggeekly.com/2013/02/open-sourcing-for-impact-and-profit/</link>
		<comments>http://publishinggeekly.com/2013/02/open-sourcing-for-impact-and-profit/#comments</comments>
		<pubDate>Sat, 16 Feb 2013 12:37:41 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Publishing industry]]></category>
		<category><![CDATA[XSLT]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Saxon]]></category>
		<category><![CDATA[strategy]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=274</guid>
		<description><![CDATA[Michael Kay announced recently at XML Prague that Saxonica is going to open-source Saxon CE, the XSLT2 processor that runs in every modern browser. At the same conference, we (le-tex) announced that we will open-source our IDML/OOXML conversion pipelines (documentation/examples will follow). Previously Saxon-CE was licensed on a per-site basis, but probably didn’t find many <a href='http://publishinggeekly.com/2013/02/open-sourcing-for-impact-and-profit/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>Michael Kay announced recently at <a href="http://www.xmlprague.cz/">XML Prague</a> that Saxonica is going to open-source <a href="http://saxonica.com/html/ce/doc/about/intro.html">Saxon CE</a>, the XSLT2 processor that runs in every modern browser. At the same conference, we (<a title="le-tex publishing services GmbH, Leipzig, Germany" href="http://www.le-tex.de/en/">le-tex</a>) announced that we will open-source our <a href="https://subversion.le-tex.de/idmltools/trunk/">IDML</a>/OOXML <a href="https://subversion.le-tex.de/common/">conversion pipelines</a> (documentation/examples will follow).</p>
<p><span id="more-274"></span></p>
<p>Previously Saxon-CE was licensed on a per-site basis, but probably didn’t find many licensees yet. One reason is that mainstream Web development takes place in Javascript and that most of that stack – the browsers’ JS engines, debuggers, libraries such as jQuery, etc. – is free. When I had to outweigh the complications of Saxon CE licensing and the lack of acceptance of this maverick XSLT2 technology, even in my own organization, against the mainstram-ness of a jQuery extension, I opted for <a title="jQuery plugin: tablemanager" href="https://github.com/maze-le/jquery-tablemanager">the latter</a>.</p>
<p>But the idea of having XSLT2 in the browser as readily available and deployable as any jQuery extension certainly appeals to me. So I was very happy about Michael’s decision to open-source Saxon CE.</p>
<p>He said although he hadn’t the faintest idea how to make money off of it, it’s important to its success that Saxon CE has 1 million rather than a couple dozen users.</p>
<p>We find ourselves in a similar situation: After years of fumbling with ad-hoc converters and Makefile orchestrations, we’ve developed a robust conversion infrastructure from/to OOXML and IDML and other XML formats, such as the central <a href="https://github.com/gimsieke/Hub">Hub</a> format that uses <a href="https://github.com/gimsieke/CSSa">CSSa</a>, as <a href="http://archive.xmlprague.cz/2013/presentations/Conveying_Layout_Information_with_CSSa/CSSa_xmlprague_gimsieke.html#/step-1">presented in Prague</a>. These converters are based on the XML stack, namely on XSLT2 and XProc. Nowadays, even in publishing, XML technologies compete with other approaches (HTML5/Python, HTML5/JSON/JS, …). So in order to maintain and demonstrate the stack’s validity, it should matter to us that we create mindshare, i.e., that both customers and competitors approve of that technology stack and use it, too.</p>
<p>Saxon CE and our tools have in common that the money has already been spent on developing them.</p>
<p>Conventional thinking knows two principal ways of monetizing these tools: either selling (licensing) them or not disclosing them and therefore being able to offer one’s services more cost-efficiently than the competitors.</p>
<p>What conventional wisdom overlooks is that adopters of a technology or a tool don’t merely buy the tool for what it does. They buy into an ecosystem. They don’t want to be left alone with their tool vendor. Even when they buy a tool that a single vendor controls, such as SAP or Microsoft, there’s some assurance that the tool will continue to be supported at more or less the same terms.</p>
<p>To buy a proprietary tool that only three developers in the world maintain, and where these three developers are working for a single small company, is risky. The company may cease to exist, key developers may leave, the product may become out of focus if the user base is too small or if it doesn’t generate substantial revenues, etc.</p>
<p>So a way forward may be to open-source the product and broaden its user base. But how will the product generate the revenues to sustain its development if it is open source?</p>
<p>Another concern, maybe less for Saxonica than for my fellow managing directors, the shareholders of le-tex: If we open the tool that has helped us maintain a competitive edge over our competitors, why should we sacrifice that competitive edge in giving the competitors the tool for free?</p>
<p>I’ll try to address the second concern first. First there’s a natural inertia and a not-invented-here attitude that keeps competitors from adopting our tool. Maybe their toolchains are so different from ours that our tool doesn’t add much value for them. Or they have similar proprietary tools for internal use. There will be many reasons for competitors not to adopt our tool. While this probable non-adoption may refute the argument that competitors will get the better of us, for free, it amounts to admitting that the tool won’t be broadly adopted. The tool being open source may then somehow appease the customer who is unwilling to buy proprietary software that only one single shop controls. But at least among customers in publishing, it isn’t the proprietary nature of tools that stifles adoption, it’s rather their lack of proven acceptance in the marketplace, their niche or even esoteric nature.</p>
<p>So hoping for non-adoption among competitors obviously doesn’t solve the adoption issue. The tool has to become mainstream, and this can only be achieved by pulling customers <em>and</em> competitors into that methodology. To spread the news about the superiority of our proprietary tool is beyond our marketing and sales capacity, and it’s increasingly hard to introduce high-priced infrastructure products in markets where databases, operatings systems, development tools etc. are free. Apart from that, our tool builds on a stack of open-source tools such as Saxon HE and XML Calabash, and the tool or its methodology aren’t exactly rocket science. To the contrary, they epitomize the way that we think that everybody should use the basic tools to convert the standard XML-based input formats to XML-based output formats. They are to us, so to say, the categorial imperative of data conversion, and of course it’s non-sensical to treat such a universally valid guideline as proprietary intellectual property.</p>
<p>What will happen if competitors (= partners), customers and other entities (the not-yet-customers) start using our tools?</p>
<p>Indian partners might use the tools for their English-speaking customers. If they have special requirements, the customers are likely to ask us, the tool’s initiator, to extend the tool with a certain functionality. This has worked for companies such as <a href="http://37signals.com/">37 Signals</a> who are in a position to pick the customers that they provide with Rails-related services. And they can charge a premium for these services because they are the initiator. </p>
<p>The English-speaking publisher market has been virtually inaccessible to us because there’s a plethora of (mostly) Indian vendors who are able to offer commodity services at a lower price, at least for English-language publications. But also in our domestic market, it’s probably true what our partner/competitor <a href="http://www.data2type.de/about/team/">Manuel Montero Pineda</a> told me after our open-source announcement: If his company uses our tools and a customer requests a modification, given their developers’ high degree of utilization, they won’t spend weeks or months to investigate the internals of the software and modify it. They’ll rather ask us to do the job, yielding revenues from a customer that we didn’t “own”, and doing so without any sales effort on our part. </p>
<p>I’m confident (although I cannot prove) that these additional effects will outweigh detrimental effects where competitors will be able to snatch away a customer because, thanks to the tools that we developed, they are able to charge less (because they don’t have the development costs) for the same services, using our tools.</p>
<p>But what’s the revenue model then? Only in rare cases can you argue that you had the development costs anyway, for creating internal-use tools, or that you also get some payback from others who extend the tool that you initially have open-sourced. </p>
<p>I see the following sources of revenue:</p>
<ul>
<li>Customers paying for new features;</li>
<li>Customers paying a premium for services around the tool (because you are the 37 Signals in your space);</li>
<li>Hosted solutions that are built on the tool and that subsidize its development;</li>
<li>Support and consultancy;</li>
<li>Voluntary contributions by customers. We have already requested and received these, but it has proven difficult to explain why a pilot customer has to pay for a feature when subsequent customers get it for free. This sense of unfairness is similar to what my colleagues feel about funding development and then let our competitors use the tool. In markets such as Norway, this model of funding open-source development is much more accepted than in Germany, because the customers are well aware of the fact that they also profit to a large degree from developments that someone else has subsidized. It’s all a matter of education, I guess (or is it a matter of abundant petrodollars, coupled with Scandinavian common sense?): Do you want to use <a href="http://basex.org/">BaseX</a> without licensing fees and maybe pay $ 7,000 for a certain feature that you need, or do you want to spend $ XX,000 upfront for MarkLogic that already has this and other features? It’s important to tell people that sponsoring open-source development is in their mid- to long-term financial and strategic interest;</li>
<li>Maintenance fees, compatibility assurance: We have successfully sold our newly open-sourced toolchain to a German publisher because we promised to open-source it (otherwise they would have selected a solution from another vendor). Apart from man&#038;material fees for further developing the tools and for configuring them, we offered an upgrade/compatibility assurance that is comparable with the 18 or so percent annual maintenance fee that commercial software vendors charge. This assurance covers that we keep a copy of the customer’s customization in our continuous integration infrastructure, and we define and continuously improve test sets taken from the customer’s documents. Whenever we change our basic tools, we will know if something will break if we deploy an update at the customer’s site. And we’ll make sure that nothing breaks or otherwise find a solution what to change in the basic tool or in the customer’s installation so that they can use the most recent versions of our basic tools. Of course this is a service that you can charge for. Of course providing this service costs you something. But you can organize these tests alongside your other CI tests in an efficient manner so that there will be profits to subsidize further development. On the other hand, the customer would have to spend much more if their own people were responsible for integrating our patches to their infrastructure. Simply because we would create these patches without checking for compatibility with their installation, and because they don’t have a sophisticated CI infrastructure. I think that this kind of assurance service may also be provided by Saxonica for Saxon CE: offer the infrastructure for customers and system integrators to upload their applications and run Selenium-like test on them, and run these tests automatically against Saxon CE release candidates.
 </li>
<li>Offering training and certification: We develop tools but we are primarily a provider of integration, conversion, typesetting, hosted solution, and support services. Saxonica, on the other hand, primarily develop tools. Apart from charging for implementing certain features or receiving direct subsidies, they cannot subsidize development by other services. But they can train integrators and certify them and their solutions. This won’t cover all development costs and incurs additional costs, but it may provide some compensation; </li>
<li>Contributions by organizations with a vested interest in the tool. For Saxon CE, this could be an organization such as Mozilla Foundation, although this seems unlikely, given their current focus on Javascript, DOM, CSS and other non-XSLT technologies. It could be NIH for a Saxon-CE-based, Web XML editor that allows editing JATS. It could be a consortium of publishers who need a configurable HTML5 editor with different kinds of XML output. We are currently plotting a deal with some German publishers. Part of that deal would be a contribution to the development of the open-source Saxon CE product (for example, what they’d save in comparison to the hitherto existing per-site licensing fees).</li>
</ul>
<p>To sum up: I think there is more opportunity in open-sourcing tools such as Saxon CE or our conversion toolchain than it is in keeping them closed. It is important to create mindshare both with respect to the technological merits of these approaches and with respect to funding models beyond conventional licensing.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2013/02/open-sourcing-for-impact-and-profit/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>XML Prague 2013: CSSa slides</title>
		<link>http://publishinggeekly.com/2013/02/xml-prague-2013-cssa-slides/</link>
		<comments>http://publishinggeekly.com/2013/02/xml-prague-2013-cssa-slides/#comments</comments>
		<pubDate>Sat, 09 Feb 2013 16:17:03 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=271</guid>
		<description><![CDATA[This is just a placeholder post to link to the slides.]]></description>
				<content:encoded><![CDATA[<p>This is just a placeholder post to link to the <a href="http://publishinggeekly.com/wp-content/uploads/2013/02/xmlprague/CSSa_xmlprague_gimsieke.html#/step-1" title="CSSa Presentation">slides</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2013/02/xml-prague-2013-cssa-slides/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>InDesign: Turning a vertical bar into a hyphen at the end of a line</title>
		<link>http://publishinggeekly.com/2012/12/turning-a-vertical-bar-into-a-hyphen-at-the-end-of-a-line/</link>
		<comments>http://publishinggeekly.com/2012/12/turning-a-vertical-bar-into-a-hyphen-at-the-end-of-a-line/#comments</comments>
		<pubDate>Thu, 27 Dec 2012 22:25:23 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Typesetting]]></category>
		<category><![CDATA[hyphenation]]></category>
		<category><![CDATA[InDesign]]></category>
		<category><![CDATA[Protip]]></category>
		<category><![CDATA[TeX]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=255</guid>
		<description><![CDATA[What’s easy in TeX is often cumbersome or impossible in InDesign. Today’s task was to allow hyphenation in words whose syllables are separated with bars, as depicted here: In TeX, you’d define some macro as \discretionary{\hyphenchar}{}{&#124;}. In InDesign, however, I fumbled with Ligatures and other OpenType features such as falt (Final Glyph on Line Alternates). <a href='http://publishinggeekly.com/2012/12/turning-a-vertical-bar-into-a-hyphen-at-the-end-of-a-line/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>What’s easy in TeX is often cumbersome or impossible in InDesign. Today’s task was to allow hyphenation in words whose syllables are separated with bars, as depicted here:</p>
<p><a href="http://publishinggeekly.com/wp-content/uploads/2012/12/dicketaluhren.png"><img src="http://publishinggeekly.com/wp-content/uploads/2012/12/dicketaluhren-231x300.png" alt="Dün|ne Berg|uh|ren ti|cken an|ders als di|cke Tal|uh|ren." title="dicketaluhren" width="231" height="300" class="alignnone size-medium wp-image-256" /></a></p>
<p><span id="more-255"></span></p>
<p>In TeX, you’d define some macro as <code>\discretionary{\hyphenchar}{}{|}</code>. In InDesign, however, I fumbled with Ligatures and other OpenType features such as <a href="https://en.wikipedia.org/wiki/List_of_typographic_features"><code>falt</code> (Final Glyph on Line Alternates)</a>. Alas, InDesign doesn’t seem to support <code>falt</code> yet. </p>
<p>To my rescue came TeX, in the form of <a href="https://en.wikipedia.org/wiki/Hyphenation_algorithm#cite_note-1">Liang’s seminal hyphenation patterns</a>. They found their way to InDesign via OpenOffice, which uses <a href="http://hunspell.sourceforge.net/">Hunspell</a>, which in turn uses (essentially) Liang patterns for hyphenation.</p>
<p>I created a new language variant under de_DE with an arbitrary name, and placed a file <code>hyph_de_DE.dic</code> in there with the following content:</p>
<pre class="brush: plain; title: ; notranslate">UTF8
7|/=-</pre>
<p>I introduced it to InDesign (CS5.5 or newer) by following <a href="https://blogs.adobe.com/typblography/2011/11/how-to-enable-more-languages-in-indesign-cs5-5.html">this step-by-step guide</a>. </p>
<p>What I didn’t find out is how to name this new language variant. So I created a character style with this nameless language and assigned it to the bar-bearing phrases.</p>
<p>Other hyphenation patterns didn’t seem necessary. This is because the bars in the input represent all legal hyphenation positions. The only requirement was to allow line breaks at the bar positions and turn the bars into hyphens when there’s a line break at their position.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2012/12/turning-a-vertical-bar-into-a-hyphen-at-the-end-of-a-line/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dr. Strangechar or: How I Learned to Stop Worrying and Love Unicode</title>
		<link>http://publishinggeekly.com/2012/08/dr-strangechar/</link>
		<comments>http://publishinggeekly.com/2012/08/dr-strangechar/#comments</comments>
		<pubDate>Mon, 27 Aug 2012 22:08:25 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Encoding]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[UTF-8]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=240</guid>
		<description><![CDATA[Talk about Unicode at the second XML User Group Stuttgart meeting (2012-07-16). See the slides (in German).]]></description>
				<content:encoded><![CDATA[<p>Talk about Unicode at the second <a href="http://xugs.de/post/27552296343/folien-2-xugs-treffen">XML User Group Stuttgart</a> meeting (2012-07-16). See the <a href="http://publishinggeekly.com/wp-content/uploads/2012/07/dr_strangechar.html">slides</a> (in German).</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2012/08/dr-strangechar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make Makeshifts, Part I: User-defined Functions (and variable export issues with them)</title>
		<link>http://publishinggeekly.com/2012/05/make-makeshifts-1-functions-export/</link>
		<comments>http://publishinggeekly.com/2012/05/make-makeshifts-1-functions-export/#comments</comments>
		<pubDate>Thu, 31 May 2012 19:28:42 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Workflow]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[GNU make]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Process automation]]></category>
		<category><![CDATA[Protip]]></category>
		<category><![CDATA[XProc]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=218</guid>
		<description><![CDATA[Only very recently did I discover a nifty feature of GNU make, which is user-defined functions and the call function. It has proven useful when writing portable Makefiles that work on Cygwin and Unix-like systems when Java is involved. The issue with Java and Cygwin is the following. Suppose that you have installed Cygwin in <a href='http://publishinggeekly.com/2012/05/make-makeshifts-1-functions-export/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>Only very recently did I discover a nifty feature of GNU make, which is <a href="https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function">user-defined functions and the call function</a>.</p>
<p><span id="more-218"></span></p>
<p>It has proven useful when writing portable Makefiles that work on Cygwin and Unix-like systems when Java is involved. The issue with Java and Cygwin is the following. Suppose that you have installed Cygwin in C:/cygwin and you have installed Java SE for Windows. Then if you want to refer to a file /home/gerrit/test.xml you’ll have to translate the path to C:/cygwin/home/gerrit/test.xml. There’s a cygwin utility, <a href="http://cygwin.com/cygwin-ug-net/using-utils.html#cygpath">cygpath</a>, that works similar to realpath(1) in that it can translate a filename to its (Windows) full name, including the directory. For example, when I invoke cygpath -ma test.xml in my home dir it will give me C:/cygwin/home/gerrit/test.xml, the full path, as suitable for Java.</p>
<p>Trying to use relative paths throughout proved to difficult, since different tools assume different base directories for files. An XSLT 2 processor, for example, will try to resolve  a pathless file name relative to the stylesheet’s directory, so you’d have to figure out what the relative path to your file from there will be. Another XSLT processor requirement (depending on you configuration) is that it wants to have URIs for files. In above example, it will expect file:///c:/cygwin/home/gerrit/test.xml as a file name argument, while you can just pass it /home/gerrit/test.xml on Linux.</p>
<p>The most elegant solutions (at least if you stick with make and don’t use XProc for automation, which has its own peculiarities) is to use a make function like this:</p>
<pre class="brush: plain; title: ; notranslate">ifeq ($(shell uname -o),Cygwin)
win_path = $(shell cygpath -ma $(1))
uri = file:///$(call win_path,$(1))
else
uri = $(1)
endif </pre>
<p>Here’s an application example that uses the uri function twice:</p>
<pre class="brush: plain; first-line: 16; title: ; notranslate">
%.idml.HUB %.idml.INDEXTERMS %.idml.TAGGED: %.idml Makefile xslt/*.xsl xslt/modes/*.xsl
mkdir -p $&amp;lt;.tmp
unzip -u -o -d $ $(SAXON) \
$(SAXONOPTS) \
-xsl:xslt/idml2xml.xsl \
-it:$(call lc,$(subst .,,$(suffix $@))) \
src-dir-uri=$(call uri,$ $@
</pre>
<p>It also features a function lc that converts its argument to lower case. It is defined as</p>
<pre class="brush: plain; title: ; notranslate">
lc = $(shell echo $(1) | tr '[:upper:]' '[:lower:]')
</pre>
<h2>Makefile functions don’t survive export</h2>
<p>When a sub-make is called, the function is exported as a plain variable rather than as a function, and the variable is expanded on the way. This issue is already described in a <a href="http://stackoverflow.com/questions/7789389/exporting-recursive-makefile-variables-to-submakes">post on stackoverflow</a>. Moving the function definition to another file that is imported by both Makefiles will improve the situation.</p>
<p>But today I ran into an issue where a Makefile invoked itself recursively and exported all of its variables. My user-defined function, even when reduced to a simple cat $(1), didn’t finish. This was also true when I outsourced the function definition to an included file, because the exported variables supersede the default definitions. So because $(1) was expanded to the empty string, the function that the sub-make called consisted of a mere cat, without argument placeholder, that was waiting for someone to feed it via STDIN.</p>
<p>The solution consisted of unexporting the function/variable:</p>
<pre class="brush: plain; title: ; notranslate">
# export all variables:
export
# except for the testfunc function:
unexport linecount
linecount = $(shell wc -l $(1))

test1:
$(MAKE) test2

test2:
@echo $(call linecount,Makefile)
</pre>
<p>Invoking this yields:</p>
<pre class="brush: plain; title: ; notranslate">
$ make
make test2
make[1]: Entering directory `/home/gerrit'
11 Makefile
make[1]: Leaving directory `/home/gerrit'
</pre>
<p>Commenting out the &#8216;unexport&#8217; line gives the following output</p>
<pre class="brush: plain; title: ; notranslate">
$ make
make test2
</pre>
<p>and it doesn’t finish, because wc is waiting for input on STDIN.</p>
<h2>To be continued…</h2>
<p>I recently discovered (and needed, and used) <a href="https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html#Secondary-Expansion">secondary expansion</a>, a true makeshift that I will deal with in another post. There you’ll get a glimpse why this kind of tinkering with good old make and its expansion mechanism was probably the last straw that have made others concoct cleaner alternatives to make, such as ant or XProc. But never forget that these features, such as call, eval, and seconary expansion, give you “<a href="https://httpd.apache.org/docs/2.0/rewrite/">all the configurability and flexibility of Sendmail</a>”. Take dynamic evaluation. You have it in XProc processor vendor extensions, but not in ant (maybe with Jelly, I don’t know this stuff too well). Make is still our favorite process automation tool. Maybe <a href="http://www.w3.org/wiki/XprocVnext">XProc V.next</a>, that will hopefully deal better with non-XML files, will be a runner-up.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2012/05/make-makeshifts-1-functions-export/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>floodit.xsl</title>
		<link>http://publishinggeekly.com/2012/02/floodit-xsl/</link>
		<comments>http://publishinggeekly.com/2012/02/floodit-xsl/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 16:41:14 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[XSLT]]></category>
		<category><![CDATA[browserXML]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=207</guid>
		<description><![CDATA[floodit.xsl is an XSLT 2.0 implementation of the popular Flood-It game. It is built on Saxon CE, Saxonica’s XSLT 2.0 processor for browsers. The code is on github. However, you need to obtain a Saxon CE license in order to deploy your own derivative solutions.]]></description>
				<content:encoded><![CDATA[<p><a title="Play floodit.xsl in your browser." href="/wp-content/uploads/2012/02/floodit-xsl/floodit.html">floodit.xsl</a> is an XSLT 2.0 implementation of the popular <a title="Flood-It on Google+" href="https://plus.google.com/games/479261262298">Flood-It</a> game.</p>
<p>It is built on <a title="Saxon CE documentation" href="http://www.saxonica.com/ce/doc/contents.html">Saxon CE</a>, Saxonica’s XSLT 2.0 processor for browsers.</p>
<p>The code is on <a href="https://github.com/gimsieke/floodit-xsl">github</a>. However, you need to <a href="http://saxonica.com/html/license/license.html">obtain a Saxon CE license</a> in order to deploy your own derivative solutions.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2012/02/floodit-xsl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Should a Boutique Sell Commodities?</title>
		<link>http://publishinggeekly.com/2012/02/boutique-commodities/</link>
		<comments>http://publishinggeekly.com/2012/02/boutique-commodities/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 22:31:10 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Publishing industry]]></category>
		<category><![CDATA[premedia]]></category>
		<category><![CDATA[strategy]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=153</guid>
		<description><![CDATA[As a typesetting and data conversion service provider, we sell on page price. No matter how much we spend on R&#38;D and how well we may cope with difficult content or authors, in the end it’s the unit price that matters. If a customer’s procurement department only compares page prices, they will try to replace <a href='http://publishinggeekly.com/2012/02/boutique-commodities/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>As a typesetting and data conversion service provider, we sell on page price. No matter how much we spend on R&amp;D and how well we may cope with difficult content or authors, in the end it’s the unit price that matters. If a customer’s procurement department only compares page prices, they will try to replace us with commodity service providers whenever possible. But this will only work well for standardized processes or less complicated manuscripts/authors. As a consequence, the relatively easy, high-volume production will be offshored while the so-called boutique production remains at our shop (because some authors or editors insist that their complicated stuff will be treated appropriately). As a consequence, our average page price even gets higher, because there is less cheap off-the-shelf  producton in the mix. As a consequence, the procurement people who only compare page prices seek to quench us out.</p>
<p>What can be done about it? A couple of things.</p>
<ul>
<li>Establish a low-cost production line and rigidly define what is included in the price and what is not. The drawback is that the surcharges that you inevitably charge will contribute to the average cost per page, making you still more expensive. But at least the reasons become much more transparent.</li>
<li>Raise awareness that there are different production categories. The customer might already have different production categories. Convince him that the criterion whether a book is typeset in a standard layout or whether the author used a template is not sufficient.</li>
<li>Emphasize the role of the intake report. Establish automated tools for checking adherence to templates, image profiles, etc.</li>
<li>Establish a Web-based frill counter where you document the production editor’s or author’s special requests. For titles that are supposed in a standard workflow,  ask a customer’s representative to approve every single deviating requirement.</li>
</ul>
<p>These measures will assist the customers in improving their own processes and hopefully in moving away from underparameterized per-page pricing expectations. Per-page isn’t going to work in the long run, since more and more publications will be unpaginated. However, moving from page to kilobyte metrics won’t be a solution.</p>
<p>To answer the initial question: a boutique shouldn’t necessarily sell commodities. However, flat, per-page price comparisons might suggest diluting boutique production prices with commodity prices.</p>
<p>Another reason for us as a boutique to keep standardized, high-volume production is: not only do we deliver boutique <em>production</em>, but also boutique workflow consultancy and automation. In order to fully understand high-volume production requirements, we have got to do it ourselves. Therefore, we as a boutique do also strive to sell commodities, against all odds.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2012/02/boutique-commodities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why doesn’t my template match?</title>
		<link>http://publishinggeekly.com/2011/04/template-match/</link>
		<comments>http://publishinggeekly.com/2011/04/template-match/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 12:53:12 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[XSLT]]></category>
		<category><![CDATA[IDML]]></category>
		<category><![CDATA[Protip]]></category>
		<category><![CDATA[XPath]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=172</guid>
		<description><![CDATA[XSLT/XPath 2.0/3.0 are powerful technologies. But sometimes they’ll drive you nuts. A large share of issues falls into the category of “why doesn’t my template match?” The reasons are manifold. Here are some typical traps: not including the namespace prefix typo in the namespace URI processing the document in a different mode than the template <a href='http://publishinggeekly.com/2011/04/template-match/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>XSLT/XPath 2.0/3.0 are powerful technologies. But sometimes they’ll drive you nuts. A large share of issues falls into the category of “why doesn’t my template match?” The reasons are manifold. Here are some typical traps:</p>
<ul>
<li>not including the namespace prefix</li>
<li>typo in the namespace URI</li>
<li>processing the document in a different mode than the template is supposed to match in</li>
<li>other typos (in predicates, element names, modes)</li>
<li>skipping intermediate elements, e.g., formulating predicates for &lt;td&gt;s when the template is supposed to match &lt;tr&gt;</li>
<li>other templates have higher priority</li>
<li>import precedence: this template is an imported one, and there is a matching template of whatever priority in the importing stylesheet, or in a template imported after the template in question</li>
<li>logical misconceptions in the predicates</li>
<li>if the template is supposed to match a result of a previous transformation: the output of the previous tranformation is not as expected</li>
<li>processing some surrounding element with xsl:copy-of instead of xsl:apply-templates</li>
</ul>
<p>My tactics of debugging these cases include</p>
<p><span id="more-172"></span></p>
<ul>
<li>to make the non-matching template increasingly less specific (dropping terms in the predicate),</li>
<li>increase the priority to insane values,</li>
<li>make the template output debugging info such as &#8220;I&#8217;m here&#8221;, or count(*) and count(B) in the context of A (first make sure that the template matches A – &#8216;I&#8217;m A&#8217;),</li>
<li>output intermediate processing steps to a file (&lt;xsl:result-document href=&#8221;_debug.35.fooify-bar.xml&#8221;&gt;&lt;xsl:copy-of select=&#8221;$foo&#8221;/&gt;&lt;/xsl:result-document&gt;)</li>
</ul>
<p>Schema-aware processing will probably help detect many of the issues, too. But I have to admit that I don’t usually undergo the effort of creating schemas for intermediate transformation results.</p>
<h2>Templates that match too much</h2>
<p>This might also happen, and in fact a template that matched unexpectedly many nodes was the reason that I wrote this post.</p>
<p>Last night I spent hours debugging this template:</p>
<pre class="brush: xml; title: ; notranslate">&lt;xsl:template match=&quot;ParagraphStyleRange
                       [count(XMLElement) eq 1]
                       [every $x in descendant::XMLElement
                         [ancestor::ParagraphStyleRange[1] is current()/..]
                         satisfies (
                           not($x/XMLAttribute[@Name = 'aid:pstyle'])
                         )
                       ]
                       [every $c in CharacterStyleRange satisfies (matches($c, '^$'))]
                     /XMLElement
                       [not(every $c in * satisfies ($c/self::Table or $c/self::XMLAttribute))]&quot;
              mode=&quot;idml2xml:GenerateTagging&quot;&gt;
  &lt;xsl:copy&gt;
    &lt;xsl:copy-of select=&quot;@*&quot; /&gt;
    &lt;xsl:apply-templates mode=&quot;#current&quot; /&gt;
    &lt;XMLAttribute Name=&quot;xmlns:idml2xml&quot; Value=&quot;http://www.le-tex.de/namespace/idml2xml&quot; /&gt;
    &lt;XMLAttribute Name=&quot;idml2xml:AppliedParagraphStyle&quot; Value=&quot;{replace(../@AppliedParagraphStyle, '^ParagraphStyle/', '')}&quot; /&gt;
    &lt;XMLAttribute Name=&quot;idml2xml:reason&quot; Value=&quot;gp3&quot; /&gt;
  &lt;/xsl:copy&gt;
&lt;/xsl:template&gt;</pre>
<p>This is an example from an IDML processing pipeline as described in the <a href="/2010/11/17/indesign-xml-rope-of-sand/">ropes of sand</a> post. After splitting the text at every paragraph break, I want to attach pstyle information to elements that span a whole paragraph and that don’t already carry an aid:pstyle attribute. But there may already be XMLElements carrying a pstyle that are not immediately below the ParagraphStyleRange element. So in lines 3–8, I’m filtering the template to apply only to non-pstyled XMLElements. Caveat: there may be embedded ParagraphStyleRanges further down, for example, when there’s a Table or another Story contained in this range. So I’ll have to exclude XMLElements that are located in embedded ParagraphStyleRanges. And that’s what I originally wanted to check by applying the condition that every XMLElement[ancestor::ParagraphStyleRange[1] is current()] doesn’t have a pstyle. current() was working well as long as the template matched ParagraphStyleRanges. But then I modified it to have the current form, to match ParagraphStyleRange/XMLElement. Then suddenly it matched many more XMLElements, including such that had a pstyle attached to them. Why?</p>
<p>The reason is that by modifying the pattern from A[…] to A[…]/B (where A stands for ParagraphStyleRange, etc.), the term current() in A’s predicate no longer referred to A, but to B!. Therefore the condition [every $x in descendant::B[ancestor::A[1] is current()] satisfies …] was always true because in no circumstances may there be an ancestor::A that is of type B. And if the sequence after “every $x in” is empty, the “every … satisfies” clause is always true. Therefore my filter filtered too little of the ParagraphStyleRanges away, so that my template matched too many XMLElements. Changing current() to current()/.. in line 4 improved the situation.</p>
<p>Subtle, subtle. If I had to categorize it, I’d put it into the “logical misconceptions in the predicate” basket.</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2011/04/template-match/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Next Stop: proxy.apple.com</title>
		<link>http://publishinggeekly.com/2011/02/next-stop-proxy-apple-com/</link>
		<comments>http://publishinggeekly.com/2011/02/next-stop-proxy-apple-com/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 22:01:54 +0000</pubDate>
		<dc:creator>Gerrit Imsieke</dc:creator>
				<category><![CDATA[Publishing industry]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[distribution]]></category>
		<category><![CDATA[IAP]]></category>
		<category><![CDATA[Sony]]></category>

		<guid isPermaLink="false">http://publishinggeekly.com/?p=158</guid>
		<description><![CDATA[BREAKING: In #iOS 6/#MacOS 11, Web access only thru proxy.apple.com. Analyst: Web pages bypassing IAP a threat to revenue model With all the recent fuss about Apple’s In-App Purchase (IAP) API enforcement, the train toward Web apps will take up more traction. Apple themselves are constantly improving Mobile Safari: it supports most of the events <a href='http://publishinggeekly.com/2011/02/next-stop-proxy-apple-com/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<blockquote><p><a href="http://twitter.com/#!/gimsieke/status/29822284332011520">BREAKING</a>: In #iOS 6/#MacOS 11, Web access only thru proxy.apple.com. Analyst: Web pages bypassing IAP a threat to revenue model</p></blockquote>
<p>With all the <a href="http://www.wired.com/epicenter/2011/02/apple-cut-of-e-book-sales">recent fuss</a> about Apple’s In-App Purchase (IAP) API enforcement, the train toward Web apps will take up more traction.</p>
<p>Apple themselves are constantly improving Mobile Safari: it supports most of the events that iOS native apps do support, it is fast enough, and you can imitate a native app’a user experience quite well already. Plus: the Web has gotten really interoperable. You can get almost the same user experience with any iOS browser as with any Android browser without the need to develop for different hardware/software platforms.</p>
<p>German weekly <a href="http://www.informationarchitects.jp/en/news-on-ipad-the-obvious-way/">Die Zeit</a> already draw the consequences and abandoned the idea of native apps for their main content.</p>
<p>So in the view of the hefty app tax of 30%, will players such as Sony or Amazon offer their libraries as a pure Web site?</p>
<p><span id="more-158"></span>Currently it seems as if they may get Apple’s approval for the apps while still being able to sell content separately. Apple interprets its terms such that vendors may offer an alternative purchase path. This path must not be initiatable from within App store, and the vendors must also offer an In-App-Purchase path (probably at the same end user conditions? Apple will surely clarify this matter soon…).</p>
<p>For impulse buyers, the App store point of sales may be more attractive than going to Amazon’s Web site first, purchasing content and then reading it in the Kindle app. But subscribers of electronic magazines or newspapers will already have a well-established relationship with the publisher’s Web site. So they are likely to extend their existing subscription to the iPad version, not via App store but via publisher’s site, download the free app and start reading on the iPad. The publisher won’t have to pay the 30% Apple tax.</p>
<p>“<a href="http://www.mondaynote.com/2011/01/23/apples-bet-on-publishing/">In their usual cold My Way Or The Highway manner</a>”, Apple will certainly try to close this hole as soon as significant revenues bypass IAP. If antitrust authorities won’t help Amazon and Sony (for which they’ll have to blame Google because the success of Android kept Apple from monopolizing the smartphone/tablet markets), they’ll most probably step out off the App store and move to pure Web offerings. Optimized for mobile, of course, including caching of content, and with a crisp, app-like look &amp; feel.</p>
<p>What will Apple do then? They certainly won’t discontinue Mobile Safari, the tool that enables these Web apps. For some minutes, they might consider disabling HTML forms so that users won’t be able to log in or submit their credit card data to non-Apple services. But this will really break the Web experience; people wouldn’t accept this, and service providers would find ways to GET around these restrictions.</p>
<p>So the ultimate solution will be à la Chinoise: the great filter, or <strong>proxy.apple.com</strong> (iWall sounds to obstructive).</p>
<p>In order to improve the quality of service, to filter offensive or explicit content, etc. blah, all traffic will be routed through a content delivery network operated by Apple. Apple reserves the right to disallow connections to servers that host content that is discriminatory, sexually offensive, glorifying violence, …, …, …, and it will block servers that offer transactions bypassing Apple’s then-called iPay system. Since this proxy will be built into the devices’ firmware, only jailbroken devices may circumvent this.</p>
<p>The part of the Internet that will be accessible to Apple users will then be known as the <strong>iNet</strong>. And I’m sure Apple won’t content themselves with fencing in the mobile crowd. Mac users! Not only will you be allowed to taste the sweet and amazingly low-priced App store fruit, you will also be <span style="text-decoration: line-through;">restricted </span>invited to iNet, which means you will also be forced to use iPay for online purchases. Paypal, Visa, Flattr, invoice? These services violate the terms of use and will be blocked.</p>
<p>I wonder why so many morons surrender to Apple so wholeheartedly, for such a small usability or coolness advantage, if any. But I similarly wondered 15 years ago, when I was advocating Linux against Windows. Now my phone runs Linux, and it’s quite usable.</p>
<blockquote><p>the definition of open: &#8220;mkdir android ; cd android ; repo init -u  git://android.git.kernel.org/platform/manifest.git ; repo sync ; make&#8221; (<a href="http://twitter.com/#!/arubin/status/27808662429">@arubin</a>)</p></blockquote>
<p>See also:<br />
<a href="http://mikecanex.wordpress.com/2011/02/01/the-day-apple-became-nathan-myhrvold/">Mike Cane: The Day Apple Became Nathan Myhrvold</a> (added 2011-02-01 23:25Z)</p>
]]></content:encoded>
			<wfw:commentRss>http://publishinggeekly.com/2011/02/next-stop-proxy-apple-com/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
