Register Guidelines E-Books Search Today's Posts Mark Forums Read

Go Back   MobileRead Forums > E-Book Software > Calibre > Conversion

Notices

Reply
 
Thread Tools Search this Thread
Old 02-21-2015, 09:58 AM   #1
bowlins
Member
bowlins began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Jul 2014
Device: none
Does .pdf conversion support indexOf()?

I've just discovered the ability to use javascript in headers and footers when converting EPUB to PDF. I think it's great.

So far I've been able to write simple functions with conditionals. However, I'm stuck when I introduce an indexOf().

I would like not to show headers in initial pages (TOC, title page, etc.) so I'm trying to write something like this after <p id="header">....</p>

Code:
<script>
function header() {
   if ( document.getElementById("header").indexOf("Title Page") >= 0 ){
       document.getElementById("header").style.display = 'none'
   }
}
header()
</script>
If I remove
Code:
.indexOf("Page Title") >= 0
the function works as expected as all the headers are hidden in output file.

This is why I'm suspecting Calibre may not accept indexOf(). Is this right? And if so, how to hide headers and page numbers for certain sections?

Last edited by bowlins; 02-21-2015 at 10:06 AM.
bowlins is offline   Reply With Quote
Old 02-21-2015, 10:20 AM   #2
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
indexOf operates on strings, getElementById returns DOM nodes.

calibre uses WebKit for pdf conversion, which means it has a complete browser engine with full javascript support.

You want document.getElementById("header").innerHTML.indexO f
kovidgoyal is offline   Reply With Quote
Advert
Old 02-22-2015, 12:06 PM   #3
bowlins
Member
bowlins began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Jul 2014
Device: none
That works like a charm!!! Thank you so much for that. I had no idea calibre conversion came with a full JS search engine. That's impressive

Having realised that, I was wondering how each page is rendered when converting into PDF.

I've managed now to hide headers for certain sections, but I'm not able to hide them when page has headings with a certain class (e.g.: "chapter"). If heading is relatively big, then the header doesn't look that good.

So far I've managed to check if a class exists with this:

Code:
function header() {
var chapter = document.getElementsByClassName("chapter");
if (chapter != 'undefined' || chapter != null )
	{document.getElementById("header").style.display = 'none';}
header()
I can see that the function is working because if I set the conditions to equal, the header shows as normal. However, with this function it looks as if the whole .pdf file is the document. The result is that the header is hidden for all pages and not just the ones with the class "chapter".

Is there a way of checking if class exists in the current page?
bowlins is offline   Reply With Quote
Old 02-22-2015, 11:18 PM   #4
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
pages are made using the css 3 columns module. So if you want to check whether a particular element is on the current page you would need to check if its position is contained in the current viewport position.
kovidgoyal is offline   Reply With Quote
Old 02-23-2015, 11:28 AM   #5
bowlins
Member
bowlins began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Jul 2014
Device: none
Glad to know that there's a way but after too many hours trying I'm unable to put it in place.

Because I can't print variables on console I don't know which position (if any) my functions are returning. I've tried many variations of offsetParent and offsetTop but with no visible results.

However, the most logical option to me would be to use a variation of my previous answer:

Code:
if (document.getElementsByClassName("chapter").getBoundingClientRect()  != null ||
    document.getElementsByClassName("chapter").getBoundingClientRect() != 'undefined') {
//Code to hide header
}
There doesn't seem to be any errors when I run this as the rest of the script runs as it should. But without a console I don't know what value getBoundingClientRect() (or even getBoundingClientRect().top) is actually returning.

Would this be a correct method? Or how could I check returned values?
bowlins is offline   Reply With Quote
Advert
Old 02-23-2015, 11:51 AM   #6
eschwartz
Ex-Helpdesk Junkie
eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.eschwartz ought to be getting tired of karma fortunes by now.
 
eschwartz's Avatar
 
Posts: 19,422
Karma: 85397180
Join Date: Nov 2012
Location: The Beaten Path, USA, Roundworld, This Side of Infinity
Device: Kindle Touch fw5.3.7 (Wifi only)
Well, you could always do a test run that just prints out the return value.
eschwartz is offline   Reply With Quote
Old 02-23-2015, 12:04 PM   #7
bowlins
Member
bowlins began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Jul 2014
Device: none
I've tried many variations of document.write() but with no success. I just don't know if JS scripts in the header/footer can interact with the body element. Also using document.write() makes the pdf conversion to fail

Looking at the documentation in MDN, xhtml documents do not allow for document.write(), which makes things even more complicated https://developer.mozilla.org/en-US/...Document/write
bowlins is offline   Reply With Quote
Old 02-23-2015, 10:37 PM   #8
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
Why do you say there is no logging? console.log works fine, its output will be in the conversion log. As does using innerHTML to change the document contents for debugging.
kovidgoyal is offline   Reply With Quote
Old 02-24-2015, 01:30 AM   #9
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
And getElementsByClassName returns an list of elements. You want to get the bounding rect of a single element.
kovidgoyal is offline   Reply With Quote
Old 02-24-2015, 11:32 AM   #10
bowlins
Member
bowlins began at the beginning.
 
Posts: 18
Karma: 10
Join Date: Jul 2014
Device: none
It's been intense with many unexpected issues along the way, but I now have some code which removes headers from chapters' first page in pdf output files.

Print books do not normally have headers at the start of a chapter, but I'm not sure if this is something that people are actually using in Calibre. I'll post some explanations for future reference with code below just in case it helps someone.

JS methods which are normally used for screen viewports were very problematic and I never got them to work correctly. I assume that this is because as a print document, viewports work differently (?).

I eventually manage to print values in the pdf output document using innerHTML in the footer (sorry kovidgoyal but couldn't find where the console would be printed in the log files). This helped me to see that methods based on offset properties and getBoundingClientRect() were retrieving the position of the element fine but the position value remained the same for the whole chapter for all pages. This meant that any hiding of the header would be applied to the whole xhtml file and not just the first page.

Instead of carrying through that route, I stumbled upon a set of functions based on the Pythagorean Theorem http://stackoverflow.com/questions/1...ements-centers

I eventually had my Eureka moment as the triangle measures the distance between any two elements for the whole chapter/file but this time the value is updated for each page. Now that the value was changing on each page, it was finally possible to remove the header in the first page of each chapter (or any section for that matter).

Code:
function hasChapter() {
    var chapter = document.getElementsByClassName("chapter")[0],
        header = document.getElementById("header");

    var getPositionAtCenter = function (element) {
        var data = element.getBoundingClientRect();
        return {
            x: data.left + data.width / 2,
            y: data.top + data.height / 2
        };
    };

    var getDistanceBetweenElements = function(a, b) {
        var aPosition = getPositionAtCenter(header);
        var bPosition = getPositionAtCenter(chapter);

        return Math.sqrt(
            Math.pow(aPosition.x - bPosition.x, 2) + 
            Math.pow(aPosition.y - bPosition.y, 2) 
        );
    };
    
    var distance = getDistanceBetweenElements(document.getElementById("x"),
                                              document.getElementById("y"));
    
    if ( distance < 200 ) {
       document.getElementById("header").style.display = 'none';
    }   
}
hasChapter();
Other people using this may need to check the minimum distance or the class name for their section headings.

But overall this works!!
bowlins is offline   Reply With Quote
Old 02-24-2015, 10:48 PM   #11
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
Here is a simple way to test if an element is on the current screen

var br = elem.getBoundingClientRect()

var on_current_page = br.left + 20 > window.pageXOffset && br.right - 20 < window.pageXOffset + window.innerWidth
kovidgoyal is offline   Reply With Quote
Old 03-01-2015, 10:52 PM   #12
EbokJunkie
Addict
EbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blue
 
Posts: 229
Karma: 13495
Join Date: Feb 2009
Location: SoCal
Device: Kindle 3, Kindle PW, Pocketbook 301+, Pocketbook Touch, Sony 950, 350
@kovidgoyal
Looks as JavaScript is disabled in command line.
This header template:
Code:
<div id="header" style="font-size:x-small"><p style="float:left">_TITLE_</p><p style="float:right;"><i>_AUTHOR_</i></p></div><script>document.getElementById("header").style.display = "none";</script>
being used in Calbre GUI Pdf output allows to toggle header on and off at all pages using either "inline" or "none".
Exact copy of the same template used in CLI --pdf-header-template option doesn't eliminate header if style.display="none".

Same about this template from Calibre website:
Code:
<p id="pagenum" style="text-align:center;"></p><script>document.getElementById("pagenum").innerHTML = "" + (_PAGENUM_ + 3)</script>
CLI throws an error until all blanks are eliminated; even after this command does nothing.
Same template (with all blanks, exact copy from the web page) works perfectly in GUI.

Is there any way to enable JavaScript in command line?

Last edited by EbokJunkie; 03-01-2015 at 11:00 PM.
EbokJunkie is offline   Reply With Quote
Old 03-04-2015, 09:16 PM   #13
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,839
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
There is no difference between command line and GUI. Make sure you are escaping command line strings properly. Remember that your shell will be interpreting all arguments you pass, so you have to quote/escape them properly.
kovidgoyal is offline   Reply With Quote
Old 03-05-2015, 01:19 AM   #14
EbokJunkie
Addict
EbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blue
 
Posts: 229
Karma: 13495
Join Date: Feb 2009
Location: SoCal
Device: Kindle 3, Kindle PW, Pocketbook 301+, Pocketbook Touch, Sony 950, 350
Thanks for advice. I tried all imaginable (to me) combinations of escaping by quotes but exhausted my options...
This is the command line I experimented with intending to turn off the header:

Code:
ebook-convert "book.epub" "book.pdf"  --custom-size 78.836x108.31 --unit millimeter   --override-profile-size --pdf-default-font-size 17  --margin-top 12  --pdf-header-template "<div id="header" style="font-size:x-small"><p style="float:left">_TITLE_</p><p style="float:right;"><i>_AUTHOR_</i></p></div><script>document.getElementById("header").style.display="none";</script>"
No matter where I placed additional quotes header always stayed put.
Please give me a hint: How to place quotes in this line to set javascript to work?
EbokJunkie is offline   Reply With Quote
Old 03-12-2015, 02:07 PM   #15
EbokJunkie
Addict
EbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blueEbokJunkie can differentiate black from dark navy blue
 
Posts: 229
Karma: 13495
Join Date: Feb 2009
Location: SoCal
Device: Kindle 3, Kindle PW, Pocketbook 301+, Pocketbook Touch, Sony 950, 350
Solved escaping in command line JavaScript .
Just need to escape quotes like \"header\" and \"none\".
Might be useful to point this out in Calibre online documentation.
EbokJunkie is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Multi-Core Conversion support? evandy Calibre 5 09-18-2015 10:49 AM
KF8 conversion and support in Calibre? Rhialto Conversion 19 01-16-2012 05:45 PM
PDF to PDF conversion creates much larger file? rocketcat Conversion 11 09-30-2011 07:37 PM
when will calibre support vector graphics in pdf to epub conversion smith9 Calibre 5 11-13-2010 05:03 AM
Any chance for chm to epub/mobi/pdf conversion support joblack Calibre 4 11-02-2010 01:06 AM


All times are GMT -4. The time now is 08:19 PM.


MobileRead.com is a privately owned, operated and funded community.