Menu

#532 Extend SVG terminal

open
nobody
None
5
2013-02-10
2011-03-10
Marco
No

It would be nice to have an option for the svg terminal that makes it easier
to include the output in other svg documents. I'd suggest an option to just output
the svg element, this means in particular:

1) No XML declaration
2) No DOCTYPE declaration
3) Change namespace xmlns to xmlns:svg
4) Prepend svg: to all tags

This would make working with the output files much easier.

Discussion

  • Marco

    Marco - 2011-03-10

    Typo Correction:

    > [...] to include the output in other svg documents
    Of course i mean: to include the output in other XML documents, xhtml in particular. See
    http://www.w3.org/TR/XHTMLplusMathMLplusSVG/#bugs

     
  • Ethan Merritt

    Ethan Merritt - 2011-04-11

    I don't know enough about SVG or xml to translate your request into actual code.
    Could you upload a before/after pair of *.svg files showing the difference?
    I.e. create a simple file
    set term svg
    set output 'before.svg'
    plot x
    then copy before.svg to after.svg and edit it so that it represents the variant output your would like. I can then use the diff between the two files to guide changes to the terminal driver.

     
  • Marco

    Marco - 2011-04-12

    Simple plot, unchanged

     
  • Marco

    Marco - 2011-04-12

    Simple plot, XML header, doctype removed, namespace changed, all tags prefixed with svg:

     
  • Christoph Bersch

    Hi,

    please find attached a patch which accounts for your suggestions and adds three new terminal options:

    'standalone': Use an XML declaration (default)
    'nostandalone': Don't use an XML declaration

    'namespace' allows using a namespace for the image. 'namespace "svg"' changes the namespace to xmlns:svg and prefixes all tags with "svg:". Default is to use no namespace.

    Index: gnuplot.patched/term/svg.trm

    RCS file: /cvsroot/gnuplot/gnuplot/term/svg.trm,v
    retrieving revision 1.122
    diff -u -r1.122 svg.trm
    --- gnuplot.patched/term/svg.trm 4 Sep 2011 02:05:24 -0000 1.122
    +++ gnuplot.patched/term/svg.trm 3 Oct 2011 19:14:57 -0000
    @@ -49,6 +49,9 @@
    *
    * Contributed by <forgery69@users.sf.net>
    * Javascript code to toggle plots on/off
    + *
    + * Christoph Bersch, Oct 2011: added options standalone, nostandalone,
    + * namespace. Removed DTD.
    */

    #include "driver.h"
    @@ -110,8 +113,10 @@
    static unsigned char SVG_color_mode = TC_DEFAULT;
    static char *SVG_linecolor = NULL;
    static char *SVG_name = NULL;
    +static char SVG_namespace[MAX_ID_LEN+1] = "";
    static char *SVG_scriptdir = NULL;
    static TBOOLEAN SVG_mouseable = FALSE;
    +static TBOOLEAN SVG_standalone = FALSE;

    static TBOOLEAN SVG_groupFilledIsOpen = FALSE; /* open pm3d group flag*/

    @@ -214,8 +219,8 @@
    SVG_GroupFilledClose();
    if (!SVG_groupIsOpen) {

    - fprintf (gpoutfile, "<g style=\"fill:none; color:%s; stroke:",
    - SVG_pens[SVG_Pen_RealID (SVG_LineType)].color);
    + fprintf (gpoutfile, "<%sg style=\"fill:none; color:%s; stroke:",
    + SVG_namespace, SVG_pens[SVG_Pen_RealID (SVG_LineType)].color);

    if \(SVG\_color\_mode == TC\_RGB\)
        fprintf\(gpoutfile, "rgb\(%3d, %3d, %3d\)", SVG\_red, SVG\_green, SVG\_blue\);
    

    @@ -243,10 +248,10 @@
    {
    SVG_GroupFilledClose();
    if (SVG_groupIsOpen) {
    - fputs ("</g>\n", gpoutfile);
    - SVG_groupIsOpen = FALSE;
    - SVG_fillPattern = -1;
    - }
    + fprintf (gpoutfile, "</%sg>\n", SVG_namespace);
    + SVG_groupIsOpen = FALSE;
    + SVG_fillPattern = -1;
    + }
    }

    /*------------------------------------------------------------------------------------------------------------------------------------
    @@ -258,7 +263,7 @@
    if (!SVG_pathIsOpen) {
    SVG_GroupFilledClose();

    - fputs ("\t<path ", gpoutfile);
    + fprintf (gpoutfile, "\t<%spath ", SVG_namespace);

    /\* Line color \*/
    if \(SVG\_color\_mode == TC\_RGB\)
    

    @@ -336,8 +341,9 @@
    {
    if (!SVG_groupFilledIsOpen) {
    SVG_PathClose();
    - fputs("\t<g style = 'stroke:none; shape-rendering:crispEdges'>\n",
    - gpoutfile);
    + fprintf(gpoutfile,
    + "\t<%sg style = 'stroke:none; shape-rendering:crispEdges'>\n",
    + SVG_namespace);
    SVG_groupFilledIsOpen = TRUE;
    }
    }
    @@ -346,7 +352,7 @@
    SVG_GroupFilledClose()
    {
    if (SVG_groupFilledIsOpen) {
    - fputs("\t</g>\n", gpoutfile);
    + fprintf(gpoutfile, "\t</%sg>\n", SVG_namespace);
    SVG_groupFilledIsOpen = FALSE;
    }
    }
    @@ -381,9 +387,9 @@
    SVG_fillPatternIndex++;

    fprintf\(gpoutfile,
    

    - "\t<defs>\n"
    - "\t\t<pattern id='gpPat%d' patternUnits='userSpaceOnUse' x='0' y='0' width='8' height='8'>\n",
    - SVG_fillPatternIndex);
    + "\t<%sdefs>\n"
    + "\t\t<%spattern id='gpPat%d' patternUnits='userSpaceOnUse' x='0' y='0' width='8' height='8'>\n",
    + SVG_namespace, SVG_namespace, SVG_fillPatternIndex);
    switch (fillpat) {
    default:
    case 0:
    @@ -416,16 +422,16 @@
    char *figure = "fill:none;";
    if (!strcmp(style,"fill")) figure = "stroke:none;";
    if (SVG_color_mode == TC_RGB)
    - fprintf(gpoutfile,"\t\t\t<path style='%s %s:rgb(%d,%d,%d)' d='%s'/>\n",
    - figure, style, SVG_red, SVG_green, SVG_blue, path);
    + fprintf(gpoutfile,"\t\t\t<%spath style='%s %s:rgb(%d,%d,%d)' d='%s'/>\n",
    + SVG_namespace, figure, style, SVG_red, SVG_green, SVG_blue, path);
    else if (SVG_color_mode == TC_LT)
    - fprintf(gpoutfile, "\t\t\t<path style = '%s %s:%s' d= '%s'/>\n",
    - figure, style, SVG_linecolor, path);
    + fprintf(gpoutfile, "\t\t\t<%spath style = '%s %s:%s' d= '%s'/>\n",
    + SVG_namespace, figure, style, SVG_linecolor, path);
    else
    - fprintf(gpoutfile, "\t\t\t<path style = '%s %s:currentColor' d='%s'/>\n",
    - figure, style, path);
    + fprintf(gpoutfile, "\t\t\t<%spath style = '%s %s:currentColor' d='%s'/>\n",
    + SVG_namespace, figure, style, path);
    }
    - fputs("\t\t</pattern>\n" "\t</defs>\n", gpoutfile);
    + fprintf(gpoutfile, "\t\t</%spattern>\n" "\t</%sdefs>\n", SVG_namespace, SVG_namespace);
    }
    }

    @@ -613,7 +619,38 @@
    SVG_background = parse_color_name();
    continue;
    }
    -
    +
    + if (almost_equals(c_token, "stand$alone")) {
    + c_token++;
    + SVG_standalone = TRUE;
    + continue;
    + }
    +
    + if (almost_equals(c_token, "nostand$alone")) {
    + c_token++;
    + SVG_standalone = FALSE;
    + continue;
    + }
    +
    + if (almost_equals(c_token, "namespace")) {
    + char *s;
    + c_token++;
    + if (!(s = try_to_get_string()))
    + int_error(c_token,"expecting namespace string");
    +
    + size_t len;
    + len = strlen(s);
    + if (len == 0) {
    + strncpy(SVG_namespace, "", sizeof(SVG_namespace));
    + } else if (len >= (sizeof(SVG_namespace) - 1)) {
    + int_error(c_token, "namespace string is too long");
    + } else {
    + snprintf(SVG_namespace, sizeof(SVG_namespace), "%s:", s);
    + }
    + free(s);
    + continue;
    + }
    +
    int_error(c_token, "unrecognized terminal option");
    }

    @@ -657,7 +694,16 @@
    sprintf(term_options + strlen(term_options),
    "background \"#%06x\" ", SVG_background);
    }
    -
    +
    + if (strlen(SVG_namespace) > 0) {
    + char *namespace = gp_strdup(SVG_namespace);
    + namespace[strlen(namespace) - 1] = '\0';
    + sprintf(term_options + strlen(term_options),
    + "namespace \"%s\" ", namespace);
    + free(namespace);
    + }
    +
    + sprintf(term_options + strlen(term_options), "%sstandalone", SVG_standalone ? "" : "no");
    }

    static void
    @@ -773,11 +819,12 @@
    break;
    }

    - fprintf (gpoutfile,
    - "<?xml version=\"1.0\" %s standalone=\"no\"?>\n"
    - "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n"
    - " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
    - "<svg ", svg_encoding);
    + if (SVG_standalone) {
    + fprintf (gpoutfile, "<?xml version=\"1.0\" %s standalone=\"no\"?>\n", svg_encoding);
    + }
    + /* removed the DTD and added 'version' attribute as suggested in
    + <https://jwatt.org/svg/authoring/#doctype-declaration> */
    + fprintf(gpoutfile, "<%ssvg version=\"1.1\" ", SVG_namespace);

    if (SVG_mouseable)
    fprintf (gpoutfile, "onload=\"if (typeof(gnuplot_svg)!='undefined') gnuplot_svg.Init(evt)\" ");
    @@ -790,7 +837,15 @@
    fprintf (gpoutfile, "\n viewBox=\"0 0 %u %u\"\n",
    (unsigned int) (term->xmax / SVG_SCALE),
    (unsigned int) (term->ymax / SVG_SCALE));
    - fprintf (gpoutfile, " xmlns=\"http://www.w3.org/2000/svg\"\n");
    + fprintf (gpoutfile, " xmlns");
    + if (strlen(SVG_namespace) > 0) {
    + fputc(':', gpoutfile);
    + char *namespace = gp_strdup(SVG_namespace);
    + namespace[strlen(namespace) - 1] = '\0';
    + fputs(namespace, gpoutfile);
    + free(namespace);
    + }
    + fprintf (gpoutfile, "=\"http://www.w3.org/2000/svg\"\n");
    fprintf (gpoutfile, " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
    #if (0)
    /* This should be required, but Firefox gets it totally wrong */
    @@ -799,8 +854,8 @@
    fprintf (gpoutfile, ">\n\n");

    fprintf (gpoutfile,
    - "<desc>Produced by GNUPLOT %s patchlevel %s </desc>\n\n",
    - gnuplot_version, gnuplot_patchlevel);
    + "<%sdesc>Produced by GNUPLOT %s patchlevel %s </%sdesc>\n\n",
    + SVG_namespace, gnuplot_version, gnuplot_patchlevel, SVG_namespace);

    /*
    * FIXME: This code could be shared with canvas.trm
    @@ -849,24 +904,25 @@

    if (SVG_mouseable) {
    /* This is sufficient to support toggling plots on/off */
    - fprintf(gpoutfile,"<script type=\"text/javascript\" xlink:href=\"%sgnuplot_svg.js\"/>\n",
    - SVG_scriptdir);
    + fprintf(gpoutfile,"<%sscript type=\"text/javascript\" xlink:href=\"%sgnuplot_svg.js\"/>\n",
    + SVG_namespace, SVG_scriptdir);
    }

    if (SVG_mouseable) { /* FIXME: Should only do this for 2D plots */
    /* This is extra code to support tracking the mouse coordinates */
    fprintf(gpoutfile,"\n<!-- Tie mousing to entire bounding box of the plot -->\n");
    - fprintf(gpoutfile,"<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"",
    - 0, 0, (int)(term->xmax/SVG_SCALE), (int)(term->ymax/SVG_SCALE));
    + fprintf(gpoutfile,"<%srect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"",
    + SVG_namespace, 0, 0, (int)(term->xmax/SVG_SCALE), (int)(term->ymax/SVG_SCALE));
    fprintf(gpoutfile," fill=\"#%06x\" stroke=\"black\" stroke-width=\"1\"\n",
    SVG_background>0 ? SVG_background : 0xffffff);
    fprintf(gpoutfile,"onclick=\"gnuplot_svg.toggleCoordBox(evt)\" onmousemove=\"gnuplot_svg.moveCoordBox(evt)\"/>\n");
    fprintf(gpoutfile,"\n<!-- Also track mouse when it is on a plot element -->\n");
    - fprintf(gpoutfile,"<g id=\"gnuplot_canvas\" onclick=\"gnuplot_svg.toggleCoordBox(evt)\" onmousemove=\"gnuplot_svg.moveCoordBox(evt)\">\n\n");
    + fprintf(gpoutfile,"<%sg id=\"gnuplot_canvas\" onclick=\"gnuplot_svg.toggleCoordBox(evt)\" onmousemove=\"gnuplot_svg.moveCoordBox(evt)\">\n\n",
    + SVG_namespace);
    } else {
    - fprintf(gpoutfile,"<g id=\"gnuplot_canvas\">\n\n");
    - fprintf(gpoutfile,"<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"",
    - 0, 0, (int)(term->xmax/SVG_SCALE), (int)(term->ymax/SVG_SCALE));
    + fprintf(gpoutfile,"<%sg id=\"gnuplot_canvas\">\n\n", SVG_namespace);
    + fprintf(gpoutfile,"<%srect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"",
    + SVG_namespace, 0, 0, (int)(term->xmax/SVG_SCALE), (int)(term->ymax/SVG_SCALE));
    if (SVG_background > 0)
    fprintf(gpoutfile," fill=\"#%06x\"", SVG_background);
    else
    @@ -876,7 +932,7 @@

    /* Start prologue section of output file, and load fonts if requested */

    - fprintf(gpoutfile,"<defs>\n");
    + fprintf(gpoutfile,"<%sdefs>\n", SVG_namespace);
    if (SVG_embedded_font)
    SVG_load_fontfile(SVG_embedded_font);

    @@ -891,46 +947,49 @@
    fprintf (gpoutfile,
    "\n"
    /* dot: */
    - "\t<circle id='gpDot' r='0.5' stroke-width='0.5'/>\n"
    + "\t<%scircle id='gpDot' r='0.5' stroke-width='0.5'/>\n"
    /* 0 plus */
    - "\t<path id='gpPt0' stroke-width='%.3f' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>\n"
    + "\t<%spath id='gpPt0' stroke-width='%.3f' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>\n"
    /* 1 X */
    - "\t<path id='gpPt1' stroke-width='%.3f' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>\n"
    + "\t<%spath id='gpPt1' stroke-width='%.3f' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>\n"
    /* 2 star */
    - "\t<path id='gpPt2' stroke-width='%.3f' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>\n"
    + "\t<%spath id='gpPt2' stroke-width='%.3f' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>\n"
    /* 3 box */
    - "\t<rect id='gpPt3' stroke-width='%.3f' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>\n"
    + "\t<%srect id='gpPt3' stroke-width='%.3f' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>\n"
    /* 4 box filled */
    - "\t<rect id='gpPt4' stroke-width='%.3f' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>\n"
    + "\t<%srect id='gpPt4' stroke-width='%.3f' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>\n"
    /* 5 circle */
    - "\t<circle id='gpPt5' stroke-width='%.3f' stroke='currentColor' cx='0' cy='0' r='1'/>\n"
    + "\t<%scircle id='gpPt5' stroke-width='%.3f' stroke='currentColor' cx='0' cy='0' r='1'/>\n"
    /* 6 circle (disk) filled */
    - "\t<use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>\n"
    + "\t<%suse xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>\n"
    /* 7 triangle */
    - "\t<path id='gpPt7' stroke-width='%.3f' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>\n"
    + "\t<%spath id='gpPt7' stroke-width='%.3f' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>\n"
    /* 8 triangle filled */
    - "\t<use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>\n"
    + "\t<%suse xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>\n"
    /* 9 upside down triangle */
    - "\t<use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>\n"
    + "\t<%suse xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>\n"
    /* 10 upside down triangle filled */
    - "\t<use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>\n"
    + "\t<%suse xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>\n"
    /* 11 diamond */
    - "\t<use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>\n"
    + "\t<%suse xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>\n"
    /* 12 diamond filled */
    - "\t<use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>\n"
    + "\t<%suse xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>\n"

         /\* NOTE: Fill patterns must be defined after the stroke color has been
          \* set to use the correct \(current\) stroke color. Therefore we can't
          \* define fill patterns here. \*/
    

    - "</defs>\n"
    - , stroke_width
    - , stroke_width
    - , stroke_width
    - , stroke_width
    - , stroke_width
    - , stroke_width
    - , stroke_width
    + "</%sdefs>\n"
    + , SVG_namespace
    + , SVG_namespace, stroke_width
    + , SVG_namespace, stroke_width
    + , SVG_namespace, stroke_width
    + , SVG_namespace, stroke_width
    + , SVG_namespace, stroke_width
    + , SVG_namespace, stroke_width
    + , SVG_namespace
    + , SVG_namespace, stroke_width
    + , SVG_namespace, SVG_namespace, SVG_namespace, SVG_namespace, SVG_namespace, SVG_namespace
    );
    }

    @@ -968,7 +1027,7 @@
    struct udvt_entry *udv;
    char *name = (SVG_name) ? SVG_name : "gnuplot";

    - fprintf(gpoutfile, "\n<script type=\"text/javascript\"><![CDATA[\n");
    + fprintf(gpoutfile, "\n<%sscript type=\"text/javascript\"><![CDATA[\n", SVG_namespace);
    fprintf(gpoutfile, "// plot boundaries and axis scaling information for mousing \n");
    fprintf(gpoutfile, "gnuplot_svg.plot_term_xmax = %d;\n", (int)(term->xmax / CANVAS_OVERSAMPLE));
    fprintf(gpoutfile, "gnuplot_svg.plot_term_ymax = %d;\n", (int)(term->ymax / CANVAS_OVERSAMPLE));
    @@ -1040,24 +1099,24 @@
    } else
    fprintf(gpoutfile, "gnuplot_svg.plot_timeaxis_x = \"\";\n");

    - fprintf(gpoutfile,"]]>\n</script>\n");
    + fprintf(gpoutfile,"]]>\n</%sscript>\n", SVG_namespace);
    } /* End of section writing out variables for mousing */

    /* Close off the group with id=gnuplot_canvas that wraps the entire plot */
    - fprintf(gpoutfile,"</g>\n");
    + fprintf(gpoutfile,"</%sg>\n", SVG_namespace);

    /* Now create a text element to hold the mouse-tracking text. */
    /* It comes _after_ the plot group so that it floats on top. */
    if (SVG_mouseable) {
    - fprintf(gpoutfile,"\n <text id=\"coord_text\" text-anchor=\"start\" pointer-events=\"none\"\n");
    + fprintf(gpoutfile,"\n <%stext id=\"coord_text\" text-anchor=\"start\" pointer-events=\"none\"\n", SVG_namespace);
    fprintf(gpoutfile," font-size=\"12\" font-family=\"Arial\"\n");
    - fprintf(gpoutfile," visibility=\"hidden\"> </text>\n");
    + fprintf(gpoutfile," visibility=\"hidden\"> </%stext>\n", SVG_namespace);
    }

    /* If there were any grid lines in this plot, add a button to toggle them */
    if (SVG_mouseable && SVG_hasgrid) {
    - fprintf(gpoutfile,"\n <image x='10' y='%d' width='16' height='16' xlink:href='grid.png'\n",
    - (int)(term->ymax/SVG_SCALE)-26);
    + fprintf(gpoutfile,"\n <%simage x='10' y='%d' width='16' height='16' xlink:href='grid.png'\n",
    + SVG_namespace, (int)(term->ymax/SVG_SCALE)-26);
    fprintf(gpoutfile," onclick='gnuplot_svg.toggleGrid();'/>\n");
    }
    }
    @@ -1068,7 +1127,7 @@
    TERM_PUBLIC void
    SVG_reset ()
    {
    - fputs("</svg>\n\n", gpoutfile);
    + fprintf(gpoutfile, "</%ssvg>\n\n", SVG_namespace);
    }

    /*------------------------------------------------------------------------------------------------------------------------------------
    @@ -1173,12 +1232,14 @@

    if (number < 0) { /* do dot */
    fprintf (gpoutfile, "\ -\t<use xlink:href='#gpDot' x='%.1f' y='%.1f'%s/>\n",
    +\t<%suse xlink:href='#gpDot' x='%.1f' y='%.1f'%s/>\n",
    + SVG_namespace,
    X(x), Y(y), color_spec);
    } else { /* draw a point symbol */
    fprintf (gpoutfile, "\ -\t<use xlink:href='#gpPt%u' transform='translate(%.1f,%.1f) scale(%.2f)'%s/>\ +\t<%suse xlink:href='#gpPt%u' transform='translate(%.1f,%.1f) scale(%.2f)'%s/>\ \n",
    + SVG_namespace,
    number % 13, X(x), Y(y),
    term_pointsize * term->h_tic / (2 * SVG_SCALE),
    color_spec);
    @@ -1246,7 +1307,7 @@

    /* define text position and attributes */

    - fprintf (gpoutfile, "\t<g transform=\"translate(%.1f,%.1f)", X(h), Y(v));
    + fprintf (gpoutfile, "\t<%sg transform=\"translate(%.1f,%.1f)", SVG_namespace, X(h), Y(v));
    if (SVG_TextAngle)
    fprintf (gpoutfile, " rotate(%i)", -SVG_TextAngle);
    fprintf (gpoutfile, "\" style=\"stroke:none; fill:");
    @@ -1265,9 +1326,9 @@
    /* output text (unless the enhanced_text processing is in action) */

    if (strstr(str," "))
    - fputs ("\t\t<text xml:space=\"preserve\">", gpoutfile);
    + fprintf (gpoutfile, "\t\t<%stext xml:space=\"preserve\">", SVG_namespace);
    else
    - fputs ("\t\t<text>", gpoutfile);
    + fprintf (gpoutfile, "\t\t<%stext>", SVG_namespace);

    if (!ENHsvg_string_state) {

    @@ -1290,7 +1351,7 @@

        str++;
    \}
    

    - fputs("</text>\n\t</g>\n", gpoutfile);
    + fprintf(gpoutfile, "</%stext>\n\t</%sg>\n", SVG_namespace, SVG_namespace);
    }
    }

    @@ -1407,7 +1468,7 @@
    }

    SVG_GroupFilledOpen();
    - fputs("\t\t<polygon ", gpoutfile);
    + fprintf(gpoutfile, "\t\t<%spolygon ", SVG_namespace);

    switch (style) {
    case FS_EMPTY: /* fill with background color */
    @@ -1456,15 +1517,15 @@
    SVG_GroupClose();
    ++SVG_plotno;
    name = (SVG_name) ? SVG_name : "gnuplot";
    - fprintf(gpoutfile, "\t<g id=\"%s_plot_%d\" ", name,SVG_plotno);
    - fprintf(gpoutfile, "><title>%s_plot_%d</title>\n", name,SVG_plotno);
    + fprintf(gpoutfile, "\t<%sg id=\"%s_plot_%d\" ", SVG_namespace, name, SVG_plotno);
    + fprintf(gpoutfile, "><%stitle>%s_plot_%d</%stitle>\n", SVG_namespace, name, SVG_plotno, SVG_namespace);
    SVG_LineType = LT_UNDEFINED; /* Force a new group on next stroke */
    break;

    case TERM\_LAYER\_AFTER\_PLOT:
        SVG\_PathClose\(\);
        SVG\_GroupClose\(\);
    

    - fprintf(gpoutfile, "\t</g>\n");
    + fprintf(gpoutfile, "\t</%sg>\n", SVG_namespace);
    SVG_LineType = LT_UNDEFINED; /* Force a new group on next stroke */
    break;

    @@ -1482,7 +1543,7 @@
    SVG_PathClose();
    SVG_GroupFilledClose();
    name = (SVG_name) ? SVG_name : "gnuplot";
    - fprintf(gpoutfile, "\t<g visibility=\"visible\" ");
    + fprintf(gpoutfile, "\t<%sg visibility=\"visible\" ", SVG_namespace);
    fprintf(gpoutfile,
    "onclick=\"gnuplot_svg.toggleVisibility(evt,'%s_plot_%d')\"",
    name,SVG_plotno);
    @@ -1494,7 +1555,7 @@
    if (SVG_mouseable) {
    SVG_PathClose();
    SVG_GroupFilledClose();
    - fprintf(gpoutfile, "\t</g>\n");
    + fprintf(gpoutfile, "\t</%sg>\n", SVG_namespace);
    SVG_LineType = LT_UNDEFINED;
    }
    break;
    @@ -1522,9 +1583,10 @@
    write_png_image (m, n, image, color_mode, image_file);

    /* Map it onto the terminals coordinate system. */
    - fprintf(gpoutfile, "<image x='%.1f' y='%.1f' width='%.1f' height='%.1f' preserveAspectRatio='none' ",
    - X(corner[0].x), Y(corner[0].y),
    - X(corner[1].x) - X(corner[0].x), Y(corner[1].y) - Y(corner[0].y));
    + fprintf(gpoutfile, "<%simage x='%.1f' y='%.1f' width='%.1f' height='%.1f' preserveAspectRatio='none' ",
    + SVG_namespace,
    + X(corner[0].x), Y(corner[0].y),
    + X(corner[1].x) - X(corner[0].x), Y(corner[1].y) - Y(corner[0].y));

    fprintf(gpoutfile, "xlink:href='%s_image_%02d.png'/>;\n",
    base_name, SVG_imageno);
    @@ -1560,8 +1622,8 @@
    * they all get piled on top of one another.
    */
    ENHsvg_FLUSH();
    - fprintf(gpoutfile, "<tspan dx=\"-%.1fem\" dy=\"%.1fpt\">",
    - 0.5 * ENHsvg_charcount, ENHsvg_base-base);
    + fprintf(gpoutfile, "<%stspan dx=\"-%.1fem\" dy=\"%.1fpt\">",
    + SVG_namespace, 0.5 * ENHsvg_charcount, ENHsvg_base-base);
    ENHsvg_base = base;
    ENHsvg_x_offset = 0.0;
    enhanced_cur_text = enhanced_text;
    @@ -1586,7 +1648,7 @@
    enhanced_cur_text = enhanced_text;

    /\* Start a new textspan fragment \*/
    

    - fputs("<tspan", gpoutfile);
    + fprintf(gpoutfile, "<%stspan", SVG_namespace);
    if (strcmp(SVG_fontNameCur, fontname)) {
    free(SVG_fontNameCur);
    SVG_fontNameCur = gp_strdup(fontname);
    @@ -1621,7 +1683,7 @@
    if (ENHsvg_opened_string) {
    ENHsvg_opened_string = FALSE;
    *enhanced_cur_text = '\0';
    - fprintf(gpoutfile, "%s</tspan>", enhanced_text);
    + fprintf(gpoutfile, "%s</%stspan>", enhanced_text, SVG_namespace);
    }
    }

    @@ -1674,15 +1736,15 @@
    SVG_fontNameCur = fontname;
    fontname = NULL;
    if (SVG_fontSizeCur != fontsize || ENHsvg_base != 0) {
    - fprintf(gpoutfile, "<tspan font-size=\"%.1fpt\" dy=\"%.2fpt\"></tspan>",
    - fontsize, ENHsvg_base);
    + fprintf(gpoutfile, "<%stspan font-size=\"%.1fpt\" dy=\"%.2fpt\"></t%sspan>",
    + SVG_namespace, fontsize, ENHsvg_base, SVG_namespace);
    SVG_fontSizeCur = fontsize;
    ENHsvg_base = 0;
    }
    ENHsvg_preserve_spaces = FALSE;

    /* Close the text section */
    - fputs("</text>\n\t</g>\n", gpoutfile);
    + fprintf(gpoutfile, "</%stext>\n\t</%sg>\n", SVG_namespace, SVG_namespace);

    return;
    }
    @@ -1856,6 +1918,8 @@
    " {fontfile <filename>}",
    " {rounded|butt} {solid|dashed} {linewidth <lw>}",
    " {background <rgb_color>}",
    +" {{no}standalone}",
    +" {namespace \"<namespace>\"}",
    "",
    " where <x> and <y> are the size of the SVG plot to generate,",
    " `dynamic` allows a svg-viewer to resize plot, whereas the default",
    @@ -1889,5 +1953,10 @@
    " the desired font. Gnuplot will look for the requested file using the",
    " directory list in the GNUPLOT_FONTPATH environmental variable.",
    " NB: You must embed an svg font, not a TrueType or PostScript font."
    +"",
    +" `standalone` inserts an XML declaration with the selected encoding at the"
    +" document beginning, `nostandalone` omits this declaration. `namespace` "
    +" allows the use of a namespace for the svg image which simplifies inclusion "
    +" in other documents."
    END_HELP(svg)
    #endif

     
  • Ethan Merritt

    Ethan Merritt - 2011-10-04

    I am definitely not an expert here, but I note that the W3C guide explicitly says that a DOCTYPE declaration is required: http://www.w3.org/QA/2002/04/valid-dtd-list.html

    So while I don't understand the ins and outs of creating a standalone document versus a fragment to be embedded, I think that unconditionally removing the DTD is not correct. Can someone clarify?

     
  • Christoph Bersch

    The W3C guide does not say that a DOCTYPE is required. Concerning the SVG DOCTYPE it says <http://www.w3.org/QA/2002/04/valid-dtd-list.html#DTD>:

    "Optional doctype declarations

    Beyond the specificities of (X)HTML processing, Doctype declarations in XML languages are only useful to declare named entities and to facilitate the validation of documents based on DTDs. This means that in many XML languages, doctype declarations are not necessarily useful.

    The list below is provided only if you actually need to declare a doctype for these types of documents."

    Christoph

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.