Convert FB2 to XHTML with saving nested drawings

    I had a slight need to convert books in FB format to xhtml.
    Well, of course, I climbed onto www.gribuser.ru/xml/fictionbook/2.0/xsl/export where I took the file
    FB2_2_xhtml.xsl (at the same time I captured FB2_2_txt.xsl you never need to get a text book)
    I tried to convert the book and noticed a little problem, the drawings are gone. :(
    In principle, the drawings are not the main thing in the book, but it’s still a little offensive. Therefore, we’ll need to understand what the problem is.

    According to the FB2 standard, embedded images are described in binary tags. And they are referenced with an anchor in the link, that is




    At first, the idea arose of just pulling out the pictures, and putting them in a folder with the converted file. It turned out something like

    $path='book'; //путь к папке куда будем складывать рисунки
    $doc=new DOMDocument();
    $doc->load($xml_filename);    
    $nodes=$doc->getElementsByTagName('binary');
    foreach ($nodes as $node)
    {
        $value=base64_decode($node->nodeValue);
        $fname= $node->attributes->getNamedItem('id')->nodeValue;
        $fh=fopen($path.'/'.$fname,'w+');
        fwrite($fh,$value);
        fclose($fh);
    }


    Then we do the xslt file conversion taken from the off site and enjoy life, the pictures appeared. That's just the volume, if you make a small library, you need to store txt files, fb2 files, xhtml, and even the pictures, it’s unprofitable. In principle, you can store one fb2'sku and receive a file upon request, the delay is small, a couple of seconds and you can wait (this is on a netbook, on the desktop, conversion is performed only on the fly). And then I remembered that there was such a thing as Data Uri , so why not use it and embed the pictures directly in the resulting xhtml. Of course, the size will increase, but we only get xhtml when you need to see it, besides, if you get such an xsl file, you can read fb2'ki normally in the browser.
    And so I started digging into the FB2_2_xhtml.xsl file.
    You can immediately see the reason why the drawings disappeared
    :template match="fb:image">
         align="center">
             border="1">
                :choose>
                    :when test="starts-with(@xlink:href,'#')">
                        :attribute name="src">:value-of select="substring-after(@xlink:href,'#')"/>:attribute>
                    
    :when>
                    :otherwise>
                        :attribute name="src">:value-of select="@xlink:href"/>:attribute>
                    
    :otherwise>
                
    :choose>
            
    >
        
    >
    :template>


    in this case, just cut out # before the picture. And it is assumed that the drawings will lie side by side.
    After some shamanism the following code turned out

    :when test="starts-with(@xlink:href,'#')">
        :attribute name="src">
            :text>data::text>
            :variable name="href" select="substring-after(@xlink:href,'#')" />
             variable="href" expression="substring-after(@xlink:href,'#')"/>
            :value-of select="//fb:binary[@id=$href]/@content-type" disable-output-escaping="yes" />
            :text>;base64,:text>
            :value-of select="//fb:binary[@id=$href]" disable-output-escaping="yes"/>
        
    :attribute>
    :when>


    Why is it a simple design
    :variable name="href" select="substring-after(@xlink:href,'#')" />


    I didn’t want to set the variable, it was not visible in the xpath expression, after an additional definition
    variable="href" expression="substring-after(@xlink:href,'#')"/>
    everything worked as it should.

    Also made small changes regarding the display of the title of the book on top
    align="center">
        :value-of select="fb:description/fb:title-info/fb:book-title"/>
    >

    As well as cover output

    :for-each select="fb:description/fb:title-info/fb:coverpage/fb:image">
        :call-template name="image"/>
    :for-each>


    having preliminarily corrected it to
    Maybe it’s worth moving the content to the end, but in principle everything suits me.

    The resulting file can be taken here bit.ly/1JOIvz

    PS while I was looking in the net for a suitable solution I came across rusec.livejournal.com/11740.html :)

    Well, regarding fb2 readers under Linux I can not quote the message that I came across on lore
    I found a great reader for fictonbook for myself:
    "zcat book.fb2.zip | xsltproc FB2_2_txt.xsl - | less -s"
    ;)

    juick.com/demyan/70753



    PPS I hope this is useful to someone. :)

    Also popular now: