Numbering sections and block-level elements in wpautop(); WordPress as CMS for long-form writing;

I am starting to learn how to write plugins for WordPress. I’m interested in using WP as a CMS for long essays (6000-9000 words or more). My problem is what I call the Kindle problem, which is how do you reliably address the different parts of an unpaginated document which can be read on a variety of screens/devices, and will reflow differently in each case. If I’m citing an ebook on my e-reader or in a browser, it’s hard to refer to a specific passage and know that my reader will be able to follow it to the exact text location because there’s no absolute “page number.”

One possible solution is putting HTML anchors in the text. Is there any way to get WordPress to do this automatically? Even better, is it possible for WordPress to treat elements as if they were the beginning of an SGML element, and then automatically generate hierarchically numbered anchors for each heading, each sub-heading, and each paragraph or block ‘enclosed’ with them. I’m thinking of some way of doing what LaTeX does to \section{} tags.

Has this been done? Where exactly would this filter apply? Adam Brown says that there are over 1500 hooks you can use! That’s pretty amazing, but also daunting too.

Thanks for your help.

Cheers,

Ryan

http://rschram.org/

1 Answer
1

You could probably achieve this with a filter of some sort on the_content.

Here’s a quick and dirty example that finds all instances of <p> and inserts a named anchor, then adds a list of links to each anchor at the top of the content.

Check out the Shortcode API as well, which could similarly allow you to add arbitrary sections with text by adding a shortcode of your own, like [section id="something"].

class InsertAnchors {
    protected $count = 0;
    protected $links="";
    public function build( $pattern, $content ) {
        $this->count = 0;
        $this->links="";
        $content = preg_replace_callback( $pattern, array( $this, '_replacer' ), $content );
        return '<p>' . $this->links . '</p>' . $content;
    }
    public function _replacer( $matches ) {
        $this->count++;
        $this->links .= '<a href="#section_' . $this->count . '">Section ' . $this->count . '</a><br>';
        return '<p><a name="section_' . $this->count . '"></a>';
    }
}

function anchors_content_filter( $content ){
    $insert = new InsertAnchors();
    return $insert->build( '~<p>~', $content );
}
add_filter( 'the_content', 'anchors_content_filter', 100 );

Leave a Comment