Script Inkscape: cara menampilkan / menyembunyikan layer dan mengekspor?

8

Saya punya kartun dengan banyak lapisan; di antara lapisan-lapisan itu saya memiliki lapisan Jerman dan Inggris. Mereka memiliki teks dalam bahasa masing-masing. Idenya adalah untuk menyembunyikan lapisan Jerman dan menunjukkan lapisan bahasa Inggris dan ekspor sebagai kartun bahasa Inggris atau untuk menyembunyikan lapisan bahasa Inggris dan menunjukkan lapisan Jerman untuk versi Jerman dari kartun. Saya ingin skrip ekspor itu.

Ini adalah bagian dari file SVG saya:

  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="English"
     style="display:inline">
     <text
         xml:space="preserve"  
         <!-- .... --> 
         id="text3255">
         <tspan id="tspan3257">I don't think</tspan>
         <!-- ... -->

dan

 <g
     inkscape:groupmode="layer"
     id="layer4"
     inkscape:label="German"
     style="display:none"> 
     <text
           xml:space="preserve"
           <!-- ... -->
           id="text3284">   
           <tspan id="tspan3286">Ich glaube nicht,</tspan> 
           <!-- ... -->

Saya telah melihat /programming/9652573/inkscape-command-line-programming dan mencoba perintah ini (dan banyak variasi untuk itu):

inkscape -z --file=cartoon.svg --select=English --verb=LayerHideAll --select=German --verb=LayerShowAll --export-png=cartoon-de.png --export-area-drawing

Tapi saya terus mendapatkan teks bahasa Inggris, mungkin karena ketika saya menyimpan file, lapisan bahasa Inggris terlihat dan lapisan Jerman tidak.

Saya juga telah mencoba memilih lapisan dengan ID mereka (dalam kode di atas layer3 dan layer4, masing-masing), dan memilih <text>elemen yang sebenarnya ; Saya sudah mencoba berbagai kombinasi kata kerja Inkscape. Tapi tidak berhasil juga.

Bagaimana saya bisa skrip ekspor ini, menyembunyikan atau menampilkan lapisan bahasa sesuai kebutuhan? Dapatkah saya melakukan ini dengan kata kerja Inkscape atau haruskah saya bekerja dengan XML dan mencoba mengatur atribut style untuk ditampilkan: inline atau display: none?

Robert
sumber

Jawaban:

3

Ok, saya main-main dengan berbagai modul parsing XML dan berakhir dengan kode berikut.

use XML::LibXML;
use XML::LibXML::XPathContext;

my $xml = XML::LibXML->load_xml(location => $file);
my $xpath = XML::LibXML::XPathContext->new($xml);  
$xpath->registerNs("defNs", 'http://www.w3.org/2000/svg');
foreach my $layer ($xpath->findnodes('/defNs:svg/defNs:g[@inkscape:groupmode="layer"])) {
    my $label = $layer->{'inkscape:label'};
    foreach my $otherLang (@languages) {
        if ($label =~ m/$other_lang$/) {
            $layer->{'style'} =~ s{\bdisplay:inline\b}{display:none};
        }
    }
    if ($layerLang eq $lang) {
        $layer->{'style'} =~ s{\bdisplay:none\b}{display:inline};
    }
}
$xml->toFile($tempFileName);

Ini menyelesaikan masalah saya. Semoga bermanfaat bagi orang lain juga.

Robert
sumber
1
@StephenEglen Sebenarnya, ini buggy ... Anda tidak bisa hanya mengatur gaya yang display:...menyebabkan ini akan rusak jika Anda sudah memiliki atribut gaya lain seperti opacity. Saya sudah memperbarui jawabannya.
Robert
Terima kasih. Apakah maksud Anda bahwa kadang-kadang item "style" untuk layer dapat berisi banyak atribut? dalam hal apa kita harus mencari / mengganti tampilan: inline <--> display: sesuai?
Stephen Eglen
1
@StephenEglen Ya, tepatnya. Saya perhatikan dengan opacity, tetapi mungkin ada yang lain juga. Oleh karena itu regex hanya untuk mengganti tampilan: ... dan biarkan semuanya seperti apa adanya.
Robert
2

Saya tahu ini agak terlambat, tetapi saya menemukan proyek Github hide-latyer-svg yang menggunakan skrip python untuk membuat file baru dengan lapisan tertentu yang ditampilkan dan disembunyikan berdasarkan node xml yang Anda buat pada tuas layer.

Terbaik, Christoph

Christoph
sumber
2

Mengenai mengapa pengujian baris perintah tidak berfungsi, saya yakin jawabannya adalah Anda pertama-tama harus memilih item pada layer (dan bukan layer itu sendiri) untuk menjadi "in" layer. Setelah itu, kata kerja yang benar adalah LayerToggleHide. (Tidak yakin apakah kata kerja ini tersedia saat pertanyaan ini diajukan.) Dan, ya, objek hanya dapat dipilih dengan ID, dan bukan nama.

Lebih jauh, karena tidak ada kata kerja LayerHide dan LayerShow (mengapa?), Untuk dapat melakukan skrip dengan andal ini, Anda harus terlebih dahulu menggunakan LayerHideAllatau LayerShowAllmengatur semua layer dengan satu cara atau yang lain sebelum menggunakan LayerToggleHideuntuk mencapai hasil akhir.

Saya belum menguji rute baris perintah ini jadi saya tidak bisa menunjukkan solusi yang pasti. Alih-alih, setelah memikirkan rute command-line banyak dan menyadari berapa banyak scripting yang diperlukan untuk membuatnya bekerja untuk kebutuhan saya, saya memutuskan untuk hanya melakukan semua dan menulis ekstensi Inskape yang menangani kebutuhan seperti ini. Saya menyebutnya Combiator Lapisan SLiCk dan dapat ditemukan di sini: https://github.com/juanitogan/slick

juanitogan
sumber