181 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Factor
		
	
	
		
		
			
		
	
	
			181 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Factor
		
	
	
| 
								 | 
							
								! Copyright (C) 2008 Doug Coleman.
							 | 
						||
| 
								 | 
							
								! See http://factorcode.org/license.txt for BSD license.
							 | 
						||
| 
								 | 
							
								USING: accessors arrays combinators html.elements io io.streams.string
							 | 
						||
| 
								 | 
							
								kernel math memoize namespaces peg peg.ebnf prettyprint
							 | 
						||
| 
								 | 
							
								sequences sequences.deep strings xml.entities vectors splitting
							 | 
						||
| 
								 | 
							
								xmode.code2html ;
							 | 
						||
| 
								 | 
							
								IN: farkup
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SYMBOL: relative-link-prefix
							 | 
						||
| 
								 | 
							
								SYMBOL: disable-images?
							 | 
						||
| 
								 | 
							
								SYMBOL: link-no-follow?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TUPLE: heading1 obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: heading2 obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: heading3 obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: heading4 obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: strong obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: emphasis obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: superscript obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: subscript obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: inline-code obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: paragraph obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: list-item obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: list obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: table obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: table-row obj ;
							 | 
						||
| 
								 | 
							
								TUPLE: link href text ;
							 | 
						||
| 
								 | 
							
								TUPLE: image href text ;
							 | 
						||
| 
								 | 
							
								TUPLE: code mode string ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								EBNF: farkup
							 | 
						||
| 
								 | 
							
								nl               = ("\r\n" | "\r" | "\n") => [[ drop "\n" ]]
							 | 
						||
| 
								 | 
							
								2nl              = nl nl
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								heading1      = "=" (!("=" | nl).)+ "="
							 | 
						||
| 
								 | 
							
								    => [[ second >string heading1 boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								heading2      = "==" (!("=" | nl).)+ "=="
							 | 
						||
| 
								 | 
							
								    => [[ second >string heading2 boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								heading3      = "===" (!("=" | nl).)+ "==="
							 | 
						||
| 
								 | 
							
								    => [[ second >string heading3 boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								heading4      = "====" (!("=" | nl).)+ "===="
							 | 
						||
| 
								 | 
							
								    => [[ second >string heading4 boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								strong        = "*" (!("*" | nl).)+ "*"
							 | 
						||
| 
								 | 
							
								    => [[ second >string strong boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								emphasis      = "_" (!("_" | nl).)+ "_"
							 | 
						||
| 
								 | 
							
								    => [[ second >string emphasis boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								superscript   = "^" (!("^" | nl).)+ "^"
							 | 
						||
| 
								 | 
							
								    => [[ second >string superscript boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								subscript     = "~" (!("~" | nl).)+ "~"
							 | 
						||
| 
								 | 
							
								    => [[ second >string subscript boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline-code   = "%" (!("%" | nl).)+ "%"
							 | 
						||
| 
								 | 
							
								    => [[ second >string inline-code boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								escaped-char  = "\" .                => [[ second ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								image-link       = "[[image:" (!("|") .)+  "|" (!("]]").)+ "]]"
							 | 
						||
| 
								 | 
							
								                    => [[ [ second >string ] [ fourth >string ] bi image boa ]]
							 | 
						||
| 
								 | 
							
								                  | "[[image:" (!("]").)+ "]]"
							 | 
						||
| 
								 | 
							
								                    => [[ second >string f image boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								simple-link      = "[[" (!("|]" | "]]") .)+ "]]"
							 | 
						||
| 
								 | 
							
								    => [[ second >string dup link boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								labelled-link    = "[[" (!("|") .)+ "|" (!("]]").)+ "]]"
							 | 
						||
| 
								 | 
							
								    => [[ [ second >string ] [ fourth >string ] bi link boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								link             = image-link | labelled-link | simple-link
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								heading          = heading4 | heading3 | heading2 | heading1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline-tag       = strong | emphasis | superscript | subscript | inline-code
							 | 
						||
| 
								 | 
							
								                   | link | escaped-char
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline-delimiter = '*' | '_' | '^' | '~' | '%' | '\' | '['
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								table-column     = (list | (!(nl | inline-delimiter | '|').)+ | inline-tag | inline-delimiter  ) '|'
							 | 
						||
| 
								 | 
							
								    => [[ first ]]
							 | 
						||
| 
								 | 
							
								table-row        = "|" (table-column)+
							 | 
						||
| 
								 | 
							
								    => [[ second table-row boa ]]
							 | 
						||
| 
								 | 
							
								table            =  ((table-row nl => [[ first ]] )+ table-row? | table-row)
							 | 
						||
| 
								 | 
							
								    => [[ table boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								paragraph-item = ( table | (!(nl | code | heading | inline-delimiter | table ).) | inline-tag | inline-delimiter)+
							 | 
						||
| 
								 | 
							
								paragraph = ((paragraph-item nl => [[ first ]])+ nl+ => [[ first ]]
							 | 
						||
| 
								 | 
							
								             | (paragraph-item nl)+ paragraph-item?
							 | 
						||
| 
								 | 
							
								             | paragraph-item)
							 | 
						||
| 
								 | 
							
								    => [[ paragraph boa ]]
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								list-item      = '-' ((!(inline-delimiter | nl).)+ | inline-tag)*
							 | 
						||
| 
								 | 
							
								    => [[ second list-item boa ]]
							 | 
						||
| 
								 | 
							
								list = ((list-item nl)+ list-item? | list-item)
							 | 
						||
| 
								 | 
							
								    => [[ list boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								code       =  '[' (!('{' | nl | '[').)+ '{' (!("}]").)+ "}]"
							 | 
						||
| 
								 | 
							
								    => [[ [ second >string ] [ fourth >string ] bi code boa ]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								stand-alone      = (code | heading | list | table | paragraph | nl)*
							 | 
						||
| 
								 | 
							
								;EBNF
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: invalid-url "javascript:alert('Invalid URL in farkup');" ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: check-url ( href -- href' )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        { [ dup empty? ] [ drop invalid-url ] }
							 | 
						||
| 
								 | 
							
								        { [ dup [ 127 > ] contains? ] [ drop invalid-url ] }
							 | 
						||
| 
								 | 
							
								        { [ dup first "/\\" member? ] [ drop invalid-url ] }
							 | 
						||
| 
								 | 
							
								        { [ CHAR: : over member? ] [
							 | 
						||
| 
								 | 
							
								            dup { "http://" "https://" "ftp://" } [ head? ] with contains?
							 | 
						||
| 
								 | 
							
								            [ drop invalid-url ] unless
							 | 
						||
| 
								 | 
							
								        ] }
							 | 
						||
| 
								 | 
							
								        [ relative-link-prefix get prepend ]
							 | 
						||
| 
								 | 
							
								    } cond ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: escape-link ( href text -- href-esc text-esc )
							 | 
						||
| 
								 | 
							
								    >r check-url escape-quoted-string r> escape-string ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: write-link ( text href -- )
							 | 
						||
| 
								 | 
							
								    escape-link
							 | 
						||
| 
								 | 
							
								    "<a" write
							 | 
						||
| 
								 | 
							
								    " href=\"" write write "\"" write
							 | 
						||
| 
								 | 
							
								    link-no-follow? get [ " nofollow=\"true\"" write ] when
							 | 
						||
| 
								 | 
							
								    ">" write write "</a>" write ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: write-image-link ( href text -- )
							 | 
						||
| 
								 | 
							
								    disable-images? get [
							 | 
						||
| 
								 | 
							
								        2drop "<strong>Images are not allowed</strong>" write
							 | 
						||
| 
								 | 
							
								    ] [
							 | 
						||
| 
								 | 
							
								        escape-link
							 | 
						||
| 
								 | 
							
								        >r "<img src=\"" write write "\"" write r>
							 | 
						||
| 
								 | 
							
								        dup empty? [ drop ] [ " alt=\"" write write "\"" write ] if
							 | 
						||
| 
								 | 
							
								        "/>" write
							 | 
						||
| 
								 | 
							
								    ] if ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: render-code ( string mode -- string' )
							 | 
						||
| 
								 | 
							
								    >r string-lines r>
							 | 
						||
| 
								 | 
							
								    [
							 | 
						||
| 
								 | 
							
								        <pre>
							 | 
						||
| 
								 | 
							
								            htmlize-lines
							 | 
						||
| 
								 | 
							
								        </pre>
							 | 
						||
| 
								 | 
							
								    ] with-string-writer write ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								GENERIC: write-farkup ( obj -- )
							 | 
						||
| 
								 | 
							
								: <foo.> ( string -- ) <foo> write ;
							 | 
						||
| 
								 | 
							
								: </foo.> ( string -- ) </foo> write ;
							 | 
						||
| 
								 | 
							
								: in-tag. ( obj quot string -- ) [ <foo.> call ] keep </foo.> ; inline
							 | 
						||
| 
								 | 
							
								M: heading1 write-farkup ( obj -- ) [ obj>> write-farkup ] "h1" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: heading2 write-farkup ( obj -- ) [ obj>> write-farkup ] "h2" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: heading3 write-farkup ( obj -- ) [ obj>> write-farkup ] "h3" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: heading4 write-farkup ( obj -- ) [ obj>> write-farkup ] "h4" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: strong write-farkup ( obj -- ) [ obj>> write-farkup ] "strong" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: emphasis write-farkup ( obj -- ) [ obj>> write-farkup ] "em" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: superscript write-farkup ( obj -- ) [ obj>> write-farkup ] "sup" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: subscript write-farkup ( obj -- ) [ obj>> write-farkup ] "sub" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: inline-code write-farkup ( obj -- ) [ obj>> write-farkup ] "code" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: list-item write-farkup ( obj -- ) [ obj>> write-farkup ] "li" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: list write-farkup ( obj -- ) [ obj>> write-farkup ] "ul" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: paragraph write-farkup ( obj -- ) [ obj>> write-farkup ] "p" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: link write-farkup ( obj -- ) [ text>> ] [ href>> ] bi write-link ;
							 | 
						||
| 
								 | 
							
								M: image write-farkup ( obj -- ) [ href>> ] [ text>> ] bi write-image-link ;
							 | 
						||
| 
								 | 
							
								M: code write-farkup ( obj -- ) [ string>> ] [ mode>> ] bi render-code ;
							 | 
						||
| 
								 | 
							
								M: table-row write-farkup ( obj -- )
							 | 
						||
| 
								 | 
							
								    obj>> [ [ [ write-farkup ] "td" in-tag. ] each ] "tr" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: table write-farkup ( obj -- ) [ obj>> write-farkup ] "table" in-tag. ;
							 | 
						||
| 
								 | 
							
								M: fixnum write-farkup ( obj -- ) write1 ;
							 | 
						||
| 
								 | 
							
								M: string write-farkup ( obj -- ) write ;
							 | 
						||
| 
								 | 
							
								M: vector write-farkup ( obj -- ) [ write-farkup ] each ;
							 | 
						||
| 
								 | 
							
								M: f write-farkup ( obj -- ) drop ;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								: convert-farkup ( string -- string' )
							 | 
						||
| 
								 | 
							
								    farkup [ write-farkup ] with-string-writer ;
							 |