Skip to content

Instantly share code, notes, and snippets.

@nathanmacinnes
Created August 29, 2012 18:09
Show Gist options
  • Save nathanmacinnes/3516393 to your computer and use it in GitHub Desktop.
Save nathanmacinnes/3516393 to your computer and use it in GitHub Desktop.
Split your paragraphs into pages
/*
Copyright (c) 2012 Nathan MacInnes
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// ==ClosureCompiler==
// @output_file_name jquery.pagify.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// @code_url http://closure-compiler.googlecode.com/svn/trunk/contrib/externs/jquery-1.6.js
// ==/ClosureCompiler==
/*jslint sub: true, maxlen: 80, indent: 4 */
(function ($) {
"use strict";
// use square bracket notation for Closure Compiler
$.fn['pagify'] = function (options) {
var currentPage, // jQuery object representing a page element
defaults, // Default parameters for the options object
done, // Set to true when we're as deep into the DOM as possible
el = this, // Avoid problems with this keyword by re-assigning
firstPage, // jQuery object representing the first page element
nextPage, // jQuery object equivalent to currentPage.next();
pageHtml, // HTML used when creating a new page
pageIsOverflowed, // fn: Determine if the page has too much on it
splitNode, // jQuery object for an element which is being split
splitNodeCopy, // Copy of split element to put on the next page
splitNodeIntoWords; // fn: split a text node
pageIsOverflowed = function (page) {
// Pass it a .page and it works out if the page-inner it contains
// has a greater height (outerHeight including margins) than the
// page itself (innerHeight). Returns a boolean.
var pageInner = page.children('.' + options.innerClass),
marginCollapseAdjustment;
marginCollapseAdjustment =
parseInt(pageInner.children().first().css('margin-top'), 10) -
parseInt(pageInner.css('margin-top'), 10);
if (marginCollapseAdjustment < 0) {
marginCollapseAdjustment = 0;
}
return pageInner.outerHeight(true) + marginCollapseAdjustment >
page.innerHeight();
};
splitNodeIntoWords = function (lastNode) {
var startOfWord = /\W\b/,
result;
while (startOfWord.exec(lastNode.nodeValue) !== null) {
result = startOfWord.exec(lastNode.nodeValue);
// startOfWord matches the character before the start of a
// word, so need to add 1.
lastNode = lastNode.splitText(result.index + 1);
}
return lastNode;
};
defaults = {
'pageTag' : 'div',
'pageClass': 'page',
'innerClass': 'page-inner',
'pageSize': 'A4',
'pageSizeClassPrefix': 'page-',
'pageOrientation': 'portrait',
'splitElementClass': 'split-element'
};
options = $.extend(options, defaults);
pageHtml = '<' + options.pageTag + ' class="' + options.pageClass + ' ' +
options.pageSizeClassPrefix +
options.pageSize.toLowerCase() + '" />';
firstPage = $(pageHtml).appendTo(el);
firstPage.append('<' + options.pageTag + ' class="' + options.innerClass + '" />');
el.children().not(firstPage).appendTo(
firstPage.children('.' + options.innerClass)
);
// Loop while the last page is too long... need to add another page
while (pageIsOverflowed($('.' + options.pageClass).last())) {
// Assign the last page to a variable, THEN insert another page
// below it
currentPage = $('.' + options.pageClass).last();
nextPage = $(pageHtml).appendTo(el);
splitNode = currentPage;
splitNodeCopy = nextPage;
done = false;
// This loop splits up elements across page breaks into two, and
// keeps going deeper until we can't do any more.
while (!done) {
// make the page overflow by moving the first node of the
// next page to this page
splitNodeCopy.contents().first().appendTo(splitNode);
// if the node we want to split is a text node
if (splitNode.contents().last().get(0).nodeType === 3) {
splitNodeIntoWords(splitNode.contents().last().get(0));
done = true;
} else {
splitNode = splitNode.contents().last();
splitNodeCopy = splitNode.clone().empty()
.prependTo(splitNodeCopy);
}
while (pageIsOverflowed(currentPage)) {
splitNode.contents().last().prependTo(splitNodeCopy);
}
}
}
};
}(jQuery));
@avblink
Copy link

avblink commented Aug 25, 2017

Hi Nathan,

I found this gist on google and trying to figure out how to use it.
My understanding is that the script splits long text into A4 pages.

Could you please give me an example of how to use the script.

Kind regards

Alex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment