如何使DOT正确地将UTF-8处理为PostScript并具有多个图形/页面?

如何使DOT正确地将UTF-8处理为PostScript并具有多个图形/页面?,utf-8,graphviz,postscript,dot,Utf 8,Graphviz,Postscript,Dot,这个点源 graph A { a; } graph B { "Enûma Eliš"; } 使用dot-Tps编译时会生成此错误 警告:UTF-8输入使用此PostScript驱动程序无法处理的非拉丁字符 我可以通过传递-Tps:cairo来修复UTF-8问题,但是输出中只有图形A——它被截断为一个页面。同样的情况也发生在-Tpdf上。我的安装中没有其他postscript驱动程序可用 我可以将这些图拆分成单独的文件,然后将它们连接起来,但我不希望这样。有没有一种方法可以实现正

这个点源

graph A
{
    a;
}
graph B
{
    "Enûma Eliš";
}
使用
dot-Tps
编译时会生成此错误

警告:UTF-8输入使用此PostScript驱动程序无法处理的非拉丁字符

我可以通过传递
-Tps:cairo
来修复UTF-8问题,但是输出中只有图形A——它被截断为一个页面。同样的情况也发生在
-Tpdf
上。我的安装中没有其他postscript驱动程序可用


我可以将这些图拆分成单独的文件,然后将它们连接起来,但我不希望这样。有没有一种方法可以实现正确的UTF-8处理和多页输出?

显然,
dot
PS驱动程序无法处理旧的ISO8859-1以外的其他编码。我认为它也不能改变字体

您可以做的一件事是运行一个过滤器来更改
dot
的PostScript输出。下面的Perl程序就是这样做的,它是对我的一些代码的改编。它将编码从UTF-8更改为修改的ISO编码,用额外字符替换未使用的字符

当然,输出仍然取决于具有字符的字体。由于
dot
(我想)只使用默认的PostScript字体,所以任何超出“标准拉丁语”的内容都是不可能的

它与Ghostscript或任何定义
AdobeGlyphList
的解释器一起工作

过滤器应按以下方式使用:

dot -Tps graph.dot | perl reenc.pl > output.ps
这是:

#!/usr/bin/perl

use strict;
use warnings;
use open qw(:std :utf8);

my $ps = do { local $/; <STDIN> };
my %high;
my %in_use;
foreach my $char (split //, $ps) {
    my $code = (unpack("C", $char))[0];
    if ($code > 127) {
        $high{$char} = $code;
        if ($code < 256) {
            $in_use{$code} = 1;
        }
    }
}
my %repl;
my $i = 128;
foreach my $char (keys %high) {
    if ($in_use{$high{$char}}) {
        $ps =~ s/$char/sprintf("\\%03o", $high{$char})/ge;
        next;
    }
    while ($in_use{$i}) { $i++; }
    $repl{$i} = $high{$char};
    $ps =~ s/$char/sprintf("\\%03o", $i)/ge;
    $i++;
}
my $psprocs = <<"EOPS";
/EncReplacements <<
  @{[ join(" ", %repl) ]}
>> def
/RevList AdobeGlyphList length dict dup begin
  AdobeGlyphList { exch def } forall
end def
% code -- (uniXXXX)
/uniX { 16 6 string cvrs dup length 7 exch sub exch
  (uni0000) 7 string copy dup  4 2 roll putinterval } def
% font code -- glyphname
/unitoname { dup RevList exch known
  { RevList exch get }
  { uniX cvn } ifelse
  exch /CharStrings get 1 index known not
  { pop /.notdef } if
} def
/chg-enc { dup length array copy EncReplacements
  { currentdict exch unitoname 2 index 3 1 roll put } forall
} def
EOPS

$ps =~ s{/Encoding EncodingVector def}{/Encoding EncodingVector chg-enc def};
$ps =~ s/(%%BeginProlog)/$1\n$psprocs/;

print $ps;
#/usr/bin/perl
严格使用;
使用警告;
使用开放式qw(:标准:utf8);
my$ps=do{local$/;};
我的百分比很高;
我的%在使用中;
foreach my$char(拆分/,$ps){
我的$code=(解包(“C”,$char))[0];
如果($code>127){
$high{$char}=$code;
如果($code<256){
$in_use{$code}=1;
}
}
}
我的%repl;
我的$i=128;
foreach my$char(键%high){
if($in_use{$high{$char}}){
$ps=~s/$char/sprintf(\\%03o),$high{$char})/ge;
下一个
}
而($使用{$i}){$i++;}
$repl{$i}=$high{$char};
$ps=~s/$char/sprintf(\\%03o),$i)/ge;
$i++;
}

我的$psprocs=生成PDF或SVG也可以绕过编码问题

dot  -Tpdf  chs.dot > chs.pdf

// or

dot  -Tsvg  chs.dot > chs.svg

您可以尝试基于点语法的
blockdiag
,但不适用于方框图。它的编码可以正确地处理UTF-8,但不能在同一个源中处理多个图表。不过,小组可能会做到这一点。SVG输出允许每个组有一个单独的图像文件<代码>pip安装blockdiag
以试用它。