Script Inkscape: comment afficher / masquer un calque et exporter?

8

J'ai un dessin animé avec plusieurs couches; parmi ces couches, j'ai une couche allemande et une couche anglaise. Ils ont le texte dans leurs langues respectives. L'idée est de masquer le calque allemand et d'afficher le calque anglais et d'exporter en tant que dessin animé anglais ou de masquer le calque anglais et d'afficher le calque allemand pour une version allemande du dessin animé. Je voudrais scénariser cette exportation.

Voici une partie de mon fichier 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>
         <!-- ... -->

et

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

J'ai vu /programming/9652573/inkscape-command-line-programming et essayé cette commande (et de nombreuses variantes):

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

Mais je continue à recevoir le texte anglais, probablement parce que lorsque j'ai enregistré le fichier, le calque anglais était visible et le calque allemand ne l'était pas.

J'ai également essayé de sélectionner les couches par leurs identifiants (dans le code au-dessus de layer3 et layer4, respectivement), et de sélectionner les <text>éléments réels ; J'ai essayé différentes combinaisons de verbes Inkscape. Mais pas de chance non plus.

Comment puis-je créer un script pour cette exportation en masquant ou en affichant la couche de langue selon les besoins? Puis-je le faire avec les verbes Inkscape ou dois-je travailler avec le XML et essayer de définir l'attribut style pour afficher: inline ou display: none?

Robert
la source

Réponses:

3

Ok, je me suis amusé avec divers modules d'analyse XML et je me suis retrouvé avec le code suivant.

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

Cela résout mon problème. J'espère que cela sera également utile à quelqu'un d'autre.

Robert
la source
1
@StephenEglen En fait, c'est un buggy ... vous ne pouvez pas simplement définir le style pour display:...que cela se brise si vous avez déjà d'autres attributs de style comme l'opacité. J'ai mis à jour la réponse.
Robert
Merci. Voulez-vous dire que parfois l'élément "style" du calque peut contenir plusieurs attributs? dans ce cas, nous devons rechercher / remplacer display: inline <--> display: inline en conséquence?
Stephen Eglen
1
@StephenEglen Oui, exactement. Je l'ai remarqué avec opacité, mais il peut aussi y en avoir d'autres. D'où l'expression régulière pour remplacer uniquement l'affichage: ... et laisser tout le reste tel quel.
Robert
2

Je sais qu'il est un peu tard mais j'ai trouvé ce projet Github hide-latyer-svg qui utilise un script python pour créer de nouveaux fichiers avec certaines couches affichées et masquées sur la base d'un nœud xml que vous créez sur le levier de couche.

Cordialement, Christoph

Christoph
la source
2

Quant à savoir pourquoi les tests en ligne de commande ne fonctionnaient pas, je pense que la réponse est que vous devez d'abord sélectionner un élément dans le calque (et non le calque lui-même) pour être "dans" le calque. Après cela, le verbe correct serait LayerToggleHide. (Je ne sais pas si ce verbe était disponible lorsque cette question a été posée.) Et, oui, les objets ne peuvent être sélectionnés que par ID et non par nom.

De plus, comme il n'y a pas de verbes LayerHide et LayerShow (pourquoi?), Pour créer un script de manière fiable, vous devez d'abord utiliser LayerHideAllou LayerShowAlldéfinir toutes les couches d'une manière ou d'une autre avant de les utiliser LayerToggleHidepour obtenir le résultat final.

Je n'ai pas testé cette route de ligne de commande, je ne peux donc pas montrer de solution de travail définitive. Au lieu de cela, après avoir longuement réfléchi à la route de ligne de commande et réalisé combien de scripts il faudrait pour que cela fonctionne pour mes besoins, j'ai décidé de me lancer et d'écrire une extension Inskape qui gère des besoins comme celui-ci. Je l'appelle le SLiCk Layer Combinator et il peut être trouvé ici: https://github.com/juanitogan/slick

juanitogan
la source