Source file src/cmd/vendor/github.com/google/pprof/internal/driver/svg.go
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 15 package driver 16 17 import ( 18 "regexp" 19 "strings" 20 21 "github.com/google/pprof/third_party/svgpan" 22 ) 23 24 var ( 25 viewBox = regexp.MustCompile(`<svg\s*width="[^"]+"\s*height="[^"]+"\s*viewBox="[^"]+"`) 26 graphID = regexp.MustCompile(`<g id="graph\d"`) 27 svgClose = regexp.MustCompile(`</svg>`) 28 ) 29 30 // massageSVG enhances the SVG output from DOT to provide better 31 // panning inside a web browser. It uses the svgpan library, which is 32 // embedded into the svgpan.JSSource variable. 33 func massageSVG(svg string) string { 34 // Work around for dot bug which misses quoting some ampersands, 35 // resulting on unparsable SVG. 36 svg = strings.Replace(svg, "&;", "&;", -1) 37 38 // Dot's SVG output is 39 // 40 // <svg width="___" height="___" 41 // viewBox="___" xmlns=...> 42 // <g id="graph0" transform="..."> 43 // ... 44 // </g> 45 // </svg> 46 // 47 // Change it to 48 // 49 // <svg width="100%" height="100%" 50 // xmlns=...> 51 52 // <script type="text/ecmascript"><![CDATA[` ..$(svgpan.JSSource)... `]]></script>` 53 // <g id="viewport" transform="translate(0,0)"> 54 // <g id="graph0" transform="..."> 55 // ... 56 // </g> 57 // </g> 58 // </svg> 59 60 if loc := viewBox.FindStringIndex(svg); loc != nil { 61 svg = svg[:loc[0]] + 62 `<svg width="100%" height="100%"` + 63 svg[loc[1]:] 64 } 65 66 if loc := graphID.FindStringIndex(svg); loc != nil { 67 svg = svg[:loc[0]] + 68 `<script type="text/ecmascript"><![CDATA[` + string(svgpan.JSSource) + `]]></script>` + 69 `<g id="viewport" transform="scale(0.5,0.5) translate(0,0)">` + 70 svg[loc[0]:] 71 } 72 73 if loc := svgClose.FindStringIndex(svg); loc != nil { 74 svg = svg[:loc[0]] + 75 `</g>` + 76 svg[loc[0]:] 77 } 78 79 return svg 80 } 81