commit
523ca2033b
|
@ -0,0 +1,2 @@
|
|||
Slava Pestov
|
||||
Doug Coleman
|
|
@ -28,7 +28,7 @@ TUPLE: test-tuple m n ;
|
|||
[
|
||||
H{
|
||||
{ "bar" "hello" }
|
||||
} \ foo query>quot
|
||||
} \ foo query>seq
|
||||
] with-scope
|
||||
] unit-test
|
||||
|
||||
|
|
|
@ -1,55 +1,39 @@
|
|||
! Copyright (C) 2006 Slava Pestov
|
||||
! Copyright (C) 2006 Slava Pestov, Doug Coleman
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: kernel vectors io assocs quotations splitting strings
|
||||
words sequences namespaces arrays hashtables debugger
|
||||
continuations tuples classes io.files
|
||||
http http.server.templating http.basic-authentication
|
||||
webapps.callback html html.elements
|
||||
http.server.responders furnace.validator vocabs ;
|
||||
USING: arrays assocs debugger furnace.sessions furnace.validator
|
||||
hashtables html.elements http http.server.responders
|
||||
http.server.templating
|
||||
io.files kernel namespaces quotations sequences splitting words
|
||||
strings vectors webapps.callback ;
|
||||
USING: continuations io prettyprint ;
|
||||
IN: furnace
|
||||
|
||||
SYMBOL: default-action
|
||||
|
||||
SYMBOL: template-path
|
||||
|
||||
: define-authenticated-action ( word params realm -- )
|
||||
pick swap "action-realm" set-word-prop
|
||||
over t "action" set-word-prop
|
||||
"action-params" set-word-prop ;
|
||||
|
||||
: define-action ( word params -- )
|
||||
f define-authenticated-action ;
|
||||
|
||||
: code>quotation ( word/quot -- quot )
|
||||
dup word? [ 1quotation ] when ;
|
||||
|
||||
: define-form ( formword actionword params -- )
|
||||
SYMBOL: default-action
|
||||
SYMBOL: template-path
|
||||
|
||||
: render-template ( template -- )
|
||||
template-path get swap path+
|
||||
".furnace" append resource-path
|
||||
run-template-file ;
|
||||
|
||||
: define-action ( word hash -- )
|
||||
over t "action" set-word-prop
|
||||
"action-params" set-word-prop ;
|
||||
|
||||
: define-form ( word1 word2 hash -- )
|
||||
dupd define-action
|
||||
swap code>quotation "form-quotation" set-word-prop ;
|
||||
swap code>quotation "form-failed" set-word-prop ;
|
||||
|
||||
: define-redirect ( word quot -- )
|
||||
"action-redirect" set-word-prop ;
|
||||
: default-values ( word hash -- )
|
||||
"default-values" set-word-prop ;
|
||||
|
||||
: responder-vocab ( name -- vocab )
|
||||
"webapps." swap append ;
|
||||
|
||||
: lookup-action ( name webapp -- word )
|
||||
responder-vocab lookup dup [
|
||||
dup "action" word-prop [ drop f ] unless
|
||||
] when ;
|
||||
|
||||
: truncate-url ( url -- action-name )
|
||||
CHAR: / over index [ head ] when* ;
|
||||
|
||||
: current-action ( url -- word/f )
|
||||
dup empty? [ drop default-action get ] when
|
||||
truncate-url "responder" get lookup-action ;
|
||||
|
||||
PREDICATE: word action "action" word-prop ;
|
||||
|
||||
: quot>query ( seq action -- hash )
|
||||
>r >array r> "action-params" word-prop
|
||||
[ first swap 2array ] 2map >hashtable ;
|
||||
SYMBOL: request-params
|
||||
SYMBOL: current-action
|
||||
SYMBOL: validators-errored
|
||||
SYMBOL: validation-errors
|
||||
|
||||
: action-link ( query action -- url )
|
||||
[
|
||||
|
@ -59,6 +43,34 @@ PREDICATE: word action "action" word-prop ;
|
|||
word-name %
|
||||
] "" make swap build-url ;
|
||||
|
||||
: action-param ( hash paramsepc -- obj error/f )
|
||||
unclip rot at swap >quotation apply-validators ;
|
||||
|
||||
: query>seq ( hash word -- seq )
|
||||
"action-params" word-prop [
|
||||
dup first -rot
|
||||
action-param [
|
||||
t validators-errored >session
|
||||
rot validation-errors session> set-at
|
||||
] [
|
||||
nip
|
||||
] if*
|
||||
] curry* map ;
|
||||
|
||||
: lookup-session ( hash -- session )
|
||||
"furnace-session-id" over at* [
|
||||
sessions get-global at
|
||||
[ nip ] [ "furnace-session-id" over delete-at lookup-session ] if*
|
||||
] [
|
||||
drop new-session rot "furnace-session-id" swap set-at
|
||||
] if ;
|
||||
|
||||
: quot>query ( seq action -- hash )
|
||||
>r >array r> "action-params" word-prop
|
||||
[ first swap 2array ] 2map >hashtable ;
|
||||
|
||||
PREDICATE: word action "action" word-prop ;
|
||||
|
||||
: action-call? ( quot -- ? )
|
||||
>vector dup pop action? >r [ word? not ] all? r> and ;
|
||||
|
||||
|
@ -71,62 +83,94 @@ PREDICATE: word action "action" word-prop ;
|
|||
t register-html-callback
|
||||
] if ;
|
||||
|
||||
: render-link ( quot name -- )
|
||||
<a swap quot-link =href a> write </a> ;
|
||||
: replace-variables ( quot -- quot )
|
||||
[ dup string? [ request-params session> at ] when ] map ;
|
||||
|
||||
: action-param ( params paramspec -- obj error/f )
|
||||
unclip rot at swap >quotation apply-validators ;
|
||||
: furnace-session-id ( -- hash )
|
||||
"furnace-session-id" request-params session> at
|
||||
"furnace-session-id" associate ;
|
||||
|
||||
: query>quot ( params action -- seq )
|
||||
"action-params" word-prop [ action-param drop ] curry* map ;
|
||||
: redirect-to-action ( -- )
|
||||
current-action session>
|
||||
"form-failed" word-prop replace-variables
|
||||
quot-link furnace-session-id build-url permanent-redirect ;
|
||||
|
||||
SYMBOL: request-params
|
||||
: if-form-page ( if then -- )
|
||||
current-action session> "form-failed" word-prop -rot if ;
|
||||
|
||||
: perform-redirect ( action -- )
|
||||
"action-redirect" word-prop
|
||||
[ dup string? [ request-params get at ] when ] map
|
||||
[ quot-link permanent-redirect ] when* ;
|
||||
: do-action
|
||||
current-action session> [ query>seq ] keep add >quotation call ;
|
||||
|
||||
: (call-action) ( params action -- )
|
||||
over request-params set
|
||||
[ query>quot ] keep [ add >quotation call ] keep
|
||||
perform-redirect ;
|
||||
: process-form ( -- )
|
||||
H{ } clone validation-errors >session
|
||||
request-params session> current-action session> query>seq
|
||||
validators-errored session> [
|
||||
drop redirect-to-action
|
||||
] [
|
||||
current-action session> add >quotation call
|
||||
] if ;
|
||||
|
||||
: call-action ( params action -- )
|
||||
dup "action-realm" word-prop [
|
||||
[ (call-action) ] with-basic-authentication
|
||||
] [ (call-action) ] if* ;
|
||||
: page-submitted ( -- )
|
||||
[ process-form ] [ request-params session> do-action ] if-form-page ;
|
||||
|
||||
: service-request ( params url -- )
|
||||
current-action [
|
||||
: action-first-time ( -- )
|
||||
request-params session> current-action session>
|
||||
[ "default-values" word-prop swap union request-params >session ] keep
|
||||
request-params session> do-action ;
|
||||
|
||||
: page-not-submitted ( -- )
|
||||
[ redirect-to-action ] [ action-first-time ] if-form-page ;
|
||||
|
||||
: setup-call-action ( hash word -- )
|
||||
over lookup-session session set
|
||||
current-action >session
|
||||
request-params session> swap union
|
||||
request-params >session
|
||||
f validators-errored >session ;
|
||||
|
||||
: call-action ( hash word -- )
|
||||
setup-call-action
|
||||
"furnace-form-submitted" request-params session> at
|
||||
[ page-submitted ] [ page-not-submitted ] if ;
|
||||
|
||||
: responder-vocab ( str -- newstr )
|
||||
"webapps." swap append ;
|
||||
|
||||
: lookup-action ( str webapp -- word )
|
||||
responder-vocab lookup dup [
|
||||
dup "action" word-prop [ drop f ] unless
|
||||
] when ;
|
||||
|
||||
: truncate-url ( str -- newstr )
|
||||
CHAR: / over index [ head ] when* ;
|
||||
|
||||
: parse-action ( str -- word/f )
|
||||
dup empty? [ drop default-action get ] when
|
||||
truncate-url "responder" get lookup-action ;
|
||||
|
||||
: service-request ( hash str -- )
|
||||
parse-action [
|
||||
[ call-action ] [ <pre> print-error </pre> ] recover
|
||||
] [
|
||||
"404 no such action: " "argument" get append httpd-error
|
||||
] if* ;
|
||||
|
||||
: service-get ( url -- ) "query" get swap service-request ;
|
||||
: service-get
|
||||
"query" get swap service-request ;
|
||||
|
||||
: service-post ( url -- ) "response" get swap service-request ;
|
||||
: service-post
|
||||
"response" get swap service-request ;
|
||||
|
||||
: send-resource ( name -- )
|
||||
template-path get swap path+ resource-path <file-reader>
|
||||
stdio get stream-copy ;
|
||||
|
||||
: render-template ( template -- )
|
||||
template-path get swap path+
|
||||
".furnace" append resource-path
|
||||
run-template-file ;
|
||||
|
||||
: web-app ( name default path -- )
|
||||
: web-app ( name defaul path -- )
|
||||
[
|
||||
template-path set
|
||||
default-action set
|
||||
"responder" set
|
||||
[ service-get ] "get" set
|
||||
[ service-post ] "post" set
|
||||
! [ service-head ] "head" set
|
||||
] make-responder ;
|
||||
|
||||
USING: classes html tuples vocabs ;
|
||||
: explode-tuple ( tuple -- )
|
||||
dup tuple-slots swap class "slot-names" word-prop
|
||||
[ set ] 2each ;
|
||||
|
@ -145,3 +189,24 @@ SYMBOL: model
|
|||
<a f >vocab-link browser-link-href =href a>
|
||||
"Browse source" write
|
||||
</a> ;
|
||||
|
||||
: send-resource ( name -- )
|
||||
template-path get swap path+ resource-path <file-reader>
|
||||
stdio get stream-copy ;
|
||||
|
||||
: render-link ( quot name -- )
|
||||
<a swap quot-link =href a> write </a> ;
|
||||
|
||||
: session-var ( str -- newstr )
|
||||
request-params session> at ;
|
||||
|
||||
: render ( str -- )
|
||||
request-params session> at [ write ] when* ;
|
||||
|
||||
: render-error ( str error-str -- )
|
||||
swap validation-errors session> at validation-error? [
|
||||
write
|
||||
] [
|
||||
drop
|
||||
] if ;
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
USING: assocs calendar init kernel math.parser namespaces random ;
|
||||
IN: furnace.sessions
|
||||
|
||||
SYMBOL: sessions
|
||||
|
||||
[ H{ } clone sessions set-global ] "furnace.sessions" add-init-hook
|
||||
|
||||
: new-session-id ( -- str )
|
||||
1 big-random number>string ;
|
||||
|
||||
TUPLE: session created last-seen user-agent namespace ;
|
||||
|
||||
: <session> ( -- obj )
|
||||
now dup H{ } clone
|
||||
[ set-session-created set-session-last-seen set-session-namespace ]
|
||||
\ session construct ;
|
||||
|
||||
: new-session ( -- obj id )
|
||||
<session> new-session-id [ sessions get-global set-at ] 2keep ;
|
||||
|
||||
: get-session ( id -- obj/f )
|
||||
sessions get-global at* [ "no session found 1" throw ] unless ;
|
||||
|
||||
: destroy-session ( id -- )
|
||||
sessions get-global delete-at ;
|
||||
|
||||
: session> ( str -- obj )
|
||||
session get session-namespace at ;
|
||||
|
||||
: >session ( value key -- )
|
||||
session get session-namespace set-at ;
|
|
@ -60,11 +60,18 @@ IN: http
|
|||
: url-decode ( str -- str )
|
||||
[ 0 swap url-decode-iter ] "" make ;
|
||||
|
||||
: build-url ( path query-params -- str )
|
||||
: hash>query ( hash -- str )
|
||||
[ [ url-encode ] 2apply "=" swap 3append ] { } assoc>map
|
||||
"&" join ;
|
||||
|
||||
: build-url ( str query-params -- newstr )
|
||||
[
|
||||
swap % dup assoc-empty? [
|
||||
"?" % dup
|
||||
[ [ url-encode ] 2apply "=" swap 3append ] { } assoc>map
|
||||
"&" join %
|
||||
] unless drop
|
||||
over %
|
||||
dup assoc-empty? [
|
||||
2drop
|
||||
] [
|
||||
CHAR: ? rot member? "&" "?" ? %
|
||||
hash>query %
|
||||
] if
|
||||
] "" make ;
|
||||
|
||||
|
|
|
@ -34,14 +34,10 @@ focused? ;
|
|||
: field-theme ( gadget -- )
|
||||
gray <solid> swap set-gadget-boundary ;
|
||||
|
||||
: construct-editor ( class -- tuple )
|
||||
>r <editor> { set-gadget-delegate } r> construct
|
||||
: construct-editor ( object class -- tuple )
|
||||
>r { set-gadget-delegate } r> construct
|
||||
dup dup set-editor-self ; inline
|
||||
|
||||
TUPLE: source-editor ;
|
||||
|
||||
: <source-editor> source-editor construct-editor ;
|
||||
|
||||
: activate-editor-model ( editor model -- )
|
||||
2dup add-connection
|
||||
dup activate-model
|
||||
|
@ -340,9 +336,6 @@ M: editor gadget-text* editor-string % ;
|
|||
: delete-to-end-of-line T{ one-line-elt } editor-backspace ;
|
||||
|
||||
editor "general" f {
|
||||
{ T{ key-down f f "RET" } insert-newline }
|
||||
{ T{ key-down f { S+ } "RET" } insert-newline }
|
||||
{ T{ key-down f f "ENTER" } insert-newline }
|
||||
{ T{ key-down f f "DELETE" } delete-next-character }
|
||||
{ T{ key-down f { S+ } "DELETE" } delete-next-character }
|
||||
{ T{ key-down f f "BACKSPACE" } delete-previous-character }
|
||||
|
@ -448,6 +441,23 @@ editor "selection" f {
|
|||
{ T{ key-down f { S+ C+ } "END" } select-end-of-document }
|
||||
} define-command-map
|
||||
|
||||
! Multi-line editors
|
||||
TUPLE: multiline-editor ;
|
||||
|
||||
: <multiline-editor> ( -- editor )
|
||||
<editor> multiline-editor construct-editor ;
|
||||
|
||||
multiline-editor "general" f {
|
||||
{ T{ key-down f f "RET" } insert-newline }
|
||||
{ T{ key-down f { S+ } "RET" } insert-newline }
|
||||
{ T{ key-down f f "ENTER" } insert-newline }
|
||||
} define-command-map
|
||||
|
||||
TUPLE: source-editor ;
|
||||
|
||||
: <source-editor> ( -- editor )
|
||||
<multiline-editor> source-editor construct-editor ;
|
||||
|
||||
! Fields are like editors except they edit an external model
|
||||
TUPLE: field model editor ;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ deploy-gadget "toolbar" f {
|
|||
{ f com-help }
|
||||
{ f com-revert }
|
||||
{ f com-save }
|
||||
{ T{ key-down f f "RETURN" } com-deploy }
|
||||
{ T{ key-down f f "RET" } com-deploy }
|
||||
} define-command-map
|
||||
|
||||
: buttons,
|
||||
|
|
|
@ -33,9 +33,8 @@ help ;
|
|||
|
||||
: <interactor> ( output -- gadget )
|
||||
<source-editor>
|
||||
{ set-interactor-output set-gadget-delegate }
|
||||
interactor construct
|
||||
dup dup set-editor-self
|
||||
interactor construct-editor
|
||||
tuck set-interactor-output
|
||||
dup init-interactor-history
|
||||
dup init-caret-help ;
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ M: live-search handle-gesture* ( gadget gesture delegate -- ? )
|
|||
|
||||
TUPLE: search-field ;
|
||||
|
||||
: <search-field> ( -- gadget ) search-field construct-editor ;
|
||||
: <search-field> ( -- gadget )
|
||||
<editor> search-field construct-editor ;
|
||||
|
||||
search-field H{
|
||||
{ T{ key-down f f "UP" } [ find-search-list select-previous ] }
|
||||
|
|
|
@ -6,18 +6,19 @@ USING: kernel furnace furnace.validator http.server.responders
|
|||
arrays io.files ;
|
||||
IN: webapps.help
|
||||
|
||||
! : string>topic ( string -- topic )
|
||||
! " " split dup length 1 = [ first ] when ;
|
||||
|
||||
: show-help ( topic -- )
|
||||
serving-html
|
||||
dup article-title [
|
||||
[ help ] with-html-stream
|
||||
] simple-html-document ;
|
||||
|
||||
: string>topic ( string -- topic )
|
||||
" " split dup length 1 = [ first ] when ;
|
||||
|
||||
\ show-help {
|
||||
{ "topic" "handbook" v-default string>topic }
|
||||
{ "topic" }
|
||||
} define-action
|
||||
\ show-help { { "topic" "handbook" } } default-values
|
||||
|
||||
M: link browser-link-href
|
||||
link-name
|
||||
|
@ -32,9 +33,10 @@ M: link browser-link-href
|
|||
lookup show-help ;
|
||||
|
||||
\ show-word {
|
||||
{ "word" "call" v-default }
|
||||
{ "vocab" "kernel" v-default }
|
||||
{ "word" }
|
||||
{ "vocab" }
|
||||
} define-action
|
||||
\ show-word { { "word" "call" } { "vocab" "kernel" } } default-values
|
||||
|
||||
M: f browser-link-href
|
||||
drop \ f browser-link-href ;
|
||||
|
@ -47,9 +49,11 @@ M: word browser-link-href
|
|||
f >vocab-link show-help ;
|
||||
|
||||
\ show-vocab {
|
||||
{ "vocab" "kernel" v-default }
|
||||
{ "vocab" }
|
||||
} define-action
|
||||
|
||||
\ show-vocab { { "vocab" "kernel" } } default-values
|
||||
|
||||
M: vocab-spec browser-link-href
|
||||
vocab-name [ show-vocab ] curry quot-link ;
|
||||
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
|
||||
<table>
|
||||
|
||||
<input type="hidden" name="n" value="<% "n" get number>string write %>" />
|
||||
|
||||
<tr>
|
||||
<th align="right">Summary:</th>
|
||||
<td><input type="TEXT" name="summary" value="" /></td>
|
||||
<td><input type="TEXT" name="summary" value="<% "summary" render %>" /></td>
|
||||
<td align="left" class="error"><% "summary" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="right">Your name:</th>
|
||||
<td><input type="TEXT" name="author" value="" /></td>
|
||||
<td><input type="TEXT" name="author" value="<% "author" render %>" /></td>
|
||||
<td class="error"><% "author" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -23,11 +23,25 @@
|
|||
<td><% "modes" render-template %></td>
|
||||
</tr>
|
||||
|
||||
<!--
|
||||
<tr>
|
||||
<th align="right">Channel:</th>
|
||||
<td><input type="TEXT" name="channel" value="#concatenative" /></td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td colspan="2" class="error" align="left"><% "contents" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="right" valign="top">Content:</th>
|
||||
<td><textarea rows="24" cols="60" name="contents"></textarea></td>
|
||||
<td colspan="2"><textarea rows="24" cols="60" name="contents"><% "contents" render %></textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="hidden" name="n" value="<% "n" get number>string write %>" />
|
||||
<input type="hidden" name="furnace-form-submitted" value="annotate-paste"/>
|
||||
<input type="SUBMIT" value="Annotate" />
|
||||
</form>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<% USING: xmode.catalog sequences kernel html.elements assocs io sorting ; %>
|
||||
<% USING: furnace xmode.catalog sequences kernel html.elements assocs io sorting continuations ; %>
|
||||
|
||||
<select name="mode">
|
||||
<% modes keys natural-sort [
|
||||
<option dup "factor" = [ "true" =selected ] when option> write </option>
|
||||
<option dup "mode" session-var = [ "true" =selected ] when option> write </option>
|
||||
] each %>
|
||||
</select>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<% USING: furnace namespaces ; %>
|
||||
<% USING: continuations furnace namespaces ; %>
|
||||
|
||||
<%
|
||||
"New paste" "title" set
|
||||
|
@ -11,12 +11,14 @@
|
|||
|
||||
<tr>
|
||||
<th align="right">Summary:</th>
|
||||
<td><input type="TEXT" name="summary" value="" /></td>
|
||||
<td><input type="TEXT" name="summary" value="<% "summary" render %>" /></td>
|
||||
<td align="left" class="error"><% "summary" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="right">Your name:</th>
|
||||
<td><input type="TEXT" name="author" value="" /></td>
|
||||
<td><input type="TEXT" name="author" value="<% "author" render %>" /></td>
|
||||
<td class="error"><% "author" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -31,12 +33,18 @@
|
|||
</tr>
|
||||
-->
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td colspan="2" class="error" align="left"><% "contents" "*Required" render-error %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="right" valign="top">Content:</th>
|
||||
<td><textarea rows="24" cols="60" name="contents"></textarea></td>
|
||||
<td colspan="2"><textarea rows="24" cols="60" name="contents"><% "contents" render %></textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="hidden" name="furnace-form-submitted" value="new-paste"/>
|
||||
<input type="SUBMIT" value="Submit paste" />
|
||||
</form>
|
||||
|
||||
|
|
|
@ -84,28 +84,37 @@ C: <annotation> annotation
|
|||
store save-store
|
||||
] keep paste-link permanent-redirect ;
|
||||
|
||||
\ new-paste
|
||||
\ submit-paste {
|
||||
{ "summary" "- no summary -" v-default }
|
||||
{ "author" "- no author -" v-default }
|
||||
{ "channel" "#concatenative" v-default }
|
||||
{ "mode" "factor" v-default }
|
||||
{ "summary" v-required }
|
||||
{ "author" v-required }
|
||||
{ "channel" }
|
||||
{ "mode" v-required }
|
||||
{ "contents" v-required }
|
||||
} define-action
|
||||
} define-form
|
||||
|
||||
\ new-paste {
|
||||
{ "channel" "#concatenative" }
|
||||
{ "mode" "factor" }
|
||||
} default-values
|
||||
|
||||
: annotate-paste ( n summary author mode contents -- )
|
||||
<annotation> swap get-paste
|
||||
paste-annotations push
|
||||
store save-store ;
|
||||
[ paste-annotations push store save-store ] keep
|
||||
paste-link permanent-redirect ;
|
||||
|
||||
[ "n" show-paste ]
|
||||
\ annotate-paste {
|
||||
{ "n" v-required v-number }
|
||||
{ "summary" "- no summary -" v-default }
|
||||
{ "author" "- no author -" v-default }
|
||||
{ "mode" "factor" v-default }
|
||||
{ "summary" v-required }
|
||||
{ "author" v-required }
|
||||
{ "mode" v-required }
|
||||
{ "contents" v-required }
|
||||
} define-action
|
||||
} define-form
|
||||
|
||||
\ annotate-paste [ "n" show-paste ] define-redirect
|
||||
\ show-paste {
|
||||
{ "mode" "factor" }
|
||||
} default-values
|
||||
|
||||
: style.css ( -- )
|
||||
"text/css" serving-content
|
||||
|
|
|
@ -35,3 +35,7 @@ pre.code {
|
|||
border: 1px solid #C1DAD7;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ refresh_image() {
|
|||
}
|
||||
|
||||
install_libraries() {
|
||||
sudo apt-get install libc6-dev libfreetype6-dev wget git-core git-doc libx11-dev glutg3-dev rlwrap
|
||||
sudo apt-get install libc6-dev libfreetype6-dev libx11-dev xorg-dev glutg3-dev wget git-core git-doc rlwrap
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
|
Loading…
Reference in New Issue