nendo 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/nendo +37 -2
- data/example/cgi/dekamoji.cgi +100 -0
- data/example/cgi/sample.cgi +32 -0
- data/{sample → example}/exit.nnd +0 -0
- data/{sample → example}/fact.nnd +2 -2
- data/{sample → example}/fizzbuzz1.nnd +2 -2
- data/example/html-lite-sample.nnd +51 -0
- data/{sample → example}/scratch.nnd +1 -5
- data/{sample → example}/tak.nnd +0 -0
- data/lib/init.nnd +171 -30
- data/lib/init.nndc +3736 -2009
- data/lib/nendo.rb +322 -127
- data/lib/text/html-lite.nnd +231 -0
- data/lib/text/html-lite.nndc +2652 -0
- data/lib/text/tree.nnd +23 -0
- data/lib/text/tree.nndc +215 -0
- metadata +14 -7
data/bin/nendo
CHANGED
@@ -1,12 +1,47 @@
|
|
1
1
|
#!/usr/local/bin/ruby -W0
|
2
|
+
# -*- encoding: utf-8 -*-
|
2
3
|
#
|
3
|
-
# Nendo: "
|
4
|
+
# Nendo: "Nendo is a diarect of Lisp."
|
4
5
|
#
|
5
6
|
require 'nendo'
|
7
|
+
require 'getoptlong'
|
6
8
|
|
7
9
|
def main
|
10
|
+
loadInit = true
|
8
11
|
core = Nendo.new()
|
9
|
-
|
12
|
+
|
13
|
+
opts = GetoptLong.new(
|
14
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
15
|
+
[ '--no-init-file', '-q', GetoptLong::NO_ARGUMENT ],
|
16
|
+
[ '--load', '-l', GetoptLong::REQUIRED_ARGUMENT ]
|
17
|
+
).each { |opt, arg|
|
18
|
+
case opt
|
19
|
+
when '--help'
|
20
|
+
puts <<-EOF
|
21
|
+
|
22
|
+
nendo [OPTION] [script-file]
|
23
|
+
|
24
|
+
-h, --help:
|
25
|
+
show help
|
26
|
+
|
27
|
+
-q, --no-init-file:
|
28
|
+
Does not read the default initialization file.
|
29
|
+
|
30
|
+
-l, --load:
|
31
|
+
Does not read the default initialization file.
|
32
|
+
|
33
|
+
EOF
|
34
|
+
when '--no-init-file'
|
35
|
+
loadInit = false
|
36
|
+
when '--load'
|
37
|
+
core.load( arg )
|
38
|
+
STDERR.printf( "loaded file [%s]\n", arg )
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
if loadInit
|
43
|
+
core.loadInitFile
|
44
|
+
end
|
10
45
|
if 0 < ARGV.length
|
11
46
|
core.load( ARGV[0] )
|
12
47
|
else
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
:; #-*- mode: nendo; syntax: scheme -*-;;
|
3
|
+
:; exec /usr/local/bin/nendo $0 $*
|
4
|
+
|
5
|
+
(load-library "text/html-lite")
|
6
|
+
(load-library "text/tree")
|
7
|
+
(require "cgi")
|
8
|
+
(require "RMagick")
|
9
|
+
|
10
|
+
(define (response-dekamoji str pointsize)
|
11
|
+
(let* ((font-dots pointsize)
|
12
|
+
(margin (* pointsize 0.3))
|
13
|
+
(image (Magick::Image.new (+ (* str.size font-dots) margin) (+ font-dots margin)))
|
14
|
+
(imlist (Magick::ImageList.new))
|
15
|
+
(dr (Magick::Draw.new)))
|
16
|
+
(set! image.background_color "none")
|
17
|
+
(set! image.format "PNG")
|
18
|
+
(imlist.push image)
|
19
|
+
;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ホリデイMDJP03")
|
20
|
+
;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/みかちゃん")
|
21
|
+
;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ丸ゴ ProN W4.otf")
|
22
|
+
;;(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ明朝 Pro W6.otf")
|
23
|
+
(set! dr.font "/Volumes/Macintosh HD/Library/Fonts/ヒラギノ明朝 Pro W3.otf")
|
24
|
+
(set! dr.pointsize pointsize)
|
25
|
+
(set! dr.fill "#404040")
|
26
|
+
(set! dr.stroke "#080808")
|
27
|
+
(set! dr.font_weight Magick::BoldWeight)
|
28
|
+
(set! dr.gravity Magick::CenterGravity)
|
29
|
+
(dr.annotate imlist 0 0 0 0 str)
|
30
|
+
(let1 blur (imlist.blur_image 1.0 1.0)
|
31
|
+
(blur.to_blob))))
|
32
|
+
|
33
|
+
|
34
|
+
(define default-wording "デカ文字")
|
35
|
+
(define default-size 2)
|
36
|
+
(define size-list '(
|
37
|
+
(1 . "サイズ小")
|
38
|
+
(2 . "サイズ中")
|
39
|
+
(3 . "サイズ大")
|
40
|
+
(4 . "サイズ特大")
|
41
|
+
))
|
42
|
+
|
43
|
+
|
44
|
+
(define (top-page params)
|
45
|
+
(let* ((size (if (hash-table-exist? params "size")
|
46
|
+
(to-i (car (to-list (hash-table-get params "size"))))
|
47
|
+
default-size))
|
48
|
+
(wording (if (hash-table-exist? params "w")
|
49
|
+
(car (to-list (hash-table-get params "w")))
|
50
|
+
default-wording)))
|
51
|
+
(let* ((size (if (> 1 size) 1 size))
|
52
|
+
(size (if (< (length size-list) size) (length size-list) size)))
|
53
|
+
`(
|
54
|
+
,(html-doctype)
|
55
|
+
,(html:head
|
56
|
+
(html:title "デカ文字作成"))
|
57
|
+
,(html:body
|
58
|
+
(html:div :style "text-align: center; "
|
59
|
+
(html:h1 "デカ文字作成")
|
60
|
+
(html:p
|
61
|
+
"下記に文章を入れて『画像化』ボタンを押して下さい")
|
62
|
+
(html:form
|
63
|
+
:method "GET"
|
64
|
+
:action "./dekamoji.cgi"
|
65
|
+
(html:input :name "w" :type "text" :cols 140 :value wording)
|
66
|
+
(map
|
67
|
+
(lambda (x)
|
68
|
+
(list
|
69
|
+
(html:input :name "size" :type "radio"
|
70
|
+
:value (car x)
|
71
|
+
:CHECKED (eq? (car x) size))
|
72
|
+
(cdr x)))
|
73
|
+
size-list)
|
74
|
+
(html:br)
|
75
|
+
(html:input :type "submit" :value "画像化"))
|
76
|
+
(html:hr)
|
77
|
+
(html:img :src (sprintf "./dekamoji.cgi?img=1&size=%d&w=%s" size wording))
|
78
|
+
(html:hr)))))))
|
79
|
+
|
80
|
+
(define fontsize-alist '(
|
81
|
+
("1" . 40)
|
82
|
+
("2" . 80)
|
83
|
+
("3" . 160)
|
84
|
+
("4" . 260)
|
85
|
+
))
|
86
|
+
|
87
|
+
(let1 cgi (CGI.new)
|
88
|
+
(cond ((hash-table-exist? cgi.params "img")
|
89
|
+
(cgi.print
|
90
|
+
(cgi.header "image/png"))
|
91
|
+
(cgi.print
|
92
|
+
(response-dekamoji
|
93
|
+
(car (to-list (hash-table-get cgi.params "w")))
|
94
|
+
(assv-ref (car (to-list (hash-table-get cgi.params "size"))) fontsize-alist))))
|
95
|
+
(else
|
96
|
+
(cgi.print
|
97
|
+
(cgi.header))
|
98
|
+
(cgi.print
|
99
|
+
(tree->string
|
100
|
+
(top-page cgi.params))))))
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
:; #-*- mode: nendo; syntax: scheme -*-;;
|
3
|
+
:; exec /usr/local/bin/nendo $0 $*
|
4
|
+
|
5
|
+
(load-library "text/html-lite")
|
6
|
+
(load-library "text/tree")
|
7
|
+
(require "cgi")
|
8
|
+
|
9
|
+
(define (params-list-page cgi)
|
10
|
+
`(
|
11
|
+
,(html-doctype)
|
12
|
+
,(html:head
|
13
|
+
(html:title "CGI parameter list"))
|
14
|
+
,(html:body
|
15
|
+
(html:h1 "CGI parameter list")
|
16
|
+
(html:table :border 1
|
17
|
+
(html:tr
|
18
|
+
(html:th "key")
|
19
|
+
(html:th "value"))
|
20
|
+
(hash-table-for-each cgi.params
|
21
|
+
(lambda (key value)
|
22
|
+
(html:tr
|
23
|
+
(html:td key)
|
24
|
+
(html:td (string-join value.to_list "/")))))))))
|
25
|
+
|
26
|
+
|
27
|
+
(let1 cgi (CGI.new)
|
28
|
+
(cgi.print
|
29
|
+
(cgi.header))
|
30
|
+
(cgi.print
|
31
|
+
(tree->string
|
32
|
+
(params-list-page cgi))))
|
data/{sample → example}/exit.nnd
RENAMED
File without changes
|
data/{sample → example}/fact.nnd
RENAMED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
:; #-*- mode: nendo; syntax: scheme -*-;;
|
3
|
+
:; exec /usr/local/bin/nendo $0 $*
|
4
|
+
|
5
|
+
(load-library "text/html-lite")
|
6
|
+
(load-library "text/tree")
|
7
|
+
|
8
|
+
(define (page-sample)
|
9
|
+
`(
|
10
|
+
,(html:head
|
11
|
+
(html:title "title of page"))
|
12
|
+
,(html:body
|
13
|
+
(html:p "これはサンプルです")
|
14
|
+
(html:h1 "section 1")
|
15
|
+
(html:h2 "section 1-2")
|
16
|
+
(html:table :border 1
|
17
|
+
(html:tr
|
18
|
+
(html:th "head1")
|
19
|
+
(html:th "head2"))
|
20
|
+
(html:tr
|
21
|
+
(html:td "data1")
|
22
|
+
(html:td "data2"))
|
23
|
+
(html:tr
|
24
|
+
(html:td "data3")
|
25
|
+
(html:td "data4"))
|
26
|
+
(html:hr)))))
|
27
|
+
|
28
|
+
(write-tree
|
29
|
+
(page-sample))
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
data/{sample → example}/tak.nnd
RENAMED
File without changes
|
data/lib/init.nnd
CHANGED
@@ -107,6 +107,8 @@
|
|
107
107
|
(define (ninth lst) (nth 8 lst))
|
108
108
|
(define (tenth lst) (nth 9 lst))
|
109
109
|
|
110
|
+
(define (x->string object) (to-s object))
|
111
|
+
|
110
112
|
;; ----------------------------------------
|
111
113
|
;; basic forms
|
112
114
|
;; ----------------------------------------
|
@@ -126,7 +128,9 @@
|
|
126
128
|
(let ((condition (if (eq? 'else (car elem))
|
127
129
|
true
|
128
130
|
(car elem)))
|
129
|
-
(body (cdr elem))
|
131
|
+
(body (if (null? (cdr elem))
|
132
|
+
'(#t)
|
133
|
+
(cdr elem)))
|
130
134
|
(tmpsym (gensym)))
|
131
135
|
;;(display "CONDITION") (print condition)
|
132
136
|
;;(display "BODY") (print body)
|
@@ -311,6 +315,13 @@
|
|
311
315
|
;; don't touch
|
312
316
|
`(let ,@lst))))
|
313
317
|
|
318
|
+
;; ----------------------------------------
|
319
|
+
;; errorf
|
320
|
+
;; ----------------------------------------
|
321
|
+
(define errorf
|
322
|
+
(macro (format . args)
|
323
|
+
`(error
|
324
|
+
(sprintf ,format ,@args))))
|
314
325
|
|
315
326
|
;; ----------------------------------------
|
316
327
|
;; List utilities imported from TinyScheme
|
@@ -388,6 +399,13 @@
|
|
388
399
|
(filter-map pred (cdr lst))))))
|
389
400
|
|
390
401
|
|
402
|
+
(define (find pred lst)
|
403
|
+
(let1 result (filter pred lst)
|
404
|
+
(if (null? result)
|
405
|
+
#f
|
406
|
+
(car result))))
|
407
|
+
|
408
|
+
|
391
409
|
(define lambda
|
392
410
|
(macro src
|
393
411
|
(if (not (list? (cadr src)))
|
@@ -477,43 +495,80 @@
|
|
477
495
|
(let*-expand exps body))))
|
478
496
|
|
479
497
|
|
498
|
+
;; ----------------------------------------
|
499
|
+
;; values
|
500
|
+
;; ----------------------------------------
|
501
|
+
(define (values . args)
|
502
|
+
(case (length args)
|
503
|
+
((1)
|
504
|
+
(car args))
|
505
|
+
(else
|
506
|
+
(make-values args))))
|
507
|
+
|
508
|
+
|
509
|
+
(define (call-with-values producer consumer)
|
510
|
+
(let ((v (producer)))
|
511
|
+
(if (values? v)
|
512
|
+
(apply consumer (values-values v))
|
513
|
+
(consumer v))))
|
514
|
+
|
515
|
+
;; srfi-8
|
516
|
+
(define receive
|
517
|
+
(macro (vars expr . body)
|
518
|
+
`(call-with-values
|
519
|
+
(lambda () ,expr)
|
520
|
+
(lambda ,vars ,@body))))
|
521
|
+
|
522
|
+
|
523
|
+
;; ----------------------------------------
|
524
|
+
;; keyword
|
525
|
+
;; ----------------------------------------
|
526
|
+
(define (get-keyword key kv-list . fallback)
|
527
|
+
(cond
|
528
|
+
((or (not (list? kv-list)) (>= 2 (length kv-list)))
|
529
|
+
(if (null? fallback)
|
530
|
+
(errorf "Error: imcomplete key list: %s\n" (write-to-string kv-list))
|
531
|
+
(car fallback)))
|
532
|
+
(else
|
533
|
+
(let loop ((k (car kv-list))
|
534
|
+
(v (cadr kv-list))
|
535
|
+
(rest (cddr kv-list)))
|
536
|
+
(if (eq? k key)
|
537
|
+
v
|
538
|
+
(case (length rest)
|
539
|
+
((0)
|
540
|
+
(if (null? fallback)
|
541
|
+
(errorf "Error: value for key %s is not provided : %s\n" (write-to-string key) (write-to-string kv-list))
|
542
|
+
(car fallback)))
|
543
|
+
((1)
|
544
|
+
(errorf "Error: incomplete key list: %s\n" (write-to-string kv-list)))
|
545
|
+
(else
|
546
|
+
(loop (car rest)
|
547
|
+
(cadr rest)
|
548
|
+
(cddr rest)))))))))
|
549
|
+
|
480
550
|
;; ----------------------------------------
|
481
551
|
;; for Ruby interop
|
482
552
|
;; ----------------------------------------
|
483
|
-
;; dot_operator
|
484
553
|
(define dot-operator
|
485
554
|
(macro lst
|
486
|
-
(letrec ((
|
555
|
+
(letrec ((generate-method-call-form
|
487
556
|
(lambda (lst)
|
488
|
-
(
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
(map
|
496
|
-
(lambda (x)
|
497
|
-
(if (pair? x)
|
498
|
-
(to-s (dot-operator-iter x))
|
499
|
-
(if (symbol? x)
|
500
|
-
(to-s x)
|
501
|
-
(error (sprintf "dot-operator requires symbol, but got %s" x)))))
|
502
|
-
(cdr lst))
|
503
|
-
"."))
|
504
|
-
(error "dot-operator requires symbol or (. symbol symbol) form.")))
|
505
|
-
(else
|
506
|
-
lst)))))
|
507
|
-
|
557
|
+
(let1 tmp (gensym)
|
558
|
+
(if (symbol? (first lst))
|
559
|
+
`(,(string->symbol (+ (to-s (first lst)) "." (to-s (second lst))))
|
560
|
+
,@(cddr lst))
|
561
|
+
`(let ((,tmp ,(first lst)))
|
562
|
+
(,(string->symbol (+ (to-s tmp) "." (to-s (second lst))))
|
563
|
+
,@(cddr lst))))))))
|
508
564
|
(cond
|
509
|
-
((
|
510
|
-
(
|
511
|
-
((and (eq? 1 (length lst))
|
512
|
-
(symbol? (car lst)))
|
513
|
-
(intern (+ "." (to-s (car lst)))))
|
565
|
+
((> 2 (length lst))
|
566
|
+
(raise ArgumentError ". dot-operator requires 2+ arguments."))
|
514
567
|
(else
|
515
|
-
((
|
516
|
-
|
568
|
+
(if (symbol? (second lst))
|
569
|
+
(generate-method-call-form lst)
|
570
|
+
(raise TypeError ". dot-operator requires method name as symbol.")))))))
|
571
|
+
|
517
572
|
|
518
573
|
(define (with-open filename pred . lst)
|
519
574
|
(let1 len (length lst)
|
@@ -538,6 +593,92 @@
|
|
538
593
|
x))
|
539
594
|
|
540
595
|
|
596
|
+
(define (cons* arg . args)
|
597
|
+
(if (null? args)
|
598
|
+
arg
|
599
|
+
(cons arg (apply list* args))))
|
600
|
+
(define list* cons*)
|
601
|
+
|
602
|
+
|
603
|
+
;; ----------------------------------------
|
604
|
+
;; hash-table library functions
|
605
|
+
;; ----------------------------------------
|
606
|
+
(define (make-hash-table)
|
607
|
+
(Hash.new))
|
608
|
+
|
609
|
+
(define (hash-table? h)
|
610
|
+
(h.is_a? Hash))
|
611
|
+
|
612
|
+
(define (hash-table-num-entries h)
|
613
|
+
(h.length))
|
614
|
+
|
615
|
+
(define (hash-table . kv-list)
|
616
|
+
(let1 h (make-hash-table)
|
617
|
+
(for-each
|
618
|
+
(lambda (entry)
|
619
|
+
(if (pair? (cdr entry))
|
620
|
+
(hash-table-put! h (car entry) (cadr entry))
|
621
|
+
(hash-table-put! h (car entry) (cdr entry))))
|
622
|
+
kv-list)
|
623
|
+
h))
|
624
|
+
|
625
|
+
(define (hash-table-exist? h key)
|
626
|
+
(h.has_key? key))
|
627
|
+
|
628
|
+
(define (hash-table-clear! h)
|
629
|
+
(h.clear))
|
630
|
+
|
631
|
+
(define (hash-table-delete! h key)
|
632
|
+
(h.delete key))
|
633
|
+
|
634
|
+
(define (hash-table-keys h)
|
635
|
+
(to-list (h.keys)))
|
636
|
+
|
637
|
+
(define (hash-table-values h)
|
638
|
+
(to-list (h.values)))
|
639
|
+
|
640
|
+
(define (hash-table-map h pred)
|
641
|
+
(let1 keys (hash-table-keys h)
|
642
|
+
(map
|
643
|
+
(lambda (key)
|
644
|
+
(pred key (hash-table-get h key)))
|
645
|
+
keys)))
|
646
|
+
(define hash-table-for-each hash-table-map)
|
647
|
+
|
648
|
+
(define (hash-table->alist h)
|
649
|
+
(if (not (h.is_a? Hash))
|
650
|
+
(raise TypeError "Error: hash-table->alist expects Hash instance.")
|
651
|
+
(let1 keys (hash-table-keys h)
|
652
|
+
(map
|
653
|
+
(lambda (key)
|
654
|
+
(cons key (hash-table-get h key)))
|
655
|
+
keys))))
|
656
|
+
|
657
|
+
(define (alist->hash-table alist)
|
658
|
+
(if (not (list? alist))
|
659
|
+
(raise TypeError "Error: alist->hash-table expects alist.")
|
660
|
+
(apply hash-table alist)))
|
661
|
+
|
662
|
+
;; ----------------------------------------
|
663
|
+
;; Ruby interop librarys
|
664
|
+
;; ----------------------------------------
|
665
|
+
;; I will implement in the future...
|
666
|
+
(define export
|
667
|
+
(macro (name)
|
668
|
+
`(define ,name nil)))
|
669
|
+
|
670
|
+
(define (load-library name)
|
671
|
+
(let* ((home (get-nendo-home))
|
672
|
+
(path (+ home "/" name)))
|
673
|
+
(cond
|
674
|
+
((File.exist? (+ path ".nndc"))
|
675
|
+
(load-compiled-code (+ path ".nndc")))
|
676
|
+
((File.exist? (+ path ".nnd"))
|
677
|
+
(load (+ path ".nnd")))
|
678
|
+
(else
|
679
|
+
(errorf "Error: can't load library file [%s]\n" path )))))
|
680
|
+
|
681
|
+
|
541
682
|
;; ----------------------------------------
|
542
683
|
;; Utility function for testing and debugging
|
543
684
|
;; ----------------------------------------
|