diagrams / diagrams-svg

An SVG backend for diagrams
http://projects.haskell.org/diagrams
Other
49 stars 39 forks source link

Spaces not preserved in text #94

Open rgleichman opened 7 years ago

rgleichman commented 7 years ago

By default, SVG does not preserve spaces in text. This is explained in the SVG spec:

‘xml:space’ is an inheritable attribute which can have one of two values:

'default' (The initial/default value for ‘xml:space’.) When xml:space="default", the SVG user agent will do the following using a copy of the original character data content. First, it will remove all newline characters. Then it will convert all tab characters into space characters. Then, it will strip off all leading and trailing space characters. Then, all contiguous space characters will be consolidated.

'preserve' When xml:space="preserve", the SVG user agent will do the following using a copy of the original character data content. It will convert all newline and tab characters into space characters. Then, it will draw all space characters, including leading, trailing and multiple contiguous space characters. Thus, when drawn with xml:space="preserve", the string "a b" (three spaces between "a" and "b") will produce a larger separation between "a" and "b" than "a b" (one space between "a" and "b").

I am working on a visual representation of Haskell rendered using diagrams (Glance), so of course I want to preserve spaces for string literals and comments.

As a workaround, I made a customized version of renderSVG that adds the attribute bindAttr XmlSpace_ (pack "preserve")

customRenderSVG outputFilename size = renderSVG' outputFilename svgOptions where
  -- This xml:space=preserve attribute preserves the spaces in the svg text.
  attributes = [bindAttr XmlSpace_ (pack "preserve")]
  svgOptions = SVGOptions size Nothing (pack "") attributes True
byorgey commented 7 years ago

So are you implying that you think diagrams-svg ought to always set xml:space="preserve" by default? I suppose that would be more consistent with other backends; on the other hand there has never been any particular promise that text will result in something that looks exactly the same when rendered by different backends, just that it uses the native text support provided by each backend. In which case it might make sense to have the default text output be whatever the default is. ...on the other hand, if the default were "preserve" it would be easy for a user to implement the space-stripping behavior themselves if they really wanted it, whereas given the current situation the workaround is more fiddly and harder to discover.

rgleichman commented 7 years ago

So are you implying that you think diagrams-svg ought to always set xml:space="preserve" by default?

I am not advocating for a specific solution, but as far I know setting xml:space="preserve" by default would be fine. As a user, all that I would like is some way to enable xml:space="preserve" without using renderSVG' so that it's easy to switch backends.

byorgey commented 7 years ago

As a user, all that I would like is some way to enable xml:space="preserve" without using renderSVG' so that it's easy to switch backends.

Ah, thanks for the clarification, that does make sense. I hadn't considered it from the point of view of switching backends. I'm guessing (but don't actually know for sure) that most, if not all, other backends essentially do something like xml:space="preserve"?