Too Much Documentation?
2012-01-22
When trying to run ‘make distcheck’ on gnome-user-docs, I got this error:
make[1]: execvp: /bin/sh: Argument list too long
This roughly translates to “You have so much documentation translated into so many languages that your poor build system can’t handle it.” Congratulations to everybody involved in reaching this wonderful error.
Update: I’ve added a custom distdir target to yelp.m4 to fix this problem. If you maintain a package with a large document and a lot of translations (gnome-user-docs, ubuntu-docs), install yelp-tools 3.3.2 before making your next release. You may need to run ‘make distclean’ and rebuild completely to get the new build rules.
Mobile Mallard and Conditional Processing
2012-01-17
Last time, I gave a demo of a Mallard document rendered in a way that adapts to handheld devices like phones. Because Mallard is not a presentational language, most of the formatting can be adjusted automatically, and authors don’t have to worry about anything. But sometimes, you really do want to change the content when viewing on a handheld device.
First, though, let’s look at some specific formatting differences between desktop and mobile. For each of the pages below, click the ‘Desktop’ and ‘Mobile’ links above the iframe to see the difference.
- Desktop Help – The purely decorative hover previews are turned off for mobile. (Good luck hovering with your finger anyway.) Also, the three-column grid changes to a two-column grid.
- Delete files and folders – The notes and step lists use all the available horizontal space. The automatic links at the bottom fill the whole page width as well.
- Sound, video & pictures – The two-column link layout changes to a single column, and the link boxes span the entire page width, making them easier to tap.
But sometimes we add content that’s visually helpful on large screens, but cumbersome at small sizes. Things like screenshots are often nice to have, as long as they don’t get in the way. This is where conditional processing comes into play. I’ve been busy retooling Mallard conditional processing to allow things like this:
<media src="figures/shell-top-bar.png" if:test="!target:mobile"/>
The result is an image that’s only displayed in non-mobile reading environments. Switch between desktop and mobile on these pages to see it in action:
This isn’t limited to images, of course. You can use conditional processing on any block element or list item. What’s more, Mallard conditional processing allows full branching and fallback, giving you an easy way to display one thing for the desktop, and something else for mobile.
Mobile Help With Mallard
2012-01-12
Don’t want to read? Skip to the Mobile Mallard demo.
As people use more and more mobile devices, it’s important that we can deliver help in a way that feels comfortable to users. It’s not just about help for mobile apps. Look at any book on documentation from the 80s or 90s and you’ll see an example about a field technician using documentation differently than an office worker. But now people are increasingy using phones and tablets to read documentation for everything, including devices in the world around them.
Mallard is already a natural choice for creating help to deliver on mobile platforms. Its focus on small, focused topics and its decidedly non-book-like navigation structure fit comfortably on a small screen, and its minimalist structured markup means you can easily adapt it to new needs without carrying a bunch of legacy baggage.
But the design we use for large, mouse-driven screens don’t always feel right on small, finger-driven devices. We use multi-column links that feel scrunched on small screens. We have purely decorative link previews on hover that you can’t even get to with your finger. We have margins and padding that are refreshing on large displays, but they just keep you from seeing more content on your phone. Luckily, Mallard doesn’t specify these kinds of presentation details, so we can make help that adapts to the form factor you’re viewing it on.
Check out the Mobile Mallard demo to see the initial work on making Mallard documents more suitable for mobile devices. This is still very early work, and it needs a lot of real-world testing. The next step is to use Mallard conditional processing to allow you to actually control what content is shown on mobile devices.
Help With MariaDB Docs
2011-12-02
Know stuff about databases and SQL? Then we could use your help on the Knowledgebase for MariaDB. MariaDB is a community-developed fork of the popular MySQL database (now owned by Oracle). A top-notch database deserves top-notch documentation, and a community project needs contributors like you and me.
Getting involved is easy. Just create an account or log in with your existing OpenID account. Then pick a page and start editing. And don’t forget to keep in touch. Join the #maria channel on Freenode, and join the Maria Docs group and mailing list on Launchpad. Don’t forget to introduce yourself!
We’re working on getting a public TODO list online to make it easier to contribute. Until then, here’s a short list of things you can help with:
- CREATE TABLE
- Add a section about PRIMARY KEY. Include a brief description of what it does. Provide a reference for both the PRIMARY KEY keyword on a single column and defining multi-column keys.
- Add a section about FOREIGN KEY and REFERENCES. Include a brief description of what it does. Provide a reference for both the REFERENCES keyword on a single column and defining multi-column foreign keys.
- Add a section about INDEX, including SPATIAL and FULLTEXT. (Should these have separate sections? It depends on how full the sections get.) It’s probably worth putting all the detailed information about indexes on the CREATE INDEX page and just link there from CREATE TABLE and ALTER TABLE.
- Create a section describing TEMPORARY tables.
- Write documentation for the various table options and the partition options. Some of these require more in-depth experience using MariaDB or MySQL.
- CREATE EVENT
- Explain the various SCHEDULE options thoroughly, possibly with examples.
- Explain the time units.
- Explain the ON COMPLETION, ENABLE, and DISABLE keywords.
- CREATE DATABASE
- Write documentation about CHARACTER SET and COLLATE.
This is just a sampling of a few easy places to get involved. I have more; ping me (shaunm) on IRC. Or leave a comment here.
Mallard and EPUB
2011-11-10
Did you know you can easily convert a Mallard document into an EPUB file? It’s built right into Yelp Tools, the collection of documentation tools built on top of the core of the Yelp help viewer. Install yelp-tools from your package manager and run the following command in a directory containing Mallard page files:
yelp-build epub .
If you have Yelp customization stylesheets you use for the web, you can use them for your EPUB output too. Or you can create customizations to better fit the form factor of an e-book reader. Of course, as with everything from Yelp, the formatting is non-ugly by default.
Don’t forget that a Mallard document is just a collection of pages that link among themselves dynamically. If you want to publish an EPUB of only certain pages (for example, to provide your accessibility topics for people to read from another device), just limit it to only the pages you want. There’s no need to hand-edit a driver file.
Searchable Menu Video
2011-10-25
For some reason, blogs.gnome.org doesn’t let me upload webm or ogv files. Go watch a video of searchable menus on Google+. Some notes on what’s going on:
- The initial menu items are not specified by Nautilus. The menu is populated with items based on tags in the Mallard help files.
- Start typing to search. This is searching on title and desc elements from the GNOME desktop help. The results are filtered to only include pages relevant to Nautilus. The scroll arrows showing momentarily as you type is an unfortunate glitch I hope to iron out.
- Click a topic and Yelp opens immediately to that topic.
- What’s more, Yelp knows that you arrived there from a menu item you got after searching in a menu, and offers a link at the top to perform a full text search on your search terms.
Searchable Help Menu
2011-10-20
New Cree LEDs
2011-10-03
For the last year and a half, I’ve been slowly transitioning all the lighting in my house to high-power LED lamps. I love LEDs. They’re energy efficient and they light the room as if it were broad daylight. You don’t have to live with CFLs to get energy-efficient lighting.
The downside, of course, is the cost. LED lighting is still fairly new, and as with any new technology, it’s still fairly expensive. I definitely consider myself an early adopter. But just like computers and cell phones, I think the day will come when virtually everybody uses LED lighting. It’s just better.
I have a lot of recessed lighting in my house, including 30 six-inch canisters, and the LED replacements for these are about $50 per light. So I was really excited to discover that Cree holds a monthly contest to give away five CR6 lamps. I won the August contest, and my new lights have just arrived:
I had three of these in my house already, plus one similar light from another manufacturer. (If you’re in the US, Home Depot rebrands these lights under the EcoSmart brand.) With these bulbs, all of the overhead lighting in my kitchen is now LED.
Installation is really easy. First, remove the old bulb, the trim, and the brackets holding the socket in place. The trim is usually held on with a couple of springs, and the brackets with a single thumb screw.
(Funny story: Just after I took this picture, I accidentally dropped this CFL bulb on the floor and spent the next hour trying to make sure my kitchen is mercury-free. Just say no to fluorescent.)
Screw in the LED module, then push it into the canister. The prongs will hold it in place. If it feels loose against the ceiling, give it a slight clockwise turn to tighten it up.
That’s five more lights finished, thanks to Cree. Next on my list is the master bedroom.
My Helpful Help Presentation
2011-08-06
Earlier today, I gave my talk, Helpful Help, at the Desktop Summit. Unfortunately, there were technical issues with the projector and the video. So nobody saw my slides, and there’s no recording of my talk. My slides are an image-heavy HTML application, but I’ll work on a PDF export for desktopsummit.org. (I am in the business of document tools, after all.) But since there’s no recording, I thought I’d recap the talk in a blog post.
In his keynote session earlier in the morning, Dirk Hohndel related some of his grief in finding documentation. I spent a couple minutes addressing his points. I asked how many in the audience wrote code for GNOME or KDE, and how many of them are professional programmers. Most were. I then asked how many did any documentation work, and how many were professional technical writers. Unsurprisingly, most documentation contributors are not professionals. I have a book’s worth of thoughts on making great documentation with few or no expert writers, but that’s another talk entirely.
I did make the point that single pain points in documentation can leave a worse impression than in software. People don’t usually spend a lot of time looking at the documentation, so if the one experience they had was negative, they’ll have a bad impression, even if the rest of the documentation is stellar. In software, an overall great experience can help users forget about small pain points.
I went on to tell people to stop thinking about books. There’s an allure to books. Writers aspire to be published. Entire books feel like an accomplishment. And while I think there are places for books, if you approach your help from the book world view, it seriously limits the kind of innovation you can do.
Instead, I encourage people to think in topics.Topics don’t have to be text topics. They don’t have to be in Mallard or DITA or DocBook 5.2. I have three rules for what makes good topic-oriented help: 1) Each topic is self-contained and contains only the information that’s necessary. 2) Topics can be navigated and found using a model that makes sense to the user. Notably, topics need to be able to appear in multiple places in the navigation. 3) Topics are heavily cross-linked so that users can explore if they want to.
With that, I jumped into various hare-brained ideas on things people could be doing with help. Some of these are things I’m actively exploring. Some of them are things I want to explore. Some of them are things I hope others will pick up. I was not giving people solutions. I was trying to plant seeds in people’s minds so they’ll start exploring new ideas in help.
I talked about inlining help. This is the focus of the GLib/GTK+ help API I’ve been working on. See my recent post to gtk-devel-list for details. The idea is to bring the help into the application. Rather than having the help live in a separate viewer, we can make applications fully aware of their help. Help menus and buttons be dynamically populated. Help can be searched directly within the application. We can do super-tooltips much more superly.
I talked about interactive help. I talked about this last year, and it’s a favorite topic of mine. Applications that have a roughly document-like interface lend themselves to doing the help within the interface itself. And when you do that, you can make the help live, so users can explore your application from within the help, rather than using the help passively. The Inkscape tutorials are a great example of this.
I also talked about image and video help. There’s nothing new about using screenshots, and even screencasts are old-hat by now. But they’re still very passive. I talked about how technologies like HTML5 can empower us to create videos that tightly integrate with the text content and the rest of the help.
I then talked about using games as a learning tool. Games are generally not going to be good for on-demand help. But they can be good for exploratory learning. If you make learning fun, people will do it, especially for applications that people consider important to their life or job. I’m not in the habit of promoting Microsoft, but I pointed out Ribbon Hero 2 as a fantastic learning game. Google it.
In every talk I give, I promise the audience two things: They will see XML markup, and they will see pictures of ducks. Without a projector, nobody saw markup or ducks. So go read some Mallard markup, then look at this duck picture:
Understanding XInclude
2011-07-21
I’m often surprised when people don’t know about XInclude, but I suppose not everybody eats and breathes XML the way I do. XInclude is a way to include other files (or portions of other files) into a single XML file. We actually use them throughout GNOME documentation, though few people realize it. XInclude isn’t tied to any particular XML vocabulary like Mallard or DocBook. It’s an XML feature defined by the W3C, and you can use it in any XML file, as long as your processing tools support it.
If you’ve used SYSTEM entities in XML before, it’s important to understand a key difference. (If you haven’t, skip this paragraph.) SYSTEM entities are a pre-parse text slurp. The text of the included file are inserted, byte-for-byte, at the inclusion point, and the resultant run of characters is then parsed. With XInclude, the included file is parsed, and its infoset is merged into the inclusion point.
Basic XInclude
The simplest use of XInclude is to include the entirety of an external XML file. We use this in many of our Mallard and DocBook documents to include common legal information. In gnome-help, for example, we have a file called legal.xml that looks like this:
<license xmlns="http://projectmallard.org/1.0/"> <p>Creative Commons Share Alike 3.0</p> </license>
Then, in the info element of every page file, we use this:
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
When the file is parsed, the entirety of the license element from legal.xml is inserted in place of the include element.
Text XInclude
By default, XInclude expects the included file to be well-formed XML. You can tell it to treat the file as text instead. This is useful if you want to show the text contents of a file, such as inside a Mallard code element.
Just add parse=”text” to the XInclude element, like so:
<include href="somefile.txt" parse="text" xmlns="http://www.w3.org/2001/XInclude"/>
I use this on the source pages of the tutorials on projectmallard.org. Look at the Ten Minute Tour Source page, for example. This shows the entire XML source of the Ten Minute Tour inside a Mallard code block.
The XML markup for the Ten Minute Tour Source page uses a text XInclude. The nice thing about this is that you don’t have to worry about escaping characters in the included file. So if you’re writing a lot of code examples with angle brackets, text XIncludes can be a convenient alternative to escaping or using CDATA blocks.
It’s important to note that an XInclude processor does not care what the file extension or reported MIME type of the included file is. The file is either parsed as XML or as text, and this depends solely on the parse attribute.
Parts of Documents
In the first example, we included a single standard element. You might wonder if you can include lots of boilerplate element. If all the pages in a document share the same authors, you might want to put them all in one file and XInclude them in.
<credit><name>Shaun McCance</name></credit> <credit><name>Phil Bull</name></credit> <credit><name>Jim Campbell</name></credit>
If you put this into a file and try to XInclude it, you’ll get an error. Any file you XInclude (with the XML parse type) must be fully well-formed XML. Among other things, that means there must be a single root element. The example above has three root elements. So just wrap them with another element:
<info xmlns="http://projectmallard.org/1.0/"> <credit><name>Shaun McCance</name></credit> <credit><name>Phil Bull</name></credit> <credit><name>Jim Campbell</name></credit> </info>
Notice also that you do need the xmlns declaration to use namespaces. This will now parse, and XInclude works. But you’ll have an extra info element nested in the including document’s info element. That’s not right.
You can include only a portion of the included XML using XPointer. XPointer is a W3C syntax for pointing to pieces of documents. There are different schemes you can use with it to select data in different ways, but we’ll just stick to the xpointer() scheme, which uses XPath. The basic syntax looks like this:
<include href="credits.xml" xpointer="xpointer(/info/credit)" xmlns="http://www.w3.org/2001/XInclude"/>
This won’t work, however, because we’re using XML namespaces. You need to declare a namespace prefix and use it in your XPath. To do that, use the xmlns() XPointer scheme:
<include href="credits.xml" xpointer="xmlns(mal=http://projectmallard.org/1.0/)xpointer(/mal:info/mal:credit)" xmlns="http://www.w3.org/2001/XInclude"/>
This does exactly what we need. We wrap the credit elements with an info element to make the included file well-formed. (It also gives us a convenient single place to declare namespaces.) Then we select only the credit elements to XInclude with an XPath expression. I won’t go into all the details of what XPath can do, but for simple cases like this, it looks basically like a directory path.
This does require you to keep and distribute an extra file. Instead of doing that, you could keep the information in one of your page files, then XInclude portions of that file in every other page file. Since every Mallard document has an index page, you could do this for index.page:
<page xmlns="http://projectmallard.org/1.0/"> <info> <credit><name>Shaun McCance</name></credit> <credit><name>Phil Bull</name></credit> <credit><name>Jim Campbell</name></credit> </info> <title>My Index Page</title> <page>
Then in every page except index.page, use this in the info element:
<include href="credits.xml" xpointer="xmlns(mal=http://projectmallard.org/1.0/)xpointer(/mal:page/mal:info/mal:credit)" xmlns="http://www.w3.org/2001/XInclude"/>
You might wonder if you can use XPointer to include only a portion of a file included with parse=”text”, such as a certain range of lines. XPointer allows extension schemes to be defined. In fact, there are a couple dozen schemes registered with the W3C. One of them allows you to select a string range from an XML file, although there is no registered scheme to select a range from a text file.
You don’t need a registered scheme, though. All you need is for your XML processor to understand the scheme you’re using. Unfortunately, libxml2 only supports the xpointer(), xmlns(), and element() schemes at this time. But if you really need this kind of functionality, you can probably hire an expert to implement it for you.









