Syntax highlighting using Mediawiki formatting: Difference between revisions

m
→‎{{header|Wren}}: Minor change
m (→‎{{header|Julia}}: change comment)
m (→‎{{header|Wren}}: Minor change)
(15 intermediate revisions by 4 users not shown)
Line 7:
'''bold-word''' and ''italic-word'' appears as '''bold-word''' and ''italic-word''.
<br><br>
This could be used to provide simple syntax-highlighting without the use of the relatively more expensive &lt;syntachighlightsyntaxhighlight&gt; tags or for languages not currently supported by Pygments.
A few languages on Rosetta Code are currently using schemes like this.
<br>
Line 35:
Handles upper-stropping Algol 68 sources (as used by ALGOL 68G and most other compilers).
 
''#CO Convert an upper-stropped Algol 68 source to "wiki" format #''
''# each line is preceeded by a space, #''
''# bold words are enclosed in &apos;&apos;&apos; and &apos;&apos;&apos; and comments in &apos;&apos; and &apos;&apos; #''
''# &apos;, &amp;, &lt; and &gt; are converted to &amp;apos; &amp;amp; &amp;lt; and &amp;gt; #''
''# everything else if output as is #''
'' quote-stropping, point-stropping and res-stropping is not suppoered''
''# the source is read from stand in and written to stand out #''
'' the source is read from stand in and written to stand out''
''# the last line in the file must end with a newline #''
'' the last line in the file must end with a newline''
''# { and } are assumed to be alternatives for ( and ), if { } should be #''
'' { and } are assumed to be alternatives for ( and ), if { } should be''
''# treated as comments ( as in ALGOL68RS/algol68toc ) #''
''# treated change rs style briefas comments to TRUE ( as in ALGOL68RS/algol68toc #)''
'' change rs style brief comments to TRUE''
''CO''
'''BEGIN'''
'''BOOL''' in string := '''FALSE''';
'''BOOL''' in brief comment := '''FALSE''';
'''INT''' rs comment depth := 0;
'''STRING''' comment delimiter := "";
''# TRUE if {} delimits a nestable brief comment, as in ALGOL 68RS and #''
Line 59 ⟶ 66:
);
'''CHAR''' nl = '''REPR''' 10; ''# newline character #''
'''INT''' error count := 0; ''# number of errors reported #''
'''STRING''' line := nl; ''# current source line #''
'''INT''' pos := '''LWB''' line; ''# current position in line #''
'''CHAR''' c := " "; ''# current source character #''
'''PROC''' error = ( '''STRING''' message )'''VOID''': ''# reports an error #''
'''BEGIN'''
error count +:= 1;
print( ( newline, newline, "**** ", message, newline ) )
'''END''' ''# error #'' ;
''# reports an unterminated construct ( e.g. string, comment ) #''
'''PROC''' unterminated = ( '''STRING''' construct )'''VOID''': error( "Unterminated " + construct );
'''PROC''' next char = '''VOID''': ''# gets the next source character, stores it in c #''
'''IF''' pos &lt;= '''UPB''' line '''THEN'''
Line 81 ⟶ 80:
'''THEN'''
line +:= nl; ''# have another line #''
posc := line[ pos := '''LWB''' line ];
c := line[ pos ];
pos +:= 1
'''ELSE'''
Line 89 ⟶ 87:
'''FI''' ''# next char #'' ;
'''PROC''' out char = ( '''CHAR''' ch )'''VOID''': ''# conveerts and outputs ch #''
'''IF''' ch = nl '''THEN''' print( ( newline, " " ) )
'''IF''' '''NOT''' in brief comment '''AND''' rs comment depth = 0 '''AND''' comment delimiter = "" '''THEN'''
print( ( newline, " " ) ) ''# newline not in a comment #''
'''ELSE''' ''# newline in a comment #''
italic delimiter; print( ( newline, " " ) ); italic delimiter
'''FI'''
'''ELIF''' ch = "&lt;" '''THEN''' print( ( "&amp;lt;" ) )
'''ELIF''' ch = "&gt;" '''THEN''' print( ( "&amp;gt;" ) )
Line 96 ⟶ 99:
'''ELSE''' print( ch )
'''FI''' ''# out char #'' ;
''# outputs the current character and gets the next #''
'''PROC''' out and next char = '''VOID''': '''BEGIN''' out char( c ); next char '''END''';
''# outputs a wiki start/end italic delimiter #''
'''PROC''' italic delimiter = '''VOID''': print( ( "&apos;&apos;" ) );
''# outputs a wiki start/end bold delimiter #''
'''PROC''' bold delimiter = '''VOID''': print( ( "&apos;&apos;&apos;" ) );
''# returns TRUE if the current character is a string delimiter #''
'''PROC''' have string delimiter = '''BOOL''': c = """";
''# returns TRUE if the current character can start a bold word #''
'''PROC''' have bold = '''BOOL''': c &gt;= "A" '''AND''' c &lt;= "Z";
''# outputs a brief comment to stand out #''
''# end char is the closing delimiter, #''
''# nested char is the opening delimiter for nestable brief comments #''
''# if nested char is blank, the brief comment does not nest #''
''# this handles ALGOL 68RS and algol68toc style {} comments #''
'''PROC''' copy brief comment = ( '''CHAR''' end char, '''CHAR''' nested char )'''VOID''':
'''BEGIN'''
out char( c );
'''WHILE''' next char;
'''NOT''' at eof '''AND''' c /= end char
'''DO'''
'''IF''' c = nested char '''AND''' nested char /= " " '''THEN'''
''# nested brief comment #''
copy brief comment( end char, nested char )
'''ELSE'''
''# notmal comment char #''
out char( c )
'''FI'''
'''OD''';
'''IF''' at eof '''THEN'''
''# unterminated comment #''
unterminated( """" + end char + """ comment" );
c := end char
'''FI''';
out char( c );
next char
'''END''' ''# copy brief comment #'' ;
'''PROC''' copy string = '''VOID''': ''# outputs a string denotation from the source #''
'''WHILE''' have string delimiter '''DO''' ''# within a string denotation, #''
'''WHILE''' out char( c ); ''# "" denotes the " character #''
next char;
'''NOT''' at eof '''AND''' '''NOT''' have string delimiter
'''DO''' '''SKIP''' '''OD''';
'''IF''' '''NOT''' have string delimiter '''THEN'''
unterminated( "string" );
c := """"
'''FI''';
out char( c );
next char
'''OD''' ''# copy string #'' ;
'''PROC''' get bold word = '''STRING''': ''# gets a bold word from then source #''
'''BEGIN'''
Line 150 ⟶ 111:
result
'''END''' ''# get bold word #'' ;
'''PROC''' copy to bold = '''STRING''': ''# copies the source to the output #''
'''IF''' at eof ''# until a bold word is encountered #''
'''THEN''' ""
'''ELSE''' '''STRING''' result := "";
'''WHILE''' out char( c );
next char;
'''NOT''' at eof
'''AND''' '''NOT''' have bold
'''DO''' '''SKIP''' '''OD''';
'''IF''' '''NOT''' at eof '''THEN''' result := get bold word '''FI''';
result
'''FI''' ''# copy to bold #'' ;
'''PROC''' bold word or comment = '''VOID''': ''# handles a bold COMMENT #''
'''IF''' '''STRING''' bold word := get bold word; ''# or other bold word #''
bold word = "CO" '''OR''' bold word = "COMMENT"
'''THEN'''
italic delimiter; ''# have a bold comment #''
'''STRING''' delimiter = bold word;
'''WHILE''' print( ( bold word ) );
bold word := copy to bold;
'''NOT''' at eof
'''AND''' bold word /= delimiter
'''DO''' '''SKIP''' '''OD''';
'''IF''' at eof '''THEN'''
unterminated( """" + delimiter + """ comment" )
'''FI''';
print( ( delimiter ) );
italic delimiter
'''ELSE''' ''# some other bold word #''
bold delimiter;
print( ( bold word ) );
bold delimiter
'''FI''' ''# bold word or comment #'' ;
''# copy the source to stand out, conveerting to wiki format #''
next char;
'''WHILE''' '''NOT''' at eof '''DO'''
'''IF''' cin = "#"string '''THEN''' ''# briefcurrently in a commentstring #''
in string := c /="""";
out and next char
'''ELIF''' in brief comment '''THEN''' ''# currently in a brief comment #''
in brief comment := c /= "#";
out and next char;
'''IF''' '''NOT''' in brief comment '''THEN''' italic delimiter '''FI'''
'''ELIF''' rs comment depth &gt; 0 '''THEN''' ''# currently in a nesting {...} comment #''
'''IF''' c = "}" '''THEN''' rs comment depth -:= 1 '''FI''';
out and next char;
'''IF''' rs comment depth &lt; 1 '''THEN''' italic delimiter '''FI'''
'''ELIF''' comment delimiter /= "" '''THEN''' ''# in a CO/COMMENT comment #''
'''IF''' '''NOT''' have bold '''THEN'''
out and next char ''# haven&apos;t reached a bold word #''
'''ELSE'''
'''STRING''' word = get bold word; ''# at the start of a bold word #''
print( ( word ) );
'''IF''' word = comment delimiter '''THEN'''
''# reached the end of the comment #''
italic delimiter;
comment delimiter := ""
'''FI'''
'''FI'''
'''ELIF''' c = """" '''THEN''' ''# start of a string or character denotation #''
out and next char;
in string := '''TRUE'''
'''ELIF''' c = "#" '''THEN''' ''# start of a brief comment such as this one #''
italic delimiter;
copyout briefand comment(next "#", " " )char;
italicin delimiterbrief comment := '''TRUE'''
'''ELIF''' c = "{" '''AND''' rs style brief comments '''THEN''' ''# nestable brief #''
italic delimiter; ''# nestable brief comment ( ALGOL 68RS and algol68toc ) #''
italicout delimiterand next char;
copy briefrs comment( "}",depth "{":= );1
italic delimiter
'''ELIF''' have string delimiter '''THEN''' ''# STRING or CHAR denotation #''
copy string
'''ELIF''' have bold '''THEN''' ''# have a bold word #''
bold'''STRING''' word or= commentget bold word;
'''ELSEIF''' word /= "CO" '''AND''' word /= "COMMENT" '''THEN'''
''# anything else print( ( "&apos;&apos;&apos;", word, "&apos;&apos;&apos;" ) ) ''# non-comment bold word #''
out char( c );'''ELSE'''
italic delimiter; ''# start of a bold comment #''
next char
print( ( word ) );
comment delimiter := word
'''FI'''
'''ELSE''' ''# anything else #''
out and next char
'''FI'''
'''OD''';
'''IF''' in string '''THEN''' print( ( "**** unterminated string", newline ) )
'''IFELIF''' errorin brief comment count &gt; 0 '''THEN''' print( ( "**** unterminated brief comment", newline ) )
''#'ELIF''' hadrs errorscomment processingdepth the&gt; source0 '''THEN''' print( ( "**** unterminated {...} comment", newline ) #'')
'''ELIF''' comment delimiter /= "" '''THEN''' print( ( "**** unterminated ", whole(comment error count, 0 ), " errors"delimiter, newline ) )
'''FI'''
'''END'''
 
=={{header|ALGOL W}}==
 
'''begin''' ''comment syntax highlight an Algol W source using Mediawiki formatting''
'' the source is read from standard input and written to standard output''
'' ;''
''% Algol W strings are limited to 256 characters in length so source lines %''
''% are limited to 256 characters %''
'''integer''' lineWidth, errorCount, lowerA, upperA, linePos, kwMax;
'''integer''' MAX_TOKEN_LENGTH;
'''string'''(1) nl;
'''string'''(256) line;
'''string'''(1) currChar, commentEnd;
'''string'''(9) '''array''' kw ( 1 :: 64 );
'''logical''' inString, inComment;
''% returns true if currChar is in the inclusive range low to high, false otherwise %''
'''logical''' '''procedure''' range( '''string'''(1) '''value''' low, high ) ; currChar &gt;= low '''and''' currChar &lt;= high;
'''procedure''' nextChar ; ''% gets the next source character %''
'''if''' linePos = lineWidth '''then''' '''begin'''
currChar := nl;
linePos := linePos + 1
'''end'''
'''else''' '''if''' linePos &gt; lineWidth '''then''' '''begin'''
readcard( line );
lineWidth := 256;
'''while''' lineWidth &gt; 1 '''and''' line( lineWidth - 1 // 1 ) = " " '''do''' lineWidth := lineWidth - 1;
linePos := 1;
currChar := line( 0 // 1 )
'''end'''
'''else''' '''begin'''
currChar := line( linePos // 1 );
linePos := linePos + 1
'''end''' nextChar ;
''% returns true if the current character can start an identifier, false otherwise %''
'''logical''' '''procedure''' identifierStartChar ; range( "a", "z" ) '''or''' range( "A", "Z" );
''% returns true if the current character can be pat of an identifier, false otherwise %''
'''logical''' '''procedure''' identifierChar ; identifierStartChar '''or''' range( "0", "9" ) '''or''' currChar = "_";
'''procedure''' outAndNextChar ; '''begin''' ''% output currChar and get the next %''
'''if''' currChar = "&apos;" '''then''' writeon( "&amp;apos;" )
'''else''' '''if''' currChar = "&amp;" '''then''' writeon( "&amp;amp;" )
'''else''' '''if''' currChar = "&lt;" '''then''' writeon( "&amp;lt;" )
'''else''' '''if''' currChar = "&gt;" '''then''' writeon( "&amp;gt;" )
'''else''' '''if''' currChar = nl '''then''' '''begin'''
'''if''' inComment '''then''' writeon( "&apos;&apos;" );
write( " " );
'''if''' inComment '''then''' writeon( "&apos;&apos;" )
'''end'''
'''else''' writeon( currChar );
nextChar
'''end''' outAndNextChar ;
'''procedure''' identifierOrKeyword ; '''begin''' ''% handle an indentifier or keyword %''
'''string'''(9) word, lWord;
'''integer''' wLength;
''% recursive keyword binary search %''
'''logical''' '''procedure''' isKeyword ( '''integer''' '''value''' low, high ) ;
'''if''' high &lt; low '''then''' '''false'''
'''else''' '''begin'''
'''integer''' mid;
mid := ( low + high ) '''div''' 2;
'''if''' kw( mid ) &gt; lWord '''then''' isKeyword( low, mid - 1 )
'''else''' '''if''' kw( mid ) = lWord '''then''' '''true'''
'''else''' isKeyword( mid + 1, high )
'''end''' binarySearchR ;
wLength := 0;
'''for''' chPos := 0 '''until''' 8 '''do''' '''begin'''
'''if''' identifierChar '''then''' '''begin'''
word( chPos // 1 ) := currChar;
lWord( chPos // 1 ) := '''if''' range( "A", "Z" ) '''then''' code( ( decode( currChar ) - upperA ) + lowerA )
'''else''' currChar;;
wLength := wLength + 1;
nextChar
'''end'''
'''else''' '''begin'''
lWord( chPos // 1 ) := " ";
word( chPos // 1 ) := " "
'''end''' if_identifierChar__
'''end''' for_chPos ;
'''if''' identifierChar '''then''' '''begin'''
''% all keywords are &lt;= 9 characters long so this must be an identifier %''
writeon( word );
'''while''' identifierChar '''do''' outAndNextChar
'''end'''
'''else''' '''if''' lWord = "comment" '''then''' '''begin'''
writeon( "&apos;&apos;comment" );
commentEnd := ";";
inComment := '''true'''
'''end'''
'''else''' '''if''' isKeyword( 1, kwMax ) '''then''' '''begin'''
writeon( "&apos;&apos;&apos;" );
'''for''' chPos := 0 '''until''' wLength - 1 '''do''' writeon( word( chPos // 1 ) );
writeon( "&apos;&apos;&apos;" )
'''end'''
'''else''' '''begin''' ''% identifier %''
'''for''' chPos := 0 '''until''' wLength - 1 '''do''' writeon( word( chPos // 1 ) )
'''end''' if_various_words
'''end''' identifierOrKeyword ;
s_w := 0; i_w := 1; ''% output formarting %''
MAX_TOKEN_LENGTH := 256;
nl := code( 10 );
lowerA := decode( "a" );
upperA := decode( "A" );
''% allow the program to continue after reaching end-of-file %''
ENDFILE := EXCEPTION( '''false''', 1, 0, '''false''', "EOF" );
''% ensure the first call to nextChar reads the first line %''
lineWidth := 256;
linePos := lineWidth + 1;
currChar := " ";
'''begin''' ''% keywords %''
'''procedure''' K ( '''string'''(9) '''value''' kwStr ) ; '''begin'''
kwMax := kwMax + 1;
kw( kwMax ) := kwStr
'''end''' K ;
kwMax := 0;
K("abs");K("algol");K("and");K("array");K("assert");K("begin");K("bits");
K("case");K("complex");K("div");K("do");K("else");K("end");K("false");
K("for");K("fortran");K("go");K("goto");K("if");K("integer");K("is");
K("logical");K("long");K("not");K("null");K("of");K("or");
K("procedure");K("real");K("record");K("reference");K("rem");K("result");
K("shl");K("short");K("shr");K("step");K("string");
K("then");K("to");K("true");K("until");K("value");K("while")
'''end''' keywords ;
inString := inComment := '''false''';
outAndNextChar;
'''while''' '''not''' XCPNOTED(ENDFILE) '''do''' '''begin'''
'''if''' inString '''then''' '''begin''' ''% in a string %''
inString := currChar '''not''' = """";
outAndNextChar;
'''end'''
'''else''' '''if''' inComment '''then''' '''begin''' ''% in a comment %''
inComment := currChar '''not''' = ";" '''and''' currChar '''not''' = commentEnd;
outAndNextChar;
'''if''' '''not''' inComment '''then''' writeon( "&apos;&apos;" );
'''end'''
'''else''' '''if''' identifierStartChar '''then''' identifierOrKeyword
'''else''' '''if''' currChar = """" '''then''' '''begin''' ''% string literal %''
outAndNextChar;
inString := '''true'''
'''end'''
'''else''' '''if''' currChar = "%" '''then''' '''begin''' ''% brief comment %''
writeon( "&apos;&apos;" );
commentEnd := "%";
inComment := '''true''';
outAndNextChar
'''end'''
'''else''' outAndNextChar
'''end''' while_not_ar_eof ;
'''if''' inComment '''then''' write( "**** unterminated comment" )
'''else''' '''if''' inString '''then''' write( "**** unterminated string" )
'''end'''.
=={{header|AWK}}==
 
Line 227 ⟶ 341:
'''BEGIN''' \
{
''# reserved word list as in gawk and treating getline as reserved ''
kw = "BEGIN/BEGINFILE/END/ENDFILE/" \
Line 241 ⟶ 354:
} ''# BEGIN''
{
{
printf( " " );
line = $0;
Line 269 ⟶ 382:
'''if'''( c == "\\" )
{
printfoutAndNextChar( "%s", c );
nextChar();
}
printfoutAndNextChar( "%s", c );
nextChar();
}
'''while'''( c != "\"" &amp;&amp; c != "" );
Line 290 ⟶ 401:
''# pattern''
bracketDepth = 0;
printfoutAndNextChar( "%s", c );
nextChar();
'''while'''( c != "" &amp;&amp; ( c != "/" || bracketDepth &gt; 0 ) )
{
'''if'''( c == "\\" || c == "[" )
{
'''if''' ( c == "[" )
{
bracketDepth ++;
}
printfoutAndNextChar( "%s", c );
nextChar();
}
'''else''' '''if'''( c == "]" )
Line 307 ⟶ 416:
bracketDepth --;
}
printfoutAndNextChar( "%s", c );
nextChar();
}
'''if'''( c != "/" )
Line 339 ⟶ 447:
{
''# something else''
printfoutAndNextChar( "%s", c );
nextChar();
}
}
Line 347 ⟶ 454:
printf( "\n" );
}
'''function''' outAndNextChar()
{
printf( "%s", c );
nextChar();
}
Line 359 ⟶ 472:
{
''# at end of line''
c lastC = c = "";
}
'''else'''
Line 370 ⟶ 483:
} ''# nextChar''
 
=={{header|Julia}}==
''#= Keywords in Julia. Handles two word reserved keywords. #= Also
#= handles nested comments such as this. =# =#
''#= Keywords in Julia. Note that though two word keywords are listed, they ''
=#''
'' only work if the two words are separated by a single space character. ''
'' #= Handles nested comments such as this. =#''
''=#''
'''const''' KEYWORDS = map(
w -&gt; Regex("^" * w * "\\W"),
sort(
[
raw"abstract \s+type",
"baremodule",
"begin",
"break",
"catch",
"const",
"continue",
"do",
"else",
"elseif",
"end",
"export",
"false",
"finally",
"for",
"function",
"global",
"if",
"import",
"in",
"isa",
"let",
"local",
"macro",
"module",
raw"mutable \s+struct",
"outer",
raw"primitive \s+type",
"quote",
"return",
"struct",
"true",
"try",
"using",
"while",
"where",
], rev = '''true''', by = length),
) ''# reorder to largest first then convert to Regex''
""" Find the #= =# delineated comment, including nested versions """
'''function''' nestedcommentlimits(s::AbstractString, startcomment = "#=", stopcomment = "=#")
either = Regex("$startcomment|$stopcomment", "sa")
depth, startpos, stoppos = 0, 0, 0
'''for''' (i, m) '''in''' enumerate(eachmatch(either, s))
'''if''' m.match == startcomment
startpos = startpos == 0 ? m.match.offset : startpos
depth += 1
'''else'''
stoppos = max(stoppos + 1, m.match.offset + 2)
depth -= 1
'''end'''
depth &lt;= 0 &amp;&amp; '''break'''
'''end'''
'''return''' startpos, stoppos
'''end'''
"""
Given a string, output a string that has been modified by adding surrounding
\'\' or \'\'\' bracketing for syntax highlighting of keywords and comments
"""
'''function''' partialhighlight(txt)
outtxt = Char[]
idx, len = 1, length(txt)
'''while''' idx &lt;= len
'''if''' !isvalid(txt, idx) ''# exclude internal positions of multibyte Char''
idx += 1
'''continue'''
'''end'''
c = txt[idx]
'''if''' c == &apos;\\&apos; ''# escape the next char, send as is''
push!(outtxt, c, txt[idx+1])
idx += 2
'''elseif''' c == &apos;\"&apos; ''# quotation start''
'''if''' idx &lt; len - 2 &amp;&amp; c == txt[idx+1] == txt[idx+2] ''# """ quotes """''
qlen = findfirst(r"(?<!\\)\"\"\""sa, txt[idx+3:'''end'''])
qlen == nothing &amp;&amp; error("error with terminator of quote at $idx")
app'''end'''!(outtxt, collect(replace(txt[idx:idx+qlen.stop+2], "\n" =&gt; "\n ")))
idx += qlen.stop + 3
'''else''' ''# " quote "''
qlen = findfirst(r"(?<!\\)\"", txt[idx+1:'''end'''])
qlen == nothing &amp;&amp; error("error with terminator of quote at $idx")
app'''end'''!(outtxt, collect(replace(txt[idx:idx+qlen.stop+1], "\n" =&gt; "\n ")))
idx += qlen.stop + 2
'''end'''
'''elseif''' c == &apos;#&apos; &amp;&amp; txt[max(1, idx - 1)] != &apos;&apos;&apos; ''# start comment''
'''if''' idx &lt; len &amp;&amp; txt[idx+1] == &apos;=&apos; ''#= comment =#''
start, stop = nestedcommentlimits(txt[idx:'''end'''])
s = replace(txt[idx:idx+stop-1], "\n" =&gt; "''\n ''")
app'''end'''!(outtxt, collect("\'\'$s\'\'"))
idx += stop
'''else''' ''# found a line comment, like this '''else'comment''
newlinepos = something(findfirst(==(&apos;\n&apos;), txt[idx+1:'''end''']), len - idx)
app'''end'''!(outtxt, collect("\'\'$(txt[idx:idx+newlinepos-1])\'\'"))
newlinepos == nothing &amp;&amp; error("unterminated double quote at $idx")
idx += app'''end'''!(outtxt, collect("''$(txt[idx:idx+newlinepos-1])''"))
idx += newlinepos'''end'''
'''elseif''' c &apos;a&apos;:&apos;z&apos; ''# lowercase char so check for keyword '''end'match''
'''for''' (j, reg) '''elseifin''' c ∈ &apos;a&apos;:&apos;z&apos;enumerate(KEYWORDS)
m = '''for''' match(jreg, reg) txt[idx:'''inend''' enumerate(KEYWORDS])
m = match(reg, txt[idx:'''endif''']) m != nothing
wlen '''if'''= m.match.ncodeunits !=- nothing2
app'''end'''!(outtxt, collect("\'\'\'$(txt[idx:idx+wlen = m.match.ncodeunits - 2])\'\'\'"))
idx += wlen + app'''end'''!(outtxt, collect("'''$(txt[idx:idx+wlen])'''"))1
idx += wlen + 1'''break'''
'''elseif''' j == lastindex(KEYWORDS) ''# no keyword found, send char to '''break'output''
push!(outtxt, '''elseif''' j == lastindex(KEYWORDSc)
idx += push!(outtxt, c)1
idx += 1'''end'''
'''end'''
'''elseif''' c '''in''' [&apos;&apos;&apos;, &apos;&amp;&apos;, &apos;&lt;&apos;, &apos;&gt;&apos;] ''# \x26 is char & for HTML entity translation''
'''end'''
s '''elseif'''= c '''in'''== [&apos;&apos;&apos;, ? "\x26apos;" : c == &apos;&amp;&apos;, ? "\x26amp;" : c == &apos;&lt;&apos;, &apos? "\x26lt;&gt;&apos" : "\x26gt;]"
app'''end'''!(outtxt, collect(s))
s = c == &apos;&apos;&apos; ? "&apos;" : c == &apos;&amp;&apos; ? "&amp;" : c == &apos;&lt;&apos; ? "&lt;" : "&gt;"
idx += app'''end'''!(outtxt, collect(s))1
'''else''' ''# nothing special found, so pass char to output and increment index into idx += 1input''
push!(outtxt, '''else'''c)
idx += push!(outtxt, c)1
'''end'''
c == &apos;\n&apos; &amp;&amp; push!(outtxt, &apos; &apos;)
outtxt['''end'''] == &apos;\n&apos; &amp;&amp; push!(outtxt, &apos; &apos;)
idx += 1
'''end'''
'''endreturn''' String(outtxt)
'''return''' String(outtxt)
'''end'''
println(partialhighlight(read("onedrive/documents/julia programs/test1.jl"PROGRAM_FILE, String)), "\n")
 
=={{header|Phix}}==
Line 584 ⟶ 694:
'''puts'''(1,out)
{} = '''wait_key'''()
 
=={{header|PL/M}}==
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
Note that PL/M doesn't have in-built I/O or standard libraries, hence the need to define the various BDOS system calls.<br>
As CP/M doesn't have redirection, the source file and output file names must be specified on the command line, e.g. if the source is in D:SYNTAX.PLM and the desired output file is D:SYNTAX.OUT and the program is compiled to D:SYNTAX.COM, then the command:<br>
<code>D:SYNTAX D:SYNTAX.PLM D:SYNTAX.OUT</code><br> will create SYNTAX.OUT as a copy of SYNTAX.PLM with the markup for the highlighting. Note the output file must not exist before running the program.<br>
The output is also echoed to the console.
100H: ''/* SYNTAX HIGHLIGHT A PL/M SOURCE USING MEDIAWIKI MARKUP */''
'''DECLARE''' FALSE '''LITERALLY''' &apos;0&apos;, TRUE '''LITERALLY''' &apos;0FFH&apos;;
'''DECLARE''' NL$CHAR '''LITERALLY''' &apos;0AH&apos;; ''/* NEWLINE: CHAR 10 */''
'''DECLARE''' CR$CHAR '''LITERALLY''' &apos;0DH&apos;; ''/* CARRIAGE RETURN, CHAR 13 */''
'''DECLARE''' EOF$CHAR '''LITERALLY''' &apos;26&apos;; ''/* EOF: CTRL-Z */''
'''DECLARE''' AMP '''LITERALLY''' &apos;026H&apos;; ''/* AMPERSAND */''
'''DECLARE''' LCA '''LITERALLY''' &apos;061H&apos;; ''/* LOWER CASE &apos;A&apos; */''
'''DECLARE''' LCG '''LITERALLY''' &apos;067H&apos;; ''/* LOWER CASE &apos;G&apos; */''
'''DECLARE''' LCL '''LITERALLY''' &apos;06CH&apos;; ''/* LOWER CASE &apos;L&apos; */''
'''DECLARE''' LCM '''LITERALLY''' &apos;06DH&apos;; ''/* LOWER CASE &apos;M&apos; */''
'''DECLARE''' LCO '''LITERALLY''' &apos;06FH&apos;; ''/* LOWER CASE &apos;O&apos; */''
'''DECLARE''' LCP '''LITERALLY''' &apos;070H&apos;; ''/* LOWER CASE &apos;P&apos; */''
'''DECLARE''' LCS '''LITERALLY''' &apos;073H&apos;; ''/* LOWER CASE &apos;S&apos; */''
'''DECLARE''' LCT '''LITERALLY''' &apos;074H&apos;; ''/* LOWER CASE &apos;T&apos; */''
''/* CP/M BDOS SYSTEM CALL, RETURNS A VALUE */''
BDOS: '''PROCEDURE'''( FN, ARG )'''BYTE'''; '''DECLARE''' FN '''BYTE''', ARG '''ADDRESS'''; '''GOTO''' 5; '''END''';
''/* CP/M BDOS SYSTEM CALL, NO RETURN VALUE */''
BDOS$P: '''PROCEDURE'''( FN, ARG ); '''DECLARE''' FN '''BYTE''', ARG '''ADDRESS'''; '''GOTO''' 5; '''END''';
EXIT: '''PROCEDURE'''; '''CALL''' BDOS$P( 0, 0 ); '''END'''; ''/* CP/M SYSTEM RESET */''
PR$CHAR: '''PROCEDURE'''( C ); '''DECLARE''' C '''BYTE'''; '''CALL''' BDOS$P( 2, C ); '''END''';
PR$STRING: '''PROCEDURE'''( S ); '''DECLARE''' S '''ADDRESS'''; '''CALL''' BDOS$P( 9, S ); '''END''';
PR$NL: '''PROCEDURE'''; '''CALL''' PR$STRING( .( 0DH, NL$CHAR, &apos;$&apos; ) ); '''END''';
FL$EXISTS: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* RETURNS TRUE IF THE FILE NAMED IN THE */''
'''DECLARE''' FCB '''ADDRESS'''; ''/* FCB EXISTS */''
'''RETURN''' ( BDOS( 17, FCB ) &lt; 4 );
'''END''' FL$EXISTS ;
FL$OPEN: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* OPEN THE FILE WITH THE SPECIFIED FCB */''
'''DECLARE''' FCB '''ADDRESS''';
'''RETURN''' ( BDOS( 15, FCB ) &lt; 4 );
'''END''' FL$OPEN;
FL$MAKE: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* CREATE AND OPEN THE FILE WITH THE */''
'''DECLARE''' FCB '''ADDRESS'''; ''/* SPECIFIED FCB */''
'''RETURN''' ( BDOS( 22, FCB ) &lt; 4 );
'''END''' FL$MAKE;
FL$READ: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* READ THE NEXT RECORD FROM FCB */''
'''DECLARE''' FCB '''ADDRESS''';
'''RETURN''' ( BDOS( 20, FCB ) = 0 );
'''END''' FL$READ;
FL$WRITE: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* WRITE A RECORD TO FCB */''
'''DECLARE''' FCB '''ADDRESS''';
'''RETURN''' ( BDOS( 21, FCB ) = 0 );
'''END''' FL$WRITE;
FL$CLOSE: '''PROCEDURE'''( FCB )'''BYTE'''; ''/* CLOSE THE FILE WITH THE SPECIFIED FCB */''
'''DECLARE''' FCB '''ADDRESS''';
'''RETURN''' ( BDOS( 16, FCB ) &lt; 4 );
'''END''' FL$CLOSE;
DMA$SET: '''PROCEDURE'''( DMA ); ''/* SET THE DMA BUFFER ADDRESS FOR I/O */''
'''DECLARE''' DMA '''ADDRESS''';
'''CALL''' BDOS$P( 26, DMA );
'''END''' DMA$SET;
''/* I/O USES FILE CONTROL BLOCKS CONTAINING THE FILE-NAME, POSITION, ETC. */''
''/* WHEN THE PROGRAM IS RUN, THE CCP WILL FIRST PARSE THE COMMAND LINE AND */''
''/* PUT THE FIRST PARAMETER IN FCB1, THE SECOND PARAMETER IN FCB2 */''
''/* BUT FCB2 OVERLAYS THE END OF FCB1 AND THE DMA BUFFER OVERLAYS THE END */''
''/* OF FCB2 */''
'''DECLARE''' FCB$SIZE '''LITERALLY''' &apos;36&apos;; ''/* SIZE OF A FCB */''
'''DECLARE''' FCB1 '''LITERALLY''' &apos;5CH&apos;; ''/* ADDRESS OF FIRST FCB */''
'''DECLARE''' FCB2 '''LITERALLY''' &apos;6CH&apos;; ''/* ADDRESS OF SECOND FCB */''
'''DECLARE''' DMA$BUFFER '''LITERALLY''' &apos;80H&apos;; ''/* DEFAULT DMA BUFFER ADDRESS */''
'''DECLARE''' DMA$SIZE '''LITERALLY''' &apos;128&apos;; ''/* SIZE OF THE DMA BUFFER */''
INIT$FCB: '''PROCEDURE'''( FCB ); ''/* INITIALISE A FILE-CONTROL-BLOCK */''
'''DECLARE''' FCB '''ADDRESS''';
'''DECLARE''' F$PTR '''ADDRESS''';
'''DECLARE''' F '''BASED''' F$PTR '''BYTE''', P '''BYTE''';
F$PTR = FCB;
F = 0; ''/* DEFAULT DRIVE */''
'''DO''' F$PTR = FCB + 1 '''TO''' FCB + 11; ''/* NO NAME */''
F = &apos; &apos;;
'''END''';
'''DO''' F$PTR = FCB + 12 '''TO''' FCB + ( FCB$SIZE - 1 ); ''/* OTHER FIELDS */''
F = 0;
'''END''';
'''END''' INIT$FCB;
MOVE$FCB: '''PROCEDURE'''( FROM$FCB, TO$FCB ); ''/* MOVE THE CONTENTS OF AN FCB */''
'''DECLARE''' ( FROM$FCB, TO$FCB ) '''ADDRESS''';
'''DECLARE''' ( F$PTR, T$PTR ) '''ADDRESS''';
'''DECLARE''' F '''BASED''' F$PTR '''BYTE''', T '''BASED''' T$PTR '''BYTE''', P '''BYTE''';
'''CALL''' INIT$FCB( TO$FCB );
F$PTR = FROM$FCB;
T$PTR = TO$FCB;
'''DO''' P = 0 '''TO''' 11; ''/* COPY DRIVE, FILENAME AND EXTENSION */''
T = F;
F$PTR = F$PTR + 1;
T$PTR = T$PTR + 1;
'''END''';
'''END''' MOVE$FCB;
SHOW$FCB: '''PROCEDURE'''( FCB ); ''/* SHOW THE CONTENTS OF AN FCB */''
'''DECLARE''' FCB '''ADDRESS''';
'''DECLARE''' F$PTR '''ADDRESS''';
'''DECLARE''' F '''BASED''' F$PTR '''BYTE''', P '''BYTE''';
F$PTR = FCB;
'''DO''' P = 0 '''TO''' 11; ''/* DRIVE, FILENAME AND EXTENSION */''
'''IF''' P = 9 '''THEN''' '''CALL''' PR$CHAR( &apos;.&apos; );
'''IF''' P = 1 '''THEN''' '''CALL''' PR$CHAR( &apos;:&apos; );
'''CALL''' PR$CHAR( F );
F$PTR = F$PTR + 1;
'''END''';
'''END''' SHOW$FCB;
'''DECLARE''' F$PTR '''ADDRESS''', F$CHAR '''BASED''' F$PTR '''BYTE''';
'''DECLARE''' W$PTR '''ADDRESS''', W$CHAR '''BASED''' W$PTR '''BYTE''';
'''DECLARE''' FCB$OUT$DATA ( FCB$SIZE )'''BYTE''';
'''DECLARE''' OUT$DMA ( DMA$SIZE )'''BYTE''';
'''DECLARE''' OUT$BUFFER '''LITERALLY''' &apos;.OUT$DMA&apos;;
'''DECLARE''' FCB$IN '''LITERALLY''' &apos;FCB1&apos;;
'''DECLARE''' FCB$OUT '''LITERALLY''' &apos;.FCB$OUT$DATA&apos;;
'''DECLARE''' K '''LITERALLY''' &apos;CALL ADDKW&apos;;
'''DECLARE''' KW ( 34 )'''ADDRESS''';
'''DECLARE''' KW$MAX '''BYTE''';
KW$MAX = -1;
ADDKW: '''PROCEDURE'''( ADDR ); ''/* ADDS A KEYWORD TO KW */''
'''DECLARE''' ADDR '''ADDRESS''';
KW( KW$MAX := KW$MAX + 1 ) = ADDR;
'''END''' ADDKW ;
K(.&apos;ADDRESS$&apos;);K(.&apos;AND$&apos;);K(.&apos;BASED$&apos;);K(.&apos;BY$&apos;);K(.&apos;BYTE$&apos;);K(.&apos;CALL$&apos;);
K(.&apos;CASE$&apos;);K(.&apos;DATA$&apos;);K(.&apos;DECLARE$&apos;);K(.&apos;DISABLE$&apos;);K(.&apos;DO$&apos;);K(.&apos;ELSE$&apos;);
K(.&apos;ENABLE$&apos;);K(.&apos;END$&apos;);K(.&apos;EOF$&apos;);K(.&apos;GO$&apos;);K(.&apos;GOTO$&apos;);K(.&apos;HALT$&apos;);
K(.&apos;IF$&apos;);K(.&apos;INITIAL$&apos;);K(.&apos;INTERRUPT$&apos;);K(.&apos;LABEL$&apos;);K(.&apos;LITERALLY$&apos;);
K(.&apos;MINUS$&apos;);K(.&apos;MOD$&apos;);K(.&apos;NOT$&apos;);K(.&apos;OR$&apos;);K(.&apos;PLUS$&apos;);K(.&apos;PROCEDURE$&apos;);
K(.&apos;RETURN$&apos;);K(.&apos;THEN$&apos;);K(.&apos;TO$&apos;);K(.&apos;WHILE$&apos;);K(.&apos;XOR$&apos;);
''/* MOVE THE SECOND FCB TO A NEW PLACE SO IT ISN&apos;T OVERWRITTEN BY FCB1 */''
'''CALL''' MOVE$FCB( FCB2, FCB$OUT );
''/* CLEAR THE PARTS OF FCB1 OVERLAYED BY FCB2 */''
'''DO''' F$PTR = FCB1 + 12 '''TO''' FCB1 + ( FCB$SIZE - 1 );
F$CHAR = 0;
'''END''';
STR$EQUAL: '''PROCEDURE'''( S1, S2 )'''BYTE'''; ''/* RETURN TRUE IF S1 = S2 */''
'''DECLARE''' ( S1, S2 ) '''ADDRESS''';
'''DECLARE''' ( S1$PTR, S2$PTR ) '''ADDRESS''';
'''DECLARE''' C1 '''BASED''' S1$PTR '''BYTE''', C2 '''BASED''' S2$PTR '''BYTE''', SAME '''BYTE''';
S1$PTR = S1; S2$PTR = S2;
'''DO''' '''WHILE''' ( SAME := C1 = C2 ) '''AND''' C1 &lt;&gt; &apos;$&apos; '''AND''' C2 &lt;&gt; &apos;$&apos;;
S1$PTR = S1$PTR + 1; S2$PTR = S2$PTR + 1;
'''END''';
'''RETURN''' SAME;
'''END''' STR$EQUAL ;
IS$WORD$CHAR: '''PROCEDURE'''( CH )'''BYTE'''; ''/* RETURN TRUE IF CH IS PART OF A WORD */''
'''DECLARE''' CH '''BYTE''';
'''RETURN''' ( CH &gt;= &apos;A&apos; '''AND''' CH &lt;= &apos;Z&apos; ) '''OR''' CH = &apos;$&apos;
'''OR''' ( CH &gt;= &apos;0&apos; '''AND''' CH &lt;= &apos;9&apos; );
'''END''' IS$WORD$CHAR ;
'''IF''' '''NOT''' FL$EXISTS( FCB$IN ) '''THEN''' '''DO''';
'''CALL''' SHOW$FCB( FCB$IN );
'''CALL''' PR$STRING( .&apos;: INPUT FILE NOT FOUND$&apos; );'''CALL''' PR$NL;
'''END''';
'''ELSE''' '''IF''' FL$EXISTS( FCB$OUT ) '''THEN''' '''DO''';
'''CALL''' SHOW$FCB( FCB$OUT );
'''CALL''' PR$STRING( .&apos;: OUTPUT FILE ALREADY EXISTS$&apos; );'''CALL''' PR$NL;
'''END''';
'''ELSE''' '''IF''' '''NOT''' FL$OPEN( FCB$IN ) '''THEN''' '''DO''';
'''CALL''' PR$STRING( .&apos;UNABLE TO OPEN THE INPUT FILE$&apos; );'''CALL''' PR$NL;
'''END''';
'''ELSE''' '''IF''' '''NOT''' FL$MAKE( FCB$OUT ) '''THEN''' '''DO''';
'''CALL''' PR$STRING( .&apos;UNABLE TO OPEN THE OUTPUT FILE$&apos; );'''CALL''' PR$NL;
'''IF''' '''NOT''' FL$CLOSE( FCB$IN ) '''THEN''' '''DO''';
'''CALL''' PR$STRING( .&apos;UNABLE TO CLOSE THE INPUT FILE$&apos; ); '''CALL''' PR$NL;
'''END''';
'''END''';
'''ELSE''' '''DO'''; ''/* FILES OPENED OK - ATTEMPT TO FORMAT THE SOURCE */''
'''DECLARE''' ( GOT$RCD, IS$HEADING ) '''BYTE''', ( DMA$END, OUT$END ) '''ADDRESS''';
'''DECLARE''' IN$STRING '''BYTE''', COMMENT$STATE '''ADDRESS''', GOT$NEXT '''BYTE''';
IN$CHAR: '''PROCEDURE''';
F$PTR = F$PTR + 1;
'''IF''' F$PTR &gt; DMA$END '''THEN''' '''DO'''; ''/* END OF BUFFER */''
GOT$RCD = FL$READ( FCB$IN ); ''/* GET THE NEXT RECORDD */''
'''IF''' '''NOT''' GOT$RCD '''THEN''' F$CHAR = EOF$CHAR;
F$PTR = DMA$BUFFER;
'''END''';
'''END''' IN$CHAR ;
OUT$CHAR: '''PROCEDURE'''( CH ); ''/* OUTPUT A CHARECTER TO THE OUTPOUT FILE */''
'''DECLARE''' CH '''BYTE''';
'''IF''' CH &lt;&gt; EOF$CHAR '''THEN''' '''CALL''' PR$CHAR( CH );
W$CHAR = CH;
W$PTR = W$PTR + 1;
'''IF''' W$PTR &gt; OUT$END '''OR''' CH = EOF$CHAR '''THEN''' '''DO''';
''/* THE OUTPUT BUFFER IS FULL OR WE ARE WRITTING EOF */''
'''IF''' CH = EOF$CHAR '''THEN''' '''DO'''; ''/* EOF - FILL THE BUFFER WITH NULS */''
'''DO''' '''WHILE''' W$PTR &lt;= OUT$END;
W$CHAR = 0;
W$PTR = W$PTR + 1;
'''END''';
'''END''';
'''CALL''' DMA$SET( OUT$BUFFER ); ''/* SWITCH DMA TO THE OUTOUT BUFFER */''
'''IF''' '''NOT''' FL$WRITE( FCB$OUT ) '''THEN''' '''DO'''; ''/* I/O ERROR */''
'''CALL''' PR$STRING( .&apos;I/O ERROR ON WRITING $&apos; );
'''CALL''' SHOW$FCB( FCB$OUT );
'''CALL''' PR$NL;
'''CALL''' EXIT;
'''END''';
'''CALL''' DMA$SET( DMA$BUFFER ); ''/* RESET DMA TO THE DEFAULT BUFFER */''
W$PTR = OUT$BUFFER;
'''END''';
'''END''' OUT$CHAR;
OUT$STRING: '''PROCEDURE'''( STR ); ''/* OUTPUT A STRING */''
'''DECLARE''' STR '''ADDRESS''';
'''DECLARE''' S$PTR '''ADDRESS''';
'''DECLARE''' S$CHAR '''BASED''' S$PTR '''BYTE''';
S$PTR = STR;
'''DO''' '''WHILE''' S$CHAR &lt;&gt; &apos;$&apos;;
'''CALL''' OUT$CHAR( S$CHAR );
S$PTR = S$PTR + 1;
'''END''';
'''END''' OUT$STRING;
DMA$END = DMA$BUFFER + ( DMA$SIZE - 1 );
OUT$END = OUT$BUFFER + ( DMA$SIZE - 1 );
GOT$RCD = FL$READ( FCB$IN ); ''/* GET THE FIRST RECORD */''
F$PTR = DMA$BUFFER;
W$PTR = OUT$BUFFER;
IN$STRING = FALSE;
GOT$NEXT = FALSE;
COMMENT$STATE = 0;
'''CALL''' OUT$CHAR( &apos; &apos; );
'''DO''' '''WHILE''' GOT$RCD;
'''IF''' F$CHAR = CR$CHAR '''THEN''' '''DO'''; ''/* CARRIAGE RETURN */''
'''IF''' COMMENT$STATE &gt; 1 '''THEN''' '''DO''';
COMMENT$STATE = 2;
'''CALL''' OUT$STRING( .&apos;&apos;&apos;&apos;&apos;$&apos; );
'''END''';
'''CALL''' OUT$CHAR( F$CHAR );
'''END''';
'''ELSE''' '''IF''' F$CHAR = NL$CHAR '''THEN''' '''DO''';
'''CALL''' OUT$CHAR( F$CHAR );
'''CALL''' OUT$CHAR( &apos; &apos; );
'''IF''' COMMENT$STATE &gt; 1 '''THEN''' '''CALL''' OUT$STRING( .&apos;&apos;&apos;&apos;&apos;$&apos; );
'''END''';
'''ELSE''' '''IF''' F$CHAR = AMP '''THEN''' '''DO''';
'''CALL''' OUT$STRING( .( AMP, LCA, LCM, LCP, &apos;;$&apos; ) );
'''END''';
'''ELSE''' '''IF''' F$CHAR = &apos;&apos;&apos;&apos; '''THEN''' '''DO''';
'''CALL''' OUT$STRING( .( AMP, LCA, LCP, LCO, LCS, &apos;;$&apos; ) );
IN$STRING = COMMENT$STATE = 0 '''AND''' '''NOT''' IN$STRING;
'''END''';
'''ELSE''' '''IF''' F$CHAR = &apos;&lt;&apos; '''THEN''' '''DO''';
'''CALL''' OUT$STRING( .( AMP, LCL, LCT, &apos;;$&apos; ) );
'''END''';
'''ELSE''' '''IF''' F$CHAR = &apos;&gt;&apos; '''THEN''' '''DO''';
'''CALL''' OUT$STRING( .( AMP, LCG, LCT, &apos;;$&apos; ) );
'''END''';
'''ELSE''' '''IF''' IN$STRING '''THEN''' '''CALL''' OUT$CHAR( F$CHAR );
'''ELSE''' '''IF''' COMMENT$STATE = 1 '''THEN''' '''DO'''; ''/* HAVE A CHARACTER AFTER / */''
'''IF''' F$CHAR = &apos;*&apos; '''THEN''' '''DO''';
COMMENT$STATE = 2;
'''CALL''' OUT$STRING( .&apos;&apos;&apos;&apos;&apos;/*$&apos; );
'''END''';
'''ELSE''' '''DO''';
COMMENT$STATE = 0;
'''CALL''' OUT$CHAR( &apos;/&apos; );
'''CALL''' OUT$CHAR( F$CHAR );
'''END''';
'''END''';
'''ELSE''' '''IF''' COMMENT$STATE = 2 '''THEN''' '''DO'''; ''/* IN A COMMENT */''
'''IF''' F$CHAR = &apos;*&apos; '''THEN''' COMMENT$STATE = 3;
'''CALL''' OUT$CHAR( F$CHAR );
'''END''';
'''ELSE''' '''IF''' COMMENT$STATE = 3 '''THEN''' '''DO'''; ''/* IN A COMMENT, EXPECTING / */''
'''IF''' F$CHAR = &apos;/&apos; '''THEN''' '''DO'''; ''/* END OF COMMENT */''
'''CALL''' OUT$STRING( .&apos;/&apos;&apos;&apos;&apos;$&apos; );
COMMENT$STATE = 0;
'''END''';
'''ELSE''' '''DO'''; ''/* NOT END OF COMMENT */''
'''CALL''' OUT$CHAR( F$CHAR );
'''IF''' F$CHAR &lt;&gt; &apos;*&apos; '''THEN''' COMMENT$STATE = 2;
'''END''';
'''END''';
'''ELSE''' '''IF''' F$CHAR = &apos;/&apos; '''THEN''' '''DO''';
'''IF''' COMMENT$STATE = 0 '''THEN''' COMMENT$STATE = 1;
'''ELSE''' '''IF''' COMMENT$STATE = 3 '''THEN''' '''DO''';
''/* END OF COMMENT */''
'''CALL''' OUT$STRING( .&apos;/&apos;&apos;&apos;&apos;$&apos; );
COMMENT$STATE = 0;
'''END''';
'''ELSE''' '''CALL''' OUT$CHAR( F$CHAR );
'''END''';
'''ELSE''' '''IF''' F$CHAR = EOF$CHAR '''THEN''' GOT$RCD = FALSE; ''/* END OF FILE */''
'''ELSE''' '''IF''' F$CHAR &gt;= &apos;A&apos; '''AND''' F$CHAR &lt;= &apos;Z&apos; '''THEN''' '''DO'''; ''/* WORD */''
'''DECLARE''' W ( 10 )'''BYTE''', W$POS '''BYTE''', HAS$DOLLAR '''BYTE''';
OUT$WORD: '''PROCEDURE'''; ''/* OUTPUT W (WHICH MAY CONTAIN $ */''
'''DECLARE''' I '''BYTE''';
'''DO''' I = 0 '''TO''' W$POS - 1; '''CALL''' OUT$CHAR( W( I ) ); '''END''';
'''END''' OUT$WORD ;
W$POS = 0;
HAS$DOLLAR = FALSE;
'''DO''' '''WHILE''' W$POS &lt; 9 '''AND''' IS$WORD$CHAR( F$CHAR );
'''IF''' F$CHAR = &apos;$&apos; '''THEN''' HAS$DOLLAR = TRUE;
W( W$POS ) = F$CHAR; W$POS = W$POS + 1; '''CALL''' IN$CHAR;
'''END''';
W( W$POS ) = &apos;$&apos;;
'''IF''' IS$WORD$CHAR( F$CHAR ) '''THEN''' '''DO'''; ''/* WORD IS TOO LONG FOE A */''
'''CALL''' OUT$WORD; ''/* KEYWORD */''
'''DO''' '''WHILE''' IS$WORD$CHAR( F$CHAR );
'''CALL''' OUT$CHAR( F$CHAR );'''CALL''' IN$CHAR;
'''END''';
'''END''';
'''ELSE''' '''IF''' HAS$DOLLAR '''THEN''' '''DO'''; ''/* ASSUME IT ISN&apos;T A KEYWORD */''
'''CALL''' OUT$WORD; ''/* I.E., THE PROGRAMMER HASN&apos;T WRITTEN E.G.: */''
'''END'''; ''/* RE$TURN X; */''
'''ELSE''' '''DO'''; ''/* SHORT WORD - COULD BE A KEYWORD */''
'''DECLARE''' ( IS$KW, KW$POS ) '''BYTE''';
IS$KW = FALSE;
KW$POS = 0;
'''DO''' '''WHILE''' '''NOT''' IS$KW '''AND''' KW$POS &lt;= KW$MAX;
IS$KW = STR$EQUAL( .W, KW( KW$POS ) );
KW$POS = KW$POS + 1;
'''END''';
'''IF''' IS$KW '''THEN''' '''CALL''' OUT$STRING( .&apos;&apos;&apos;&apos;&apos;&apos;&apos;$&apos; );
'''CALL''' OUT$WORD;
'''IF''' IS$KW '''THEN''' '''CALL''' OUT$STRING( .&apos;&apos;&apos;&apos;&apos;&apos;&apos;$&apos; );
'''END''';
GOT$NEXT = TRUE;
'''END''';
'''ELSE''' '''DO'''; ''/* HAVE ANOTHER CHARACTER */''
'''CALL''' OUT$CHAR( F$CHAR );
'''END''';
'''IF''' '''NOT''' GOT$NEXT '''THEN''' '''CALL''' IN$CHAR;
GOT$NEXT = FALSE;
'''END''';
'''CALL''' OUT$CHAR( EOF$CHAR );
''/* CLOSE THE FILES */''
'''IF''' '''NOT''' FL$CLOSE( FCB$IN ) '''THEN''' '''DO''';
'''CALL''' PR$STRING( .&apos;UNABLE TO CLOSE THE INPUT FILE$&apos; ); '''CALL''' PR$NL;
'''END''';
'''IF''' '''NOT''' FL$CLOSE( FCB$OUT ) '''THEN''' '''DO''';
'''CALL''' PR$STRING( .&apos;UNABLE TO CLOSE THE OUTPUT FILE$&apos; ); '''CALL''' PR$NL;
'''END''';
'''END''';
'''CALL''' EXIT;
'''EOF'''
 
=={{header|Python}}==
Line 678 ⟶ 1,139:
'''if''' __name__ == &quot;__main__&quot;:
main()
 
=={{header|Wren}}==
{{libheader|Wren-ioutil}}
Note that, rightly or wrongly, this code would not highlight keywords occurring in interpolated string expressions.
 
''// Convert a Wren source to "wiki" format:''
''// each line is preceded by a space''
''// keywords are enclosed in &apos;&apos;&apos; and &apos;&apos;&apos; and comments in &apos;&apos; and &apos;&apos;''
''// &apos;, &amp;, &lt; and &gt; are converted to &amp;apos; &amp;amp; &amp;lt; and &amp;gt;''
''// everything else is output as is''
''// The source is read from a file and written to standard output.''
''// The file name should be passed as a command line argument.''
'''import''' "./ioutil" '''for''' FileUtil
'''import''' "os" '''for''' Process
'''var''' keywords = [
"as", "break", "class", "construct", "continue", "else", "false",
"for", "foreign", "if", "in", "is", "import", "null", "return",
"static", "super", "this", "true", "var", "while"
]
'''var''' alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_."
'''var''' highlight = Fn.new { |lines|
'''var''' inStr = '''false''' ''// within a string literal''
'''var''' inRaw = '''false''' ''// within a raw string literal''
'''var''' inCom = '''false''' ''// within a multi-line comment''
'''var''' level = 0 ''// nesting level for multi-line comment''
'''for''' (line '''in''' lines) {
System.write(" ")
line = line.replace("&amp;", "&amp;amp;").replace("&apos;", "&amp;apos;")
.replace("&lt;", "&amp;lt;").replace("&gt;", "&amp;gt;")
'''var''' word = ""
'''var''' chrs = line.toList ''// convert to list of unicode characters''
'''var''' cc = chrs.count
'''var''' i = 0
'''if''' (inCom) System.write("&apos;&apos;")
'''while''' (i &lt; cc) {
'''var''' c = chrs[i]
'''if''' (inCom) { ''// if inside a multi-line comment''
'''if''' (c == "/" &amp;&amp; i &lt; cc-1 &amp;&amp; chrs[i+1] == "*") {
level = level + 1
System.write("/*")
i = i + 1
} '''else''' '''if''' (c == "*" &amp;&amp; i &lt; cc-1 &amp;&amp; chrs[i+1] == "/") {
level = level - 1
System.write("*/")
i = i + 1
'''if''' (level == 0) {
inCom = '''false'''
System.write("&apos;&apos;")
}
} '''else''' {
System.write(c)
}
} '''else''' '''if''' (inStr &amp;&amp; c == "\\" &amp;&amp; i &lt; cc-1 &amp;&amp; chrs[i+1] == "\"") {
''/* escaped double quote in string literal */''
System.write("\\\"")
i = i + 1
} '''else''' '''if''' (c == "\"") { ''// any other double quote''
'''if''' (i &gt; 1 &amp;&amp; chrs[i-2] == "\"" &amp;&amp; chrs[i-1] == "\"") {
inRaw = !inRaw
} '''else''' '''if''' (!inRaw) {
inStr = !inStr
}
System.write("\"")
} '''else''' '''if''' (inStr || inRaw) { ''// otherwise if within a string just write it''
System.write(c)
} '''else''' '''if''' (c == "/") { ''// forward slash''
'''if''' (i &lt; cc-1 &amp;&amp; chrs[i+1] == c) {
System.write("&apos;&apos;" + chrs[i..-1].join() + "&apos;&apos;")
'''break'''
} '''else''' '''if''' (i &lt; cc-1 &amp;&amp; chrs[i+1] == "*") {
inCom = '''true'''
level = 1
System.write("&apos;&apos;" + "/*")
i = i + 1
} '''else''' {
System.write(c)
}
} '''else''' '''if''' (alphabet.contains(c)) { ''// if eligible, add to current word''
word = word + c
} '''else''' '''if''' (keywords.contains(word)) { ''// if it&apos;s a keyword, embolden it''
System.write("&apos;&apos;&apos;" + word + "&apos;&apos;&apos;" + c)
word = ""
} '''else''' { ''// otherwise just write the word''
System.write(word + c)
word = ""
}
i = i + 1
}
'''if''' (inCom) {
System.write("&apos;&apos;")
} '''else''' '''if''' (word != "") {
'''if''' (keywords.contains(word)) {
System.write("&apos;&apos;&apos;" + word + "&apos;&apos;&apos;")
} '''else''' {
System.write(word)
}
}
System.print()
}
}
'''var''' args = Process.arguments
'''if''' (args.count != 1) {
''/* make sure double quotes and keywords in raw strings are handled properly */''
Fiber.abort("""Please pass the file name to be highlighted "as" the only argument.""")
}
'''var''' lines = FileUtil.readLines(args[0])
highlight.call(lines)
''/* this code should now be saved to''
'' /* a file named */''
'' Syntax_highlighting_using_Mediawiki_formatting.wren */''
 
=={{header|XPL0}}==
Key words in XPL0 are easy to distinguish from variable names because
they start with lowercase letters while variables start with uppercase
letters. This program highlights its own code properly, but it will not
properly highlight all possible cases, such as when key words appear
in quoted strings.
'''proc''' CharOut(Ch);
'''int''' Ch;
'''begin'''
'''case''' Ch '''of'''
^&apos;: Text(0, "&amp;apos;");
^&amp;: Text(0, "&amp;amp;");
^&lt;: Text(0, "&amp;lt;");
^&gt;: Text(0, "&amp;gt;")
'''other''' ChOut(1, Ch);
'''end''';
'''int''' Ch;
'''loop''' '''begin'''
ChOut(1, $20); ''\leading space''
Ch:= ChIn(1);
'''loop''' '''begin'''
'''while''' Ch &lt;= $20 '''do''' ''\pass whitespace to output''
'''begin'''
'''if''' Ch = $1A ''\EOF\'' '''then''' '''return''';
ChOut(1, Ch);
'''if''' Ch = $0A ''\LF\'' '''then''' '''quit''';
Ch:= ChIn(1);
'''end''';
'''if''' Ch = ^\ '''then''' ''\pass comment to output''
'''begin'''
Text(0, "&apos;&apos;"); ''\in italics''
ChOut(1, Ch);
Ch:= ChIn(1);
'''while''' Ch#^\ &amp; Ch#$0A ''\LF\'' '''do'''
'''begin'''
CharOut(Ch); Ch:= ChIn(1);
'''end''';
'''if''' Ch = ^\ '''then''' ChOut(1, Ch);
Text(0, "&apos;&apos;");
'''if''' Ch = $0A ''\LF\'' '''then'''
'''begin'''
ChOut(1, Ch); '''quit''';
'''end''';
Ch:= ChIn(1);
'''end'''
'''else''' '''if''' Ch&gt;=^a &amp; Ch&lt;=^z '''then''' ''\pass key words to output''
'''begin'''
Text(0, "&apos;&apos;&apos;"); ''\in bold''
'''while''' Ch&gt;=^a &amp; Ch&lt;=^z '''do'''
'''begin'''
ChOut(1, Ch); Ch:= ChIn(1);
'''end''';
Text(0, "&apos;&apos;&apos;");
'''end'''
'''else''' '''begin''' ''\pass anything else''
'''repeat''' CharOut(Ch);
Ch:= ChIn(1);
'''until''' Ch &lt;= $20; ''\until whitespace''
'''end''';
'''end''';
'''end'''
9,482

edits