Dodanie języka XAML do Crayon Syntax Highlighter

Podczas pisania pierwszego wpisu zawierającego kod źródłowy natknąłem się na problem. Potrzebowałem pluginu pozwalającego na zaprezentowanie kodu źródłowego w przystępnej formie. Wypróbowałem chyba każdy darmowy plugin, jaki wpadł mi w ręce. I „chyba” znalazłem najlepszy.

Crayon Syntax Highlighter

Według mnie Crayon jest najlepszym pluginem do prezentacji kodu. Możemy praktycznie wszystko w nim ustawić od wielkości czcionki aż po kolor tła, na którym wyświetla się kod. Oczywiście posiada on również swoje wady, ale o tym później.

Crayon pozwala nam na wyświetlenie kodu w bardzo czysty, przejrzysty sposób. Jest bardzo dużo stylów do wyboru, więc na pewno każdy znajdzie coś dla siebie – nawet jeśli nie, to ma możliwość edycji dowolnego stylu pod swoje potrzeby. Mamy również dostęp do bogatej gamy języków, z których możemy wybierać. Jako że piszę aplikację Archiwista potrzebowałem wyświetlić kod napisany w języku XAML, którego niestety nie było na liście. Zajrzałem więc do dokumentacji i zobaczyłem, że można go dodać w miarę prosty sposób. Postanowiłem spróbować swoich sił i dodać własny styl kolorowania składni dla tego języka.

Własny język

W dokumentacji znajdziemy rozdział odnośnie dodawania nowego języka, aby dodać nowy język należy utworzyć nowy folder z nazwą języka i umieścić w nim plik tekstowy o takiej samej nazwie. W pliku powinny znajdować się wyrażenia regularne reprezentujące poszczególne elementy języka, przypisane atrybutom ze stylów nadającym im odpowiedni kolor.

Badanie

Przed przystąpieniem do tworzenia pliku zawierającego opis języka, utworzę wyrażenia regularne przedstawiające elementy XAML, które chce pokolorować. Aby tego dokonać pierw skopiowałem kod źródłowy do publikacji, wkleiłem go na stronę regexr.com — która pozwala nam na wizualizację naszych wyrażeń regularnych w sposób graficzny. Skonstruowałem wyrażenia regularne i zacząłem testować jak wygląda kolorowanie składni i na co mogę sobie pozwolić a na co nie. Zajęło mi trochę czasu rozgryzienie, w jaki sposób działa kolorowanie składni. Okazało się, że tekst jest kolorowany względem pliku od góry do dołu.

Dużym zdziwieniem dla mnie był fakt, że operacja niegrupująca nie działała – mam tutaj na myśli (?:#wyrazenie#). Za każdym razem, kiedy używałem jej w moich wyrażeniach była ona pomijana i brana i tak pod uwagę. Kiedy przyjrzałem się dokładnie co zwraca maszyna wyrażeń regularnych okazało się, że są zwracane dwie grupy. Grupa 0 posiada wszystko łącznie z elementem, który zakwalifikował się do zignorowania, a w grupie 1 znajdował się łańcuch mnie interesujący spełniający wszelkie kryteria wyrażenia. Wychodzi na to, że plugin bierze pod uwagę tylko pierwszą grupę, czyli 0, a druga jest ignorowana.

Kolejną ciekawostką było to, że po pokolorowaniu tekstu nie można go drugi raz pokolorować w połowie tylko trzeba go pomalować całkowicie. Na przykład, jeżeli pokoloruję i później będę chciał pokolorować wszystkie znaki <, > na inny kolor, to wyrażenie, mimo iż wykryje symbol i go pokoloruje nie zobaczymy widocznych zmian. Aby była widoczna zmiana koloru musimy pomalować cały obszar objęty wcześniejszym wyrażeniem lub większy.

Implementacja

Skoro wiem jak działa mechanizm wyrażeń regularnych oraz kolorowania mogę zabrać się za kolorowanie składni. Jednak przed przystąpieniem do kolorowania składni ze względu na problem ze zmianą koloru muszę przyjąć odpowiednią strategię, aby później nie okazało się, że czegoś nie mogę pokolorować, ponieważ przyjąłem złą kolejność.

Pierwszą rzeczą, jaką zrobię będzie wytyczenie elementów do pokolorowania a następnie kolejność umożliwiająca ich bezkonfliktowe pokolorowanie.

Wytypowałem 6 elementów do pokolorowania:

  • Nazwa znacznika,
  • Atrybuty znacznika,
  • Ciągi znaków,
  • Ciągi znaków posiadających “{}”,
  • Komentarze,
  • Znaki: <, >, </, =.

Następnym krokiem będzie ułożenie ich w odpowiedniej kolejności. Przyjąłem strategię od najbardziej ogólnego do szczegółowego. Najbardziej ogólnym typem pola jest nazwa znacznika, ponieważ jest to zwykły ciąg znaków, który może wystąpić wszędzie, dlatego jako pierwsze pokoloruje nazwy znaczników. Kolejnymi będą atrybuty znaczników, następnie zwykłe łańcuchy znaków i zaraz po nich specjalne łańcuchy znaków. Na sam koniec zostaje pokolorowanie komentarzy oraz znaków rozpoczynających i kończących każdy znacznik. W tym momencie napotkałem problem. Jeżeli pokoloruję znaczniki początku oraz końca bloków jako pierwsze, to komentarze będą posiadały ten kolor na bokach i wtedy nie będzie to wyglądało ładnie. Dlatego zdecydowałem się na skorzystanie z jednej z własności, którą opisałem wcześniej. Jeżeli pokolorujemy już jakiś element tekstu kolorem, to aby go przemalować musimy zmienić cały tekst małe zmiany jak zmiana koloru jednego znaku nic nie zmienia. Tym sposobem, jeżeli pierw pokoloruje komentarze, to nieważne jakbym próbował, nie pokoloruję znaków rozpoczynających i kończących komentarze przez przypadek. Na koniec prezentuję gotowy plik tekstowy zawierający wyrażenia regularne wraz z odpowiadającymi im atrybutami kolorów ze stylów.

Kończąc

Kolorowanie składni można zobaczyć w akcji na innych moich wpisach, jeżeli chcesz zobaczyć posty zawierające kody xaml kliknij tutaj.

Względem dewelopera Crayon nie jest ideałem – posiada parę wad między innymi problem z operacjami niegrupującymi, przez co bardziej zaawansowane wyrażenia regularne nie mają tutaj sensu. A co za tym idzie powstają niepotrzebne kolizje w kolorowaniu elementów składni danego języka. Co prawda brak możliwości przekolorowania można zaliczyć do minusów, jak i plusów, ponieważ można go wykorzystać tak jak ja to zrobiłem z komentarzami. Jednak jest to dodatkowa gimnastyka, która według mnie jest niepotrzebna.

Koniec końców uważam, że Crayon Syntax Highlighter jest najlepszym pluginem pozwalającym na kolorowanie składni z bogatym dostępem do języków oraz stylów z możliwością ich modyfikacji do własnych potrzeb.

Leave a Reply

Translate »