Menu

#100 Support SVG hyperlinks and event handling

Default
closed-fixed
nobody
None
5
2024-04-09
2023-11-01
No

SVG supports embedded hyperlinks, and the ability to trigger scripts on keyboard, mouse, and document events. But docutils does not, because SVG files are referenced by HTML "img" elements instead of "svg" elements.

Might be best to use the SVG "image" element, nested in a HTML "svg" element, to reference the underlying SVG file.

Related

Feature Requests: #40
Feature Requests: #83
Patches: #61

Discussion

  • Karl O. Pinc

    Karl O. Pinc - 2023-11-01

    See also, the releated Sphinx bug:
    https://github.com/sphinx-doc/sphinx/issues/2240

     
    • engelbert gruber

      at least an example of what you want would be really helpful

      a discussion of 10+ pages is no specification, is it ?

       

      Last edit: Günter Milde 2023-11-08
      • Karl O. Pinc

        Karl O. Pinc - 2023-11-02

        On Thu, 02 Nov 2023 00:03:36 -0000
        engelbert gruber via Docutils-develop
        docutils-develop@lists.sourceforge.net wrote:

        at least an example of what you want would be really helpful

        Here's a random web page with SVG that responds to events:
        https://www.tutorialspoint.com/svg/svg_interactivity.htm

        Note that it is not, at the same time, resizeable depending
        on browser window size. (See below.)

        Here's another with SVG that contains a hyperlink:
        https://developer.mozilla.org/en-US/docs/Web/SVG/Element/a

        Is this what you were asking for?

        SVG files called up in a browser using a file:/// URL
        also are scriptable and hyperlinkable. I could surely
        find some SVG file and attach it if that's helpful.

        a discussion of 10+ pages is no specification, is it ?

        There is nothing to specify that is RST author-facing. All the
        design work would be implementation. At least ideally,
        since there's no need for any more RST options. SVG
        has hyperlinks and responds to events by virtue of
        being SVG.

        The 2 new desired behaviors are:
        be scriptable (respond to keyboard, mouse, and document events)
        support hyperlinks in the image

        The 2 existing behaviors to retain are:
        be dynamically re-sizeable to browser window size
        not need a separate copy each time the SVG appears in a web page
        (be able to refer to a SVG file via a "href="-like mechanism)

        The last is not really required, but sure would be nice. I want all
        of the above behaviors to be available at the same time in the
        same SVG image.

        I tried coming up with an implementation and was not entirely
        successful. Here's what I found:

        If the image file for RST image or figure directives
        is SVG render with the HTML "svg" element,
        otherwise render with the "img" element.

        As near as I can tell, if you want your SVG to have
        hyperlinks or respond to events the browser's require
        the use of the "svg" element. (Other elements
        like "object" work too but have problems I can't
        now remember, perhaps having to do with events
        happening to the SVG being unavailable to the
        outer DOM.)

        As it turns out, the SVG "image" element won't produce
        something interactive, following clicked on hyperlinks
        or responding to events. I don't really know how to
        make an SVG image in an external file size dynamically and,
        at the same time, be interactive. Or whether it's possible to
        re-use SVG files by way of "href="-like linking or if the
        SVG would have to be embedded in the HTML. Ideas follow.

        You would think that the SVG "use" element (which has
        a "href" attribute) would allow re-use of
        an entire SVG file, but apparently not. One work-around might
        be to open the SVG file, extract the "svg" element's
        opening and closing tags for use in the HTML, re-write
        the SVG file putting a group around the entire content,
        then put a SVG "use" element in the "svg" element in the
        HTML and have it use the new group. That would get the
        original viewBox attribute into the HTML so that scaling the image
        size would work, and the "use" element means that interactivity
        is available. This seems like a kludge, but seems like it would work.

        (Sphinx, at least, copies image files into its build directory.
        Modifying the copied files seems not unreasonable. If docutils
        rejects this feature request because it does not want to modify
        files that's a reason to push the request back into the
        Sphinx space.)

        One would think there's a better way. Surely somebody wants
        to reference (href) a SVG file in their HTML, and have it be both
        dynamically re-sizeable and interactive. But I can't
        find an example that does all 3 -- only embedding SVG
        in HTML, not referencing an existing file via "href=",
        seems to be what people do. I suppose RST could embed SVG too,
        but that also seems clunky.

        So that's 2 possible approaches. Embed the SVG file directly
        in the HTML, or re-write the SVG file so that the SVG "use" element
        can reference the file's content.

        Regards,

        Karl kop@karlpinc.com
        Free Software: "You don't pay back, you pay forward."
        -- Robert A. Heinlein

         
  • Günter Milde

    Günter Milde - 2023-11-14

    [r9468] updates and extends the functional test with SVG images. Now you can compare inclusion with <object> tags (by the "html4" writer) https://docutils.sourceforge.io/test/functional/expected/standalone_rst_html5.html#svg-images
    and with <img> tags (by the "html5" writer) https://docutils.sourceforge.io/test/functional/expected/standalone_rst_html4css1.html#svg-images.
    The source is https://docutils.sourceforge.io/test/functional/input/data/svg_images.txt

    It turns out that <img> is the most failprove, privacy-friendly and safe method to include SVGs, while <object> provides interactivity for included images but may fail under some circumstances. Fortunately, the ratio of SVGs "in the wild" without a viewBox seems to be decreasing over the last years.

    You may experiment with the <object> method using rst2html4 or selecting the "html4" writer in Sphinx, to see whether it may work four your use cases.
    (The method was initially devised as a workaround for older browsers requiring a plug-in to display SVG images.) If it works satisfactory, we may consider using it in the "html5" writer as an alternative.

    Direct embedding is currently only available via "raw" (see the examples in svg_images.txt).
    As SVG images only work with HTML, this is no major limitation.

    For native support of embedding SVG, we still have to solve the issue on how to handle size and scaling options, (wrap in <div>, wrap in <svg> with ViewPort, ...).

    I don't think the "rewriting method" will be implemented in Docutils: it is too complicated and error-prone. However, if we get direct embedding of SVG, users may create re-usable images if they want to go this way. You may try with "raw" to embedding two SVG files with one defining something to use and the second using it.

     

    Related

    Commit: [r9468]


    Last edit: Günter Milde 2023-11-14
  • Günter Milde

    Günter Milde - 2023-12-16

    With the SVG embedding patch proposed in the last comment to feature-requests:#40, re-using SVG elements across embedded images works (but will have to be done by authors, not "automagically" by Doctutils.
    Example attached.

     
  • Günter Milde

    Günter Milde - 2024-01-15
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,3 +1,3 @@
     SVG supports embedded hyperlinks, and the ability to trigger scripts on keyboard, mouse, and document events.  But docutils does not, because SVG files are referenced by HTML &#34;img&#34; elements instead of &#34;svg&#34; elements.
    
    -Might be best to use the SVG &#34;image&#34; element, nested in a HTML &#34;svg&#34; element, to reference the underlying SVG file.
    +&lt;s&gt;Might be best to use the SVG &#34;image&#34; element, nested in a HTML &#34;svg&#34; element, to reference the underlying SVG file.&lt;/s&gt;
    
    • status: open --> open-fixed
     
  • Günter Milde

    Günter Milde - 2024-01-15

    [r9517] implements embedding SVG in an <svg> element, so embedded SVG images are now interactive.

     

    Related

    Commit: [r9517]

  • Günter Milde

    Günter Milde - 2024-04-09
    • Status: open-fixed --> closed-fixed
     

Log in to post a comment.