2015-01-01 2 views
1

Этот точечный источникКак я могу сделать DOT правильно обрабатывать UTF-8 PostScript и иметь несколько графиков/страниц?

graph A 
{ 
    a; 
} 
graph B 
{ 
    "Enûma Eliš"; 
} 

при компиляции с dot -Tps формирует эту ошибку

Внимание: UTF-8, вход использует не Latin1 символы, которые не могут быть обработаны с помощью этого драйвера PostScript

Я могу исправить проблему UTF-8, передав -Tps:cairo, но тогда на выходе будет только граф A - он усечен на одну страницу. То же самое происходит с -Tpdf. В моей установке нет других драйверов postscript.

Я мог бы разделить графики на отдельные файлы и объединить их позже, но я бы предпочел не делать этого. Есть ли способ иметь правильную обработку UTF-8 и вывод нескольких страниц?

+0

Вы можете попробовать 'blockdiag', основанный на синтаксисе DOT, но для блок-диаграмм. Он закодирован для правильной обработки UTF-8, но не для нескольких диаграмм в одном источнике. Однако группы могут сделать трюк. Выход SVG позволяет создать отдельный файл изображения для каждой группы. 'pip install blockdiag', чтобы попробовать. –

ответ

0

По-видимому, драйвер PS dot не может обрабатывать другие кодировки, чем старый ISO8859-1. Я думаю, что он не может изменить шрифты.

Одна вещь, которую вы можете сделать, это запустить фильтр для изменения вывода PostScript dot. Следующая программа 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; 
0

Создание PDF или SVG может обойти проблему кодирования тоже.

dot -Tpdf chs.dot > chs.pdf 

// or 

dot -Tsvg chs.dot > chs.svg