Weryfikacja terminologii za pomocą xbench

Weryfikacja terminologii to jeden z ważnych aspektów kontroli jakości tłumaczenia. Terminologię przygotowuje się pod kątem konkretnego klienta. Na przykład dla większości odbiorców właściwym tłumaczeniem terminu „command” jest „polecenie”, ale Duży Niebieski konsekwentnie trzyma się wersji „komenda”. W obiegu są też dwa różne tłumaczenia terminu „instance”. Dla niektórych jest to po prostu „instancja”, ale inni zdecydowanie wolą „wystąpienie”. Przed oddaniem projektu koniecznie należy sprawdzić zastosowaną w nim terminologię.

Niektóre programy dla tłumaczy są wyposażone w narzędzia do kontroli terminologii. Na przykład w Passolo istnieje grupa opcji ukrywająca się pod nazwą Terminology, a w Alchemy Catalyst jest coś, co nazywa się Validate Expert, jednak oba te narzędzia są niespecjalnie wygodne w użyciu. Najlepiej pod tym względem wygląda Trados Studio, gdzie jest blok opcji Terminology Verifier, który pozwala zdefiniować ustawienia domyślne na poziomie całego programu, a na poziomie konkretnego projektu wprowadzić pewne modyfikacje. Terminologię można też oczywiście sprawdzić za pomocą xbench (opcja Key Term Mismatch w grupie Content), ale wszystko to zawodzi w przypadku języka polskiego, w którym słowa się odmieniają, przez co wymienione powyżej opcje generują w większości tzw. „false positives”.

W kontekście weryfikacji terminologii usłyszałem kiedyś o próbie rozwiązania problemu odmiany słów przez zastosowanie wyrażeń regularnych. Rzeczywiście jest to możliwe, ale niestety bardzo pracochłonne. Każde słowo używane w testach terminologii należy przekształcić w odpowiednie wyrażenie regularne, co, jeśli jest wykonywane ręcznie, w przypadku większych list terminów staje się niepraktyczne i z tego względu nie jest stosowane. Przyszło mi wtedy do głowy, że można ten proces zautomatyzować, a najlepiej nadaje się do tego xbench rozszerzony o odpowiednią wtyczkę. (Kilka słów o xbench napisałem w tym artykule na temat innej wtyczki mojego autorstwa). Opracowałem więc taką wtyczkę, a właściwie dwie wtyczki: jedną do weryfikacji tłumaczeń z języka angielskiego na polski (można ją pobrać stąd), a drugą do tłumaczeń z języka niemieckiego na polski (jest dostępna tutaj). Wersje są dwie, ponieważ oprócz odmiany języka polskiego uwzględniłem także odmianę języka źródłowego, a między językami angielskim i niemieckim występują oczywiście różnice. Żeby wtyczki działały, należy skopiować pobrane biblioteki DLL do tego samego katalogu, w którym znajduje się program xbench.exe (zwykle jest to katalog C:/Program Files (x86)/ApSIC/Xbench). Po skopiowaniu plików wtyczek do odpowiedniego katalogu i uruchomieniu programu xbench na karcie QA będą widoczne opcje przedstawione na poniższej ilustracji.

CheckList-01.png

Działanie wtyczek polega na utworzeniu pliku tekstowego w formacie „czeklisty” xbench. Plik ten można wczytać do xbench w oknie dialogowym Checklist Management wywoływanym za pomocą opcji Tools > Manage Checklists. W tym oknie dialogowym należy następnie wybrać opcję Checklist > Add > Local. Wczytany w ten sposób plik pojawi się na liście List of Checks w grupie testów Chcecklists. Jeśli w tym momencie bieżący projekt zostanie zapisany, wczytana „czeklista” stanie się integralnym jego elementem. Oznacza to, że po ponownym wczytaniu tego samego projektu „czeklista” ta będzie w dalszym ciągu znajdować się na liście List of Checks. Proces tworzenia „czeklisty” nie jest specjalnie skomplikowany, a jego zasadnicze etapy to:

  1. Przygotowanie pliku z terminologią
  2. Wczytanie pliku z terminologią do xbench
  3. Uruchomienie narzędzia Generate Checklist
  4. Ewentualna korekta niektórych terminów

Przygotowanie pliku z terminologią

Ten etap przebiega poza programem xbench. Plik z terminologią może mieć dowolny format, który jest rozpoznawany przez xbench, czyli Tab-delimited Text File, XLIFF File, TMX Memory itd. Niestety klienci przygotowują terminologię najczęściej w Excelu (z jakiegoś powodu jest to dla nich najwygodniejsze). Tłumacz ma potem do wyboru dwie możliwości: albo przez cały projekt mocuje się z Excelem, tracąc na to cenny czas, albo na początku pracy nad projektem samodzielnie przygotuje i wyeksportuje arkusz w formacie pliku .csv, który można wczytać do xbench (w xbench format ten nazywa się Tab-delimited Text File) i wygodnie później przeszukiwać. Aby nie było problemów z wczytywaniem, lepiej zmienić rozszerzenie nazwy pliku z .csv na .txt. Dla uproszczenia dalszego wywodu przygotowałem przykładowy słownik w formacie Tab-delimited Text File. Jego zawartość znajduje się poniżej:

website	witryna internetowa
area	obszar
on the fly	na bieżąco
string	ciąg znakowy
data store	magazyn danych
command	polecenie
string field	pole znakowe
snap	dociągnąć, dociąganie
geographic coordinate system 	układ współrzędnych geograficznych 
render	wyświetlanie, prezentowanie
renderer	moduł renderowania
client	aplikacja kliencka

Najważniejszą rzeczą, o której należy pamiętać, przygotowując słownik z terminologią, jest stosowanie przecinków lub średników do oddzielania tłumaczeń alternatywnych. Innych znaków interpunkcyjnych lepiej nie stosować, gdyż nie ma pewności, czy zostaną poprawnie obsłużone przez wtyczkę. Jeśli jednak tam się znajdą, po zakończeniu działania wtyczki terminy, w których występują przecinek, cudzysłów, znak procenta lub znak ampersand, zostają wypisane w postaci listy, aby ułatwić ewentualną korektę wygenerowanych wyrażeń regularnych.

Wczytanie pliku z terminologią do xbench

Wczytanie pliku z terminologią przebiega w sposób zupełnie normalny, należy tylko pamiętać, aby wczytany plik oznaczyć jako Ongoing translation. Można to zrobić na dwa sposoby: podczas definiowania właściwości wczytywanego pliku na karcie Properties w oknie dialogowym Add Files to Project albo już po wczytaniu w oknie Project Properties.

CheckList-02.png

To bardzo ważne, ponieważ wtyczka generowania „czeklisty” działa tak jak test kontroli jakości, a takie testy są w xbench wykonywane wyłącznie na plikach bieżącego tłumaczenia.

Uruchomienie narzędzia Generate Checklist

Aby rozpocząć generowanie „czeklisty”, należy zaznaczyć opcje przedstawione na poniższej ilustracji:

CheckList-03a.png CheckList-03b.png

Po kliknięciu zaznaczonego przycisku Check Ongoing Translation należy wybrać nazwę i położenie wyjściowego pliku „czeklisty”.

CheckList-04.png

Zakończenie działania wtyczki jest sygnalizowane komunikatem:

CheckList-05.png

Po kliknięciu przycisku OK zostaje wyświetlona lista terminów, które mogą wymagać korekty. W omawianym tu przykładzie lista ta wygląda tak:

CheckList-06.png

Ewentualna korekta niektórych terminów

Po zakończeniu działania wtyczki można wczytać wygenerowaną „czeklistę” do xbench. W tym celu należy wybrać opcję Tools > Manage Checklists, a następnie w oknie dialogowym Checklist Management opcję Checklist > Add > Local. Najlepiej zrobić to jeszcze wtedy, gdy na liście wyników kontroli jakości są wyświetlane terminy, które mogą wymagać modyfikacji. Zawartość wygenerowanej „czeklisty” jest następująca:

CheckList-07.png

Na ilustracji tej podkreśliłem terminy wymagające uwagi. Aby sprawdzić i ewentualnie skorygować wyrażenie regularne, należy dwukrotnie kliknąć odpowiednią pozycję na liście. Alternatywne możliwości tłumaczenia są w wyrażeniu regularnym reprezentowane za pomocą znaku pionowej kreski:

-"(wyświetl[:alpha:]*)|(prezent[óo]w[:alpha:]*)"

W tym przykładzie żadne zmiany nie są potrzebne, a kompletna „czeklista” to:

<?xml version="1.0" encoding="utf-8" ?>
<xbench-checklist version="1.0">
	<checklist name="Checklist: test">
		<check name="website = witryna internetowa">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<websit(e|es|ed|ing)+"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(witr[:alpha:]*[:space:]+internet[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="area = obszar">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<area(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"([óo]bsz[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="on the fly = na bieżąco">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<on(s|ed|ing)?[:space:]+<th(e|es|ed|ing)+[:space:]+<fl(y|ies|ied|ying)+"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(na[:alpha:]*[:space:]+bież[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="string = ciąg znakowy">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<string(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(ci[ąę][:alpha:]*[:space:]+znak[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="data store = magazyn danych">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<data(s|ed|ing)?[:space:]+<stor(e|es|ed|ing)+"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(magaz[:alpha:]*[:space:]+danyc[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="command = polecenie">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<command(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(p[óo]lec[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="string field = pole znakowe">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<string(s|ed|ing)?[:space:]+<field(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(p[óo]l[:alpha:]*[:space:]+znak[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="snap = dociągnąć, dociąganie">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<snap(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(d[óo]ci[ąę]gn[:alpha:]*)|(d[óo]ci[ąę]g[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="geographic coordinate system = układ współrzędnych geograficznych">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<geographic(s|ed|ing)?[:space:]+<coordinat(e|es|ed|ing)+[:space:]+<system(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(ukł[:alpha:]*[:space:]+wsp[óo]łrz[ąę]dnyc[:alpha:]*[:space:]+ge[óo]graficznyc[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="render = wyświetlanie, prezentowanie">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<render(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(wyświetl[:alpha:]*)|(prezent[óo]w[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="renderer = moduł renderowania">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<renderer(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(m[óo]d[:alpha:]*[:space:]+render[óo]w[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
		<check name="client = aplikacja kliencka">
			<term type="source" xml:space="preserve" powersearch="yes" searchmode="regexp">"<client(s|ed|ing)?"</term>
			<term type="target" xml:space="preserve" powersearch="yes" searchmode="regexp">-"(aplikac[:alpha:]*[:space:]+klienc[:alpha:]*)"</term>
			<description xml:space="preserve"></description>
			<timestamp></timestamp>
		</check>
	</checklist>
</xbench-checklist>

Wyrażenia regularne to potężne narzędzie, ale tutaj nie ma miejsca na ich omawianie. Dokumentację na różnym poziomie szczegółowości można bez trudu znaleźć w Internecie.

Wykorzystanie wygenerowanej czeklisty

Skuteczność „czeklisty” zawierającej wyrażenia regularne zaprezentuję na prostym, wymyślonym na poczekaniu tekście w języku angielskim i jego specjalnie przygotowanym tłumaczeniu.
Oryginał:

This command renders the geographic coordinate system in a client’s area. A report containing strings that represent data store contents is generated by the renderer on the fly.

Tłumaczenie:

Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej. Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

Aby porównać „czeklistę” zawierającą wyrażenia regularne z testem Key Term Mismatch w xbench przygotowałem dodatkowo plik z terminami kluczowymi dla tego tłumaczenia. Plik ten jest bliźniaczo podobny do cytowanego na początku przykładowego słownika. Jedyna różnica polega na tym, że rozbiłem wiersze z terminami zawierającymi po dwa alternatywne tłumaczenia na osobne wiersze z pojedynczym tłumaczeniem każdy. Najpierw wykonam test Key Term Mismatch, a po nim test z użyciem „czeklisty”.

Wczytuję do xbench plik zawierający powyższe przykładowe tłumaczenie, wygenerowaną wcześniej „czeklistę” o nazwie test.xbckl oraz plik z terminami kluczowymi. Ustawiam na karcie QA w xbench odpowiednie opcje, aby wykonana została jedynie standardowa kontrola zgodności słów kluczowych, i klikam przycisk Check Ongoing Translation. Po krótkiej chwili (gdyż wczytane pliki są bardzo małe) na liście wyników kontroli jakości pojawia się sześć wykrytych błędów:

CheckList-09.png

Wyniki, które cytuję poniżej, są dość jasne. Trzy z sześciu (czyli połowa) zasygnalizowanych błędów to false positives, a dodatkowo nie zostały wykryte niezgodności (string / ciąg znakowy), ponieważ termin „string” występuje w liczbie mnogiej, ani (render / wyświetlanie, prezentowanie), ponieważ termin „render” występuje w trzeciej osobie liczby pojedynczej.

KeyTerm Mismatch (area / obszar)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (client / aplikacja kliencka)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (command / polecenie)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (geographic coordinate system / układ współrzędnych geograficznych)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (data store / magazyn danych)
A report containing strings that represent data store contents is generated by the renderer on the fly.
Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

KeyTerm Mismatch (renderer / moduł renderowania)
A report containing strings that represent data store contents is generated by the renderer on the fly.
Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

Teraz zobaczę, jaki będzie wynik testu za pomocą „czeklisty”. Ustawiam na karcie QA w xbench odpowiednie opcje, klikam przycisk Check Ongoing Translation i ponownie po krótkiej chwili pojawia się lista wyników kontroli jakości. Tym razem błędów też jest sześć, ale innych:

CheckList-08.png

Ponieważ w testach z użyciem wyrażeń regularnych znalezione problemy nie są wyróżniane kolorem, wymienię je i omówię po kolei.

Project Checklist: Checklist: test/command = polecenie […]
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

W tekście nie występuje poprawne tłumaczenie terminu „command”, czyli „polecenie”.

Project Checklist: Checklist: test/geographic coordinate system = układ współrzędnych geograficznych […]
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

W tekście nie występuje poprawne tłumaczenie terminu „geographic coordinate system”. Kolejność słów w tłumaczeniu jest niewłaściwa.

Project Checklist: Checklist: test/render = wyświetlanie, prezentowanie […]
This command renders the geographic coordinate system in a client’s area.
Za pomocą tej komendy można renderować geograficzny układ współrzędnych w obszarze aplikacji klienckiej.

W tekście nie występuje poprawne tłumaczenie terminu „render”.

Project Checklist: Checklist: test/render = wyświetlanie, prezentowanie […]
A report containing strings that represent data store contents is generated by the renderer on the fly.
Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

W tekście nie występuje poprawne tłumaczenie terminu „render”. To niestety jest false positive, który wynika stąd, że słowo „render” jest jednocześnie łańcuchem początkowym słowa „renderer”.

Project Checklist: Checklist: test/renderer = moduł renderowania […]
A report containing strings that represent data store contents is generated by the renderer on the fly.
Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

W tekście nie występuje poprawne tłumaczenie terminu „renderer”. To już faktyczny błąd.

Project Checklist: Checklist: test/string = ciąg znakowy […]
A report containing strings that represent data store contents is generated by the renderer on the fly.
Renderer generuje na bieżąco raport zawierający łańcuchy reprezentujące zawartość magazynu danych.

W tekście nie występuje poprawne tłumaczenie terminu „string”.

Wykrytych zostało pięć błędów, a tylko jeden okazał się być false positive. Na podstawie wyników kontroli jakości poprawię tłumaczenie i wykonam oba testy jeszcze raz. Poprawione tłumaczenie to:

Za pomocą tego polecenia można wyświetlać układ współrzędnych geograficznych w obszarze aplikacji klienckiej. Moduł renderowania generuje na bieżąco raport zawierający ciągi znakowe reprezentujące zawartość magazynu danych.

Wczytuję do xbench poprawione tłumaczenie i wykonuję test Key Term Mismatch. Wyniki są następujące:

KeyTerm Mismatch (area / obszar)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tego polecenia można wyświetlać układ współrzędnych geograficznych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (client / aplikacja kliencka)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tego polecenia można wyświetlać układ współrzędnych geograficznych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (command / polecenie)
This command renders the geographic coordinate system in a client’s area.
Za pomocą tego polecenia można wyświetlać układ współrzędnych geograficznych w obszarze aplikacji klienckiej.

KeyTerm Mismatch (data store / magazyn danych)
A report containing strings that represent data store contents is generated by the renderer on the fly.
Moduł renderowania generuje na bieżąco raport zawierający ciągi znakowe reprezentujące zawartość magazynu danych.

Cztery wyświetlone błędy, ale wszystkie z nich to false positives. Błędów, które nie zostały wykryte za pierwszym razem, już nie ma, ale wprowadzone poprawki doprowadziły do tego, że z trzech false positives zrobiły się cztery. Zobaczmy, jakie będą wyniki testu z użyciem „czeklisty”:

CheckList-10.png

Jeden błąd. Wszystkie poprawki zostały uwzględnione, a pozostał jedynie ten sam co poprzednio false positive.

<< Wróć do poprzedniej strony