I'm currently using Jade on a new project. It seems well-suited to composing webapp layouts, but not for writing static content, such as a web page of
elements containing text.
For example, to create such a paragraph, I believe I need to do this:
p
| This is my long,
| multi-line
| paragraph.
For a static web page full of real paragraphs of text, using jade becomes a burden due to that pipe symbol at the beginning of each line.
Is there some sort of syntactic sugar for marking the whole block as a text node, as the pipe symbol does on a line-by-line basis? Or an existing filter I'm unaware of?
One solution I'm exploring is the creation of a :block filter or something, that prepends each line with a | and then passes it to Jade, but jade's documentation on creating filters is sparse to say the least, so that may take a while to figure out. If anyone can provide guidance as to such a solution I'd appreciate it.
From the jade github page:
p.
foo asdf
asdf
asdfasdfaf
asdf
asd.
produces output:
<p>foo asdf
asdf
asdfasdfaf
asdf
asd
.
</p>
The trailing period after the p
is what you're looking for.
After some tinkering, I worked out the details of a filter that accomplishes this. Posting the answer here since I imagine this will be useful to others using jade.
The code to create the filter turns out to be quite simple:
var jade = require ("jade");
jade.filters.text = function(block, compiler){
return new TextBlockFilter(block).compile();
};
function TextBlockFilter(node) {
this.node = node;
}
TextBlockFilter.prototype.__proto__ = jade.Compiler.prototype;
TextBlockFilter.prototype.visit = function(node){
// first this is called with a node containing all the block's lines
// as sub-nodes, with their first word interpreted as the node's name
//
// so here, collect all the nodes' text (including its name)
// into a single Text node, and then visit that instead.
// the child nodes won't be visited - we're cutting them out of the
// parse tree
var text = new jade.nodes.Text();
for (var i=0; i < node.length; i++) {
text.push (node[i].name + (node[i].text ? node[i].text[0] : ""));
}
this.visitNode (text);
};
And then the markup looks like this. Note that it allows you to include other jade stuff in between :text blocks:
p
:text
This is my first line of text,
followed by another
and another. Now let's include a jade link tag:
a(href="http://blahblah.com")
:text
and follow it with even more text
and more,
etc