Split html string into multiple pages

Go To StackoverFlow.com

13

I am trying to develop eBook reader kind of android application. I need to split long html string(sent by server at run-time) into pages on fly based on the screen space available. Html content is an article which could contain text, images, videos etc.I am using WebView to display the html.

Can anyone give me direction towards how this can be achieved.

Thanks in advance.

2012-04-04 07:34
by Harshita
Can you share how you solved this one? Thanks - Ravi 2014-03-24 15:20


8

Doing any sort of HTML/DOM parsing is going to drive you up the wall, I think, and means that you're effectively starting to develop your own HTML layout engine.

It's a better idea to use the CSS3 column functions. Basically, get your content to render within a fixed width-and-height column. This becomes your page. Then shift your content position left to move between pages, and wrap it in a container that will hide overflow elements.

Our HTML will basically be:

<body>
    <div id="container">
        <div id="content">

            CONTENT GOES HERE

            <span id="endMarker"></span>
        </div>
    </div>
    <div>
        <button id="previous">Previous</button>
        <span id="page">Page N of M</span>
        <button id="next">Next</button>
    </div>
</body>

Our basic CSS is:

#container {
    width: 240px;
    overflow: hidden;
    background-color: yellow;
}
#content {
    position: relative;
    height: 30em;

    -moz-column-width: 240px;
    -webkit-column-width: 240px;
    column-width: 240px;

    -moz-column-gap: 10px;
    -webkit-column-gap: 10px;
    column-gap: 10px;
}

Now we will set the left CSS property for the #content to switch between pages, in multiples of -250px.

We've only got to work out how many columns our content takes, and we've got paging. How to get css3 multi-column count in Javascript gives a hint: we're going to find it from the left position of #endMarker.

Here's a working example http://lateral.co.za/pages.html, with the first chapter of Moby Dick. It works in Chrome and on Android, but not in Firefox - I think because of differences in the CSS columns implementations. Since we're interested in Android here, the code is good.

The important parts are:

  1. The CSS settings as above.
  2. The addition of a <span id="endMarker"></span> after the content (but within the #content div)
  3. The addition of a #previous and #next button, and a #page span, all outside the #container.
  4. This javascript after jQuery loads:

    var _column = 0;
    var _columnCount = 0;
    var _columnWidth = 240;
    var _columnGap = 10;
    $(function() {
        _columnCount = Math.floor($('#endMarker').position().left/(_columnWidth + _columnGap));
    
        setColumn = function(i) {
            _column = i;
            document.getElementById('content').style.left = -1 * _column * (_columnWidth + _columnGap);
            $('#page').html('Page ' + (_column+1) + ' of ' + (_columnCount+1));
        }
        $('#next').click(function() {
            if (_column==_columnCount) return;
            setColumn(_column+1);
        });
        $('#previous').click(function() {
            if (0==_column) return;
            setColumn(_column-1);
        });
        setColumn(0);
    });
    

That's it.

There's room for work. One might want to think about that number of columns calculation, I sort of sucked it from the referenced SO post, but haven't actually thought it through... The width of the container seems to affect the column width of the content, which doesn't entirely make sense to me.

But at least everything seems to be working without having to do any HTML parsing and own layout, at least in Chrome and on Android.

2014-08-11 10:53
by craigmj
this is really nice, but how can i set width and height to fill window? using width:$( window ).width(); instead width: 240px; and other column width not worked - mehdok 2014-11-18 07:36
It should be enough to make the container fill the window. Or use width: 100%; or width: 100vw;craigmj 2015-03-17 17:48
ok, but what about -moz-column-width: 240px; -webkit-column-width: 240px; column-width: 240px; if i set them to 100% only the first column shown. what about height, i want fill both height and widthmehdok 2015-03-18 05:29


0

You have to parse the HTML, best would be to use some library where you can access the DOM like in JavaScript. Then you can create a custom layout for the parsed content. Does WebView supports JavaScript? That would be a good start to try with.

Obviously you can not split at arbitrary locations of the HTML file, your have to consider the HTML-Tags. After modifying the DOM or splitting the html you can provide an custom CSS file for the content to display it in a way you like and add some pagination using your library or JavaScript.

Using <span style="display:none"></span> can help you to hide content in a website. Then you don't have to split is physically (it is in memory after loading the page anyway).

Hope that helped a bit. You will not get a full solution here, but maybe you got some ideas. If you find further more specific problems it will be easier to ask more specific questions.

2012-04-04 08:06
by Tarion
Thanks for your reply. With Jericho html parser i have parsed the html and have extracted the text content and images and then I have setup a custom layout with imageview at the top and textview below it. If there is a image i am setting it to the imageview, if not my textview fits the screen - Harshita 2012-04-05 08:55
With textview.getPaint().measureText(txt) i am getting the width of the text to be displayed.How can we calculate the number of characters or the text that fits the screen - Harshita 2012-04-05 09:06
Ads