Klucz dostępu n przeskakuje w nawigacji strony. Przejdź do początku.

Ten dokument jest tłumaczeniem. W przypadku rozbieżności i błędów aktualna wersja angielska owinna być uznana za autorytatywną. Pierwotne prawa autorskie należą do W3C jak wykazano poniżej.

Tłumacz: Andrew Osobka i Kamil Wiśniewski

Przejdź do Strony Głównej W3CPrzejdź do Strony Głównej Domeny Architektury  Internacjonalizacja 
 

Co należy wiedzieć o algorytmie bidi i znacznikach

Potencjalni odbiorcy: twórcy treści pracujący ze skryptami, koderzy XHTML/HTML (używający edytorów, lub skryptowania), twórcy skryptów (PHP, JSP, etc.), twórcy schematów (DTDs, XML Schema, RelaxNG, itd.), i każdy kto ma problemy ze znacznikach mieszanych tekstów arabskich i łacińskich.

Przewodnik na początku opisuje podstawowe zasady działania dwukierunkowego algorytmu Unicode. Potem opisane są bardziej powszechne scenariusze, w których algorytm bidi wymaga dodania odpowiednich znaczników, lub kodów kontrolnych.

Mimo, iż staramy się tu uniezależnić od znaczników, większość przykładów opiera się na XHTML, ponieważ jest on łatwo rozpoznawany. Aby uzyskać porady odnośnie konkretnego języka znaczników zobacz boczny pasek.

Definicje

Dwukierunowy tekst jest powszechny w skryptach pisanych od prawej strony do lewej, jak np. w arabskim, hebrajskim, lub syryjskim. W skryptach tych używane są także inne języki.

Każdy wkomponowany tekst ze skryptu od lewej do prawej i wszystkie liczby pisane i czytane są od lewej do prawej w tekście ogólnie napisanym od prawej do lewej. (Oczywiście, angielski tekst na tej stronie zawiera także tekst dwukierunkowy zawierający arabskie i hebrajskie przykłady.)

Termin bidi jest użwany w znaczeniu 'dwukierunkowy'. Będziemy także używać RTL jako 'z prawej do lewej' i LTR jako 'z lewej do prawej'.

Kolejność wizualna kontra logiczna

Wizualna kolejność tekstu była powszechnym sposobem reprezentowania hebrajskiego w HTML przez użytkowników, którzy nie korzystali z algorytmu bidi Unicode. Z przyzwyczajenia jest ona jeszcze do pewnego stopnia używana. Znaki, które tworzył tekst były zgromadzone w kodzie źródłowym w tej samej kolejności w jakiej widzi się je na ekranie czytając od lewej do prawej.

Na przykład, zastosujmy hebrajski tekst z wymieszaną kierunkowością.

פעילות הבינאום, W3C

Gdyby spojrzeć na te znaki z pamięci, jeden po drugim, możnaby zobaczyć taki układ dla logicznego i wizualnego układu kolejności znaków. Przedstawia to także kolejność pisania, więc graficzny tekst hebrajski musiałby być pisany od końca.

Kolejność logiczna Kolejność wizualna
05E4 פ HEBRAJSKA LITERA PE 0057 W ŁACIŃSKA DUŻA LITERA W
05E2 ע HEBRAJSKA LITERA AYIN 0033 3 LICZBA TRZY
05D9 י HEBRAJSKA LITERA YOD 0043 C ŁACIŃSKA DUŻA LITERA C
05DC ל HEBRAJSKA LITERA LAMED 0020   SPACJA
05D5 ו HEBRAJSKA LITERA VAV 002C , PRZECINEK
05EA ת HEBRAJSKA LITERA TAV 05DD ם HEBRAJSKA LITERA MEM
0020   SPACJA 05D5 ו HEBRAJSKA LITERA VAV
05D4 ה HEBRAJSKA LITERA HE 05D0 א HEBRAJSKA LITERA ALEF
05D1 ב HEBRAJSKA LITERA BET 05E0 נ HEBRAJSKA LITERA NUN
05D9 י HEBRAJSKA LITERA YOD 05D9 י HEBRAJSKA LITERA YOD
05E0 נ HEBRAJSKA LITERA NUN 05D1 ב HEBRAJSKA LITERA BET
05D0 א HEBRAJSKA LITERA ALEF 05D4 ה HEBRAJSKA LITERA HE
05D5 ו HEBRAJSKA LITERA VAV 0020   SPACE
05DD ם HEBRAJSKA LITERA MEM 05EA ת HEBRAJSKA LITERA TAV
002C , PRZECINEK 05D5 ו HEBRAJSKA LITERA VAV
0020   SPACJA 05DC ל HEBRAJSKA LITERA LAMED
0057 W ŁACIŃSKA DUŻA LITERAW 05D9 י HEBRAJSKA LITERA YOD
0033 3 LICZBA TRZY 05E2 ע HEBRAJSKA LITERA AYIN
0043 C ŁACIŃSKA DUŻA LITERA C 05E4 פ HEBRAJSKA LITERA PE

Wizualna kolejność prawie nie występuje w arabskim. Ponieważ arabskie litery łączą się z sobą, istnieje silniejsza motywacja po stronie arabskich użytkowników aby korzystać z kolejności logicznej.

Wizualna kolejność tekstu wymaga wyłączenia funkcji zawijania wierszy i i włączenie funkcji akapit z prawej, szczególnie w tabelach. Potem tekst musi być tak zakodowany, aby zapobiec uruchomieniu algorytmu bidi Unicode w późniejszych podglądach. Oto przykład w HTML:

<table width="50%"><tr><td align="right" nowrap>
,INRIA-מ הפוריאב החראה יתוריש תא הפילחמ W3C<br>
W3C-ל רשפאמ יונישה .ERCIM-ל ,תפרצב תמקממ<br>
הרימש ךות ,הפוריא יבחרב רקחמה ירשק תא קימעהל<br>
ידסייממ דחא ,INRIA םע קזחה ירוטסיהה רשקה לע<br>
.2003 ראוניל 1 ב עצבתי יונישה .ERCIM
</td></tr></table>

(Właściwie jest to całkiem proste użycie. Można też na przykład znaleźć takie rzeczy jak paragrafy z akapitem z prawej przy użyciu znaczka <nobr>..</nobr> w każdej linii. Jeśli twoje okno jest zbyt wąskie początek każdej linii znika z prawej strony przeglądarki.)

Wynikiem tego jest bardzo delikatny kod, który trudno utrzymać. Na przykład, poza trudnością zapisu tekstu hebrajskiego, jeśli chce się dodać kilka słów w drugiej linii paragrafu, trzeba dopasować koniec każdego wiersza. Trzeba też dodać i utrzymać oddzielne rozpiętości linków i znaczniki emfazy dla każdej części tekstu, która wyszła na następną linię.

Kolejność wizualna może też spowodować problemy wyższego rzędu. Na przykład, kolejność kolumn w tabeli musi być ręcznie zmieniana w przypadku tłumaczenia na inny język. Jeśli zmieni się też geometria strony, zmienione muszą być także końce wiersza. I tak dalej.

Kolejność logiczna to o wiele lepsze podejście. W tym podejściu tekst jest przechowywany w pamięci w kolejności, w której jest pisany (i wymawiany). Dwukierunkowy algorytm Unicode sam przestawia kolejność aby poprawnie wyświetlać tekst.

Sprawia to, że tworzenie długich paragrafów ciągłego tekstu jest banalnie proste, bo tekst jest automatycznie zawijany. Łatwiejsze staje się też używanie czytników ekranu.

Algorytm bidi działa na tekście o logicznej kolejności. Jeśli wolisz kolejność wizualną (graficzną) to możesz na tym już poprzestać, chociaż mógłbyś znacznie ułatwić sobie życie stosując kolejność logiczną.

Jak działa algorytm

W obecnym dokumencie przedstawiamy podstawowe, ważne wiadomości dotyczące algorytmu. Nawet jeśli tekst ten wydaje się nudny, czytaj dalej, bo bez zrozumienia podstaw możesz się później pogubić ze znacznikami.

Kierunkowe wpisywanie znaków

Wiemy już, że sekwencja łacińskich znaków jest renderowana (wyświetlana) jeden po drugim od lewej do prawej (widać to na tej stronie). Z drugiej strony algorytm bidi będzie składał sekwencje znaków RTL jeden po drugim od prawej do lewej.

Jest to możliwe, ponieważ każdy znak Unicode ma przypisaną kierunkową cechę. Większość liter jest zapisana w silnej typizacji jako LTR. Litery z dwukierunkowych skryptów są zapisywane RTL.

Kiedy tekst z różnymi kierunkami jest zmieszany w jednej linii, algorytm bidi generuje każdą sekwencję znaków z tym samym kierunkiem jako osobny ciąg kierunkowy. W poniższym przykładzie występują trzy ciągi:

bahrajn مصر kuwejt

Kontekst kierunkowy

Rezultat algorytmu dwukierunkowego zależy od ogólnego kontekstu kierunkowego paragrafu, lub strony, na której jest używany.

W XHTML, taki kontekst charakteryzuje się tym, że nie dodaje się niczego do tagów html, bo domyślna kierunkowość tekstu to LTR, lub dodaje się znacznik dir="rtl" aby wszystkie elementy w dokumencie odziedziczyły kierunek RTL. Kontekst może później zostać zmieniony poprzez dodanie atrybutu dir do odpowiedniego fragmentu tekstu.

Serie kierunkowe są ustalane na podstawie ogólnego kontekstu. W powyższym przykładzie, gdzie ogólny kontekst to LTR przeczytałbyś „Bahrajn”, potem 'مصر' (RTL), potem 'Kuwejt'. Zauważ, że nie potrzeba żadnych znaczników oni dodatkowej stylistyki aby tak się stało.

Jeśli zmienisz kontekst kierunkowy w powyższym przykładzie dodając element RTL, przykładowy tekst będzie wyglądał identycznie ale czytany będzie odwrotnie:

bahrajn مصر kuwejt

Znaki neutralne

Spacje i znaki interpunkcyjne nie mają form LTR I RTL w Unicode, bo mogą być używane w każdym typie skryptu. Dlatego są klasyfikowane jako neutralne.

I tu zaczyna się robić interesująco. Kiedy algorytm bidi napotka znaki z neutralnymi cechami (takie jak spacje i znaki interpunkcyjne) ustala jak je potraktować na podstawie otaczających je znaków.

Neutralny znak znajdujący się pomiędzy dwoma znakami pisanymi w tym samym kierunku przyjmie ten sam kierunek. Więc neutralny znak pomiędzy dwoma znakami RTL będzie traktowany jako znak RTL i będzie miał efekt przedłużenia serii. Dlatego trzy arabskie słowa (oddzielone neutralnymi znakami) w tym zdaniu czytane są od prawej do lewej jako jedna seria kierunkowa. (pierwsze arabskie słowo to مفتاح potem معايير potem الويب.)

Tytuł to مفتاح معايير الويب po arabsku.

Nadal są tu trzy serie kierunkowe. Zauważ, ze dalej niepotrzebne są znaczniki i poprawki stylistyczne.

Interesująca zachowanie pojawia się wtedy gdy neutralny znak znajduje się pomiędzy dwoma znakami o różnych kierunkach. W takim wypadku neutralny znak będzie traktowany jakby miał kierunek taki sam jak ogólny kierunek paragrafu lub kontekstu. Ma to efekt tworzenia granicy pomiędzy seriami kierunkowymi.

Nawet jeśli jest kilka neutralnych znaków pomiędzy dwoma typami znaków, będą one traktowane w taki sam sposób.

Wszystkie implikacje tych zmian staną się jasne gdy będziemy je omawiali przykładach w następnej sekcji.

Gdzie algorytm potrzebuje pomocy

W większości sytuacji algorytm bidi poradzi sobie z tekstem bez żadnych specjalnych znaczników, czy innej pomocy dzięki ogólnemu kierunkowi dokumentu. Jednak trzeba mieć wyjątkowe szczęście, żeby zawsze się to udawało.

Przemieszczone znaki neutralne

Napiszmy znak interpunkcyjny na końcu arabskiej frazy w ostatnim przykładzie. Zgodnie z ustawieniami domyślnymi otrzymamy taką serię:

Tytuł to "مفتاح معايير الويب!" po arabsku.

Cudzysłów jest na porządku, ale wykrzyknik jest na złym miejscu. Powinien być na końcu arabskiego tekstu, czyli z lewej, tak jak tu:

Tytuł to "مفتاح معايير الويب!" po arabsku.

Biorąc pod uwagę działanie algorytmu bidi wiemy czemu tak się stało. Ponieważ wykrzyknik był pomiędzy ostatnim znakiem RTL 'ب' (z lewej) i literą LTR “p”(wyrazu „po”) jego kierunek został ustalony na podstawie ogólnego kontekstu paragrafu (tutaj LTR). Zauważ, że nie ma różnicy, że są tam dwa znaki interpunkcyjne i spacja – wszystkie są neutralne, więc są jednakowo traktowane. Ponieważ wykrzyknik jest uznany za LTR zostaje dołączony do serii kierunkowej , w który wliczony jest tekst “po arabsku”.

Jak więc umieścić znaki interpunkcyjne we właściwym miejscu? W takiej sytuacji przeważnie otoczyłbyś arabski cytat znacznikami – aby oznaczyć go jako cytat, lub by podać informację o języku. W tym wypadku jest na to proste lekarstwo. Zastosuj atrybut na Tagu aby zmienić kierunek tekstu na RTL.

Oto przykład jak to może wyglądać w XHTML.

Tytuł to "<span dir="rtl" lang="ar" xml:lang="ar">مفتاح معايير الويب!</span>" 
po arabsku.

Zauważ, że znacznik span znajduje się wewnątrz cudzysłowu – to część otaczającego go polskiego tekstu.

Jest też inna możliwość: można wpisać niewidoczny znak typu RTL po wykrzykniku. Wtedy wykrzyknik zostanie zinterpretowany jako RTL i włączony do arabskiego kierunku tekstu.

Tak się składa, że istnieje taki znak – znak Unicode U+200F, zwany Z-PRAWEJ-DO-LEWEJ (RLM). Jest też podobny znak, U+200E, zwany Z-LEWEJ-DO-PRAWEJ (LRM).

Ponieważ znak ten jest niewidoczny, może będziesz wolał wpisać znak odniesienia numerycznego (&#x200F;), lub jeśli jest to możliwe, inny znak (taki jak &rlm; w XHTML). W poniższym przykładzie znak ‏ został dodany po wykrzykniku I rezultat wygląda dobrze:

Tytuł to "مفتاح معايير الويب!‏" po arabsku.

Znaki neutralne z kryzysem osobowości

W naszym kolejnym przykładzie kolejność jest nieprawidłowa, ponieważ pierwsze dwa arabskie słowa powinny być odwrócone, a przecinek będący częścią polskiego tekstu powinien pojawić się po pierwszym wyrazie.

Nazwy tych stanów po arabsku to odpowiednio مصر, البحرين i الكويت.

Chcieliśmy otrzymać:

Nazwy tych stanów po arabsku to odpowiednio مصر,‎ البحرين i الكويت.

Dzieje się tak dlatego, że w tekście pisanym od prawej do lewej (RTL) po obu stronach neutralnego znaku algorytm postrzega ten znak jako część tekstu arabskiego. W rzeczywistości jest to część polskiego tekstu i przecinek powinien oddzielać dwa teksty kierunkowe po arabsku.

Podczas gdy w poprzedniej sekcji neutralny znak myślał, że jest częścią ogólnego kontekstu, a nie był, w tej sekcji znak neutralny myśli, że jest częścią serii kierunkowej kiedy tak naprawdę jest częścią ogólnego kontekstu! Nikt nie mówił, że życie jest proste…

Dobrym rozwiązaniem w takiej sytuacji jest użycie kolejnego niewidocznego znaku Unicode, tym razem znaku LTR obok przecinka. W takim wypadku neutralny znak interpunkcyjny znajdzie się pomiędzy znakami RTL i LTR, co zmusi go do przyjęcia ogólnego kierunku kontekstu, czyli LTR. Wtedy dwa arabskie słowa odbierane są jako dwie różne serie kierunkowe, o kierunku LTR zgodnie z dominującym kierunkiem tekstu w paragrafie.

Znów możesz woleć wybrać NCR (&#x200E;) lub inny znak (taki jak &lrm;) jeśli jest to możliwe.

Wtakim wypadku wstawianie znaczników dookoła przecinka przypomina trochę obieranie jajka przy pomocy młotka.

Znowu razem

Przykłady używane do tej pory bazowały na języku polskim i orientacji LTR. Te same zasady dotyczą tekstów pisanych RTL w językach takich jak hebrajski czy arabski. Spójrzmy na jeszcze jeden przykład.

Oto co chcemy zobaczyć w paragrafie z podstawowym kierunkiem ustawionym na RTL.

W3C‏ (World Wide Web Konsorcjum) מעביר את שירותי הארחה באירופה ל - ERCIM.

Niestety, algorytm może narobić z tym trochę bałaganu.

W3C (World Wide Web Konsorcjum) מעביר את שירותי הארחה באירופה ל - ERCIM.

Wygląda to na bardzo trudne do rozwiązania, ale rozwiązanie tego problemu jest trywialne. Wystarczy wstawić RLM po „W3C” i to tyle. Naprawdę bardzo proste.

Jeśli to nie przekonuje, spójrzmy na wyjaśnienie. RLM po „W3C” sprawia, że ta seria LTR jest odbierana jako osobna seria, a nie część teksty w cudzysłowie który występuje po niej. Pamiętaj, że seria będzie ukierunkowany od prawej do lewej, bo taki jest ogólny kierunek paragrafu. Ponieważ „W3C” jest wpisane jako pierwsze, znajduje się teraz najdalej od prawej strony. Nawias jest teraz pomiędzy znakami o kierunkach RTL i LTR i dlatego też przyjmuje ogólny kierunek paragrafu – RTL. Więc jest to następne w kolejności. Na końcu jest cały seria LTR, czyli wszystko co znajduje się w nawiasie.

Aby lepiej zrozumieć sekwencję znaków w powyższym przykładzie może lepiej będzie poruszać kursorem w tekście w jakimś edytorze zamiast patrzyć się na ekran.

Zmiana hieroglifu z prawej strony nawiasu następuje automatycznie. Hieroglif użyty dla „odwróconych znaków” zmienia się zgodnie z kierunkiem tekstu. To ciągle ten sam znak.

Grupowanie serii kierunkowych

Algorytm bidi i znaczniki kierunków działają całkiem nieźle kiedy jest tylko jeden poziom mieszanego tekstu. Kiedy nastąpi sytuacja, w której są dwa, lub więcej zgrupowanych poziomów różnokierunkowych tekstów, będziemy potrzebować innego rozwiązania. Oto przykład niepoprawnie ukierunkowanego tekstu.

Tytuł to "פעילות הבינאום, W3C" po hebrajsku.

Kolejność hebrajskich słów jest poprawna, ale tekst “W3C” powiniej pojawić się z lewej strony cudzysłowu, a przecinek pomiędzy hebrajskim tekstem i “W3C”. Innymi słowy powinno to wyglądać tak:

Tytuł to "פעילות הבינאום, W3C" po hebrajsku .

Ten problem pojawia się, bo kierunki tekstu ustalane są na podstawie kontekstu LTR paragrafu. Jednak wewnątrz hebrajskiego cytatu domyślnym kierunkiem tekstu powinien być RTL.

Aby rozwiązać ten problem musimy utworzyć nowy poziom osadzania. W XHTML oznaczałoby to otoczenie cytatu znacznikami i przypisanie im kierunkowości RTL używając atrybutu dir.

Tytuł to "<span dir="rtl">פעילות הבינאום, W3C</span>" po hebrajsku.

W językach znaczników innych niż XHTML/HTML można znaleźć podobne atrybuty, do których można zastosować różne style aby uzyskać podobny efekt. Jeśli nie ma takiego atrybutu można ręcznie dostosować znaczniki, ale pewnie lepiej byłoby zwrócić się do dewelopera znaczników aby je dostarczył.

Można też użyć znaków kontrolnych Unicode aby otrzymać ten sam rezultat, ale ponieważ tworzą one obszary z niewidocznymi granicami odradza się ich używania.

Cyfry są wyjątkowe

Cyfry w skryptach RTL są w kolejności od lewej do prawej w obrębie serii pisanej od prawej do lewej, ale algorytm bidi radzi sobie z nimi trochę inaczej niż ze słowami. Mówi się, że cyfry mają słabą kierunkowość. Poniższe dwa przykłady ilustrują tę różnicę. Porównanie przykładów pokazuje, że słowa po obu stronach czwartego elementu w sekwencji zostały zmienione. Jedyną różnicą pomiędzy dwoma zdaniami jest użycie „1234” zamiast „cztery”.

jeden dwa ثلاثة cztery خمسة
jeden dwa ثلاثة 1234 خمسة

W pierwszym przykładzie litery w wyrazie “cztery” mają silną kierunkowość i dlatego przerywają arabski ciąg wyrazów na dwie serie kierunkowe, o kierunkach od lewej do prawej – tak jak cały paragraf.

W drugim przykładzie znaki o słabej kierunkowości „1234” widziane są jako część arabskiego tekstu, więc dwa arabskie słowa traktowane są jako część tej samej serii kierunkowej, mimo iż sekwencja cyfr ma kierunek LTR.

W niektórych wersjach przeglądarek Netscape i Mozilla czwarty element w szeregu wyświetli się jako ١٢٣٤ a nie 1234. Oznacza to dokładie to samo. Zauważ, że Mozilla 1.4 użyje domyślnie europejskich znaków.

Dzieje się tak tylko w tekście RTL.

Wygląda na skomplikowane? Nic się nie martw, zazwyczaj algorytm bidi załatwi wszystko za ciebie. Przedstawione tu informacje są dla tych, którzy widzą różnicę i zastanawiają się co się dzieje.

Zauważ także, że tak jak cyfry, niektóre inne znaki jak na przykład symbole walut będą traktowane raczej jako numer a nie znak neutralny.

Obejście algorytmu

Może się zdarzyć, że nie będziesz chciał aby algorytm bidi zmieniał kolejność tekstu. W takim wypadku potrzebne są dodatkowe znaczniki aby otoczyć tekst, który algorytm ma pominąć.

W XHTML 1.0 można to osiągnąć używając elementu bdo. W XHTML 2 prawdopodobnie będzie wprowadzany jako wartość rlo lub lro w atrybucie kierunku umożliwiając wprowadzenie go w dowolny element. Znaki kontrolne Unicode także są dostępne, ale ponieważ tworzą obszary z niewidocznymi granicami odradza się ich stosowanie.

Przykłady, które pokazują znaki w takiej kolejności w jakiej znajdują się one w pamięci używają znacznika bdo aby osiągnąć ten efekt. Na przykład, aby ukazać sekwencję znaków dla:

פעילות הבינאום, W3C

użyjemy następującego znacznika w XHTML 1.0:

<p><bdo dir="ltr">פעילות הבינאום, W3C</bdo></p>

Rezultat pisany od lewej do prawej to:

פעילות הבינאום, W3C

Powiedz nam co myślisz (po angielsku)

Warto przeczytać

Autor: Richard Ishida, W3C. Tłumacz: Andrew Osobka i Kamil Wiśniewski.

Ważny XHTML 1.0!
Ważne CSS!
Zakodowano w UTF-8!

Przetłumaczono z angielskiego dnia 2006-12-03. Ostatnia zmiana wersji tłumacznia 2008-03-07 19:03 GMT

Historia zmian dokumentu article-inline-bidi-markup w blogu i18n.