! ! bquote.h ! ! Synopsis ! ! Extension for writing block quotes, i.e. indented ! paragraphs, in Version 5 games. The effect is similar to ! the
tag in HTML, but it always uses a fixed ! width font. ! ! Inclusion ! ! Include the file "bquote.h" at the beginning of your ! game file. For z-code, this extension is stand-alone. ! ! For Glulx, it relies on using the standard Inform ! library. Glulx compability is provided for the case that ! you decide to flip the -G switch during development. If ! you're going for Glulx from the start, you might be ! better off using the block quote style as produced by ! glk($0086, 7); ! ! How to print block quotes ! ! First, the block quote must be opened with ! ! bq_open(margin, padding, maxwidth); ! ! This will start a block quote with the specified margin ! left and right. If you specify a padding, the block ! quote is printed in a special style, usually reverse, ! with the padding from the left and right borders. ! ! Usually, the width of the quote is determined by the ! width of the screen and the margins and paddings. If you ! specify maxwidth, the width will still be adjusted to ! the screen width, but if the inner width of the box is ! greater than maxwidth, maxwidth is used. ! ! If you specify a negative maxwidth, the margin will be ! calculated so that the quote will be centered and ! -maxwidth characters wide. If the calculated margin is ! less than the specified margin, the width will be ! adjusted. ! ! For printing the text, use the routines ! ! bq_text(str, a1, a2, a3); ! bq_newline(); ! ! where str may be the reference to a static string or a ! routine which can take up to three arguments a#. ! ! The output text must not contain the newline character ^ ! - that's what the bq_newline() function is for - and it ! must not be longer than BQ_MAX_LENGTH characters. The ! complete text may be of any length, but it must be ! defined in chunks of less than BQ_MAX_LENGTH characters. ! ! If the text is longer, a warning is issued, which ! should tell you to either break down your text into ! smaller chunks or to define a larger value for the ! constant BQ_MAX_LENGTH (default is 512) before including ! "bqoute.h". ! ! Between two chunks of text, a space is inserted ! automatically. ! ! Finally, close your quote to return to normal printing ! by calling ! ! bq_close(); ! ! Before opening and after closing a quote, a newline is ! printed. You might want to end the text before the quote ! and begin the text after it with an extra newline: ! ! description [; ! text "One section in particular catches ! your attention:^"; ! bq_open(4); ! bq_text("The security system ..."); ! bq_newline(); ! bq_newline(); ! bq_text("The password is ~Halifax~."); ! bq_close(); ! "^Now that's interesting."; ! ]; ! ! Examples of quote styles: ! ! Regular blockquote, four spaces left and right: ! ! bq_open(4); ! ! Reverse box across the whole screen with a padding of ! four: ! ! bq_open(0, 4); ! ! Zero margin boxes work on many interpreters, but on ! some terps they might cause extra blank lines, so better ! use a safty margin: ! ! bq_open(1, 3); ! ! Narrow box 30 spaces wide, aligned to left margin (4): ! ! bq_open(4, 1, 30); ! ! Same, but centered. The text is always left flushed: ! ! bq_open(4, 1, -30); ! ! Customization ! ! The style for quotes with a positive margin is reverse ! per default, making such block quotes inline box quotes. ! ! You can change the style of these quotes by specifying ! your own routines bq_style_on and bq_style_off, e.g. to ! use coloured blocks and a "mail quote" effect: ! ! Replace bq_style_on; ! Replace bq_style_off; ! ! [bq_style_on; ! if ((0->1) & 1 ~= 0) @set_colour 3 9; ! else style reverse; ! print">"; ! ]; ! ! [bq_style_off; ! if ((0->1) & 1 ~= 0) @set_colour 1 1; ! else style roman; ! ]; ! ! Include "bquote"; ! ! Words that run longer than a line are printed over the ! right margin. Buffering is off in bq mode, so that the ! layout is usually not very much affected. You can change ! this behaviour by defining the constant BQ_TRIM_LINES ! which causes long words to be pruned. A tilde is then ! printed and the word continues on the next line. This ! might be tidier for reverse boxes. ! ! Versions and History ! ! 18-May-2005 Version 1.0 ! ! Author ! ! Martin Oehm (martin.oehm at gmx.de) ! !--------------------------------------------------------------- System_file; Default BQ_MAX_LENGTH 512; Global bq_width = -1; Global bq_margin; Global bq_padding; Global bq_pos; Array bq_buffer -> BQ_MAX_LENGTH + 2; [bq_getwidth; #ifdef TARGET_ZCODE; ! read the z-code header byte return 0->$21; #ifnot; ! use the width of the status window if possible if (gg_statuswin) glk($0025, gg_statuswin, gg_arguments, gg_arguments + WORDSIZE); else glk($0025, gg_mainwin, gg_arguments, gg_arguments + WORDSIZE); return gg_arguments-->0; #endif; ]; [bq_open marg padd max; if (bq_width > 0) print "[*** Waring: bq already open. ***]"; bq_width = bq_getwidth(); bq_padding = padd; if (max < 0) { ! margins are determined by width bq_margin = (bq_width + max)/2 - bq_padding; if (bq_margin < marg) bq_margin = marg; max = 0; } else { ! width is determined by margins bq_margin = marg; } bq_width = bq_width - 2*bq_margin - 2*bq_padding; if (max && bq_width > max) bq_width = max; font off; bq_newline(1); #ifdef TARGET_ZCODE; #ifndef BQ_TRIM_LINES; ! no buffering for words that run over the right margin @buffer_mode 0; #endif; #endif; ]; [bq_style_on; style reverse; ]; [bq_style_off; style roman; ]; [bq_newline suppress; if (suppress <= 0 && bq_padding) { spaces bq_width - bq_pos + bq_padding; bq_style_off(); } new_line; bq_pos = 0; spaces bq_margin; if (suppress < 0) return; if (bq_padding) { bq_style_on(); spaces bq_padding; } ]; [bq_print a l; if (l < 0 || l > BQ_MAX_LENGTH) "***", l, " ***"; while (l--) { if (a->0 == 13 or 10) print "@@94"; else print (char) a->0; a++; bq_pos++; } ]; [bq_text s a1 a2 a3 a l ll sep; if (bq_width < 0) "[*** Error: bq not opened! ***]"; #ifdef TARGET_ZCODE; @output_stream 3 bq_buffer; if (s ofclass String) s.print(); if (s ofclass Routine) s.call(a1, a2, a3); @output_stream -3; l = bq_buffer-->0; a = bq_buffer + 2; #ifnot; l = PrintAnyToArray(bq_buffer, BQ_MAX_LENGTH, s, a1, a2, a3); a = bq_buffer; #endif; if (l > BQ_MAX_LENGTH) "[*** Error: String chunk too long! ***]"; while (bq_pos + l > bq_width) { ll = bq_width - bq_pos - 1; while (ll > 0 && a->ll ~= ' ') ll--; #ifdef BQ_TRIM_LINES; if (ll <= 0 && bq_pos == 0) { ! trim overlong words ll = bq_width - bq_pos -1; sep = true; } #ifnot; if (ll <= 0 && bq_pos == 0) { ! find next space ll = bq_width - bq_pos; while (ll < l && a->ll ~= ' ') ll++; } #endif; if (ll > 0) { bq_print(a, ll); a = a + ll + 1; l = l -ll - 1; if (sep) { print "@@126"; bq_pos++; a--; l++; sep = false; } if (l < 0) { a = a + l; l = 0; } } bq_newline(); } bq_print(a, l); if (bq_pos < bq_width) { print " "; bq_pos++; } ]; [bq_close; #ifdef TARGET_ZCODE; #ifndef BQ_TRIM_LINES; @buffer_mode 1; #endif; #endif; bq_newline(-1); font on; bq_width = -1; ];