説明なし

svg.go 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2014 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package svg provides tools related to handling of SVG files
  15. package svg
  16. import (
  17. "bytes"
  18. "regexp"
  19. "strings"
  20. )
  21. var (
  22. viewBox = regexp.MustCompile(`<svg\s*width="[^"]+"\s*height="[^"]+"\s*viewBox="[^"]+"`)
  23. graphID = regexp.MustCompile(`<g id="graph\d"`)
  24. svgClose = regexp.MustCompile(`</svg>`)
  25. )
  26. // Massage enhances the SVG output from DOT to provide better
  27. // panning inside a web browser. It uses the SVGPan library, which is
  28. // embedded into the svgPanJS variable.
  29. func Massage(in bytes.Buffer) string {
  30. svg := string(in.Bytes())
  31. // Work around for dot bug which misses quoting some ampersands,
  32. // resulting on unparsable SVG.
  33. svg = strings.Replace(svg, "&;", "&amp;;", -1)
  34. //Dot's SVG output is
  35. //
  36. // <svg width="___" height="___"
  37. // viewBox="___" xmlns=...>
  38. // <g id="graph0" transform="...">
  39. // ...
  40. // </g>
  41. // </svg>
  42. //
  43. // Change it to
  44. //
  45. // <svg width="100%" height="100%"
  46. // xmlns=...>
  47. // <script type="text/ecmascript"><![CDATA[` ..$(svgPanJS)... `]]></script>`
  48. // <g id="viewport" transform="translate(0,0)">
  49. // <g id="graph0" transform="...">
  50. // ...
  51. // </g>
  52. // </g>
  53. // </svg>
  54. if loc := viewBox.FindStringIndex(svg); loc != nil {
  55. svg = svg[:loc[0]] +
  56. `<svg width="100%" height="100%"` +
  57. svg[loc[1]:]
  58. }
  59. if loc := graphID.FindStringIndex(svg); loc != nil {
  60. svg = svg[:loc[0]] +
  61. `<script type="text/ecmascript"><![CDATA[` + string(svgPanJS) + `]]></script>` +
  62. `<g id="viewport" transform="scale(0.5,0.5) translate(0,0)">` +
  63. svg[loc[0]:]
  64. }
  65. if loc := svgClose.FindStringIndex(svg); loc != nil {
  66. svg = svg[:loc[0]] +
  67. `</g>` +
  68. svg[loc[0]:]
  69. }
  70. return svg
  71. }