! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: assocs io.files io.pathnames io.directories io.encodings.utf8 hashtables kernel namespaces sequences vocabs.loader vocabs.metadata io combinators calendar accessors math.parser io.streams.string ui.tools.operations quotations strings arrays prettyprint words vocabs sorting sets classes math alien urls splitting ascii combinators.short-circuit alarms words.symbol system summary ; IN: tools.scaffold SYMBOL: developer-name SYMBOL: using ERROR: not-a-vocab-root string ; ERROR: vocab-name-contains-separator path ; ERROR: vocab-name-contains-dot path ; ERROR: bad-developer-name name ; M: bad-developer-name summary drop "Developer name must be a string." ; path ( vocab-root vocab -- path ) check-vocab-root/vocab [ ] [ replace-vocab-separators ] bi* append-path ; : vocab>path ( vocab -- path ) check-vocab [ find-vocab-root ] keep vocab-root/vocab>path ; : vocab-root/vocab/file>path ( vocab-root vocab file -- path ) [ vocab-root/vocab>path ] dip append-path ; : vocab-root/vocab/suffix>path ( vocab-root vocab suffix -- path ) [ vocab-root/vocab>path dup file-name append-path ] dip append ; : vocab/file>path ( vocab file -- path ) [ vocab>path ] dip append-path ; : vocab/suffix>path ( vocab suffix -- path ) [ vocab>path dup file-name append-path ] dip append ; : directory-exists ( path -- ) "Not creating a directory, it already exists: " write print ; : scaffold-directory ( vocab-root vocab -- ) vocab-root/vocab>path dup exists? [ directory-exists ] [ make-directories ] if ; : not-scaffolding ( path -- path ) "Not creating scaffolding for " write dup . ; : scaffolding ( path -- path ) "Creating scaffolding for " write dup . ; : scaffolding? ( path -- path ? ) dup exists? [ not-scaffolding f ] [ scaffolding t ] if ; : scaffold-copyright ( -- ) "! Copyright (C) " write now year>> number>string write developer-name get [ "Your name" ] unless* bl write "." print "! See http://factorcode.org/license.txt for BSD license." print ; : main-file-string ( vocab -- string ) [ scaffold-copyright "USING: ;" print "IN: " write print ] with-string-writer ; : set-scaffold-main-file ( vocab path -- ) [ main-file-string 1array ] dip utf8 set-file-lines ; : scaffold-main ( vocab-root vocab -- ) [ ".factor" vocab-root/vocab/suffix>path ] keep swap scaffolding? [ set-scaffold-main-file ] [ 2drop ] if ; : scaffold-metadata ( vocab file contents -- ) [ ensure-vocab-exists ] 2dip [ [ vocab/file>path ] dip 1array swap scaffolding? [ utf8 set-file-lines ] [ 2drop ] if ] [ 2drop ] if* ; : lookup-type ( string -- object/string ? ) "new" ?head drop [ { [ CHAR: ' = ] [ digit? ] } 1|| ] trim-tail H{ { "object" object } { "obj" object } { "quot" quotation } { "string" string } { "str" string } { "hash" hashtable } { "hashtable" hashtable } { "?" boolean } { "ch" "a character" } { "word" word } { "array" array } { "alarm" alarm } { "duration" duration } { "path" "a pathname string" } { "vocab" "a vocabulary specifier" } { "vocab-root" "a vocabulary root string" } { "c-ptr" c-ptr } { "seq" sequence } { "assoc" assoc } { "alist" "an array of key/value pairs" } { "keys" sequence } { "values" sequence } { "class" class } { "tuple" tuple } { "url" url } } at* ; : add-using ( object -- ) vocabulary>> using get [ conjoin ] [ drop ] if* ; : ($values.) ( array -- ) [ bl ] [ "{ " write dup array? [ first ] when dup lookup-type [ [ unparse write bl ] [ [ pprint ] [ dup string? [ drop ] [ add-using ] if ] bi ] bi* ] [ drop unparse write bl null pprint null add-using ] if " }" write ] interleave ; : 4bl ( -- ) " " write ; inline : $values. ( word -- ) "declared-effect" word-prop [ [ in>> ] [ out>> ] bi 2dup [ empty? ] bi@ and [ 2drop ] [ "{ $values" print [ 4bl ($values.) ] [ [ nl 4bl ($values.) ] unless-empty ] bi* nl "}" print ] if ] when* ; : symbol-description. ( word -- ) drop "{ $var-description \"\" } ;" print ; : $description. ( word -- ) drop "{ $description \"\" } ;" print ; : docs-body. ( word/symbol -- ) dup symbol? [ symbol-description. ] [ [ $values. ] [ $description. ] bi ] if ; : docs-header. ( word -- ) "HELP: " write name>> print ; : (help.) ( word -- ) [ docs-header. ] [ docs-body. ] bi ; : interesting-words ( vocab -- array ) words [ { [ "help" word-prop ] [ predicate? ] } 1|| not ] filter natural-sort ; : interesting-words. ( vocab -- ) interesting-words [ (help.) nl ] each ; : docs-file-string ( vocab -- str2 ) [ { [ "IN: " write print nl ] [ interesting-words. ] [ [ "ARTICLE: " write unparse dup write bl print ] [ "{ $vocab-link " write pprint " }" print ] bi ";" print nl ] [ "ABOUT: " write unparse print ] } cleave ] with-string-writer ; : write-using ( vocab -- ) "USING:" write using get keys { "help.markup" "help.syntax" } append natural-sort remove [ bl write ] each " ;" print ; : set-scaffold-docs-file ( vocab path -- ) utf8 [ scaffold-copyright [ docs-file-string ] [ write-using ] bi write ] with-output-stream ; : with-scaffold ( quot -- ) [ H{ } clone using ] dip with-variable ; inline : link-vocab ( vocab -- ) check-vocab "Edit documentation: " write "-docs.factor" vocab/suffix>path . ; PRIVATE> : help. ( word -- ) [ (help.) ] [ nl vocabulary>> link-vocab ] bi ; : scaffold-help ( vocab -- ) ensure-vocab-exists [ dup "-docs.factor" vocab/suffix>path scaffolding? [ set-scaffold-docs-file ] [ 2drop ] if ] with-scaffold ; : scaffold-undocumented ( string -- ) [ interesting-words. ] [ link-vocab ] bi ; : scaffold-authors ( vocab -- ) "authors.txt" developer-name get scaffold-metadata ; : scaffold-tags ( vocab tags -- ) [ "tags.txt" ] dip scaffold-metadata ; : scaffold-summary ( vocab summary -- ) [ "summary.txt" ] dip scaffold-metadata ; : scaffold-platforms ( vocab platforms -- ) [ "platforms.txt" ] dip scaffold-metadata ; : scaffold-vocab ( vocab-root string -- ) { [ scaffold-directory ] [ scaffold-main ] [ nip require ] [ nip scaffold-authors ] } 2cleave ; : scaffold-core ( string -- ) "resource:core" swap scaffold-vocab ; : scaffold-basis ( string -- ) "resource:basis" swap scaffold-vocab ; : scaffold-extra ( string -- ) "resource:extra" swap scaffold-vocab ; : scaffold-work ( string -- ) "resource:work" swap scaffold-vocab ; : scaffold-tests ( vocab -- ) ensure-vocab-exists dup "-tests.factor" vocab/suffix>path scaffolding? [ set-scaffold-tests-file ] [ 2drop ] if ; SYMBOL: examples-flag : example ( -- ) { "{ $example \"\" \"USING: prettyprint ;\"" " \"\"" " \"\"" "}" } [ examples-flag get [ 4bl ] when print ] each ; : examples ( n -- ) t \ examples-flag [ "{ $examples " print [ example ] times "}" print ] with-variable ; : touch. ( path -- ) [ touch-file ] [ "Click to edit: " write . ] bi ; : scaffold-rc ( path -- ) [ home ] dip append-path touch. ; : scaffold-factor-boot-rc ( -- ) os windows? "factor-boot-rc" ".factor-boot-rc" ? scaffold-rc ; : scaffold-factor-rc ( -- ) os windows? "factor-rc" ".factor-rc" ? scaffold-rc ; HOOK: scaffold-emacs os ( -- ) M: unix scaffold-emacs ( -- ) ".emacs" scaffold-rc ;