SPIS TREŚCI |
|
Podrozdziały |
W naszym serwisie publikujemy mnóstwo programów komputerowych dla uczniów. Aby poprawić ich czytelność, są one kolorowane. Poniżej mamy prosty przykład:
Bez kolorowania | Z kolorowaniem |
---|---|
// NWW // Data : 2.04.2008 // (C)2008 mgr Jerzy Wałaszek //---------------------------- #include <iostream> using namespace std; int main() { unsigned long long a,b,t,ab; cin >> a >> b; ab = a * b; while(b) { t = b; b = a % b; a = t; } ab /= a; cout << ab << endl << endl; return 0; } |
// NWW // Data : 2.04.2008 // (C)2008 mgr Jerzy Wałaszek //---------------------------- #include <iostream> using namespace std; int main() { unsigned long long a,b,t,ab; cin >> a >> b; ab = a * b; while(b) { t = b; b = a % b; a = t; } ab /= a; cout << ab << endl << endl; return 0; } |
Ręczne kolorowanie programów jest bardzo żmudne i niewdzięczne - często coś umyka i nie zostaje należycie pokolorowane. Poza tym zajmuje cenny czas, którego nikt z nas nie ma zbyt wiele. Dlatego opracowałem prosty skrypt w języku JavaScript, który koloruje składnię programów w następujących językach programowania:
Skrypt ten jest intensywnie wykorzystywany do kolorowania składni programów publikowanych w naszym serwisie.
Skrypt powinien znajdować się w pliku o nazwie h.js i dołączamy go na początku kodu HTML strony za pomocą wpisu (najlepiej w nagłówku <head> ... </head>):
<script type="text/javascript" src="h.js"></script>
Dodatkowo do strony należy dołączyć arkusz stylów definiujący kolory poszczególnych elementów składni. Arkusz ten powinien być w pliku h.ccs i dołączamy go do kodu strony w sekcji <head> za pomocą wpisu:
<link rel="stylesheet" type="text/css" href="h.css">
Jeśli na swoich stronach używasz stałego pliku arkusza stylów, to treść pliku h.css możesz po prostu wstawić do swojego pliku. Też powinno działać.
Nasz skrypt koloruje tylko teksty programów zawarte w znacznikach <pre> w kodzie HTML strony. Znacznikowi obejmującemu tekst programu należy nadać odpowiedni identyfikator w zależności od języka programowania:
Na końcu strony, przed zamykającym znacznikiem </body> należy umieścić wpis:
<script type="text/javascript">pcba()</script>
Oto przykładowa zawartość prostej strony HTML z kolorowanym kodem w języku C++ (na czerwono zaznaczyłem istotne elementy):
<html> <head> <title>Mój kolorowy program w C++</title> <link rel="stylesheet" type="text/css" href="h.css"> <script type="text/javascript" src="h.js"></script> </head> <body> <pre id="cpp"> // NWW // Data : 2.04.2008 // (C)2008 mgr Jerzy Wałaszek //---------------------------- #include <iostream> using namespace std; int main() { unsigned long long a,b,t,ab; cin >> a >> b; ab = a * b; while(b) { t = b; b = a % b; a = t; } ab /= a; cout << ab << endl << endl; return 0; } </pre> <script type="text/javascript">pcba()</script> </body> </html> |
Poniżej masz hiperłącza do plików, które należy pobrać (kliknij prawym przyciskiem myszki i wybierz opcję "zapisz element docelowy"):
h.js - skrypt
kolorujący składnię
h.css - arkusz stylów
współpracujący ze skryptem
Plik h.css definiuje kolory poszczególnych elementów składni za pomocą klas:
.c - komentarz
.i - instrukcja
.n - liczba
.t - tekst
.v - zmienna/stała/funkcja
.pp - preprocesor (w asemblerze kolor mnemoników oraz
rejestrów procesora)
Zawartość pliku h.css |
---|
.c { color: #008000; font-style: italic } .i { color: #000000; font-weight: bold; } .n { color: #0000FF; } .pp { color: #003366; font-weight: bold; } .t { color: #FF0000; } .v { color: #660033; } |
Plik h.js jest skryptem w języku JavaScript. Zawiera on kilka funkcji:
isAlpha(znak,język) - zwraca true, jeśli w danym języku znak może być zinterpretowany jako część nazwy lub liczby. Język jest określany za pomocą literek:
język = "p" - Pascal
język = "c" - C++
język = "b" - Basic
język = "j" - JavaScript
język = "a" - MASM
isDigit(znak,język) - zwraca true, jeśli znak może zostać w danym języku zinterpretowany jako pierwszy znak liczby. Język określany jak wyżej.
highlight(obiekt,język) - obiekt musi być obiektem znacznika <pre>. Dokonuje kolorowania składni wewnątrz obiektu zgodnie z regułami języka. Język określany jak wyżej.
pcba() - funkcja wywoływana na stronie WWW, zawierającej znaczniki <pre id="...">, które obejmują teksty programów do pokolorowania składni. Wywołujemy ją na końcu strony - ważne, w przeciwnym razie skrypt może nie działać prawidłowo.
Zawartość pliku h.js |
---|
// Kolorowanie składni w C++, Pascalu, Basicu, Javascript i Asemblerze // (C)2011 mgr Jerzy Wałaszek //-------------------------------------------- // Wywołanie z ustawionymi znacznikami: // <pre id="pas_n"|"cpp_n"|"bas_n"|"jsc_n"|"asm_n"> // pcba() //-------------------------------------------- function isAlpha(x,lng) { switch(lng) { case "p" : return (x >= "0" && x <= "9") || (x >= "A" && x <= "Z") || (x >= "a" && x <= "z") || ("_#$".indexOf(x) >= 0) case "c" : case "j" : return (x >= "0" && x <= "9") || (x >= "A" && x <= "Z") || (x >= "a" && x <= "z") || (x == "_") case "b" : return (x >= "0" && x <= "9") || (x >= "A" && x <= "Z") || (x >= "a" && x <= "z") || ("_$".indexOf(x) >= 0) case "a" : return (x >= "0" && x <= "9") || (x >= "A" && x <= "Z") || (x >= "a" && x <= "z") || ("_$?%.@".indexOf(x) >= 0) } } function isDigit(x,lng) { switch(lng) { case "p" : return x == '#' || x == '$' || (x >= '0' && x <= '9') case "c" : case "j" : case "a" : case "b" : return x >= '0' && x <= '9' } } function highlight(obj,lng) { var t = obj.innerHTML + " " var keys switch(lng) { case "p" : keys = "and array as begin case class const constructor destructor div do " + "downto else end end. except file finally for function goto if " + "implementation in inherited interface is mod not object of on or " + "packed procedure program property raise record repeat set shl " + "shr then threadvar to try type unit until uses var while with xor" break case "c" : keys = "asm auto bool break case catch char class const const_cast " + "continue default delete do double dynamic_cast else enum " + "explicit extern false float for friend goto if inline int " + "long mutable namespace new operator private protected " + "public register reinterpret_cast return short signed " + "sizeof static static_cast struct switch template this throw " + "true try typedef typeid typename union unsigned using " + "virtual void volatile wchar_t while" break case "b" : keys = "$DYNAMIC $INCLUDE $LANG $STATIC ABS ACCESS ACOS ADD ALIAS ALLOCATE " + "ALPHA AND ANDALSO ANY APPEND AS ASC ASIN ASM ASSERT ASSERTWARN " + "ATAN2 ATN BASE BEEP BIN BINARY BIT BITRESET BITSET BLOAD BSAVE " + "BYREF BYTE BYVAL CALL CALLOCATE CASE CAST CBYTE CDBL CDECL CHAIN " + "CHDIR CHR CINT CIRCLE CLEAR CLNG CLNGINT CLOSE CLS COLOR COM " + "COMMAND COMMON CONDBROADCAST CONDCREATE CONDDESTROY CONDSIGNAL " + "CONDWAIT CONS CONST CONSTRUCTOR CONTINUE COS CPTR CSHORT CSIGN " + "CSNG CSRLIN CUBYTE CUINT CULNG CULNGINT CUNSG CURDIR CUSHORT " + "CUSTOM CVD CVI CVL CVLONGINT CVS CVSHORT DATA DATE DATEADD DATEDIFF " + "DATEPART DATESERIAL DATEVALUE DAY DEALLOCATE DECLARE DEFBYTE " + "DEFDBL DEFINT DEFLNG DEFLONGINT DEFSHORT DEFSNG DEFSTR DEFUBYTE " + "DEFUINT DEFULONGINT DEFUSHORT DELETE DESTRUCTOR DIM DIR DO DOUBLE DRAW " + "DYLIBFREE DYLIBLOAD DYLIBSYMBOL DYNAMIC ELSE ELSEIF ENCODING END " + "ENUM ENVIRON EOF EQV ERASE ERFN ERL ERMN ERR ERROR ESCAPE EXEC " + "EXEPATH EXIT EXP EXPLICIT EXPORT EXTERN FIELD FILEATTR FILECOPY " + "FILEDATETIME FILEEXISTS FILELEN FIX FLIP FOR FORMAT FRAC FRE " + "FREEFILE FUNCTION GET GETJOYSTICK GETKEY GETMOUSE GOSUB GOTO HEX " + "HIBYTE HIWORD HOUR IF IIF IMAGECONVERTROW IMAGECREATE IMAGEDESTROY " + "IMAGEINFO IMP IMPORT INKEY INP INPUT INSTR INSTRREV INT INTEGER IS " + "ISDATE KILL LBOUND LCASE LEFT LEN LET LIB LINE LOBYTE LOC LOCAL " + "LOCATE LOCK LOF LOG LONG LONGINT LOOP LOWORD LPOS LPRINT LPT LSET " + "LTRIM MID MINUTE MKD MKDIR MKI MKL MKLONGINT MKS MKSHORT MOD MONTH " + "MONTHNAME MULTIKEY MUTEXCREATE MUTEXDESTROY MUTEXLOCK MUTEXUNLOCK " + "NAKED NAME NAMESPACE NEW NEXT NOGOSUB NOKEYWORD NOT NOW OCT OFFSETOF ON " + "ERROR OPEN OPERATOR OPTION OR ORELSE OUT OUTPUT OVERLOAD PAINT " + "PALETTE PASCAL PCOPY PEEK PIPE PMAP POINT POINTER POKE POS PRESERVE " + "PRESET PRINT PRIVATE PROCPTR PROPERTY PROTECTED PSET PTR PUBLIC PUT " + "RANDOM RANDOMIZE READ REALLOCATE REDIM REM RESET RESTORE RESUME " + "RETURN RGB RGBA RIGHT RMDIR RND RSET RTRIM RUN SADD SCOPE SCREEN " + "SCREENCONTROL SCREENCOPY SCREENEVENT SCREENGLPROC SCREENINFO " + "SCREENLIST SCREENLOCK SCREENPTR SCREENRES SCREENSET SCREENSYNC " + "SCREENUNLOCK SCRN SECOND SEEK SELECT SETDATE SETENVIRON SETMOUSE " + "SETTIME SGN SHARED SHELL SHL SHORT SHR SIN SINGLE SIZEOF SLEEP " + "SPACE SPC SQR STATIC STDCALL STEP STICK STOP STR STRIG STRING STRPTR " + "SUB SWAP SYSTEM TAB TAN THEN THIS THREADCREATE THREADWAIT TIME TIMER " + "TIMESERIAL TIMEVALUE TO TRANS TRIM TYPE TYPEOF UBOUND UBYTE UCASE " + "UINTEGER ULONG ULONGINT UNION UNLOCK UNSIGNED UNTIL USHORT USING VAL " + "VALINT VALLNG VALUINT VALULNG VAR VARPTR VA_ARG VA_FIRST VA_NEXT VIEW " + "WAIT WBIN WCHR WEEKDAY WEEKDAYNAME WEND WHEX WHILE WIDTH WINDOW " + "WINDOWTITLE WINPUT WITH WOCT WRITE WSPACE WSTR WSTRING XOR YEAR " + "ZSTRING DEFINE ENDIF ENDMACRO IFDEF IFNDEF INCLIB INCLUDE LIBPATH " + "LANG MACRO PRAGMA UNDEF" break case "j" : keys = "abstract boolean break byte case catch char class const continue " + "debugger default delete do double else enum export extends false " + "final finally float for function goto if implements import in " + "instanceof int interface long native new null package private " + "protected public return short static super switch synchronized this " + "throw throws transient true try typeof var void volatile while with" break case "a" : keys = "EAX AX AH AL EBX BX BH BL ECX CX CH CL EDX DX DH DL SI ESI DI EDI BP EBD " + "SP ESP IP EIP CS DS SS ES FS GS AAA AAD AAM AAS ADC ADD AND " + "ARPL BOUND BSF BSR BSWAP BT BTC BTR BTS CALL CBW CDQ CLC CLD CLI CLTS CMC " + "CMP CMPS CMPXCHNG CWD CWDE DAA DAS DEC DIV ENTER ESC HLT IDIV IMUL IN INC " + "INS INT INTO INVD INVLPG IRET IRETD JA JAE JB JBE JC JCXZ JE JG JGE JL " + "JLE JMP JNA JNAE JNB JNBE JNC JNE JNG JNGE JNL JNLE JNO JNP JNS JNZ JO " + "JP JPE JPO JS JZ JCXZ JECXZ LAHF LAR LDS LEA LEAVE LES LFS LGDT LIDT LGS " + "LLDT LMSW LOCK LODS LOOP LOOPE LOOPZ LOOPNZ LOOPNE LSL LSS LTR MOV MOVS " + "MOVSX MOVZX MUL NEG NOP NOT OR OUT OUTS POP POPA POPAD POPF POPFD " + "PUSH PUSHA PUSHAD PUSHF PUSHFD RCL RCR " + "REP REPE REPZ REPNE REPNZ RET RETF ROL ROR SAHF SAL SHL SAR SBB SCAS SETAE " + "SETNB SETB SETNAE SETBE SETNA SETE SETZ SETNE SETNZ SETL SETNGE SETGE SETNL " + "SETLE SETNG SETG SETNLE SETS SETNS SETC SETNC SETO SETNO SETP SETPE SETNP " + "SETPO SGDT SIDT SHL SHR SHLD SHRD SLDT SMSW STC STD STOS STR SUN TEST VERR " + "VERW WAIT FWAIT WBINVD XCHG XLAT XLATB XOR " + "%OUT .186 .286 .286P .287 .386 .386P .387 .486 .486P .8086 .8087 .ALPHA "+ ".BREAK .CODE .CONST .CREF .DATA .DATA? .DOSSEG .ELSE .ELSEIF .ENDIF .ENDW " + ".ERR .ERR1 .ERR2 .ERRB .ERRDEF .ERRDIF .ERRDIFI .ERRE .ERRIDN .ERRIDNI " + ".ERRNB .ERRNDEF .ERRNZ .EXIT .FARDATA .FARDATA? .IF .LALL .LFCOND .LIST " + ".LISTALL .LISTIF .LISTMACRO .LISTMACROALL .MODEL .MSFLOAT .NO87 .NOCREF " + ".NOLIST .NOLISTIF .NOLISTMACRO .RADIX .REPEAT .UNTIL .SALL .SEQ .SFCOND " + ".STACK .STARTUP .TFCOND .UNTIL .UNTILCXZ .WHILE .XALL .XCREF .XLIST " + "ALIGN ASSUME BYTE CATSTR COMM COMMENT DB DD DF DOSSEG DQ DT DUP DW DWORD " + "ECHO ELSE ELSEIF ELSEIF1 ELSEIF2 ELSEIFB ELSEIFDEF ELSEIFDEF ELSEIFE " + "ELSEIFIDN ELSEIFNB ELSEIFNDEF END ENDIF ENDM ENDP ENDS EQU EVEN EXITM " + "EXTERN EXTRN EXTERNDEF FOR FORC FWORD GOTO GROUP IF IF1 IF2 IFB IFDEF " + "IFDIF IFDIFI IFE IFIDN IFIDNI IFNB IFNDEF INCLUDE INCLUDELIB INSTR INVOKE " + "IRP IRPC LABEL LOCAL MACRO NAME OPTION ORG PAGE POPCONTEXT PROC PROTO PTR " + "PUBLIC PURGE PUSHCONTEXT QWORD REAL4 REAL8 REAL10 RECORD REPEAT REPT " + "SBYTE SDWORD SEGMENT SIZESTR STRUC STRUCT SUBSTR SUBTITLE SUBTTL SWORD " + "TBYTE TEXTEQU TITLE TYPEDEF UNION WHILE WORD" break } keys = keys.split(" ") var s = "" var w = "" var ww var c_m = 0 // komentarz blokowy var c_s = 0 // komentarz wierszowy var k_w = 0 // literał var p_p = 0 // preprocesor var t_q = 0 // tekst w cudzysłowie var t_a = 0 // tekst w apostrofie var h_e = 0 // kod HTML var h_m = 0 // znacznik HTML var t_i = 0 // ignorowanie tekstu do końca wiersza var c,i for(i = 0; i < t.length; i++) { c = t.charAt(i) // // Specjalny kod HTML &nazwa; // if(h_e) { if(c == ";") h_e = 0 } // // Znacznik HTML // else if(h_m) { if(c == ">") h_m = 0 } // // ignorowanie reszty tekstu do końca wiersza // else if(t_i) { if(c == "\n") t_i = 0 } // // Komentarz blokowy // else if(c_m) { if( (lng == "p" && c == "}") || ( (lng == "c" || lng == "j") && c == "/" && t.charAt(i-1) == "*") || (lng == "b" && c == "/" && t.charAt(i-1) == "'")) { c_m = 0 s += c + "</span>" continue } } // // Komentarz jednowierszowy // else if(c_s) { if(c == "\n") { c_s = 0 s += "</span>" } } // // Preprocesor // else if(p_p) { if(c == "\n") { p_p = 0 s += "</span>" } } // // Tekst w cudzysłowach // else if(t_q) { if(c == "\\" && lng != "a") { if(t.charAt(i+1) == "\\" || t.charAt(i+1) == '"' || t.charAt(i+1) == "'") { s += c + t.charAt(i+1) i++ continue } } else if(c == '"') { t_q = 0 s += '"</span>' continue } } // // Tekst w apostrofach // else if(t_a) { if(c == "\\" && lng != "a") { if(t.charAt(i+1) == "\\" || t.charAt(i+1) == '"' || t.charAt(i+1) == "'") { s += c + t.charAt(i+1) i++ continue } } else if(c == "'") { t_a = 0 s += "'</span>" continue } } // // Instrukcja, zmienna, liczba // else if(k_w) // słowo - instrukcja, zmienna, liczba { if(isAlpha(c,lng)) { w += c continue } else { k_w = 0 if(lng=="b" || lng=="a") ww = w.toUpperCase() else if(lng == "p") ww = w.toLowerCase() else ww = w if(isDigit(w.charAt(0),lng)) { s += '<span class="n">' + w + '</span>' i-- continue } else if(lng == "b" && (s.substr(s.length-5) == "&" && (ww.charAt(0) == "H" || ww.charAt(0) == "O" || ww.charAt(0) == "B"))) { s = s.substr(0,s.length-5) s += '<span class="n">&' + ww + '</span>' i-- continue } else if(lng == "b" && w == "_") s += w else { q = -1 for(j = 0; j < keys.length; j++) if(ww == keys[j]) { q = j break } if(q >= 0) { if(lng == "b") { if(s.charAt(s.length-1) == "#") // preprocesor { p_p = 1 s = s.substr(0,s.length-1) s += '<span class="pp">#' + ww } else // zwykła instrukcja { w = w.toLowerCase() w = ww.charAt(0) + w.substr(1) s += '<span class="i">' + w + '</span>' if(w == "Rem") { c_s = 1 s += '<span class="c">' } } } else if(lng == "a") { if(q < 224) s += '<span class="pp">' + ww.toLowerCase() + '</span>' else s += '<span class="i">' + ww + '</span>' if(ww == "INCLUDE" || ww == "INCLUDELIB") t_i = 1 else if(ww == "OPTION" || ww == ".MODEL") { p_p = 1 s += '<span class="pp">' } } else { s += '<span class="i">' + w + '</span>' i-- continue } } else { s += '<span class="v">' + w + '</span>' i-- continue } } } } // // Rozpoznanie komentarza blokowego lub wierszowego // else if((lng == "c" || lng == "j") && c == "/") { if(t.charAt(i+1) == "*") { c_m = 1 s += '<span class="c">' } else if(t.charAt(i+1) == "/") { c_s = 1 s += '<span class="c">' } } else if((lng == "p" && c == "/" && t.charAt(i+1) == "/") || (lng == "b" && c == "'") || (lng == "a" && c == ";")) { c_s = 1 s += '<span class="c">' } else if((lng == "p" && c == "{") || (lng == "b" && c == "/" && t.charAt(i+1) == "'")) { c_m = 1 s += '<span class="c">' } // // Rozpoznanie instrukcji preprocesora // else if(lng == "c" && c == "#") { p_p = 1 s += '<span class="pp">' } // // Rozpoznanie tekstu w cudzysłowach - z wyjatkiem sekwencji \" // else if(c == '"') { if(lng == "a" || (lng != "p" && c == '"' && t.charAt(i-1) != "\\")) { t_q = 1 s += '<span class="t">' } } // // Rozpoznanie tekstu w apostrofach // else if(c == "'") { t_a = 1 s += '<span class="t">' } // // Rozpoznanie literału // else if(isAlpha(c,lng)) { k_w = 1 w = c continue } // // Rozpoznanie specjalnego kodu HTML &nazwa; // if(c == "&") h_e = 1 // // Rozpoznanie znacznika HTML // if(c == "<") h_m = 1 s += c } if(c_m) s += "</span>" if(c_s) s += "</span>" if(p_p) s += "</span>" if(t_q || t_a) s += "</span>" if(h_e) s += ";" if(h_m) s += ">" obj.innerHTML = "<pre>" + s + "</pre>" } // Funkcja rozsyłowa //------------------ function pcba() { var preElements = document.getElementsByTagName("pre") var i for(i = 0; i < preElements.length; i++) { var s_id = preElements[i].id var s = s_id.substr(0,3) if(s == "pas" || s == "cpp" || s == "bas" || s == "jsc" || s == "asm") highlight(preElements[i],s.charAt(0)) } } |
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2025 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.