plinks—a purple numbers variant
Via Tim Bray, I came across the concept of Purple Numbers. In a nutshell these are permalinks attached to every paragraph on a page which, to paraphrase Tim, make every paragraph on a page a first-class Web citizen.
That’s a very worthy concept, but the implementations I’ve seen have so far failed to inspire me. First of all, while the ability to link to any paragraph on a page is useful, the links themselves are either ugly, distracting or both. While reading Tim’s entry I found myself mentally pausing after each paragraph: probably because I’m used to the purple # marks on Scripting News and other such sites designating the end of an entry. They’re also extra cruft in my markup.
So, my ideal purple numbers implementation would minimise markup pollution and visual clutter.
Another issue with purple numbers is permanency: they’re absolutely no good if they don’t stay as true permalinks. This rules out naively generating them on the fly when a page is outputted as future edits to an article could result in links targetting different paragraphs entirely. Instead, the links (in the form of id attributes on paragraph tags) need to be assigned when the content is created. If additional paragraphs are later added to the content they should be numbered in such a way as not to intefere with the original paragraph links, which I shall call plinks for the sake of brevity.
We’ll ignore the issue of visual clutter for the moment: let’s look instead at how plinks can be introduced without polluting the markup of my pages. While the IDs that form the target of the links are a critical part of the structure of the page, the actual links are something of a convenience for people who don’t want to dig through my source code looking for IDs and are unaware of the various bookmarklets that can reveal them (such as Jesse Ruderman’s named anchors). As such, I don’t see the links as a critical part of the page content, so I have no qualms whatsoever about appending them to the page using JavaScript after the page has loaded. Here’s the function I’m using:
function addpLinks() {
var paras = document.getElementsByTagName('p');
for (var i = 0; i < paras.length; i++) {
var current = paras[i];
if (/^p-/.test(current.id)) {
// It's a purple link paragraph
var plink = document.createElement('a');
plink.href = document.location.href.split('#')[0] +
'#' + current.id;
plink.className = 'plink';
plink.appendChild(document.createTextNode(' #'));
current.appendChild(plink);
}
}
}
The function iterates over every paragraph on the page looking for paragraphs with an id that starts with “p-”, my chosen format for plink IDs. When it finds one, it creates a new link using the DOM and assigns it an href attribute which is the base URL of the current page (not including any existing fragment identifier) with a # and the paragraph’s ID appended on the end.
My plinks all have a class of “plink”, which allows me to style them. This is where I can reduce the visual clutter on the page as much as possible. Consider the following:
p a.plink {
text-decoration: none;
color: #c8a8ff;
display: none;
}
p:hover a.plink {
display: inline;
}
In an ideal world this would make the links invisible until the mouse cursor was positioned over the containing paragraph. Unfortunately, IE for Windows only honors the :hover pseudo-selector when it is applied to links. I’d like IE users to have at least a chance of discovering my plinks, so I came up with this:
p a.plink {
text-decoration: none;
color: #fff; /* the page background colour */
}
p:hover a.plink, p a:hover.plink {
color: #c8a8ff;
}
The plinks are initially invisible by virtue of having the same colour as the page background. In browsers that support :hover on paragraphs, they become visible (by changing colour) when the mouse hovers over the paragraph. In browsers that only support :hover on links, they become visible when the mouse hovers over the links. Sure, they’re a lot harder to find but I see it as an easter egg for IE users. Another example of MOSe in action.
There are a couple of more pieces to the puzzle. Firstly, adding all of those IDs to those paragraph tags is the kind of task that humans avoid and computers thrive on. Now I could automate this in my CMS, but I’m not in the mood for PHP at the moment so I’ve automated it in a bookmarklet instead: Add plink IDs (drag to your bookmarks). The bookmarklet will look inside any textareas on the current page and add an ID to every paragraph, provided it’s a simple <p>. It’s something of a quick hack but it does the job. Here’s the bookmarklet code expanded to show how it works:
javascript:(function() {
var tas = document.getElementsByTagName('textarea');
for (var i = 0; i < tas.length; i++) {
var ta = tas[i];
var text = ta.value.replace('<p>', function() {
if (typeof arguments.callee.counter == 'undefined') {
arguments.callee.counter = 0;
}
return '<p id="p-'+arguments.callee.counter++ +'">';
});
ta.value = text;
}
})();
Incidentally, the above uses a technique I picked up today while flicking through David Flanagan’s eternally useful JavaScript: The Definitive Guide. Inside a JavaScript function a special object called arguments is available. The object has a property called callee which refers to the function itself, even if as above it’s an anonymous function. Since functions are objects they can have properties: in this case, I create a counter property and use it to keep track of the IDs as I assign them. The whole lot is contained within a function argument to a replace call, where the function is called every time a <p> is found to determine what to replace it with.
At this point I had everything I needed, but then inspiration struck: how about a method of highlighting a paragraph if a user should visit a page using a link that targetted it? Suporting this meant adding yet another function to be executed once the page had loaded:
function plinkHighlight() {
if (/#p-/.test(document.location)) {
// The user arrived via a plink
var plink_id = document.location.split('#')[1];
var para = document.getElementById(plink_id);
para.className = para.className + ' plinkHighlight';
}
}
A custom style for the highlighted paragraph can now be defined using the plinkHighlight class hook.
I’ve now implemented all of the above on this site (mostly in the file plinks.js) although currently this is the only entry that contains plink IDs. Best of all, I didn’t have to touch a single line of my CMS! This JavaScript thing could really catch on some day.
CpILL - 30th May 2004 09:28 - #
I agree with CpILL, the hash looks awful and is very distracting. It's also not very user-friendly: when I first came to this page I thought you'd gone wrong with your markup somewhere, when I saw all the hashes!
Perhaps you could try prepending your paragraphs, perhaps with a biblical numbering system or similar?
Forget that. How many people want to link to specific paragraphs? Is there any evidence this is a requirement? I suspect, although I have no proof, that only a small number of people would want to do this. Keep the anchors, but keep them hidden!
Thus, if the vast majority of your visitors would never use this facility, there's no reason to clutter up the page with cruft.
DarkBlue - 30th May 2004 10:56 - #
Chris Dent - 30th May 2004 12:12 - #
It seems to me a very useless application of both the markup and javascript. Distinguishing all paragraphs you distinguish no paragraph in particular, unless you believe in awards being awarded to everyone (some do). If a part of the text is to be exposed for some reason as worthy linking to, why not divide the section into subsections, use the plain old horizontal rule with an id?
Baroque.
No, it's actually Rococo, albeit viewed in a broken mirror :]
Moose - 30th May 2004 12:35 - #
mnot has something on this too today.
eric scheid - 30th May 2004 12:36 - #
First of all: very good job, Simon! I like your way of practical thinking.
And I dare to disagree with DarkBlue in his suggesting, that this concept of purple links is useless. I see it has real value for "content pages" - like this blog or SitePoint or some pages with documentation or anywhere, where you have long content which is worth pinpointing.
The visual handling of it is a matter to discuss but the concept is definitely good.
Jan Korbel - 30th May 2004 12:48 - #
Moose: You're not adding the identifiers because you want to make something special, it is so that if someone else thinks your stuff is special, they can point at it. You, being ignorant of them, don't know what they might think is special, so make everything available to be special.
This places control of what to cite in the hands of reader/citer rather than the author. I think this is a very good thing, some may not.
Chris Dent - 30th May 2004 12:56 - #
Randy Charles Morin - 30th May 2004 16:06 - #
I like the idea of purple octothorpes, particularly for data-laden posts or sites that need another level of organization, as Jan suggests -- though as Chris says, you never know when your throat clearing noises will strike someone as essential information.
And Simon, I agree entirely with your making the links invisible on the page until hovered over. (Might be worthwhile, if this thing catches on, to "stamp" a site some way in order to indicate that it's loaded with links.)
By the by, I happened to look at your page, Simon, in Firefox (Version 0.8), and your number signs are all visible and green. I have JavaScript turned on etc. Dunno.
Simon Fodden - 30th May 2004 16:18 - #
Simon Willison - 30th May 2004 18:58 - #
I really like the idea; although, the XPointer Element Scheme offers a more flexible alternative to simple idrefs. It's a pity that no browsers currently support it though... Sounds like a good javascript project to start, like this one only cross-platform.
Jimmy Cerra - 30th May 2004 19:22 - #
Wouldn't it be better to have a 'show links' button/link somewhere, so that the links only appear when it is clicked on? That way there'd be no clutter or distraction for anyone who isn't interested in this.
Another possibility is a bookmarklet which finds the anchors that selected text lies within. I don't know enough javascript to tell if that's even possible. Maybe some variant on the partial source bookmarklet.
Daniel - 31st May 2004 00:12 - #
"And I dare to disagree with DarkBlue in his suggesting, that this concept of purple links is useless."
I didn't write or suggest that the links are useless. I expressed my opinion, that I see nodal links as of being useful only to a limited audience, or to a wider audience under limited conditions.
Whether I am right or wrong in this opinion is irrelevant: even if nodal links are useful to a handful of users then it is worthwhile to employ them - providing their deployment does not negatively impact on those users to whom they are not useful.
My principle objection was to the addition of a "#" to end of each paragraph. Simon suggested that I reload the stylesheet... I did, the hashes vanished and all's well with the world.
Personally I would prefer to quote from a extrinsic resource than link to a node of it. But this is a purely subjective preference, YMMV.
DarkBlue - 31st May 2004 00:30 - #
"Wouldn't it be better to have a 'show links' button/link somewhere...?"
Exactly! Provide the mechanism, but keep it invisible to those users who have no need of it.
DarkBlue - 31st May 2004 00:33 - #
Simon Willison - 31st May 2004 01:24 - #
I can't help but feel that there must be a more intuitive way of handling this Simon. Sadly, I cannot see what it is.
Possibilities:
DarkBlue - 31st May 2004 03:09 - #
'meaningless to the informed unless "title" is descriptive'
should have read, 'meaningless to the uninformed unless "title" is descriptive'. Sorry.
DarkBlue - 31st May 2004 03:12 - #
I have to wonder, how useful is this really going to be? I can think of maybe two or three situations where I've been linked to a fragment of a page and not immediately needed to scroll up to understand what the context of the entire thing was, and none of those were blogs.
On something like A W3C Recommendation, sure, it makes a lot of sense. If I'm just interested in x new CSS selector, then having to skim through the rest of the bloated document is an unpleasant thought. What is the longest entry you've ever written though, Simon? Blog posts are usually on one coherent issue, and you really cannot take just part of the document without looking at the rest.
If, however, you do feel that a post is long enough that people might want to link to just a specific part, wouldn't it be far better to use proper headings throughout the entry and let people link to them? That also adds to the scannability of the document, and reassures visitors coming in via these links that they've started at the top of a section, so might not need to scan above (but quite possible still could).
Finally, I find the visual effect jarring. Tim Bray's implementation stops me reading for half a second at the end of each paragraph before adjusting and reading on to the next one. Your one is more subtle and doesn't do that, but if I'm mousing over a link to see where it leads, or to open it in a new tab, then as I bring my mouse cursor towards it there's a lot of distracting appearance and disappearance of hashes all over the place, the same when I mouse away.
In the end how many people are going to benefit from this? Even if you do think that people might want to link to specific paragraphs, and that that desire is warranted for your particular post, isn't it better just putting the ids into the source so that potential linkers can scrummage through that to find the link they want, rather than making it an easier experience for them at the cost of every other visitor to your site? Making it a bit harder for them to find the write place to link to could also have the advantage of leading them to consider whether they really need to link to just a specific paragraph.
I guess you could say I'm not a fan.
Lach - 31st May 2004 03:50 - #
Lach: you're probably right - this technique does serve documents such as W3C recommendations better than it does blog entries. But seeing as I don't maintain a collection of W3C recommendations and this blog is my technical playground (as demonstrated by my suicidal tendency to serve things as
application/xml+xhtml) I have no qualms about implementing plinks here. I probably won't be applying them to shorter entries - that's a benefit of adding the IDs manually (well, manually with the aid of a bookmarklet) rather than serving them up automatically.If you really can't stand them, you could always kill them out right with a user stylesheet ;)
Simon Willison - 31st May 2004 04:06 - #
Since everyone seems to agree that hashes are ugly (they beat numbers, but I haven't seen anyone too enthusiastic about their appearance), why not use pilcrow signs instead? They look much better at the end of paragraphs.
Combining them with your hovering visibility approach would still be necessary though, because a document full of pilcrows is still not very appealing :)
Michael Day - 31st May 2004 12:34 - #
I like Michael Day's suggestion of using the Pilcrow. However, traditionally the pilcrow marks the beginning of the paragraph rather than the end (which is also the point in the page that you actually want to reference). A better UI for this sort of thing would be a light-grey pilcrow (or a lighter/transluscent pilcrow in the same colour as the paragraph text) placed to the left of the first word in the paragraph. For aesthetic reasons, the paragraph body should also be fully indented from the pilcrow marks. Perhaps a stylized bullet in an unordered list would do the trick?
Hiding the pilcrows so they only appear when moused over is also important, I think.
DK
Dietmar Koblenz - 31st May 2004 20:04 - #
BTW, an OT question: When did you start using Google to redirect links from your site? What was your reasoning behind the change?
-Scott
Scott Johnson - 1st June 2004 21:33 - #
Simon Willison - 1st June 2004 21:50 - #
Apply that across an organisation's intranet and legacy system, then watch people start dealing with the documents from the inside out. When I do a search I'll be presented with a whole bunch of paragraphs that match the terms, if they look useful, I can open the document. Its just another step in weaning us from the idea of the document as the baseline for the source of information and shifting the focus to the content and the meaning.
The mockery and semi-angry behaviour attached to purple numbers is a sign that something very interesting is going on. That's the problem with an inherently disruptive technology, sometimes it upsets the cart and kicks the apples all over the place, my damned apples what's more.
The idea that "they wont get used" is not relevant, once their value is appreciated, they will spread like wildfire.
Earl Mardle - 2nd June 2004 06:25 - #
Jan! - 2nd June 2004 17:30 - #
Craig - 8th June 2004 17:33 - #
http://pharmacy.edrugstore.md/z/246/CD1014/ - 17th June 2004 21:15 - #
Anton Andreasson - 21st July 2004 11:18 - #
This bit of purple numbering javascript from my blog might get you going in the right direction.
Chris Dent - 21st July 2004 15:00 - #
Anton Andreasson - 22nd July 2004 09:22 - #
Simon Willison - 22nd July 2004 16:38 - #
Anton: Fine with me too. I think something for ALA would be fantastic. I hope you'll chase the chain of credit back through me, Simon, Eugene etc all the way back to Doug Engelbart. I'm glad the javascript is working well for you.
In a related note: Back when Tim Bray, Simon, jluster, Randy Brown and others had their sudden moment of "hey let's do purple numbers" Eugene set up a wiki and mailing list at Blue Oxen so folk could discuss the future of purple numbers. Unfortunately he and I both got distracted by other things after that and it never took off the ground. However the wiki is there and usable at http://purple.blueoxen.net/ and the mailing lists could be made active if there is interest.
Chris Dent - 22nd July 2004 17:27 - #
sureshgovi - 17th July 2006 10:17 - #