Scripting Inkscape: come mostrare / nascondere un layer ed esportare?


8

Ho un cartone animato con più livelli; tra questi livelli ho un livello tedesco e uno inglese. Hanno il testo nelle rispettive lingue. L'idea è quella di nascondere il livello tedesco e mostrare il livello inglese ed esportarlo come un fumetto inglese o nascondere il livello inglese e mostrare il livello tedesco per una versione tedesca del fumetto. Vorrei scrivere quell'esportazione.

Ecco una parte del mio file SVG:

  <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>
         <!-- ... -->

e

 <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> 
           <!-- ... -->

Ho visto /programming/9652573/inkscape-command-line-programming e ho provato questo comando (e molte varianti):

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

Ma continuo a ricevere il testo inglese, probabilmente perché quando ho salvato il file, il livello inglese era visibile e il livello tedesco no.

Ho anche provato a selezionare i layer in base ai loro ID (rispettivamente nel codice sopra layer3 e layer4) e selezionando gli <text>elementi effettivi ; Ho provato varie combinazioni di verbi Inkscape. Ma neanche fortuna.

Come posso scrivere questa esportazione, nascondendo o mostrando il livello linguistico secondo necessità? Posso farlo con i verbi di Inkscape o devo lavorare con l'XML e provare a impostare l'attributo di stile su display: inline o display: none?

Risposte:


3

Ok, ho fatto casino con vari moduli di analisi XML e ho finito con il seguente codice.

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);

Questo risolve il mio problema. Speriamo che sia utile anche a qualcun altro.


1
@StephenEglen In realtà, questo è un bug ... non puoi semplicemente impostare lo stile display:...perché questo si spezzerà se hai già altri attributi di stile come l'opacità. Ho aggiornato la risposta.
Robert,

Grazie. Vuoi dire che a volte l'elemento "stile" per il livello può contenere più attributi? nel qual caso dovremmo cercare / sostituire display: inline <--> display: inline di conseguenza?
Stephen Eglen,

1
@StephenEglen Sì, esattamente. L'ho notato con opacità, ma probabilmente ci possono essere anche altri. Da qui il regex per sostituire solo il display: ... e lasciare tutto il resto com'è.
Robert,

2

So che è un po 'tardi, ma ho trovato questo progetto Github hide-latyer-svg che utilizza uno script Python per creare nuovi file con alcuni livelli mostrati e nascosti sulla base di un nodo XML creato sulla leva del livello.

Meglio, Christoph


2

Per quanto riguarda il motivo per cui il test da riga di comando non funzionava, credo che la risposta sia che devi prima selezionare un elemento nel livello (e non il livello stesso) per essere "nel" livello. Successivamente, il verbo corretto sarebbe LayerToggleHide. (Non sono sicuro che questo verbo fosse disponibile quando è stata posta questa domanda.) E, sì, gli oggetti possono essere selezionati solo per ID e non per nome.

Inoltre, poiché non ci sono verbi LayerHide e LayerShow (perché?), Per eseguire lo script in modo affidabile dovresti prima usare LayerHideAllo LayerShowAllimpostare tutti i livelli in un modo o nell'altro prima di usarli LayerToggleHideper ottenere il risultato finale.

Non ho testato questo percorso da riga di comando, quindi non posso mostrare una soluzione operativa definitiva. Invece, dopo aver riflettuto molto sulla route della riga di comando e aver realizzato quanto scripting sarebbe necessario per farlo funzionare per le mie esigenze, ho deciso di andare all-in e scrivere un'estensione Inskape che gestisca le esigenze in questo modo. Lo chiamo SLiCk Layer Combinator e può essere trovato qui: https://github.com/juanitogan/slick

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.