"====================================================================== | | A write stream which automatically indents | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Steve Byrne. | | This file is part of GNU Smalltalk. | | GNU Smalltalk is free software; you can redistribute it and/or modify it | under the terms of the GNU General Public License as published by the Free | Software Foundation; either version 2, or (at your option) any later version. | | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | details. | | You should have received a copy of the GNU General Public License along with | GNU Smalltalk; see the file COPYING. If not, write to the Free Software | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ======================================================================" Stream subclass: #IndentedStream instanceVariableNames: 'stream level amount tabAmount column' classVariableNames: '' poolDictionaries: '' category: 'Examples-Useful' ! !IndentedStream class methodsFor: 'instance creation'! on: aStream ^self new init: aStream ! ! !IndentedStream methodsFor: 'writing'! nextPut: aChar column == 0 ifTrue: [ self indentLine ]. stream nextPut: aChar. aChar == (Character nl) ifTrue: [ column := 0. ^self ]. aChar == (Character tab) ifTrue: [ column := self nextTab. ^self ]. column := column + 1. ! nextPutAll: aString | stringSize index start nl tab ch | index := 1. stringSize := aString size. nl := Character nl. tab := Character tab. ch := aString at: index. [ index <= stringSize ] whileTrue: [ "Either the first character, or a newline, or a tab" self nextPut: ch. index := index + 1. [ (index > stringSize) or: [ ch := aString at: index. (ch = nl) | (ch = tab) ]] whileFalse: [ index := index + 1 ]. column == 0 ifTrue: [ self indentLine ]. stream nextPutAll: (aString copyFrom: start to: index - 1). column := column + (index - start) ]. ! tabTo: col | nextTab | nextTab := self nextTab. [ nextTab < col ] whileTrue: [ self tab. nextTab := nextTab + 8 ]. [ column < col ] whileTrue: [ self space ]. ! ! !IndentedStream methodsFor: 'accessing'! column ^column ! level ^level ! level: anInteger level := anInteger. self computeIndent. ! indentAmount ^amount ! indentAmount: anInteger amount := anInteger. ! popLevel self level: ((self level - 1) max: 0) ! pushLevel self level: self level + 1 ! tabAmount ^tabAmount ! tabAmount: anInteger tabAmount := anInteger. ! ! !IndentedStream methodsFor: 'private'! init: aStream stream := aStream. column := 0. self amount: 4; tabAmount: 8; level: 0 ! indentLine self tabTo: amount * level. ! nextTab ^(column + tabAmount) truncateTo: tabAmount. ! ! " | s t | s := IndentedStream on: (t := String new: 0). s pushLevel. s nl. s nextPutAll: 'hello there you rabbit'. s nl. s contents printNl. ! "