Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° ΡΠ·ΡΠΊΠΎΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ
Π Π΄Π°Π½Π½ΠΎΠΉ ΠΏΠΎΡΡΠ½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΊΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡΡΡ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΊΡΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΏΠΎ Π΄ΠΈΡΡΠΈΠΏΠ»ΠΈΠ½Π΅ «Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΠΠ». Π¦Π΅Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΡΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° — Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ°. ΠΠΎΠ½ΡΡΡΡΡΠΈΠΈ ΡΠ·ΡΠΊΠ° ΠΈ ΡΡΠΈΠ»ΠΈ Π΄Π»Ρ Π½ΠΈΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΠΈΠ· XML ΡΠ°ΠΉΠ»Π°. ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ XML ΡΠ°ΠΉΠ»Π° Π½Π° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ XML Schema. ΠΠ°Π½Π½Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΊΡΡΠΎΠ²ΡΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠΎΠΌ Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ… Π§ΠΈΡΠ°ΡΡ Π΅ΡΡ >
Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° ΡΠ·ΡΠΊΠΎΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ (ΡΠ΅ΡΠ΅ΡΠ°Ρ, ΠΊΡΡΡΠΎΠ²Π°Ρ, Π΄ΠΈΠΏΠ»ΠΎΠΌ, ΠΊΠΎΠ½ΡΡΠΎΠ»ΡΠ½Π°Ρ)
ΠΠ½Π½ΠΎΡΠ°ΡΠΈΡ
Π Π΄Π°Π½Π½ΠΎΠΉ ΠΏΠΎΡΡΠ½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ Π·Π°ΠΏΠΈΡΠΊΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡΡΡ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΊΡΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΏΠΎ Π΄ΠΈΡΡΠΈΠΏΠ»ΠΈΠ½Π΅ «Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΠΠ». Π¦Π΅Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΡΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° — Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΎΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ°. ΠΠΎΠ½ΡΡΡΡΡΠΈΠΈ ΡΠ·ΡΠΊΠ° ΠΈ ΡΡΠΈΠ»ΠΈ Π΄Π»Ρ Π½ΠΈΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΠΈΠ· XML ΡΠ°ΠΉΠ»Π°. ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ XML ΡΠ°ΠΉΠ»Π° Π½Π° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ XML Schema.
ΠΠ»Ρ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΡ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° FLTK 1.3, Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ XML — Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° LibXML2.
Π ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ 1 ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½ ΡΠ΅ΠΊΡΡ XML ΡΠ°ΠΉΠ»Π° config. xml, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅Π³ΠΎΡΡ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ ΠΎ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠ΅ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ°, Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ 2 ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½ ΡΠ΅ΠΊΡΡ XML Schema ΡΠ°ΠΉΠ»Π° schema. xml, ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 3 ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ.
ΠΠ½Π½ΠΎΡΠ°ΡΠΈΡ
1. Π€Π°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
1.1 Π€ΠΎΡΠΌΠ°Ρ ΡΠ°ΠΉΠ»Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
1.2 Π€ΠΎΡΠΌΠ°Ρ ΡΠ°ΠΉΠ»Π° ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ
2. Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
2.1 ΠΠ°Π³ΡΡΠ·ΠΊΠ° ΡΠ°ΠΉΠ»Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
2.2 Π Π°Π·Π±ΠΎΡ ΡΠ΅ΠΊΡΡΠ° ΠΈ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ΠΌΡ ΡΡΠΈΠ»Π΅ΠΉ
3. Π’Π΅ΡΡΠΎΠ²ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 1
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 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[0] = 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. ΠΠ΅ΡΠ±Π΅ΡΡ Π¨ΠΈΠ»Π΄Ρ «ΠΠΎΠ»Π½ΡΠΉ ΡΠΏΡΠ°Π²ΠΎΡΠ½ΠΈΠΊ ΠΏΠΎ XML», 2011. — 752 Ρ.
2. Π. ΠΠ΅ΠΉΠ³Π΅Π», Π. ΠΠ²ΡΠ΅Π½, Π. ΠΠ»ΠΈΠ½Π½, Π. Π‘ΠΊΠΈΠ½Π½Π΅Ρ, Π. Π£ΠΎΡΡΠΎΠ½ ΠΠΎΡΡΡΠΎΠ΅Π½ΠΈΠ΅ Π³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°.
3. ΠΠ½Π΄ΡΡ Π’ΡΠΎΠ΅Π»ΡΠ΅Π½ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° FLTK 1.3, 2010. — 752 Ρ.
4. Π. Π. ΠΠ°Π±ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° LibXML2. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ 2013.
ΡΠ°ΠΉΠ» ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠ° ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΡΡΠΈΠ»Ρ
ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ 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[0] = 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[1] = 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[2] = 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[3] = 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[4] = 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[5] = 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[6] = 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')
}
}
// '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)
loading = 1;
int insert = (ipos ≠ -1);
changed = insert;
if (!insert) strcpy (filename, «»);
int r;
if (!insert) r = textbuf->loadfile (newfile);
else r = textbuf->insertfile (newfile, ipos);
//changed = changed
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[0] == '') {
// 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[0] == '') 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)
if ((nInserted
void new_cb (Fl_Widget*, void*) {
if (!check_save ()) return;
filename[0] = '';
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[0] == '') {
// 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[0] == '') {
// 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[0] == '') {
// 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 ();
}