! OKBStyle - Library which allows style changes to be embedded in text. ! By Brendan "BrenBarn" Barnwell, alias OKB (BrenBarn@aol.com) ! ! From ideas and experimentation by himself, Adam "jwalrus" Biltcliffe, John "katre" Cater, ! Evin "thumper" Robinson, and Gunther "Gunther" Schmidl. ! ! This library is Glulx-only. ! ! This library is compatible with my Entry Inform library extension. !!!!! ! ! THE FOUR MOST IMPORTANT THINGS ! ! You must call OKBStyleRestore from your Initialise and IdentifyGlkObject routines, unless you ! are using Entry. ! ! You need two other libraries to make this one work: infglk.h (by John Cater) and ! OKBGlulx.h (by yours truly). A zip package containing these two files and ! OKBStyle.h itself is available at http://members.aol.com/brenbarn/instyle.zip . This library will ! automatically include OKBGlulx, which will automatically include infglk. ! ! You must include OKBStyle after including Parser, but before including Verblib. ! !!!!! ! ! Currently, there are two ways to embed style tags into your strings: ! HTML-style and TeX-style. ! !!! ! ! HTML-style can be used just like normal HTML: starts the tag and ! ends it. There are few syntaxes you CAN use with this library, however, that ! aren't legal in HTML. For starters, only the first letter of the tag is meaningful (so you ! can use , , or just plain ). Second of all, the end tag does not ! have to be anything but . If you want to use , , or , you ! can, but the effect is always the same: the style is reset to Normal. (It is even possible ! to begin with, say and end with , if you feel the urge.) Here is a ! full list of supported tags (only the required first letter is given): ! ! or = Emphasized !

= Preformatted ! = Header ! = Subheader ! = Alert ! = Note ! = Quote ! = Input ! <1> = User1 ! <2> = User2 ! ! None of the tags are case sensitive. ! ! The only character you might need to escape using this method is <. There ! are two ways to print out a <. First, you can use <<, and this will print as a single <. ! Second, you can use cout <<<< ~I like a monkey!~ <<<< endl;

";--.) ! ! You cannot, however, escape the < character within a tag. All this means is that ! if you try to use <1 < 2> as a tag, it will go awry. Hopefully no one was planning on ! doing that anyway. ! ! You also cannot escape the > character within a tag. This means that <2 > 0> ! will print "0>" in User2 style (it won't interpret the entire "2 > 0" package as the name ! of the tag. Again, I don't foresee anyone trying this, but just in case. . . ! !!! ! ! TeX-style formatting is a lot like using TeX, or so I hear. (I've never actually used ! TeX myself; I've had the syntax explained to me briefly by others. If you find ! something wrong with this syntax, please let me know.) The basic format is ! "|style{styled text}". Note that instead of the backslash (\) I have used the pipe ! character (|) to begin the syntax. This is because Inform has its own special meaning ! for a backslash, and won't allow the character to be used for other purposes. ! ! You can specify a different character than | to be used for TeX-style styling by defining a ! constant called TeXChar (whose value is the character you want) before Including OKBStyle. (Note ! that this character must be enclosed in single quotes, as in --Constant TeXChar '|'--.) ! ! Like HTML-style formatting (described above), TeX-style formatting has some ! syntax shortcuts for you to use. Well, actually, one syntax shortcut. Again, only the ! first character of the style name is necessary. So |bold is the same as |bogus or |b or ! even |BrendanBarnwell. Here's the full list of available styles: ! ! |b or |e = Emphasized ! |p = Preformatted ! |h = Header ! |s = Subheader ! |a = Alert ! |n = Note ! |q = Quote ! |i = Input ! |1 = User1 ! |2 = User2 ! ! None of these are case senstive. ! ! If you are printing unformatted text and you want to print a |, you can use either ! || (which will print a single bar), or |X, where X is any character not listed above ! (which will print both the bar and the character, whatever it is). If you need to print a ! } as part of some styled text (e.g., "This is a right brace: }"), you can escape it with a |. ! (So "|e{This is a right brace |}}" will print the above text in Emphasized style.) Any ! | characters found between the { braces } (except those immediately preceding a } character) will be ! printed without any fuss (this means you can't nest styles, but that's okay, since Glulx doesn't allow ! that anyway). ! !!!!! ! ! Please send any questions, comments, or other communication to me at ! BrenBarn@aol.com . ! !!!!! ! System_file; -- actual directive is at end of file for odd reasons. #IfNDef OKBStyle; #IfNDef OKBGlulx; Include "OKBGlulx"; #EndIf; Message "[Including ]"; #IfDef Enterer; Enterer OKBStyle; EnterInitialise -> OKBStyleInitialize with precedes Game, follows OKBGlulx, execute [; rfalse; ]; ! No intialization needed EnterIdentifyGlkObject -> OKBStyleIGO with precedes Game OKBGlulx, execute [phase type objref objrock; if (phase==2) @setiosys 1 OKBFilter; ]; #IfNot; Constant OKBStyle; #EndIf; Replace RestoreSub; Replace SaveSub; Constant NoStyle=0; Constant HTMLStyle 801; Constant TeXStyle 802; Default TeXChar='|'; Global Stylin=0; ! Current "state" of style (e.g., where we are in parsing the tag) Global StyleStyle=NoStyle; ! Style of styling we're using (HTMLStyle or TeXStyle) [OKBStyleRestore phase; if (phase==2) @setiosys 1 OKBFilter; ]; [OKBFilter char; ! HTML-style if (char=='<') { ! We see an HTML tag beginning switch (Stylin) { 0: Stylin=1; StyleStyle=HTMLStyle; rtrue; ! If we've just begun, we wait to see the tag 1: GlkChar('<'); Stylin=0; StyleStyle=NoStyle; rtrue; ! If we read <<, print out one < 2: rtrue; 3: Stylin=4; rtrue; 4: GlkChar('<'); Stylin=3; rtrue; 5: rtrue; } } if (Stylin==0 && StyleStyle==HTMLStyle) {GlkChar(char); rtrue;} if (Stylin==1 && StyleStyle==HTMLStyle) { Stylin=2; switch (char) { 'e','b','E','B': GlkStyle(StyleEmphasized); 'p','P': GlkStyle(StylePreformatted); 'h','H': GlkStyle(StyleHeader); 's','S': GlkStyle(StyleSubheader); 'a','A': GlkStyle(StyleAlert); 'n','N': GlkStyle(StyleNote); 'q','Q': GlkStyle(StyleQuote); 'i','I': GlkStyle(StyleInput); '1': GlkStyle(StyleUser1); '2': GlkStyle(StyleUser2); default: GlkChar('<'); GlkChar(char); Stylin=0; StyleStyle=NoStyle; rtrue; } } if (Stylin==2 && StyleStyle==HTMLStyle) { if (char=='>') {Stylin=3;} rtrue; } if (Stylin==3 && StyleStyle==HTMLStyle) {GlkChar(char); rtrue;} if (Stylin==4 && StyleStyle==HTMLStyle) { if (char=='/') { Stylin=5; GlkStyle(StyleNormal); } else { GlkChar('<'); GlkChar(char); Stylin=3; } rtrue; } if (Stylin==5 && StyleStyle==HTMLStyle) { if (char=='>') {Stylin=0; StyleStyle=NoStyle;} rtrue; } ! TeX-style if (char==TeXChar) { switch (Stylin) { 0: Stylin=1; StyleStyle=TeXStyle; rtrue; 1: GlkChar(TeXChar); Stylin=0; StyleStyle=NoStyle; rtrue; 2: rtrue; 3: Stylin=4; rtrue; 4: GlkChar(TeXChar); rtrue; 5: "Error! You began a TeX-style formatting block inside the end tag of an HTML-style formatting block!"; } } if (Stylin==0 && StyleStyle==TeXStyle) {GlkChar(char); rtrue;} if (Stylin==1 && StyleStyle==TeXStyle) { Stylin=2; switch (char) { 'e','b','E','B': GlkStyle(StyleEmphasized); 'p','P': GlkStyle(StylePreformatted); 'h','H': GlkStyle(StyleHeader); 's','S': GlkStyle(StyleSubheader); 'a','A': GlkStyle(StyleAlert); 'n','N': GlkStyle(StyleNote); 'q','Q': GlkStyle(StyleQuote); 'i','I': GlkStyle(StyleInput); '1': GlkStyle(StyleUser1); '2': GlkStyle(StyleUser2); default: GlkChar(TeXChar); GlkChar(char); Stylin=0; StyleStyle=NoStyle; rtrue; } } if (Stylin==2 && StyleStyle==TeXStyle) { if (char=='{') {Stylin=3;} rtrue; } if (Stylin==3 && StyleStyle==TeXStyle) { if (char=='}') {GlkStyle(StyleNormal); Stylin=0; StyleStyle=NoStyle;} else {GlkChar(char);} rtrue; } if (Stylin==4 && StyleStyle==TeXStyle) { if (char=='}') {GlkChar('}');} else {GlkChar(TeXChar); GlkChar(char);} Stylin=3; rtrue; } if (StyleStyle==NoStyle) {GlkChar(char); rtrue;} ]; [ RestoreSub res fref; @setiosys 2 0; fref = glk($0062, $01, $02, 0); ! fileref_create_by_prompt if (fref == 0) jump RFailed; gg_savestr = glk($0042, fref, $02, GG_SAVESTR_ROCK); ! stream_open_file glk($0063, fref); ! fileref_destroy if (gg_savestr == 0) { jump RFailed; } @restore gg_savestr res; glk($0044, gg_savestr, 0); ! stream_close gg_savestr = 0; .RFailed; L__M(##Restore,1); @setiosys 1 OKBFilter; ]; [ SaveSub res fref; @setiosys 2 0; fref = glk($0062, $01, $01, 0); ! fileref_create_by_prompt if (fref == 0) jump SFailed; gg_savestr = glk($0042, fref, $01, GG_SAVESTR_ROCK); ! stream_open_file glk($0063, fref); ! fileref_destroy if (gg_savestr == 0) { jump SFailed; } @save gg_savestr res; if (res == -1) { ! The player actually just typed "restore". We're going to print ! L__M(##Restore,2); the Z-Code Inform library does this correctly ! now. But first, we have to recover all the Glk objects; the values ! in our global variables are all wrong. GGRecoverObjects(); glk($0044, gg_savestr, 0); ! stream_close gg_savestr = 0; return L__M(##Restore,2); } glk($0044, gg_savestr, 0); ! stream_close gg_savestr = 0; if (res == 0) return L__M(##Save,2); .SFailed; L__M(##Save,1); @setiosys 1 OKBFilter; ]; System_file;