From f96afe5397c87d210d641667d4430e748bb07b72 Mon Sep 17 00:00:00 2001
From: Ben Doherty <bendohmv@gmail.com>
Date: Wed, 19 Feb 2014 00:01:37 -0500
Subject: [PATCH] 0.2 pull request - Add ability to break by Word Count instead
 of just specifying page count

---
 automatically-paginate-posts.php | 100 ++++++++++++++++++++++++++++---
 readme.txt                       |  12 +++-
 2 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/automatically-paginate-posts.php b/automatically-paginate-posts.php
index 1ee8d32..611d7f7 100644
--- a/automatically-paginate-posts.php
+++ b/automatically-paginate-posts.php
@@ -1,11 +1,11 @@
 <?php
 /*
 Plugin Name: Automatically Paginate Posts
-Plugin URI: http://www.thinkoomph.com/plugins-modules/automatically-paginate-posts/
+Plugin URI: http://www.oomphinc.com/plugins-modules/automatically-paginate-posts/
 Description: Automatically inserts the &lt;!--nextpage--&gt; Quicktag into WordPress posts, pages, or custom post type content.
-Version: 0.1
+Version: 0.2
 Author: Erick Hitter & Oomph, Inc.
-Author URI: http://www.thinkoomph.com/
+Author URI: http://www.oomphinc.com/
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -31,10 +31,12 @@ class Automatically_Paginate_Posts {
 
 	private $num_pages;
 	private $num_pages_default = 2;
+	private $num_words_default = '';
 
 	//Ensure option names match values in this::uninstall
 	private $option_name_post_types = 'autopaging_post_types';
 	private $option_name_num_pages = 'autopaging_num_pages';
+	private $option_name_num_words = 'autopaging_num_words';
 
 	private $meta_key_disable_autopaging = '_disable_autopaging';
 
@@ -74,7 +76,12 @@ class Automatically_Paginate_Posts {
 		//Number of pages to break over
 		$this->num_pages = absint( apply_filters( 'autopaging_num_pages_default', get_option( $this->option_name_num_pages, $this->num_pages_default ) ) );
 		if ( 0 == $this->num_pages )
-			$this->num_pages = 2;
+			$this->num_pages = $this->num_pages_default;
+
+		//Number of words to break over
+		$this->num_words = absint( apply_filters( 'autopaging_num_words_default', get_option( $this->option_name_num_words, $this->num_words_default ) ) );
+		if ( 0 == $this->num_words )
+			$this->num_words = $this->num_words_default;
 	}
 
 	/**
@@ -88,6 +95,7 @@ class Automatically_Paginate_Posts {
 	public function uninstall() {
 		delete_option( 'autopaging_post_types' );
 		delete_option( 'autopaging_num_pages' );
+		delete_option( 'autopaging_num_words' );
 	}
 
 	/**
@@ -115,10 +123,12 @@ class Automatically_Paginate_Posts {
 	public function action_admin_init() {
 		register_setting( 'reading', $this->option_name_post_types, array( $this, 'sanitize_supported_post_types' ) );
 		register_setting( 'reading', $this->option_name_num_pages, array( $this, 'sanitize_num_pages' ) );
+		register_setting( 'reading', $this->option_name_num_words, array( $this, 'sanitize_num_words' ) );
 
 		add_settings_section( 'autopaging', __( 'Automatically Paginate Posts', 'autopaging' ), '__return_false', 'reading' );
 		add_settings_field( 'autopaging-post-types', __( 'Supported post types:', 'autopaging' ), array( $this, 'settings_field_post_types' ), 'reading', 'autopaging' );
 		add_settings_field( 'autopaging-num-pages', __( 'Number of pages to split content into:', 'autopaging' ), array( $this, 'settings_field_num_pages' ), 'reading', 'autopaging' );
+		add_settings_field( 'autopaging-num-words', __( 'Number of words for each page:', 'autopaging' ), array( $this, 'settings_field_num_words' ), 'reading', 'autopaging' );
 	}
 
 	/**
@@ -142,7 +152,7 @@ class Automatically_Paginate_Posts {
 		//Output checkboxes
 		foreach ( $post_types as $post_type => $atts ) :
 		?>
-			<input type="checkbox" name="<?php echo esc_attr( $this->option_name_post_types ); ?>[]" id="post-type-<?php echo esc_attr( $post_type ); ?>" value="<?php echo esc_attr( $post_type ); ?>"<?php checked( in_array( $post_type, $current_types ) ); ?> /> <label for="post-type-<?php echo esc_attr( $post_type ); ?>"><?php echo esc_html( $atts->label ); ?><br />
+			<input type="checkbox" name="<?php echo esc_attr( $this->option_name_post_types ); ?>[]" id="post-type-<?php echo esc_attr( $post_type ); ?>" value="<?php echo esc_attr( $post_type ); ?>"<?php checked( in_array( $post_type, $current_types ) ); ?> /> <label for="post-type-<?php echo esc_attr( $post_type ); ?>"><?php echo esc_html( $atts->label ); ?></label><br />
 		<?php
 		endforeach;
 	}
@@ -207,6 +217,37 @@ class Automatically_Paginate_Posts {
 		return max( 2, min( intval( $num_pages ), apply_filters( 'autopaging_max_num_pages', 10 ) ) );
 	}
 
+	/**
+	 * Render dropdown for choosing number of pages to break content over
+	 *
+	 * @uses get_option, apply_filters, esc_attr, selected
+	 * @return string
+	 */
+	public function settings_field_num_words() {
+		$num_words = apply_filters( 'autopaging_num_words', get_option( $this->option_name_num_words ) )
+		?>
+			<input name="<?php echo esc_attr( $this->option_name_num_words ); ?>" value="<?php echo esc_attr( $num_words ); ?>" size="4" />
+	
+			<p class="description">If set, each page will contain approximately this many words, more or less depending on paragraph lengths, and Number of pages will be ignored.</p>
+		<?php
+	}
+
+	/**
+	 * Sanitize number of words input. No fewer than 10 (by default, filterable by autopaging_min_num_words)
+	 *
+	 * @param int $numwords
+	 * @uses apply_filters
+	 * @return int
+	 */
+	public function sanitize_num_words( $num_words ) {
+		$num_words = apply_filters( 'autopaging_num_words', $num_words );
+
+		if( empty( $num_words ) )
+			return '';	
+
+		return max( 1, (int) $num_words );
+	}
+
 	/**
 	 * Add autopaging metabox
 	 *
@@ -275,8 +316,9 @@ class Automatically_Paginate_Posts {
 				if ( in_array( $the_post->post_type, $this->post_types ) && ! preg_match( '#<!--nextpage-->#i', $the_post->post_content ) && ! (bool) get_post_meta( $the_post->ID, $this->meta_key_disable_autopaging, true ) ) {
 					//In-time filtering of number of pages to break over, based on post data. If value is less than 2, nothing should be done.
 					$num_pages = absint( apply_filters( 'autopaging_num_pages', absint( $this->num_pages ), $the_post ) );
+					$num_words = absint( apply_filters( 'autopaging_num_words', absint( $this->num_words ), $the_post ) );
 
-					if ( $num_pages < 2 )
+					if ( $num_pages < 2 && empty( $num_words ) )
 						continue;
 
 					//Start with post content, but alias to protect the raw content.
@@ -291,9 +333,51 @@ class Automatically_Paginate_Posts {
 
 					//Keep going, if we have something to count.
 					if ( is_int( $count ) && 0 < $count ) {
-						//Explode content at double line breaks
+						//Explode content at double (or more) line breaks
 						$content = explode( "\r\n\r\n", $content );
 
+						//Aggregate paragraphs
+						if( !empty( $num_words ) ) {
+							$word_counter = 0;
+
+							//Aggregate num_words paged content here
+							$aggregate = array();
+							$aggregate_index = 0;
+
+							//Collapse together paragraph according to number of words per page
+							foreach( $content as $index => $paragraph ) {
+								$paragraph_words = count( preg_split( '/\s+/', strip_tags( $paragraph ) ) );
+
+								if( $word_counter + $paragraph_words / 2 >= $num_words ) {
+									$aggregate_index++;
+									$word_counter = 0;
+								}
+
+								if( !isset( $aggregate[$aggregate_index] ) )
+									$aggregate[$aggregate_index] = '';
+
+								$aggregate[$aggregate_index] .= $paragraph . "\r\n\r\n";
+
+								$word_counter += $paragraph_words;
+
+								if( $word_counter > $num_words ) {
+									$aggregate_index++;
+									$word_counter = 0;
+								}
+							}
+
+							//Pretend the aggregated paragraphs based on max_words
+							//are the original set
+							$content = $aggregate;
+
+							//Override num_pages
+							$num_pages = count( $content );
+
+							unset( $word_counter );
+							unset( $aggregate );
+							unset( $aggregate_index );
+						}
+
 						//Count number of paragraphs content was exploded to
 						$count = count( $content );
 
@@ -345,4 +429,4 @@ class Automatically_Paginate_Posts {
 	}
 }
 new Automatically_Paginate_Posts;
-?>
\ No newline at end of file
+?>
diff --git a/readme.txt b/readme.txt
index 3f616c6..306b06f 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,5 +1,5 @@
 === Automatically Paginate Posts ===
-Contributors: ethitter, thinkoomph
+Contributors: ethitter, thinkoomph, bendoh
 Donate link:
 Tags: paginate, nextpage, Quicktag
 Requires at least: 3.4
@@ -16,7 +16,7 @@ Automatically paginate WordPress content by inserting the &lt;!--nextpage--&gt;
 
 Option is provided to control what post types are automatically paginated (default is just `post`). Supports `post`, `page`, and any public custom post types.
 
-Option is also provided to specify how many pages content should be broken out over.
+Option is also provided to specify how many pages content should be broken out over, or how many words should be included per page.
 
 == Installation ==
 
@@ -48,7 +48,13 @@ You can also use the filter `autopaging_post_types` to add support by appending
 = 0.1 =
 * Initial release.
 
+= 0.2 =
+* Allow for number of words to be specified instead of number of pages.
+
 == Upgrade Notice ==
 
 = 0.1 =
-Initial release
\ No newline at end of file
+Initial release
+
+= 0.2 =
+* Allow for number of words to be specified instead of number of pages.
-- 
GitLab