USING: combinators io.encodings.utf8 io.files kernel make namespaces sequences unicode.categories ; IN: t2t ! Predicates : strip ( line -- line' ) [ blank? ] trim ; : heading? ( string -- ? ) [ f ] [ [ first "=+" member? ] [ last "=+" member? ] bi and ] if-empty ; : list? ( string -- ? ) [ f ] [ [ first "-+" member? ] [ heading? not ] bi and ] if-empty ; : comment? ( line -- ? ) first CHAR: % = ; : table-row? ( line -- ? ) strip [ f ] [ [ first CHAR: | = ] [ last CHAR: | = ] bi and ] if-empty ; ! Parsing helpers SYMBOL: lines : eof? ( -- ? ) lines get empty? ; : skip-line ( -- ) lines get [ "skip-line found EOF" throw ] [ 1 tail-slice lines set ] if-empty ; : peek-line ( -- line ) lines get [ "peek-line found EOF" throw ] [ first ] if-empty ; ! Parsing words : parse-heading ( -- ) "heading" , skip-line ; : parse-list ( -- ) "list" , skip-line peek-line list? [ skip-line ] when ; ! example of peeking the next item : parse-text ( -- ) "text" , skip-line ; : parse-lines ( -- ) [ eof? not ] [ { { [ peek-line empty? ] [ "empty" , skip-line ] } { [ peek-line comment? ] [ skip-line ] } { [ peek-line heading? ] [ parse-heading ] } { [ peek-line list? ] [ parse-list ] } [ parse-text ] } cond ] while ; : parse ( filename -- ast ) utf8 file-lines lines set [ parse-lines ] { } make ;