Skip to content

Commit

Permalink
Merge pull request #22 from remy/master
Browse files Browse the repository at this point in the history
Add support for rounding to end of sentence
  • Loading branch information
cgiffard committed Sep 2, 2014
2 parents e65fe59 + 5bf701a commit 2eadf3e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
45 changes: 37 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ var XRegexp = require('xregexp').XRegExp;
(function (exportTo) {
"use strict";

// Define our parse states
var PARSER_UNINITIALISED = 0,
PARSER_TAG_COMMENCED = 1,
PARSER_TAG_STRING = -1,
PARSER_TAG_STRING_SINGLE = -2,
PARSER_COMMENT = -3;

// Nodes which should be considered implicitly self-closing
// Taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#void-elements
var voidElements = [
"area", "base", "br", "col", "command", "embed", "hr", "img", "input",
"keygen", "link", "meta", "param", "source", "track", "wbr"
];

var sentenceTerminatorElements = [
"br", "p", "ol", "ul", "li", "div", "form", "article", "section", "body", "title", "h1", "h2", "h3", "h4", "h5", "h6", "header", "footer", "main", "dd", "dt", "pre", "figure", "figcapture", "td", "th"
];

var downsize = function (text, inputOptions, offset) {
var stack = [],
pointer = 0,
Expand All @@ -34,6 +45,14 @@ var XRegexp = require('xregexp').XRegExp;
Number(options.characters);
options.limit = isNaN(options.limit) ? Infinity : options.limit;

function peekTag() {
var peek = null;
text.slice(pointer).replace(/^(?:<[/]?([a-z]+)?)>/i, function (all, match, position) {
peek = match;
});
return peek;
}

function isAtLimit() {
var stackIndex = 0;

Expand All @@ -42,6 +61,23 @@ var XRegexp = require('xregexp').XRegExp;
return false;
}

if (options.round) {
if (parseState !== PARSER_TAG_COMMENCED) {
return false;
}

// If we are at a PARSER_TAG_COMMENCED then sniff the tag and check
// whether it's a sentence terminator
if (parseState === PARSER_TAG_COMMENCED) {
var tag = peekTag();
if (~sentenceTerminatorElements.indexOf(tag)) {
return true;
} else {
return false;
}
}
}

// If we've got no special context to retain, do an early return.
if (!options.keepContext) {
return true;
Expand Down Expand Up @@ -87,13 +123,6 @@ var XRegexp = require('xregexp').XRegExp;
}
}

// Define our parse states
var PARSER_UNINITIALISED = 0,
PARSER_TAG_COMMENCED = 1,
PARSER_TAG_STRING = -1,
PARSER_TAG_STRING_SINGLE = -2,
PARSER_COMMENT = -3;

var exit = false;
for (; pointer < text.length && !exit; pointer++) {

Expand All @@ -110,11 +139,11 @@ var XRegexp = require('xregexp').XRegExp;

if (parseState === PARSER_UNINITIALISED &&
text[pointer + 1].match(/[a-z0-9\-\_\/\!]/)) {
parseState = PARSER_TAG_COMMENCED;
if (isAtLimit()) {
exit = true;
break;
}
parseState = PARSER_TAG_COMMENCED;
tagBuffer += text[pointer];
}

Expand Down
27 changes: 27 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,33 @@ describe("Appending", function () {

});

describe("Rounding", function () {
it("should round a sentence up", function () {
downsize("<p>abcdefghij</p><p>klmnop</p><p>qrs</p>", {characters: 15, round: true})
.should.equal("<p>abcdefghij</p><p>klmnop</p>");
});

it("should handle sentences shorter than required", function () {
downsize("<p>here's some text.</p>", {words: 5, round: true})
.should.equal("<p>here's some text.</p>");
});

it("should round up to end of sentence, not just next tag", function () {
downsize("<p>here's <em>some</em> text.</p>", {characters: 2, round: true})
.should.equal("<p>here's <em>some</em> text.</p>");
});

it("should not have trailing empty tags", function () {
downsize("<p>characters</p><i>what</i>", {characters: 10, round: true})
.should.equal("<p>characters</p>");
});

it("should scoop up to end of text if no closing paragraph found", function () {
downsize("<p>characters</p><i>what</i>", {characters: 11, round: true})
.should.equal("<p>characters</p><i>what</i>");
});
});

describe("Performance", function () {
var perfTestSeed = "";
for (var i = 0; i < 1000000; i++) {
Expand Down

0 comments on commit 2eadf3e

Please sign in to comment.