Link between SVG image and text in an XML document

Here should go questions about transforming XML with XSLT and FOP.
david-gopois69
Posts: 17
Joined: Fri Dec 15, 2017 6:13 pm

Link between SVG image and text in an XML document

Post by david-gopois69 » Tue Oct 23, 2018 1:23 pm

Hello,

I would like create links between a parts list (xml data) and items on SVG illustration.
The SVG illustration is embedded in the XML document (with a reference mechanism).

With XSLFO, is it possible to create a link from an XML text toward an item text on a SVG illustration ?

During the FOP conversion, are the text ID references of the SVG illustrations kept in the PDF output (SVG code example: <text id="fig-1-hot-1" ... />)?

Kind regards

David

Dan
Posts: 447
Joined: Mon Feb 03, 2003 10:56 am

Re: Link between SVG image and text in an XML document

Post by Dan » Wed Oct 24, 2018 4:55 pm

Hello David,

I set up an example, but it works with mixed results.

Assuming that in the XSL FO you have a block with the id "my_block_id":

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
<fo:layout-master-set>
<fo:simple-page-master master-name="sample">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>

<!-- Declare the ID as named destination -->
<fox:destination internal-destination="my_block_id"/>

<fo:page-sequence master-reference="sample">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<!-- This has links like "#my_block_id" -->
<fo:external-graphic src="svg_with_link.svg"/>
</fo:block>
<fo:block>Lore ipsum</fo:block>
<fo:block>Lore ipsum</fo:block>
<fo:block>Lore ipsum</fo:block>


<!-- Put many more lines here to see that it scrolls to the target ... -->
<fo:block color="red" id="my_block_id">Target</fo:block>


</fo:flow>
</fo:page-sequence>
</fo:root>
In the SVG you should refer the fo:block by #my_block_id

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg viewBox="0 0 362 232" version="1.0" width="400pt" height="400pt"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<g stroke="none" stroke-width="1" fill="none"
fill-rule="evenodd">
<a xlink:href="#my_block_id"
target="_blank">
<circle id="circle" fill="#3AC3CA"
cx="211.5" cy="139.5" r="56.5">
</circle>
</a>
</g>
</svg>
If hover the mouse pointer over the circle, Acrobat Reader will popup a tooltip containing the link URL, and it looks ok. If you click it, it will ask if you want to open the link target, but then it does nothing, it does not scroll to the red block. This could be a side effect from the fact that I tested with a local file, maybe if the PDF is put on a website it will work better .
If you open the same PDF in a browser like IE, Chrome or Firefox, it still does not scroll to the red block, although they show a hand cursor over the circle.

So probably the PDF is correct, but the viewers cannot handle it.

Many regards,
Dan

david-gopois69
Posts: 17
Joined: Fri Dec 15, 2017 6:13 pm

Re: Link between SVG image and text in an XML document

Post by david-gopois69 » Wed Oct 24, 2018 5:27 pm

Hi,
Thank you for your reply.
But I don't want to create a link on an SVG object leading to a target text. I would like to click on a link in the text and go to an object in the SVG file.
Is it possible?
Kind regards.
David

Dan
Posts: 447
Joined: Mon Feb 03, 2003 10:56 am

Re: Link between SVG image and text in an XML document

Post by Dan » Wed Oct 24, 2018 5:32 pm

I have not tested it, but you can easily try the reverse.
In the SVG sample put an ID on the circle, then add an fo:external-link (or internal) in the FO document having the target that ID.

Many regards,
Dan

david-gopois69
Posts: 17
Joined: Fri Dec 15, 2017 6:13 pm

Re: Link between SVG image and text in an XML document

Post by david-gopois69 » Wed Oct 24, 2018 5:54 pm

I try this code but it doesn't work.

<fo:block>
<fo:basic-link internal-destination="{'circle'}"
color="blue" text-decoration="underline">
Link to circle
</fo:basic-link>
</fo:block>

What is the good syntax or the good code to create the link between the text "Link to circle" and the circle in the Embedded SVG ?

Kind regards,
David

Dan
Posts: 447
Joined: Mon Feb 03, 2003 10:56 am

Re: Link between SVG image and text in an XML document

Post by Dan » Thu Oct 25, 2018 9:06 am

In theory this should work:

Code: Select all


....
<!-- Declare the ID as named destination -->
<fox:destination internal-destination="circle"/>
....
<fo:block color="green">
<fo:basic-link external-destination="#circle"> Go to circle. </fo:basic-link>
</fo:block>
...
In the SVG you should have:

Code: Select all


    <circle id="circle" ... >
But in Acrobat Reader does not want to scroll to (show) the circle.

What will work is putting an ID on the fo:external-graphic and then linking to it.

Code: Select all


<fo:block>
<fo:external-graphic src="svg_with_link.svg" id="my_graphic" />
</fo:block>
....
<fo:basic-link internal-destination="#my_graphic"> Go to graphic. </fo:basic-link>
Regards,
Dan

david-gopois69
Posts: 17
Joined: Fri Dec 15, 2017 6:13 pm

Re: Link between SVG image and text in an XML document

Post by david-gopois69 » Fri Oct 26, 2018 9:31 am

Hello Dan
Thank you for your reply.
Regards
David

NicoAMP
Posts: 40
Joined: Tue Mar 06, 2018 2:07 pm
Contact:

Re: Link between SVG image and text in an XML document

Post by NicoAMP » Fri Mar 27, 2020 2:01 pm

Hi Dan,

I tried your solution to make a link between an embed SVG in fo and a fo:block with FOP.
Dan wrote:
Wed Oct 24, 2018 4:55 pm

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="sample">
      <fo:region-body/>
    </fo:simple-page-master>
  </fo:layout-master-set>

  <!-- Declare the ID as named destination -->
  <fox:destination internal-destination="my_block_id"/>

  <fo:page-sequence master-reference="sample">
    <fo:flow flow-name="xsl-region-body">
      <fo:block>
        <!-- This has links like "#my_block_id" -->
        <fo:external-graphic src="svg_with_link.svg"/>
      </fo:block>
      <fo:block>Lore ipsum</fo:block>
      <fo:block>Lore ipsum</fo:block>
      <fo:block>Lore ipsum</fo:block>


      <!-- Put many more lines here to see that it scrolls to the target ... -->
      <fo:block color="red" id="my_block_id">Target</fo:block>


    </fo:flow>
  </fo:page-sequence>
</fo:root>
In the SVG you should refer the fo:block by #my_block_id

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg viewBox="0 0 362 232" version="1.0" width="400pt" height="400pt"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  
  <g stroke="none" stroke-width="1" fill="none"
    fill-rule="evenodd">
    <a xlink:href="#my_block_id"
      target="_blank">
      <circle id="circle" fill="#3AC3CA"
        cx="211.5" cy="139.5" r="56.5">
      </circle>
    </a>
  </g>
</svg>

My code:

Code: Select all

<fo:block-container absolute-position="absolute" top="0" left="0" margin="0" padding="0">
                    <fo:block margin="0" padding="0">
                      <fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">
                        <svg:svg height="231px" width="145px">
                          <svg:a xlink:href="#my_block_id" target="_blank">
                            <svg:circle stroke="blue" fill="blue" stroke-width="1" fill-opacity="1" stroke-opacity="1" r="4px" cx="101px" cy="130px"/>
                          </svg:a>
                        </svg:svg>
                      </fo:instream-foreign-object>
                    </fo:block>
</fo:block-container>
                  
 ...
                  
<fo:block id="my_block_id">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</fo:block>  
                  
This mechanism is OK with Antenna House : when I click on SVG I go to #my_block_id in PDF

But in FOP (I use v2.4) It doesn't work, I have the following message and when I click on "Accept" button nothing append:
Document try to connect to file:///C|Temp/topic.pdf%23my_block_id
If someone have an idea of why it doesn't work :)

Regards

Nicolas

julien_lacour
Posts: 84
Joined: Wed Oct 16, 2019 3:47 pm

Re: Link between SVG image and text in an XML document

Post by julien_lacour » Fri Mar 27, 2020 4:07 pm

Hello Nicolas,

To make the link works don't forget the <fox:destination internal-destination="my_block_id"/> declaration in the document (including the fox namespace declaration), here is a small example:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <fo:layout-master-set>
        <fo:simple-page-master master-name="sample">
            <fo:region-body/>
        </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Declare the ID as named destination -->
    <fox:destination internal-destination="my_block_id"/>
    
    <fo:page-sequence master-reference="sample">
        <fo:flow flow-name="xsl-region-body">
            <fo:block-container absolute-position="absolute" top="0" left="0" margin="0" padding="0">
                <fo:block margin="0" padding="0">
                    <fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg">
                        <svg:svg height="231px" width="145px">
                            <svg:a xlink:href="#my_block_id" target="_blank">
                                <svg:circle stroke="blue" fill="blue" stroke-width="1" fill-opacity="1" stroke-opacity="1" r="4px" cx="101px" cy="130px"/>
                            </svg:a>
                        </svg:svg>
                    </fo:instream-foreign-object>
                </fo:block>
            </fo:block-container>
        </fo:flow>
    </fo:page-sequence>
    <fo:page-sequence master-reference="sample">
        <fo:flow flow-name="xsl-region-body">
            <fo:block id="my_block_id">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</fo:block>  
        </fo:flow>
    </fo:page-sequence>
</fo:root>
Please not that the link does not work inside a local file (opened from the system) but it works if you copy the PDF on an Apache server for example, you will see the URL going from http://localhost/test.pdf to http://localhost/test.pdf#my_block_id.

Regards,
Julien

Post Reply