REBOL [ Title: "REBOL browser" File: %browser.r Date: 2000-06-10 Author: "Ingo Hohmann" Email: ingo@2b1.de Site: http://www.2b1.de/ Rights: "(c) Ingo Hohmann" Purpose: {A simple WWW Browser} Based-upon: "Carls text-view" Category: [view VID networking] Changes: [ [ 0.0.4 {startmessage displayed correctly} {mailto: links removed from visitable links} ] [ 0.0.3 {some more errors corrected} ] [ 0.0.2 {translates to " "} {evaluates } {prelimenary
handling} {corrected some errors} ] [ 0.0.1 {initial release (the unnumbered one)} ] ] Version: first first changes todo: [ {use load-thru ?} {handling needs other font} {let buttons reflect presence of scripts} {some cleaning} {testing, of course} ] ] browser: make object! [ help: {The browser Object} start-url: form http://www.2b1.de/ html: make object! [ help: {A html parser} evaluate: false read-error: none skip: false spaces: charset " ^-^/" non-spaces: complement spaces delimiters: charset { ^-^/="} ;" non-delimiters: complement delimiters html-source: copy "" get-html: func [][ return html-source ] find-base: func [ url [url! file!] /local u2][ if #"/" = last url [ return url ] if exists? u2: to-url rejoin [ url "/" ] [ return u2 ] first split-path url ] conv-list: [ "&" "&" "<" "<" ">" ">" """ {"} "ä" "ä" "Ä" "Ä" "ö" "ö" "Ö" "Ö" "ü" "ü" "Ü" "Ü" "ß" "ß" " " " "] clean: func [ {Converts html-entities to special-characters} text [string!] /local special entity ] [ foreach [special entity] conv-list [ replace/all text special entity ] text ] parse-tag: func [ {parses a tag, returns block of tag-name arguments} tag /local tag-name tag-params] [ name-rule: [ some non-delimiters ] param-rule: [ any spaces [ copy param-name name-rule (append tag-params param-name) any spaces [ "=" any spaces [ {"} copy param-val to {"} skip | {'} copy param-val to {'} skip | copy param-val some non-delimiters skip ] (append tag-params param-val) | (append tag-params true) ] ] ] tag-params: copy [] parse/all tag [ copy tag-name name-rule any param-rule ] compose [ (tag-name) (tag-params) ] ] read: func [ {read url and return the page as ...} url [url! file!] /html "html source" /text "text" /links "link-list" /local data txt lnk return-block ] [ return-block: copy [] either error? err: try [data: read url] [ read-error: disarm err ] [ read-error: none if html [ append return-block data ] if any [ txt links ] [ set [txt lnk] to-text url data if text [ append return-block txt ] if links [ append/only return-block lnk ] ] print dir? url ] ] to-text: func [ {Convert html to text, url is needed for handling of relative urls} url [url! file!] html [string!] /local elem txt links link lfd link-blk pos end-pos the-script script-funcs ] [ script-funcs: make object! [ print: func [val][ insert pos load/markup form join val newline ] prin: func [val][ insert pos load/markup form val ] ] url: find-base url links: copy [] link-blk: copy [] html-source: copy html html: load/markup html txt: make string! 500 lfd: 0 parse html [ some [ set elem string! ( if not skip [ if 0 < length? trim/lines elem [ append txt rejoin [ elem " "] ] ] ) | pos: set elem tag! ( elem: parse-tag elem switch first elem [ "a" [ lfd: lfd + 1 append txt rejoin [ "(" lfd ")" ] elem: select elem "href" if elem [ if all [ not find elem "://" not find elem "mailto:"] [ ; ??? elem: rejoin [ url elem ] ] append links compose [ (lfd) (elem)] ] ] "img" [ either elem: select elem "alt" [ append txt rejoin [ "[" elem "]" ] ] [ append txt "[graphic]" ] ] "p" [append txt "^/^/"] "br" [append txt newline] "hr" [append txt "^/------------------------------------^/" ] "li" [append txt "^/* "] "ul" [append txt newline] "/ul" [append txt newline] "ol" [append txt newline] "/ol" [append txt newline] "div" [append txt newline] "/div" [append txt newline] "blockquote" [append txt newline] "/blockquote" [append txt newline] "style" [skip: true] "/style" [skip: false] "pre" [ end-pos: find posappend txt rejoin [ newline copy/part next pos end-pos ] pos: end-pos ] "script" [ either all [ evaluate "rebol" = select elem "language" ] [ end-pos: find pos the-script: copy/part next pos end-pos remove/part pos next end-pos if error? err: try [ do bind load rejoin the-script in script-funcs 'print ] [ inform layout [ title red "Error in script !" text mold disarm err ] ] pos: back pos ][ skip: true ] ] ; do bind load rejoin n in t 'print "/script" [skip: false] "/title" [append txt "^/^/"] ] pos: next pos ) :pos ] ] txt: clean txt append txt "^/^/^/The links:^/-------^/^/" foreach [lfd link] links [ append txt rejoin [ lfd " " link newline]] foreach [lfd link] links [ if not find link "mailto:" [append link-blk rejoin [ lfd " " link]]] return compose/deep [ (txt) [(link-blk)]] ] ] size: 0x0 link-list: copy [] visited-links: copy [] ; Browsers GUI browser: layout [ backdrop effect [gradient -1x-1 0.200.0] title rejoin [ "Very basic WWW browser ... (Ver: " system/script/header/version ")"] box 656x4 effect [gradient 1x0 200.0.0] across space 6 text bold "File:" f1: field 516x24 start-url [ either all [ not error? try [ url: load f1/text ] any [ url? url file? url ] ] [ either not error? err: try [ txt: read url ] [ insert visited-links url set [txt link-list] html/to-text url txt t3/text: either length? txt [txt][none] show t3 size: size-text t3 c1/text: either empty? link-list ["no links found"]["Goto link"] show c1 true ][ inform layout [ title red "Error" text mold disarm err ] ] ] [ inform layout [ title red "Error" text rejoin [ "Not a valid url: " f1/text ] ] ] ] button "Load" #"^l" [ do f1/action none none] return indent 37 c1: button 516x24 #"^g" "No Links found" [ choose link-list func [f a] [f1/text: copy find f/text "http://" show f1] c1 ] button "Back" #"^b" [ remove visited-links if not empty? visited-links [ f1/text: first visited-links show f1 ] ] return space 0 t3: text 640x480 with [color: 250.250.250 ] s1: slider 16x480 [ t3/para/origin/y: s1/data - 1 * size/y / -480 + 2 show t3 ] return space 6 pad 0x6 button "broWse" #"^w" [ browse f1/text ] tab bEval: button "Evaluate" #"^e" [ html/evaluate: not html/evaluate bEval/text: either html/evaluate ["don't Eval"]["Evaluate"]] button "Run" #"^r" [ if error? err: try [ do load f1/text 'true ] [ inform layout [ title red rejoin ["Can't 'do " f1/text] text mold disarm err ] ] ] tab button "CloSE" #"^(ESC)" [ unview/all ] ] t3/text: trim/auto { Me little Rebol Browser ... ^/ Well, I just couldn't get the time to write a real Reblet, so I just settled to this one. You can type in an url, and press return. If the page contains further links, then the links will be displayed as a link-list, and can be choosen from the "Goto"-Button. ^^g goto ^^l load ^^w start WWW browser on url ESC close window Bugs: ^^b back (doesn't work yet) AND NOW PRESS LOAD ... } view browser ]