diff --git a/src/Kunoichi/TocGenerator/Item.php b/src/Kunoichi/TocGenerator/Item.php
index f8e8a4b..0694fed 100644
--- a/src/Kunoichi/TocGenerator/Item.php
+++ b/src/Kunoichi/TocGenerator/Item.php
@@ -13,7 +13,7 @@ class Item {
/**
* @var \DOMNode
*/
- private $dom = null;
+ protected $dom = null;
/**
* Item constructor.
diff --git a/src/Kunoichi/TocGenerator/Parser.php b/src/Kunoichi/TocGenerator/Parser.php
index f05c848..81e5a9a 100644
--- a/src/Kunoichi/TocGenerator/Parser.php
+++ b/src/Kunoichi/TocGenerator/Parser.php
@@ -27,17 +27,21 @@ class Parser {
protected $title = '';
+ protected $item_class = '';
+
/**
* Constructor
*
* @param int $max_depth
* @param bool $ignore_deeper
* @param string $id
+ * @param string $item_class
*/
- public function __construct( $max_depth = 3, $ignore_deeper = false, $id = 'content-section-' ) {
+ public function __construct( $max_depth = 3, $ignore_deeper = false, $id = 'content-section-', $item_class = Item::class ) {
$this->id_prefix = $id;
$this->max_depth = $max_depth;
$this->ignore_deeper = $ignore_deeper;
+ $this->item_class = $item_class;
}
/**
@@ -95,7 +99,7 @@ public function parse_html( $html ) {
if ( $this->ignore_deeper && ( (int) $level > $this->max_depth ) ) {
continue;
}
- $items[] = new Item( $hn );
+ $items[] = new $this->item_class( $hn );
}
return $items;
}
diff --git a/src/Kunoichi/TocGenerator/WpItem.php b/src/Kunoichi/TocGenerator/WpItem.php
new file mode 100644
index 0000000..26c543b
--- /dev/null
+++ b/src/Kunoichi/TocGenerator/WpItem.php
@@ -0,0 +1,76 @@
+page();
+
+ if ( $page !== $item_page ) {
+ // @see _wp_link_page()
+ global $wp_rewrite;
+ $post = get_post();
+ $query_args = array();
+ $item_page = $this->page();
+
+ if ( 1 === $item_page ) {
+ $url = get_permalink();
+ } else {
+ if ( ! get_option( 'permalink_structure' ) || in_array( get_post_status(), array(
+ 'draft',
+ 'pending'
+ ), true ) ) {
+ $url = add_query_arg( 'page', $item_page, get_permalink() );
+ } elseif ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === get_the_ID() ) {
+ $url = trailingslashit( get_permalink() ) . user_trailingslashit( "$wp_rewrite->pagination_base/" . $item_page, 'single_paged' );
+ } else {
+ $url = trailingslashit( get_permalink() ) . user_trailingslashit( $item_page, 'single_paged' );
+ }
+ }
+
+ if ( is_preview() ) {
+ if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) {
+ $query_args['preview_id'] = wp_unslash( $_GET['preview_id'] );
+ $query_args['preview_nonce'] = wp_unslash( $_GET['preview_nonce'] );
+ }
+ $url = get_preview_post_link( $post, $query_args, $url );
+ }
+ $link = sprintf( '%s%s', $url, $this->href() );
+
+ } else {
+ $link = $this->href();
+ }
+
+ return sprintf( '%s', esc_url( $link ), esc_attr( $item_page ), esc_html( $this->text() ) );
+ }
+
+ /**
+ * Return page attributes
+ *
+ * @return int
+ */
+ public function page() {
+ return (int) $this->dom->getAttribute( 'data-page' );
+ }
+}
diff --git a/src/Kunoichi/TocGenerator/WpParser.php b/src/Kunoichi/TocGenerator/WpParser.php
index 98c9cc7..3f34513 100644
--- a/src/Kunoichi/TocGenerator/WpParser.php
+++ b/src/Kunoichi/TocGenerator/WpParser.php
@@ -14,15 +14,18 @@ class WpParser extends Parser {
protected $done = false;
+ protected $page_counter = 0;
+
/**
* Constructor
*
* @param int $max_depth
* @param bool $ignore_deeper
* @param string $id
+ * @param string $item_class
*/
- public function __construct( $max_depth = 3, $ignore_deeper = false, $id = 'content-section-' ) {
- parent::__construct( $max_depth, $ignore_deeper, $id );
+ public function __construct( $max_depth = 3, $ignore_deeper = false, $id = 'content-section-', $item_class = WpItem::class ) {
+ parent::__construct( $max_depth, $ignore_deeper, $id, $item_class );
add_action( 'wp_head', [ $this, 'prepare' ] );
add_filter( 'the_content', [ $this, 'post_content' ] );
add_action( 'kunoichi_toc_generate', [ $this, 'generate' ], 10 );
@@ -56,9 +59,56 @@ public function post_content( $content ) {
$this->save_parsed_html( $content );
$this->done = true;
}
+
return $content;
}
+ /**
+ * Add link id to html elements.
+ *
+ * @param string $html
+ *
+ * @return string
+ */
+ public function add_link_html( $html ) {
+ $contents = preg_split( '//u', $html );
+ if ( is_array( $contents ) ) {
+ $replaced_html = '';
+ $this->page_counter = 0;
+ foreach ( $contents as $content ) {
+ $this->counter = 0;
+ $this->page_counter ++;
+ $replaced_html .= preg_replace_callback( '/<(h[1-6])([^>]*?)>/u', [ $this, 'convert_link' ], $content );
+ }
+
+ return $replaced_html;
+ } else {
+ return preg_replace_callback( '/<(h[1-6])([^>]*?)>/u', [ $this, 'convert_link' ], $html );
+ }
+ }
+
+ /**
+ * Add link to title elements.
+ *
+ * @param string[] $matches
+ *
+ * @return string
+ */
+ protected function convert_link( $matches ) {
+ $this->counter ++;
+ $attributes = $matches[2];
+ if ( preg_match( '/id=\'|"([\'"]*)(\'|")/u', $matches[2], $id_matches ) ) {
+ $id = $id_matches[1];
+ } else {
+ $id = sprintf( '%s%d', $this->id_prefix, $this->counter );
+ $attributes .= sprintf( ' id="%s"', $id ) . $matches[2];
+ }
+ // Add an attribute for the page number.
+ $attributes .= sprintf( ' data-page="%d"', $this->page_counter );
+
+ return sprintf( '<%s%s>', $matches[1], $attributes );
+ }
+
/**
* If post id is
*