ΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² написании студСнчСских Ρ€Π°Π±ΠΎΡ‚
АнтистрСссовый сСрвис

НаписаниС тСкстового Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° с подсвСткой синтаксиса

ΠšΡƒΡ€ΡΠΎΠ²Π°ΡΠŸΠΎΠΌΠΎΡ‰ΡŒ Π² Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠΈΠ£Π·Π½Π°Ρ‚ΡŒ ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒΠΌΠΎΠ΅ΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹

Атрибут name элСмСнта entry ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для задания ΠΈΠΌΠ΅Π½ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Ρƒ подсвСтки. По ΡΡ‚ΠΎΠΌΡƒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρƒ Π΄Π°Π½Π½Ρ‹Π΅ для подсвСтки синтаксиса Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ Π² Ρ‚Скстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€. Он ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния: Plain (ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ тСкст), Line Comments (строковыС ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ), Block Comments (многостроковыС ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ), Strings (строки), Directives (Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹), Types (Ρ‚ΠΈΠΏΡ‹), Keywords (ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова). Π’ Π΄Π°Π½Π½ΠΎΠΌ… Π§ΠΈΡ‚Π°Ρ‚ΡŒ Π΅Ρ‰Ρ‘ >

НаписаниС тСкстового Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° с подсвСткой синтаксиса (Ρ€Π΅Ρ„Π΅Ρ€Π°Ρ‚, курсовая, Π΄ΠΈΠΏΠ»ΠΎΠΌ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Π°Ρ)

  • Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅
  • 1. Π€Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
  • 1.1 Π€ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
  • 1.2 Π€ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ
  • 2. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹
  • 2.1 Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
  • 2.2 Π Π°Π·Π±ΠΎΡ€ тСкста ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ΠΌΡƒ стилСй
  • 3. ВСстовый ΠΏΡ€ΠΈΠΌΠ΅Ρ€
  • Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅
  • Бписок Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Ρ‹
  • ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ

Данная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° являСтся тСкстовым Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ΠΎΠΌ с ΠΏΠΎΠ΄ΡΠ²Π΅Ρ‚ΠΊΠΎΠΉ синтаксиса языков программирования. Настройки для подсвСтки синтаксиса ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ конструкции языка Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ ΠΈΠ· XML Ρ„Π°ΠΉΠ»Π°. Π­Ρ‚ΠΎ обСспСчиваСт простоту конфигурирования ΠΏΠΎΠ΄ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ языки программирования. Π˜Π·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° сконфигурирована ΠΏΠΎΠ΄ Π‘++.

Для контроля ошибок Π² XML Ρ„Π°ΠΉΠ»Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ XML Schema. Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с XML ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° LibXML2, ΠΎΠ½Π° ΠΆΠ΅ осущСствляСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Ρ„Π°ΠΉΠ»Π° настроСк ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ схСмы.

Для Ρ€Π°Π·Π±ΠΎΡ€Π° Π²Π²ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ тСкста ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π±ΡƒΡ„Π΅Ρ€, Π² ΠΎΠ΄Π½ΠΎΠΌ хранится Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ тСкст, Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅. Поиск конструкций языка Π² Π±ΡƒΡ„Π΅Ρ€Π΅ осущСствляСтся стандартным Π½Π°Π±ΠΎΡ€ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π‘++.

1. Π€Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

1.1 Π€ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

Π€Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ прСдставляСт собой XML — Ρ„Π°ΠΉΠ», Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ хранятся Π΄Π°Π½Π½Ρ‹Π΅, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для подсвСтки синтаксиса. Π€Π°ΠΉΠ» состоит ΠΈΠ· ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта language, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² ΡΠ²ΠΎΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ содСрТит 3 Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнта: style, keywords ΠΈ types.

Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ style содСрТит 7 пустых Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов entry Π²ΠΈΠ΄Π°

ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ 3 Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°: name, color ΠΈ font. Один элСмСнт enty описываСт ΠΎΠ΄Π½ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ подсвСтки синтаксиса. НапримСр, элСмСнт Π²ΠΈΠ΄Π° описываСт ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ для подсвСтки строковых ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π², для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ‚Ρ‘ΠΌΠ½ΠΎ-Π·Π΅Π»Ρ‘Π½Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚ ΡˆΡ€ΠΈΡ„Ρ‚Π° ΠΈ ΡˆΡ€ΠΈΡ„Ρ‚ HELVETICA Π² ΠΊΡƒΡ€ΡΠΈΠ²Π½ΠΎΠΌ Π½Π°Ρ‡Π΅Ρ€Ρ‚Π°Π½ΠΈΠΈ.

Атрибут name элСмСнта entry ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для задания ΠΈΠΌΠ΅Π½ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Ρƒ подсвСтки. По ΡΡ‚ΠΎΠΌΡƒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρƒ Π΄Π°Π½Π½Ρ‹Π΅ для подсвСтки синтаксиса Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ Π² Ρ‚Скстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€. Он ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния: Plain (ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ тСкст), Line Comments (строковыС ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ), Block Comments (многостроковыС ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ), Strings (строки), Directives (Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹), Types (Ρ‚ΠΈΠΏΡ‹), Keywords (ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова).

Атрибут color Π·Π°Π΄Π°Ρ‘Ρ‚ Ρ†Π²Π΅Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°ΡΠΊΡ€Π°ΡˆΠ΅Π½Ρ‹ конструкции языка, подходящиС ΠΏΠΎΠ΄ Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния: FL_BLACK, FL_GREEN, FL_DARK_GREEN, FL_BLUE, FL_DARK_BLUE, FL_RED, FL_DARK_RED, FL_MAGENTA, FL_DARK_MAGENTA, FL_CYAN, FL_DARK_CYAN, FL_YELLOW, FL_DARK_YELLOW.

Атрибут font Π·Π°Π΄Π°Ρ‘Ρ‚ ΡˆΡ€ΠΈΡ„Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для конструкций языка, подходящих ΠΏΠΎΠ΄ Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния: FL_COURIER, FL_COURIER_BOLD, FL_COURIER_ITALIC, FL_COURIER_BOLD_ITALIC, FL_HELVETICA, FL_HELVETICA_BOLD, FL_HELVETICA_ITALIC, FL_HELVETICA_BOLD_ITALIC, FL_TIMES, FL_TIMES_BOLD, FL_TIMES_ITALIC, FL_TIMES_BOLD_ITALIC, FL_SCREEN, FL_SCREEN_BOLD.

Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ keywords содСрТит Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ элСмСнты Π²ΠΈΠ΄Π° keyword_name, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова языка.

Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ types содСрТит Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ элСмСнты Π²ΠΈΠ΄Π° type_name, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² ΡΠ·Ρ‹ΠΊΠ΅.

1.2 Π€ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ

Π’ΠΎ Π²Ρ€Π΅ΠΌΡ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ производится Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ XML Schema. XML Schema загруТаСтся ΠΈΠ· Ρ„Π°ΠΉΠ»Π° schema. xsd. Она опрСдСляСт Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… свойств ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΎΠ², ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ элСмСнтов ΠΈ ΠΈΡ… ΠΊΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ, допустимыС значСния для пСрСчислСний.

ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ опрСдСляСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

Π—Π΄Π΅ΡΡŒ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ name ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ (use="required"), Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ тСкстовым (base="xs: string") ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° value элСмСнта xs: enumeration.

ΠšΠΎΡ€Π½Π΅Π²ΠΎΠΉ элСмСнт language Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ 3 Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнта: style, keywords ΠΈ types. На ΡΠ·Ρ‹ΠΊΠ΅ XML Schema это ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ записываСтся Ρ‚Π°ΠΊ:

Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ types ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ 1 ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов type, значСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ строкового Ρ‚ΠΈΠΏΠ°. Π”Π°Π½Π½ΠΎΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ рСализуСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ конструкции:

Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ style содСрТит 7 Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов entry, содСрТащих Π΄Π°Π½Π½Ρ‹Π΅ слоТного Ρ‚ΠΈΠΏΠ°. ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ для Π΄Π°Π½Π½ΠΎΠ³ΠΎ утвСрТдСния выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

тСкстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ подсвСтка синтаксис

2. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

2.1 Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

Для Π½Π°Ρ‡Π°Π»Π° создадим 3 ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠ° xmlChar:

xmlChar *uri; // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для хранСния Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ²

xmlChar *color; // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для хранСния значСния Ρ†Π²Π΅Ρ‚Π°

xmlChar *font; // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для хранСния значСния ΡˆΡ€ΠΈΡ„Ρ‚Π°

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· XML Ρ„Π°ΠΉΠ»Π° происходит Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ loadHighlightingData ():

void loadHighlightingData ()

{

xmlDocPtr doc1;

const char * filename = «config. xml» ;

doc1 = xmlReadFile (filename, NULL, XML_PARSE_NONET);

if (is_valid (doc1, «schema. xsd») == 1)

{

int i = 0;

xmlDocPtr xmldoc = NULL;

xmlChar *uri;

if ((xmldoc = xmlReadFile (filename, NULL, 0)) == NULL) return;

xmlNodePtr cur = xmlDocGetRootElement (xmldoc);

parseXMLDoc (xmldoc, «style», «entry»);

parseXMLDoc (xmldoc, «keywords», «keyword»);

parseXMLDoc (xmldoc, «types», «type»);

xmlFree (uri);

xmlFree (color);

xmlFree (font);

}else

{

// Ошибка Π² XML

xmlErrorPtr XMLError;

XMLError = xmlGetLastError ();

fl_alert (XMLError->message);

}

}

Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΡΠΎΠ·Π΄Π°Ρ‘ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ xmlDocPtr doc1;, присваиваСм имя Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ filename. Π—Π°Ρ‚Π΅ΠΌ считываСм Ρ„Π°ΠΉΠ» ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ XML Schema. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ осущСствляСт функция is_valid (const xmlDocPtr doc, const char *schema_filename), ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π°Ρ Π² ΠΊΠ°Ρ‡Π΅ΡΡ‚Π²Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΈ ΠΈΠΌΡ Ρ„Π°ΠΉΠ»Π° XML Schema. Π’ Π΄Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сначала загруТаСтся Ρ„Π°ΠΉΠ» схСмы:

xmlDocPtr schema_doc = xmlReadFile (schema_filename, NULL, XML_PARSE_NONET);

if (schema_doc == NULL) {

fl_alert («The schema cannot be loaded or is not well-formed»);

return — 1;

}

Π’ ΡΠ»ΡƒΡ‡Π°Π΅ нСвозмоТности Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» выводится ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ сообщСниС ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fl_alert ();

Π”Π°Π»Π΅Π΅ создаётся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒΠ½Π° контСкст парсСра схСмы, ΠΈ Ρ‚Π°ΠΊΠΆΠ΅ выводится сообщСниС ΠΎ ΠΎΡˆΠΈΠ±ΠΊΠ΅ ΠΏΡ€ΠΈ нСвозмоТности Π΅Π³ΠΎ создания:

xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt (schema_doc);

if (parser_ctxt == NULL) {

fl_alert («Unable to create a parser context for the schema», «Ok»);

xmlFreeDoc (schema_doc);

return — 2;

}

Π—Π°Ρ‚Π΅ΠΌ сама схСма провСряСтся Π½Π° ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ ΠΈ Ρ‚Π°ΠΊΠΆΠ΅ выдаётся сообщСниС ΠΎ ΠΎΡˆΠΈΠ±ΠΊΠ΅ ΠΏΡ€ΠΈ Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ ошибок Π² ΡΡ…Π΅ΠΌΠ΅:

xmlSchemaPtr schema = xmlSchemaParse (parser_ctxt);

if (schema == NULL) {

fl_alert («the schema itself is not valid», «Ok»);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return — 3;

}

ПослС этого создаётся контСкст ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ:

xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt (schema);

if (valid_ctxt == NULL) {

fl_alert («unable to create a validation context for the schema», «Ok»);

xmlSchemaFree (schema);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return — 4;

}

И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, происходит ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°:

int is_valid = (xmlSchemaValidateDoc (valid_ctxt, doc) == 0);

xmlSchemaFreeValidCtxt (valid_ctxt);

xmlSchemaFree (schema);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return is_valid? 1: 0;

Π’ ΡΠ»ΡƒΡ‡Π°Π΅, Ссли Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹ΠΉ XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΈΠΌΠ΅Π΅Ρ‚ ошибки, Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ΅Ρ‚ся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

xmlErrorPtr XMLError;

XMLError = xmlGetLastError ();

fl_alert (XMLError->message);

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΡΠΎΠ·Π΄Π°Ρ‘ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρƒ XMLError, заносим Π² ΡΡ‚Ρƒ структуру свСдСния ΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ошибкС, ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π΄Π°Ρ‘ΠΌ сообщСниС ΠΎ ΠΎΡˆΠΈΠ±ΠΊΠ΅ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fl_allert ();.

Если ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° XML Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ΅Ρ‚ся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

xmlDocPtr xmldoc = NULL;

if ((xmldoc = xmlReadFile (filename, NULL, 0)) == NULL) return;

xmlNodePtr cur = xmlDocGetRootElement (xmldoc);

parseXMLDoc (xmldoc, «style», «entry»);

parseXMLDoc (xmldoc, «keywords», «keyword»);

parseXMLDoc (xmldoc, «types», «type»);

xmlFree (uri);

xmlFree (color);

xmlFree (font);

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΡΠΎΠ·Π΄Π°Ρ‘ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚, Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ элСмСнт Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈ Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ стилСй Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΈΠ· XML Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ parseXMLDoc (xmlDocPtr doc, char *nodeName, char *curNode). Π­Ρ‚Π° функция вызываСтся 3 Ρ€Π°Π·Π°: для чтСния Π΄Π°Π½Π½Ρ‹Ρ… подсвСтки, для получСния списка ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов ΠΈ ΡΠΏΠΈΡΠΊΠ° Ρ‚ΠΈΠΏΠΎΠ². Рассмотрим эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅:

void parseXMLDoc (xmlDocPtr doc, char *nodeName, char *curNode)

{

xmlNodePtr cur;

cur = xmlDocGetRootElement (doc);

cur = cur->xmlChildrenNode;

while (cur! = NULL)

{

if ((! xmlStrcmp (cur->name, (const xmlChar *) nodeName)))

{

parseNodes (doc, cur, curNode);

}

cur = cur->next;

}

}

Π‘Π½Π°Ρ‡Π°Π»Π° создаётся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠ»Π΅ΠΌΠ΅Π½Ρ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈ Π΅ΠΌΡƒ присваиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта. Π—Π°Ρ‚Π΅ΠΌ устанавливаСтся Ρ€Π΅ΠΆΠΈΠΌ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов ΠΈ Π² Ρ†ΠΈΠΊΠ»Π΅ осущСствляСтся поиск элСмСнта, Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. ΠŸΡ€ΠΈ Π΅Π³ΠΎ Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ выполняСтся функция parseNodes (xmlDocPtr doc, xmlNodePtr cur, char *curNode), которая ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ стилСй, ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов ΠΈ Ρ‚ΠΈΠΏΠΎΠ². Данная функция Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

void parseNodes (xmlDocPtr doc, xmlNodePtr cur, char *curNode)

{

xmlChar *key;

int exit (0);

cur = cur->xmlChildrenNode;

while (cur! = NULL)

{

if ((! xmlStrcmp (cur->name, (const xmlChar *) curNode)))

{

if ((! xmlStrcmp (cur->name, (const xmlChar *)" entry")))

{

parseStyles (doc, cur, «Plain»);

parseStyles (doc, cur, «Line Comments»);

parseStyles (doc, cur, «Block Comments»);

parseStyles (doc, cur, «Strings»);

parseStyles (doc, cur, «Directives»);

parseStyles (doc, cur, «Types»);

parseStyles (doc, cur, «Keywords»);

return;

}else

{

key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);

if (strcmp (curNode, «type») == 0)

{

code_types. push_back ((const char *) key);

}else

{

code_keywords. push_back ((const char *) key);

}

xmlFree (key);

}

}

cur = cur->next;

}

return;

}

Данная функция состоит ΠΈΠ· 2 частСй: пСрвая Ρ‡Π°ΡΡ‚ΡŒ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ стилСй, вторая для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов ΠΈ Ρ‚ΠΈΠΏΠΎΠ². Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° стилСй осущСствляСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ parseStyles (xmlDocPtr doc, xmlNodePtr cur, const char *name), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ всС 7 элСмСнтов описаны ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

if ((! xmlStrcmp (uri, (const xmlChar *)" Plain")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ XMLValue2FLfont (const xmlChar* XMLvalue) ΠΈ XMLValue2FLColor (const xmlChar* XMLvalue) ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΡ‚Ρ€ΠΎΠΊΡƒ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚, являСтся Π»ΠΈ ΠΎΠ½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ FLCOLOR ΠΈΠ»ΠΈ FLFONT ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_BLACK")))

{

return FL_BLACK;

}

ΠΈΠ»ΠΈ

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_COURIER")))

{

return FL_COURIER;

}

Если функция parseNodes ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠ»Π΅ΠΌΠ΅Π½Ρ‚, содСрТащий значСния ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ Π² ΠΌΠ°ΡΡΠΈΠ² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

code_keywords. push_back ((const char *) key). Π’Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ ΠΈ Ρ‚ΠΈΠΏΡ‹: code_types. push_back ((const char *) key).

2.2 Π Π°Π·Π±ΠΎΡ€ тСкста ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ΠΌΡƒ стилСй

FL_Text_Editor Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ подсвСтку синтаксиса Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ, ΡˆΡ€ΠΈΡ„Ρ‚Π°ΠΌΠΈ ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ ΡˆΡ€ΠΈΡ„Ρ‚Π°. Π”Π°Π½Π½Ρ‹ΠΉ класс основан Π½Π° ΡΠ΄Ρ€Π΅ тСкстового Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° NEdit, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹ΠΉ стилСвой Π±ΡƒΡ„Π΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ†Π²Π΅Ρ‚Π΅, ΡˆΡ€ΠΈΡ„Ρ‚Π΅ ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅ тСкста, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отобраТаСтся.

Для хранСния стилСй ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ структура Fl_Text_Display: Style_Table_Entry, опрСдСлённая Π² Ρ„Π°ΠΉΠ»Π΅ Fl_Text_Display. H:

struct Style_Table_Entry

{

Fl_Colorcolor;

Fl_Fontfont;

intsize;

unsignedattr;

}

color Π·Π°Π΄Π°Ρ‘Ρ‚ Ρ†Π²Π΅Ρ‚ для тСкста, font Π·Π°Π΄Π°Ρ‘Ρ‚ индСкс FLTK ΡˆΡ€ΠΈΡ„Ρ‚Π°, size Π·Π°Π΄Π°Ρ‘Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΡˆΡ€ΠΈΡ„Ρ‚Π° Π² ΠΏΠΈΠΊΡΠ΅Π»ΡΡ…. attr Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ся.

ВсС сСмь стилСй ассоциированы с Π»Π°Ρ‚инскими Π±ΡƒΠΊΠ²Π°ΠΌΠΈ — A (ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ тСкст), B (строковый ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ), C (Π±Π»ΠΎΠΊΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ), D (строки), E (Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹), F (Ρ‚ΠΈΠΏΡ‹), G (ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ слова).

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ Π² ΡΡ‚ΠΈΠ»Π΅Π²ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ описываСтся символом, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠΌΡΡ с 'A'.

Π§Ρ‚ΠΎΠ±Ρ‹ Π°ΡΡΠΎΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΡ‚ΠΈΠ»Π΅Π²ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΈ Π±ΡƒΡ„Π΅Ρ€ с Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠΌ тСкстового Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π°, Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ highlight_data ():

Fl_Text_Buffer * stylebuf;

w->editor->highlight_data (stylebuf, styletable,

sizeof (styletable) /sizeof (styletable [0])

`A', style_unfinished_cb, 0);

Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ callback ΠΊ Π³Π»Π°Π²Π½ΠΎΠΌΡƒ тСкстовому Π±ΡƒΡ„Π΅Ρ€Ρƒ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, измСнСния Π² Ρ‚Скстовом Π±ΡƒΡ„Π΅Ρ€Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ Π² ΡΡ‚ΠΈΠ»Π΅Π²ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅:

textbuf->add_modify_callback (style_update, w->editor);

Ѐункция style_update () вызываСтся ΠΊΠΎΠ³Π΄Π° тСкст Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Ρ‘Π½ ΠΈΠ· Ρ‚Скстового Π±ΡƒΡ„Π΅Ρ€Π°. Она ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ измСнСния Π² ΡΡ‚ΠΈΠ»Π΅Π²ΠΎΠΌ Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΈ Π·Π°Ρ‚Π΅ΠΌ обновляСт ΡΡ‚ΠΈΠ»Π΅Π²ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ.

Ѐункция style_parse () сканируСт копию тСкста Π² Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ стилСвыС символы для отобраТСния стиля. Π Π°Π·Π±ΠΎΡ€ начинаСтся с Π½Π°Ρ‡Π°Π»Π° строки.

3. ВСстовый ΠΏΡ€ΠΈΠΌΠ΅Ρ€

На Ρ€ΠΈΡΡƒΠ½ΠΊΠ΅ 1 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΌ тСкстом Π½Π° ΡΠ·Ρ‹ΠΊΠ΅ Π‘++.

Рисунок 1.

На Ρ€ΠΈΡΡƒΠ½ΠΊΠ΅ 2 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ сообщСниС ΠΎ ΠΎΡˆΠΈΠ±ΠΊΠ΅ ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ„Π°ΠΉΠ»Π° настроСк.

Рисунок 2.

На Ρ€ΠΈΡΡƒΠ½ΠΊΠ΅ 3 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ сообщСниС ΠΎ ΠΎΡˆΠΈΠ±ΠΊΠ΅ ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ„Π°ΠΉΠ»Π° схСмы.

Рисунок 3.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ Π΄Π°Π½Π½ΠΎΠΌ курсовом ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π±Ρ‹Π» Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ тСкстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ с ΠΏΠΎΠ΄ΡΠ²Π΅Ρ‚ΠΊΠΎΠΉ синтаксиса языков программирования с Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ конфигурирования настроСк подсвСтки синтаксиса ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠΎΠ² ΠΈ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… слов языка. Данная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° являСтся кроссплатформСнной, Ρ‚.ΠΊ. ΠΎΠ½Π° написана с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ кроссплатформСнных Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ FLTK 1.3.0 ΠΈ LibXML2.

1. http://www.fltk.org

2. http://xmlsoft.com

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 1

and

and_eq

asm

bitand

bitor

break

case

catch

compl

continue

default

delete

do

else

false

for

goto

if

new

not

not_eq

operator

or

or_eq

return

switch

template

this

throw

true

try

while

xor

xor_eq

auto

bool

char

class

const

const_cast

double

dynamic_cast

enum

explicit

extern

float

friend

inline

int

long

mutable

namespace

private

protected

public

register

short

signed

sizeof

static

static_cast

struct

template

typedef

typename

union

unsigned

virtual

void

volatile

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 2

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 3

#include

#include

#include

#ifdef __MWERKS__

# define FL_DLL

#endif

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

int changed = 0;

char filename [FL_PATH_MAX] = «» ;

char title [FL_PATH_MAX];

Fl_Text_Buffer *textbuf = 0;

// Syntax highlighting stuff.

#define TS 14 // default editor textsize

Fl_Text_Buffer *stylebuf = 0;

Fl_Text_Display: Style_Table_Entry styletable [7]; // Style table

std: vector code_keywords;

std: vector code_types;

std: vector: iterator it;

std: vector: iterator it1;

xmlChar *uri;

xmlChar *color;

xmlChar *font;

int i (0);

Fl_Text_Display: Style_Table_Entry stylebuftemp;

int is_valid (const xmlDocPtr doc, const char *schema_filename)

{

xmlDocPtr schema_doc = xmlReadFile (schema_filename, NULL, XML_PARSE_NONET);

if (schema_doc == NULL) {

fl_alert («The schema cannot be loaded or is not well-formed»);

return — 1;

}

xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt (schema_doc);

if (parser_ctxt == NULL) {

fl_alert («Unable to create a parser context for the schema», «Ok»);

xmlFreeDoc (schema_doc);

return — 2;

}

xmlSchemaPtr schema = xmlSchemaParse (parser_ctxt);

if (schema == NULL) {

fl_alert («the schema itself is not valid», «Ok»);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return — 3;

}

xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt (schema);

if (valid_ctxt == NULL) {

fl_alert («unable to create a validation context for the schema», «Ok»);

xmlSchemaFree (schema);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return — 4;

}

int is_valid = (xmlSchemaValidateDoc (valid_ctxt, doc) == 0);

xmlSchemaFreeValidCtxt (valid_ctxt);

xmlSchemaFree (schema);

xmlSchemaFreeParserCtxt (parser_ctxt);

xmlFreeDoc (schema_doc);

return is_valid? 1: 0;

}

unsigned int XMLValue2FLColor (const xmlChar* XMLvalue)

{

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_BLACK")))

{

return FL_BLACK;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_GREEN")))

{

return FL_GREEN;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_GREEN")))

{

return FL_DARK_GREEN;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_BLUE")))

{

return FL_BLUE;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_BLUE")))

{

return FL_DARK_BLUE;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_RED")))

{

return FL_RED;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_RED")))

{

return FL_DARK_RED;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_MAGENTA")))

{

return FL_MAGENTA;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_MAGENTA")))

{

return FL_DARK_MAGENTA;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_CYAN")))

{

return FL_CYAN;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_CYAN")))

{

return FL_DARK_CYAN;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_YELLOW")))

{

return FL_YELLOW;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_DARK_YELLOW")))

{

return FL_DARK_YELLOW;

}

}

int XMLValue2FLfont (const xmlChar* XMLvalue)

{

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_COURIER")))

{

return FL_COURIER;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_COURIER_BOLD")))

{

return FL_COURIER_BOLD;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_COURIER_ITALIC")))

{

return FL_COURIER_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_COURIER_BOLD_ITALIC")))

{

return FL_COURIER_BOLD_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_HELVETICA")))

{

return FL_HELVETICA;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_HELVETICA_BOLD")))

{

return FL_HELVETICA_BOLD;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_HELVETICA_ITALIC")))

{

return FL_HELVETICA_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_HELVETICA_BOLD_ITALIC")))

{

return FL_HELVETICA_BOLD_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_TIMES")))

{

return FL_TIMES;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_TIMES_BOLD")))

{

return FL_TIMES_BOLD;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_TIMES_ITALIC")))

{

return FL_TIMES_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_TIMES_BOLD_ITALIC")))

{

return FL_TIMES_BOLD_ITALIC;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_SCREEN")))

{

return FL_SCREEN;

}

if ((! xmlStrcmp (XMLvalue, (const xmlChar *)" FL_SCREEN_BOLD")))

{

return FL_SCREEN_BOLD;

}

}

void parseStyles (xmlDocPtr doc, xmlNodePtr cur, const char *name)

{

while (cur! = NULL)

{

uri = xmlGetProp (cur, (const xmlChar *)" name");

if ((! xmlStrcmp (uri, (const xmlChar *)" Plain")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Line Comments")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Block Comments")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Strings")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Directives")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Types")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

if ((! xmlStrcmp (uri, (const xmlChar *)" Keywords")))

{

color = xmlGetProp (cur, (const xmlChar *)" color");

font = xmlGetProp (cur, (const xmlChar *)" font");

stylebuftemp. color = XMLValue2FLColor (color);

stylebuftemp. font = XMLValue2FLfont (font);

stylebuftemp. size = TS;

styletable = stylebuftemp;

}

cur = cur->next;

}

}

void parseNodes (xmlDocPtr doc, xmlNodePtr cur, char *curNode)

{

xmlChar *key;

int exit (0);

cur = cur->xmlChildrenNode;

while (cur! = NULL)

{

if ((! xmlStrcmp (cur->name, (const xmlChar *) curNode)))

{

if ((! xmlStrcmp (cur->name, (const xmlChar *)" entry")))

{

parseStyles (doc, cur, «Plain»);

parseStyles (doc, cur, «Line Comments»);

parseStyles (doc, cur, «Block Comments»);

parseStyles (doc, cur, «Strings»);

parseStyles (doc, cur, «Directives»);

parseStyles (doc, cur, «Types»);

parseStyles (doc, cur, «Keywords»);

return;

}else

{

key = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);

if (strcmp (curNode, «type») == 0)

{

code_types. push_back ((const char *) key);

}else

{

code_keywords. push_back ((const char *) key);

}

xmlFree (key);

}

}

cur = cur->next;

}

return;

}

void parseXMLDoc (xmlDocPtr doc, char *nodeName, char *curNode)

{

xmlNodePtr cur;

cur = xmlDocGetRootElement (doc);

cur = cur->xmlChildrenNode;

while (cur! = NULL)

{

if ((! xmlStrcmp (cur->name, (const xmlChar *) nodeName)))

{

parseNodes (doc, cur, curNode);

}

cur = cur->next;

}

}

void loadHighlightingData ()

{

xmlDocPtr doc1;

const char * filename = «config. xml» ;

doc1 = xmlReadFile (filename, NULL, XML_PARSE_NONET);

if (is_valid (doc1, «schema. xsd») == 1)

{

int i = 0;

xmlDocPtr xmldoc = NULL;

xmlChar *uri;

if ((xmldoc = xmlReadFile (filename, NULL, 0)) == NULL) return;

xmlNodePtr cur = xmlDocGetRootElement (xmldoc);

parseXMLDoc (xmldoc, «style», «entry»);

parseXMLDoc (xmldoc, «keywords», «keyword»);

parseXMLDoc (xmldoc, «types», «type»);

xmlFree (uri);

xmlFree (color);

xmlFree (font);

}else

{

// error in XML

xmlErrorPtr XMLError;

XMLError = xmlGetLastError ();

fl_alert (XMLError->message);

}

}

// 'style_parse () ' - Parse text and produce style data.

void

style_parse (const char *text,

char *style,

int length) {

char current;

int col;

int last;

char buf [255],

*bufptr;

const char *temp;

// Style letters:

// A — Plain

// B — Line comments

// C — Block comments

// D — Strings

// E — Directives

// F — Types

// G — Keywords

for (current = *style, col = 0, last = 0; length > 0; length — -, text ++) {

if (current == 'B' || current == 'F' || current == 'G') current = 'A';

if (current == 'A') {

// Check for directives, comments, strings, and keywords.

if (col == 0 && *text == '#') {

// Set style to directive

current = 'E';

} else if (strncmp (text, «// «,

2) == 0) {

current = 'B';

for (; length > 0 && *text! = 'n'; length — -, text ++) *style++ = 'B';

if (length == 0) break;

} else if (strncmp (text, «/*» ,

2) == 0) {

current = 'C';

} else if (strncmp (text, «» «,

2) == 0) {

// Quoted quote.

*style++ = current;

*style++ = current;

text ++;

length — -;

col += 2;

continue;

} else if (*text == '" ') {

current = 'D';

} else if (! last && (islower ((*text) &255) || *text == '_')) {

// Might be a keyword.

for (temp = text, bufptr = buf;

(islower ((*temp) &255) || *temp == '_') && bufptr < (buf + sizeof (buf) — 1);

*bufptr++ = *temp++);

if (! islower ((*temp) &255) && *temp! = '_') {

*bufptr = '';

bufptr = buf;

it = find (code_types. begin (), code_types. end (), bufptr);

it1 = find (code_keywords. begin (), code_keywords. end (), bufptr);

if (it! = code_types. end ())

{

while (text < temp) {

*style++ = 'F';

text ++;

length — -;

col ++;

}

text — -;

length ++;

last = 1;

continue;

} else if (it1! = code_keywords. end ())

{

while (text < temp) {

*style++ = 'G';

text ++;

length — -;

col ++;

}

text — -;

length ++;

last = 1;

continue;

}

}

}

} else if (current == 'C' && strncmp (text, «*/» ,

2) == 0) {

// Close a C comment.

*style++ = current;

*style++ = current;

text ++;

length — -;

current = 'A';

col += 2;

continue;

} else if (current == 'D') {

// Continuing in string.

if (strncmp (text, «» «,

2) == 0) {

// Quoted end quote.

*style++ = current;

*style++ = current;

text ++;

length — -;

col += 2;

continue;

} else if (*text == '" ') {

// End quote.

*style++ = current;

col ++;

current = 'A';

continue;

}

}

// Copy style info.

if (current == 'A' && (*text == '')) *style++ = 'G';

else *style++ = current;

col ++;

last = isalnum ((*text) &255) || *text == '_' || *text == '. ';

if (*text == 'n')

// Reset column and possibly reset the style

col = 0;

if (current == 'B'

}

}

// 'style_init () ' - Initialize the style buffer.

void

style_init (void) {

char *style = new char [textbuf->length () + 1];

char *text = textbuf->text ();

memset (style, 'A', textbuf->length ());

style [textbuf->length ()] = '';

if (! stylebuf) stylebuf = new Fl_Text_Buffer (textbuf->length ());

style_parse (text, style, textbuf->length ());

stylebuf->text (style);

delete [] style;

free (text);

}

// 'style_unfinished_cb () ' - Update unfinished styles.

void

style_unfinished_cb (int, void*) {

}

// 'style_update () ' - Update the style buffer.

void

style_update (int pos, // I — Position of update

int nInserted, // I — Number of inserted chars

int nDeleted, // I — Number of deleted chars

int /*nRestyled*/, // I — Number of restyled chars

const char * /*deletedText*/, // I — Text that was deleted

void *cbArg) { // I — Callback data

intstart, // Start of text

end; // End of text

charlast, // Last style on line

*style, // Style data

*text; // Text data

// If this is just a selection change, just unselect the style buffer.

if (nInserted == 0 && nDeleted == 0) {

stylebuf->unselect ();

return;

}

// Track changes in the text buffer.

if (nInserted > 0) {

// Insert characters into the style buffer.

style = new char [nInserted + 1];

memset (style, 'A', nInserted);

style [nInserted] = '';

stylebuf->replace (pos, pos + nDeleted, style);

delete [] style;

} else {

// Just delete characters in the style buffer.

stylebuf->remove (pos, pos + nDeleted);

}

// Select the area that was just updated to avoid unnecessary

// callbacks.

stylebuf->select (pos, pos + nInserted — nDeleted);

// Re-parse the changed region; we do this by parsing from the

// beginning of the previous line of the changed region to the end of

// the line of the changed region. Then we check the last

// style character and keep updating if we have a multi-line

// comment character.

start = textbuf->line_start (pos);

// if (start > 0) start = textbuf->line_start (start — 1);

end = textbuf->line_end (pos + nInserted);

text = textbuf->text_range (start, end);

style = stylebuf->text_range (start, end);

if (start==end)

last = 0;

else

last = style [end — start — 1];

// printf («start = %d, end = %d, text = „%s“, style = „%s“, last='%c'. n» ,

// start, end, text, style, last);

style_parse (text, style, end — start);

// printf («new style = „%s“, new last='%c'. n» ,

// style, style [end — start — 1]);

stylebuf->replace (start, end, style);

((Fl_Text_Editor *) cbArg) — >redisplay_range (start, end);

if (start==end || last! = style [end — start — 1]) {

// printf («Recalculate the rest of the buffer stylen»);

// Either the user deleted some text, or the last character

// on the line changed styles, so reparse the

// remainder of the buffer.

free (text);

free (style);

end = textbuf->length ();

text = textbuf->text_range (start, end);

style = stylebuf->text_range (start, end);

style_parse (text, style, end — start);

stylebuf->replace (start, end, style);

((Fl_Text_Editor *) cbArg) — >redisplay_range (start, end);

}

free (text);

free (style);

}

// Editor window functions and class.

void save_cb ();

void saveas_cb ();

void find2_cb (Fl_Widget*, void*);

void replall_cb (Fl_Widget*, void*);

void replace2_cb (Fl_Widget*, void*);

void replcan_cb (Fl_Widget*, void*);

class EditorWindow: public Fl_Double_Window {

public:

EditorWindow (int w, int h, const char* t);

~EditorWindow ();

Fl_Window *replace_dlg;

Fl_Input *replace_find;

Fl_Input *replace_with;

Fl_Button *replace_all;

Fl_Return_Button *replace_next;

Fl_Button *replace_cancel;

Fl_Text_Editor *editor;

char search [256];

};

EditorWindow: EditorWindow (int w, int h, const char* t): Fl_Double_Window (w, h, t) {

replace_dlg = new Fl_Window (300, 105, «Replace»);

replace_find = new Fl_Input (80, 10, 210, 25, «Find: «);

replace_find->align (FL_ALIGN_LEFT);

replace_with = new Fl_Input (80, 40, 210, 25, «Replace: «);

replace_with->align (FL_ALIGN_LEFT);

replace_all = new Fl_Button (10, 70, 90, 25, «Replace All»);

replace_all->callback ((Fl_Callback *) replall_cb, this);

replace_next = new Fl_Return_Button (105, 70, 120, 25, «Replace Next»);

replace_next->callback ((Fl_Callback *) replace2_cb, this);

replace_cancel = new Fl_Button (230, 70, 60, 25, «Cancel»);

replace_cancel->callback ((Fl_Callback *) replcan_cb, this);

replace_dlg->end ();

replace_dlg->set_non_modal ();

editor = 0;

*search = (char) 0;

loadHighlightingData ();

}

EditorWindow: ~EditorWindow () {

delete replace_dlg;

}

int check_save (void) {

if (! changed) return 1;

int r = fl_choice («The current file has not been saved. n»

" Would you like to save it now?" ,

" Cancel", «Save», «Don't Save»);

if (r == 1) {

save_cb (); // Save the file.

return! changed;

}

return (r == 2)? 1: 0;

}

int loading = 0;

void load_file (const char *newfile, int ipos)

void save_file (const char *newfile) {

if (textbuf->savefile (newfile))

fl_alert («Error writing to file '%s': n%s.», newfile, strerror (errno));

else

strcpy (filename, newfile);

changed = 0;

textbuf->call_modify_callbacks ();

}

void copy_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

Fl_Text_Editor: kf_copy (0, e->editor);

}

void cut_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

Fl_Text_Editor: kf_cut (0, e->editor);

}

void delete_cb (Fl_Widget*, void*) {

textbuf->remove_selection ();

}

void find_cb (Fl_Widget* w, void* v) {

EditorWindow* e = (EditorWindow*) v;

const char *val;

val = fl_input («Search String:», e->search);

if (val! = NULL) {

// User entered a string — go find it!

strcpy (e->search, val);

find2_cb (w, v);

}

}

void find2_cb (Fl_Widget* w, void* v) {

EditorWindow* e = (EditorWindow*) v;

if (e->search == '') {

// Search string is blank; get a new one.

find_cb (w, v);

return;

}

int pos = e->editor->insert_position ();

int found = textbuf->search_forward (pos, e->search, &pos);

if (found) {

// Found a match; select and update the position.

textbuf->select (pos, pos+strlen (e->search));

e->editor->insert_position (pos+strlen (e->search));

e->editor->show_insert_position ();

}

else fl_alert («No occurrences of '%s' found!», e->search);

}

void set_title (Fl_Window* w) {

if (filename == '') strcpy (title, «Untitled»);

else {

char *slash;

slash = strrchr (filename, '/');

#ifdef WIN32

if (slash == NULL) slash = strrchr (filename, '\');

#endif

if (slash! = NULL) strcpy (title, slash + 1);

else strcpy (title, filename);

}

if (changed) strcat (title, «(modified)»);

w->label (title);

}

void changed_cb (int, int nInserted, int nDeleted, int, const char*, void* v) nDeleted) &&! loading) changed = 1;

EditorWindow *w = (EditorWindow *) v;

set_title (w);

if (loading) w->editor->show_insert_position ();

void new_cb (Fl_Widget*, void*) {

if (! check_save ()) return;

filename = '';

textbuf->select (0, textbuf->length ());

textbuf->remove_selection ();

changed = 0;

textbuf->call_modify_callbacks ();

}

void open_cb (Fl_Widget*, void*) {

if (! check_save ()) return;

Fl_Native_File_Chooser fnfc;

fnfc. title («Open file»);

fnfc. type (Fl_Native_File_Chooser: BROWSE_FILE);

if (fnfc. show ()) return;

load_file (fnfc. filename (), — 1);

}

void insert_cb (Fl_Widget*, void *v) {

Fl_Native_File_Chooser fnfc;

fnfc. title («Insert file»);

fnfc. type (Fl_Native_File_Chooser: BROWSE_FILE);

if (fnfc. show ()) return;

EditorWindow *w = (EditorWindow *) v;

load_file (fnfc. filename (), w->editor->insert_position ());

}

void paste_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

Fl_Text_Editor: kf_paste (0, e->editor);

}

int num_windows = 0;

void close_cb (Fl_Widget*, void* v) {

EditorWindow* w = (EditorWindow*) v;

if (num_windows == 1) {

if (! check_save ())

return;

}

w->hide ();

w->editor->buffer (0);

textbuf->remove_modify_callback (style_update, w->editor);

textbuf->remove_modify_callback (changed_cb, w);

Fl: delete_widget (w);

num_windows—;

if (! num_windows) exit (0);

}

void quit_cb (Fl_Widget*, void*) {

if (changed &&! check_save ())

return;

exit (0);

}

void replace_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

e->replace_dlg->show ();

}

void replace2_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

const char *find = e->replace_find->value ();

const char *replace = e->replace_with->value ();

if (find == '') {

// Search string is blank; get a new one.

e->replace_dlg->show ();

return;

}

e->replace_dlg->hide ();

int pos = e->editor->insert_position ();

int found = textbuf->search_forward (pos, find, &pos);

if (found) {

// Found a match; update the position and replace text.

textbuf->select (pos, pos+strlen (find));

textbuf->remove_selection ();

textbuf->insert (pos, replace);

textbuf->select (pos, pos+strlen (replace));

e->editor->insert_position (pos+strlen (replace));

e->editor->show_insert_position ();

}

else fl_alert («No occurrences of '%s' found!», find);

}

void replall_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

const char *find = e->replace_find->value ();

const char *replace = e->replace_with->value ();

find = e->replace_find->value ();

if (find == '') {

// Search string is blank; get a new one.

e->replace_dlg->show ();

return;

}

e->replace_dlg->hide ();

e->editor->insert_position (0);

int times = 0;

// Loop through the whole string

for (int found = 1; found;) {

int pos = e->editor->insert_position ();

found = textbuf->search_forward (pos, find, &pos);

if (found) {

// Found a match; update the position and replace text.

textbuf->select (pos, pos+strlen (find));

textbuf->remove_selection ();

textbuf->insert (pos, replace);

e->editor->insert_position (pos+strlen (replace));

e->editor->show_insert_position ();

times++;

}

}

if (times) fl_message («Replaced %d occurrences.», times);

else fl_alert («No occurrences of '%s' found!», find);

}

void replcan_cb (Fl_Widget*, void* v) {

EditorWindow* e = (EditorWindow*) v;

e->replace_dlg->hide ();

}

void save_cb () {

if (filename == '') {

// No filename — get one!

saveas_cb ();

return;

}

else save_file (filename);

}

void saveas_cb () {

Fl_Native_File_Chooser fnfc;

fnfc. title («Save File As?»);

fnfc. type (Fl_Native_File_Chooser: BROWSE_SAVE_FILE);

if (fnfc. show ()) return;

save_file (fnfc. filename ());

}

Fl_Window* new_view ();

void view_cb (Fl_Widget*, void*) {

Fl_Window* w = new_view ();

w->show ();

}

Fl_Menu_Item menuitems [] = {

{ «&File», 0, 0, 0, FL_SUBMENU },

{ «&New File», 0, (Fl_Callback *) new_cb },

{ «&Open File.», FL_COMMAND + 'o', (Fl_Callback *) open_cb },

{ «&Insert File.», FL_COMMAND + 'i', (Fl_Callback *) insert_cb, 0, FL_MENU_DIVIDER },

{ «&Save File», FL_COMMAND + 's', (Fl_Callback *) save_cb },

{ «Save File &As.», FL_COMMAND + FL_SHIFT + 's', (Fl_Callback *) saveas_cb, 0, FL_MENU_DIVIDER },

{ «New &View», FL_ALT + 'v', (Fl_Callback *) view_cb, 0 },

{ «&Close View», FL_COMMAND + 'w', (Fl_Callback *) close_cb, 0, FL_MENU_DIVIDER },

{ «E&xit», FL_COMMAND + 'q', (Fl_Callback *) quit_cb, 0 },

{ 0 },

{ «&Edit», 0, 0, 0, FL_SUBMENU },

{ «Cu&t», FL_COMMAND + 'x', (Fl_Callback *) cut_cb },

{ «&Copy», FL_COMMAND + 'c', (Fl_Callback *) copy_cb },

{ «&Paste», FL_COMMAND + 'v', (Fl_Callback *) paste_cb },

{ «&Delete», 0, (Fl_Callback *) delete_cb },

{ 0 },

{ «&Search», 0, 0, 0, FL_SUBMENU },

{ «&Find.», FL_COMMAND + 'f', (Fl_Callback *) find_cb },

{ «F&ind Again», FL_COMMAND + 'g', find2_cb },

{ «&Replace.», FL_COMMAND + 'r', replace_cb },

{ «Re&place Again», FL_COMMAND + 't', replace2_cb },

{ 0 },

{ 0 }

};

Fl_Window* new_view () {

EditorWindow* w = new EditorWindow (660, 400, title);

w->begin ();

Fl_Menu_Bar* m = new Fl_Menu_Bar (0, 0, 660, 30);

m->copy (menuitems, w);

w->editor = new Fl_Text_Editor (0, 30, 660, 370);

w->editor->textfont (FL_COURIER);

w->editor->textsize (TS);

w->editor->buffer (textbuf);

w->editor->highlight_data (stylebuf, styletable,

sizeof (styletable) / sizeof (styletable [0]),

'A', style_unfinished_cb, 0);

textbuf->text ();

style_init ();

w->end ();

w->resizable (w->editor);

w->callback ((Fl_Callback *) close_cb, w);

textbuf->add_modify_callback (style_update, w->editor);

textbuf->add_modify_callback (changed_cb, w);

textbuf->call_modify_callbacks ();

num_windows++;

return w;

}

int main (int argc, char **argv) {

LIBXML_TEST_VERSION;

textbuf = new Fl_Text_Buffer;

style_init ();

Fl_Window* window = new_view ();

window->show (1, argv);

if (argc > 1) load_file (argv [1], — 1);

return Fl: run ();

}

ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ вСсь тСкст
Π—Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ