! Copyright (C) 2014 John Benediktsson ! See https://factorcode.org/license.txt for BSD license USING: accessors calendar colors combinators formatting images.loader images.loader.private images.viewer io io.encodings.binary io.encodings.string io.encodings.utf8 io.sockets io.styles io.timeouts kernel make namespaces present prettyprint sequences splitting summary urls urls.encoding ; IN: gopher ERROR: not-a-gopher-url url ; : gopher ( url -- item-type byte-array ) >url 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 '[ 1 minutes input-stream get set-timeout _ gopher-get ] with-client ; url present ; : ( item -- gopher-link ) unclip swap "\t" split first4 gopher-link boa ; M: gopher-link >url dup type>> CHAR: h = [ selector>> "URL:" ?head drop ] [ { [ host>> ] [ port>> ] [ type>> ] [ selector>> ] } cleave "gopher://%s:%s/%c%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 split-lines { "." } split1 drop ; : gopher-text. ( object -- ) gopher-text [ print ] each ; : gopher-gif. ( object -- ) "gif" (image-class) load-image* image. ; : gopher-image. ( path object -- path ) over image-class load-image* image. ; : gopher-menu. ( object -- ) gopher-text [ [ nl ] [ gopher-link. ] if-empty ] each ; PRIVATE> : gopher. ( url -- ) >url [ path>> ] [ gopher swap ] bi { { A_TEXT [ gopher-text. ] } { A_MENU [ gopher-menu. ] } { A_INDEX [ gopher-menu. ] } { A_GIF [ gopher-gif. ] } { A_IMAGE [ gopher-image. ] } [ drop . ] } case drop ;