有几个资源讨论了在SVG文档中使用variables,包括:
尽pipe基于CSS,JavaScript和HTML的解决scheme对于Web来说非常有用,但在其他情况下,SVG是有用的,并且有能力为variables定义外部源也同样方便。
SVG不提供定义SVG相关软件包(如Inkscape和rsvg-convert )可以重复使用的可重用文本的机制。 例如,以下将是非常棒的:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg ...> <input href="definitions.svg" /> ... <text ...>${variableName}</text> </svg>
image元素可以被重载来导入一个外部文件,但是这是一个黑客行为,并且不允许将文本值赋给variables名以便重用。
你如何从服务器上的外部文件(例如,一个YAML文件,但可能是一个数据库)读取variables名称和值,并在渲染之前replaceSVG文件中的variables?
另一个可能的解
在Inkscape中设置对象属性
保存它,我们会有类似的东西
... <text xml:space="preserve" style="font-style:normal;font-weight:normal;font-size:60px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;image-rendering:auto" x="262.91638" y="86.339157" id="mytest" sodipodi:linespacing="125%" inkscape:label="#myvar"><desc id="desc4150">The test object to replace with a var</desc><title id="title4148">myobj</title><tspan sodipodi:role="line" id="tspan4804" x="262.91638" y="86.339157" style="fill:#ffffff">sample</tspan></text> ...
然后用键值对创建yaml文件
myvar: hello world
并解析SVG并替换值
#! /usr/bin/env python import sys from xml.dom import minidom import yaml yvars = yaml.load(file('drawing.yaml', 'r')) xmldoc = minidom.parse('drawing.svg') for s in xmldoc.getElementsByTagName('text'): for c in s.getElementsByTagName('tspan'): c.firstChild.replaceWholeText(yvars[s.attributes['inkscape:label'].value[1:]]) print xmldoc.toxml()
这些值将被替换
<text id="mytest" inkscape:label="#myvar" sodipodi:linespacing="125%" style="font-style:normal;font-weight:normal;font-size:60px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;image-rendering:auto" x="262.91638" xml:space="preserve" y="86.339157"><desc id="desc4150">The test object to replace with a var</desc><title id="title4148">myobj</title> <tspan id="tspan4804" sodipodi:role="line" style="fill:#ffffff" x="262.91638" y="86.339157">hello world</tspan></text>
一个可能的解决方案使用以
以下脚本:
有很多可以改进的地方,但是对于那些希望使用YAML在SVG文档中进行基本的变量替换的人来说,这应该是一个好的开始。
没有执行卫生措施,因此在运行此脚本之前确保输入是干净的。
#!/bin/bash COMMAND="inkscape -z" DEFINITIONS=../variables.yaml # Parses YAML files. # # Courtesy of https://stackoverflow.com/a/21189044/59087 function parse_yaml { local prefix=$2 local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') sed -ne "s|^\($s\):|\1|" \ -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \ -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | awk -F$fs '{ indent = length($1)/2; vname[indent] = $2; for (i in vname) {if (i > indent) {delete vname[i]}} if (length($3) > 0) { vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")} printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3); } }' } # Load variable definitions into this environment. eval $(parse_yaml $DEFINITIONS ) for i in *.svg; do INPUT=$i OUTPUT=$i # Replace strings in the file with values from the variable definitions. REPLACE_INPUT=tmp-$INPUT echo "Converting $INPUT..." # Subsitute if there's at least one match. if grep -q -o -m 1 -h \${.*} $INPUT; then cp $INPUT $REPLACE_INPUT # Loop over all the definitions in the file. for svgVar in $(grep -oh \${.*} $INPUT); do # Strip off ${} to get the variable name and then the value. varName=${svgVar:2:-1} varValue=${!varName} # Substitute the variable name for its value. rpl -fi "$svgVar" "$varValue" $REPLACE_INPUT > /dev/null 2>&1 done INPUT=$REPLACE_INPUT fi $COMMAND $INPUT -A m_k_i_v_$OUTPUT.pdf rm -f $REPLACE_INPUT done
通过执行一般搜索并替换SVG文档,脚本不需要维护。 另外,变量可以在文件中的任何地方定义,不仅在text
块内。
我看到的一种方法是使用Jinja模板在将其转换为PDF之前自定义Postscript文件。
你可以使用相同的方法。
把你的SVG文本文件作为Jinja模板,并把你的变量放在YAML中。
使用Python加载Jinja模板,然后应用在YAML文件中找到的变量