Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
On the announcement page for Windows Live, it says: "Don't worry, MSN isn't going anywhere."
OPML -- reading list for Team Foundation started
You can just browse to http://msdn2.microsoft.com/library/ (fully qualified type name).
For example:
http://msdn2.microsoft.com/library/system.web.ui.webcontrols.textbox.aspx
A user, Susan, wants to learn how to publish documentation as a feed. She knows some of the technologies she will need, while some are new to her. At this point, she doesn't actually know what she will need to know, or why she will need to do this and that. She starts at a starting point, tautologically speaking. Actually, at this point I'm not sure just where that point "is".
Another user, Richard, has gone through the process of setting up a docFeed before. As he read how to do it, he made a record of what he looked at, and whether it was useful. In the fullness of time this will be automated some, using something akin to [[Attention]], but for now he does it manually (and time consumingly) using del.icio.us and his browser history. As his project moves along, he saves his Attention record for later harvesting to [[OPML]] or RSS. This outline is essentially the table of contents of the virtual doc set that he found useful. He saves his outline on the net just like any other web page, and gives it the title "What I need to know to publish a doc feed." Since Richard doesn't like technical writing any more, he hasn't contributed any new content to his document. It's really just collection of syndicated feeds and links with some metadata indicating how it can be ordered, searched, indexed.
Susan opens Richard's outline and scans the TOC to get a bird's eye view of the task, and looks for unfamiliar technologies she will have to learn. One of the technologies she will need is SimpleListExtensions (SLE), which defines how a set of topics can be arranged into a nested ordered list. This is how she will produce the TOC for her docfeed. She opens the SLE section of the TOC and sees the content Richard used to build his project. Some of that content is static, such as MSDN reference pages. Other parts are dynamic, such as old-fashioned blogs by ~SMEs, and more usefully, updated outlines that other experts have published.
The difference between the contents of the outline that Richard published, and the one that Susan is looking at, is that in between Richard publishing his outline and Susan starting, other users found there was some information missing that Richard took for granted. The outlines that Richard's outline consumes includes feeds for that missing content.
Susan keeps coming across the term microformat, and doesn't know what it means. She does a search for pages tagged as relating to microformats and docFeeds, and gets an outline of the feeds about microformats that the most other users have found useful. Reading this material, she has an epiphany and sees that outlines are a kind of microformat, and that her job is arrange her content in microformat packages.
She looks through Richard's docFeed and doesn't see anything relating to any microformats that appear relevant to her problem domain, so she has to do some searching. It takes her a while to track down an appropriate microformat and tools, and as she is doing this, she is recording her actions in an Attention file.
When she is satisfied that she has found the right microformat and tools for her job, she publishes an outline of the docs that she found useful.
Since the last post I've added caching to my ~MSDN2 to RSS converter, done some exploration of the overlapping spaces between documentation and software factories, and played with feeds listing MSDN blogs.
And dug the mud out of my garage after a heavy rain washing the construction dirt next door down my driveway and into the garage. The city government in Seattle is pwned by the building industry; I never realized how corrupt it was until we tried to get some laws enforced. Playing with MSDN was much more fun!
Dave Morehouse had two gems on his blog last week. The first was the magic guid for a feed listing MSDN feeds with recent content. More on that later. The other gem was a musing on tagging, OPML, and community. [[He says|http://davemscom.spaces.live.com/Blog/cns!217A4DFE679DE9D4!253.entry]]:
//let's bust tags out of the cloud and display a person's tagging behavior/interests in the form of a graph by which users can potentially navigate.//
Bingo. It's a pity tags are dismissed too often as just something that goes in a tag cloud. For me, the cloud is just the collection of items that have permalinks. A tag cloud is not a cloud-- it is a picture of parts of the cloud. The graph Dave writes about is the tree described by your tags. Your tags are your description of how you organize the part of the cloud you're interested in. That description can be analyzed to further organize the parts of the cloud you haven't visited yet, building a local tree of potential interest.
How to express that tree? So far, OPML is the only widely supported format for expressing trees. Dave considers the possibility of sharing arbitrary items along with hierarchical structure in OPML. Yes! OPML is fine for importing/exporting feeds in a reader, but I'm happy to see people looking beyond this to publish structured collections of links. The folks at Grazr totally get this, and the new 3-pane Grazr browser is especially well suited for this.
So, now to the magic guid Dave posted for a feed of feeds. By itself, the feed is handy if you want to quickly look over some active blogs. It's an RSS feed, which makes some sense being a simple unordered list. As OPML is mostly used today, it wouldn't make as much sense to publish the list in OPML because it requires you to manually import the OPML into your browser. This is a perfect application for an active OPML browser. Like Grazr. I wrote a simple XSLT to convert the RSS to OPML, to be loaded into Grazr. You can see here that it's actually a very pleasant way to scan the active blogs. The OPML is never more than 30 minutes out of date. What you don't get is a record of what items you have looked at before, but that's OK since the items are feeds and not text content. It's obvious what it means to have read a posting, but not so clear what it means to have read a feed.
[[Here's the OPML|http://www.TreesAndClouds.net/msfeeds/default.aspx]], and [[here's that OPML in Grazr|http://www.TreesAndClouds.net/msfeeds/NewFeedsInGrazr.htm]].
Next posting: adventures trying to build OPML for the feeds, filtered variously.
Here's a hack for getting MSDN pages faster, at the cost of showing the wrong TOC. According to [[today's announcement|http://msdn.microsoft.com/aboutmsdn/changes/]], MSDN has moved several of the Developer Centers over to the ~MSDN2 system, where they sport a new Atlasized TOC. The Library pages still use the old-style TOC, which does take its time to smell the roses.
The ~URLs for the English language ASP.NET Developer Center are in this form: msdn2.microsoft.com/en-us/asp.net///topicID//
However, you can use the topic id of topics not in the Developer Center and get them rendered as if they were part of the center. For example, the VS Team Foundation top node has the URL:
http://msdn2.microsoft.com/en-us/library/ms181232
If you browse to that URL, you will see the Team Foundation page, and this chunk of TOC:
[img[VS TFS in normal TOC|http://www.TreesAndClouds.net/VSTSTOC.gif]]
Now if you change the ''library'' in the URL for ''asp.net'', as in
http://msdn2.microsoft.com/en-us/asp.net/ms181232
you see the same page, but with the lean, mean, and irrelevant TOC for the ASP.NET section:
[img[VS TFS in ASP Dev Center TOC|http://www.TreesAndClouds.net/VSTSASP.gif]]
It's missing some other parts, such as UI to collapse code examples for languagues you're not interested in. Apart from the TOC not being synced with the content, all the links are functional. You can also use alias ~URLs this way too, such as http://msdn2.microsoft.com/en-us/asp.net/system.windows.forms. It does look odd seeing a Forms reference page on the ASP.NET site!
You would never see this TOC behavior through normal navigation. You have to manually edit the URL. But if you can do without the TOC pane, your pages will load faster. I'm guessing it's a bug that will be fixed, but in the meantime consider it an actually useful feature. If I was still scraping pages then I'd probably use this trick a lot, but if you want to get content programatically then the content service is the way to go.
Attention.XML is an XML file (specifically an XOXO file) that contains an outline of feeds/blogs, where each feed itself is an outline, and each post is also an outline under the feed. This hierarchical outline structure is then annotated with per-feed and per-post information which captures such information as, the last time the feed/post was accessed, the duration of time spent on the feed/post, recent times of feed/post access, user set (dis)approval of posts, etc.
Attention may be useful when gathering documentation feeds. One or more ~SMEs can browse the available resources for the feed and use attention to record a suitable path for consumers of the doc feed.
I'm moving my blog from TiddlyWiki to dasBlog. The hardest part of the migration is mapping my ~TiddlyWiki tags to a new set of dasBlog categories. I was also doing some aggregation on the ~TechNetEventsBloggers site, where again the hard part was post classification.
~TiddlyWiki is a pleasure to work with and I'm going to keep it, but move it in the direction of a reference work. The syndication part of ~TiddlyWiki has been useful, but it is missing some features I'd like (such as comments and API support). ~TiddlyWiki is, after all, Wiki-centric and not blog-centric. dasBlog is a ASP.NET application, and ~TiddlyWiki is done in javascript. Now the content migration is done, the dasBlog site has 695 files. The ~TiddlyWiki still has one (1) file.
It took only a little bit of work to get move the old content from ~TiddlyWiki into dasBlog. Considering how vastly different platform are, the migration could have been a real nuisance. But, ~TiddlyWiki exports content in RSS and dasBlog has a decent API. Oh how I wish some content migrations in the past had been so easy! My blog has several thousand fewer topics than the C++ docs or Exchange Server SDK, and less formatting and structural diversity.
There was one headache in this conversion that I didn't escape. The dreaded schema wars. Just because you're the only person involved doesn't let you off the hook! ~TiddlyWiki uses tags nicely, but the tags I like in the wiki don't work so well in a blogish context. I'm still playing around with taxonomy and mappings to the old fauxsonomy. There's also some CSS tweaking left to do.
[[Le Chatelier's principle|http://chemed.chem.purdue.edu/genchem/topicreview/bp/ch16/lechat.php]] states that "a change in one of the variables that describe a system at equilibrium produces a shift in the position of the equilibrium that counteracts the effect of this change." When you squeeze a balloon it oozes out somewhere else. (It doesn't pop in this posting.)
Codified process usually come from a desire to not make that mistake all over again. That label warning not to use that lawnmower inside is there because of that lawsuit over the mangled carpet. Documentation departments employ editors and technical review workflow for the same reasons product groups have QA process. But when the process becomes too hardened then Mssr. Le Chatelier pays a visit.
Blogs are a terrific conduit for informal and valuable information, nearly unfiltered, straight from an expert. I doubt that you, dear reader, need much convincing of the value of blogs. This has been a hot topic at work this week. It's time for ~SP1 of TFS. Brian Harry has [[blogged|http://blogs.msdn.com/bharry/archive/2006/09/28/775891.aspx]] about it, starting his post: "Well, I'm going to try to beat a new path here. We're trying to be more transparent about what we are doing, when we are doing it and why we are doing it." That's a very excellent thing, IMHO. Brian Harry knows what he's talking about, and this is "must read" info for Team System connoisseurs. He's also reasonable about what he set out to do: "I don't have the bandwidth to document a good customer consumable description of each bug." Brian is great, but he doesn't scale.
Documentation groups do scale. Processes have been refined over the years to ensure that 10,000 disasterettes don't happen again. Product names get verified, geopolitical traps are detoured, content is cleaned for localization, and so on and on and on. Eventually documentation emerges from the other side of the pipeline. But it takes a long time, and simple things like getting art or posting a text file on a web server can become an exercise in exasperation.
It is so very tempting to use blogs as an escape valve for documentation that would take a lot of effort to push through the machine. So can we document this new API on a blog? Of course we can! Should we? Does everybody know to look at that blog? If you can't find the documentation then it might as well not exist. I heard a new term in the discussion: "taxonomic docs". I'm guessing this refers to the documents that are given a specific place within a TOC that orders the doc set. The place is what helps you discover the document. If the taxonomy is well-designed, you will be able to navigate it more easily than finding the name of the person who developed a piece of software you want so you can find their blog. In real life, I have said things like "Mr. Grazr" or "Mr. MAPI" but people generally are not the best taxonomies for object models.
Here's what I want: a process (yes, a process) to accommodate the content that shows up quickly on a blog or forum posting, keeping the content visible, as it progresses from useful ephemera to solid core findable documentation, and eventual retirement in the archive. More on that shortly.
Here's the link to the page I'm used for a brownbag presentation on Syndication for UE. http://www.TreesAndClouds.net/brownbag.html.
The page uses a Grazr OPML browser to show an OPML outline for the talk, and also a ZoomClouds tag cloud.
Having gone through several rounds of converting docsets to whatever form the newest system uses, I am very sympathetic to the concept of re-using legacy docs in their native format as much as possible. Here are some thoughts on how to accomplish that.
''In what formats are the legacy docs available?''
Some formats are more difficult to work with than others. It is more difficult to programatically get content from a compressed chm than the source html files used to build it. In some cases it will be feasible to re-purpose the source documents for feed scraping. In the worst case scenario, where the docset is compiled into a closed format requiring a specialized viewer, a docfeed can at least provide links to the source of the compiled docset and viewer, and additionally, a potentially rich description of the contents of the docset.
Other fomats lend themselves well to either batch or on-the-fly conversion to RSS feeds. ~MSDN2 content, for example, is published as XHTML, which simplifies the conversion.
''Content scraping''
Content scraping refers to the technique of programatically locating content within documents and copying it into feed items. There are services available that scrape content from arbitrary specified pages. Custom scrapers generally use ~XPath or regular expressions to locate content. ~XPath is used to locate nodes within XML documents that meet specified criteria, and regular expressions are used to locate specific content within text sources.
~MSDN2 content is well suited for content scraping, since it is published as XHTML, and appears to be consistent. I have written a C# console application to take sets of ~MSDN2 pages and convert them into RSS items. Contact me if you want a copy of the ~MSDN2 scraper application or source.
''Assembling groups of diffuse topics into a feed''
Feed items need not contain the entire content of a web page! In many or most cases, the feed item need only contain a title and description of the topic. When a doc set consists of links to dispersed web pages, one way to group them is to tag them in [[del.icio.us]] with a unique tag and then create a del.icio.us feed for those links. In the fullness of time, the [[Attention]] tools or something similar, will help automate this process to some extent.
I've been building a weather station this week, with a lot of help from the excellent [[Weather Toys|http://www.weathertoys.net/weathertoys/main.html]] book. At this moment only temperature and humidity sensors are connected, and the results posted [[here|www.TreesAndClouds.net/weather.htm]] once a minute in a minimalist page.
The system runs on a [[1-Wire|http://www.maxim-ic.com/products/1-wire]] network (aka microlan) by [[Maxim/Dallas Semiconductor|http://www.maxim-ic.com/auto_info.cfm]]. Remarkably, there really is just one wire connecting all the devices, not counting ground. The devices are powered by the data line, which is nominally powered at 5v. Each device has a tiny capacitor to store power for up to a millisecond, which is longer than any logic pulse on the line. The bus master is a USB device.
The book describes how to use the Java ~APIs provided by the 1-Wire SDK. I was going to write the software in Java, but saw that Maxim has compiled the library as J# to create a managed library. Modifying the Java samples to C# has been trivial, and I'm developing my station software now in Visual Studio with C#. One of the first major benefits for me is being able to run the app as a service (so I don't have to leave a console open all the time).
If you've ever wanted to reach out from your computer and touch the world of molecules, then give the 1-Wire stuff a look. The [[Hobby Boards|http://www.hobby-boards.com/catalog/main_page.php]] store won't make you buy 1-Wire components in lots of 1,000. Meanwhile, if you ever wonder what the dewpoint is at my desk you know where to look.
The [[MSDN DevWiki|http://msdnwiki.microsoft.com/en-us/mtpswiki/default.aspx]] is very cool. But being so new, the content is still a bit sparse there. I confess that I go straight to ~MSDN2 myself, and not the Wiki. Nonetheless, I still want to know if there is extra content there. Luckily the wiki pages are easy to get to-- just substitute the URL {{{http://msdnwiki.microsoft.com/en-us/mtpswiki/}}} for the old {{{http://msdn2.microsoft.com/en-us/library/}}} and there you are.
Not so luckily, the content isn't as easy to work with. The XML seems generally to be not valid. It renders fine in a browser, but you can't load it into an Xpath document to find the content goodies. There is a quick way to see if there is any "community content" on a page, though. Just see if the page source contains the string {{{MtpsWiki_Text"}}} (yes, the string ends with a quote mark).
You can also find out which topics have recently been adorned with fresh wiki content, by checking [[this|http://msdnwiki.microsoft.com/wikiedit/newblocks.aspx]] RSS feed. I don't find that feed very useful, however, because I can't easily tell where the changes are, and which topics they are in. What I really want is to find, for example, all the new content in the .Net Development tree of the MSDN library.
MTPS Content Service to the rescue! Using the webservice into the MSDN library content you can check which tree the topics belong to. I wrote a very quick and dirty utility to do this, in about 100 lines of code. It's an ugly console app, but it does work. It takes one argument-- the short topic identifier of a topic in the MSDN library. It returns all child topics that have new content, and the wiki content for those topics. In raw XML. I'll spiff it up and add some extra features I want over the next interval. In the meantime, [[here|http://www.TreesAndClouds.net/WikiFeed.zip]] are the source and binaries.
Tomorrow we're off to enjoy the most excellent [[Orcas Island Chamber Music Festival|http://www.oicmf.org]]. Yum!
Clouds move more than trees. Only recently, with better software tools, have dynamic clouds become a viable tool for organizing large sets of information. Clouds are built after content is created. You don't send your book to the indexer until you have written it. Creating a good index takes considerable skill. It typically takes human intelligence to discern what conceptual label can be applied to a chunk of document, especially when there is no clear one-to-one mapping between concepts and labels. Consequently, the See Also entries in an index provide an especially valuable contribution.
The type of cloud that this experiment is mostly concerned with is the attribute tag cloud. Tags have surged in popularity as they have been hoisted to core features of websites such as Flickr, del.icio.us, and Technorati. These sites popularized the concept of social tagging, whereby users apply informal attributes to content in a way that is meaningful to them. The term folksonomy has been coined to describe this style of metadata. Folksonomies do not use a standardized taxonomy to describe items.
A good way to see how tagging works on a large docset is to look at [[del.icio.us]], and for a small docset look at the tags in this document. Within this wiki, click on a tag to see other topics with the same tag.
//"Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations"//
This is Conway's Law, which (as described [[here|http://www.eskimo.com/~hottub/software/programming_quotes.html]]) means that if you have four groups working on a compiler then you'll get a 4-pass compiler.
In the documentation biz Conway's Law can be seen in the way the Table of Contents is usually a representation of the company org chart.
I've been spending the last few months working on the plumbing for some demos. A lot of this has been simply coming up to speed on ASP.NET and some other technologies. I'm focusing on using content from the MTPS (MSDN Technet Publishing System) Content Service, and also blogs and forum content. If it's available via RSS or web service, and if it's about developing for Microsoft platforms, then I want to consume it.
The application I'm working towards is an ASP.NET web app that is essentially a mashup of various kinds of Microsoft developer content. Some pieces of it are available for download [[here|Downloads]]. The application will present excerpted content from multiple sources on a single page, and supply hints about potentially useful other content items.
At the moment I'm working on a custom site-map data provider for the ASP.NET navigation controls. The provider uses the MTPS web service as a data source. As of this writing, it works but is a bit fragile. I'll post it when the edge cases are handled better, but if you just can't wait then do let me know.
The next phase will be making the documentation trees produced by the application publishable. That is, if you come up with a really good doc set for your domain, I wan you to be able to share it with others in your domain.
[[Welcome to the Trees and Clouds blog!]]
[[Progress Report]]
[[PackageThis hackery]]
[[PackageThis, PrintThat]]
[[For want of a connection string...]]
[[Weather station development]]
[[Linq between weather and data access]]
[[Building my new weather station]]
[[Miscellaneous, the Book]]
[[When the API is SendKeys]]
[[Make your own mini-MSDN library]]
[[Input devices and happy hands]]
[[Blog migration and classification]]
[[Gadgets, Sound, Formats, and Time]]
[[Did you see an SDK around here, by any chance?]]
[[Trees and Clouds 2.0]]
[[What to do next?]]
[[Taking stock in Trees and Clouds]]
[[Documentation Development Integration, and upcoming events]]
[[Live Search Macros, Custom Search Engines, and Crappy UI]]
[[del.icio.us, Duality, Triples, and the Buckybase]]
[[More Posts]]
Friend and former project lead Francis "François" Langois has a fairly new blog: SDK writer. He recently reposted [[this gem|http://blogs.msdn.com/franla/pages/sdks-whither.aspx]], originally written back around the time I wrote my [[The Law of Conservation of Documentation]] post. Yes, the snark was turned up to 11. That was about when [[this motivational poster|http://www.TreesAndClouds.net/images/NotAbandoned.jpg]] came to be. It was actually one of the best projects I ever worked on. These are true facts.
Back in college days I used to load the Sunday newspaper onto delivery trucks at the Seattle Times' plant. A few times a night the paper sheet in a press line would tear (a "web break") and the line would have to be restarted. The web has changed some since then, but processes with a lot of linear dependencies are still prone to breakage. What the new web provides is a way for the news to come out by other means when the press line is down.
When we wrote the posts linked above, it was a "web break" episode. Before the press line could get back running, we had the opportunity (necessity, actually) to work in the style I believe describes the future of documentation/user-education work.
What's the difference? Writers in the future will be more engaged in identifying useful content from a richly varied multitude of streams and tagging it in skillful ways to create usefully ordered scavangings that are more valuable than their components. Francis has some great ideas about this, and I hope he'll blog more about it. Especially if he uses his snark persona!
''Docfeed''
A collection of links, feeds, and content that makes up a documentation set. A docFeed can contain static and dynamic content. It is delivered as an outline of RSS feeds.
Some of the static content may be embedded within RSS feeds, and other static content may be linked to by URL.
Dynamic content can include other outlines (themselves presented as a feed), blogs, search results, and so on.
Lots going on the next few weeks! I'm looking forward eagerly to [[Seattle Mind Camp|http://www.seattlemind.com/index.php/mindcamp/about]] on November 11-12. Even sooner is the Search Mashup event on the Microsoft campus, Wednesday this week (November 1). If you're going to be at these events I hope to see you there.
My last day on the [[Team Foundation Server|http://msdn.microsoft.com/vstudio/teamsystem/team/]] gig is November 13. In the remaining days, I'm working on an app to move metadata from our documentation authoring envionment into Team System. This is a big deal, methinks, and not just for the immediate need to get documentation and product bugs in the same database. In a sense, documentation is metadata for the product. The place to capture metadata is close to where you capture the data. One big reason I've been looking at software factories is that by rigorously defining the development process (which is the heart of the factory approach) you get //situational awareness// and //context// at each step that can be milked for accurate documentation content.
Team System doesn't have a documentation component, but neither does any other system I've used. Doc groups usually keep their bugs in a different database than the product group. This isn't just a Microsoft thing; it was the same setup for ~WebLogic Workshop when I was at BEA. I suspect the development and documentation tasks will be a long time coming together, not just for cultural reasons, but because there is still a huge gap between designing function and designing implementation.
Meanwhile, any integration between the development platform and the authoring platform is a good thing. I may not be posting a whole lot in the next two weeks while I pitch in to close the gap a bit more.
A class that encapsulates a MTPS topic, described [[here|Mtps Topic Class]]. Source and binary [[here|http://www.TreesAndClouds.net/TopicClass.zip]].
A tool for finding MSDN wiki content by subject, described [[here|Checking for MSDN Wiki content by subject area]]. Source and binary [[here|http://www.TreesAndClouds.net/WikiFeed.zip]].
An ASP.NET application for presenting topics using the MTPS web service, described [[here|Serving MTPS Pages With ASP.NET]]. Source and binary [[here|http://www.TreesAndClouds.net/WikiFeed.zip]].
This is how I described my goal in April, 2006:
<<<
My goal is to help hasten the inevitable move towards large-scale documentation sets being made available loosely-coupled services as syndicated resources. There it is, in a sentence!
I’ve been spending a lot of time talking with documentation folks about my Trees and Clouds vision. Hearty thanks to the good people who have listened, commented, and challenged, as I’ve practiced and refined my explanation of the vision.
One thing I haven’t had to talk much about is what is broken with “the system” now. A few loaded phrases trigger all the shared understanding and context we need to discuss this problem or that. Conversion. Schema. Legacy. TOC reorg. Getting a topic inserted. OK. Enough already!
I think that many of these problems are a natural side-effect of the centralization of tools and within documentation organizations. There is a natural force that drives attempts to create efficiencies of scale and consistency. A natural countervailing force decreases the efficiency of system users, and a blossoming of creative ways to circumvent rules. This struggle ensures that no monolithic system works well for everyone.
The solution, I believe, is to offer many systems that support each other. Using the syndication model, we can incrementally build loosely-coupled services to deliver more relevant documentation. That’s what I’m working towards.
<<<
Like most wikis, TiddlyWiki supports a range of simplified character formatting:
| !To get | !Type this |h
| ''Bold'' | {{{''Bold''}}} |
| ==Strikethrough== | {{{==Strikethrough==}}} |
| __Underline__ | {{{__Underline__}}} (that's two underline characters) |
| //Italic// | {{{//Italic//}}} |
| Superscript: 2^^3^^=8 | {{{2^^3^^=8}}} |
| Subscript: a~~ij~~ = -a~~ji~~ | {{{a~~ij~~ = -a~~ji~~}}} |
| @@highlight@@ | {{{@@highlight@@}}} |
<<<
The highlight can also accept CSS syntax to directly style the text:
@@color:green;green coloured@@
@@background-color:#ff0000;color:#ffffff;red coloured@@
@@text-shadow:black 3px 3px 8px;font-size:18pt;display:block;margin:1em 1em 1em 1em;border:1px solid black;Access any CSS style@@
<<<
Bullet points:
* Just add an asterisk
* at the beginning of a line.
** If you want to create sub-bullets
** start the line with two asterisks
*** And if you want yet another level
*** use three asterisks
* Edit this tiddler to see how it's done
Numbered lists:
# Use a single '#' at the start of each line
# and the tiddler will automatically
# start numbering your list.
## If you want a sub-list
## within any bullets
## add two '#'s at the start of the lines.
# When you go back to a single '#'
# the main numbered list will start up
# where it left off.
<<<
A TiddlyWiki is like a blog because it's divided up into neat little chunks, but it encourages you to read it by hyperlinking rather than sequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole.
<<<
Like BulletPoints and NumberedBulletPoints, you can have multiple levels of BlockQuotes.
>level 1
>level 1
>>level 2
>>level 2
>>>level 3
>>>level 3
>>level 2
>level 1
After playing with the MSDN feeds feed in OPML, I wanted to filter the feeds going into the OPML. At first glance this looked easy. The feed feed has category metadata for each feed it contains. Now, after several hours of poking at various listings of feeds, I'm not sure how to approach it. There are three category domains, described below, and listed here.
''Audience'': 32 categories, which look like they probably map to some internal set of personas. Some aren't very obvious. Are you an "active practical follower" or a "dual enthuser follower"?
''Subject'': 110 categories, which are not normalized. There is a C# category and a separate Microsoft Visual C# category. Some apply to products, some to technologies (e.g. XSD), and some defy categorization (e.g. manageability).
''~FeedType'': 34 categories which are easy to grasp. We know what things like announcements, podcasts, blogposts, and tutorials are.
These domains map loosely to the three domains on the Microsoft Feeds Directory (www.microsoft.com/rss):
''Feeds For'': Home, Work, Businesses, Developers, IT Professionals
''Feed Categories'': Communities, Computer Languages, Downloads, Events & Webcasts, Security, Support, General Topics
''Product Families'': Windows, Office, Servers, Developer Tools, Business Solutions, Games & Xbox, Windows Mobile.
The categories on the feed of feeds are not exclusive. That is, a feed could be targeted at both practical influencers and passive practical followers. It's really easier to consider them as tags, but I don't have a nice way to present the choices to the user. Even if the user understood the meaning of each category, how do you politely present 176 different choices? To clean it up you need a taxonomy, and that requires more thinking that an XSLT is handy with.
So, it's not entirely surprising that the 17 categorized feed feeds are built by human editors. So far. Meanwhile, here are the three blog spots at Microsoft that I know of.
*blogs.msdn.com
*www.microsoft.com/rss
*rss.microsoft.com
[[Here|http://www.TreesAndClouds.net/FeedCategories.htm]] are the categories and URL for the feed feeds.
One development task I loathe is getting all the permissions, rights, accounts, and such lined up. Especially when they aren't lined up correctly yet. I want my app to run as a service and write to a database, which is not exactly an edge scenario. Now it seems retroactively obvious, but not before a couple of evenings of floundering in the thickets and grumbling about the lack of decent documentation. Now, of course, I can go right to the relevant topics. But when the problem is that you don't know exactly what you are looking for, then it's not easy to find the right one and harder still to know when to abandon the wrong paths. Now, however, the glory and the splendor! It is now working well and I'm enjoying seeing the ~LEDs on the 1-wire hub blinking every 30 seconds. //Yes! It is still working!//
These kinds of annoying setup issues are why I'm still holding out on playing more with Joshua Tauberer's [[SemWeb RDF library for .NET|http://razor.occams.info/code/semweb]]. He recently released v1.0. I played some earlier with the in-memory store but didn't want to mess with ~MySQL or Sqlite and hoped a SQL Server adapter would be available. If the [[LINQ to RDF|http://code.google.com/p/linqtordf]] project keeps moving along I may have to take the plunge sooner. LINQ may make using your data easier and more fun, but doesn't help a whit getting the store configured.
The Zune and iPhone have been much in the news and, interestingly, much in tech blogs. It's fun to speculate on why geeks are so passionate about tiny stereos. I enjoy reading these off-topic posts, and I really enjoy using the gadgets too.
The Zune and i* aren't for me. I prefer a small WMA player that doubles as a USB drive. This season I spent the toy budget on a [[pre-amp|http://www.phonopreamps.com]] so I can hook my turntable up to digitize my old ~LPs. I have an [[external USB sound card|http://us.creative.com/products/product.asp?category=1&subcategory=206&product=10702]], which makes a staggering difference in the sound quality. (The inside of a computer isn't a great place to put audio electronics.) After I got the new card I realized how crappy the computer speakers are. I swapped in a decent (inexpensive) set of speakers. Very much better!
My wife and I go to the symphony a lot. I love the sound there. A very significant portion of my Trees and Clouds //aha!// moments have happened up there in the top side balcony box practically on top of the orchestra (great for strings, but not the best seats for voice). I don't expect to hear that sound at home. It won't fit in a box. //A recording isn't a method of replicating music, it's a composition for speakers.// ([[Lucas Gonze|http://gonze.com/weblog/story/recording]] via [[Danny Ayres|http://dannyayers.com/2006/12/28/qotd--telemusik]])
The pattern is consistent for each sound media generation (LP, CD, ~MP3/WMA). The sound quality has improved with time, and then plunged with the next platform. To my ears 320 kbps WMA is now only a little worse than a good LP.
I hooked up the turntable and have been enjoying playing through my old ~LPs. I'm saving copies digitized at 96kHz/24-bit and then downgrading copies to 320 kbps for my player. When push comes to shove, I'd rather lug Nanophone than a Gramophone. My first ~PC-XT booted and started Word in about as much time as the one now, but I'm not looking back.
I bought some of those ~LPs 35 years ago. They sound great. Will I be able to play the WMA files in 35 years? How crappy will the formats sound by then? As always, enjoy the music while you can!
It's been a fine Summer. My nephew stayed here with us for six fun weeks while he worked as an intern at the university. He's got a lot of computer smarts, and among other things designed a website for the lab where he worked. I enjoyed playing Guru, and he left with a solid understanding of why presentation belongs to CSS, why data belongs in XML, and why we're tight with loose coupling. I never knew about those things when I was 15 years old.
Alas, he's gone now. The consolation is more time to play with the MSDN Content Service. There is another iteration of the docs available [[here|http://services.msdn.microsoft.com/ContentServices/ContentService.asmx]].
The latest beta Grazr browser now has a very nice 3-pane option, which will come in handy when it goes into production. It's the nicest browser experience I've had that presents a nice path from OPML to RSS to HTML without having to think about what filetype you're looking at. What's the first thing I pointed it to? That was an OPML collection of queries into the MSDN Forums, built with the help of Joe Morel's neat little [[tool|http://www.gotdotnet.com/codegallery/codegallery.aspx?id=eb5f1dc5-6868-4fde-9c78-909832315ccc]] to build query strings without breaking a sweat. That was well and good, but since the results only contain a sentence worth of body text from the thread you still have to open up the target HTML.
So, in an ideal world, how would you syndicate a thread? I need to think about that some.
The forums are much on my mind these days because customers are starting to actually use the Team Foundation Server SDK, and I'm following the forums for hints about the customer experience.
Grazr is a really great OPML browser that you can embed in a web page. That means you can start enjoying OPML goodness right away without having to install anything. Grazr is great for demos, for quick looks at OPML, and a lot of other imaginative things. It's free, easy, and cool. Just to drive the point home... give it a try!
[[Here|http://www.TreesAndClouds.net/brownbag.html]] are the "slides" for an early presentation I gave using Grazr instead of Powerpoint. Want to try Grazr instead of Powerpoint? Go to the OPML Workstation and get your Powerpoint converted to OPML.
[[www.grazr.com|http://www.grazr.com]]
See MoreGrazr for more Grazr goodness.
Collections of topics are presented as RSS feeds, and collections of feeds are presented as OPML reading lists. The items in a feed are analogous to topics in a help file, except that they can be dynamically created. The feeds in the reading list are analogous to chapters in a TOC, except that they can be dynamically created.
RSS provides the content publishing mechanism, and OPML provides the tree structure.
Items in a feed are tagged with attributes that describe the content of the item or the feed. The source of these tags is a combination of metadata accompanying the original source, tags applied by users, and automatically generated sets of related tags and topics.
That was a marginally interesting waste of time. I just bailed after spending a few hours trying to get ~WordPress or Moveable Type running on my server. Since these are ~LAMP-centric (Linux, Apache, ~MySQL, PHP) apps, I was expecting to jump through a few hoops to get one running on a WIMP (Windows, IIS, etc.) environment. What I want is pretty basic—a tool to maintain a simple blog and corresponding feed, and publish it on the same machine. I've been doing that so far using TiddlyWiki. It's a single file of HTML that does everything with javascript contained inside the page. I have a copy of it that I carry around on my mp3 player to work on.
Still, I was having some WikiWoe with TiddlyWiki in the way it generates the RSS feed. I've been tweaking the feed in Visual Studio before publishing it, and every time I had to spend a few minutes to do that I resolved to hunting for a tool that wouldn't require that step. The most efficient solution would have been to write a couple of macros in VS, or regex, and be done with it. But being curious about what a fancier platform might enable, I did some looking around and settled on ~WordPress or Moveable Type. I considered the OPML, but I don't really trust it enough and if I'm going to invest time in learning another scripting language I'd rather go with Perl than Frontier.
I did the Perl and ~MySQL installs. It would have been nice if SQL Server was supported, since it was already running. The last straw was being pestered to open up extra ports on the firewall. wtf? This is for a database running on the same server. On the same disk, for crying out loud. Keep your hands off localhost unless you let me know what you're up to!
Finally, I spent the 10 minutes to write a Visual Studio macro to polish the TiddlyWiki feed. Now I can get back to working on what I really wanted to do in the first place. If you can recommend a nice WISA (Windows, IIS, SQL Server, ASP.NET) blog tool, do let me know.
The [[Colemak keyboard|http://colemak.com]] looks like an excellent idea. It's another keyboard layout like Dvorak and the awful Qwerty . Colemak offers vast improvements over Qwerty and modest improvements over Dvorak in terms of same-finger combos, right/left hand alternation, distance travelled, and so on.
A decade ago I switched to the Dvorak layout to minimize RSI pain. It took a few months to get my speed back, but I'm very glad about making the switch. My fingers remember Qwerty if I have to use it for more than 5 minutes, but I'm always astonished by how awkward and uncomfortable it is. Seriously, if you're concerned about RSI then choose a time not 2 months before a major deadline and take the plunge. It's worth it. Not for speed, but for pain relief.
That said, I won't be switching to Colemak! It is designed for ease of conversion from Qwerty. If Colemak was around 10 years ago, it would have been an obvious choice.
Yesterday I did an amusing and successful project making a toe mouse. It doesn't move the pointer yet, but the clicks work nicely and it's gives my hand a nice rest when I have a lot of mouse work to do.
I've been tinkering with the weather station. A few more sensors are hooked up, and the web page has a simple time series chart (thanks to the opensource [[ZedGraph|http://ZedGraph.org]] control). My favorite sensor gets the temperature of the air coming from my computer's CPU fan. It's like watching perfmon, but the thermal mass of the computer averages the data. It's fun to look at the chart and be able to map it to the intervals of CPU intensive work. Last evening my wife called me to ask if I had stopped working. She had seen [[on the chart|weather.htm]] that the computer temperature had gone way down. Nope, I'm still working, but it got stuffy and I opened the door! Data without context is useless.
When I was still looking at various charting controls I saw a [[post|http://www.knowing.net/PermaLink,guid,32f45ea2-e324-4326-8496-697a07c15a96.aspx]] on Larry O'Brien's [[Knowing .NET|http://www.knowing.net/]] blog pointing out a nice looking [[graph tool from MSR|http://research.microsoft.com/~levnach/GLEEWebPage.htm]]. Ha! It's for the other kind of graphs... the kind that represents the TOC I really want to see. But that's a treasure for another day. This weekend I was looking at tabular data.
The tricky part was not having settled on a schedule for polling the sensors. Frequent readings are good for calibration and measuring sensitivity. Less frequent readings mean I won't be stuck with a huge log file. Not only that, but I'm still adding sensors. The evolution of the data format went from comma separated values, to XML, to SQL. It's easy to append readings to the end of a CSV file, but a pain to find entries. The tools for playing with XML are familiar, but in this case it doesn't give me much more than a fancy wrapper for the CSV and it's not such a great format for a dynamic log file. SQL gives me the best options for analyzing the data, but for a quickie project the plumbing overhead is high, especially if you don't do databases every day.
The data is now going into SQL, and I'm loving LINQ for querying the data. I especially appreciate the flexibility it gives me while I'm still messing with the data collection part. No doubt a SQL programmer would find it trivial doing my queries on this tiny one table database. But what LINQ opens up for a non-SQL guy is amazing. More to come!
On the down side, this glorious rainy weather will probably have ended by the time the rain gauge I ordered arrives.
A few weeks I was [[griping|Miscellaneous]] about Live Search. There are actually some really cool developments going on there, but good luck finding them. Inspired by [[Andy Edmonds|http://blogs.msdn.com/andyed/archive/2006/10/12/live-search-opml-generator-bootstrap-your-blogosphere-engagement.aspx]]' and [[Raghavendra Prabhu|http://blogs.msdn.com/rprabhu/archive/2006/09/16/757978.aspx]]'s postings on search macros, I've been playing some.
Open [[Live Search|http://www.live.com/?searchonly=true]] and there is no indication that there is any advanced functionality. Not even your own search macros appear. Only after you run [[a search|http://search.live.com/results.aspx?q=Bottesini&mkt=en-us&FORM=LVSP&go.x=0&go.y=0&go=Search]] will you see the More button on the toolbar at the top. Click it, and some interesting looking choices appear in the dropdown: "What do you want to search?" including feeds, academic, video, products, and even more yummy Edit macros and Find macros. But this is a tease. Move the mouse off the More menu and the dropdown disappears! You can still get to Edit menus by dragging there and then clicking before the dropdown vanishes. Blech! But, persevere, because the payoff is sweet.
A search macro is a custom filter you can apply to your searches. A quite powerful and fancy filter. It's really worth trying to figure out. Now how about subscribing to the query? It's easy enough, just append "&format=rss" to the query URL. Typing is easy, right? But the UI won't help you much at all. You can see that the results are available as a feed because the RSS icon lights up, but there is nowhere visible to copy either the URL in text, or to copy the link. You have to add the feed url to your live bookmarks, and then inspect the properties for the feed. Alternatively, you can view the page source and get the feed url from the rel tag. It needs to be very much more discoverable than that! Forcing users to muck with ~URLs is not cool.
It's a pity that the UI is so opaque. There are actually some very powerful tools hidden away if you have the perseverance to dig them out. I'd like to see it become very much easier to create and publish search queries. Look at how popular lists are. You can hardly look at del.icio.us/popular or digg without seeing a list of the top seven reasons Ruby is cooler than CSS or something. Why don't you see any hot queries there? Why don't you even see lists of hot queries? It's not because a good result set is not interesting. It's because they are still too awkward to publish. Forcing users to muck with ~URLs is not cool.
Meanwhile over at the Google, there are shiny new [[Custom Search Engines|http://www.google.com/coop/cse/overview]] to play with. Not only that, but documentation. And examples. And a nifty tool, the Marker, to help collect pages or sites for your queries. I'm looking forward to playing with that some more. It's an inviting offering. Strangely, Google also holds closely the secrets to syndicated query results.
Don Park has some good observations of these offerings today on his [[Google implements SearchPoint before MSN does|http://www.docuverse.com/blog/donpark/2006/10/23/google-implements-searchpoint-before-msn-does]] post.
So how are we going to publish all these great queries we can make now? I've been looking at one stunningly beautiful tool. But I'm not allowed to write about it yet, so you'll just have to check back soon to see some healthy saplings sprouting out of the clouds.
MSDN (Microsoft Developer Network) is a repository for developer-oriented content from Microsoft. There are currently at least three different MSDN sites. I am doing some MSDNContentScraping to get sample feeds.
''http://msdn.microsoft.com'' is the older legacy site, and will not be used much in this DocFeed experiment. The biggest reason I'm not using the old site is that there are a lot of pages (maybe all of them) that are in old-fashioned HTML.
''http://msdn2.microsoft.com'' contains the newer documentation for Visual Studio 2005 and other newer content. Most (or maybe all) of the content on this site is in XHTML
''http://lab.msdn.microsoft.com/search'' is the new ~MSN-powered search site for MSDN. It is totally cool, and lets you subscribe to search results as a feed.
Exciting news!! MSDN has released a web service for access to MSDN content! This step has huge implications for how the content can be used. This is the dawn of the MSDN mashups!
This actually makes my last few weeks work obsolete, and I'm delighted. I've been wading hip-deep through XHTML writing code to count table cells to determine the TOC depth of MSDN topics. Obsolete! Hooray! Obsolete too is all that code to crawl the TOC. And crawl it again when I come across yet another way the crawler can stumble. Now we can start to do interesting things with the content, and not spend all that time just trying to scrape it out of MSDN.
The other thing I've been working on is XSLT to use OPML in the new ASP.NET navigation controls. The new navigation controls are really clean and powerful. OPML seems to me like a good format for XML representations of site maps that the ASP.NET ~TreeView control consumes. The very most basic TOC format for the ~TreeView control is almost identical to OPML.
{{{<SiteMapNode title="The title of the node" description="A description of the node" url="theTopicUrl.html" />}}}
Change out ~SiteMapNode for outline, and you've just about got OPML. You nest these nodes just like outline nodes. There isn't a date field, but that is broken in OPML anyway, and you can add fields if you want. Or put the sitemap into a database, or whatever. So, why would you want to use OPML? Because there are a ton of apps out there that understand OPML, and none besides your own web application that use your own sitemap representation. When you can transform your TOC into OPML, you can share it.
It's been a great week for MSDN. They also have a new search on the labs.msdn site showing off faceted search and many improvements.
Page scraping is a term for a variety of techniques for getting specific pieces of data from, usally from web pages. If you need to get data off a web page that isn't available as a feed, you'll often end up scraping the page. Common tools for scraping are ~XPath and regular expressions.
I am scraping a small set of MSDN pages for this experiment.
The RSS <description> element comes from <meta name="Description" content="the page description">
The RSS <title> element comes from <title> on the MSDN page
Topic content is inside <div id="mainBody">, for full feed scraping.
[[Trees and Clouds]]
[[More Posts]]
[[Current Projects]]
[[Early Goals]]
[[A Useage Scenario]]
[[Mtps Topic Class]]
[[Presentations]]
[[Downloads]]
[[del.icio.us/iredwards|http://del.icio.us/iredwards]]
[[Reading List]]
[[Tools I Like]]
[[Richard Edwards]]
[img[FOAF|http://www.TreesAndClouds.net/images/foafTiny.gif][http://www.TreesAndClouds.net/foaf.rdf]] [img[OPML|http://www.TreesAndClouds.net/images/opml-icon.png][http://www.TreesAndClouds.net/ReadingList.opml]] [img[RSS|http://www.TreesAndClouds.net/images/rss_button.gif][http://www.TreesAndClouds.net/default.xml]]
The new [[Package This|http://www.codeplex.com/packagethis]] tool makes it a snap to create your own chm or hxs of just the content you want from MSDN. You just select the pages you want from the MSDN library and Package This grabs the content from MSDN using the [[Content Service|http://services.msdn.microsoft.com/ContentServices/ContentService.asmx]] webservice and passes it to the appropriate help compilers. Very nice!
Package This is interesting for other reasons too. It's a great example of the Content Service in action. Source code is there waiting for you on ~CodePlex, and it's a "batteries included" project containing the transforms, stylesheets, and wrappers that weren't included in the Content Service docs.
<link rel='outline' type='text/xml+opml' title='Reading List' href='http://www.TreesAndClouds.net/ReadingList.opml' />
<link rel="meta" type="application/rdf+xml" title="FOAF" href="http://www.TreesAndClouds.net/foaf.rdf" />
Quoting Jeremy Ruston:
<<<
MicroContent being a fashionable word for self-contained fragments of content that are typically smaller than entire pages. Often MicroContent is presented via some kind of aggregation that reduces the perceptual shock and resource cost of context switching (eg Blogs aggregating several entries onto a page or Flickr presenting photos in an album). This TiddlyWiki aggregates MicroContent items that I call 'tiddlers' into pages that are loaded in one gulp and progressively displayed as the user clicks hypertext links to read them.
<<<
The possibility to aggregate multiple MSDN topics onto a single page would be a welcome feature, methinks. That is something to investigate in the future. There are (at least) two ways this can be done:
* ''static'' aggregation brings the separate chunks of content together always in the same way, and is appropriate for material such as tutorials.
* ''dynamic'' aggregation orders the chunks on the fly, as is being done in this wiki.
Designed for humans first and machines second, microformats are a set of simple, open data formats built upon existing and widely adopted standards. Instead of throwing away what works today, microformats intend to solve simpler problems first by adapting.
//"We need microformats."// - Bill Gates
See http://microformats.org/about/
//The miscellaneous world is reorganizing itself largely around topics because that's a—the?—fundamental unit of interest//. ([[David Weinberger|http://www.hyperorg.com/blogger/mtarchive/being_there_or_knowing_what.html]])
Weinberger's current book, due next year, is titled //Everything is Miscellaneous//. I'm looking forward to reading it, and meanwhile wondering if it will have a TOC. Every TOC reorg I've ever been through has started out as a game of 52-pickup and proceeded quickly until half the topics were assigned new buckets and the other half were still in Miscellaneous. Then it gets much harder. In fact, I wouldn't say Everything is Miscellaneous. Rather it's more like Half of Everything is Miscellaneous.
''Exhibit A:'' Some weeks ago I wrote a little tool to find out what MSDN library topics you like have extra ~DevWiki content. It got the list of wikified topics from a feed that only listed recent entries. I was lucky enough to get a spreadsheet listing the wikified topics, and used that to revise the ~WikiFeed tool. It functions like the old one, but returns all topics. Actually, it might miss a few because I'm missing data for a week or two.
The [[new tool|http://www.TreesAndClouds.net/NewWikiFeed.zip]] has to get a list of topics to work because the list can't be created dynamically (unless you want to walk the entire library every time you use the tool). The list ([[here|http://www.TreesAndClouds.net/TopicPaths.txt]]) is fairly compact, but clear text. Each wikified topic has one line. The first character indicates the version (vs.80, msdn.10, or sql.90). The next eight indicate the topic id, and the rest of the line lists the topics in the path to the top of the TOC. If you don't like the spartan UI, then grab the source and spiff it up.
''Exhibit B:'' Apple has sent Podcast Ready a "cease and desist" letter, claiming that the terms "Podcast Ready" and "myPodder" infringe Apple's trademarks. From [[Randy Charles Morin|http://www.kbcafe.com/rss/?guid=20060924203715]]: "Anton Wilson suggests using Netcasting in place of Podcasting. I like it!" I like it too. Podcasting sounds too close to Broadcasting, when it's really narrowcasting. Although you can listen to a netcast on an iPod, the interesting pieces of the technology don't happen on the player. It's like calling a home stereo a "speakercaster." I listen to [[this|http://www.nrk.no/kanal/nrk_p3/5332366.html]] netcast every day, and [[Alex Bartett's netcasts|http://www.alexbarnett.net/blog/archive/2006/09/23/Alex-Barnett-Podcasts.aspx]] on OPML long long ago really changed my world. But I wouldn't trade [[my mp3 player|http://www.creative.com/products/product.asp?category=213&subcategory=214&product=12720]] for a [[bulky pod|http://www.makezine.com/blog/archive/2006/10/getting_a_discount_for_an_ipod.html?CMP=OTC-0D6B48984890]] with no mic and no replaceable battery. I'll pass on the Zune too.
''Exhibit C:'' I used to like MSN Search. A lot. It wasn't too hard to write fancy queries and consume them as feeds. But I've got a gripe with that new-fangled [[Live Search|http://www.live.com/?searchonly=true]]. To get the Search Builder link you first have to issue a query (any query). The query reference is very well hidden, and it's a nuisance trying to get a feed URL. What happened to the useful old [[RESTful|http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm]] MSN Search? In a moment of frustration I asked Live Search "[[Where did you hide MSN Search?|http://search.live.com/results.aspx?q=Where+did+you+hide+MSN+Search%3F&mkt=en-US&form=QBRE&go.x=0&go.y=0&go=Search]]". The first result: [["You Can't Hide from MSN|http://www.did-it.com/articles/092905.htm]]"!
I totally agree with Weinberger about topics, especially since he doesn't define what a topic is.
The metadata musings of David Weinberger have greatly influenced my thinking about software documentation. His [[blog|http://www.hyperorg.com/blogger/index.html]] is on my shortlist of mustreads, and I've been [[anticipating|Miscellaneous]] his latest book [[Everything is Miscellaneous|http://www.amazon.com/Everything-Miscellaneous-Power-Digital-Disorder/dp/0805080430]]. It's a splendid addition to the Metadata Thriller canon and a real page turner. I read it in a two long sittings. Apart from making 60-grit out of my corneas, it's an easy read. But for the lack of umlauts it could pass as a long New Yorker article, very much in the style of Malcolm Gladwell's writing.
I didn't catch any brand spanking new ideas that haven't been blogged about in the skinny part of the long tail, but not everyone follows this conversation. Weinberger's book is an excellent survey of the Wonderful World of Metadata. He is a master of illustration (see above: no art). If someone doesn't yet understand why metadata is important, this book spells it out.
The words "graph" and "network" aren't even in the index. There is one entry for "clouds" and 13 for "trees". It's like one of those books on Physics that boasts no equations.
[[Shelly Powers|http://burningbird.net/technology/misc]] has a good (and highly critical) review, and I agree with many of her gripes (especially wrt facets and the semantic web). Weinberger pushes the unfortunate myth that the semantic web is a top-down effort. He's not alone doing that.
The entire book linear text (1st order order) with some footnotes and an adequate index (2nd order order). That's a property shared by information representations made from molecules. Nonetheless, he had to choose one concrete structure and the book is organized into a chapters and down to H2 headings. The TOC only shows chapter headings. It would be fascinating to see some of the previous iterations of the TOC while he was writing the book, and why he settled on the one he uses. A little art would have gone a long way. How can you talk about taxonomy without some diagrams? (I plead guilty!)
A few factoids:
*The Library of Congress has 530 miles of bookshelves.
*Alphabetization by first letter dates back to ancient Greece, but it took centuries to extend the sorting to the second letter. Nearly 2000 years later it was still a tough concept. That's why nobody called AAAA Limosine in the Canterbury Tales.
*The concept of nested "is a" relationships dates back to Aristotle, but the first graphical representation of a tree structure came 700 years later.
*The title of the first book about faceted taxonomies: //Colon Classification//.
Curiously, nobody had tagged his book on Amazon as "miscellaneous". I fixed that.
Also, the "Customers who bought this item also bought" section doesn't list [[Ambient Findability|http://www.amazon.com/Ambient-Findability-What-Changes-Become/dp/0596007655]]. I can't fix that alone, and invite fellow Metadatappreciators to help.
Bonus Trees and Clouds factoid: on del.icio.us over the last 4 months there are about 20 ~URLs tagged as miscellaneous daily. The most highly related tags are: misc local unusual tutorials knowledge tutorial number numbers file-formats cool fonts
Confession: I started this post a month ago but got distracted. I had something else profound to say but have forgotten it. No doubt.
You can find all of the posts here, or on the Timeline, All, Tags, and More tabs on the right side of the page.
[[PackageThis hackery]]
[[PackageThis, PrintThat]]
[[For want of a connection string...]]
[[Weather station development]]
[[Linq between weather and data access]]
[[Building my new weather station]]
[[Miscellaneous, the Book]]
[[When the API is SendKeys]]
[[Welcome to the Trees and Clouds blog!]]
[[Make your own mini-MSDN library]]
[[Input devices and happy hands]]
[[Blog migration and classification]]
[[Gadgets, Sound, Formats, and Time]]
[[Trees and Clouds 2.0]]
[[What to do next?]]
[[Taking stock in Trees and Clouds]]
[[Documentation Development Integration, and upcoming events]]
[[Live Search Macros, Custom Search Engines, and Crappy UI]]
[[del.icio.us, Duality, Triples, and the Buckybase]]
[[OPML popping up in the most useful places]]
[[The Kirov Orchestra and Software Documentation]]
[[Scraping MSDN Forums with SGML]]
[[Original Material]]
[[Miscellaneous]]
[[The Law of Conservation of Documentation]]
[[Blogs and taxonomic documentation]]
[[Works in progress]]
[[Shiny new distractions]]
[[A quick MSDN library hack]]
[[Filtering MSDN feeds]]
[[A feed of feeds]]
[[Prettier feeds from the MTPS service]]
[[Conway's Law]]
[[Reading MSDN as a feed]]
[[Useful tools and diversions]]
[[Navigation paths and content items in the MTPS webservice]]
[[Checking for MSDN Wiki content by subject area]]
[[Rewriting ASP.NET URLs]]
[[Serving MTPS Pages With ASP.NET]]
[[Wrapping the MSDN Content Service]]
[[Mtps Topic Class]]
[[Grazing MSDN Forums]]
[[My Frightfully Ugly MSDN Viewer!]]
[[MSDN Available by Web Service!]]
[[Building feeds for legacy docsets]]
WikiWoe
[[OPML Camp Notes]]
[[OPML Editor]]
[[I am not a WIMP]]
[[The first post on this TiddlyWiki|8 March 2006]]
Good news [[here|http://blog.grazr.com/]] that Adam Green joining as a partner in Grazr. I haven't met them, and wouldn't know Mike from Adam, but I'm nonetheless very much indebted to them. Both for Grazr itself, and also for Adam Green's putting together [[OPML Camp|http://www.OPMLCamp.com]], and his assistance and hospitality. Thanks guys, and I'm looking forward to seeing what great stuff comes out of this.
Grazr is useful to me as a quick way to, well, graze OPML. It's been even more useful as a demo aid to show off OPML. I actually used Grazr as the primary set of "slides" for my first presentation on Trees and Clouds instead of Powerpoint, and will likely do it again. The semi-transparent wallpaper coming in Grazr looks yummy to me. I've been enjoying using pictures of trees and clouds as backgrounds in my slides.
There is one feature that I extremely wish Grazr had. I'm hoping to events to let me know which page Grazr is on. I want to keep a tag cloud in sync with Grazr, but need events for this. To see what I mean, look [[here|http://www.TreesAndClouds.net/brownbag.html]], and imagine the tags synced to Grazr. Grazr shows my [[Trees]]. The tag cloud (currently using ZoomClouds) shows my [[Clouds]].
!Topic Class for the MTPS Content Service
This class represents a topic in MTPS (MSDN Technet Publishing System).
It takes care of the web service stuff, so you have to have a reference to the web service in your app.
When you create a topic instance, you can access the various documents it contains.
Source in C# is [[here|http://www.TreesAndClouds.net/TopicClass.zip]]. For more information on the service, here is the [[documentation|http://services.msdn.microsoft.com/ContentServices/ContentService.asmx]] and the web service [[WSDL|http://services.msdn.microsoft.com/ContentServices/ContentService.asmx?wsdl]].
!Constructors
''Topic()''
Creates a topic for the root node of the MSDN library: the "magic" ("ms310241", "msdn.10", "en-us") node.
''Topic( id )''
Id can be in any of the three forms: short, alias, or guid. The default version will be "VS.80", but if that version doesn't exist, it will be created using the "MSDN.10" version. Example:
{{{Topic XPathNavigatorClassRefPage = new Topic("system.xml.xpathnavigator");}}}
''Topic( id, version)''
The default locale is your system environment locale.
''Topic( id, version, locale)''
You must use this form if you want any other locale besides the system locale. It will attempt to create the topic with the specified version, but will try another version if necessary. In the following example, the topic is actually created using the "MSDN.10" version.
{{{Topic aPageInJapanese = new Topic("4twe3fay", "vs.80", "ja-jp");}}}
!Properties
|''Property''|''Type''|''Description''|
|Version|string|topic version: currently MSDN.10 or VS.80|
|Locale|string|topic locale, such as en-us|
|~GuidId|string|guid form of the topic ID|
|Alias|string|friendly topic name, such as "system.xml.xsl"|
|~ShortId|string|short form of the topic ID, such as "4twe3fay"|
|Xhtml|~XmlDocument|the topic content in XHTML|
|Toc|~XmlDocument|list of child nodes in the MSDN table of contents|
|Links|~XmlDocument|list of links in the topic|
|Search|~XmlDocument|a treasure trove of topic metadata|
!Example
{{{
Topic t = new Topic ("system.xml.xsl");
Console.WriteLine(t.ShortId); // prints 70k6zz96
Console.WriteLine(t.Version); // prints MSDN.10
Console.WriteLine(t.Locale); // prints en-US
Console.WriteLine(t.Xhtml.OuterXml); // prints topic content in raw xml
}}}
!Exceptions
There is no exception handling (yet). The web service throws an exception if the topic isn't valid. Next step is to create an ~IsValid property that is false if the topic fails.
When someone gets their hands on a powerful tool, we may hope they use it to do good. Alas, I'm playing with the great new web services interface into the MSDN and ~TechEd content. And I've used it to create really ugly interface. Yikes! If you happen to know the identifier for a page and type it in the form, you get back a spew of raw XML for the page. If you get the id wrong, it fails ungracefully.
And I'm calling this good news!
This was the first time I've consumed a SOAP web service in a web app (actually, any app). It took a few hours, but really wasn't all that hard to figure out. There is plenty of room for improvement in my app, and I'm looking forward to doing some more interesting work with the content. Meanwhile I'm excited to get the first step running. I love it when stuff works!
There was one puzzle I haven't figured out. I couldn't run the app until I put the name of the ~WebReference in a "using" statement. None of the topics and books I looked at had that, and I only put it there in a grasping-at-straws moment. I don't know why it worked, and that's the only yucky part of the experience.
Masochists are welcome to use this newest MSDN browser [[here|www.TreesAndClouds.net/msdn/default.aspx]].
In the MTPS content webservice, content and navigation are entirely separate things, expressed by entirely separate kinds of documents. That is well and good. The table of contents is, after all, a somewhat arbitrary structure to give content a location. You don't really need the TOC if you are fine with using search and maybe the index. Still, the TOC is a handy map of the content. It's good that the content is independent of the TOC: so we can use it without the TOC, so we create our own TOC trees, and so we can use the same topic in several places in the tree.
In the MTPS service model, there are several kinds of XML documents you can get, including topic content, topic links, TOC fragments, metadata, images, and navigation paths. The relationships between these documents is a bit complicated, however.
The webservice has two operations, ''~GetContent'' and ''~GetNavigationPaths''. You use the ''~GetContent'' operation to get topic content. But you also use ''~GetContent'' to get navigational data, in the form of fragments of the TOC. Here's the confusing part: a fragment of the TOC is considered to be a content item. Over time I've managed to talk myself into believing this makes sense: after all, the TOC is a document you can render onto a screen. So now keep in mind that your item might be a topic page, or it might be a fragment of the TOC.
Each TOC fragment item lists the associated content topic, and its child topics, if any. But, the TOC item does not list the parent topic. That's where the ''~GetNavigationPaths'' operation comes in. Let's follow now how to get a topic and it's place in the TOC:
#Call ''~GetContent'' to identify the topic, and what documents are associated with it. A complete topic is identified not just by the topic identifier, but also by locale and version. The service will return a list of all the combinations of topic, version, and locale that are available, and what documents are associated with the topic. If you already know exactly what topic you want (and how many images it contains) you can skip this step.
#Call ''~GetNavigationPaths'' to get a list of topics between your one and the root topic in the TOC. If you topic appears more than one place in the TOC then you will get more than one path. The list you get back will identify both the content items and their associated TOC fragments.
#Call ''~GetContent'' (for the second time, if you had to do step 1) with complete information on exactly what topic you want, and what associated documents you want (images, lists of links, etc.).
#Call ''~GetContent'' again, for the third time. But this time, you request the TOC fragment, not the content item.
So now, after four calls we have the information we want. I added the navigation paths to my wrapper for a topic, because even if you don't need to know the parent topic, you might as well keep that information on hand from when you used ''~GetNavigationPaths'' to get the id of the TOC fragment.
You can pick up the updated Topic class source code [[here|http://www.TreesAndClouds.net/TopicClass.zip]].
OPML is a flavor of XML that can express hierarchical structures, such as trees. It is an acronym for Outline Processor Markup Language, and was first used as the native file format for an outlining application. The ability of OPML to describe trees makes it a valuable adjunct to RSS, which does not lend itself to outlines. Of course XML does great trees as well, but the simplicity and constrained vocabulary of OPML make it easier to move it between systems.
There are several ways OPML can be used.
* Currently it is mostly used as a container for RSS files. RSS readers usually export and import collections of RSS feeds in an OPML file that lists basic information about the feeds, such as name and url.
* OPML was originally intended to create outlines, and does this well.
* It can be used as a content authoring format. As OPML use increases, it remains to be seen how much content will migrate to the OPML file itself, and how much will be linked from the OPML.
OPML is significant for the DocFeed project as the delivery vehicle for ~TOCs. OPML is also problematic for this project because there are still few implementations of OPML browsers, and no support that I've found yet in RSS readers that support tree structures.
An important feature of OPML is that outlines in OPML can themselves reference other outlines. This is referred to as inclusion (or transclusion). Inclusion will be an important mechanism by which ~TOCs will be built.
OPML Camp this last weekend was interesting, often exciting, exhausting, and lots of fun. It was also tasty, thanks to Adam Green's hospitality. Thanks Adam! Bravo!
I really enjoyed getting to see a variety of problem domains where OPML is useful. The biggest differences were along the "how much content is in the OPML" axis. My use for OPML is all the way over on the "no content" side of the continuum. So, it was instructive seeing other approaches, and made me think (again) about where I want my content to be, and where I want to put my metadata.
OPML started life as, literally, a markup language for an outline processor. This line is still clearly visible, and we saw demos of three tools that would be appropriate for writing an outline, in a word processor-ish environment. These tools have platform differences, but are similar in that humans creating text entries are the central use case. I hadn’t realized the extent to which OPML Editor is scriptable, and I’d take another look if I was going to be writing outlines.
OPML gained a new set of users as the de facto import/export format for moving sets of feed subscriptions between browsers. These sets of subscriptions are being shared, often with the label "Reading list". One exercise we did at OPML Camp was to come up with our most simple and concise definitions of a reading list. I’ve seen a few blog rolls also called reading lists, too. Blog Bridge is doing some interesting things in the area of OPML sharing, and integrating it nicely into the reading experience.
I’m using OPML simply as a container, because of it’s ability to express hierarchies. Since feeds themselves are flat collections of items, possibly ordered in some way, you need to use some other way to build trees using content delivered in feeds. I think OPML is well suited for that task. It is lightweight and simple. OPML doesn’t rely on fixed hierarchy levels. A node is a child only when it is enclosed by a parent. There are no h1, h2, or h-whatever levels. This is consistent with my view of local trees. That is, I want to show hierarchical relationships between nearby nodes, with arbitrary nodes serving as the root. Since I’m looking at this local tree as a projection of a view into the set of elements, it is meaningless to try to build a tree that contains all nodes in any meaningful way.
So why am I interested in these other uses for OPML besides a nice tree container? It's because all of us want our trees rendered. Somehow. The work that the outliner and reading list folks are doing helps me too, by driving the development of OPML browsers, or at the very least import/export of OPML into other browsers. There may be other ways to express trees, but none with such a nice path to the browser.
The Grazr browser is the a beautiful example. All the way from OPML to RSS to items, Grazr just displays whatever it is pointing at. The transition from tree to branch to leaf is so smooth you don't notice it unless you know what to look for. That's the kind of polymorphism I want in an OPML browser. It models a local tree, where every node is the trunk and everywhere you travel on the tree you just see more branches and leaves. And all these local trees make up the network.
For a few weeks I was using Dave Winer's [[OPML Editor|http://support.opml.org/]]. If you’re actually going to write OPML, like with your fingers, then it’s nice to have an editor to help out. At that time I was playing around with formatting text in the OPML, but when I looked at the OPML that the editor created there was a lot of weird stuff, like <b></b><b></b> and worse. I was spending too much time cleaning it up in the Visual Studio IDE. Since VS let me collapse XML nodes and move them around, it was easy enough to do promotions and hoists and such. And I was more familiar with writing macros for VS.
But the real reason I stopped using OPML Editor was that when it was running I would get “router behind router” complaints on my network. Huh? Just what is that editor doing? I was skeptical, because it is just too odd. It might have just been a coincidence, but it has never happened since I stopped using the editor. I thought about this again when Tom Morris was talking about how the editor promotes OPML to the server. For a while I was playing around with a blog on opml.org. And then a few days I saw a notice about a tool to monitor OPML Editor processes, or something. Going forward, I don’t think I’ll be writing OPML by hand much. The exception will be if I use Grazr instead of ~PowerPoint, and that’s a whole ‘nuther topic. Of course, I’ll be generating and consuming OPML reading lists in RSS browsers.
The real fun will be playing around TOC (Table of Contents) in OPML and, uh, XHTML. Steve Butler asked me during a much longer conversation why I couldn’t just use XHTML for the TOC. I immediately responded with my usual “need OPML for the tree and the RSS” but have been thinking about that a lot since. It comes down to browser problems. Grazr is the only browser I know of that moves gracefully all the way between OPML and XHTML. I want to mess around with both the OPML and XHTML approach to see what the in-browser experience would be like. First step: ~XSLTs to roundtrip OPML and XHTML.
Speaking of moving between micro and macro levels. Steve also pointed me towards ICE (Information and Content Exchange Protocol) and NITF (News Industry Text Format) used in the news media industry. These are, in a literal sense, industrial-strength specs for syndication in a domain with long experience. The ICE spec is a fascinating read, as a preview of challenges coming up in the blogosphere. Actually, at 195 pages printed, it was just the right length to skim during my commute. Check it out!
It's a milestone week for OPML. Two fantastic new applications almost usher in the era of Trees and Clouds.
!OPML add-in for Firefox
Sergio "kromeboy" Longoni has released his [[OPML Reader for Firefox|http://dev.kromeboy.net/opmlr/]]. It is based on the [[OPML Auto-discovery Bookmarklet|http://www.cleverclogs.org/2006/10/opml_autodiscov.html]] by Marjolein "[[CleverClogs|http://www.cleverclogs.org]]" Hoekstra. Here is her article about [[OPML autodiscovery|http://www.cleverclogs.org/2006/10/opml_reader_opm.html]] and more.
This is important because it punches a hole through the wall separating the OPML and HTML worlds. Now you don't have to go through pasting URLs into a separate application or importing feeds or whatever usually yucky procedure your choice of browsers dictated. If you already installed the OPML Reader extension, you probably noticed the OPML indicator on the status bar light up. Now you can click and go straight to view my reading list in Grazr or Optimal. It's very beautiful.
As with RSS auto-discovery, you may still have to provide a hint to enable your readers to get the auto part of auto-discovery. Take a hint if you publish OPML: add a rel tag in the head of your document. The tag will resemble the one for RSS that you probably added already. At this time, only one OPML can be discovered in a file.
Here's what I added to make my reading list autodiscoverable:
{{{
<link rel='outline' type='text/xml+opml' title='Reading List' href='http://www.TreesAndClouds.net/ReadingList.opml' />
}}}
!Windows Live Search OPML Generator
[[Andy Edmonds|http://blogs.msdn.com/andyed/]] made the [[OPML Generator|http://surfmind.com/lab/msn/opml/]]. It's a search application that makes it a snap to create an OPML containing feeds that match your query. The query runs against Windows Live Search. Some things I found especially interesting:
*It showed me some blogs by folks doing cool things in my niche, and these were people I probably wouldn't have found by sifting through the postings of the A-listers.
*Apps that assist you using the big search sites are useful. Even if you have invested the time to master the query syntax, a good search app serves as a guide keeping you on productive paths. Joe Morel's Forum Explorer is another great example of this.
*The OPML Generator is crying out for navigation straight from OPML. Actually, I made the cry to Andy a few minutes ago begging for the auto-discovery rel tag.
When you can navigate straight from a ''query'' into an ''OPML'' then you have an instance of ''Trees'' //and// ''Clouds''. Not just Trees //or// Clouds. Exciting times!
I've posted a rough outline of what I'll be talking about at OPML Camp. The OPML is [[here|http://www.TreesAndClouds.net/OC.opml]], and you can view it in [[Grazr|http://www.TreesAndClouds.net/OC.html]] and [[Optimal|http://www.optimalbrowser.com/optimal.php?url=http%3A%2F%2Fwww.treesandclouds.net%2Foc.opml&submit=Submit]]. I doubt I'll talk about all the stuff on the outline, but if someone is interested in parts we can talk about it.
Adam Green has posted his outline notes too [[here|http://www.optimalbrowser.com/optimal.php?url=http%3A%2F%2Fopmlcamp.com%2Fpresentation%2Fopmlapi.xml&submit=Submit&linktarget=new]] . I'm hoping we can create an outline for all presentations by transcluding (ha! used a fancy word!) our outlines into the event outline.
Last Friday afternoon I had the great pleasure of talking with Steve Butler for four hours about docs navigation/discovery stuff. It was superfantastic getting to see some of the great stuff cooking at MSDN, and I'm still trying to get my mind around some of his ideas.
One of most immediately useful tricks I saw was how to get the plain XML of ~MSDN2 pages. Just look at the printer friendly url, but change d=printer to d=xml.
These InterfaceOptions for customising TiddlyWiki are saved in your browser
Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)
<<option Richard Edwards>>
<<option chkSaveBackups>> SaveBackups
<<option chkAutoSave>> AutoSave
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
<<option chkAnimate>> EnableAnimations
See AdvancedOptions
Where is my original material?
In a small way, it got overwritten. I'm diligent about my weekly backups, but never got around to source control at home. That's why there is a week's hole in the MSDN ~DevWiki coverage for the ~WikiFeed tool I posted yesterday. Dogfooding is well and good, but I'm not going to install Team Foundation Server in my garden shed. Last week I learned that [[Perforce|http://www.perforce.com]] is free for up to 2 users and 5 clients. It took less than 30 minutes to download and set up. (I've used p4 before, but had not set up the server.) Very nice.
In the larger sense, I'm trying to understand what "original material" is. The posting on [[The Law of Conservation of Documentation]] got some e-mails moving. Clearly there are many definitions along a gradient in who knows how many dimensions. An easy impossible first step might be nailing down the distinction between content and presentation. (When you finish that one, can you do the same for data and metadata please?)
Technical writers are usually hired to document a project or process that someone else has designed. When projects are run well then writers are involved in the design phase, and are often valued for contributions to the UI. The writer may help write the specs (the specs are almost always better for it), and those early meetings are great help towards understanding the product.
What writers do not do is jump in the fray and drive the product design. At least, I've only ever heard of one who did (and got smacked down, even though it turned out he was right). Technical writers document someone else's design. It often takes a lot of imagination to do well. Does it take a solid understanding of the product? I've heard strong arguments both ways, but I've made up my mind on that one as a user reading documentation that is clearly science fiction. (Not to be confused with the absolutely mind-bending scrumptious fiction from ex-msft writer [[Ted Chiang|http://www.amazon.com/Stories-Your-Life-Others-Chiang/dp/0765304198]].)
For me, original material is the stuff nobody in your neighborhood has ever thought of, and probably wouldn't think of. Writers always work with original material, and the best ones know where to get it. At the moment I'll be happy just to submit these changes and get the post up.
I've been playing around more with the [[PackageThis|http://www.codeplex.com/packagethis]] application. Last month I modified it to print large chunks of MSDN or ~TechNet documentation. That utility wasn't compatible with ~PackageThis. I've merged the print and cache parts back into my local modification of ~PackageThis. SQL Server Express is required, but the database is set up automatically now. I might switch to SQL Server Compact, which is easier to install as an embedded component than Express. Compact, however, doesn't support full text search. I, meanwhile, don't support full text search either.
Now I can play with bigger chunks of concatenated topics a whole new set of nuisances emerge. For example, empty self-closing bold tags (<b />) aren't all that common in MSDN topics, but if I hit one then all the subsequent text is rendered bold. Instead of playing with content selection I've had to mess around with content appearance much more than I want. My biggest gripe with the Mtps Content Webservice remains the lack of transforms and stylesheets. I've got a rats nest of ~XSLTs, ~XLinq queries, and regular expressions that somehow squeeze readable content out in the end. Without the transforms in ~PackageThis it would have been a lot harder.
I've also been playing a bit with my weather station. The data collection service now has no responsibilities besides politely tossing numbers into SQL Server. The display is handled by ASP and LINQ. The URL for the new site is [[http://www.TreesAndClouds.net/weather|/weather]]. The page isn't very attractive, and after working with the MSDN pages I'm quite satisfied to put no presentation effort into it. Yes, but the data is tasty!
Last Spring when the [[PackageThis|http://www.codeplex.com/packagethis]] application came out I sent a "nice job" email to Larry Jordan at MSDN. He forwarded it to the ~PackageThis author. By happy coincidence that was none other than Erik Larsen, a co-worker on the Visual C++ Language Reference back almost 15 years ago.
~PackageThis is a nice tool that lets you build your own selection of MSDN or ~TechNet topics into a .chm or .hxs. It is also a nice sample showing the [[Mtps content webservice|http://services.msdn.microsoft.com/ContentServices/ContentService.asmx]] in action. I'm not much of a fan or .chm or .hxs, so while I enjoyed looking at the code, I never actually used the tool. The tool I really wanted was one to print multiple MSDN topics to read on the bus. If you've ever tried to print a .chm you know that's not a nice user experience! What I want is to print the topics stripped of non-relevant (for me) sections such as See Also, code samples in VB, supported platforms, etc. The ~PackageThis tool got me charged up to finally make my ~PrintThis tool. Besides working code, ~PackageThis offers a special treasure: an XSLT to render decent-looking pages from the XML returned by the content webservice. The webservice docs should really have included a sample XSLT. It's a time-consuming bore having to write your own.
The print tool is working quite nicely, most of the time. It's handy also just as a MSDN browser that can display multiple topics. However, I simply took Erik's code and went my merry way. I'm slowly getting it ready to merge back into the ~PackageThis tool. I've also added a page cache to the tool that saves pages you visit into a SQL database.
Today I gave a presentation on Syndication and Documentation to my group at work. It's really a pleasure doing this, and I get excited when people come afterwards with great questions. This was part of a series of talks I've been giving to different documentation groups at Microsoft in preparation for OPML Camp later this month.
The previous presentation I did using the [[Grazr]] browser instead of Powerpoint. Hopefully the next one will be on Grazr again.
There were a lot of short demos in the presentation, and a longer one for del.icio.us. Actually, there were thirteen demos in an hour talk! I would have given a quick look at a RSS reader if there was time, but cut it out, saying that it's important to note that feeds won't necessarily end up in a reader like HTML shows up in a browser. Here's what I showed:
|Comic relief | Web 2.1 [[server-side blinking text|http://cheese.blartwendo.com/web21-demo.html]] demo|
|Mashups | [[HousingMaps|http://www.HousingMaps.com]] and [[Colr Pickr|http://www.krazydad.com/colrpickr/]]|
|Tagging | [[my del.icio.us|http://del.icio.us/iredwards]], [[Expialodocio.us|http://www.expialodocio.us]], and [[Delicious soup|http://www.zitvogel.com/delicioussoup/index.php]]|
|User Power! | [[Safari Bookshelf|http://safari.oreilly.com]] + [[Greasemonkey|http://greasemonkey.mozdev.org]], and [[FeedJumbler|http://www.vstscontent.com/VSTS-TeamFoundation.htm]]|
|Taxonomy | [[Aqua browser|http://aqua.kcls.org/]], and [[Fac.etio.us|http://demo.siderean.com/facetious/facetious.jsp]]|
|Trees and Clouds | [[Grazr|http://www.grazr.com]] + [[ZoomClouds|http://www.zoomclouds.com]] together on [[this page|http://www.TreesAndClouds.net/brownbag.html]]|
|Attention | [[Gesture Bank|http://root.net/people/redwards]]|
The slides for the show are available at [[www.TreesAndClouds.net/JahMtg.ppt|http://www.TreesAndClouds.net/JahMtg.ppt]].
Here notes for some presentations I did.
[[Windows CE UE|BrownBagPresentation]], at Microsoft, April 23, 2006
[[Visual Studio Team System UE|Presentation Notes]], at Microsoft, May 9, 2006
[[OPML Camp|OPMLCampOutline]], at Harvard University, May 14, 2006
Please let me know if you would like me to give a presentation to your organization.
It's well and good to have presentation-neutral content delivered from the MTPS web service. Ultimately though, the whole point about documentation is to read it. And to read it, you have to render it. That's not too hard... just past it through an XSL transform, right? Well yes, as long as you have a nice transform handy. Now after a couple of days of XSL anguish it's easy again!
Namespaces in XSL appear very straightforward at the first skimover, but it took me quite a while to get the hang of it. I still don't understand why my results kept being decorated with namespaces listed in the exclude-result-prefix attribute. I read somewhere that XSL makes hard things easy, and easy things hard. Eventually, the following template got me started fixing up the transformed results and bending namespaces to my will.
{{{
<xsl:template match="xhtml:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
}}}
These kinds of speedbumps on the path to technology mastery still don't take as much time as just handling all the edge cases and quirks. I really think the MTPS service docs should include some ready-to-go transforms for folks who just want to consume the content and not spend a lot time mucking around in the XML.
[[Here|http://www.TreesAndClouds.net/CSharpReference.xml]] and [[here|http://www.TreesAndClouds.net/system.xml.xml]] are some new examples of sets of topics rendered as an RSS feed. The tool I made these with takes a topic Id, and delivers the topic and all it's children in an RSS feed, with just the parts of the topic I find interesting. As soon as I remember how I got the Url rewriting to work last week then you can make your own ~RESTfull feeds on my web server.
There is a reason I want these feeds: they form the basis for portable mashups of many kinds of content, organized by small local trees.
I haven't posted here for almost two months. How time flies! Here's a little progress report on the Weather and PackageThis projects.
!!Weather
It happens every time. You're confident your app is finished. Sure, it has plenty of features you still want to add, and some rough edges to polish. But the app closely resembles what you set out to build and does what you wanted it to do. It's been running like a champ for a while. Sounds like it's time to celebrate and indulge in a bit of showing off. Isn't this little demo the cat's miao! So... how come it rained 120 inches last week? It doesn't feel like it's -999 degrees outside.
Lessons learned:
*Inadvertently setting your system clock a month fast can cause severe weather events.
*When you create a service account and neglect to make the password never expire, the service will not come to life and renew its password by itself.
!!~PackageThis
I moved the ~PackageThis cache over to SQL Server Compact, which makes installation a snap. It also has a nifty installer and some other features. That project has been on the back burner for a few weeks now, but if anyone is interested I can provide what I've got. There were some problems installing on Vista, but I'm hoping that is fixed now that Orcas and the 3.5 Framework have shipped.
RSS (Real Simple Syndication) is a simple XML document format used to exchange documents.
The specification for RSS 2.0 can be found [[here|http://blogs.law.harvard.edu/tech/rss]].
An OPML file containing the feeds someone follows is often referred to as a reading list.
You can see my reading list here at [[www.TreesAndClouds.net/ReadingList.opml|http://www.TreesAndClouds.net/ReadingList.opml]].
You can see a lot of other reading lists at the wonderful Share Your OPML site: [[http://share.opml.org|http://share.opml.org]].
I've been wanting to be able to get MSDN topics by RSS, choosing the topics by TOC location. It's possible (and useful) to get to them through a MSN Search output as a feed. But there are two big problems. You only get the topics you can hit with your query, and you only get a tiny excerpt from the topic to help you identify it.
I tried earlier building feeds from pages downloaded from the library. If you get an Xhtml page by specifying (d=xml) in the Url, then you get a much cleaner page than the normal behemoth pages. Still, I had trouble getting these pages into a feed. For example, the ~XPathNavigator chokes on script on many of the pages.
It's a lot easier using the content service. The hardest part is deciding how to render it for the feed. If you think writing HTML by hand is boring, try writing escaped HTML (where, for example, the less-than {{{<}}} character is written as the entity {{{>}}}). XSLT has a disable-output-escaping attribute for the xsl:text instruction, but I found it difficult to handle topics that described output escaping and other edge cases. In the end I just used the XSLT to pick what I wanted f