Collapse long text (with more/less links) I wrote a little function to compact long text. I am relatively new to JavaScript so I am not sure I wrote it as elegantly as possible. I wrote it to be runnable on the server side (Node.js) as well, so can't use jQuery or such. Can the code be improved?

// change a long text into  "bla bla bla... (more)" where (more) is a link to open the rest of the text
// compact text if over maxWords words (split by ' ', default 25)
//           or if over maxRows lines (split by '&lt;br&gt;', default 2)
// but avoid compacting if no more than "almostFinished" (default 5) words to the end of the text
compactText = function(text, prefix, maxWords, maxRows, almostFinished) {
    if (!maxWords) {
        maxWords = 25;
    }
    if (!maxRows) { 
        maxRows = 2;
    }
    if (!almostFinished) {
        almostFinished = 5;
    }

    var result = [];
    var compacted = false;
    // escape the html code in the text
    text = (text || '').replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g,'&amp;gt;').replace(/\r/g, ' ').replace(/\n/g, ' &lt;br&gt; ')
    var pn = text.split(' ');
    var row = 1;
    for (var word=0; word&lt; pn.length; word++) {
        if (pn[word] === "&lt;br&gt;") {
            row++;
        }
        if (!compacted &amp;&amp; (row &gt; maxRows || word == maxWords) &amp;&amp; word&lt; pn.length - almostFinished) {
            compacted = true;
            /* too long - add a (more) link and open hidden span for rest of text */
            result.push('&lt;span class="'+prefix+'-more-text"&gt;...&lt;a href="#" onclick="javascript:$('+
                    "'."+prefix+"-more-text').toggle(); return false;"+
                    '"&gt;(show more)&lt;/a&gt;&lt;/span&gt;');
            result.push('&lt;span class="'+prefix+'-more-text" style="display:none"&gt;');
        }

        result.push(pn[word]);
    }
    if (compacted) {
        // compacted: add link to toggle back (less) and close the hidden span.
        result.push('&lt;a href="#" onclick="javascript:$('+
            "'."+prefix+"-more-text').toggle(); return false;"+
            '"&gt;(show less)&lt;/a&gt;&lt;/span&gt;');
    }

    return result.join(' ');
}
Instead of pn use a longer variable name. A variable like this with such a big scope really deserves a longer name. It would make the code easier to read.

var pn = text.split(' ');

Instead of commenting use the comment name as a function name:

// escape the html code in the text
text = (text || '').replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g,'&amp;gt;').replace(/\r/g, ' ').replace(/\n/g, ' &lt;br&gt; ')


I'd write this:

function escapeHtml(text) {
    if (!text) {
        return "";
    }
    return text.replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g,'&amp;gt;').replace(/\r/g, ' ').replace(/\n/g, ' &lt;br&gt; ')        
}

I'd create a createToggleLink function. 

function createToggleLink(prefix, linkText) {
    return '&lt;a href="#" onclick="javascript:$(' +
            "'." + prefix + "-more-text').toggle(); return false;" +
            '"&gt;(" + linkText + ")&lt;/a&gt;');
}


It removes some code duplication and furthermore makes it more explicit that you close the span tag:

if (compacted) {
    var toggleLink = createToggleLink(prefix, '(show less)');
    result.push(toggleLink);
    result.push('&lt;/span&gt;');
}


So, the comment is unnecessary, the code says the same.