<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2606986058284855798</id><updated>2011-11-02T20:07:21.087+01:00</updated><category term='grammar'/><category term='fop'/><category term='maven'/><category term='git'/><category term='font'/><category term='java'/><category term='security'/><category term='identifier'/><title type='text'>The Novelang blog</title><subtitle type='html'>The official blog of the Novelang project</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default?start-index=101&amp;max-results=100'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>186</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1334136118205402814</id><published>2011-09-03T06:41:00.001+02:00</published><updated>2011-09-03T06:41:46.723+02:00</updated><title type='text'>Good article on O’Reilly Radar: Why an ebook still needs an index</title><content type='html'>&lt;p&gt;Read this excellent post, &lt;a href="http://radar.oreilly.com/2011/09/ebook-index-search-discovery.html"&gt; Why an ebook still needs an index &lt;/a&gt; on O&amp;rsquo;Reilly Radar.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;We learn why full text search won&amp;rsquo;t replace a good old-fashioned book index. We also learn that most ebooks don&amp;rsquo;t have one, because it&amp;rsquo;s horribly difficult to create a useful semantic index.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Yes, there are &lt;a href="http://novelang.blogspot.com/2009/06/book-index.html"&gt; plans &lt;/a&gt; to include book index into Novelang.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1334136118205402814?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1334136118205402814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1334136118205402814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1334136118205402814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1334136118205402814'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/09/good-article-on-o-radar-why-ebook-still.html' title='Good article on O&amp;rsquo;Reilly Radar: Why an ebook still needs an index'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5760337263554411197</id><published>2011-06-26T22:49:00.000+02:00</published><updated>2011-09-11T13:40:06.301+02:00</updated><title type='text'>iA Writer</title><content type='html'>&lt;p&gt;&lt;a href="http://www.iawriter.com/"&gt; iA Writer &lt;/a&gt; is the most clever text editor I’ve ever seen. Serious. Just watch its 1-minute presentation. It’s a lot of fun. I watched it three times already. They say:  &lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;iA Writer for Mac is a digital writing tool that makes sure that all your thoughts go into the text instead of the program.  &lt;/blockquote&gt;That’s a lot of shared mindset with Novelang. While both tools leverage on a Wiki syntax, iA Writer tackles the problem with a dedicated graphical interface. It’s a minimalistic text editor that dynamically adjusts its display according to a Wiki syntax (&lt;a href="http://daringfireball.net/projects/markdown/syntax"&gt; Markdown &lt;/a&gt;). It has no menus, no preferences, and, well… almost no features. You pay for getting rid of the crap. It’s a paying application, only available on Mac and iPad, through the AppStore. Yes, it screws GPL lovers, but that’s not a reason to not look closely at what it does.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;Markdown&lt;/b&gt;&lt;/p&gt;&lt;p&gt;iA Writer relies on the Markdown syntax. I don’t like &lt;a href="http://daringfireball.net/projects/markdown/syntax"&gt; Markdown syntax &lt;/a&gt;, for various reasons.  &lt;/p&gt;&lt;p&gt;But Markdown is simple enough to be extremely fast to learn (especially with HTML left out). By sticking to this minimalistic level, iA Writer becomes easy to learn and keeps focused on the text being written.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;I should have invented it first!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;During a presentation of Novelang for corporate use, a guy asked me: “Do you plan some graphical editor for Novelang?” I answered: “Never, it would lose the purpose of the tool. Maybe I’ll package some syntax highlighting configuration for text editors one day but nothing more.”  &lt;/p&gt;&lt;p&gt;This was a decent answer, but iA Writer is more clever. I didn’t envisage dynamic formatting, just because it seems hard to program. One author if &lt;a href="http://www.jetbrains.com/idea"&gt; IntelliJ IDEA &lt;/a&gt; explained that they fully rewrote a Java parser by hand to be fault-tolerant. The rule about parsers is: don’t write them by hand because you’re not clever enough for that. And Novelang syntax is more complex than Java.  &lt;/p&gt;&lt;p&gt;I didn’t play with iA Writer so I’ve no hint on how its parser works. Probably the display asks for a best effort given a paragraph, and when the parsing fails there is just no styling. Because of the interactive nature of the application, the user quickly learns how to fix broken text.  &lt;/p&gt;&lt;p&gt;Novelang’s strict parser offers strong guarantees about correctness, and that’s a strong point when it comes to generate the final document. But this all-or-nothing approach greatly reduces interactivity. (Interactivity happens later in the Web browser, with some JavaScript to show metadata.)  &lt;/p&gt;&lt;p&gt;iA Writer found a new path to the ultimate ease-of-use, while still relying on the Wiki syntax that’s at the heart of Novelang philosophy. I’m just disappointed I didn’t think first about an “augmented” text editor for aiding input of a Wiki text. On the other hand, this wouldn’t have helped me to keep focused on a restrained feature set.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;Outsmarting iA Writer?&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Spending hundreds of hours of effort to mimick iA Writer sounds like a waste. On the other hand, iA Writer only runs on the Mac/iOS platform and doesn’t offer more than a text editor when inserted in a publication chain. By now, a simple mix of &lt;a href="http://notepad-plus-plus.org/"&gt; Notepad++ &lt;/a&gt;, Novelang and &lt;a href="http://git-scm.com/"&gt; git &lt;/a&gt; already offers a complete collaborative solution.  &lt;/p&gt;&lt;p&gt;But iA Writer is not the end of the story. By now it works with a full-size keyboard, or with iPad’s keyboard emulation –&amp;nbsp;not the most comfortable thing you can dream about. There are things to invent for a post-iPad world, when handheld devices will have something like a &lt;a href="http://www.8pen.com/"&gt; decent virtual keyboard &lt;/a&gt;. Starting experiments on a graphical interface with a dedicated parser could be a step in the future.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/p&gt;&lt;p&gt;By now, Novelang is good at what it does, but lacks a few features: intralinks, embeddability, ePub, and &lt;a href="http://novelang.blogspot.com/2011/02/novelang-desktop.html"&gt; desktop integration &lt;/a&gt;. It’s important to finish that first.  &lt;/p&gt;&lt;p&gt;Novelang could support Markdown as optional syntax. This would make iA Writer the editor of choice and keep Novelang project focused on document agregation and rendering. Two different syntaxes trigger the “double feature alarm”. The source parser could become a pluggable thing, letting other people implement Markdown support. By now, the very few users of Novelang are happy with the out-of-the-box experience and didn’t ask for such geeky features.  &lt;/p&gt;&lt;p&gt;Hacking a special text editor component that behaves like iA Writer’s one could be a nice experiment, but it shouldn’t be part of Novelang’s core before years. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5760337263554411197?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5760337263554411197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5760337263554411197' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5760337263554411197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5760337263554411197'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/06/ia-writer.html' title='iA Writer'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8657048284195872726</id><published>2011-06-15T05:54:00.002+02:00</published><updated>2011-06-15T05:56:21.043+02:00</updated><title type='text'>AsciiFlow: WYSIWYG ASCIIArt</title><content type='html'>&lt;p&gt;&lt;a href="http://www.asciiflow.com"&gt; AsciiFlow &lt;/a&gt; is a drawing tool for producing ASCII art. Currently supports lines and boxes, plus an eraser tool. Looks like the ultimate tool for UML diagrams &amp;ndash;&amp;nbsp;no kidding.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Thanks to &lt;a href="http://archiloque.net"&gt; Julien Kirch &lt;/a&gt; who reported this to me first.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8657048284195872726?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8657048284195872726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8657048284195872726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8657048284195872726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8657048284195872726'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/06/asciiflow-wysiwyg-asciiart-asciiflow-is.html' title='AsciiFlow: WYSIWYG ASCIIArt'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7269214941181836744</id><published>2011-03-23T08:51:00.003+01:00</published><updated>2011-03-23T20:00:29.236+01:00</updated><title type='text'>Jekyll: a static website generator</title><content type='html'>&lt;p&gt;Quoting its presentation, "&lt;a href="https://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt; is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server."&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Jekyll is It&amp;rsquo;s &lt;a href="http://github.com"&gt;github&lt;/a&gt;'s Wiki engine. This is a clever integration: the VCS tracks Wiki page changes, which means the project hosted by github has a wiki &lt;em&gt;and&lt;/em&gt; versioned documentation along with sourcecode.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Jekyll is a batch-only generator, so no interactive preview. Markdown and Textile are also more lenient about grammar validation. But Jekyll is probably much lighter than Novelang, which makes it a better choice for github.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7269214941181836744?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7269214941181836744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7269214941181836744' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7269214941181836744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7269214941181836744'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/03/jekyll-static-website-generator.html' title='Jekyll: a static website generator'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2045272146105946459</id><published>2011-03-12T01:28:00.000+01:00</published><updated>2011-03-12T01:29:00.556+01:00</updated><title type='text'>Novelang-0.56.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.56.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Added Romanian characters, as listed on &lt;a href="http://en.wikipedia.org/wiki/Romanian_alphabet" &gt;Wikipedia&lt;/a&gt;. This includes diacritics made obsolete by the spelling reform of 1904, minus the d/D letter with a comma below, for which Unicode offers no precomposed characters.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2045272146105946459?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2045272146105946459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2045272146105946459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2045272146105946459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2045272146105946459'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/03/novelang-0560-released.html' title='Novelang-0.56.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3416462711736354792</id><published>2011-02-05T13:13:00.000+01:00</published><updated>2011-02-05T13:13:39.374+01:00</updated><title type='text'>Novelang-Desktop</title><content type='html'>&lt;p&gt;This is the result of a conversation with another Novelang user, coming with ideas for a better integration with the desktop environment.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;First, as strange as it seems, Novelang &lt;em&gt;is&lt;/em&gt; a desktop application. While it embeds a Web server it&amp;rsquo;s not meant to serve content to remote clients. The support of a Web client is just the fastest approach to give quick preview of files edited in a desktop-integrated text editor. (For serving Novelang documents on the World Wide Web, it&amp;rsquo;s much faster to generate them as static files first.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;By now the desktop integration relies on a &lt;code&gt;java -jar Novelang-...jar&lt;/code&gt; typed in a command-line console. That&amp;rsquo;s a bit harsh.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The yet-to-develop Novelang-desktop project would be fancier. Novelang-desktop is a graphical application where user sets content roots and associated TCP ports. With this, editing or viewing Novelang documents from multiple content directories doesn&amp;rsquo;t require to start several JVMs anymore.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Here is a skeletal view of the main window of Novelang-desktop:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt; ___________________________________________
|  __________________________               |
| | C:\projects\docs  | 8081 |  [ Add...  ] |
| | I:\shared\foo     | 8082 |  [ Edit... ] |
| |___________________|______|  [ Remove  ] |
|                                           |
| [?]                      [ Configure... ] |
|___________________________________________|
&lt;/pre&gt;&lt;p&gt;Double-clicking on a table line opens a Web browser with the directory listing of the content root.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The directory listing comes with great improvements. It shows every files, and each Novelang source file has several associated links: &lt;ul&gt;&lt;li&gt; Open in current Web browser (one link per rendition MIME type, like PDF, HTML, FO, XML). &lt;/li&gt; &lt;li&gt; Open in default editor. &lt;/li&gt; &lt;li&gt; Batch generation. &lt;/li&gt; &lt;/ul&gt;&lt;/p&gt;&lt;p&gt;For the last two there is a trick: the link loops back to a special service of Novelang-desktop, which has all the powers to execute arbitrary code and scan local filesystem. &lt;ul&gt;&lt;li&gt; For editor opening it executes a pre-configured command with the file path as an argument. &lt;/li&gt; &lt;li&gt; For batch generation first it opens a dialog requesting target directory. &lt;/li&gt; &lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Novelang-desktop&amp;rsquo;s configuration goes in user&amp;rsquo;s home directory by default.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3416462711736354792?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3416462711736354792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3416462711736354792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3416462711736354792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3416462711736354792'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/02/novelang-desktop.html' title='Novelang-Desktop'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8140249513182605362</id><published>2011-02-04T21:15:00.001+01:00</published><updated>2011-02-04T21:15:20.451+01:00</updated><title type='text'>Novelang-0.55.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.55.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;New &lt;code &gt;--temporary-dir&lt;/code&gt; option. For better error messages, Novelang now buffers the whole document before sending it to the HTTP client. When the document is too big Novelang buffers it into a temporary file under this directory. If an error occurs then its not too late to send an HTTP redirection.&lt;/li&gt;&lt;li &gt;Fixed SVG embedding for PDF. Now the image appears as true vector image inside the PDF. Correct reference to the SVG resource implied adding a &lt;code &gt;$content-directory&lt;/code&gt; parameter passed to XSL stylesheets.&lt;/li&gt;&lt;li &gt;Fixed loss of request parameters when issuing error page.&lt;/li&gt;&lt;li &gt;Less verbose logging of Logback configuration at startup.&lt;/li&gt;&lt;li &gt;Fixed various cases of bad problem reporting, where location in origin file was missing.&lt;/li&gt;&lt;li &gt;Plenty of other small fixes.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8140249513182605362?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8140249513182605362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8140249513182605362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8140249513182605362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8140249513182605362'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/02/novelang-0550-released.html' title='Novelang-0.55.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2387979024255986887</id><published>2011-01-23T00:41:00.005+01:00</published><updated>2011-01-23T10:48:56.591+01:00</updated><title type='text'>Secrets for embedding SVG images in PDF documents</title><content type='html'>&lt;p&gt;Nhovestone reports don&amp;rsquo;t look good when zooming, because the charts are bitmap images. While trying to render them as vector images, a few interesting things did appear.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;(Most of them relate to FOP-1.0 and Batik-1.7 which are the latest versions at this time.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;There was a bug (fixed in HEAD) preventing from embedding SVG images in PDF documents. Novelang resolves the image path (in &lt;code&gt;n:vector-image/n:resource-location&lt;/code&gt;) as relative to the content directory. But most of times the stylesheet doesn&amp;rsquo;t reside right under the content root, so FOP (the PDF renderer) couldn&amp;rsquo;t find the SVG file. Now XSL stylesheets receive a &lt;code&gt;$content-directory&lt;/code&gt; parameter to solve this.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;There are several manners to embed an SVG file into a PDF. In order to keep the vector graphics (means: avoiding an ugly conversion to a bitmap) FOP needs a rather twisted declaration of the form:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;fo:instream-foreign-object&gt;
  &amp;lt;svg:svg width="123px" height="456px" &gt;
    &amp;lt;svg:image width="123px" height="456px" xlink:href="file:/my/image.svg" /&gt;
  &amp;lt;/svg:svg&gt;
&lt;/pre&gt;&lt;p&gt;The documentation explains that width and the height must appear two times, with exactly the same values.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;It&amp;rsquo;s important to note that an SVG image must always have width and height. Moreover, they must be in pixel unit. Pixel unit is bad, as it introduces a dependency to document&amp;rsquo;s resolution. But units other than pixel don&amp;rsquo;t work.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Knowing this, the graphs started to look really good. Unfortunately, the grid becomes bigger when zooming in. In theory, the solution is to set line with to a zoom-independant value with &lt;code&gt;vector-effect="non-scaling-stroke"&lt;/code&gt; property (thanks to &lt;a href="http://stackoverflow.com/questions/1039714/svg-problems/1039815#1039815"&gt; StackOverflow &lt;/a&gt; for that hint). Unfortunately, this is SVG 1.2. Batik doesn&amp;rsquo;t support this yet and some archived mails show this is somewhat tricky to implement.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Conclusion: while SVG embedding in PDF is far from perfect, it&amp;rsquo;s much better than rasterized images that seemed to be FOP&amp;rsquo;s approach. In order to get best vector images we'll have to wait for non-scaling stroke feature in Batik, and maybe some FOP upgrade in order to propagate this feature to generated PDF.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2387979024255986887?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2387979024255986887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2387979024255986887' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2387979024255986887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2387979024255986887'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/secrets-for-embedding-svg-images-in-pdf.html' title='Secrets for embedding SVG images in PDF documents'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4734602766511261230</id><published>2011-01-18T21:04:00.003+01:00</published><updated>2011-01-19T05:52:31.732+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Aggregated javadoc with Maven</title><content type='html'>&lt;p&gt;
This generates a javadoc covering every subproject.
From Novelang root project:
&lt;/p&gt;&lt;pre&gt;mvn -Dnovelang.javadoc.skip=false javadoc:aggregate
&lt;/pre&gt;&lt;p&gt;Generated HTML goes in &lt;code&gt;target/site/apidocs&lt;/code&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4734602766511261230?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4734602766511261230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4734602766511261230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4734602766511261230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4734602766511261230'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/aggregated-javadoc-with-maven.html' title='Aggregated javadoc with Maven'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-611232588357055026</id><published>2011-01-17T23:02:00.000+01:00</published><updated>2011-01-17T23:02:08.607+01:00</updated><title type='text'>Nhovestone report for Novelang-0.54.0</title><content type='html'>&lt;p&gt;The &lt;a href="http://novelang.sourceforge.net/nhovestone.pdf"&gt;Nhovestone report&lt;/a&gt; shows that Novelang-0.54.0 is as at least as fast as previous versions. Good news!&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-611232588357055026?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/611232588357055026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=611232588357055026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/611232588357055026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/611232588357055026'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/nhovestone-report-for-novelang-0540.html' title='Nhovestone report for Novelang-0.54.0'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2069338038640140176</id><published>2011-01-07T00:30:00.001+01:00</published><updated>2011-01-07T00:30:37.604+01:00</updated><title type='text'>Novelang-0.54.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.54.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Because of some cleanup, &lt;code &gt;n:relative-identifier&lt;/code&gt; becomes illegal in stylesheets (wasn&amp;rsquo;t generated since a few versions). This might break a few existing stylesheets.&lt;/li&gt;&lt;li &gt;Better logging of accessed resources.&lt;/li&gt;&lt;li &gt;Documentation enhancements.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2069338038640140176?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2069338038640140176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2069338038640140176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2069338038640140176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2069338038640140176'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/novelang-0540-released.html' title='Novelang-0.54.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8783890139888677242</id><published>2011-01-03T23:11:00.001+01:00</published><updated>2011-01-03T23:11:42.001+01:00</updated><title type='text'>Novelang-0.53.6 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.53.6! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed resource loading bug appeared in 0.53.5, that caused to ignore overriden resources (like stylesheets).&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8783890139888677242?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8783890139888677242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8783890139888677242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8783890139888677242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8783890139888677242'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/novelang-0536-released.html' title='Novelang-0.53.6 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7437092289060190732</id><published>2011-01-01T18:02:00.000+01:00</published><updated>2011-01-01T18:03:01.420+01:00</updated><title type='text'>Novelang-0.53.5 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.53.5! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Various logging enhancements.&lt;/li&gt;&lt;li &gt;Various enhancements to the documentation.&lt;/li&gt;&lt;li &gt;Disabled full parsing and validation for SVG files.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7437092289060190732?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7437092289060190732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7437092289060190732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7437092289060190732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7437092289060190732'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2011/01/novelang-0535-released.html' title='Novelang-0.53.5 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4220372203564097861</id><published>2010-12-29T08:39:00.001+01:00</published><updated>2010-12-29T08:39:45.140+01:00</updated><title type='text'>Novelang-0.53.4 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.53.4! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed logging configuration with &lt;code &gt;--log-dir&lt;/code&gt; option.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4220372203564097861?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4220372203564097861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4220372203564097861' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4220372203564097861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4220372203564097861'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/novelang-0534-released.html' title='Novelang-0.53.4 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2124932730291837751</id><published>2010-12-27T22:35:00.001+01:00</published><updated>2010-12-27T22:35:16.166+01:00</updated><title type='text'>Novelang-0.53.3 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.53.3! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed barcode generation.&lt;/li&gt;&lt;li &gt;Minor logging enhancements.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2124932730291837751?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2124932730291837751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2124932730291837751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2124932730291837751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2124932730291837751'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/novelang-0533-released.html' title='Novelang-0.53.3 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7678449107458348079</id><published>2010-12-27T20:37:00.004+01:00</published><updated>2010-12-27T20:38:15.574+01:00</updated><title type='text'>Browser compatibility for HTML documentation</title><content type='html'>&lt;p&gt;Since version 0.53.0 Novelang HTML documentation displays correctly on following browsers: &lt;ul&gt;&lt;li&gt; Safari 5.0 (Mac OS X 10.6.5, Windows XP 32bits SP3). &lt;/li&gt; &lt;li&gt; Firefox 3.6 (Mac OS X 10.6.5, Windows XP 32bits SP3). &lt;/li&gt; &lt;li&gt; Google Chrome 8.0 (Windows XP 32bits SP3). &lt;/li&gt; &lt;li&gt; Internet Explorer 8 (Windows XP 32bits SP3). &lt;/li&gt; &lt;/ul&gt;
&lt;/p&gt;&lt;p&gt;The website also passed &lt;a href="http://validator.w3.org/check?uri=novelang.org&amp;charset=%28detect+automatically%29&amp;doctype=Inline&amp;group=0"&gt;W3C validation&lt;/a&gt; for HTML 4.0 Transitional.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7678449107458348079?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7678449107458348079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7678449107458348079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7678449107458348079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7678449107458348079'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/browser-compatibility-for-html.html' title='Browser compatibility for HTML documentation'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5369052671657696121</id><published>2010-12-27T20:20:00.002+01:00</published><updated>2010-12-27T20:39:45.147+01:00</updated><title type='text'>Some links about CSS layout</title><content type='html'>&lt;p&gt;&lt;a href="http://www.positioniseverything.net/thr.col.stretch.html"&gt; Three Column Stretch &lt;/a&gt;: strech isn&amp;rsquo;t that good, makes too long lines for main text.
&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.positioniseverything.net/piefecta-rigid-right.html"&gt; Piefecta &amp;ndash;&amp;nbsp;A superb 3-col tableless layout&amp;nbsp;&amp;ndash; long right col &lt;/a&gt; looks good on Safari and zooms well. Tells it deals with various browser bugs. Probably the finest piece of engineering but too many fixes are making it unreadable. We don&amp;rsquo;t care about supporting IE6. License: unknown.
&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.dynamicdrive.com/style/layouts/item/css-fixed-layout-31-fixed-fixed-fixed/"&gt; CSS Fixed Layout #3.1 (Fixed-Fixed-Fixed) &lt;/a&gt; zooms correctly. Much simpler. License: unknown.
&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.csszengarden.com/?cssfile=http://green-beast.com/portfolio/zen/css/zen.css"&gt; Elastic-fluid hybrid &lt;/a&gt; got it right. It scales up and down in with, staying in fixed limits. Read author&amp;rsquo;s &lt;a href="http://green-beast.com/blog/?p=67"&gt; comments &lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;Also check this &lt;a href="http://jontangerine.com/log/2007/09/the-incredible-em-and-elastic-layouts-with-css"&gt; tutorial &lt;/a&gt; about elastic layout.
&lt;/p&gt;&lt;p&gt;&lt;a href="http://matthewjamestaylor.com/blog/ultimate-3-column-holy-grail-ems.htm"&gt; The Holy Grail 3 column Liquid Layout &lt;/a&gt; has great explainations. (Only 1 error on &lt;a href="http://validator.w3.org"&gt; W3C validator &lt;/a&gt; but the element reported to be missing appears as it should &amp;ndash;&amp;nbsp;validator bug?) License: free to use, linkback appreciated. After a close look, it turned out that forcing &lt;code&gt;min-width&lt;/code&gt; and &lt;code&gt;max-width&lt;/code&gt; for the column (worst case: nesting another &lt;code&gt;div&lt;/code&gt;) and using proper text alignment does the job.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5369052671657696121?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5369052671657696121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5369052671657696121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5369052671657696121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5369052671657696121'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/some-links-about-css-layout.html' title='Some links about CSS layout'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1851391191372657929</id><published>2010-12-26T20:37:00.002+01:00</published><updated>2010-12-26T20:41:35.169+01:00</updated><title type='text'>Novelang-0.53.2 released!</title><content type='html'>&lt;p &gt;Just released Novelang-0.53.2! &lt;/p&gt;&lt;p &gt;Summary of changes: &lt;/p&gt;&lt;div class="descriptor" &gt;&lt;/div&gt;&lt;ul class="big-list" &gt;&lt;li &gt;Indicating error location when something goes bad during XSL transformation.&lt;/li&gt;
&lt;li &gt;Minor fixes on HTML documentation.&lt;/li&gt;
&lt;/ul&gt;&lt;p &gt;Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt;&lt;p &gt;Enjoy! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1851391191372657929?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1851391191372657929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1851391191372657929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1851391191372657929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1851391191372657929'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/novelang-0532-released.html' title='Novelang-0.53.2 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4078568105180223754</id><published>2010-12-23T21:53:00.002+01:00</published><updated>2010-12-26T20:41:16.175+01:00</updated><title type='text'>Novelang-0.53.1 released!</title><content type='html'>&lt;p &gt;Just released Novelang-0.53.1! &lt;/p&gt;&lt;p &gt;Summary of changes: &lt;/p&gt;&lt;div class="descriptor" &gt;&lt;/div&gt;&lt;ul class="big-list" &gt;&lt;li &gt;Minor cosmetic changes for HTML generation.&lt;/li&gt;
&lt;/ul&gt;&lt;p &gt;Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt;&lt;p &gt;Enjoy! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4078568105180223754?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4078568105180223754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4078568105180223754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4078568105180223754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4078568105180223754'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/novelang-0531-released.html' title='Novelang-0.53.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4021089648221001173</id><published>2010-12-23T19:01:00.001+01:00</published><updated>2010-12-23T19:01:36.834+01:00</updated><title type='text'>Novelang-0.53.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.53.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Experimental support for Multipage. See the result in Novelang documentation.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Small logging enhancements.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;More restrictive rules when applying XSL stylesheets. Generation now breaks on warnings. This might break existing incorrect stylesheets.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Changed default representation of Fragment Identifiers, both Implicit and Explicit. Removed leading double reverse solidus &lt;code &gt;\\&lt;/code&gt; when rendering (still required in document sources).&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4021089648221001173?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4021089648221001173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4021089648221001173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4021089648221001173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4021089648221001173'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/12/novelang-0530-released.html' title='Novelang-0.53.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5316419688375136669</id><published>2010-11-19T21:47:00.000+01:00</published><updated>2010-11-19T21:47:39.779+01:00</updated><title type='text'>Rule-based number spelling</title><content type='html'>&lt;p&gt;Novelang comes with a &lt;code&gt;Numbering&lt;/code&gt; class which formats an integer value in words. This adds a bit of magic when the stylesheet writes "Chapter fourty-two" from a stupid counter.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Currently the &lt;code&gt;Numbering&lt;/code&gt; class only supports French and English, and values from 0 to 50 (all values are hardcoded). The &lt;a href="http://site.icu-project.org" &gt;ICU project&lt;/a&gt; offers the &lt;a href="http://icu-project.org/apiref/icu4j/com/ibm/icu/text/RuleBasedNumberFormat.html" &gt;&lt;code&gt;RuleBasedNumberFormat&lt;/code&gt;&lt;/a&gt; which supports rule-based formatting. This makes easy to support much greater ranges.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5316419688375136669?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5316419688375136669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5316419688375136669' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5316419688375136669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5316419688375136669'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/rule-based-number-spelling.html' title='Rule-based number spelling'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-605962560588959243</id><published>2010-11-17T22:53:00.005+01:00</published><updated>2010-11-17T23:20:59.304+01:00</updated><title type='text'>XSL mockup for multipage rendering</title><content type='html'>&lt;p&gt;Here is how an XSL would render a &lt;a href="http://novelang.blogspot.com/2010/09/technical-study-multi-page-html.html" &gt;multipage document&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;First, let&amp;rsquo;s consider the whole document defining the opus:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;== One

Some text of level one.

== Two

Some text of level two.

=== Two-one

Some text of level two-one.
&lt;/pre&gt;&lt;p&gt;The XML form of the document above is:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;
&amp;lt;opus&amp;gt;
  &amp;lt;level&amp;gt;
    &amp;lt;title&amp;gt;One&amp;lt;/title&amp;gt;
    &amp;lt;paragraph&amp;gt;Some text of level one.&amp;lt;/paragraph&amp;gt;
  &amp;lt;/level&amp;gt;
  &amp;lt;level&amp;gt;
    &amp;lt;title&amp;gt;Two&amp;lt;/title&amp;gt;
    &amp;lt;paragraph&amp;gt;Some text of level two.&amp;lt;/paragraph&amp;gt;
    &amp;lt;level&amp;gt;
      &amp;lt;title&amp;gt;Two-one&amp;lt;/title&amp;gt;
      &amp;lt;paragraph&amp;gt;Some text of level two-one.&amp;lt;/paragraph&amp;gt;
    &amp;lt;/level&amp;gt;
  &amp;lt;/level&amp;gt;
&amp;lt;/opus&amp;gt;
&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s take for granted that Novelang supports XSL metadata. Our multipage-enabled stylesheet would define an embedded stylesheet that transforms a whole opus into a simple map of page names and page paths. A path is whatever the stylesheet may reprocess, but an XPath expression is quite good. For the document above, here is how our map could look like, if we want to support 2 levels:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;page1 -&gt; /opus/level[1]
page2 -&gt; /opus/level[2]
page3 -&gt; /opus/level[2]/level[1]
&lt;/pre&gt;&lt;p&gt;Please note that, at this point, the decisision to support a given depth, or exclude some tagged levels, entirely belongs to the page-extracting stylesheet.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;By merging the page map with the opus, we get the XML input for the rendering of one page. Novelang knows which page it is either because it is iterating over all known pages of the map (batch mode), or because the page name is a part of the request issued to the HTTP dæmon.&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;op&amp;gt;us&amp;gt;
  &amp;lt;meta&amp;gt;
    &amp;lt;page&amp;gt;
      &amp;lt;name&amp;gt;page2&amp;lt;/name&amp;gt;
      &amp;lt;path&amp;gt;/opus/level[2]&amp;lt;/path&amp;gt;
    &amp;lt;/page&amp;gt;
  &amp;lt;/meta&amp;gt;

  &amp;lt;level&amp;gt;
    &amp;lt;title&amp;gt;One&amp;lt;/title&amp;gt;
    &amp;lt;paragraph&amp;gt;Some text of level one.&amp;lt;/paragraph&amp;gt;
  &amp;lt;/level&amp;gt;
  &amp;lt;level&amp;gt;
    &amp;lt;title&amp;gt;Two&amp;lt;/title&amp;gt;
    &amp;lt;paragraph&amp;gt;Some text of level two.&amp;lt;/paragraph&amp;gt;
    &amp;lt;level&amp;gt;
      &amp;lt;title&amp;gt;Two-one&amp;lt;/title&amp;gt;
      &amp;lt;paragraph&amp;gt;Some text of level two-one.&amp;lt;/paragraph&amp;gt;
    &amp;lt;/level&amp;gt;
  &amp;lt;/level&amp;gt;
&amp;lt;/opus&amp;gt;
&lt;/pre&gt;&lt;p&gt;(Note: the &lt;code&gt;n:&lt;/code&gt; namespace prefix doesn&amp;rsquo;t appear here for brevity.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The stylesheet gets this whole document as input for every page. All what changes is the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt; pair in the &lt;code&gt;meta/page&lt;/code&gt; element. The stylesheet needs to know which page it is rendering, and the whole document tree as well, in order to create a navigation bar or any kind of header or footer corresponding to a specially-titled or tagged level of the document.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;This involves some XSL trickery: evaluating an XPath expression at runtime. While it&amp;rsquo;s not part of XPath 1.0 specification, it is a part of semi-official &lt;a href="http://www.exslt.org"&gt; EXSLT &lt;/a&gt; communitiy initiative. The &lt;code&gt;dyn:evaluate&lt;/code&gt; &lt;a href="http://www.exslt.org/dyn/functions/evaluate"&gt; http://www.exslt.org/dyn/functions/evaluate &lt;/a&gt; does that for us. It works well with Xalan-2.7.1 which is the XSLT engine bundled with Novelang (it works a slightly better than JDK&amp;rsquo;s one).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;In the stylesheet below, we save useful expressions into variables.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The root template prints those variables, then a pseudo-navigation bar made of nested lists.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The nested loop for iterating over &lt;code&gt;level&lt;/code&gt; elements is rather ugly but it makes sense as we don&amp;rsquo;t want infinite deph of titles in a navigation bar.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;The &lt;code&gt;title-with-locator&lt;/code&gt; template just adds bold on the title in the navigation bar that corresponds to current page.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;All other templates mimic Novelang&amp;rsquo;s standard rendering.&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:dyn="http://exslt.org/dynamic"
    extension-element-prefixes="dyn"
&amp;gt;
  &amp;lt;!-- Be sure to use Xalan-2.7.1 (not JDK's default). --&amp;gt;

  &amp;lt;!--
    Here, expect a meta section, embedding a stylesheet 
    that extracts the pages we'll find in the meta section 
    of input document.
  --&amp;gt;

  &amp;lt;xsl:output method="html" /&amp;gt;

  &amp;lt;xsl:variable name="page-name" select="/opus/meta/page/name" /&amp;gt;
  &amp;lt;xsl:variable name="page-path" select="/opus/meta/page/path" /&amp;gt;
  &amp;lt;xsl:variable name="page-nodeset" 
      select="dyn:evaluate( $page-path )" /&amp;gt;
  &amp;lt;xsl:variable name="page-id" 
      select="generate-id( $page-nodeset )" /&amp;gt;

  &amp;lt;xsl:template match="meta/page" &amp;gt;
    $page-name=&amp;lt;xsl:value-of select="$page-name" /&amp;gt;
    $page-path=&amp;lt;xsl:value-of select="$page-path" /&amp;gt;
    $page-id=&amp;lt;xsl:value-of select="$page-id" /&amp;gt;
  &amp;lt;/xsl:template&amp;gt;

  &amp;lt;xsl:template match="/opus" &amp;gt;
    &amp;lt;html&amp;gt;
      &amp;lt;xsl:apply-templates select="meta" /&amp;gt;

      &amp;lt;!-- Navigation bar --&amp;gt;
      &amp;lt;ul&amp;gt;
        &amp;lt;xsl:for-each select="level"&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;xsl:call-template name="title-with-locator"/&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;xsl:if test="level"&amp;gt;
            &amp;lt;ul&amp;gt;
              &amp;lt;xsl:for-each select="level"&amp;gt;
                &amp;lt;li&amp;gt;
                  &amp;lt;xsl:call-template name="title-with-locator"/&amp;gt;
                &amp;lt;/li&amp;gt;
              &amp;lt;/xsl:for-each&amp;gt;
            &amp;lt;/ul&amp;gt;
          &amp;lt;/xsl:if&amp;gt;
        &amp;lt;/xsl:for-each&amp;gt;
      &amp;lt;/ul&amp;gt;

      &amp;lt;!-- Document body, same templates as usual --&amp;gt;
      &amp;lt;xsl:apply-templates select="$page-nodeset" /&amp;gt;

    &amp;lt;/html&amp;gt;

  &amp;lt;/xsl:template&amp;gt;


  &amp;lt;xsl:template match="paragraph" &amp;gt;
    &amp;lt;p&amp;gt;
      &amp;lt;xsl:value-of select="." /&amp;gt;
    &amp;lt;/p&amp;gt;
  &amp;lt;/xsl:template&amp;gt;

  &amp;lt;xsl:template match="title" /&amp;gt;

  &amp;lt;xsl:template match="level" &amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;xsl:value-of select="title" /&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;xsl:apply-templates/&amp;gt;
  &amp;lt;/xsl:template&amp;gt;

  &amp;lt;xsl:template match="level/level" &amp;gt;
    &amp;lt;h3&amp;gt;&amp;lt;xsl:value-of select="title" /&amp;gt;&amp;lt;/h3&amp;gt;
    &amp;lt;xsl:apply-templates/&amp;gt;
  &amp;lt;/xsl:template&amp;gt;

  &amp;lt;xsl:template name="title-with-locator" &amp;gt;
    &amp;lt;xsl:text&amp;gt;
    &amp;lt;/xsl:text&amp;gt;
    &amp;lt;xsl:choose&amp;gt;
      &amp;lt;xsl:when test="generate-id( . ) = $page-id" &amp;gt;
        &amp;lt;b&amp;gt;&amp;lt;xsl:call-template name="title-alone" /&amp;gt;&amp;lt;/b&amp;gt;
      &amp;lt;/xsl:when&amp;gt;
      &amp;lt;xsl:otherwise&amp;gt;
        &amp;lt;xsl:call-template name="title-alone" /&amp;gt;
      &amp;lt;/xsl:otherwise&amp;gt;
    &amp;lt;/xsl:choose&gt;
  &amp;lt;/xsl:template&gt;

  &amp;lt;xsl:template name="title-alone" &gt;
    Title: &amp;lt;xsl:value-of select="title" /&gt;
  &amp;lt;/xsl:template&gt;

&amp;lt;/xsl:stylesheet&amp;gt;
&lt;/pre&gt;&lt;p&gt;Finally, this is how the rendering looks like:&lt;br /&gt;
&lt;/p&gt;&lt;img src=http://lh5.ggpht.com/_c-k7nfw_Y8o/TORP8b2HyQI/AAAAAAAAAPQ/hCIvs65Rk5o/s800/rendering.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-605962560588959243?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/605962560588959243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=605962560588959243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/605962560588959243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/605962560588959243'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/xsl-mockup-for-multipage-rendering.html' title='XSL mockup for multipage rendering'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_c-k7nfw_Y8o/TORP8b2HyQI/AAAAAAAAAPQ/hCIvs65Rk5o/s72-c/rendering.png&quot;' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6123544451411730350</id><published>2010-11-13T22:51:00.001+01:00</published><updated>2010-11-13T22:51:09.267+01:00</updated><title type='text'>Novelang-0.52.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.52.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Added &lt;code &gt;n:block-inside-asterisk-pairs&lt;/code&gt;. Default stylesheet render it as bold.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6123544451411730350?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6123544451411730350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6123544451411730350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6123544451411730350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6123544451411730350'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0520-released.html' title='Novelang-0.52.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1588776398837461940</id><published>2010-11-13T21:16:00.002+01:00</published><updated>2010-11-13T21:19:41.696+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grammar'/><title type='text'>Grammar pattern: twin delimiters</title><content type='html'>&lt;p&gt;This post describes a tricky point of Novelang&amp;rsquo;s grammar design: how to handle twin delimiters like &lt;code&gt;//&lt;/code&gt; in a non-ambiguous manner for an ANTLR grammar. It&amp;rsquo;s a useful refresh before adding long-awaited &lt;code&gt;**&lt;/code&gt; (asterisk pair) delimiter.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;The problem&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For paired delimiters like &lt;code&gt;(&lt;/code&gt; and &lt;code&gt;)&lt;/code&gt; or &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; it&amp;rsquo;s easy to know when to &amp;ldquo;open&amp;rdquo; or &amp;ldquo;close&amp;rdquo; a block, and support nested blocks. In contrast, a twin delimiter is an opening one if not preceded by a closing one inside the same block, regardless of what happens in subblocks. This is a complicated way to say we support this kind of nesting:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;// block-1 ( block-2 //block-3// ) //

+ block-inside-solidus-pairs
    block-1
  + block-inside-parenthesis
      block-2
    + block-inside-solidus-pairs
        block-3
&lt;/pre&gt;&lt;p&gt;We also support this:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;block-1 // block-2 // block-3 // block-4 //

  block-1
+ block-inside-solidus-pairs
    block-2
  block-3
+ block-inside-solidus-pairs
    block-4
&lt;/pre&gt;&lt;p&gt;(We have only one level of nesting here. 2 levels of nesting is counter-intuitive and would have required very complex lookahead.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;The pattern&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The pattern is to define special grammatical elements when inside a block defined by a twin delimiter, to propagate this element cannot appear again, unless inside some other subblock.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Taking &amp;ldquo;XXX&amp;rdquo; for the name of some twin delimiter, here is a simplified version of the grammar for spreadblocks. The term &amp;ldquo;spreadblock&amp;rdquo; stands for a block that may spread on several lines (containing single line breaks).&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;paragraph
  : ... mixedDelimitedSpreadblock
  ;

mixedDelimitedSpreadblock
  : word ( punctuationSign | delimitedSpreadblock ) ...

delimitedSpreadblock
  : xxxSpreadblock
  : parenthesizedSpreadblock
  | squareBracketsSpreadblock
  | doubleQuotedSpreadblock
  | hyphenPairSpreadblock
  ;

parenthesizedSpreadblock  
  : '(' spreadblockBody ')' // Same for other paired delimiters.
  ;

spreadblockBody
  : ... mixedDelimitedSpreadblock
  ;

xxxSpreadblock
  : XXX spreadblockBodyNoXxx XXX
  ;

spreadblockBodyNoXxx
  : ... mixedDelimitedSpreadblockNoXxx ...
  ;

mixedDelimitedSpreadblockNoXxx
  : ... delimitedSpreadblockNoXxx ...
  ;

delimitedSpreadblockNoXxx
  : parenthesizedSpreadblock
  | squareBracketsSpreadblock
  | doubleQuotedSpreadblock
  | hyphenPairSpreadblock
  ;
&lt;/pre&gt;&lt;p&gt;This is more or less the same for tightblocks. &amp;ldquo;Tightblocks&amp;rdquo; stand for blocks containing no line breaks, like cells and embedded lists.&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;acell  // Same for embedded list items.
  : ... mixedDelimitedTightblock ..
  ;

mixedDelimitedTightblock
  : word ( punctuationSign | delimitedTightblock | ... ) ...
  : word ( punctuationSign | delimitedSpreadblock | ... ) ...
  ;

delimitedTightblock
  : xxxTightblock
  | parenthesizedTightblock
  | squareBracketsTightblock
  | doubleQuotedTightblock
  | hyphenPairTightblock
  ;

xxxTightblock
  : XXX tightblockBodyNoXxx XXX
  ;

tightblockBodyNoXxx
  : ... mixedDelimitedTightblockNoXxx ...
  ;

mixedDelimitedTightblockNoXxx
  : word ( punctuationSign | delimitedTightblockNoXxx ) ...
  ;

delimitedTightblockNoXxx
  : parenthesizedTightblock 
  | squarebracketsTightblock
  | doubleQuotedTightblock
  | hyphenPairTightblock
  ; // That's all.
&lt;/pre&gt;&lt;p&gt;Thought it is over? There is another kind of block, the &lt;code&gt;delimitedTightblockNoSeparator&lt;/code&gt; used inside the &lt;code&gt;subblockAfterTilde&lt;/code&gt; which reflects each block inside &lt;code&gt;~x~y~z&lt;/code&gt;! But at this point you probably got the idea.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Yes this makes the grammar quite verbose, but factoring it would reduce ANTLR&amp;rsquo;s ability to check for inconsistencies. Anyways, the slightest addition brings the need of writing test cases for every logical path inside each ANTLR grammar rule.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1588776398837461940?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1588776398837461940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1588776398837461940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1588776398837461940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1588776398837461940'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/grammar-pattern-twin-delimiters.html' title='Grammar pattern: twin delimiters'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7752692440872701912</id><published>2010-11-07T19:01:00.001+01:00</published><updated>2010-11-07T19:01:04.752+01:00</updated><title type='text'>Novelang-0.51.1 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.51.1! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Upgraded from FOP-0.95 to &lt;a href="http://xmlgraphics.apache.org/fop/1.0/releaseNotes_1.0.html" &gt;FOP-1.0&lt;/a&gt;. FOP is the library for generating PDF documents.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Various other library upgrades that shouldn&amp;rsquo;t affect normal users.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7752692440872701912?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7752692440872701912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7752692440872701912' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7752692440872701912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7752692440872701912'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0511-released.html' title='Novelang-0.51.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1802686476046014415</id><published>2010-11-06T21:00:00.001+01:00</published><updated>2010-11-06T21:00:20.939+01:00</updated><title type='text'>Novelang-0.51.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.51.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed: list with double hyphen and number sign was using a &amp;ldquo;plus sign&amp;rdquo; everywhere (source documents and XML elements). This might break existing documents and stylesheet using this brand new feature.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1802686476046014415?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1802686476046014415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1802686476046014415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1802686476046014415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1802686476046014415'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0510-released.html' title='Novelang-0.51.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7709495752293964149</id><published>2010-11-06T15:30:00.000+01:00</published><updated>2010-11-06T15:31:25.865+01:00</updated><title type='text'>Novelang-0.50.2 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.50.2! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed: support paragraphs as lists (&lt;code &gt;n:list-with-triple-hyphen&lt;/code&gt; and &lt;code &gt;n:list-with-double-hyphen-and-plus-sign&lt;/code&gt;) inside &lt;code &gt;n:paragraphs-inside-angled-bracket-pairs&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7709495752293964149?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7709495752293964149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7709495752293964149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7709495752293964149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7709495752293964149'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0502-released.html' title='Novelang-0.50.2 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-732997757511285186</id><published>2010-11-06T13:54:00.001+01:00</published><updated>2010-11-06T13:54:31.262+01:00</updated><title type='text'>Novelang-0.50.1 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.50.1! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Minor fix on &lt;code &gt;JavaShell&lt;/code&gt; for cleaner shutdown when there is no default &lt;code &gt;JmxKit&lt;/code&gt;. This only may affect users of Novelang-attirail subproject.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Fixed documentation generation where release notes for SNAPSHOT versions appeared for non-SNAPSHOT versions.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-732997757511285186?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/732997757511285186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=732997757511285186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/732997757511285186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/732997757511285186'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0501-released.html' title='Novelang-0.50.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-639025289981630166</id><published>2010-11-05T22:48:00.001+01:00</published><updated>2010-11-05T22:48:28.460+01:00</updated><title type='text'>Novelang-0.50.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.50.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Embedded numbered lists (&lt;code &gt;n:embedded-list-with-number-sign&lt;/code&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Paragraphs as numbered lists (&lt;code &gt;n:list-with-double-hyphen-and-plus-sign&lt;/code&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Switched to Maven&amp;nbsp;3. This required no change but future build features may not work with formerly-used Maven&amp;nbsp;2.2.1.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-639025289981630166?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/639025289981630166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=639025289981630166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/639025289981630166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/639025289981630166'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/11/novelang-0500-released.html' title='Novelang-0.50.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3522076629050329750</id><published>2010-10-30T20:59:00.001+02:00</published><updated>2010-10-30T20:59:56.361+02:00</updated><title type='text'>Novelang-0.49.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.49.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;In default stylesheet for HTML and PDF, the first &lt;code &gt;n:cell-row&lt;/code&gt; element renders as a table header, if there is more than one. This might break existing documents.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3522076629050329750?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3522076629050329750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3522076629050329750' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3522076629050329750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3522076629050329750'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/novelang-0490-released.html' title='Novelang-0.49.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5843352053733645675</id><published>2010-10-30T20:36:00.006+02:00</published><updated>2011-02-03T20:46:24.213+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Maven cheat sheet (update)</title><content type='html'>&lt;p&gt;This is an update of &lt;a href="http://novelang.blogspot.com/2010/07/maven-cheat-sheet-0442.html"&gt;previous Maven cheat sheet&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;mvn -e --batch-mode clean release:prepare -Dnovelang.build.distribution -DreleaseVersion=M.m.f &gt; build-release-prepare.log

mvn release:perform -Dnovelang.build.distribution -DreleaseVersion=M.m.f &gt; build-release-perform.log
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5843352053733645675?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5843352053733645675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5843352053733645675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5843352053733645675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5843352053733645675'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/maven-cheat-sheet-0470.html' title='Maven cheat sheet (update)'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4788763081404382657</id><published>2010-10-25T05:47:00.001+02:00</published><updated>2010-10-25T05:47:41.158+02:00</updated><title type='text'>Novelang-0.48.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.48.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed startup option in documentation.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Tags and location for lines of literal. Required an intermediate &lt;code &gt;n:raw-lines&lt;/code&gt; element nested inside &lt;code &gt;n:lines-of-literal&lt;/code&gt;. This might break existing stylesheets.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Location for cell rows with vertical line.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4788763081404382657?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4788763081404382657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4788763081404382657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4788763081404382657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4788763081404382657'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/novelang-0480-released.html' title='Novelang-0.48.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4659251284327216719</id><published>2010-10-13T10:42:00.000+02:00</published><updated>2010-10-13T10:42:04.878+02:00</updated><title type='text'>Random text generator for French</title><content type='html'>&lt;p&gt;This is &lt;a href="http://enneagon.org/phrases" &gt;a cool one&lt;/a&gt;. As it takes random phrases from classical French litteracy, punctuation signs and "typographic grey" look natural.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4659251284327216719?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4659251284327216719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4659251284327216719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4659251284327216719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4659251284327216719'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/random-text-generator-for-french.html' title='Random text generator for French'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2703458310624453019</id><published>2010-10-07T12:00:00.000+02:00</published><updated>2010-10-07T12:00:18.620+02:00</updated><title type='text'>Cheatsheet template</title><content type='html'>&lt;p&gt;Wikipedia definitely offers the right &lt;a href="http://upload.wikimedia.org/wikipedia/commons/0/05/Cheatsheet-en.pdf"&gt; template &lt;/a&gt; for a cheat sheet. Short and easy to render with Novelang.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2703458310624453019?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2703458310624453019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2703458310624453019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2703458310624453019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2703458310624453019'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/cheatsheet-template.html' title='Cheatsheet template'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3125751688415948805</id><published>2010-10-04T17:56:00.001+02:00</published><updated>2010-10-04T17:56:38.323+02:00</updated><title type='text'>Novelang-0.47.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.47.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Feature removal: relative identifier. Never used, and would make &lt;a href="http://novelang.blogspot.com/2010/09/technical-study-multi-page-html.html" &gt;multipage rendering&lt;/a&gt; much more complicated.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Small enhancements to Novelang-attirail, the reusable library.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3125751688415948805?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3125751688415948805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3125751688415948805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3125751688415948805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3125751688415948805'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/10/novelang-0470-released.html' title='Novelang-0.47.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3039399650206145037</id><published>2010-09-20T05:59:00.002+02:00</published><updated>2010-11-14T08:57:29.213+01:00</updated><title type='text'>Technical study: multi-page HTML rendering</title><content type='html'>&lt;p&gt;&lt;b&gt;What we need&lt;/b&gt;&lt;/p&gt;&lt;p&gt;How hard would that be to render a single Novelang document over multiple HTML pages? Better ask: how cool would that be? Think about Novelang documentation taking one single huge page. This makes non-linear reading quite uncomfortable. Of course, multi-page rendering should work for both batch and interactive mode.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Technical implications&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For batch rendering, there can be a simple approach. Xalan (XSLT rendering engine) offers the &lt;a href="http://xml.apache.org/xalan-j/extensionslib.html#redirect"&gt; redirect extension &lt;/a&gt; for redirecting output into a given file.&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;xsl:template match="/doc/foo"&amp;gt;
  &amp;lt;redirect:write select="@file"&gt;
    &amp;lt;foo-out&gt;
      &amp;lt;xsl:apply-templates/&gt;
    &amp;lt;/foo-out&gt;
  &amp;lt;/redirect:write&gt;
&amp;lt;/xsl:template&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately, this is not suitable for interactive rendering. For interactive rendering, the endering process must known both:
&lt;ul&gt;&lt;li&gt;The requested page, through a URL aware of the page (as sub-part of the whole document).&lt;/li&gt;
&lt;li&gt;The whole document, because we may need to render links to other chapters or whatever.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;p&gt;The same need arises for batch rendering but with Xalan&amp;rsquo;s Redirect extension mentioned above, the whole logic gets buried inside the XSLT (which probably makes it quite complex).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Obviously, we need a Renderer to work the same way for batch and interactive rendering, e. g. there should be no special handling of interactive or batch rendering in the XSL stylesheet. (But multi-page rendering would require a special stylesheet anyways, at least for generating navigation.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;While XSLT-based rendering is the most common case in Novelang, it&amp;rsquo;s better to think about the general contract of a &lt;code&gt;org.novelang.rendering.Renderer&lt;/code&gt;. As it already does, the Renderer should spit bytes into a &lt;code&gt;java.io.OutputStream&lt;/code&gt; with no knowledge wether it is a file or a socket. The job of creating the output (which means chosing a file name in the case of batch rendering) is left to some upstream object opening the &lt;code&gt;OutputStream&lt;/code&gt;. Currently, this is done by &lt;code&gt;org.novelang.batch.DocumentGenerator&lt;/code&gt; or &lt;code&gt;org.novelang.daemon.DocumentHandler&lt;/code&gt; which both end by calling &lt;code&gt;DocumentProducer&lt;/code&gt;, passing it the &lt;code&gt;OutputStream&lt;/code&gt;.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;So rendering stage needs additional logic. Interactive rendering implies to extract the requested page from the URL. Batch rendering implies to find the list of pages to create corresponding files on the filesystem.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;New Renderer contract&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There can&amp;rsquo;t be unique way to split a document into pages, so we have new responsabilties for our Renderer:Given a document tree (as a &lt;code&gt;org.novelang.common.SyntacticTree&lt;/code&gt;) it calculates a list of page identifiers.Given the same document tree, plus a page identifier, it renders the corresponding page to an &lt;code&gt;OutputStream&lt;/code&gt;.With something like a single empty page identifier, we should get the same single-page rendering as we have now.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;For an XSLT-based Renderer, we should embed page identifiers generation in the same XSL stylesheet (as a part of already-discussed &lt;a href="http://novelang.blogspot.com/2008/09/opening-access-to-fop-configuration.html"&gt; stylesheet metadata &lt;/a&gt;):&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet [namespaces blah blah] &gt;

  &amp;lt;nlm:multipage&gt;
    &amp;lt;!-- 
      Some XSL tranformations here,
      starting from &lt;n:opus&gt; element. 
    --&amp;gt;
  &amp;lt;/nlm:multipage&gt;

  ...&lt;/pre&gt;&lt;p&gt;Before page rendering occurs, Novelang asks the Renderer for page identifiers. The default XSL-based Renderer applies the content of the &lt;code&gt;&lt;nlm:multipage&gt;&lt;/code&gt; element (if there is one) as a stylesheet &lt;em&gt;on the whole document tree&lt;/em&gt;. Then it obtains a list of page identifiers as follows:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;pages&gt;
  &amp;lt;page name="Home" &gt;/n:opus&lt;/page-identifier&gt;
  &amp;lt;page name="ChapterOne" &gt;/n:opus/n:level[1]&lt;/page-identifier&gt;
  &amp;lt;page name="ChapterTwo" &gt;/n:opus/n:level[2]&lt;/page-identifier&gt;
&amp;lt;pages&gt;&lt;/pre&gt;&lt;p&gt;Of course each page name is unique. In order to achieve this with no tweak, the document tree may embed unique identifiers by extending the semantic of &lt;code&gt;n:implicit-identifier&lt;/code&gt; or by adding a new &lt;code&gt;n:unique-identifier&lt;/code&gt; element. Node paths seem easy to &lt;a href="http://www.dpawson.co.uk/xsl/sect2/N6077.html#d8278e153"&gt; generate &lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Now for each page, Novelang creates the corresponding file out of the page name. If the stylesheet in the &lt;code&gt;&lt;/nlm:multipage&gt;&lt;/code&gt; did chose filesystem-friendly names, those will be used verbatim (otherwise we may apply some variant of URL encoding). And, for each page, Novelang calls the Renderer with the whole document tree again, and passes additional metadata elements to tell the Renderer which page it is rendering. Input XML looks like this:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&amp;lt;n:opus&gt;
  &amp;lt;n:meta&gt;
    &amp;lt;n:page-name&gt;ChapterOne&lt;/n:page-name&gt;
    &amp;lt;n:page-path&gt;/n:opus/n:level[1]&lt;/n:page-path&gt;
  &amp;lt;/n:meta&gt;
&amp;lt;/n:opus&gt;&lt;/pre&gt;&lt;p&gt;This should be enough for the Renderer to figure how to render only the page of interest. It might need to peek elsewhere in the document tree (like for a footer with a copyright notice, or find other chapter names for a navigation bar).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Mix with other features (present or future)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There is an additional role for node identifiers: they might help to &amp;ldquo;enhance&amp;rdquo; internal links by adding the prefix corresponding to the target page. (The internal link feature is yet in inception phase. It just seems easier to implement it right after multipage rendering.)&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Unique page names&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Novelang&amp;rsquo;s Fragment Identifier is the perfect candidate to generate page identifers. Unfortunately, composite identifier contain the &lt;code&gt;\&lt;/code&gt; character. Should we escape it, or mix it with some weird pseudo-directory feature? But maybe it&amp;rsquo;s time to remove relative identifiers which never proved useful, and don&amp;rsquo;t guarantee identifer uniqueness, anyways.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;It&amp;rsquo;s easy to create a new &lt;code&gt;&lt;n:unique-identifier&gt;&lt;/code&gt; element by adding a simple counter to a colliding identifier. The &lt;code&gt;&lt;n:unique-identifier&gt;&lt;/code&gt; value for some given document fragment may change across several generations, when adding fragments with colliding identifiers. This won&amp;rsquo;t be a problem for internal links (links defined by the document itself) prohibit usage of unique identifier. Remember: unique identifiers are only for pure HTML links.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;If there is a chance that a foreign HTML documents links to the HTML anchor defined by the unique identifier (in a pure WWWW &amp;ndash;&amp;nbsp;World Wide Web Way) then document author should use explicit identifiers.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;New URL scheme&lt;/b&gt;&lt;/p&gt;&lt;p&gt;With single-page rendering, the rendered document has the same name as the source document (with the difference of the extension). Multi-page adds a new &amp;ldquo;dimension&amp;rdquo;. Because the name of the page may collide with another document&amp;rsquo;s name, the name of the originating document prefixes the page name. Let&amp;rsquo;s look at different options:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;/main/documentation~syntax.html
/main/documentation!syntax.html
/main/documentation,syntax.html
/main/documentation^syntax.html
/main/documentation--syntax.html
&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s see which character we could use (only checked on Mac OS X, to do: check on Windows):&lt;br /&gt;
&lt;/p&gt;&lt;table&gt;&lt;tr&gt; &lt;td&gt; Character &lt;/td&gt; &lt;td&gt; Escaped? &lt;/td&gt; &lt;td&gt; Comments &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;~&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Already used for Novelang meta pages. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;-&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Already used for Novelang identifiers. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;^&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Meaningless in that context. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;#&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Fragment in URL. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;,&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Hard to distinguish from full stop &lt;code&gt;.&lt;/code&gt; character. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;!&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Hard to read. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;_&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Too common in file names. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;+&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Used in URL encoding. Usage unrelated to &amp;ldquo;plus&amp;rdquo; meaning. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;%&lt;/code&gt; &lt;/td&gt; &lt;td&gt; No &lt;/td&gt; &lt;td&gt; Used in URL encoding. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;=&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Used in URL encoding. Usage unrelated to &amp;ldquo;equality&amp;rdquo; meaning. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;$&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Overused. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;;&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Hard to read. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;|&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Hard to read. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;'&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Hard to read. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;&amp;&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Already used for URL parameters. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;?&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Already used for URL parameters, DOS wildcard. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;@&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Inverted meaning if page name appears second. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;{&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Weird because unpaired. Meaningful otherwise. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;§&lt;/code&gt; &lt;/td&gt; &lt;td&gt; Yes &lt;/td&gt; &lt;td&gt; Mac OS X console doesn&amp;rsquo;t like it. &lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt; &lt;code&gt;:&lt;/code&gt; &lt;/td&gt; &lt;td&gt; - &lt;/td&gt; &lt;td&gt; Path separator on Unix. &lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;The &amp;ldquo;Escaped?&amp;rdquo; column means, it requires escaping on Mac OS X console.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Finally, it turns out that &lt;code&gt;--&lt;/code&gt; looks the best, especially with a variable-width font like in Mac OS X Finder or Windows Explorer.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Special case: if the page identifier was blank, the page separator doesn&amp;rsquo;t appear so we would still have:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;/main/documentation.html
&lt;/pre&gt;&lt;p&gt;This naming scheme also implies that all pages appear flatly in the same directory. This should help when resolving resource names.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3039399650206145037?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3039399650206145037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3039399650206145037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3039399650206145037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3039399650206145037'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/09/technical-study-multi-page-html.html' title='Technical study: multi-page HTML rendering'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3116044324158292538</id><published>2010-09-04T17:45:00.001+02:00</published><updated>2010-09-04T17:45:57.792+02:00</updated><title type='text'>Novelang-0.46.1 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.46.1! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Added source packaging for Novelang-attirail subproject.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3116044324158292538?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3116044324158292538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3116044324158292538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3116044324158292538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3116044324158292538'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/09/novelang-0461-released.html' title='Novelang-0.46.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1257053352288357443</id><published>2010-08-29T10:10:00.002+02:00</published><updated>2010-10-04T10:34:00.510+02:00</updated><title type='text'>Novelang-0.46.0 released!</title><content type='html'>&lt;p &gt;Just released Novelang-0.46.0! &lt;/p&gt;&lt;p &gt;Summary of changes: &lt;/p&gt;&lt;p &gt;New experimental features for code reuse: &lt;/p&gt;&lt;ul &gt;&lt;li &gt;Novelang-attirail subproject aggregating various tools. It&amp;rsquo;s not part of standard distribution, by now it requires separate rebuild.&lt;/li&gt;
&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Pluggable logging implementation.&lt;/li&gt;
&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Java code all under &lt;code &gt;org.novelang&lt;/code&gt; package (was &lt;code &gt;novelang&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;p &gt;Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt;&lt;p &gt;Enjoy! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1257053352288357443?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1257053352288357443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1257053352288357443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1257053352288357443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1257053352288357443'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/novelang-0460-released.html' title='Novelang-0.46.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4305675932535138054</id><published>2010-08-27T12:16:00.001+02:00</published><updated>2010-08-27T12:16:41.325+02:00</updated><title type='text'>Novelang-0.45.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.45.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Added Greek and Polish characters to the grammar.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4305675932535138054?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4305675932535138054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4305675932535138054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4305675932535138054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4305675932535138054'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/novelang-0450-released.html' title='Novelang-0.45.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4609980714666665706</id><published>2010-08-08T18:08:00.001+02:00</published><updated>2010-08-08T18:08:57.219+02:00</updated><title type='text'>Novelang-0.44.5 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.44.5! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed release notes generation.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4609980714666665706?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4609980714666665706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4609980714666665706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4609980714666665706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4609980714666665706'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/novelang-0445-released_08.html' title='Novelang-0.44.5 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2472284991050916196</id><published>2010-08-08T17:12:00.003+02:00</published><updated>2010-08-08T17:19:17.533+02:00</updated><title type='text'>Novelang-0.44.4 released!</title><content type='html'>&lt;p &gt;Just released Novelang-0.44.4! &lt;/p&gt;&lt;p &gt;Summary of changes: &lt;/p&gt;&lt;ul &gt;&lt;li &gt;Fixed a few references to old "Part" and "Book" terms, and file suffixes as well.&lt;/li&gt;
&lt;/ul&gt;&lt;p &gt;Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt;&lt;p &gt;Enjoy! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2472284991050916196?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2472284991050916196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2472284991050916196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2472284991050916196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2472284991050916196'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/novelang-0444-released.html' title='Novelang-0.44.4 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3852589572343302202</id><published>2010-08-08T16:02:00.002+02:00</published><updated>2010-08-08T16:02:51.382+02:00</updated><title type='text'>Script for renaming to new extensions</title><content type='html'>&lt;p&gt;Here is a Bash script (tested on Mac OS X) that renames every &lt;code&gt;.nlp&lt;/code&gt; into &lt;code&gt;.novella&lt;/code&gt; and &lt;code&gt;.nlb&lt;/code&gt; into &lt;code&gt;.opus&lt;/code&gt;. It also changes file content. Use with care.&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;#!/bin/sh

SED='s/\.nlp/\.novella/g;s/\.nlb/\.opus/g'
for file in `find src modules \( -name *.nlp -o -name *.nlb \) `
do
  newfile=` echo "$file" | sed $SED `
  echo "$file -&gt; $newfile"
  sed $SED &lt; $file &gt; $newfile
  rm $file
done
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3852589572343302202?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3852589572343302202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3852589572343302202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3852589572343302202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3852589572343302202'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/script-for-renaming-to-new-extensions.html' title='Script for renaming to new extensions'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5075672100435006198</id><published>2010-08-07T10:51:00.001+02:00</published><updated>2010-08-07T10:51:37.812+02:00</updated><title type='text'>Novelang-0.44.3 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.44.3! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed Nhovestone report generation.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5075672100435006198?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5075672100435006198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5075672100435006198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5075672100435006198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5075672100435006198'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/08/novelang-0443-released.html' title='Novelang-0.44.3 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7527678888219704443</id><published>2010-07-25T22:49:00.005+02:00</published><updated>2011-01-03T22:43:20.383+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Maven cheat sheet (0.44.2)</title><content type='html'>&lt;p&gt;There is an &lt;a href="../../2010/10/maven-cheat-sheet-0470.html" &gt;updated version&lt;/a&gt; of this post.&lt;/p&gt;

&lt;p&gt;This is a list of useful Maven commands. They work with Novelang-0.44.2. Later version will probably make some of them less verbose, using some default parameters.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Convention: the &lt;code&gt;Novelang/$&lt;/code&gt; represents the command prompt, with working directory being Novelang&amp;rsquo;s home directory. Subdirectories appear when needed.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Plugin versions&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Stay up-to-date by listing more recent plugins (there is another goal for dependencies):&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn versions:display-plugin-updates
&lt;/pre&gt;&lt;p&gt;Show dependency tree:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn dependency:tree
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Feed local repository with fresh artifacts&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn clean install 
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Force child modules version&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Force the version of every child module to the one of the parent:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn -N versions:update-child-modules
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Performing a release (may be specific to Novelang-0.44.2)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;First, clean previous POM backup files:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn release:clean
&lt;/pre&gt;&lt;p&gt;Then prepare the release. This does the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Check VCS state. Includes: no uncommitted file; remote repository sync&amp;rsquo;ed with local.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Change the POM versions to release version (shown as &lt;code&gt;M.m.f&lt;/code&gt; in the snippet below).&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Run the build, using declared &lt;code&gt;&lt;preparationgoals&gt;&lt;/code&gt;.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Commit changed POMs to local SCM.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Tag the SCM locally.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Pushes the changes on remote repository, including tags (failing on a conflict).&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Revert SCM versions to development version.&lt;br /&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;pre&gt;Novelang/$ mvn -e --batch-mode release:prepare -Drelease=false -DlocalCheckout=true -DreleaseVersion=M.m.f -DdevelopmentVersion=SNAPSHOT -Dtag=release-M.m.f &gt; build-release-prepare.log
&lt;/pre&gt;&lt;p&gt;This part is likely to fail. If something goes wrong: &lt;ul&gt;&lt;li&gt;Reset git in the &lt;code&gt;--hard&lt;/code&gt; way, to the version immediately before Maven&amp;rsquo;s changes.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Delete &lt;code&gt;release-M.m.f&lt;/code&gt; tag local git repository.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Delete &lt;code&gt;release-M.m.f&lt;/code&gt; tag on remote git repository: &lt;code&gt;git push -v github :refs/tags/release-M.m.f&lt;/code&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Force synchronization between local git repository and remote one. This may be done by committing an innocuous change, then pushing it with &lt;code&gt;--force&lt;/code&gt; option (better idea, anyone?).&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Call again: &lt;code&gt;Novelang/$ mvn release:clean&lt;/code&gt;Get sure that&amp;rsquo;s everything OK with gitk.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;
Might be useful to reset all POM version (like after some POM or branch hacking): set root &lt;code&gt;pom.xml&lt;/code&gt; version to &lt;code&gt;SNAPSHOT&lt;/code&gt; and run &lt;code&gt;mvn versions:update-child-modules&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;Once this is done, our git repositories contain good, tagged stuff. Last step is to perform the final build. &lt;/p&gt;&lt;pre&gt;Novelang/$ mvn release:perform &gt; build-release-perform.log
&lt;/pre&gt;&lt;p&gt;(There is no additional parameter to pass; the &lt;code&gt;release.prepare&lt;/code&gt; did create some POM copies with relevant information.) &lt;/p&gt;&lt;p&gt;The &lt;code&gt;release.perform&lt;/code&gt; goal performs a fresh checkout in &lt;code&gt;Novelang/target/checkout&lt;/code&gt; where all the &lt;code&gt;pom.xml&lt;/code&gt; contain expected &lt;code&gt;M.m.f&lt;/code&gt; version. The build calls the &lt;code&gt;deploy:deploy&lt;/code&gt; on &lt;code&gt;Novelang-documentation&lt;/code&gt; and &lt;code&gt;Novelang-distribution&lt;/code&gt; which upload relevant files on SourceForge and send email notifications. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Useful links&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.sonatype.com/books/mvnref-book/reference/appendix-settings-sect-encrypting-passwords.html"&gt; Using master password. &lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://maven.apache.org/guides/mini/guide-releasing.html"&gt; Mini-guide &lt;/a&gt; about Maven release plugin. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Untested&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Resume from a give module folder instead of restarting the build since the beginning: &lt;/p&gt;&lt;pre&gt;Novelang/$ mvn reactor:resume -Dfrom=bar 
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7527678888219704443?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7527678888219704443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7527678888219704443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7527678888219704443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7527678888219704443'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/07/maven-cheat-sheet-0442.html' title='Maven cheat sheet (0.44.2)'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1970489631163425132</id><published>2010-07-25T21:43:00.001+02:00</published><updated>2010-07-25T21:43:19.323+02:00</updated><title type='text'>Novelang-0.44.2 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.44.2! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Another fix for a build problem. Now the &lt;code &gt;deploy:deploy&lt;/code&gt; goal should work properly when called from &lt;code &gt;release:perform&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1970489631163425132?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1970489631163425132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1970489631163425132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1970489631163425132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1970489631163425132'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/07/novelang-0442-released.html' title='Novelang-0.44.2 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7095511394108974624</id><published>2010-07-25T21:08:00.001+02:00</published><updated>2010-07-25T21:08:19.541+02:00</updated><title type='text'>Novelang-0.44.1 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.44.1! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Fixed build problem when deploying files and sending annoucements.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7095511394108974624?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7095511394108974624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7095511394108974624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7095511394108974624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7095511394108974624'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/07/novelang-0441-released.html' title='Novelang-0.44.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2695160607052721610</id><published>2010-07-24T23:11:00.001+02:00</published><updated>2010-07-24T23:11:57.601+02:00</updated><title type='text'>Novelang-0.44.0 released!</title><content type='html'>&lt;p &gt; Just released Novelang-0.44.0! &lt;/p&gt; &lt;p &gt; Summary of changes: &lt;/p&gt; &lt;ul &gt;&lt;li &gt;Renamed Part into Novella and Book into Opus. Nicer, clearer. New recommended file suffixes are &lt;code &gt;.novella&lt;/code&gt; and &lt;code &gt;.opus&lt;/code&gt;. Old &lt;code &gt;.nlp&lt;/code&gt; and &lt;code &gt;.nlb&lt;/code&gt; suffixes still supported.&lt;/li&gt;&lt;/ul&gt;&lt;ul &gt;&lt;li &gt;Switched build system from Ant to Maven. This should be transparent for users.&lt;/li&gt;&lt;/ul&gt;&lt;p &gt; Download it from &lt;a href="http://sourceforge.net/projects/novelang/files" &gt;here&lt;/a&gt;. &lt;/p&gt; &lt;p &gt; Enjoy! &lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2695160607052721610?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2695160607052721610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2695160607052721610' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2695160607052721610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2695160607052721610'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/07/novelang-0440-released.html' title='Novelang-0.44.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-487871657538409342</id><published>2010-06-26T00:03:00.000+02:00</published><updated>2010-06-26T00:03:32.439+02:00</updated><title type='text'>Syntax highlighter for HTML</title><content type='html'>The &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter" &gt;SyntaxHighlighter&lt;/a&gt; project looks nice. It has a "copy to clipboard" feature (implemented in Flash). With some additional hacking, this would save from keeping Novelang's nasty zero-width spaces added for correct line wrapping.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-487871657538409342?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/487871657538409342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=487871657538409342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/487871657538409342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/487871657538409342'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/06/syntax-highlighter-for-html.html' title='Syntax highlighter for HTML'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4667633413637024366</id><published>2010-06-19T08:55:00.000+02:00</published><updated>2010-06-19T08:55:32.663+02:00</updated><title type='text'>Zipper for faster tree modifications</title><content type='html'>&lt;p&gt;Novelang uses &lt;a href="http://github.com/caillette/novelang/tree/master/src/main/novelang/common/tree/" &gt;immutable trees&lt;/a&gt; to represent a document and transform it. While immutable data structure have well-known advantages, Novelang's tree library requires to update every parent node on each change on any child node. Clever guys found how to save those changes when performing multiple local modifications. This relies on a tree structure called &lt;b&gt;Zipper&lt;/b&gt;. Here is a &lt;a href="http://www.google.com/url?sa=D&amp;q=http%3A%2F%2Fblog.ezyang.com%2F2010%2F04%2Fyou-could-have-invented-zippers%2F" &gt;very clear explaination&lt;/a&gt;, the &lt;a href="http://www.google.com/url?sa=D&amp;q=http%3A%2F%2Fwww.st.cs.uni-saarland.de%2Fedu%2Fseminare%2F2005%2Fadvanced-fp%2Fdocs%2Fhuet-zipper.pdf" &gt;original paper&lt;/a&gt; (site currently down), the &lt;a href="http://www.google.com/url?sa=D&amp;q=http%3A%2F%2Fbiosimilarity.blogspot.com%2F2010%2F05%2Fhuets-zipper.html" &gt;Scala implementation&lt;/a&gt; and the &lt;a href="http://www.google.com/url?sa=D&amp;q=http%3A%2F%2Fgithub.com%2Frichhickey%2Fclojure%2Fblob%2Fmaster%2Fsrc%2Fclj%2Fclojure%2Fzip.clj" &gt;Clojure one&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4667633413637024366?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4667633413637024366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4667633413637024366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4667633413637024366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4667633413637024366'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/06/zipper-for-faster-tree-modifications.html' title='Zipper for faster tree modifications'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4234880580900142567</id><published>2010-05-30T19:24:00.002+02:00</published><updated>2010-05-30T19:43:39.934+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='font'/><title type='text'>Google's font directory</title><content type='html'>This is an &lt;a href="http://code.google.com/webfonts/"&gt;amazing initiative&lt;/a&gt; from Google: a directory for Web fonts. Fonts are available under SIL Open Font License 1.1. There are some beautiful fonts available, with a nice and clear browsing interface. One can download font sources from &lt;a href="http://code.google.com/p/googlefontdirectory/source/browse" &gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4234880580900142567?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4234880580900142567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4234880580900142567' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4234880580900142567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4234880580900142567'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/05/googles-fonts-directory.html' title='Google&apos;s font directory'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2622372074886565768</id><published>2010-04-26T23:04:00.001+02:00</published><updated>2010-04-26T23:04:49.369+02:00</updated><title type='text'>Novelang-0.43.0 released!</title><content type='html'>         Download Novelang-0.43.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Added &lt;code xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;nohead&lt;/code&gt; option to &lt;code xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;insert&lt;/code&gt; command.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed some bugs around identifiers.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Introduced detection of colliding explicit identifiers. This has no useful purpose for now but will serve as a basis for implementing internal links.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Small performance enhancement on HTML document rendering in a Web browser: don&amp;rsquo;t use JavaScript to set collapsible descriptors hidden.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2622372074886565768?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2622372074886565768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2622372074886565768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2622372074886565768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2622372074886565768'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/04/novelang-0430-released.html' title='Novelang-0.43.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7137576250926779391</id><published>2010-04-25T17:40:00.003+02:00</published><updated>2010-04-25T17:47:49.193+02:00</updated><title type='text'>MinorThird's Mixup</title><content type='html'>Could this be useful in Novelang? The &lt;a href="http://sourceforge.net/apps/trac/minorthird/wiki/MixupLanguage" &gt;Mixup language&lt;/a&gt; performs complex queries on pure text. It's "like a regex query, but while regex operates at character level, Mixup operates at token level."

Mixup is part of the &lt;a href="http://sourceforge.net/projects/minorthird/" &gt;MinorThird&lt;/a&gt; suite and available under BSD license.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7137576250926779391?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7137576250926779391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7137576250926779391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7137576250926779391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7137576250926779391'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/04/minorthirds-mixup.html' title='MinorThird&apos;s Mixup'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7450270802837440340</id><published>2010-04-22T21:57:00.000+02:00</published><updated>2010-04-22T22:02:10.060+02:00</updated><title type='text'>Novelang-0.42.0 released!</title><content type='html'>         Download Novelang-0.42.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Now requires Java 6.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;a xsltc-extension="http://xml.apache.org/xalan/xsltc" href="http://novelang.sf.net/nhovestone.pdf" &gt;Nhovestone&lt;/a&gt; report: Novelang has its own benchmark!&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Added stylesheet &lt;code xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;html-FR.xsl&lt;/code&gt; for French punctuation.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Performance enhancement on rendered HTML page: when containing many tags it should load faster. Instead of dynamically computing styles on the Web browser, HTML rendered by the server directly includes those styles.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Various performance enhancements on document generation. With the same amount of memory (&lt;code xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;-Xmx&lt;/code&gt; parameter), Novelang handles documents twice bigger and serves them 20&amp;nbsp;% faster than previous version. &lt;a xsltc-extension="http://xml.apache.org/xalan/xsltc" href="http://novelang.sourceforge.net/nhovestone.pdf" &gt;Benchmark&lt;/a&gt; ran against version 0.41.0 and 0.38.1. This includes buffered reading of Part files, multithreaded Part rendering, and reduced memory consumption when dealing with AST (Abstract Syntax Tree).&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7450270802837440340?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7450270802837440340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7450270802837440340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7450270802837440340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7450270802837440340'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/04/novelang-0420-released.html' title='Novelang-0.42.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6162951111641006805</id><published>2010-04-05T16:01:00.002+02:00</published><updated>2010-04-05T16:07:49.369+02:00</updated><title type='text'>Nhovestone</title><content type='html'>&lt;p&gt;
&amp;ldquo;Nhovestone&amp;rdquo; is the name of Novelang&amp;rsquo;s dedicated benchmark tool, and also a &lt;a href="http://en.wikipedia.org/wiki/Dhrystone"&gt; geeky pun &lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;

Nhovestone aims to highlight performance variations across versions using only a few (carefully selected) measurements:How does response time evolve when increasing the number of documents aggregated in a single Book?How does response time evolve when increasing the size of one single document?
&lt;/p&gt;&lt;p&gt;

Nhovestone doesn&amp;rsquo;t try to generate an absolute performance index. This is because such an index makes sense only when computed from always the same source documents and the same hardware.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How it works&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

Nhovestone focuses on HTML generation using default stylesheet, because HTML is great for fast edit-and-review roundtrips. It uses the &lt;a href="http://novelang.blogspot.com/2010/03/novelist-random-text-generation.html"&gt; Novelist &lt;/a&gt; to generate pseudo-random text with a realistic structure. For each benchmarked Novelang version, Nhovestone starts a JVM with a small amount of memory (currently &lt;code&gt;-Xmx32M&lt;/code&gt;). With few memory the breaking point appears sooner. Nhovestone increases the size of the source document(s) in a linear fashion, and after each increasing, measures how long takes the call of a Novelang instance.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Performance degradation&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

Response time start to increase exponentially as document becomes fairly big in regard of available memory. This triggers a lot of CPU-intensive garbage collection consuming a lot of time. Nhovestone detects that a running Novelang HTTP daemon gets &amp;ldquo;strained&amp;rdquo; when response time gets above a dynamically-computed threshold. The threshold comes from the straight line drawn from a &lt;a href="http://en.wikipedia.org/wiki/Linear_regression"&gt; linear regression &lt;/a&gt; on the first half of the measurements, with a slope made steeper by a fixed coefficient. When a response time appears above this straight line, the Novelang HTTP daemon got strained and it&amp;rsquo;s not worth any further measurement.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Adding Parts&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

This is the first scenario: for each new measurement, there is an additional Part file. All Parts are more or less equal in size and complexity (including level depth). The graph below shows that performance degradation stays linear until the 300&lt;sup&gt;th&lt;/sup&gt; call. Then, version 0.41.0 starts suffering before older versions. It&amp;rsquo;s likely that new features require additional memory so starvation occurs sooner.
&lt;/p&gt;
&lt;img src="http://lh6.ggpht.com/_c-k7nfw_Y8o/S7ntuQObQ_I/AAAAAAAAAOs/p5t3tL1Vqrs/s800/IncreasingNovellacount.png" /&gt;
&lt;p&gt;&lt;b&gt;Increasing the size of the same Part&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

This is the second scenario: the generated document comes from a single Part file of a size increasing before each call. Each fragment added to the Part has the same size and structure as in the previous test, but all 3 versions show fatigue much sooner (at least 7.5 times). This shows that creating a Part takes much more temporary memory than the finished Part itself.
&lt;/p&gt;
&lt;img src="http://lh6.ggpht.com/_c-k7nfw_Y8o/S7ntusx2ihI/AAAAAAAAAOw/chQ4o27TZb4/s800/SingleevergrowingNovella.png" /&gt;
&lt;p&gt;&lt;b&gt;Tuning&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

These figures are strongly connected to the volume and the structure of underlying document. Experience shows that small increments generate more measurements (before the fatal strain) and therefore show a more readable trend. They also reduce measurement artefacts that could fool strain detection.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Report generation&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;

&lt;a href="http://www.jfree.org/jfreechart"&gt; JFreeChart &lt;/a&gt; generates those graphs. JFreeChart is probably the best charting library for Java at this time, at least on the OSS marketplace. It is stable and highly configurable.
&lt;/p&gt;&lt;p&gt;

The next step: embed those graphs in a Novelang-generated PDF and publish it as a complement of existing documentation.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6162951111641006805?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6162951111641006805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6162951111641006805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6162951111641006805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6162951111641006805'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/04/nhovestone.html' title='Nhovestone'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_c-k7nfw_Y8o/S7ntuQObQ_I/AAAAAAAAAOs/p5t3tL1Vqrs/s72-c/IncreasingNovellacount.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1540902533310516477</id><published>2010-03-20T17:07:00.000+01:00</published><updated>2010-03-20T17:08:09.918+01:00</updated><title type='text'>The Novelist: random text generation</title><content type='html'>&lt;p&gt;
Novelang already does all the typesetting for you. What&amp;rsquo;s next? Writing text, of course! The just-started Novelist subproject, which aims to generate big documents for Novelang testing under heavy load.
&lt;/p&gt;&lt;p&gt;
Based on French metrics, random text looks like this:
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;
Uomuecto eaufues xuner ig ocanerr, ebanu otpaa. Uuse, on eian aibtd, rttaintlufe elvettarrh, yrn enemlcmlun, ebcazepuer madscg, êiiovemtt teeost eseeerde? Fetn eearréetcs emrseoss icia ntmvesrud. Aoasro cênit ctainetda aèugedet css eali, unero aaie eneoden, nrortio. Oovlod; tfsmenco méttsna, eesdis uoeaeanao rcuent, desungtt av au oneerao, dxuaste umeinétniu lccdeiilne rliùearde veyiritisac yàslu. Iinmseuo odiapqied cmiiapearlo ebnjtus uauueis, libginmasa edrc emaèi sllieyr sode!
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;
It bases on simplistic distribution algorithm. Word count and letter count from uniform distribution in a pre-defined range (something like 5-20 for words and 2-12 for letters). Letters come from a &lt;a href="http://en.wikipedia.org/wiki/Letter_frequency"&gt; frequency table &lt;/a&gt; giving the percentage of appearance for each letter.
&lt;/p&gt;&lt;p&gt;
While the result doesn&amp;rsquo;t look much like real text, it&amp;rsquo;s good enough to stress basic parsing and typesetting.
&lt;/p&gt;&lt;p&gt;
There has been a lot of research about text analysis, first for cryptography, next for natural language analysis and Web crawling. Among all of them, there is a nifty one: the &lt;a href="http://en.wikipedia.org/wiki/N-gram"&gt; n-grams &lt;/a&gt;, which describe all the different letter sequences of a fixed length in a given text. The &lt;a href="http://www.wolframalpha.com/input/?i=n-grams+%22Novelang+is+so+sexy+you+know%22"&gt; demo &lt;/a&gt; on Wolfram Alpha is gorgeous. It shows how combinations grow fast: a simple sentence like &amp;ldquo;ceramics come from&amp;rdquo; contains 69 3-grams. Google&amp;rsquo;s &lt;a href="http://www.ldc.upenn.edu/Catalog/CatalogEntry.jsp?catalogId=LDC2006T13"&gt; n-grams database &lt;/a&gt; (ranging from 1-grams to 5-grams) weights 24 GiB gzip&amp;rsquo;ed and contains near 1 billion of 3-grams. Amazingly, this number doesn&amp;rsquo;t increase so much for 4-grams and 5-grams.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1540902533310516477?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1540902533310516477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1540902533310516477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1540902533310516477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1540902533310516477'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/novelist-random-text-generation.html' title='The Novelist: random text generation'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3074349880113233727</id><published>2010-03-15T23:50:00.001+01:00</published><updated>2010-03-15T23:50:30.626+01:00</updated><title type='text'>Novelang-0.41.1 released!</title><content type='html'>         Download Novelang-0.41.1 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed bug with Promoted Tags, not detected under some circumstances.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3074349880113233727?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3074349880113233727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3074349880113233727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3074349880113233727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3074349880113233727'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/novelang-0411-released.html' title='Novelang-0.41.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4037459356871229180</id><published>2010-03-14T12:09:00.000+01:00</published><updated>2010-03-14T12:10:07.860+01:00</updated><title type='text'>Novelang-0.41.0 released!</title><content type='html'>         Download Novelang-0.41.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New feature: Promoted Tags. Implicit Tags matching Explicit Tags become Promoted Tags.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Support lines of literal inside paragraphs inside angled bracket pairs.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Minor enhancements on HTML default stylesheet.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4037459356871229180?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4037459356871229180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4037459356871229180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4037459356871229180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4037459356871229180'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/novelang-0410-released.html' title='Novelang-0.41.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5668156741064137417</id><published>2010-03-08T22:42:00.001+01:00</published><updated>2010-03-08T22:42:53.576+01:00</updated><title type='text'>Novelang-0.40.1 released!</title><content type='html'>         Download Novelang-0.40.1 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed display bug on generated documentation.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5668156741064137417?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5668156741064137417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5668156741064137417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5668156741064137417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5668156741064137417'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/novelang-0401-released.html' title='Novelang-0.40.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1688204904356705559</id><published>2010-03-08T22:22:00.001+01:00</published><updated>2010-03-08T22:22:10.348+01:00</updated><title type='text'>Novelang-0.40.0 released!</title><content type='html'>         Download Novelang-0.40.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Brand new stylesheet for HTML.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1688204904356705559?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1688204904356705559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1688204904356705559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1688204904356705559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1688204904356705559'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/novelang-0400-released.html' title='Novelang-0.40.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2439927185820352288</id><published>2010-03-03T22:11:00.004+01:00</published><updated>2010-03-03T22:23:06.014+01:00</updated><title type='text'>HTML default stylesheet improvements</title><content type='html'>&lt;p&gt;
A new default HTML stylesheet will be available soon. It should improve Novelang usability a lot. Key features are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A better look.&lt;/li&gt;
&lt;li&gt;Scaling up with metadata-oriented features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
If a picture is worth a thousand words:
&lt;/p&gt;

&lt;img src="http://lh3.ggpht.com/_c-k7nfw_Y8o/S47P6e377TI/AAAAAAAAAOE/8sIffTR7Wmc/s800/wholePage.png" /&gt;

&lt;p&gt;&lt;b&gt;Fluid layout&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
New layout supports horizontal resize. The column for rendered text may span from 500 to 1000 pixels.
&lt;/p&gt;&lt;p&gt;
Lines of literal (&lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; tag) wrap if they are too long. Because wrapping only occurs with the &lt;code&gt;white-space : pre-line&lt;/code&gt; style, which discards indentation by default. To prevent this, some JavaScript replaces every space character inside a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; by a non-brekable space, immediately followed by a zero-width space. This causes a clean-looking wrapping, but text copied in the clipboard has unwanted character.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Overall look&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Titles are indented. This is a compromise with the Descriptor feature (described later).
&lt;/p&gt;&lt;p&gt;
Line spacing is constant, even between two paragraphs, or between a paragraph and an embedded list. There is a slight loss of information (it may be hard to see where a paragraph begins) but this globally increases readability.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Fonts&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Font choice has a huge impact on overall look. Chosing fonts is hard stuff, because fonts rendering is
&lt;a href="http://www.ampsoft.net/webdesign-l/WindowsMacFonts.html"&gt; hardly the same&lt;/a&gt;
across Web browsers. Font readability also changes a lot, depending on line spacing, contrast, and other fonts around.
&lt;/p&gt;&lt;p&gt;
The convention is: serif font for rendered document, sans-serif for extra information like actions and tags. Literal (&lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;) shows with a fixed-with font, which is serif, too.
&lt;/p&gt;&lt;p&gt;
After experimenting with a lot of combinations, finally, the winners are:
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;
&lt;a href="http://en.wikipedia.org/wiki/Palatino"&gt;Palatino Linotye&lt;/a&gt;
for the rendered document. This gorgeous font is a bit more readable than Times New Roman. It&amp;rsquo;s available on all platform, and looks gorgeous with appropriate contrats (dark grey over light gray instead of black over white).
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp
&lt;a href="http://en.wikipedia.org/wiki/Lucida_Grande"&gt; Lucida Grande &lt;/a&gt;
with 
&lt;a href="http://en.wikipedia.org/wiki/Tahoma_(typeface)"&gt;Tahoma&lt;/a&gt;
as second choice.
Lucida Grande is highly readable (was chosen as default for Mac OS X), but sophisticated enough to not look &amp;ldquo;poor&amp;rdquo; aside Palatino.
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp
&lt;a href="http://en.wikipedia.org/wiki/Courier_New"&gt; Courier New&lt;/a&gt;
is not new at all, but it mixes harmoniously across text in Palatino.
Those fonts display much better on Mac OS X, or with Safari on Windows XP.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Descriptors&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Descriptors appeared in Novelang-0.39.0, as an experimental feature. They now display with a nice fade and animation, in order to preserve user&amp;rsquo;s visual landmarks. Descriptor have a vertical bar that helps to see the scope of the descriptor. This vertical bar only shows when Descriptor is discloed.
&lt;/p&gt;&lt;p&gt;
Descriptor disclosers now appear close to Tag column. This avoids polluting the left margin.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Scalable lists for metadata&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
On big documents, there can be so many tags they don&amp;rsquo;t fit in the height on a Web browser&amp;rsquo;s window. But &lt;em&gt;most of time&lt;/em&gt;, they all fit so it&amp;rsquo;s convenient to have all of them at a fixed position. How to deal with the exception without hurting common case? Having a 2&lt;sup&gt;nd&lt;/sup&gt; scrollbar in a browser&amp;rsquo;s frame looks confusing. But the scrollbar has a great feature: it shows that some items are out of sight. One trick could be displaying a huge popup, but this probably means a lot of work for a poor result.
&lt;/p&gt;&lt;p&gt;
Finally, the solution comes with a fade to grey at the end of the list to show that all items don&amp;rsquo;t show. A tiny button &amp;ldquo;unpins&amp;rdquo; the tag list from the top of Web browser&amp;rsquo;s window and lets it go to the document&amp;rsquo;s beginning. So, when entering the &amp;ldquo;1 % case&amp;rdquo; we still have a standard behavior.
&lt;/p&gt;&lt;p&gt;
Here is the Tag tab in its default pinned state (note the fade at the bottom and scrollbar position):
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/S47P66BCqhI/AAAAAAAAAOM/E38Y4d-YVEk/s800/manyTags-pinned.png" /&gt;

&lt;p&gt;
Unpinning causes it to scroll with the rest of the document:
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/S47P7D2pH6I/AAAAAAAAAOQ/0hIEXjN3F4U/s800/manyTags-unpinned.png" /&gt;

&lt;p&gt;
In addition to Tags, there will be, in a (hopefully near) future, more metadata like Identifiers. Tags show up under a tab bar where it&amp;rsquo;s easy to add new tabs.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2439927185820352288?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2439927185820352288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2439927185820352288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2439927185820352288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2439927185820352288'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/03/html-default-stylesheet-improvements.html' title='HTML default stylesheet improvements'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_c-k7nfw_Y8o/S47P6e377TI/AAAAAAAAAOE/8sIffTR7Wmc/s72-c/wholePage.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5624623236459751651</id><published>2010-02-21T22:46:00.001+01:00</published><updated>2010-02-21T22:46:54.050+01:00</updated><title type='text'>Novelang-0.39.2 released!</title><content type='html'>         Download Novelang-0.39.2 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Reject diacritics in tags.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Filter on implicit tags as on explicit tags.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5624623236459751651?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5624623236459751651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5624623236459751651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5624623236459751651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5624623236459751651'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/02/novelang-0392-released.html' title='Novelang-0.39.2 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-461383947355185038</id><published>2010-02-17T21:39:00.001+01:00</published><updated>2010-02-17T21:39:30.865+01:00</updated><title type='text'>Novelang-0.39.1 released!</title><content type='html'>         Download Novelang-0.39.1 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed documentation generation.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-461383947355185038?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/461383947355185038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=461383947355185038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/461383947355185038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/461383947355185038'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/02/novelang-0391-released.html' title='Novelang-0.39.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1763472519196404106</id><published>2010-02-17T21:18:00.001+01:00</published><updated>2010-02-17T21:18:33.335+01:00</updated><title type='text'>Novelang-0.39.0 released!</title><content type='html'>         Download Novelang-0.39.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Experimental feature: &lt;a xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" href="http://novelang.blogspot.com/2009/12/descriptors-in-html.html" &gt;descriptors&lt;/a&gt; in default HTML stylesheet.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Support Unicode files starting with a &lt;a xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" href="http://unicode.org/faq/utf_bom.html#BOM" &gt;BOM&lt;/a&gt; (Byte Order Mark).&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Reject TAB character.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Display Unicode name of a rejected character (as long as it belongs to the set of 16 bit Unicode characters as defined in Unicode 5.2 standard). This feature is experimental and may wreck existing error messages.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1763472519196404106?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1763472519196404106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1763472519196404106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1763472519196404106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1763472519196404106'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2010/02/novelang-0390-released.html' title='Novelang-0.39.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4499195429133541559</id><published>2009-12-27T18:17:00.002+01:00</published><updated>2009-12-27T18:23:44.959+01:00</updated><title type='text'>Descriptors in HTML</title><content type='html'>&lt;p&gt;
Designators are identifiers and tags. Source document may contain explicit designators, but since version 0.37.0 Novelang is smart enough to generate &lt;em&gt;implicit designators&lt;/em&gt; from the text of source documents. &lt;a href="http://novelang.blogspot.com/2009/12/generating-human-friendly-designators.html"&gt; Rules &lt;/a&gt; for implicit designators are as intuitive as possible, but it is helpful to show somewhere the implicit designators Novelang generated for you.
&lt;/p&gt;&lt;p&gt;
So default HTML stylesheet introduce a new artefact called &amp;ldquo;descriptor&amp;rdquo;. It&amp;rsquo;s a text area surrounding a paragraph or a level title, that unfolds for displaying implicit descriptors and maybe other useful things in the future, like location in the source document.
&lt;/p&gt;&lt;p&gt;
Looks like this:
&lt;/p&gt;
&lt;img src="http://lh5.ggpht.com/_c-k7nfw_Y8o/SzeXPoknKxI/AAAAAAAAANg/qSoVSwLkMGA/s800/descriptor.png" /&gt;
&lt;p&gt;
The descriptor shows:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Implicit identifier: &lt;code&gt;\\ThisIsASectionWithATitle_andStyleInsideTheTitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Implicit tag: &lt;code&gt;ThisIsASectionWithATitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Implicit tag: &lt;code&gt;andStyleInsideTheTitle&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
While working on layout and animation I found those links useful:
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://jquery.com"&gt; JQuery &lt;/a&gt;, the must-have JavaScript framework for doing everything with browser&amp;rsquo;s DOM in an concise and elegant fashion.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know"&gt; Stuff &lt;/a&gt; &lt;a href="http://www.smashingmagazine.com/2009/10/19/the-mystery-of-css-float-property"&gt; About &lt;/a&gt; CSS floats. (As a bonus, found this one about &lt;a href="http://tjkdesign.com/articles/float-less_css_layouts.asp"&gt; floatless layout &lt;/a&gt;, may become useful one day.)
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://tjkdesign.com/articles/css%20pop%20ups"&gt; CSS popups &lt;/a&gt; are fine but I gave up this way as the popup only appears with mouse pointer over a drop zone, prevents from copy-pasting.
&lt;/p&gt;&lt;p&gt;
This one about &lt;a href="http://tjkdesign.com/articles/nulllinks.asp"&gt; null HTML links &lt;/a&gt; also helped to drop bad ideas.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4499195429133541559?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4499195429133541559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4499195429133541559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4499195429133541559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4499195429133541559'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/12/descriptors-in-html.html' title='Descriptors in HTML'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_c-k7nfw_Y8o/SzeXPoknKxI/AAAAAAAAANg/qSoVSwLkMGA/s72-c/descriptor.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6442586615399973761</id><published>2009-12-22T20:42:00.000+01:00</published><updated>2009-12-22T20:43:07.797+01:00</updated><title type='text'>Novelang-0.38.1 released!</title><content type='html'>         Download Novelang-0.38.1 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed occasional crash caused by Implicit Tags.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6442586615399973761?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6442586615399973761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6442586615399973761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6442586615399973761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6442586615399973761'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/12/novelang-0381-released.html' title='Novelang-0.38.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1967261411197295562</id><published>2009-12-21T21:40:00.001+01:00</published><updated>2009-12-21T21:40:37.507+01:00</updated><title type='text'>Novelang-0.38.0 released!</title><content type='html'>         Download Novelang-0.38.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Experimental support for Implicit Tags, deduced from level&amp;rsquo;s title.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1967261411197295562?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1967261411197295562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1967261411197295562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1967261411197295562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1967261411197295562'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/12/novelang-0380-released.html' title='Novelang-0.38.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5862921447685528147</id><published>2009-12-14T20:57:00.002+01:00</published><updated>2009-12-14T20:59:40.588+01:00</updated><title type='text'>Generating human-friendly designators</title><content type='html'>&lt;p&gt;
A &lt;em&gt;Designator&lt;/em&gt; helps to locate text fragments. This is a generic term for Tags and Identifiers. With Novelang-0.37.0 come Implicit Identifiers, that make a level title behave as an Identifier. With explicit Identifiers, to reference a level from an &lt;code&gt;insert&lt;/code&gt; command you decorate the level with an Identifier like this:
&lt;/p&gt;&lt;pre&gt;
  \\Preamble
== Preamble

This is a preamble, blah blah blah...
&lt;/pre&gt;&lt;p&gt;
And this is how to insert only the Part with &amp;ldquo;Preamble&amp;rdquo; title in some Novelang book:
&lt;/p&gt;&lt;pre&gt;
insert file:my-document.nlp \\Preamble
&lt;/pre&gt;&lt;p&gt;
But why duplicating the &amp;ldquo;Preamble&amp;rdquo; word? As long it doesn&amp;rsquo;t collide with another Identifier we should be able to write:
&lt;/p&gt;&lt;pre&gt;
== Preamble

This is a preamble, blah blah blah...
&lt;/pre&gt;&lt;p&gt;
… And use the &lt;code&gt;insert&lt;/code&gt; command the same way.
&lt;/p&gt;&lt;p&gt;
Now with this feature available, it makes sense to support implicit Tags, too. When requesting a document containing only fragments tagged with &lt;code&gt;@Preamble&lt;/code&gt; one could expect to see our level with &amp;ldquo;Preamble&amp;rdquo; title. The need for Implicit Tags and Identifier came out from documents looking like this:
&lt;/p&gt;&lt;pre&gt;
  \\Preamble
  @Preamble
== Preamble

...
&lt;/pre&gt;&lt;p&gt;
Quite not good, for a typing-savvy tool, is it? So now we need a common rule to create Implicit Tags and Implicit Identifiers out from legal Novelang level titles.
&lt;/p&gt;&lt;p&gt;
There are some differences between Implicit Tags and Implicit Identifiers.
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Implicit Tags don&amp;rsquo;t appear in the list of explicitely-defined Tags (in the &lt;code&gt;n:meta/n:tags&lt;/code&gt; element).
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;One given level title generates only one Implicit Identifier, but it may generate several Implicit Tags. This makes sense for long titles; the longer they are the less likely they are to appear several times in the rendered document. With a simple rule &amp;ndash;&amp;nbsp;like breaking on punctuation signs&amp;nbsp;&amp;ndash; a long title may generate several meaningful Tags.
&lt;/p&gt;&lt;p&gt;
Here are some generic rules for crafting Implicit Designators:
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Generate something as close as possible of what a human could write.
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Resolve to a limited set of characters that comply with the specification of a &lt;a href="http://www.ietf.org/rfc/rfc1738.txt"&gt; URL &lt;/a&gt;. By now, Tags appear in the URL-like document request as parameters. There is a chance to support Identifiers as document request parameters, too.
&lt;/p&gt;&lt;p&gt;
To make a long story short, the RFC lists diacriticless letters, digits and &lt;code&gt;"$-_.+!*'(),"&lt;/code&gt; characters as legal part of a URL. We can note there is non-uniform support of punctuation signs (&lt;code&gt;!&lt;/code&gt; supported but not &lt;code&gt;?&lt;/code&gt; and &lt;code&gt;:&lt;/code&gt;). For this reason, we exclude punctuation signs. Same for paired delimiters. The asterisk, plus sign, and dollar sign don&amp;rsquo;t appear as document construct (they may only appear under some escaped form), so we exclude them too. Only remain low line &lt;code&gt;_&lt;/code&gt; and hyphen minus &lt;code&gt;-&lt;/code&gt;.
&lt;/p&gt;&lt;p&gt;
Implicit Tags split on punctuation signs, while Implicit Identifiers must keep them by some mean. By disallowing the low line in Tag syntax, we save it for punctuation sign replacement for Implicit Identifiers.
&lt;/p&gt;&lt;p&gt;
The hyphen minus may replace space character. But forcing character case to &lt;a href="http://en.wikipedia.org/wiki/CamelCase"&gt; camel case &lt;/a&gt; makes shorter Designators, while keeping them quite readable. Camel case only happens for whitespace stripping between two adjacent words.
&lt;/p&gt;&lt;p&gt;
Samples:
&lt;/p&gt;&lt;pre&gt;
Document source   Implicit Designator
aéœ               aeoe
x, yz             x_yz      -&gt; 2 Tags: @x  @yz 
X, yz             X_yz      -&gt; 2 Tags: @X  @yz 
v `0.1.2`         v0-1-2
Foo bar           FooBar
foo bar           fooBar
foO BAR           foOBAR
w (x yz)          w_xYz     -&gt; 3 Tags: @w  @x  @yz
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5862921447685528147?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5862921447685528147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5862921447685528147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5862921447685528147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5862921447685528147'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/12/generating-human-friendly-designators.html' title='Generating human-friendly designators'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-365074063932820793</id><published>2009-12-13T22:04:00.001+01:00</published><updated>2009-12-13T22:04:15.959+01:00</updated><title type='text'>Novelang-0.37.0 released!</title><content type='html'>         Download Novelang-0.37.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Implicit identifiers, deduced from level&amp;rsquo;s title. See &amp;ldquo;Identifiers&amp;rdquo; chapter in Part syntax.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-365074063932820793?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/365074063932820793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=365074063932820793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/365074063932820793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/365074063932820793'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/12/novelang-0370-released.html' title='Novelang-0.37.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-452429917334026296</id><published>2009-09-27T17:41:00.001+02:00</published><updated>2009-09-27T17:41:49.183+02:00</updated><title type='text'>Novelang-0.36.0 released!</title><content type='html'>         Download Novelang-0.36.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;--style-dirs&lt;/code&gt; command line parameter (superceding &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;--style-dir&lt;/code&gt;) for multiple style directories.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Minor identifier-related fixes and internal refactorings.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-452429917334026296?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/452429917334026296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=452429917334026296' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/452429917334026296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/452429917334026296'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/09/novelang-0360-released.html' title='Novelang-0.36.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6786845642659136948</id><published>2009-09-20T19:10:00.001+02:00</published><updated>2009-09-20T19:10:56.078+02:00</updated><title type='text'>Novelang-0.35.0 released!</title><content type='html'>         Download Novelang-0.35.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Experimental support for identifiers. See &amp;ldquo;Identifiers&amp;rdquo; chapter in Part syntax, and &amp;ldquo;Insert Command&amp;rdquo; in &amp;ldquo;Book Files&amp;rdquo;.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6786845642659136948?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6786845642659136948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6786845642659136948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6786845642659136948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6786845642659136948'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/09/novelang-0350-released.html' title='Novelang-0.35.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8025337134029544493</id><published>2009-09-09T23:15:00.002+02:00</published><updated>2009-09-09T23:31:29.974+02:00</updated><title type='text'>Novelang-0.34.1 released!</title><content type='html'>Download Novelang-0.34.1 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed: bug preventing from starting a Novelang release with a numbered version.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8025337134029544493?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8025337134029544493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8025337134029544493' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8025337134029544493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8025337134029544493'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/09/novelang-0341-released.html' title='Novelang-0.34.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4254806896708048646</id><published>2009-09-09T22:36:00.001+02:00</published><updated>2009-09-09T22:36:22.290+02:00</updated><title type='text'>Novelang-0.34.0 released!</title><content type='html'>         Download Novelang-0.34.0 &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; !         &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;levelabove&lt;/code&gt; option for &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;insert&lt;/code&gt; book command.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;sort&lt;/code&gt; option for &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;insert&lt;/code&gt; book command.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;explodelevel&lt;/code&gt; batch command for splitting one document&amp;rsquo;s levels into several parts.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;New &lt;code xalan="http://xml.apache.org/xalan" xsltc-extension="http://xml.apache.org/xalan/xsltc" &gt;--content-root&lt;/code&gt; command line argument for setting the directory where content files reside.&lt;/li&gt;&lt;/ul&gt;&lt;ul n="http://novelang.org/book-xml/1.0" &gt;&lt;li &gt;Fixed: paragraph as list did not support indented embedded list items.&lt;/li&gt;&lt;/ul&gt;         &lt;p&gt;        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4254806896708048646?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4254806896708048646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4254806896708048646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4254806896708048646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4254806896708048646'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/09/novelang-0340-released_7109.html' title='Novelang-0.34.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8166719006047414175</id><published>2009-08-23T18:10:00.001+02:00</published><updated>2009-08-23T18:10:38.940+02:00</updated><title type='text'>Novelang-0.33.1 released!</title><content type='html'>         A new release of Novelang is available!         Download it &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; and see         documentation for details.        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8166719006047414175?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8166719006047414175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8166719006047414175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8166719006047414175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8166719006047414175'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/08/novelang-0331-released.html' title='Novelang-0.33.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5058303336469059562</id><published>2009-08-21T20:15:00.002+02:00</published><updated>2009-08-23T07:47:02.329+02:00</updated><title type='text'>Apostrophe and quotation marks</title><content type='html'>&lt;p&gt;
Finally, people getting serious about &lt;a href="http://www.presentationzen.com/presentationzen/2009/08/apostrophes-and-quotation-marks.html" &gt;this&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5058303336469059562?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5058303336469059562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5058303336469059562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5058303336469059562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5058303336469059562'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/08/apostrophe-and-quotation-marks.html' title='Apostrophe and quotation marks'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6256954905897766486</id><published>2009-08-17T08:15:00.001+02:00</published><updated>2009-08-17T08:15:54.851+02:00</updated><title type='text'>Novelang-0.33.0 released!</title><content type='html'>         A new release of Novelang is available!         Download it &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; and see         documentation for details.        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6256954905897766486?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6256954905897766486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6256954905897766486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6256954905897766486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6256954905897766486'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/08/novelang-0330-released.html' title='Novelang-0.33.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7095234248857126297</id><published>2009-08-08T08:31:00.001+02:00</published><updated>2009-08-08T08:31:55.832+02:00</updated><title type='text'>Novelang-0.32.1 released!</title><content type='html'>         A new release of Novelang is available!         Download it &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; and see         documentation for details.        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7095234248857126297?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7095234248857126297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7095234248857126297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7095234248857126297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7095234248857126297'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/08/novelang-0321-released.html' title='Novelang-0.32.1 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8089569900278349509</id><published>2009-08-02T18:38:00.000+02:00</published><updated>2009-08-02T18:39:26.640+02:00</updated><title type='text'>Novelang-0.32.0 released!</title><content type='html'>         A new release of Novelang is available!         Download it &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt; and see         documentation for details.        &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8089569900278349509?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8089569900278349509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8089569900278349509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8089569900278349509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8089569900278349509'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/08/novelang-0320-released.html' title='Novelang-0.32.0 released!'/><author><name>Novelang announcer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1852591405904759276</id><published>2009-07-26T16:00:00.003+02:00</published><updated>2009-07-26T16:01:40.850+02:00</updated><title type='text'>Novelang-0.31.1 released!</title><content type='html'>&lt;p&gt;
This release brings minor fixes around new block-after-tilde feature. Can be downloaded &lt;a href="https://sourceforge.net/projects/novelang/files"&gt;here&lt;/a&gt;. See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1852591405904759276?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1852591405904759276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1852591405904759276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1852591405904759276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1852591405904759276'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/novelang-0311-released.html' title='Novelang-0.31.1 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6768792822101135725</id><published>2009-07-26T15:26:00.000+02:00</published><updated>2009-07-26T15:27:33.168+02:00</updated><title type='text'>Idiom: custom blocks</title><content type='html'>&lt;div class="tag-scope" &gt;&lt;p &gt;
Novelang has no semantic markup, insteads it creates an AST (Abstract Syntax Tree) to feed a stylesheet with. This allows creating document-specific idioms, to be handled at stylesheet level. Here is one.
&lt;/p&gt;
&lt;/div&gt;&lt;div class="tag-scope" &gt;&lt;p &gt;
Starting from source document like this:
&lt;/p&gt;
&lt;/div&gt;&lt;pre &gt;
&amp;lt;&amp;lt;
[INFO] This is an info block.
&amp;gt;&amp;gt;

&amp;lt;&amp;lt;
[WARNING] Beware of "this" paragraph.

(This warning spreads on several paragraphs.)
&amp;gt;&amp;gt;
&lt;/pre&gt;
&lt;div class="tag-scope" &gt;&lt;p &gt;
We want lines of literal to appear in a special manner (like within a frame and with a special icon in the margin). Here is how to achieve this:
&lt;/p&gt;
&lt;/div&gt;&lt;pre &gt;
&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
   xmlns:n="http://novelang.org/book-xml/1.0"
&amp;gt;
 &amp;lt;xsl:import href="default-html.xsl" /&amp;gt;
 &amp;lt;xsl:import href="punctuation-FR.xsl" /&amp;gt;

 &amp;lt;xsl:template match="/" &amp;gt;
   &amp;lt;xsl:apply-imports/&amp;gt;
 &amp;lt;/xsl:template&amp;gt;

 &amp;lt;xsl:template match="n:paragraphs-inside-angled-bracket-pairs" &amp;gt;
   &amp;lt;xsl:choose&amp;gt;
     &amp;lt;xsl:when 
         test="n:paragraph-regular[1]/n:block-inside-square-brackets[1]='WARNING'" 
     &amp;gt;
       &amp;lt;blockquote&amp;gt;
         &amp;lt;b&amp;gt;WARNING&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;
         &amp;lt;xsl:apply-templates /&amp;gt;
       &amp;lt;/blockquote&amp;gt;
     &amp;lt;/xsl:when&amp;gt;
     &amp;lt;xsl:when 
         test="n:paragraph-regular[1]/n:block-inside-square-brackets[1]='INFO'" 
     &amp;gt;
       &amp;lt;blockquote&amp;gt;
         &amp;lt;b&amp;gt;INFO&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;
         &amp;lt;xsl:apply-templates /&amp;gt;
       &amp;lt;/blockquote&amp;gt;
     &amp;lt;/xsl:when&amp;gt;
     &amp;lt;xsl:otherwise&amp;gt;
       &amp;lt;blockquote&amp;gt;
         &amp;lt;xsl:apply-templates /&amp;gt;
       &amp;lt;/blockquote&amp;gt;
     &amp;lt;/xsl:otherwise&amp;gt;
   &amp;lt;/xsl:choose&amp;gt;

 &amp;lt;/xsl:template&amp;gt;

 &amp;lt;xsl:template 
     match="n:block-inside-square-brackets[ text()='WARNING' or text()='INFO' ]" 
 /&amp;gt;

&amp;lt;/xsl:stylesheet&amp;gt;

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6768792822101135725?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6768792822101135725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6768792822101135725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6768792822101135725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6768792822101135725'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/idiom-custom-blocks.html' title='Idiom: custom blocks'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6768763399289135485</id><published>2009-07-26T14:59:00.001+02:00</published><updated>2009-07-26T14:59:36.716+02:00</updated><title type='text'>Rendering document source samples</title><content type='html'>&lt;p&gt;
A nice feature in the documentation would be to show the Novelang source and the rendering result at the same time. There are several ways to achieve this:
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Duplicate the source code in the Novelang document. One is escaped, one is not. The latter gets rendered in the document itself, in a &lt;code&gt;n:paragraphs-inside-angled-bracket-pairs&lt;/code&gt; element with a special tag. For now this won&amp;rsquo;t work in many cases, like levels or lines of literal.
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Reference a screenshot of a previous rendering. This is the most stupid solution because it&amp;rsquo;s boring to do and hard to keep up-to-date.
&lt;/p&gt;&lt;p&gt;
&amp;mdash;&amp;nbsp;Be clever and generate the image dynamically from the source snippet.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Rendering tools&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
How to render a PDF fragment into an embeddable image?
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.icepdf.org"&gt; IcePDF &lt;/a&gt; claims to be open source but the license doesn&amp;rsquo;t appear on the Web site and downloading the product requires registration. Anyway, the Java WebStart&amp;rsquo;ed demo doesn&amp;rsquo;t display anything except a pair of messages telling it&amp;rsquo;s a trial version. This behavior was observed on Mac OS X 10.5 and Java 6.
&lt;/p&gt;&lt;p&gt;
&lt;a href="https://pdf-renderer.dev.java.net"&gt; PDFRenderer &lt;/a&gt; is available under LGPL. The project seems a bit asleep for now; it looks like a dump-everything-to-the-community effect of Sun&amp;rsquo;s policy last years. PDFRenderer does a nice job with many PDF, but Novelang-generated ones appear severely broken!
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://incubator.apache.org/pdfbox"&gt; PDFBox &lt;/a&gt; is licensed under the Apache License, but contains license notices from Adobe (for AFM fonts) and Sun (for JAI). A close look at &lt;code&gt;PDFBox-7.3.jar&lt;/code&gt; shows it embeds those AFM fonts.
&lt;/p&gt;&lt;p&gt;
Since PDFBox-7.3 doesn&amp;rsquo;t work (spits an exception), let&amp;rsquo;s check a snapshot out! This is revision 795516 or something. The build goes well, and image generation doesn&amp;rsquo;t crash. But the text in images appears seriously damaged! And the font doesn&amp;rsquo;t look correct. The original was created using Linux Libertine; images contain a Helvetica-like which may not have the same metrics. And all text in non-proportional fonts doesn&amp;rsquo;t appear at all.
&lt;/p&gt;&lt;p&gt;
Should I give up my dream of finding an OSS solution for rendering images out from FOP-generated PDF documents? Debugging FOP or PDFRenderer looks like a lot of work. And, while it&amp;rsquo;s easier to get perfect control on PDF rendering, HTML rendering may be enough for creating the samples.
&lt;/p&gt;&lt;p&gt;
So here comes &lt;a href="https://xhtmlrenderer.dev.java.net"&gt; Flying Saucer &lt;/a&gt; to the rescue. It&amp;rsquo;s pure Java XHTML renderer which supports CSS 2.1. I&amp;rsquo;ve used it already and I know it works. The &amp;ldquo;inheritable&amp;rdquo; nature of CSS means I can tweak the output a bit (reducing margins and page width) while reusing the default CSS stylesheet.
&lt;/p&gt;&lt;p&gt;
Finally, all this product review turns to be nonsense, because FOP is supposed to &lt;a href="http://xmlgraphics.apache.org/fop/0.95/output.html#bitmap"&gt; generate images directly &lt;/a&gt;! Insanely great!
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Integration to Novelang&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Here comes hard stuff. Including external resources depends if the document is self-contained (PDF) or multipart (HTML), and if document is generated by generator (batch) or HTTP dæmon (interactive). As a self-contained document, PDF is generated the same way wether it&amp;rsquo;s a batch or interactive context.
&lt;/p&gt;&lt;p&gt;
The FO stylesheet may manage image embedding into the PDF, thus avoiding to spread complexity elsewhere. For SVG, the &lt;code&gt;fo:instream-foreign-object&lt;/code&gt; allows direct inclusion of the XML. For images, the architecturally-simple approach would be to write a FOP extension taking the code snippet as parameter, then inserting the rendered image into the &lt;a href="http://xmlgraphics.apache.org/fop/dev/design/areas.html"&gt; Area Tree &lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Using external files only makes sense when generating an HTML documents, because we&amp;rsquo;re pretty sure in this case that user agent won&amp;rsquo;t request the image before it can read its address from the HTML. For PDF documents, the temporary file must exist before running the FO stylesheet, so it would require some kind of ugly pre-processing.
&lt;/p&gt;&lt;p&gt;
External files are generated &amp;ldquo;once-for-all&amp;rdquo; in batch mode. But, in interactive mode, how long should they live? And does it make sense to write files on the filesystem while the resource could be dynamically generated?
&lt;/p&gt;&lt;p&gt;
Dynamic resources could be kept in some session-scoped cache. This is how it would work:No need to cache the generated image, only the source snippet. This allows deferred generation.The HTTP session contains several cache areas, one per document name.When a fresh document is generated, reset the whole cache area for this document name.During XSLT processing, call an XSL extension that feeds the cache with snippets.Given a snippet, the cache returns some kind of identifier to be inserted as a link in resulting HTML.A special resource handler (at HTTP dæmon level) queries the cache with the identifiers.If the cache has such a snippet, then it returns it for rendering.
&lt;/p&gt;&lt;p&gt;
The XSL extension called by the stylesheet could trigger two different behavior, wether it&amp;rsquo;s dæmon or interactive mode:Use the caching stuff as above.Just write the image file on the filesystem.
&lt;/p&gt;&lt;p&gt;
How to invalidate the cache? Session expiration is not enough: if several documents exist in the same session, some may become unused therefore causing excessive memory consumption. To avoid this, turn reference to &amp;ldquo;old&amp;rdquo; documents to &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/ref/SoftReference.html"&gt; soft references &lt;/a&gt; so the JVM would clean them upon memory demand.
&lt;/p&gt;&lt;p&gt;
Bad behavior would occuring when trying to load an image inside an HTML page after the cache got cleaned by some way (session expiration or memory reclaim) and prior to refreshing the whole page. This sounds like a tolerable annoyance.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Conclusion(s)&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
I wanted to avoid coding whatever looks like a cache for as long as possible. Now there is a case where caching is linked to a feature out of the performance scope. Anyways, the cache described above is a &amp;ldquo;toy&amp;rdquo; cache. Real caching would take the whole resource graph (source documents, images, stylesheets and so one) in account.
&lt;/p&gt;&lt;p&gt;
Dynamically-generated images could also make sense for rendering &lt;a href="http://novelang.blogspot.com/2009/02/embedded-maths.html"&gt; ASCII Math &lt;/a&gt; for Web browsers which don&amp;rsquo;t support SVG.
&lt;/p&gt;&lt;p&gt;
As often, a bit of additional comfort requires a lot of work.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6768763399289135485?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6768763399289135485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6768763399289135485' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6768763399289135485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6768763399289135485'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/rendering-document-source-samples.html' title='Rendering document source samples'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5480375233699720314</id><published>2009-07-26T14:55:00.001+02:00</published><updated>2009-07-26T14:55:52.180+02:00</updated><title type='text'>First Novelang demo in the enterprise world!</title><content type='html'>&lt;p&gt;
Last week I gave an introduction to Novelang at a software publisher&amp;rsquo;s who&amp;rsquo;s looking at a collaborative tool for writing it&amp;rsquo;s product&amp;rsquo;s documentation. The attenders were the internal IT manager, two technical writers and and an IT intern. Technical writers were enthusiastic, since Novelang is a huge leap from FrameMaker and Robohelp &amp;ndash;&amp;nbsp;that&amp;rsquo;s what they&amp;rsquo;re working with for now. They had a look at &lt;a href="http://scenari-platform.org/projects/scenari/en/pres/co/desc.html"&gt; Scenari &lt;/a&gt; and &lt;a href="http://www.nuxeo.com"&gt; Nuxeo &lt;/a&gt;. While both are open-source product, the setup fees seemed hugely overpriced.
&lt;/p&gt;&lt;p&gt;
(In my own humble opinion, Scenari is overengineered crap with excessively complex graphical editor. But it has nice slides to explain the &amp;ldquo;What You See Is What You Mean&amp;rdquo; concept. I spent no time looking at Nuxeo for now.)
&lt;/p&gt;&lt;p&gt;
The technical writers really liked that Novelang never asks for more information that the very minimum required (I guess FrameMaker doesn&amp;rsquo;t do that). I had a chance to show off with how whitespaces, non-breakable spaces, zero-width spaces, indentation, line breaks, separators, and automatic handling of punctuation typography through a customizable stylesheet. After spending countless hours on those obscure cases that&amp;rsquo;s &lt;em&gt;great&lt;/em&gt; to discover that I&amp;rsquo;m not the only guy to who this matters (oh, by the way both tech writers are girls).
&lt;/p&gt;&lt;p&gt;
Now they&amp;rsquo;re evaluating the product but I already got some feedeback.
&lt;/p&gt;&lt;p&gt;
With somebody looking over my should, I realized how Novelang installation looks ugly. I unzipped the Novelang archive, did set a pair of system properties, and wrote a .bat file at the root of their working directory, all with my bare hands.
&lt;/p&gt;&lt;p&gt;
The &amp;ldquo;local webserver&amp;rdquo; concept is confusing. For most of people, a webserver is a remote host. This leads to some confusion on collaborative features. They were tempted to store the source document on a shared network drive. On the other hand, they&amp;rsquo;re not used to source control tools like CVS (the one in use in their company).
&lt;/p&gt;&lt;p&gt;
The lack of graphical editor looks strange to people who are not accustomed to technical writing.
&lt;/p&gt;&lt;p&gt;
There is no &amp;ldquo;guided tour&amp;rdquo; document nor &amp;ldquo;cheat sheet&amp;rdquo; to give an overview of every feature and how to use it best.
&lt;/p&gt;&lt;p&gt;
I had a deep look at the documents they&amp;rsquo;re producing for now. The content seems to fit in Novelang syntax. They have some very big tables with one column full of content like lists. For this, a level-based structure seems more appropriate than Novelang&amp;rsquo;s cell rows.
&lt;/p&gt;&lt;p&gt;
Having image resolution for PDF hardcoded to 300 dpi won&amp;rsquo;t work here. At least they need a command-line option until &lt;a href="http://novelang.blogspot.com/2008/09/opening-access-to-fop-configuration.html"&gt; stylesheet metadata &lt;/a&gt; gets implemented.
&lt;/p&gt;&lt;p&gt;
A big requirement is the already-discussed &lt;a href="http://novelang.blogspot.com/2009/06/book-index.html"&gt; index &lt;/a&gt; feature.
&lt;/p&gt;&lt;p&gt;
To be continued!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5480375233699720314?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5480375233699720314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5480375233699720314' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5480375233699720314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5480375233699720314'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/first-novelang-demo-in-enterprise-world.html' title='First Novelang demo in the enterprise world!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-4217700348307242050</id><published>2009-07-22T20:23:00.003+02:00</published><updated>2009-07-22T20:26:58.337+02:00</updated><title type='text'>Liberation fonts</title><content type='html'>&lt;a href="https://fedorahosted.org/liberation-fonts/" &gt;Liberation&lt;/a&gt; is a superb font set under the GPL+ license, which allows redistribution while not extending the GPL licence to the documents produced with the fonts. Definitely a must-have. It's a 3-family set (Serif, Sans, Mono) with the 4 combinations with bold and italics. At the first glance they look more elegant than Times + Arial + Courier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-4217700348307242050?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/4217700348307242050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=4217700348307242050' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4217700348307242050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/4217700348307242050'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/liberation-fonts.html' title='Liberation fonts'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-9073829432408716178</id><published>2009-07-12T22:50:00.003+02:00</published><updated>2009-07-13T09:25:28.922+02:00</updated><title type='text'>Novelang-0.31.0 released!</title><content type='html'>&lt;p&gt;
So sweet! &lt;a href="https://sourceforge.net/projects/novelang/files/"&gt;This release&lt;/a&gt; brings better control over &lt;a href="http://novelang.blogspot.com/2009/07/removing-unwanted-spaces-continued.html"&gt;whitespace suppression&lt;/a&gt;. See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-9073829432408716178?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/9073829432408716178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=9073829432408716178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/9073829432408716178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/9073829432408716178'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/novelang-0300-released.html' title='Novelang-0.31.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6461202443262804514</id><published>2009-07-12T13:34:00.002+02:00</published><updated>2009-07-12T13:38:19.415+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grammar'/><title type='text'>Removing unwanted spaces (continued)</title><content type='html'>&lt;p&gt;
This is about some kind of brand new operator: it groups all words an blocks and punctuation signs which are not separated by space.
&lt;/p&gt;&lt;p&gt;
A great feature of Novelang is to apply standard typographic rules, especially when there is punctuation. The problem is, sometimes you can&amp;rsquo;t apply those rules in a blunt manner.
&lt;/p&gt;&lt;p&gt;
Consider these cases: on the left, what&amp;rsquo;s in the source document, and on the right default rendering.
&lt;/p&gt; &lt;table&gt; &lt;tr&gt; &lt;td&gt; Source document &lt;/td&gt; &lt;td&gt; Default rendering &lt;/td&gt; &lt;td&gt; Hack &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;code&gt;imprimé(e)s&lt;/code&gt; &lt;/td&gt; &lt;td&gt; imprimé (e) s &lt;/td&gt; &lt;td&gt; &lt;code&gt;`imprimé(e)s`&lt;/code&gt; &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;code&gt;F.B.I.&lt;/code&gt; &lt;/td&gt; &lt;td&gt; F. B. I. (superfluous spaces) &lt;/td&gt; &lt;td&gt; &lt;code&gt;`F.B.I`&lt;/code&gt; &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;code&gt;computer//ing//&lt;/code&gt; &lt;/td&gt; &lt;td&gt; computer &lt;em&gt;ing&lt;/em&gt; &lt;/td&gt; &lt;td&gt; No hack available &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;p&gt;
Default space insertion makes it all wrong. I tried to &lt;a href="http://novelang.blogspot.com/2009/05/space-character-and-related-stuff.html"&gt; fix &lt;/a&gt; it by detecting proximity (lack of spaces) between casual words and blocks inside grave accents. But, if adding other cases like full stops, blocks inside solidus pairs and blocks inside parenthesis, we end up with many complex tranformations which just break existing whitespace addition for the common case.
&lt;/p&gt;&lt;p&gt;
The solution is something more generic. I&amp;rsquo;m thinking about a special character which groups everything that follows until there is a space, a line break or the end of the document. This character would be the tilde &lt;code&gt;~&lt;/code&gt; because it looks like a kind of elastic ligature.
&lt;/p&gt;&lt;p&gt;
So, with source document like this:
&lt;/p&gt;&lt;pre&gt;
~computer//ing//
&lt;/pre&gt;&lt;p&gt;
We get an AST (Abstract Syntax Tree) like this:
&lt;/p&gt;&lt;pre&gt;
+ block-after-tilde
  + word "computer"
  + block-inside-pair-of-solidus "ing"
&lt;/pre&gt;&lt;p&gt;
But we still miss the feature of adding zero-width spaces when needed. How to express this? Since zero-width spaces only make sense inside a group with no space, we can reuse the tile character safely.
&lt;/p&gt;&lt;p&gt;
This:
&lt;/p&gt;&lt;pre&gt;
~A.L.L.~O.F~'E.M.
&lt;/pre&gt;&lt;p&gt;
… becomes:
&lt;/p&gt;&lt;pre&gt;
+ block-after-tilde
  + subblock
    + word "A"
    + punctuation-sign full-stop
    + word "L"
    + punctuation-sign full-stop
    + word "L"
    + punctuation-sign full-stop
  + subblock
    + word "O"
    + punctuation-sign full-stop
    + word "F"
    + punctuation-sign full-stop
  + subblock
    + apostrophe-wordmate
    + word "E"
    + punctuation-sign full-stop
    + word "M"
&lt;/pre&gt;&lt;p&gt;
And this is enough for the stylesheet to find where to insert zero-width spaces.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6461202443262804514?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6461202443262804514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6461202443262804514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6461202443262804514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6461202443262804514'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/07/removing-unwanted-spaces-continued.html' title='Removing unwanted spaces (continued)'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6567071394629600555</id><published>2009-06-25T23:06:00.002+02:00</published><updated>2009-06-25T23:08:16.516+02:00</updated><title type='text'>Foreign characters</title><content type='html'>I like seeing all of those strange &lt;a href="http://en.wikipedia.org/wiki/Language_recognition_chart"&gt;letters&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6567071394629600555?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6567071394629600555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6567071394629600555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6567071394629600555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6567071394629600555'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/06/foreign-characters.html' title='Foreign characters'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2965413337434950453</id><published>2009-06-21T11:18:00.000+02:00</published><updated>2009-06-21T11:19:22.987+02:00</updated><title type='text'>Autotagging</title><content type='html'>&lt;p&gt;
The &lt;a href="http://novelang.blogspot.com/2009/05/novelang-0270-released.html"&gt; Tag &lt;/a&gt; feature is great. It turns out that I&amp;rsquo;m mainly using it to tag levels, and too often it leads to duplicate information like this:
&lt;/p&gt;&lt;pre&gt;
  @Graphics
== Graphics

...
&lt;/pre&gt;&lt;p&gt;
What I want is to simply write:
&lt;/p&gt;&lt;pre&gt;
== Graphics

...
&lt;/pre&gt;&lt;p&gt;
And then Novelang should guess that &amp;ldquo;Graphics&amp;rdquo; matches the &lt;code&gt;Graphics&lt;/code&gt; tag. I call this &amp;ldquo;Autotagging&amp;rdquo;.
&lt;/p&gt;&lt;p&gt;
We need a few simple tranformations rules to turn titles into tags.
&lt;/p&gt;

&lt;table &gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;foo&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@foo&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;Foo&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@Foo&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;Foo bar&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@Foobar&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;Foo, bar&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@Foo&amp;nbsp;@bar&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;Foo. Bar&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@Foo&amp;nbsp;@Bar&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr &gt;&lt;td &gt;&amp;ldquo;Foo-bar&amp;rdquo;&lt;/td&gt;&lt;td &gt;&lt;code &gt;@Foo-bar&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;
Automatically-generated tags wouldn&amp;rsquo;t be part of the tag list, but they would be used for the matching of a known tag with existing level titles.
&lt;/p&gt;&lt;p&gt;
Depending on the document, this behavior may produce a lot of noise so it requires explicit activation.
&lt;/p&gt;&lt;p&gt;
Of course, the default tag list (with checkboxes) has a new option to enable autotagging, with some JavaScript adding an &lt;code&gt;autotag&lt;/code&gt; parameter in the URL.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2965413337434950453?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2965413337434950453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2965413337434950453' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2965413337434950453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2965413337434950453'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/06/autotagging.html' title='Autotagging'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1974073872132919934</id><published>2009-06-19T22:39:00.000+02:00</published><updated>2009-06-19T22:40:34.961+02:00</updated><title type='text'>Novelang-0.30.0 released!</title><content type='html'>&lt;p&gt;
Latest release available &lt;a href="https://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
This release fixes a few bugs and brings some minor enhancements. See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1974073872132919934?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1974073872132919934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1974073872132919934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1974073872132919934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1974073872132919934'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/06/novelang-0300-released.html' title='Novelang-0.30.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5744738537098403375</id><published>2009-06-07T09:13:00.006+02:00</published><updated>2009-06-13T07:37:59.856+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='identifier'/><title type='text'>Book index</title><content type='html'>&lt;p&gt;
Start small, think big: while I don&amp;rsquo;t even provide a decent default stylesheet, I&amp;rsquo;m not afraid to blog about a tough subject: book index.
&lt;/p&gt;&lt;p&gt;
An index is a table at the end of a book, referencing pages or chapters containing a pertinent usage of a key word.
&lt;/p&gt;&lt;p&gt;
A very simple kind of index could look like this:
&lt;/p&gt;&lt;pre&gt;
icons, 21, 136, 138
&lt;/pre&gt;&lt;p&gt;
You can have ranges:
&lt;/p&gt;&lt;pre&gt;
gender in language, 4-6
&lt;/pre&gt;&lt;p&gt;
References avoid duplicates:
&lt;/p&gt;&lt;pre&gt;
GUIs, see graphical user interfaces (GUIs)
&lt;/pre&gt;&lt;p&gt;
Words can group on several levels (3 being the maximum):
&lt;/p&gt;&lt;pre&gt;
keys
  capitalizing name of, 68
  typographic conventions for, 144, 147
  writing about, 142
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Simplest representation&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
How could Novelang help to represent this?
&lt;/p&gt;&lt;p&gt;
The simplest thing to do is to use some kind of delimiter to tell that a word is an index entry. (As usual the meaning of the delimiter would be a matter of stylesheet.)
&lt;/p&gt;&lt;pre&gt;
The {icon} is displayed on the corner.
&lt;/pre&gt;&lt;p&gt;
Obviously, this doesn&amp;rsquo;t work, because we want the index entry to show a plural. So we invent some new kind of syntactic form representing a tuple (which symbols are used doesn&amp;rsquo;t matter at this stage).
&lt;/p&gt;&lt;pre&gt;
The { icon | icons } is displayed in the corner.
&lt;/pre&gt;&lt;p&gt;
Great, but how to model several levels of entries? We could make the source document look like this:
&lt;/p&gt;&lt;pre&gt;
In this case we must
{ capitalize | { keys | capitalizing name of } }
the name of a key.
&lt;/pre&gt;&lt;p&gt;
This feels just unreadable!
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;External index entry declaration&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
The trick: split index entry declaration from its complete definition, using several files. Complete definition would rely on a subset of Novelang grammar for source files. Example above becomes:
&lt;/p&gt;&lt;pre&gt;
%% source document:

In this case we must
{ capitalize | capitalizing-name-of-key }
the name of a key.


%% index definition file:

capitalizing-name-of-key
- capitalizing name of
  - keys
&lt;/pre&gt;&lt;p&gt;
This deserves a few explainations. The first &lt;code&gt;capitalize&lt;/code&gt; in the source document is still what&amp;rsquo;s displayed. The &lt;code&gt;capitalize-name-of-key&lt;/code&gt; is the entry name that is not supposed to be read by anybody else than the document writer &amp;ndash;&amp;nbsp;could be 123456 as well. The &lt;code&gt;capitalizing name of&lt;/code&gt; in the index definition file is what to display in the index. The &lt;code&gt;keys&lt;/code&gt; subitem is the parent item.
&lt;/p&gt;&lt;p&gt;
Because name of the index entry has no semantic meaning, we can let Novelang generate it using simple replacement rules (spaces becoming hyphen minus…). Explicit names are useful for special cases (like homonyms) but now we expect to be able to write:
&lt;/p&gt;&lt;pre&gt;
%% source document:

In this case we must {capitalize} the name
of a key.


%% index definition file:

capitalize
- keys
  - capitalizing name of
&lt;/pre&gt;&lt;p&gt;
Because for the same index entry we may have another pertinent words which are not exactly &amp;ldquo;capitalize&amp;rdquo; we let the index entry support several names.
&lt;/p&gt;&lt;pre&gt;
%% source document place 1:

In this case we must {capitalize} the name
of a key.


%% source document place 2:

Sometime the name of a key should not be
{in capitals}.


%% index definition file:

in-capitals
capitalize
- keys
  - capitalizing name of
&lt;/pre&gt;&lt;p&gt;
The index definition file could support lots of features.Some styling. There are rare cases (like latin names) where italics are required.A kind of markup to tell which words to take in account in alphabetical sort.Multiple posting: the same keyword in the source document has several index entries. This can happen using several embedded list items.&amp;ldquo;See&amp;rdquo; and &amp;ldquo;See Also&amp;rdquo; references.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Reusing tags and identifiers&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
Now, entry names may give some feeling of déjà vu. We already have machine-processed names with tags (implemented) and identifiers (not implemented yet). Are entry names just redundant? As tags and identifier apply on a whole paragraph or level, they don&amp;rsquo;t have the same level of precision when it comes to refer to the exact location of a word. And it turns out that referencing a range of paragraphs (or even chapters) is what we need for supporting page ranges.
&lt;/p&gt;&lt;p&gt;
The obvious way of handling page range would be to add a new &amp;ldquo;end of index entry range&amp;rdquo; here polluting the source document and making it look like LaTeX. This is a convention of the Novelang grammar: avoid end delimiters whenever possible. Tags and identifiers provide a nice extension.
&lt;/p&gt;&lt;p&gt;
Here is how we use a tag in the index definition file. Instead of tagging, it refers to the tagged text as index entry name:
&lt;/p&gt;&lt;pre&gt;
%% source document:

@gender
== Stylistic principles

=== Avoid jargon

 ...

=== Avoid sexist language

 ...

=== Common gender

 ...


%% index definition file:

@gender
- gender in language
&lt;/pre&gt;&lt;p&gt;
This is not yet perfect because page ranges are bound to the scope of a tag​/​identifier. But it seems possible to Some tree-mangling could detect that several tagged nodes appear consecutively:
&lt;/p&gt;&lt;pre&gt;
%% source document:

== Stylistic principles

=== Avoid jargon

 ...

@gender
=== Avoid sexist language

 ...


@gender
=== Common gender

 ...
&lt;/pre&gt;&lt;p&gt;
Tree-mangling could add a special marker as the last child of the last node of the consecutive tagged ones. Our tree would look like:
&lt;/p&gt;&lt;pre&gt;
level
  + level-title     "Stylistic principles"
  + level
  |   + level-title "Avoid jargon"
  + level
  |   + level-title "Avoid sexist language"
  |   + tag         "gender"
  |   + paragraph
  |   |   + start-of-range "gender"
  |   |   + ...
  |   + paragraph
  + level
      + level-title "Common gender"
      + tag         "gender"
      + paragraph
      + paragraph
         + ...
         + end-of-range    "gender"

&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Foreseen weaknesses&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
This is still unperfect because page ranges are bound to the scope of tags​/​identifiers but this looks like a pretty good approximation.
&lt;/p&gt;&lt;p&gt;
Another possible drawback is the ability to have overlapping ranges or page numbers with several different tags​/​identifiers, or index entries in the middle. Because FOP provides no hook to deal with page numbers once they are known, Novelang could not fix a serie of page numbers like &lt;code&gt;14-17, 15-18, 15, 16&lt;/code&gt;. It&amp;rsquo;s a long way to perfection.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Bibliography&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;All examples from A Style Guide for the Computer Industry, Sun Technical Publications, 1996.&lt;/em&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5744738537098403375?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5744738537098403375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5744738537098403375' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5744738537098403375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5744738537098403375'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/06/book-index.html' title='Book index'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-5802275989639850379</id><published>2009-06-03T08:34:00.002+02:00</published><updated>2009-06-03T08:37:05.893+02:00</updated><title type='text'>Novelang-0.29.0 released!</title><content type='html'>&lt;p&gt;
Latest release available &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
It brings various enhancements to whitespace handling, and the &lt;a href="http://novelang.blogspot.com/2009/05/pretty-color-palette-for-tags.html"&gt;pretty color palette for tags&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-5802275989639850379?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/5802275989639850379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=5802275989639850379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5802275989639850379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/5802275989639850379'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/06/novelang-0290-released.html' title='Novelang-0.29.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7220271826703706978</id><published>2009-05-30T00:39:00.002+02:00</published><updated>2009-05-30T00:44:43.973+02:00</updated><title type='text'>Image processing</title><content type='html'>&lt;p&gt;
In my endless quest of nice libraries to integrate into Novelang, I&amp;rsquo;ve been wandering about image processing. This makes sense for technical documentation with screen captures; often it is useful to do some rescale of fade. Ccompression is useful, too, but it should be probably be left to the rendering stage.
&lt;/p&gt;&lt;p&gt;
When updating the captured image, you need to process the image again with your Gimp or whatever. This should be done automatically! I&amp;rsquo;m looking for a scripting language to do clever things. I&amp;rsquo;ve no idea on how to integrate it to Novelang &amp;ndash;&amp;nbsp;maybe some special files to avoid messing macro-instructions with content.
&lt;/p&gt;&lt;p&gt;
The language itself could be something like this:
&lt;/p&gt;&lt;pre&gt;
  {
    rescale( 40% )
    fade( SOUTHWEST, 3px )
  }
  ./my-image.png
&lt;/pre&gt;&lt;p&gt;
I want something clever with an explicit representation of pipeline processing. And, yes, it should be all in Java and with a GPL-compatible license. Am I asking too much here?
&lt;/p&gt;&lt;p&gt;
I&amp;rsquo;ve found an amazing software piece: &lt;a href="http://rsbweb.nih.gov/ij" &gt;ImageJ&lt;/a&gt;, a public domain tool for image processing with huge amount of macros and plugins. It seems widely used for science. Bad news, image transparency &lt;a href="http://homepages.inf.ed.ac.uk/s9808248/imagej/unpack"&gt;doesn't look&lt;/a&gt; like a great concern. The &lt;a href="http://imagejdocu.tudor.lu/doku.php?id=plugin:utilities:alpha_channel:start"&gt;Alpha Channel plugin&lt;/a&gt; is the best I&amp;rsquo;ve found so far with its rough edges.
&lt;/p&gt;&lt;p&gt;
NetKernel has a &lt;a href="http://www.1060research-server-1.co.uk/docs/2.0.6/book/declarative/doc_map_Images.html"&gt;pipeline image processing&lt;/a&gt; feature that looks like what I want. But I don&amp;rsquo;t like their everything-is-a-String approach.
&lt;/p&gt;&lt;p&gt;
Maybe I shouldn&amp;rsquo;t be so ambitious, and just start hacking &amp;ldquo;the smallest thing that could possibly work&amp;rdquo; for solving my own problem instead of looking for a save-the-world solution.
&lt;/p&gt;&lt;p&gt;
By the way, this is an interactive &lt;a href="http://weblogs.java.net/blog/zixle/archive/2006/07/beanshell_2d_in.html"&gt;rendering effect editor&lt;/a&gt; based on BeanShell that may ease some pain while hacking image filters.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7220271826703706978?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7220271826703706978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7220271826703706978' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7220271826703706978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7220271826703706978'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/image-processing.html' title='Image processing'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-6284217411061516301</id><published>2009-05-28T14:43:00.001+02:00</published><updated>2009-05-28T14:45:07.651+02:00</updated><title type='text'>Space character and related stuff</title><content type='html'>&lt;p&gt;
&lt;b&gt;Blocks of literal&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
Most of times, the text inside blocks of literal should be kept in one piece. A blatant example is a numeric value and its unit.
&lt;/p&gt;&lt;p&gt;
Compact several spaces into one for the same reason as above.Trim leading and trailing spaces. Otherwise they offer a suspicious mean to override text layout.Replace spaces by non-break spaces.
&lt;/p&gt;&lt;p&gt;
With the low line character &lt;code&gt;_&lt;/code&gt; figuring the no-break space we&amp;rsquo;d like to obtain such transformation:
&lt;/p&gt;&lt;pre&gt;
` 20   m  ` -&gt; `20_m`
&lt;/pre&gt;&lt;p&gt;
This means a long block of literal with several spaces (transformed into no-break spaces) could become very cumbersome and mess the layout. So we need a hint to allow line breaks at some places. This can be done by splitting the big block of literal into several small ones, which are not separated by spaces.
&lt;/p&gt;&lt;p&gt;
With the vertical bar character | figuring the zero-width space we have such transformation:
&lt;/p&gt;&lt;pre&gt;
   `Y.O.U.``A.R.E.``B.E.A.U.T.I.F.U.L` 
-&gt; `Y.O.U.|A.R.E.|B.E.A.U.T.I.F.U.L`
&lt;/pre&gt;&lt;p&gt;
See more about the zero-width space &lt;a href="http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Grapheme_joiners_and_non-joiners"&gt;here&lt;/a&gt;. A quick test shows that FOP supports it.
&lt;/p&gt;&lt;p&gt;
Implementation will be done at tree-mangling level. A whitespace between two consecutive blocks of literal will be replaced by a special node meaning that a break is allowed here. The special node will be replaced by a no-width space at rendering time.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;
Apostrophe
&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;
This technique could be useful to keep apostrophe character stuck to a word when in last position. By now, Novelang does not take care of the whitespace after or before the apostrophe.
&lt;/p&gt;&lt;pre&gt;
he's here     -&gt; he’s here
houses' roofs -&gt; houses’roofs
during '60    -&gt; during’60
&lt;/pre&gt;&lt;p&gt;
This is because whitespaces are used as separators, but don&amp;rsquo;t cary &amp;ldquo;real&amp;rdquo; information (except in a few cases, like indentation for embedded lists). Before discarding &lt;code&gt;WHITESPACE&lt;/code&gt; nodes, the ones immediately preceding or following an apostrophe could become an &lt;code&gt;EXPLICIT_WHITESPACE&lt;/code&gt; to be rendered as, yes, a space character.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-6284217411061516301?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/6284217411061516301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=6284217411061516301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6284217411061516301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/6284217411061516301'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/space-character-and-related-stuff.html' title='Space character and related stuff'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2479099798293527971</id><published>2009-05-27T00:00:00.003+02:00</published><updated>2009-05-27T00:11:38.297+02:00</updated><title type='text'>Pretty color palette for tags</title><content type='html'>&lt;p&gt;
Default representation of tags attempts to help locating them at a glance, with nice colors. &amp;ldquo;Nice colors&amp;rdquo; means a lot of care.
&lt;/p&gt;&lt;p&gt;
Defining a color palette from scratch is tricky. Colors must be dinstiguishable one from the other. They must spread evenly on the visible spectrum; but this is not easy because the visual effect depends on the display. For this reason, I use the &lt;a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords"&gt;140 colors&lt;/a&gt; of the SVG specification (the same are used in the CSS spec). Much of hard work is done here, including finding pretty names.
&lt;/p&gt;&lt;p&gt;
But that&amp;rsquo;s not all. Because the small rectangle of the tag has text, too, there must be a foreground color. First I tried to compute it, using a simple algorithm (increasing Red, Green and Blue of 50% each and applying modulus 255). The text was always barely readable. Not really good.
&lt;/p&gt;&lt;p&gt;
Another problem was the choice of the color for each tag. I&amp;rsquo;ve chosen to pick the color of each tag in a predefined list. When all the colors have been set, we start from the start again. This round-robin algorithm for chosing colors is ok, but inside the 140 colors, many look quite the same. Colors like mistyrose and lavenderblush are very close, and if we have only 10 tags, it&amp;rsquo;s a pity to see two tags looking the same. So it makes sense to edit the color list in order to make the first one look very different. In addition, because those first colors will be picked up the most often, they must be in the same tone (mild saturation).
&lt;/p&gt;&lt;p&gt;
If there are more than 10 or 20 tags, similar colors will be unavoidable, finally. But, since we display text (and a thin border) there is a foreground color to chose. This gives (140 × 139) 19460 possibilities! Of course background and foreground cannot be the same (hence the 139) and many possibilities are unreadable. But, given a color like white, those colors look quite similar: mintcream, honeydew, ghostwhite, floralwhite, seashell, azure, linen, aliceblue, cornsilk, oldlace, ivory, snow, whitesmoke. Wow!
&lt;/p&gt;&lt;p&gt;
Maybe there is a clever algorithm to detect which foreground colors give best contrast &lt;em&gt;and&lt;/em&gt; distinguishability, but I didn&amp;rsquo;t find it. It seems much more convenient to let a human do the job.
&lt;/p&gt;&lt;p&gt;
Since editing some lines of code would require to switch back-and-forth between the code editor and the web browser, I wrote a palette editor based on a HTML page. It looks like this:
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/ShxnBq7V7fI/AAAAAAAAAMA/cHxv0KQkw58/s800/All-tags.png" /&gt;
&lt;p&gt;
It&amp;rsquo;s easy to change the order of appearance of a color with a drag and drop:
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/ShxnekzxHQI/AAAAAAAAAMI/pOtHg37OtsE/s800/Moving-color.png" /&gt;
&lt;p&gt;
And, after clicking on one color, you set the foreground with an &lt;code&gt;alt-click&lt;/code&gt; on wished color.
&lt;/p&gt;&lt;p&gt;
Don&amp;rsquo;t forget to save using the Save button (File &gt; Save in Web browser&amp;rsquo;s menu won&amp;rsquo;t work). Yes, the color palette editor only runs on Firefox by now.
&lt;/p&gt;
&lt;img src="http://lh3.ggpht.com/_c-k7nfw_Y8o/ShxnBy8fwnI/AAAAAAAAAME/CyuEzKQ0g54/s800/Save.png" /&gt;
&lt;p&gt;
The color palette is located in:
&lt;/p&gt;
&lt;pre&gt;src/main-resources/style/javascript/colors.htm&lt;/pre&gt;
&lt;p&gt;
This new feature (and the beautiful color palette) will be available in the next release of Novelang (0.29.0).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2479099798293527971?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2479099798293527971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2479099798293527971' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2479099798293527971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2479099798293527971'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/pretty-color-palette-for-tags.html' title='Pretty color palette for tags'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_c-k7nfw_Y8o/ShxnBq7V7fI/AAAAAAAAAMA/cHxv0KQkw58/s72-c/All-tags.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7362444048961351302</id><published>2009-05-24T15:53:00.002+02:00</published><updated>2009-05-24T15:56:11.658+02:00</updated><title type='text'>Novelang-0.28.0 released!</title><content type='html'>&lt;p&gt;
Latest release available &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Now tags are handled as query parameters. This is much faster on big documents, and it works for every kind of document.
&lt;/p&gt;
&lt;p&gt;
See documentation for details, and the list of other enhancements.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7362444048961351302?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7362444048961351302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7362444048961351302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7362444048961351302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7362444048961351302'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/novelang-0280-released.html' title='Novelang-0.28.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8718014624839786273</id><published>2009-05-17T22:26:00.003+02:00</published><updated>2009-05-28T14:47:33.645+02:00</updated><title type='text'>Missing closing delimiters</title><content type='html'>&lt;p&gt;

By now, a block with a missing closing delimiter was properly detected as an error, but the error message was ugly. See, for this:
&lt;/p&gt;&lt;pre&gt;

Something -- missing

&lt;/pre&gt;&lt;p&gt;

You got:
&lt;/p&gt;&lt;pre&gt;

line 0:-1 mismatched input '' expecting HYPHEN_MINUS

&lt;/pre&gt;&lt;p&gt;

Not a great deal here, but pretty annoying in a 1000-line long source document.
&lt;/p&gt;&lt;p&gt;

After a close look, it looked very complex to determine where the error was coming from. Considering this case:
&lt;/p&gt;&lt;pre&gt;

There " is ( something " missing

&lt;/pre&gt;&lt;p&gt;

… The problem is obviously with the unclosed parenthesis. It&amp;rsquo;s easy to see (for a human) because parenthesis are &lt;em&gt;paired&lt;/em&gt; delimiters: there is an opening and a closing one. The double quotes &lt;code&gt;"&lt;/code&gt; is &lt;em&gt;single&lt;/em&gt; in the sense it may be used for both opening and closing a block, depending on the context. In the example above, the Novelang parser started evaluating a parenthesized block, and the double quote looked like an unclosed block. How to handle this correctly?
&lt;/p&gt;&lt;p&gt;

&amp;mdash;&amp;nbsp;In order to avoid grammar bloat, the grammar emits some kind of events, telling it started parsing a block with such or such delimiter. The position of every token for a start delimiter is kept. If something goes wrong, the error message(s) will report the position of the unclosed delimiter.
&lt;/p&gt;&lt;p&gt;

&amp;mdash;&amp;nbsp;Event consistency check is scoped: if an unclosed delimiter is detected inside a paragraph, this should have no influence on the way unclosed delimiters are handled inside another paragraph.
&lt;/p&gt;&lt;p&gt;

&amp;mdash;&amp;nbsp;When trying to figure where is the opening delimiter with no closing counterpart, the trick is, to look at paired delimiters first. If something went wrong with paired delimiters, just report the errors about them. Otherwise, report errors with single delimiters.
&lt;/p&gt;&lt;p&gt;

I just checked this new feature into Github and the results are pretty good. Given source document like this (line numbers added for clarity):
&lt;/p&gt;&lt;pre&gt;
1   ( s
2  t -- u
3  v )
4  
5  // w
6  x [ y
7  z //
&lt;/pre&gt;&lt;p&gt;

Instead of a bunch of nonsense, Novelang now returns following problems:
&lt;/p&gt;&lt;pre&gt;

2:2: Missing delimiter. For '--' there should be a matching '--' or '-_'
7:4: no viable alternative at input '\n'
6:2: Missing delimiter. For '[' there should be a matching ']'

&lt;/pre&gt;&lt;p&gt;

This will be available in the next version (0.28.0). Keep informed reading this blog!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8718014624839786273?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8718014624839786273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8718014624839786273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8718014624839786273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8718014624839786273'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/missing-closing-delimiters.html' title='Missing closing delimiters'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-1075576636635560182</id><published>2009-05-10T20:16:00.003+02:00</published><updated>2009-05-11T15:45:23.101+02:00</updated><title type='text'>Novelang-0.27.1 released!</title><content type='html'>&lt;p&gt;
Just a fix after I messed MIME type for rendered documents. 
As usual, available &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-1075576636635560182?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/1075576636635560182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=1075576636635560182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1075576636635560182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/1075576636635560182'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/novelang-0271-released.html' title='Novelang-0.27.1 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2196409793241278801</id><published>2009-05-10T19:20:00.004+02:00</published><updated>2009-05-17T22:28:58.296+02:00</updated><title type='text'>Novelang-0.27.0 released!</title><content type='html'>&lt;p&gt;
Latest release available &lt;a href="herehttp://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Novelang-0.27.0 enhances the tag feature with standard HTML stylesheet displaying the list of user-defined tags. In a source document, tags are words preceded by an arrobas &lt;code&gt;@&lt;/code&gt;. Levels, paragraphs, paragraphs inside angled bracket pairs (aka blockquotes) and cell rows (aka tables) may be tagged.
&lt;/p&gt;&lt;pre&gt;
  @javascript @performance
By now this feature all relies on Javascript 
running inside the Web browser.  
&lt;/pre&gt;&lt;p&gt;
HTML generated using default stylesheet renders tags like this, with a nice color set making tags distinguishable at a glance:
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/SgcOQnja5fI/AAAAAAAAALg/StxfQsxmCJU/s800/tags-decorating-text.png"/&gt;
&lt;p&gt;
It is now possible to hide all the text which is not tagged, selecting tags in a list which appear on topright corner of HTML document, with a fixed position that keeps it always visible and a disclosure box which hides the list by default:
&lt;/p&gt;
&lt;img src="http://lh4.ggpht.com/_c-k7nfw_Y8o/SgcOQ_qtN_I/AAAAAAAAALk/11S96f6j1BA/s800/tag-list.png" /&gt;

&lt;p&gt;
If a level or a set of paragraphs inside angled bracket pairs do have at least one of requested tags, it is displayed with all of its content. If a paragraph has at least one of requested tags, it is displayed, as all its parents (levels or set of paragraphs).
&lt;/p&gt;&lt;p&gt;
By now this feature all relies on Javascript running inside the Web browser. This doesn&amp;rsquo;t scale on big documents (with lots of paragraphs and levels). For some big document with HTML generation taking about 13 s, selecting one tag takes more than 70 s and triggers several &amp;ldquo;slow script&amp;rdquo; warnings.
&lt;/p&gt;&lt;p&gt;
A more suitable approach would be to trim the AST (Abstract Syntax Tree) server-side. This requires passing parameters to the query. Because of pre-rendering processing, tag-based filtering would work for any other other format than HTML for free.
&lt;/p&gt;&lt;p&gt;
There would be less to do in Javascript; it would just update the tag list in order to reflect document&amp;rsquo;s state.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2196409793241278801?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2196409793241278801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2196409793241278801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2196409793241278801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2196409793241278801'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/05/novelang-0270-released.html' title='Novelang-0.27.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_c-k7nfw_Y8o/SgcOQnja5fI/AAAAAAAAALg/StxfQsxmCJU/s72-c/tags-decorating-text.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-7013652403007760809</id><published>2009-04-25T07:58:00.002+02:00</published><updated>2009-04-25T08:07:17.702+02:00</updated><title type='text'>Novelang-0.26.0 released!</title><content type='html'>&lt;p&gt;
Latest release available &lt;a href="https://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Outstanding new feature: &lt;b&gt;tags&lt;/b&gt;. Now you can tag some pieces of the source documents with arbitrary labels:
&lt;/p&gt;
&lt;pre&gt;
  @my-tag  @foo
This is a tagged paragraph.
&lt;/pre&gt;
&lt;p&gt;
Novelang's default HTML stylesheet generates pretty colorful tags in the margin, and a tag summary at the end.
It's intended to be for humans but stylesheets may take advantage of tags, too.
&lt;/p&gt;
&lt;p&gt;
See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-7013652403007760809?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/7013652403007760809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=7013652403007760809' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7013652403007760809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/7013652403007760809'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/04/novelang-0260-released.html' title='Novelang-0.26.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-2223641411026568558</id><published>2009-04-14T10:14:00.002+02:00</published><updated>2009-04-14T10:17:03.535+02:00</updated><title type='text'>Novelang-0.25.0 released!</title><content type='html'>&lt;p&gt;Latest release available &lt;a href="https://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
This version brings &lt;a href="http://novelang.blogspot.com/2009/04/named-url-try-again.html"&gt;relaxed syntax&lt;/a&gt; to associate names to URL:
&lt;/p&gt;
&lt;pre&gt;
Go to the "website"
http://novelang.sourceforge.net
&lt;/pre&gt;
&lt;p&gt;
See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-2223641411026568558?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/2223641411026568558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=2223641411026568558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2223641411026568558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/2223641411026568558'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/04/novelang-0250-released.html' title='Novelang-0.25.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-8287042973598190785</id><published>2009-04-12T23:45:00.001+02:00</published><updated>2009-04-12T23:46:56.973+02:00</updated><title type='text'>Novelang-0.24.0 released!</title><content type='html'>&lt;p&gt;
Latest release of Novelang available &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=227480&amp;package_id=275418"&gt;here&lt;/a&gt;. This version brings embedded lists. See documentation for details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-8287042973598190785?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/8287042973598190785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=8287042973598190785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8287042973598190785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/8287042973598190785'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/04/novelang-0240-released.html' title='Novelang-0.24.0 released!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2606986058284855798.post-3772584906919133663</id><published>2009-04-09T10:29:00.002+02:00</published><updated>2009-04-09T10:39:01.288+02:00</updated><title type='text'>Named URL: try again!</title><content type='html'>&lt;p&gt;
With Novelang-0.23.0 comes a new feature: named URL. The purpose is to associate some text to a URL, in order to let the stylesheet display something nicer than the URL itself. With source document like this:
&lt;/p&gt;&lt;pre&gt;
This is a 
  "url"
http://url.net/my-very-long-path
.
&lt;/pre&gt;&lt;p&gt;
… we get:
&lt;/p&gt;&lt;blockquote&gt;
This is a &lt;a href="http://url.net/my-very-long-path"&gt;url&lt;/a&gt;.
&lt;/blockquote&gt;&lt;p&gt;
The rationale of &lt;a href="http://novelang.blogspot.com/2008/08/url-syntax.html"&gt;this syntax&lt;/a&gt; is the consistency with &lt;a href="http://novelang.blogspot.com/2008/06/more-on-identifiers.html"&gt;decorations&lt;/a&gt;. Decorations are source metadata that is conveniently &lt;em&gt;before&lt;/em&gt; decorated source, appearing on its own single line and with some indentation for the visual comfort. It seemed a good idea to follow the same scheme.
&lt;/p&gt;&lt;p&gt;
But the syntax described above has many drawbacks.
&lt;/p&gt;&lt;p&gt;
First, it&amp;rsquo;s very space-consuming. The scarce resource is the vertical space inside the text editor, because you cannot stretch the display device in height (and long horizontal lines are hard to read). So text like this seems to waste space:
&lt;/p&gt;&lt;pre&gt;
This is
  "url one"
http://url.net/1
and here is 
  "url two"
http://url.net/2
.  
&lt;/pre&gt;&lt;p&gt;
URL must appear on their very own line, for already discussed reasons, so the full stop character at the end must stay as it is. The problem is with the blocks inside double quotes: it&amp;rsquo;s supposed to remain short, so reserving a whole line for it is obviously a waste. Finally I&amp;rsquo;d like to write text like this:
&lt;/p&gt;&lt;pre&gt;
This is "url one"
http://url.net/1
and here is "url two"
http://url.net/2
.  
&lt;/pre&gt;&lt;p&gt;
One question then arises: how to distinguish a block associated to a URL from one which is not? After all you &lt;em&gt;may&lt;/em&gt; need to display some text in double quotes right before some URL. First I thought about a new &amp;ldquo;attach&amp;rdquo; operator which would tell explicitely that some block inside double quotes is related to the following URL:
&lt;/p&gt;&lt;pre&gt;
Stupid: "url" ~
http://url.net
&lt;/pre&gt;&lt;p&gt;
This is not a good idea because experience shows that, 99 % of times, the block is related to the following URL. So it makes no sense to make the most common case a special thing which breaks the consistency of the grammar. And what if the text of the URL should appear inside double quotes? Is there some new clever escape mechanism to invent?
&lt;/p&gt;&lt;p&gt;
Corresponding Abstract Syntax Tree is also broken, in the sense where &lt;code&gt;n:external-link&lt;/code&gt; and &lt;code&gt;n:link-title&lt;/code&gt; nodes do carry semantic meaning, while I claim everywhere that such meaning is confusing when stylesheet defines alternate meaning. The &lt;code&gt;n:external-link&lt;/code&gt; was a clever idea to wrap the URL and the title in one single element, but I should find something else.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;
The solution
&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
When a block inside double quotes, or a block inside square brackets, are located right before a URL, they become URL children. Considering such source document:
&lt;/p&gt;&lt;pre&gt;
This is a ["url"]
http://url.net
.
&lt;/pre&gt;&lt;p&gt;
… we get something like this (consistent with stylesheet&amp;rsquo;s rendering of block inside double quotes):
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;
This is a &lt;a href="http://url.net"&gt;&amp;ldquo;url&amp;rdquo;&lt;/a&gt;.
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;
In the rare case where a block inside double quotes must appear verbatim, we &amp;ldquo;break&amp;rdquo; the proximity with some &amp;ldquo;invisible&amp;rdquo; character which is an empty block of literal inside grave accents. That&amp;rsquo;s a little weird but it&amp;rsquo;s not a problem as it should remain the exception:
&lt;/p&gt;&lt;pre&gt;
That's a "url" ``
http://url.net
&lt;/pre&gt;&lt;p&gt;
… so it renders like this:
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;
That&amp;rsquo;s a &amp;ldquo;url&amp;rdquo; &lt;a href="http://url.net"&gt;http://url.net&lt;/a&gt;.
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;
Finally, the &lt;code&gt;n:external-link&lt;/code&gt; disappears in favor of &lt;code&gt;n:url&lt;/code&gt;. The &lt;code&gt;n:link-title&lt;/code&gt; becomes a &lt;code&gt;n:block-inside-double-quotes&lt;/code&gt; or &lt;code&gt;n:block-inside-square-brackets&lt;/code&gt;. The text of the URL gets wrapped inside a &lt;code&gt;n:url-literal&lt;/code&gt; and that&amp;rsquo;s all.
&lt;/p&gt;&lt;pre&gt;
n:url
  + n:url-literal
  + n:block-inside-double-quotes
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2606986058284855798-3772584906919133663?l=novelang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://novelang.blogspot.com/feeds/3772584906919133663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2606986058284855798&amp;postID=3772584906919133663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3772584906919133663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2606986058284855798/posts/default/3772584906919133663'/><link rel='alternate' type='text/html' href='http://novelang.blogspot.com/2009/04/named-url-try-again.html' title='Named URL: try again!'/><author><name>Laurent Caillette</name><uri>http://www.blogger.com/profile/02771404788303028391</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
