This is G o o g l e's cache of http://home.earthlink.net/~neilbawd/lnfilt.html.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:UibmgRrCa68C:home.earthlink.net/~neilbawd/lnfilt.html+&hl=en&ie=UTF-8


Google is not affiliated with the authors of this page nor responsible for its content.

Line Filter

Line Filter

Wil Baden 1998-12-15

LINE: is used to define a line filter.

|| and || separate the three components of a line filter.

LINE; finishes the definition.

TEXT

The most powerful editor that I have ever used comes from a one-line definition given me by Ward McFarland.

    \  CLIPBOARD  gives the address and length of the
    \  text in the program clipboard.

    : CLIPBOARD  ( -- _str len_ )
        SE.SCRAP DUP @ SWAP _GetHandleSize ;

It has made a fundamental change in text and data management.

Now the principal way to handle text and data is select it, copy it to the clipboard, and submit a function name that you have defined.

The editor is written in Forth, and is directly integrated with Forth. The return key starts a new line. But there also is a submit key that interprets the line you are on or the text you have selected. Any output from the interpretation appears following the line or selection. Error messages are formatted as comments so the text can be changed and immediately submitted again without having to remove the error messages right away. .S, .., and others also output in the form of a comment. (.. is a destructive stack dump.)

In PowerMacForth the submit key is shift-return or the enter key. The enter key is distinct from the return key on the Macintosh.

A programming editor that does not have a submit stroke is deficient. With a submit stroke there is no bouncing between Forth and the editor. Almost all work is done in the editor.

"Select and submit" is the operation of selecting text and then doing the submit stroke.

CLIPBOARD makes it easy to program functions that work on text and data.

The format in the clipboard is lines separated by the #EOL-CHAR character. The #EOL-CHAR character is <return> on the Macintosh, and <linefeed> in Unix. As usual on the PC it is messier.

You can walk through the clipboard line by line using SPLIT-NEXT-LINE.

    \  SPLIT-NEXT-LINE  splits the next line from the
    \  rest of the clipboard.

    : SPLIT-NEXT-LINE  ( str len -- str2 len2 str1 len1 )
        2DUP #EOL-CHAR SCAN  DUP >R  1 /STRING  2SWAP R> - ;

Most functions on the clipboard work a line at a time.

    CLIPBOARD BEGIN  DUP 0> WHILE ( str len)
        SPLIT-NEXT-LINE           ( str2 len2 str1 len1)
        (Do a line.)              ( str2 len2)
    REPEAT 2DROP                  ( )

This logic has been encapsulated with defining word LINE:. The definition is ended with LINE;.

    LINE: function-name  (Do a line.)  LINE;

Simple functions have simple definitions.

    \  C  copies "\ " before non-empty lines.

    LINE: C
        TRIM  DUP IF  ." \ " THEN
        TYPE CR
        LINE;

The defined word will initialize four variables: TEMP, OUT, FLAG and COMMENTARY. You can use these variables for whatever you want.

I use FLAG for mode setting. Many defined functions use OUT to count lines or columns. When OUT has 0 it is the beginning of a new paragraph.

LINE: uses :NONAME three times to prepare execution tokens for special initiation, line processing, and termination.

When special initiation or termination is needed, the line processing must be bracketed by || and ||. Without || only line processing is done.

Words defined by LINE: start execution by backing over themselves. This is so the name does not appear in the output.

No stack-effect comment is given with LINE: definitions because it is invariant.

When executing, at the beginning of line processing the stack will be str2 len2 str1 len1. At the end of line processing the stack should be str2 len2. str2 len2 is the rest of the clipboard.

With this format when processing a line, you can look at the next line.

CLIPBOARD can be used for other than editing. It becomes the main source of data input. The usual mode of input is in the editor. Text is selected and copied in the editor, and then displayed by submitting a line filter command where you want the result.

"Select, copy, and submit" and "select, cut, and submit" are the usual operations.

Line filters are often defined for a particular task, used once, and abandoned.

Using CLIPBOARD is helped by an library of scanning and parsing definitions. Their use can be seen in the examples.


CLIPBOARD           ( -- str len )
Editor TEXT scrap. Dependent on PowerMacForth editor.
CB                  ( -- str len )
Synonym of CLIPBOARD. For interactive use.
BACKSPACES          ( n -- )
Backspace and wipe out n characters. Environmentally dependent.
TEMP OUT FLAG COMMENTARY  ( -- addr )
Convenient working variables when filtering the clipboard. They will be initialized to 0.
CONTINUING          ( -- addr )
ON to skip the initializing of TEMP. This is so the number in TEMP can be continued.
CONTINUED
Turn CONTINUING on.
Program Text 1
 ALSO EDITOR
 : CLIPBOARD  ( -- str len )
     SE.SCRAP DUP @ SWAP _GETHANDLESIZE ;
 PREVIOUS

: CB ( -- str len ) clipboard ;

\ 8 CONSTANT #BACKSPACE-CHAR

: BACKSPACES  ( n -- )  #BACKSPACE-CHAR EMITS ;

VARIABLE FLAG
VARIABLE COMMENTARY
VARIABLE CONTINUING

: CONTINUED  ( -- )  CONTINUING ON ;


EXDEPTH             ( -- addr )
Variable for the old DEPTH.
SAVE-DEPTH          ( -- )
Save current DEPTH.
CHECK-DEPTH         ( -- )
Display message if DEPTH changed.
Program Text 2
VARIABLE EXDEPTH

: SAVE-DEPTH        ( -- )
    DEPTH EXDEPTH ! ;

: CHECK-DEPTH       ( ... -- same )
    DEPTH EXDEPTH @ < ABORT" Stack shrinking."
    DEPTH EXDEPTH @ > ABORT" Stack growing."
    ;


#EOL-CHAR           ( -- n )
End-of-line character. 10 for Unix; 13 for Macintosh; 13 plus one more for PC.
SPLIT-NEXT-LINE     ( str len -- str2 len2 str1 len1 )
Split the next line from the rest of the text.
LINE-FILTER         ( xt -- xt' )
Execute the line filter for each line of text. Dependent on CLIPBOARD. Used in DO-LINE-FILTER:.
DO-LINE-FILTER:     ( "name" -- addr )
Create the three part filter. Used in LINE:.
Program Text 3
\  PowerMacForth to turn off line spacing after submit.
ALSO EDITOR  0 TO +CR  PREVIOUS

\ 13 VALUE #EOL-CHAR  \  10 for Unix.

: BEGIN?
    S" SAVE-DEPTH BEGIN CHECK-DEPTH DUP 0> WHILE " EVALUATE
    ; IMMEDIATE

\ : SPLIT-NEXT-LINE  ( str len -- str2 len2 str1 len1 )
\    2DUP #EOL-CHAR SCAN  DUP >R  1 /STRING  2SWAP R> - ;

: SPLIT-LINES
    S" BEGIN? SPLIT-NEXT-LINE " EVALUATE
    ; IMMEDIATE

    : STOP?  ( -- flag )
        KEY? 0=  IF  FALSE EXIT   THEN
        KEY BL = IF  KEY DROP  FALSE EXIT  THEN
        TRUE ;

    : ?REPEAT  S" STOP? UNTIL THEN " EVALUATE ; IMMEDIATE

: LINE-FILTER          ( xt -- xt' )
    >R                 ( )( R: xt)
        CLIPBOARD      ( str len)
        SPLIT-LINES    ( str2 len2 str1 len1)
            R@ @ EXECUTE  ( str2 len2)
        ?REPEAT 2DROP
    R> ;

: LINE-FILTER-INIT    ( -- )
    FLAG OFF  OUT OFF  COMMENTARY OFF
    CONTINUING DUP @ TEMP ! OFF ;

: DO-LINE-FILTER:  ( "name" -- addr )
    >IN @  CREATE
    >IN !  BL WORD C@ ,   HERE 0 , 0 , 0 ,

    DOES> ( addr)

    LINE-FILTER-INIT

    \  Backover the name.
    DUP @ BACKSPACES CELL+

    \  Execute any initialization.
    DUP CELL+ @ IF  DUP CELL+ SWAP @ EXECUTE  THEN

    \  Execute the line filter.
    LINE-FILTER

    \  Execute termination.
    CELL+ @ ?DUP IF EXECUTE THEN ;


LINE:               ( "name" -- )
Define a line filter.
||
Separate components of a line filter.
LINE;
Finish the line filter definition.
Program Text 4
: LINE:  ( "name" -- )  DO-LINE-FILTER: ( addr) :NONAME ;

: || POSTPONE ;  OVER ! CELL+ :NONAME ; IMMEDIATE

: LINE; POSTPONE ; SWAP ! ; IMMEDIATE


Go back to Neil Bawd's home page.