Inkscape scripting: làm thế nào để hiển thị / ẩn một lớp và xuất?


8

Tôi có một phim hoạt hình với nhiều lớp; Trong số các lớp đó, tôi có một lớp tiếng Đức và tiếng Anh. Họ có văn bản trong ngôn ngữ tương ứng của họ. Ý tưởng là để ẩn lớp tiếng Đức và hiển thị lớp tiếng Anh và xuất dưới dạng phim hoạt hình tiếng Anh hoặc ẩn lớp tiếng Anh và hiển thị lớp tiếng Đức cho phiên bản tiếng Đức của phim hoạt hình. Tôi muốn kịch bản xuất khẩu.

Đây là một phần của tệp SVG của tôi:

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

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

Tôi đã xem /programming/9652573/inkscape-command-line-programming và đã thử lệnh này (và rất nhiều biến thể cho nó):

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

Nhưng tôi tiếp tục nhận được văn bản tiếng Anh, có lẽ bởi vì khi tôi lưu tệp, lớp tiếng Anh có thể nhìn thấy và lớp tiếng Đức thì không.

Tôi cũng đã thử chọn các lớp theo ID của chúng (trong mã ở trên lớp 3 và lớp 4, tương ứng) và chọn các <text>phần tử thực tế ; Tôi đã thử kết hợp nhiều động từ Inkscape. Nhưng cũng không có may mắn.

Làm cách nào tôi có thể kịch bản xuất này, ẩn hoặc hiển thị lớp ngôn ngữ khi cần? Tôi có thể làm điều này với các động từ Inkscape hay tôi nên làm việc với XML và thử đặt thuộc tính style thành display: inline hoặc display: none?

Câu trả lời:


3

Ok, tôi đã loay hoay với các mô-đun phân tích cú pháp XML khác nhau và kết thúc với đoạn mã sau.

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

Điều này giải quyết vấn đề của tôi. Hy vọng nó cũng hữu ích cho người khác.


1
@StephenEglen Trên thực tế, đây là lỗi ... bạn không thể đặt kiểu để display:...làm cho nó bị hỏng nếu bạn đã có các thuộc tính kiểu khác như độ mờ đục. Tôi đã cập nhật câu trả lời.
Robert

Cảm ơn. Bạn có nghĩa là đôi khi mục "style" cho lớp có thể chứa nhiều thuộc tính? trong trường hợp nào chúng ta nên tìm kiếm / thay thế display: inline <-> display: inline?
Stephen Eglen

1
@StephenEglen Vâng, chính xác. Tôi nhận thấy nó với độ mờ đục, nhưng có lẽ cũng có thể có những người khác. Do đó, regex chỉ thay thế màn hình: ... và để mọi thứ khác như cũ.
Robert

2

Tôi biết là hơi muộn một chút nhưng tôi đã tìm thấy Dự án Github ẩn-latyer-svg này sử dụng tập lệnh python để tạo các tệp mới với các lớp nhất định được hiển thị và ẩn dựa trên nút xml mà bạn tạo trên đòn bẩy lớp.

Tốt nhất, Christoph


2

Về lý do tại sao kiểm tra dòng lệnh không hoạt động, tôi tin rằng câu trả lời là trước tiên bạn cần chọn một mục trong lớp (chứ không phải chính lớp đó) để "ở" lớp. Sau đó, động từ đúng sẽ là LayerToggleHide. (Không chắc động từ này có sẵn khi câu hỏi này được hỏi hay không.) Và, vâng, các đối tượng chỉ có thể được chọn bằng ID chứ không phải tên.

Hơn nữa, vì không có động từ LayerHide và LayerShow (tại sao?), Để kịch bản đáng tin cậy trước tiên bạn cần sử dụng LayerHideAllhoặc LayerShowAllđặt tất cả các lớp theo cách này hay cách khác trước khi sử dụngLayerToggleHide để đạt được kết quả cuối cùng.

Tôi chưa thử tuyến đường lệnh này vì vậy tôi không thể hiển thị giải pháp làm việc dứt khoát. Thay vào đó, sau khi suy nghĩ về lộ trình dòng lệnh rất nhiều và nhận ra cần bao nhiêu kịch bản để làm cho nó hoạt động theo nhu cầu của tôi, tôi quyết định chỉ viết toàn bộ và viết một phần mở rộng Inskape đáp ứng các nhu cầu như thế này. Tôi gọi nó là Bộ kết hợp lớp SLiCk và nó có thể được tìm thấy ở đây: https://github.com/juanitogan/slick

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.