Created
August 29, 2012 18:09
-
-
Save nathanmacinnes/3516393 to your computer and use it in GitHub Desktop.
Split your paragraphs into pages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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