! Copyright (C) 2014 John Benediktsson ! See http://factorcode.org/license.txt for BSD license USING: accessors byte-arrays colors.constants combinators formatting fry images images.loader images.loader.private images.viewer io io.encodings.binary io.encodings.string io.encodings.utf8 io.sockets io.styles kernel make math math.parser namespaces present prettyprint sequences splitting summary urls urls.encoding vocabs ; IN: gopher [ string>number ] [ first ] if ] [ "?" split1 [ "\t" glue ] when* "\r\n" append utf8 encode write flush input-stream get (stream-contents-by-block) ] bi* ; PRIVATE> ERROR: not-a-gopher-url url ; : gopher ( url -- item-type byte-array ) dup url? [ >url ] unless dup protocol>> "gopher" = [ not-a-gopher-url ] unless { [ host>> ] [ port>> 70 or binary ] [ path>> rest [ "1/" ] when-empty ] [ query>> [ assoc>query url-decode "?" glue ] when* ] } cleave '[ _ gopher-get ] with-client ; url present ; : ( item -- gopher-link ) [ "" ] [ unclip swap "\t" split first4 gopher-link boa ] if-empty ; M: gopher-link >url dup type>> CHAR: h = [ selector>> "URL:" ?head drop ] [ { [ host>> ] [ port>> ] [ type>> ] [ selector>> ] } cleave "gopher://%s:%s/%s%s" sprintf ] if >url ; : gopher-link. ( gopher-link -- ) dup type>> CHAR: i = [ name>> print ] [ [ name>> ] keep [ presented ,, COLOR: blue foreground ,, ] H{ } make format nl ] if ; : gopher-text ( object -- lines ) utf8 decode string-lines { "." } split1 drop ; : gopher-gif ( object -- image ) "gif" (image-class) load-image* ; : gopher-menu ( object -- links ) gopher-text [ ] map ; PRIVATE> : gopher. ( url -- ) gopher swap { { A_TEXT [ gopher-text [ print ] each ] } { A_MENU [ gopher-menu [ gopher-link. ] each ] } { A_INDEX [ gopher-menu [ gopher-link. ] each ] } { A_GIF [ gopher-gif image. ] } [ drop . ] } case ;