Заранее предупреждаю - всё тут немного сумбурно...
Графический редактор Inkscape (если пользователю и Inkscape повезёт с установкой) может запускать Python-скрипты рисующие всякие линии, круги, прямоугольники и даже текст.
Текст плагина для поиска совпадений в двух текстовых файлах (textfa.txt и textfb.txt):
#!/usr/bin/env python # coding=utf-8 # импортируем графическую магию и прочую требуху import inkex from inkex import TextElement, Group, Layer, Tspan, PathElement FntSz = 3.175 # будем выводить текст - так вот это размер текста FntHt = 1.6 # расстояние между строками FilenameA = '/home/user_name/textfa.txt' # файл первый FilenameB = '/home/user_name/textfb.txt' # файл второй sxA = 0 # координаты для вывода текста из первого файла syA = 0 sxB = 1000 # координаты для вывода текста из второго файла syB = 0 class Comparator(inkex.EffectExtension): # ну что сказать... #--#--#-----------I want to distincs the exact "SourceText" in this group somehow ------------------------------- def effect(self): # этот метод класса Comparator запускается из Инкскейпа ar23A = ['nothing','here'] # подготавливаем массив для чтения из первого файла ar23B = ['nothing','here'] # подготавливаем массив для чтения из второго файла Layer = self.PrepareThelayer('Habr23') # приготавливаем пустой Графич_слой для рисования with open(FilenameA, 'r') as file: BigTxA = file.read() # читаем текст из первого файла ar23A = BigTxA.split('\n') # разбиваем текст в массив на строки self.drawText(Layer, sxA, syA, ar23A) # выводим массив строк в Графич_файл with open(FilenameB, 'r') as file: BigTxB = file.read() # читаем текст из второго файла ar23B = BigTxB.split('\n') # разбиваем текст в массив на строки self.drawText(Layer, sxB, syB, ar23B) # выводим массив строк в Графич_файл for nA in range(0, len(ar23A)): # перебираем оба массива со строками в поисках... for nB in range(0, len(ar23B)): if (ar23A[nA] == ar23B[nB]): # ...в поисках одинаковых строк if(len(ar23A[nA]) > 1): # избегаем пустых строк yA = nA * FntHt * FntSz # подготавливаем координаты для линии между совпадающими строками yB = nB * FntHt * FntSz self.drawLine(Layer, sxA+200,syA+yA, sxB, syB+yB) # рисуем линию между совпадающими строками #--#--#--------------------------------------------------------------- def drawText(self, Layer, x, y, Tmass): # начинаем церемонию создания текст_блока elem = TextElement(x=str(x), y=str(y)) elem.style = { # задаём внешний вид нашего текст_блока 'font-size':str(FntSz), # размер шрифта 'line-height':str(FntHt), # расстояние между строк 'font-family':'courier', # и т.д. '-inkscape-font-specification':'courier', 'stroke-width':'0.264583'} # ещё немного церемониальных заклинаний elem.set('xml:space',"preserve") # и начинаем построчно выводить текст for n in range(0, len(Tmass)): tx23 = Tspan(Tmass[n]) # создаем строку tx23.set('sodipodi:role',"line") # магия... tx23.set('x' ,x) tx23.set('y' , y + (n * FntHt * FntSz)) elem.add(tx23) # присоединяя каждую строку к текстовому блоку # выводим текстовый блок в Графич_слой (то есть выводим на экран) Layer.add(elem) # выводим созданный текстовый блок на экран #--#--#--------------------------------------------------------------- def PrepareThelayer(self, Lname): # сперва попробуем найти Графич_слой с желаемым имменем svg = self.document.getroot() # ищем в документе for g in svg.xpath('//svg:g', namespaces=inkex.NSS): if g.get(inkex.addNS('groupmode', 'inkscape')) == 'layer': t23 = g.get(inkex.addNS('label', 'inkscape')) if (t23 == Lname): # совпадает ли имя Графич_слоя? for child in g: # если это желаемый слой g.remove(child) # очищаем его содержимое return g # Графич_слой с желаемым именем мы не нашли # поэтому создаём новый Графич_слой с желаемым именем newlayer=self.svg.add(Layer.new(Lname)) return newlayer #--#--#--------------------------------------------------------------- def drawLine(self, layer, x0,y0, x99, y99): # рисуем линию соблюдая все церемонии Инкскейпа # сперва создаем линию... line = PathElement() line.set('fill','none') line.set('stroke',"#4FF") # цвет line.set('stroke-width','0.8') # толщину line.set('d','M %f %f %f %f' % (x0, y0, x99, y99)) # координаты # теперь выводим линию в Графич_слой (то есть выводим на экран) layer.append(line) # Питонская ООП-магия if __name__ == '__main__': Comparator().run()
Теперь будут некоторые пояснения. Пользователь редактора Inkscape может запускать Python-скрипты через меню.

В верхнем меню графического редактора Inkscape помимо всяческих File, Edit, View – есть волшебное подменю Extensions (Расширения) при нажатии на которое выводится список уже имеющихся в редакторе и готовых к запуску Python-скриптов.
...Создатели Inkscape предписывают Linux-поклоннику держать его самодельные Python-скрипты в районе “домашней” папки “/home/user_name/.config/inkscape/extensions/” (для Windows-пользователей там что-то своё).
В этой же папке следует расположить файл с расширением *.inx
В моём случае это был файл "proba01.inx"
<?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> <_name>proba-1</_name> <id>something12345</id> <dependency type="executable" location="extensions">proba01.py</dependency> <effect> <object-type>all</object-type> </effect> <script> <command reldir="extensions" interpreter="python">proba01.py</command> </script> </inkscape-extension>
Я разместил в папке “/home/user_name/.config/inkscape/extensions/” два вышеупомянутых файла "proba01.py" и "proba01.inx", перезапустил Inkscape и с радостью обнаружил в подменю “Extensions” пункт “proba-1” который запускал скрипт “proba01.py”

И вот результат работы скрипта:

Выгдядит достаточно наукообразно.
Я планирую улучшить этот скрипт. С радостью выслушаю мнения.
(где .. тут кнопка "Сохранить" ?)
