TaoLib

Check-in [db5edcaf33]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added an annotation capacity to practcl, which allows the doctools generator to read and document class variables, options, and delegates. Added missing documentation to httpd. New version of clay which adds a new "branch" method to oo::class/oo::object's clay ensemble. The branch method tells the system to mark the designated address as a branch, even it empty. Fixed a bug in clay where a Dict or Array keyword with no values would fail to actually register in the clay system
Timelines: family | ancestors | descendants | both | clay
Files: files | file ages | folders
SHA1:db5edcaf33488a308041caaa7dee97dd56a05ae7
User & Date: hypnotoad 2018-10-16 15:28:34
Context
2018-10-24
00:13
Replaced sak with Practcl installation manager check-in: 7c1b4765ca user: hypnotoad tags: clay
2018-10-16
15:28
Added an annotation capacity to practcl, which allows the doctools generator to read and document class variables, options, and delegates. Added missing documentation to httpd. New version of clay which adds a new "branch" method to oo::class/oo::object's clay ensemble. The branch method tells the system to mark the designated address as a branch, even it empty. Fixed a bug in clay where a Dict or Array keyword with no values would fail to actually register in the clay system check-in: db5edcaf33 user: hypnotoad tags: clay
2018-10-11
06:26
Updates to clay and clay-stage from the clay project check-in: 6375364306 user: hypnotoad tags: clay
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to modules/clay-db/build/connection.tcl.

79
80
81
82
83
84
85

86
87
88
89
90
91
92
...
234
235
236
237
238
239
240



241
242
243
244
245
246
247
248
249
250
251
252
253
#    and several subject objects to manage the individual tables
#    accessed by this application.
###
::clay::define ::clay-db::connection {
  superclass ::clay-db::schema
  clay docentry {}
  Variable schema_objs {}


  clay read-only 0

  ###
  # topic: 124b0e5697a3e0a179a5bc044c735a54
  ###
  method active_layers {} {
................................................................................
      }
    }

    return {}
  }
  Ensemble table::objects {} {
    my variable table_objs schema_objs



    foreach {name obj} $schema_objs {
      foreach {tname tobh} [$obj table objects] {
        dict set result $tname $tobj
      }
    }
    return $table_objs
  }
}

###
# topic: eaf5daa1dd0baa5e8501e97af3224656
# title: High level database container
# description: A clay-db::connection implemented for sqlite







>







 







>
>
>





|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#    and several subject objects to manage the individual tables
#    accessed by this application.
###
::clay::define ::clay-db::connection {
  superclass ::clay-db::schema
  clay docentry {}
  Variable schema_objs {}
  Variable table_objs {}

  clay read-only 0

  ###
  # topic: 124b0e5697a3e0a179a5bc044c735a54
  ###
  method active_layers {} {
................................................................................
      }
    }

    return {}
  }
  Ensemble table::objects {} {
    my variable table_objs schema_objs
    if {[info exists table_objs]} {
      set result $table_objs
    }
    foreach {name obj} $schema_objs {
      foreach {tname tobh} [$obj table objects] {
        dict set result $tname $tobj
      }
    }
    return $result
  }
}

###
# topic: eaf5daa1dd0baa5e8501e97af3224656
# title: High level database container
# description: A clay-db::connection implemented for sqlite

Changes to modules/clay-db/build/schema.tcl.

27
28
29
30
31
32
33

34
35
36
37
38
39
40
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  ###
  # Otherwise use a standard string compare
  ###
  return [string compare -nocase $a $b]
}

::clay::define ::clay-db::meta.schema {


  class_method schema args {
    if {[lindex $args 0] eq "<list>"} {
      return [my clay keys schema/]
    }
    return [my clay set schema/ {*}$args]
  }
................................................................................
      return [my clay get schema/ $method]
    }
  }
}

::clay::define ::clay-db::schema {
  superclass ::clay-db::meta.schema
  Dict table_objs {}
  Variable schema_name {}

  constructor {script {oodefine {}}} {
    oo::objdefine [self] $oodefine
    my reload $script
    my Sql_Dynamic_Methods
  }







>







 







|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  ###
  # Otherwise use a standard string compare
  ###
  return [string compare -nocase $a $b]
}

::clay::define ::clay-db::meta.schema {
  Variable table_objs {}

  class_method schema args {
    if {[lindex $args 0] eq "<list>"} {
      return [my clay keys schema/]
    }
    return [my clay set schema/ {*}$args]
  }
................................................................................
      return [my clay get schema/ $method]
    }
  }
}

::clay::define ::clay-db::schema {
  superclass ::clay-db::meta.schema
  Variable table_objs {}
  Variable schema_name {}

  constructor {script {oodefine {}}} {
    oo::objdefine [self] $oodefine
    my reload $script
    my Sql_Dynamic_Methods
  }

Changes to modules/clay-db/clay-db.tcl.

52
53
54
55
56
57
58

59
60
61
62
63
64
65
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
684
685
686
687
688
689
690

691
692
693
694
695
696
697
...
839
840
841
842
843
844
845



846
847
848
849
850
851
852
853
854
855
856
857
858
  ###
  # Otherwise use a standard string compare
  ###
  return [string compare -nocase $a $b]
}

::clay::define ::clay-db::meta.schema {


  class_method schema args {
    if {[lindex $args 0] eq "<list>"} {
      return [my clay keys schema/]
    }
    return [my clay set schema/ {*}$args]
  }
................................................................................
      return [my clay get schema/ $method]
    }
  }
}

::clay::define ::clay-db::schema {
  superclass ::clay-db::meta.schema
  Dict table_objs {}
  Variable schema_name {}

  constructor {script {oodefine {}}} {
    oo::objdefine [self] $oodefine
    my reload $script
    my Sql_Dynamic_Methods
  }
................................................................................
#    and several subject objects to manage the individual tables
#    accessed by this application.
###
::clay::define ::clay-db::connection {
  superclass ::clay-db::schema
  clay docentry {}
  Variable schema_objs {}


  clay read-only 0

  ###
  # topic: 124b0e5697a3e0a179a5bc044c735a54
  ###
  method active_layers {} {
................................................................................
      }
    }

    return {}
  }
  Ensemble table::objects {} {
    my variable table_objs schema_objs



    foreach {name obj} $schema_objs {
      foreach {tname tobh} [$obj table objects] {
        dict set result $tname $tobj
      }
    }
    return $table_objs
  }
}

###
# topic: eaf5daa1dd0baa5e8501e97af3224656
# title: High level database container
# description: A clay-db::connection implemented for sqlite







>







 







|







 







>







 







>
>
>





|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
  ###
  # Otherwise use a standard string compare
  ###
  return [string compare -nocase $a $b]
}

::clay::define ::clay-db::meta.schema {
  Variable table_objs {}

  class_method schema args {
    if {[lindex $args 0] eq "<list>"} {
      return [my clay keys schema/]
    }
    return [my clay set schema/ {*}$args]
  }
................................................................................
      return [my clay get schema/ $method]
    }
  }
}

::clay::define ::clay-db::schema {
  superclass ::clay-db::meta.schema
  Variable table_objs {}
  Variable schema_name {}

  constructor {script {oodefine {}}} {
    oo::objdefine [self] $oodefine
    my reload $script
    my Sql_Dynamic_Methods
  }
................................................................................
#    and several subject objects to manage the individual tables
#    accessed by this application.
###
::clay::define ::clay-db::connection {
  superclass ::clay-db::schema
  clay docentry {}
  Variable schema_objs {}
  Variable table_objs {}

  clay read-only 0

  ###
  # topic: 124b0e5697a3e0a179a5bc044c735a54
  ###
  method active_layers {} {
................................................................................
      }
    }

    return {}
  }
  Ensemble table::objects {} {
    my variable table_objs schema_objs
    if {[info exists table_objs]} {
      set result $table_objs
    }
    foreach {name obj} $schema_objs {
      foreach {tname tobh} [$obj table objects] {
        dict set result $tname $tobj
      }
    }
    return $result
  }
}

###
# topic: eaf5daa1dd0baa5e8501e97af3224656
# title: High level database container
# description: A clay-db::connection implemented for sqlite

Changes to modules/clay-ui/build/baseclass.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
::namespace eval ::clay::ui {}
::namespace eval ::clay::ui::element  {}
::namespace eval ::clay::ui::datatype {}
set ::clay::ui::datatype::regen 1

proc ::clay::define::option {name args} {
  set class [current_class]
  set dictargs {default {}}
  foreach {var val} [::clay::args_to_dict {*}$args] {
    dict set dictargs [string trim $var -:/] $val
  }
  set name [string trimleft $name -]

................................................................................
###
# topic: 827a3a331a2e212a6e301f59c1eead59
# title: Define a class of options
# description:
#    Option classes are a template of properties that other
#    options can inherit.
###
proc ::clay::define::option_class {name args} {
  set class [current_class]
  set dictargs {default {}}
  set name [string trimleft $name -:]
  foreach {f v} [::oo::meta::args_to_dict {*}$args] {
    $class clay set option_class $name [string trim $f -/:] $v
  }
}

::clay::define ::clay::ui::datatype {
  clay set classinfo/ type core
  Variable internalvalue {}
................................................................................
  }

  class_method register {name body} {
    ::clay::define ::clay::ui::datatype::$name $body
    set ::clay::ui::datatype::regen 1
  }

  option_class organ {
    widget label
    set-command {my graft %field% %value%}
    get-command {my organ %field%}
  }

  option_class variable {
    widget entry
    set-command {my variable %field% ; set %field% %value%}
    get-command {my variable %field% ; set %field%}
  }

  method datatype_inferences {options} {}

................................................................................


clay::define ::clay::ui::element {
  superclass ::clay::ui::datatype

  clay set classinfo type core

  option unknown      {default 0}
  option showlabels   {default 1}
  option units        {default {}}
  option data_source  {default {}}
  option label        {default {}}
  option description  {default {}}
  option field        {default {}}
  option textvariable {default {}}
  option readonly     {default 0}
  option command      {default {}}
  option post_command {default {}}
  option colorstate   {default normal}
  option row          {default {}}
  option form         {class organ description {The form we are representing}}

  Variable entryvalue {}
  Variable displayvalue {}

  clay set namespace datatype:     ::clay::ui::datatype

  constructor {} {}
................................................................................


  method attach {organs args} {
    my variable field
    my graft {*}$organs

    set dictargs {}
    foreach {dfield dval} [::tool::args_to_options {*}$args] {
      dict set dictargs [string trim $dfield :] $dval
    }
    set options [my inferences [dict merge $dictargs $organs]]
    set form [dict get $options form]
    dict for {f v} $options {
      my clay set $f $v $form
    }





|







 







|



|







 







|





|







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
::namespace eval ::clay::ui {}
::namespace eval ::clay::ui::element  {}
::namespace eval ::clay::ui::datatype {}
set ::clay::ui::datatype::regen 1

proc ::clay::define::Option {name args} {
  set class [current_class]
  set dictargs {default {}}
  foreach {var val} [::clay::args_to_dict {*}$args] {
    dict set dictargs [string trim $var -:/] $val
  }
  set name [string trimleft $name -]

................................................................................
###
# topic: 827a3a331a2e212a6e301f59c1eead59
# title: Define a class of options
# description:
#    Option classes are a template of properties that other
#    options can inherit.
###
proc ::clay::define::Option_Class {name args} {
  set class [current_class]
  set dictargs {default {}}
  set name [string trimleft $name -:]
  foreach {f v} [::clay::args_to_dict {*}$args] {
    $class clay set option_class $name [string trim $f -/:] $v
  }
}

::clay::define ::clay::ui::datatype {
  clay set classinfo/ type core
  Variable internalvalue {}
................................................................................
  }

  class_method register {name body} {
    ::clay::define ::clay::ui::datatype::$name $body
    set ::clay::ui::datatype::regen 1
  }

  Option_Class organ {
    widget label
    set-command {my graft %field% %value%}
    get-command {my organ %field%}
  }

  Option_Class variable {
    widget entry
    set-command {my variable %field% ; set %field% %value%}
    get-command {my variable %field% ; set %field%}
  }

  method datatype_inferences {options} {}

................................................................................


clay::define ::clay::ui::element {
  superclass ::clay::ui::datatype

  clay set classinfo type core

  Option unknown      {default 0}
  Option showlabels   {default 1}
  Option units        {default {}}
  Option data_source  {default {}}
  Option label        {default {}}
  Option description  {default {}}
  Option field        {default {}}
  Option textvariable {default {}}
  Option readonly     {default 0}
  Option command      {default {}}
  Option post_command {default {}}
  Option colorstate   {default normal}
  Option row          {default {}}
  Option form         {class organ description {The form we are representing}}

  Variable entryvalue {}
  Variable displayvalue {}

  clay set namespace datatype:     ::clay::ui::datatype

  constructor {} {}
................................................................................


  method attach {organs args} {
    my variable field
    my graft {*}$organs

    set dictargs {}
    foreach {dfield dval} [::clay::args_to_options {*}$args] {
      dict set dictargs [string trim $dfield :] $dval
    }
    set options [my inferences [dict merge $dictargs $organs]]
    set form [dict get $options form]
    dict for {f v} $options {
      my clay set $f $v $form
    }

Changes to modules/clay-ui/build/stylesheet.tcl.

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#    Facilities expected of any object
#    that is marked as a master to a dynamic object
###
clay::define ::clay::ui::stylesheet {

  clay set const style_prefix {Clay}

  option initial-filepath [list tab General type pathname default [pwd] description {Path where file dialogs open by default}]

  option stylelist { default {} }

  option color-background [subst {
    signal stylesheet
    usage gui
    tab colors
    type color
    default white
    description {Default background color for windows}
  }]

  option color-row-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #BBF
    description {Color of even numbered rows in the display}
  }

  option color-row-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #FFF
    description {Color of even numbered rows in the display}
  }
  option color-red-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F44
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-red-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F00
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-blue-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #44F
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-blue-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #00F
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-green-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #4F4
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-green-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #0F0
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-grey-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #a0a0a0
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }
  option color-grey-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #888
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }

  option font-button {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard buttons}
  }
  option font-button-bold {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on bold buttons}
  }
  option font-button-small {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on small buttons}
  }
  option font-button-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on fixed font buttons}
  }
  option font-canvas {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on canvas elements}
  }
  option font-console {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on console widgets}
  }
  option font-editor {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on editable text widgets}
  }
  option font-entry {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard entry boxes}
  }
  option font-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Standard fixed space font}
  }
  option font-label {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard labels}
  }
  option font-normal {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {helvetica 10}
    description {Standard proportional font}
  }
  option font-popups {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on popups}
  }
  option font-text {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on normal text widgets}
  }

  option style_background {
    type color
    tab general
    signal stylesheet
    default grey
  }

  ###







|

|

|








|








|







|







|








|







|








|







|








|







|








|







|







|







|







|







|







|







|







|







|







|







|







|








|







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#    Facilities expected of any object
#    that is marked as a master to a dynamic object
###
clay::define ::clay::ui::stylesheet {

  clay set const style_prefix {Clay}

  Option initial-filepath [list tab General type pathname default [pwd] description {Path where file dialogs open by default}]

  Option stylelist { default {} }

  Option color-background [subst {
    signal stylesheet
    usage gui
    tab colors
    type color
    default white
    description {Default background color for windows}
  }]

  Option color-row-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #BBF
    description {Color of even numbered rows in the display}
  }

  Option color-row-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #FFF
    description {Color of even numbered rows in the display}
  }
  Option color-red-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F44
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-red-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F00
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-blue-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #44F
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-blue-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #00F
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-green-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #4F4
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-green-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #0F0
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-grey-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #a0a0a0
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }
  Option color-grey-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #888
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }

  Option font-button {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard buttons}
  }
  Option font-button-bold {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on bold buttons}
  }
  Option font-button-small {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on small buttons}
  }
  Option font-button-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on fixed font buttons}
  }
  Option font-canvas {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on canvas elements}
  }
  Option font-console {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on console widgets}
  }
  Option font-editor {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on editable text widgets}
  }
  Option font-entry {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard entry boxes}
  }
  Option font-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Standard fixed space font}
  }
  Option font-label {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard labels}
  }
  Option font-normal {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {helvetica 10}
    description {Standard proportional font}
  }
  Option font-popups {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on popups}
  }
  Option font-text {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on normal text widgets}
  }

  Option style_background {
    type color
    tab general
    signal stylesheet
    default grey
  }

  ###

Changes to modules/clay-ui/clay-ui.tcl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
..
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
...
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
....
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
# START: baseclass.tcl
###
::namespace eval ::clay::ui {}
::namespace eval ::clay::ui::element  {}
::namespace eval ::clay::ui::datatype {}
set ::clay::ui::datatype::regen 1

proc ::clay::define::option {name args} {
  set class [current_class]
  set dictargs {default {}}
  foreach {var val} [::clay::args_to_dict {*}$args] {
    dict set dictargs [string trim $var -:/] $val
  }
  set name [string trimleft $name -]

................................................................................
###
# topic: 827a3a331a2e212a6e301f59c1eead59
# title: Define a class of options
# description:
#    Option classes are a template of properties that other
#    options can inherit.
###
proc ::clay::define::option_class {name args} {
  set class [current_class]
  set dictargs {default {}}
  set name [string trimleft $name -:]
  foreach {f v} [::oo::meta::args_to_dict {*}$args] {
    $class clay set option_class $name [string trim $f -/:] $v
  }
}

::clay::define ::clay::ui::datatype {
  clay set classinfo/ type core
  Variable internalvalue {}
................................................................................
  }

  class_method register {name body} {
    ::clay::define ::clay::ui::datatype::$name $body
    set ::clay::ui::datatype::regen 1
  }

  option_class organ {
    widget label
    set-command {my graft %field% %value%}
    get-command {my organ %field%}
  }

  option_class variable {
    widget entry
    set-command {my variable %field% ; set %field% %value%}
    get-command {my variable %field% ; set %field%}
  }

  method datatype_inferences {options} {}

................................................................................
      }
      set datatype $v
      break
    }
  }
  if {$%NSPACE%::regen} {
    set body [my Generate_Select_Datatype]
    puts [list [self] Generate_Select_Datatype $body]
    oo::define [info object class [self]] method Select_Datatype {} $body
    return [my Select_Datatype]
  }
  set storage [dict getnull $info storage]
}]
    append buffer \n {# Adhoc rules}
    foreach {alias class} [lsort -dictionary -stride 2 [array get ::oo::dialect::cname ${nspace}::*]] {
................................................................................
    }
    append buffer \n "  " [list return [info commands ${nspace}::${default}]]
    return $buffer
  }

  method Select_Datatype {} {
    set body [my Generate_Select_Datatype]
    puts [list Select_Datatype (first call) $body]
    oo::define ::clay::ui::datatype method Select_Datatype {} $body
    tailcall my Select_Datatype
  }

  method value_display {} {
    my variable displayvalue
    if {![info exists displayvalue]} {
................................................................................


clay::define ::clay::ui::element {
  superclass ::clay::ui::datatype

  clay set classinfo type core

  option unknown      {default 0}
  option showlabels   {default 1}
  option units        {default {}}
  option data_source  {default {}}
  option label        {default {}}
  option description  {default {}}
  option field        {default {}}
  option textvariable {default {}}
  option readonly     {default 0}
  option command      {default {}}
  option post_command {default {}}
  option colorstate   {default normal}
  option row          {default {}}
  option form         {class organ description {The form we are representing}}

  Variable entryvalue {}
  Variable displayvalue {}

  clay set namespace datatype:     ::clay::ui::datatype

  constructor {} {}
................................................................................


  method attach {organs args} {
    my variable field
    my graft {*}$organs

    set dictargs {}
    foreach {dfield dval} [::tool::args_to_options {*}$args] {
      dict set dictargs [string trim $dfield :] $dval
    }
    set options [my inferences [dict merge $dictargs $organs]]
    set form [dict get $options form]
    dict for {f v} $options {
      my clay set $f $v $form
    }
................................................................................
#    Facilities expected of any object
#    that is marked as a master to a dynamic object
###
clay::define ::clay::ui::stylesheet {

  clay set const style_prefix {Clay}

  option initial-filepath [list tab General type pathname default [pwd] description {Path where file dialogs open by default}]

  option stylelist { default {} }

  option color-background [subst {
    signal stylesheet
    usage gui
    tab colors
    type color
    default white
    description {Default background color for windows}
  }]

  option color-row-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #BBF
    description {Color of even numbered rows in the display}
  }

  option color-row-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #FFF
    description {Color of even numbered rows in the display}
  }
  option color-red-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F44
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-red-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F00
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-blue-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #44F
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-blue-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #00F
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-green-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #4F4
    description {Color of even numbered red rows in the display (with error)}
  }
  option color-green-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #0F0
    description {Color of even numbered red rows in the display (with error)}
  }

  option color-grey-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #a0a0a0
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }
  option color-grey-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #888
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }

  option font-button {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard buttons}
  }
  option font-button-bold {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on bold buttons}
  }
  option font-button-small {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on small buttons}
  }
  option font-button-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on fixed font buttons}
  }
  option font-canvas {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on canvas elements}
  }
  option font-console {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on console widgets}
  }
  option font-editor {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on editable text widgets}
  }
  option font-entry {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard entry boxes}
  }
  option font-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Standard fixed space font}
  }
  option font-label {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard labels}
  }
  option font-normal {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {helvetica 10}
    description {Standard proportional font}
  }
  option font-popups {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on popups}
  }
  option font-text {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on normal text widgets}
  }

  option style_background {
    type color
    tab general
    signal stylesheet
    default grey
  }

  ###







|







 







|



|







 







|





|







 







<







 







<







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







|







 







|

|

|








|








|







|







|








|







|








|







|








|







|








|







|







|







|







|







|







|







|







|







|







|







|







|








|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
..
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
113
114
115
116
117
118
119

120
121
122
123
124
125
126
...
132
133
134
135
136
137
138

139
140
141
142
143
144
145
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
....
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
# START: baseclass.tcl
###
::namespace eval ::clay::ui {}
::namespace eval ::clay::ui::element  {}
::namespace eval ::clay::ui::datatype {}
set ::clay::ui::datatype::regen 1

proc ::clay::define::Option {name args} {
  set class [current_class]
  set dictargs {default {}}
  foreach {var val} [::clay::args_to_dict {*}$args] {
    dict set dictargs [string trim $var -:/] $val
  }
  set name [string trimleft $name -]

................................................................................
###
# topic: 827a3a331a2e212a6e301f59c1eead59
# title: Define a class of options
# description:
#    Option classes are a template of properties that other
#    options can inherit.
###
proc ::clay::define::Option_Class {name args} {
  set class [current_class]
  set dictargs {default {}}
  set name [string trimleft $name -:]
  foreach {f v} [::clay::args_to_dict {*}$args] {
    $class clay set option_class $name [string trim $f -/:] $v
  }
}

::clay::define ::clay::ui::datatype {
  clay set classinfo/ type core
  Variable internalvalue {}
................................................................................
  }

  class_method register {name body} {
    ::clay::define ::clay::ui::datatype::$name $body
    set ::clay::ui::datatype::regen 1
  }

  Option_Class organ {
    widget label
    set-command {my graft %field% %value%}
    get-command {my organ %field%}
  }

  Option_Class variable {
    widget entry
    set-command {my variable %field% ; set %field% %value%}
    get-command {my variable %field% ; set %field%}
  }

  method datatype_inferences {options} {}

................................................................................
      }
      set datatype $v
      break
    }
  }
  if {$%NSPACE%::regen} {
    set body [my Generate_Select_Datatype]

    oo::define [info object class [self]] method Select_Datatype {} $body
    return [my Select_Datatype]
  }
  set storage [dict getnull $info storage]
}]
    append buffer \n {# Adhoc rules}
    foreach {alias class} [lsort -dictionary -stride 2 [array get ::oo::dialect::cname ${nspace}::*]] {
................................................................................
    }
    append buffer \n "  " [list return [info commands ${nspace}::${default}]]
    return $buffer
  }

  method Select_Datatype {} {
    set body [my Generate_Select_Datatype]

    oo::define ::clay::ui::datatype method Select_Datatype {} $body
    tailcall my Select_Datatype
  }

  method value_display {} {
    my variable displayvalue
    if {![info exists displayvalue]} {
................................................................................


clay::define ::clay::ui::element {
  superclass ::clay::ui::datatype

  clay set classinfo type core

  Option unknown      {default 0}
  Option showlabels   {default 1}
  Option units        {default {}}
  Option data_source  {default {}}
  Option label        {default {}}
  Option description  {default {}}
  Option field        {default {}}
  Option textvariable {default {}}
  Option readonly     {default 0}
  Option command      {default {}}
  Option post_command {default {}}
  Option colorstate   {default normal}
  Option row          {default {}}
  Option form         {class organ description {The form we are representing}}

  Variable entryvalue {}
  Variable displayvalue {}

  clay set namespace datatype:     ::clay::ui::datatype

  constructor {} {}
................................................................................


  method attach {organs args} {
    my variable field
    my graft {*}$organs

    set dictargs {}
    foreach {dfield dval} [::clay::args_to_options {*}$args] {
      dict set dictargs [string trim $dfield :] $dval
    }
    set options [my inferences [dict merge $dictargs $organs]]
    set form [dict get $options form]
    dict for {f v} $options {
      my clay set $f $v $form
    }
................................................................................
#    Facilities expected of any object
#    that is marked as a master to a dynamic object
###
clay::define ::clay::ui::stylesheet {

  clay set const style_prefix {Clay}

  Option initial-filepath [list tab General type pathname default [pwd] description {Path where file dialogs open by default}]

  Option stylelist { default {} }

  Option color-background [subst {
    signal stylesheet
    usage gui
    tab colors
    type color
    default white
    description {Default background color for windows}
  }]

  Option color-row-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #BBF
    description {Color of even numbered rows in the display}
  }

  Option color-row-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #FFF
    description {Color of even numbered rows in the display}
  }
  Option color-red-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F44
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-red-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #F00
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-blue-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #44F
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-blue-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #00F
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-green-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #4F4
    description {Color of even numbered red rows in the display (with error)}
  }
  Option color-green-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #0F0
    description {Color of even numbered red rows in the display (with error)}
  }

  Option color-grey-even {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #a0a0a0
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }
  Option color-grey-odd {
    signal stylesheet
    usage gui
    tab colors
    type color
    default #888
    description {Color of even numbered grey rows in the display (with disabled/greyed)}
  }

  Option font-button {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard buttons}
  }
  Option font-button-bold {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on bold buttons}
  }
  Option font-button-small {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on small buttons}
  }
  Option font-button-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on fixed font buttons}
  }
  Option font-canvas {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on canvas elements}
  }
  Option font-console {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on console widgets}
  }
  Option font-editor {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on editable text widgets}
  }
  Option font-entry {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard entry boxes}
  }
  Option font-fixed {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Standard fixed space font}
  }
  Option font-label {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default TkDefaultFont
    description {Font used on standard labels}
  }
  Option font-normal {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {helvetica 10}
    description {Standard proportional font}
  }
  Option font-popups {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default-command {my Option_font_default %field%}
    description {Font used on popups}
  }
  Option font-text {
    signal stylesheet
    type font
    tab fonts
    usage gui
    default {fixed 10}
    description {Font used on normal text widgets}
  }

  Option style_background {
    type color
    tab general
    signal stylesheet
    default grey
  }

  ###

Changes to modules/clay/build/build.tcl.

1
2
3
4
5
6
7
8
9
10
11
set srcdir [file dirname [file normalize [file join [pwd] [info script]]]]
set moddir [file dirname $srcdir]

set version 0.4
set module clay
set filename clay
if {[file exists [file join $moddir .. practcl build doctool.tcl]]} {
  source [file join $moddir .. practcl build doctool.tcl]
} else {
  package require practcl 0.13
}



|







1
2
3
4
5
6
7
8
9
10
11
set srcdir [file dirname [file normalize [file join [pwd] [info script]]]]
set moddir [file dirname $srcdir]

set version 0.5
set module clay
set filename clay
if {[file exists [file join $moddir .. practcl build doctool.tcl]]} {
  source [file join $moddir .. practcl build doctool.tcl]
} else {
  package require practcl 0.13
}

Changes to modules/clay/build/class.tcl.

61
62
63
64
65
66
67






68
69
70
71
72
73
74
    my variable clay
    if {![info exists clay]} {
      set clay {}
    }
    switch $submethod {
      ancestors {
        tailcall ::clay::ancestors [self]






      }
      exists {
        if {![info exists clay]} {
          return 0
        }
        set path [::dicttool::storage $args]
        if {[dict exists $clay {*}$path]} {







>
>
>
>
>
>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    my variable clay
    if {![info exists clay]} {
      set clay {}
    }
    switch $submethod {
      ancestors {
        tailcall ::clay::ancestors [self]
      }
      branch {
        set path [::dicttool::storage $args]
        if {![dict exists $clay {*}$path .]} {
          dict set clay {*}$path . {}
        }
      }
      exists {
        if {![info exists clay]} {
          return 0
        }
        set path [::dicttool::storage $args]
        if {[dict exists $clay {*}$path]} {

Changes to modules/clay/build/metaclass.tcl.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56
..
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
104
105
106
107
108
109
110

111
112
113
114
115
116
117
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
151
152
153
154
155
156
157
158
159



160
161
162
163
164
165
166

###
# New OO Keywords for clay
###
proc ::clay::define::Array {name {values {}}} {
  set class [current_class]
  set name [string trim $name :/]
  #$class clay set array $name . 1
  dict for {var val} $values {
    $class clay set array/ $name $var $val
  }
}

###
# topic: 710a93168e4ba7a971d3dbb8a3e7bcbc


###
proc ::clay::define::Component {name info} {
  set class [current_class]
  foreach {field value} $info {
    $class clay set component/ [string trim $name :/]/ $field $value
  }
}

###
................................................................................
proc ::clay::define::class_method {name arglist body} {
  set class [current_class]
  $class clay set class_typemethod/ [string trim $name :/] [dict create arglist $arglist body $body]
}

proc ::clay::define::clay {args} {
  set class [current_class]
  if {[lindex $args 0] in "cget set"} {
    $class clay {*}$args
  } else {
    $class clay set {*}$args
  }
}

###
................................................................................
  append body $rawbody
  ::oo::define [current_class] destructor $body
}

proc ::clay::define::Dict {name {values {}}} {
  set class [current_class]
  set name [string trim $name :/]

  foreach {var val} $values {
    $class clay set dict/ $name/ $var $val
  }
}

###
# topic: 615b7c43b863b0d8d1f9107a8d126b21
................................................................................
#    Variables registered in the variable property are also initialized
#    (if missing) when the object changes class via the [emph morph] method.
###
proc ::clay::define::Variable {name {default {}}} {
  set class [current_class]
  set name [string trimright $name :/]
  $class clay set variable/ $name $default
  #::oo::define $class variable $name
}

proc ::clay::object_create {objname {class {}}} {
  #if {$::clay::trace>0} {
  #  puts [list $objname CREATE]
  #}
}
................................................................................


# clay::object
#
# This class is inherited by all classes that have options.
#
::clay::define ::clay::object {
  Variable clay {}
  Variable claycache {}



  Variable DestroyEvent 0

  ###
  # Instantiate variables and build ensemble methods.
  ###
  method InitializePublic {} {
    next







|






|
>
>

|







 







|







 







>







 







<







 







|
|
>
>
>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
126
127
128
129
130
131
132

133
134
135
136
137
138
139
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

###
# New OO Keywords for clay
###
proc ::clay::define::Array {name {values {}}} {
  set class [current_class]
  set name [string trim $name :/]
  $class clay branch array $name
  dict for {var val} $values {
    $class clay set array/ $name $var $val
  }
}

###
# An annotation that objects of this class interact with delegated
# methods. The annotation is intended to be a dictionary, and the
# only reserved key is [emph {description}], a human readable description.
###
proc ::clay::define::Delegate {name info} {
  set class [current_class]
  foreach {field value} $info {
    $class clay set component/ [string trim $name :/]/ $field $value
  }
}

###
................................................................................
proc ::clay::define::class_method {name arglist body} {
  set class [current_class]
  $class clay set class_typemethod/ [string trim $name :/] [dict create arglist $arglist body $body]
}

proc ::clay::define::clay {args} {
  set class [current_class]
  if {[lindex $args 0] in "cget set branch"} {
    $class clay {*}$args
  } else {
    $class clay set {*}$args
  }
}

###
................................................................................
  append body $rawbody
  ::oo::define [current_class] destructor $body
}

proc ::clay::define::Dict {name {values {}}} {
  set class [current_class]
  set name [string trim $name :/]
  $class clay branch dict $name
  foreach {var val} $values {
    $class clay set dict/ $name/ $var $val
  }
}

###
# topic: 615b7c43b863b0d8d1f9107a8d126b21
................................................................................
#    Variables registered in the variable property are also initialized
#    (if missing) when the object changes class via the [emph morph] method.
###
proc ::clay::define::Variable {name {default {}}} {
  set class [current_class]
  set name [string trimright $name :/]
  $class clay set variable/ $name $default

}

proc ::clay::object_create {objname {class {}}} {
  #if {$::clay::trace>0} {
  #  puts [list $objname CREATE]
  #}
}
................................................................................


# clay::object
#
# This class is inherited by all classes that have options.
#
::clay::define ::clay::object {
  clay branch array
  clay branch mixin
  clay branch option
  clay branch dict clay

  Variable DestroyEvent 0

  ###
  # Instantiate variables and build ensemble methods.
  ###
  method InitializePublic {} {
    next

Changes to modules/clay/build/object.tcl.

76
77
78
79
80
81
82






83
84
85
86
87
88
89
...
496
497
498
499
500
501
502

503
504
505
506
507
508
509
...
510
511
512
513
514
515
516

517
518
519
520
521
522
523
...
537
538
539
540
541
542
543





    if {![info exists config]} {set config {}}
    if {![info exists clayorder] || [llength $clayorder]==0} {
      set clayorder [::clay::ancestors [info object class [self]] {*}[info object mixins [self]]]
    }
    switch $submethod {
      ancestors {
        return $clayorder






      }
      cget {
        # Leaf searches return one data field at a time
        # Search in our local dict
        if {[llength $args]==1} {
          set field [string trim [lindex $args 0] -:/]
          if {[info exists option_canonical($field)]} {
................................................................................
      if { $var in {. clay} } continue
      set var [string trim $var :/]
      my variable $var
      if {![info exists $var]} {
        set $var {}
      }
      foreach {f v} $value {

        if {![dict exists ${var} $f]} {
          if {$::clay::trace>2} {puts [list initialize dict $var $f $v]}
          dict set ${var} $f $v
        }
      }
    }
    foreach {var value} [my clay get array/] {
................................................................................
      if { $var in {. clay} } continue
      set var [string trim $var :/]
      if { $var eq {clay} } continue
      my variable $var
      if {![info exists $var]} { array set $var {} }
      foreach {f v} $value {
        if {![array exists ${var}($f)]} {

          if {$::clay::trace>2} {puts [list initialize array $var\($f\) $v]}
          set ${var}($f) $v
        }
      }
    }
    foreach {field info} [my clay get option/] {
      if { $field in {. clay} } continue
................................................................................
      if {$setcmd ne {}} {
        {*}[string map [list %field% [list $field] %value% [list $value] %self% [namespace which my]] $setcmd]
      }
    }
  }
}













>
>
>
>
>
>







 







>







 







>







 







>
>
>
>
>
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
...
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
...
545
546
547
548
549
550
551
552
553
554
555
556
    if {![info exists config]} {set config {}}
    if {![info exists clayorder] || [llength $clayorder]==0} {
      set clayorder [::clay::ancestors [info object class [self]] {*}[info object mixins [self]]]
    }
    switch $submethod {
      ancestors {
        return $clayorder
      }
      branch {
        set path [::dicttool::storage $args]
        if {![dict exists $clay {*}$path .]} {
          dict set clay {*}$path . {}
        }
      }
      cget {
        # Leaf searches return one data field at a time
        # Search in our local dict
        if {[llength $args]==1} {
          set field [string trim [lindex $args 0] -:/]
          if {[info exists option_canonical($field)]} {
................................................................................
      if { $var in {. clay} } continue
      set var [string trim $var :/]
      my variable $var
      if {![info exists $var]} {
        set $var {}
      }
      foreach {f v} $value {
        if {$f eq "."} continue
        if {![dict exists ${var} $f]} {
          if {$::clay::trace>2} {puts [list initialize dict $var $f $v]}
          dict set ${var} $f $v
        }
      }
    }
    foreach {var value} [my clay get array/] {
................................................................................
      if { $var in {. clay} } continue
      set var [string trim $var :/]
      if { $var eq {clay} } continue
      my variable $var
      if {![info exists $var]} { array set $var {} }
      foreach {f v} $value {
        if {![array exists ${var}($f)]} {
          if {$f eq "."} continue
          if {$::clay::trace>2} {puts [list initialize array $var\($f\) $v]}
          set ${var}($f) $v
        }
      }
    }
    foreach {field info} [my clay get option/] {
      if { $field in {. clay} } continue
................................................................................
      if {$setcmd ne {}} {
        {*}[string map [list %field% [list $field] %value% [list $value] %self% [namespace which my]] $setcmd]
      }
    }
  }
}

oo::class clay branch array
oo::class clay branch mixin
oo::class clay branch option
oo::class clay branch dict clay

Changes to modules/clay/build/test.tcl.

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
...
922
923
924
925
926
927
928


























929
930
931
932
933
934
935
936



937
938

939
940
941
942
943
944
945
...
946
947
948
949
950
951
952





953
954
955
956
957
958
959
...
968
969
970
971
972
973
974






















975
976
977
978
979
980
981
set OBJ [::TEST::has_var new]
test clay-class-variable-0001 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get variable/ my_variable
} {10}

test clay-class-variable-0002 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get variable
} {clay {} claycache {} DestroyEvent 0 my_variable 10}

test clay-class-variable-0003 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay dget variable
} {. {} clay {} claycache {} DestroyEvent 0 my_variable 10}

test clay-class-variable-0004 {Test that variables declared in the class definition are initialized} {
  $OBJ get_my_variable
} 10

###
# Test array initialization
................................................................................
test clay-class-arrau-0006 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_array timeout
} 10
test clay-class-arrau-0007 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_array color
} blue



























###
# Test dict initialization
###
::clay::define ::TEST::has_dict {
  Dict my_dict {timeout 10}

  method get_my_dict {args} {
    my variable my_dict



    return [dict get $my_dict {*}$args]
  }

}

set OBJ [::TEST::has_dict new]
test clay-class-dict-0001 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get dict
} {my_dict {timeout 10}}

................................................................................
test clay-class-dict-0002 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay dget dict
} {. {} my_dict {. {} timeout 10}}

test clay-class-dict-0003 {Test that variables declared in the class definition are initialized} {
  $OBJ get_my_dict timeout
} 10






::clay::define ::TEST::has_more_dict {
  superclass ::TEST::has_dict
  Dict my_dict {color blue}
}
set BOBJ [::TEST::has_more_dict new]

................................................................................
test clay-class-dict-0006 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_dict timeout
} 10

test clay-class-dict-0007 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_dict color
} blue























###
# Test object delegation
###
::clay::define ::TEST::organelle {
  method add args {
    set total 0







|



|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>


>







 







>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
...
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
...
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
....
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
set OBJ [::TEST::has_var new]
test clay-class-variable-0001 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get variable/ my_variable
} {10}

test clay-class-variable-0002 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get variable
} {DestroyEvent 0 my_variable 10}

test clay-class-variable-0003 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay dget variable
} {. {} DestroyEvent 0 my_variable 10}

test clay-class-variable-0004 {Test that variables declared in the class definition are initialized} {
  $OBJ get_my_variable
} 10

###
# Test array initialization
................................................................................
test clay-class-arrau-0006 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_array timeout
} 10
test clay-class-arrau-0007 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_array color
} blue

::clay::define ::TEST::has_empty_array {
  Array my_array {}

  method my_array_exists {} {
    my variable my_array
    return [info exists my_array]
  }
  method get {field} {
    my variable my_array
    return $my_array($field)
  }
  method set {field value} {
    my variable my_array
    set my_array($field) $value
  }
}

test clay-class-array-0008 {Test that an declaration of an array with no values produces and empty array} {
  set COBJ [::TEST::has_empty_array new]
  $COBJ my_array_exists
} 1

test clay-class-array-0009 {Test that an declaration of an array with no values produces and empty array} {
  $COBJ set test "A random value"
  $COBJ get test
} {A random value}
###
# Test dict initialization
###
::clay::define ::TEST::has_dict {
  Dict my_dict {timeout 10}

  method get_my_dict {args} {
    my variable my_dict
    if {[llength $args]==0} {
      return $my_dict
    }
    return [dict get $my_dict {*}$args]
  }

}

set OBJ [::TEST::has_dict new]
test clay-class-dict-0001 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay get dict
} {my_dict {timeout 10}}

................................................................................
test clay-class-dict-0002 {Test that the parser injected the right value in the right place for clay to catch it} {
  $OBJ clay dget dict
} {. {} my_dict {. {} timeout 10}}

test clay-class-dict-0003 {Test that variables declared in the class definition are initialized} {
  $OBJ get_my_dict timeout
} 10

test clay-class-dict-0004 {Test that an empty dict is annotated} {
  $OBJ clay get dict
} {my_dict {timeout 10}}


::clay::define ::TEST::has_more_dict {
  superclass ::TEST::has_dict
  Dict my_dict {color blue}
}
set BOBJ [::TEST::has_more_dict new]

................................................................................
test clay-class-dict-0006 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_dict timeout
} 10

test clay-class-dict-0007 {Test that variables declared in the class definition are initialized} {
  $BOBJ get_my_dict color
} blue

::clay::define ::TEST::has_empty_dict {
  Dict my_empty_dict {}

  method get_my_empty_dict {args} {
    my variable my_empty_dict
    if {[llength $args]==0} {
      return $my_empty_dict
    }
    return [dict get $my_empty_dict {*}$args]
  }
}

set COBJ [::TEST::has_empty_dict new]

test clay-class-dict-0008 {Test that the parser injected the right value in the right place for clay to catch it} {
  $COBJ clay dget dict
} {my_empty_dict {. {}}}

test clay-class-dict-0009 {Test that an empty dict is initialized} {
  $COBJ get_my_empty_dict
} {}

###
# Test object delegation
###
::clay::define ::TEST::organelle {
  method add args {
    set total 0

Changes to modules/clay/clay.man.

1
2
3
4
5
6
7
8
9
...
170
171
172
173
174
175
176
177





178
179
180
181
182
183
184
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
...
390
391
392
393
394
395
396










397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 0.4]
[manpage_begin clay n [vset PACKAGE_VERSION]]
[keywords oo]
[copyright {2018 Sean Woods <yoda@etoyoc.com>}]
[moddesc   {Clay Framework}]
[titledesc {A minimalist framework for large scale OO Projects}]
[category  {Programming tools}]
[keywords TclOO]
................................................................................
[call proc [cmd clay::define::Array] [arg name] [opt "[arg values] [const ""]"]]

 New OO Keywords for clay




[call proc [cmd clay::define::Component] [arg name] [arg info]]








[call proc [cmd clay::define::constructor] [arg arglist] [arg rawbody]]



................................................................................


[call proc [cmd clay::ensemble_methodbody] [arg ensemble] [arg einfo]]


[call proc [cmd clay::define::Ensemble] [arg rawmethod] [arg arglist] [arg body]]


[call proc [cmd clay::cat] [arg fname]]

 Concatenate a file




[call proc [cmd clay::docstrip] [arg text]]

 Strip the global comments from tcl code. Used to
 prevent the documentation markup comments from clogging
 up files intended for distribution in machine readable format.




[call proc [cmd putb] [opt "[arg map]"] [arg text]]

 Append a line of text to a variable. Optionally apply a string mapping.


[list_end]

[section Classes]
[subsection {Class  oo::class}]

[para]
................................................................................
 Instantiate variables. Called on object creation and during clay mixin.




[list_end]
[para]











[subsection {Class  clay::object}]
 clay::object

 This class is inherited by all classes that have options.



[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "InitializePublic"]]

 Instantiate variables and build ensemble methods.




[list_end]
[para]

[subsection {Class  clay::doctool}]
[example {{ set authors {
   {John Doe} {jdoe@illustrious.edu}
   {Tom RichardHarry} {tomdickharry@illustrius.edu}
 }
 # Create the object
 ::clay::doctool create AutoDoc
 set fout [open [file join $moddir module.tcl] w]
 foreach file [glob [file join $srcdir *.tcl]] {
   set content [::clay::cat [file join $srcdir $file]]
    # Scan the file
    AutoDoc scan_text $content
    # Strip the comments from the distribution
    puts $fout [::clay::docstrip $content]
 }
 # Write out the manual page
 set manout [open [file join $moddir module.man] w]
 dict set arglist header [string map $modmap [::clay::cat [file join $srcdir manual.txt]]]
 dict set arglist footer [string map $modmap [::clay::cat [file join $srcdir footer.txt]]]
 dict set arglist authors $authors
 puts $manout [AutoDoc manpage {*}$arglist]
 close $manout


}}]
[para]

 Tool for build scripts to dynamically generate manual files from comments
 in source code files

[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "constructor"]]


[call method [cmd "arglist"] [arg arglist]]

 Process an argument list into an informational dict.
 This method also understands non-positional
 arguments expressed in the notation of Tip 471
 [uri https://core.tcl-lang.org/tips/doc/trunk/tip/479.md].
 [para]
 The output will be a dictionary of all of the fields and whether the fields
 are [const positional], [const mandatory], and whether they have a
 [const default] value.
 [para]

[para]Example: [example {   my arglist {a b {c 10}}

   > a {positional 1 mandatory 1} b {positional 1 mandatory 1} c {positional 1 mandatory 0 default 10}


}]

[call method [cmd "comment"] [arg block]]

 Convert a block of comments into an informational dictionary.
 If lines in the comment start with a single word ending in a colon,
 all subsequent lines are appended to a dictionary field of that name.
 If no fields are given, all of the text is appended to the [const description]
 field.

[para]Example: [example { my comment {Does something cool}
 > description {Does something cool}

 my comment {
 title : Something really cool
 author : Sean Woods
 author : John Doe
 description :
 This does something really cool!
 }
 > description {This does something really cool!}
   title {Something really cool}
   author {Sean Woods
   John Doe}


}]

[call method [cmd "keyword.Class"] [arg resultvar] [arg commentblock] [arg name] [arg body]]

 Process an oo::objdefine call that modifies the class object
 itself




[call method [cmd "keyword.class"] [arg resultvar] [arg commentblock] [arg name] [arg body]]

 Process an oo::define, clay::define, etc statement.




[call method [cmd "keyword.class_method"] [arg resultvar] [arg commentblock] [arg name] [opt "[arg args]"]]

 Process a statement for a clay style class method




[call method [cmd "keyword.method"] [arg resultvar] [arg commentblock] [arg name] [opt "[arg args]"]]

 Process a statement for a tcloo style object method




[call method [cmd "keyword.proc"] [arg commentblock] [arg name] [arg arglist] [arg body]]

 Process a proc statement




[call method [cmd "reset"]]

 Reset the state of the object and its embedded coroutine





[call method [cmd "Main"]]

 Main body of the embedded coroutine for the object




[call method [cmd "section.method"] [arg keyword] [arg method] [arg minfo]]

 Generate the manual page text for a method or proc




[call method [cmd "section.class"] [arg class_name] [arg class_info]]

 Generate the manual page text for a class




[call method [cmd "section.command"] [arg procinfo]]

 Generate the manual page text for the commands section




[call method [cmd "manpage"] [opt "[option "header [emph value]"]"] [opt "[option "footer [emph value]"]"] [opt "[option "authors [emph list]"]"]]

 Generate the manual page. Returns the completed text suitable for saving in .man file.
 The header argument is a block of doctools text to go in before the machine generated
 section. footer is a block of doctools text to go in after the machine generated
 section. authors is a list of individual authors and emails in the form of AUTHOR EMAIL ?AUTHOR EMAIL?...



[call method [cmd "scan_text"] [arg text]]
 Scan a block of text



[call method [cmd "scan_file"] [arg filename]]
 Scan a file of text



[list_end]
[para]

[section AUTHORS]
Sean Woods [uri mailto:<yoda@etoyoc.com>][para]
[vset CATEGORY oo]
[include ../doctools2base/include/feedback.inc]

[manpage_end]


|







 







|
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>









|

|

<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










1
2
3
4
5
6
7
8
9
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
222
223
224
225
226
227
228





















229
230
231
232
233
234
235
...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403





404
405
































406
407




















































































408
409

410
411
412
413
414















































415
416
417
418
419
420
421
422
423
424
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 0.5]
[manpage_begin clay n [vset PACKAGE_VERSION]]
[keywords oo]
[copyright {2018 Sean Woods <yoda@etoyoc.com>}]
[moddesc   {Clay Framework}]
[titledesc {A minimalist framework for large scale OO Projects}]
[category  {Programming tools}]
[keywords TclOO]
................................................................................
[call proc [cmd clay::define::Array] [arg name] [opt "[arg values] [const ""]"]]

 New OO Keywords for clay




[call proc [cmd clay::define::Delegate] [arg name] [arg info]]

 An annotation that objects of this class interact with delegated
 methods. The annotation is intended to be a dictionary, and the
 only reserved key is [emph {description}], a human readable description.




[call proc [cmd clay::define::constructor] [arg arglist] [arg rawbody]]



................................................................................


[call proc [cmd clay::ensemble_methodbody] [arg ensemble] [arg einfo]]


[call proc [cmd clay::define::Ensemble] [arg rawmethod] [arg arglist] [arg body]]























[list_end]

[section Classes]
[subsection {Class  oo::class}]

[para]
................................................................................
 Instantiate variables. Called on object creation and during clay mixin.




[list_end]
[para]

[subsection {Class  branch}]

[para]
[class {Option}]
[list_begin definitions]
[call option [cmd ]]

[list_end]
[para]

[subsection {Class  clay::object}]
 clay::object

 This class is inherited by all classes that have options.



[para]
[class {Variable}]
[list_begin definitions]
[call variable [cmd DestroyEvent]]






[list_end]
[para]
































[class {Methods}]
[list_begin definitions]




















































































[call method [cmd "InitializePublic"]]


 Instantiate variables and build ensemble methods.



















































[list_end]
[para]

[section AUTHORS]
Sean Woods [uri mailto:<yoda@etoyoc.com>][para]
[vset CATEGORY oo]
[include ../doctools2base/include/feedback.inc]

[manpage_end]

Changes to modules/clay/pkgIndex.tcl.

7
8
9
10
11
12
13
14
15
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

if {![package vsatisfies [package provide Tcl] 8.6]} {return}


package ifneeded clay 0.4 [list source [file join $dir clay.tcl]]








|

7
8
9
10
11
12
13
14
15
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

if {![package vsatisfies [package provide Tcl] 8.6]} {return}


package ifneeded clay 0.5 [list source [file join $dir clay.tcl]]

Changes to modules/httpd/build/build.tcl.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

if {[file exists [file join $moddir .. practcl build doctool.tcl]]} {
  source [file join $moddir .. practcl build doctool.tcl]
} else {
  package require practcl 0.13
}
::practcl::doctool create AutoDoc
set version 4.3
set tclversion 8.6
set module [file tail $moddir]
set filename $module

set fout [open [file join $moddir ${filename}.tcl] w]
dict set modmap  %module% $module
dict set modmap  %version% $version







|







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

if {[file exists [file join $moddir .. practcl build doctool.tcl]]} {
  source [file join $moddir .. practcl build doctool.tcl]
} else {
  package require practcl 0.13
}
::practcl::doctool create AutoDoc
set version 4.3.1
set tclversion 8.6
set module [file tail $moddir]
set filename $module

set fout [open [file join $moddir ${filename}.tcl] w]
dict set modmap  %module% $module
dict set modmap  %version% $version

Changes to modules/httpd/build/core.tcl.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30



31

32
33
34
35
36
37
38
..
66
67
68
69
70
71
72
73


74
75
76
77
78
79



80

81
82
83

84
85
86
87
88
89
90
# support the SCGI module
###

package require uri
package require dns
package require cron
package require coroutine
package require clay 0.3
package require mime
package require fileutil
package require websocket
package require Markdown
package require uuid
package require fileutil::magic::filetype

namespace eval httpd::content {}

namespace eval ::url {}
namespace eval ::httpd {}
namespace eval ::scgi {}




clay::define ::httpd::mime {


  method ChannelCopy {in out args} {
    set chunk 4096
    set size -1
    foreach {f v} $args {
      set [string trim $f -] $v
    }
................................................................................
      }
      if {[chan eof $in]} {
        break
      }
    }
  }




  method html_header {{title {}} args} {
    set result {}
    append result "<HTML><HEAD>"
    if {$title ne {}} {
      append result "<TITLE>$title</TITLE>"
    }



    append result "<link rel=\"stylesheet\" href=\"/style.css\">"

    append result "</HEAD><BODY>"
    return $result
  }

  method html_footer {args} {
    return "</BODY></HTML>"
  }

  method http_code_string code {
    set codes {
      200 {Data follows}







|













>
>
>

>







 







<
>
>


|



>
>
>
|
>



>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# support the SCGI module
###

package require uri
package require dns
package require cron
package require coroutine
package require clay 0.5
package require mime
package require fileutil
package require websocket
package require Markdown
package require uuid
package require fileutil::magic::filetype

namespace eval httpd::content {}

namespace eval ::url {}
namespace eval ::httpd {}
namespace eval ::scgi {}

###
# A metaclass for MIME handling behavior across a live socket
###
clay::define ::httpd::mime {


  method ChannelCopy {in out args} {
    set chunk 4096
    set size -1
    foreach {f v} $args {
      set [string trim $f -] $v
    }
................................................................................
      }
      if {[chan eof $in]} {
        break
      }
    }
  }


  ###
  # Returns a block of HTML
  method html_header {{title {}} args} {
    set result {}
    append result "<!DOCTYPE html>\n<HTML><HEAD>"
    if {$title ne {}} {
      append result "<TITLE>$title</TITLE>"
    }
    if {[dict exists $args stylesheet]} {
      append result "<link rel=\"stylesheet\" href=\"[dict get $args stylesheet]\">"
    } else {
      append result "<link rel=\"stylesheet\" href=\"/style.css\">"
    }
    append result "</HEAD><BODY>"
    return $result
  }

  method html_footer {args} {
    return "</BODY></HTML>"
  }

  method http_code_string code {
    set codes {
      200 {Data follows}

Changes to modules/httpd/build/file.tcl.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
::clay::define ::httpd::content.file {

  method FileName {} {
    set uri [string trimleft [my request get REQUEST_URI] /]
    set path [my clay get path]
    set prefix [my clay get prefix]
    set fname [string range $uri [string length $prefix] end]
    if {$fname in "{} index.html index.md index"} {
      return $path
    }
    if {[file exists [file join $path $fname]]} {
      return [file join $path $fname]
    }
    if {[file exists [file join $path $fname.md]]} {
      return [file join $path $fname.md]







|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
::clay::define ::httpd::content.file {

  method FileName {} {
    set uri [string trimleft [my request get REQUEST_URI] /]
    set path [my clay get path]
    set prefix [my clay get prefix]
    set fname [string range $uri [string length $prefix] end]
    if {$fname in "{} index.html index.md index index.tml"} {
      return $path
    }
    if {[file exists [file join $path $fname]]} {
      return [file join $path $fname]
    }
    if {[file exists [file join $path $fname.md]]} {
      return [file join $path $fname.md]

Changes to modules/httpd/build/manual.txt.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[category  Networking]
[keywords TclOO]
[keywords http]
[keywords httpd]
[keywords httpserver]
[keywords services]
[require Tcl 8.6]
[require httpd [opt [vset VERSION]]]
[require uuid]
[require clay]
[require coroutine]
[require fileutil]
[require fileutil::magic::filetype]
[require websocket]
[require mime]







<







5
6
7
8
9
10
11

12
13
14
15
16
17
18
[category  Networking]
[keywords TclOO]
[keywords http]
[keywords httpd]
[keywords httpserver]
[keywords services]
[require Tcl 8.6]

[require uuid]
[require clay]
[require coroutine]
[require fileutil]
[require fileutil::magic::filetype]
[require websocket]
[require mime]

Changes to modules/httpd/build/reply.tcl.

96
97
98
99
100
101
102
103

104




105
106



107
108
109
110
111
112
113
...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
# }
#
# }]
###
::clay::define ::httpd::reply {
  superclass ::httpd::mime

  Variable transfer_complete 0






  Dict reply {}




  Dict request {
    CONTENT_LENGTH 0
    COOKIE {}
    HTTP_HOST {}
    REFERER {}
    REQUEST_URI {}
    REMOTE_ADDR {}
................................................................................
  #       chan copy $sock $chan -size $SIZE -command [info coroutine]
  #       yield
  #     }
  #     catch {close $sock}
  #     chan flush $chan
  # }]
  method TransferComplete args {
    my variable chan transfer_complete
    set transfer_complete 1
    my log TransferComplete
    set chan {}
    foreach c $args {
      catch {chan event $c readable {}}
      catch {chan event $c writable {}}
      catch {chan flush $c}
      catch {chan close $c}







|
>
|
>
>
>
>


>
>
>







 







<
<







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
...
454
455
456
457
458
459
460


461
462
463
464
465
466
467
# }
#
# }]
###
::clay::define ::httpd::reply {
  superclass ::httpd::mime

  Delegate <server> {
    description {The server object which spawned this reply}
  }

  ###
  # A dictionary which will converted into the MIME headers of the reply
  ###
  Dict reply {}

  ###
  # A dictionary containing the SCGI transformed HTTP headers for the request
  ###
  Dict request {
    CONTENT_LENGTH 0
    COOKIE {}
    HTTP_HOST {}
    REFERER {}
    REQUEST_URI {}
    REMOTE_ADDR {}
................................................................................
  #       chan copy $sock $chan -size $SIZE -command [info coroutine]
  #       yield
  #     }
  #     catch {close $sock}
  #     chan flush $chan
  # }]
  method TransferComplete args {


    my log TransferComplete
    set chan {}
    foreach c $args {
      catch {chan event $c readable {}}
      catch {chan event $c writable {}}
      catch {chan flush $c}
      catch {chan close $c}

Changes to modules/httpd/httpd.man.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
67
68
69
70
71
72
73




74
75
76
77
78
79
80
81



82
83
84
85
86
87
88
...
219
220
221
222
223
224
225






















226
227
228
229
230
231
232
...
399
400
401
402
403
404
405








406
407
408
409
410
411
412
...
676
677
678
679
680
681
682






683
684
685
686
687
688
689
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 4.3]
[manpage_begin httpd n [vset PACKAGE_VERSION]]
[keywords WWW]
[copyright {2018 Sean Woods <yoda@etoyoc.com>}]
[moddesc   {Tcl Web Server}]
[titledesc {A TclOO and coroutine based web server}]
[category  Networking]
[keywords TclOO]
[keywords http]
[keywords httpd]
[keywords httpserver]
[keywords services]
[require Tcl 8.6]
[require httpd [opt [vset VERSION]]]
[require uuid]
[require clay]
[require coroutine]
[require fileutil]
[require fileutil::magic::filetype]
[require websocket]
[require mime]
................................................................................
[example {
cd ~/tcl/sandbox/tcllib
tclsh examples/httpd.tcl
}]

[section Classes]
[subsection {Class  httpd::mime}]





[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "ChannelCopy"] [arg in] [arg out] [opt "[arg args]"]]


[call method [cmd "html_header"] [opt "[arg title] [const ""]"] [opt "[arg args]"]]





[call method [cmd "html_footer"] [opt "[arg args]"]]


[call method [cmd "http_code_string"] [arg code]]

................................................................................
 	}
 }

 }]

























[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "constructor"] [arg ServerObj] [opt "[arg args]"]]


[call method [cmd "destructor"] [opt "[arg dictargs]"]]
................................................................................
[list_end]
[para]

[subsection {Class  httpd::server}]
[emph "ancestors"]: [class httpd::mime]
[para]









[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "constructor"] [arg args] [opt "[arg port] [const "auto"]"] [opt "[arg myaddr] [const "127.0.0.1"]"] [opt "[arg string] [const "auto"]"] [opt "[arg name] [const "auto"]"] [opt "[arg doc_root] [const ""]"] [opt "[arg reverse_dns] [const "0"]"] [opt "[arg configuration_file] [const ""]"] [opt "[arg protocol] [const "HTTP/1.1"]"]]


[call method [cmd "destructor"] [opt "[arg dictargs]"]]
................................................................................


[list_end]
[para]

[subsection {Class  httpd::content.exec}]







[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "CgiExec"] [arg execname] [arg script] [arg arglist]]


[call method [cmd "Cgi_Executable"] [arg script]]

|












<







 







>
>
>
>








>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 4.3.1]
[manpage_begin httpd n [vset PACKAGE_VERSION]]
[keywords WWW]
[copyright {2018 Sean Woods <yoda@etoyoc.com>}]
[moddesc   {Tcl Web Server}]
[titledesc {A TclOO and coroutine based web server}]
[category  Networking]
[keywords TclOO]
[keywords http]
[keywords httpd]
[keywords httpserver]
[keywords services]
[require Tcl 8.6]

[require uuid]
[require clay]
[require coroutine]
[require fileutil]
[require fileutil::magic::filetype]
[require websocket]
[require mime]
................................................................................
[example {
cd ~/tcl/sandbox/tcllib
tclsh examples/httpd.tcl
}]

[section Classes]
[subsection {Class  httpd::mime}]

 A metaclass for MIME handling behavior across a live socket



[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "ChannelCopy"] [arg in] [arg out] [opt "[arg args]"]]


[call method [cmd "html_header"] [opt "[arg title] [const ""]"] [opt "[arg args]"]]

 Returns a block of HTML



[call method [cmd "html_footer"] [opt "[arg args]"]]


[call method [cmd "http_code_string"] [arg code]]

................................................................................
 	}
 }

 }]



[para]
[class {Delegate}]
[list_begin definitions]
[call delegate [cmd <server>]]The server object which spawned this reply

[list_end]
[para]
[class {Variable}]
[list_begin definitions]
[call variable [cmd reply]]
 A dictionary which will converted into the MIME headers of the reply




[call variable [cmd request]]
 A dictionary containing the SCGI transformed HTTP headers for the request




[list_end]
[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "constructor"] [arg ServerObj] [opt "[arg args]"]]


[call method [cmd "destructor"] [opt "[arg dictargs]"]]
................................................................................
[list_end]
[para]

[subsection {Class  httpd::server}]
[emph "ancestors"]: [class httpd::mime]
[para]

[para]
[class {Variable}]
[list_begin definitions]
[call variable [cmd template]]

[call variable [cmd url_patterns]]

[list_end]
[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "constructor"] [arg args] [opt "[arg port] [const "auto"]"] [opt "[arg myaddr] [const "127.0.0.1"]"] [opt "[arg string] [const "auto"]"] [opt "[arg name] [const "auto"]"] [opt "[arg doc_root] [const ""]"] [opt "[arg reverse_dns] [const "0"]"] [opt "[arg configuration_file] [const ""]"] [opt "[arg protocol] [const "HTTP/1.1"]"]]


[call method [cmd "destructor"] [opt "[arg dictargs]"]]
................................................................................


[list_end]
[para]

[subsection {Class  httpd::content.exec}]

[para]
[class {Variable}]
[list_begin definitions]
[call variable [cmd exename]]

[list_end]
[para]
[class {Methods}]
[list_begin definitions]
[call method [cmd "CgiExec"] [arg execname] [arg script] [arg arglist]]


[call method [cmd "Cgi_Executable"] [arg script]]

Changes to modules/httpd/pkgIndex.tcl.

1
2
3
4

if {![package vsatisfies [package provide Tcl] 8.6]} {return}
package ifneeded httpd 4.3 [list source [file join $dir httpd.tcl]]



|

1
2
3
4

if {![package vsatisfies [package provide Tcl] 8.6]} {return}
package ifneeded httpd 4.3.1 [list source [file join $dir httpd.tcl]]

Changes to modules/tool-ui/tool-ui.tcl.

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    return 0
  }

  method Generate_Select_Datatype {} {
    set ::tool::ui::datatype::regen 0
    set nspace [my clay get namespace datatype]
    set default [my clay get namespace default]
    puts [list Generate_Select_Datatype $nspace]
    puts [list Generate_Select_Datatype [my clay get namespace]]
    set buffer [string map [list %NSPACE% $nspace] {
  set info [my config dump]
  set datatype {}
  foreach param {datatype type field widget storage} {
    if {[set v [dict getnull $info $param]] ne {}} {
      if {[info exists ::oo::dialect::cname(%NSPACE%::${v})]} {
        return $::oo::dialect::cname(%NSPACE%::${v})
................................................................................
    }
    append buffer \n "  " [list return [info commands ${nspace}::${default}]]
    return $buffer
  }

  method Select_Datatype {} {
    set body [my Generate_Select_Datatype]
    puts [list Select_Datatype (first call) $body]
    oo::define ::tool::ui::datatype method Select_Datatype {} $body
    return [my Select_Datatype]
  }

  method value_display {} {
    my variable displayvalue
    if {![info exists displayvalue]} {







<
<







 







<







45
46
47
48
49
50
51


52
53
54
55
56
57
58
..
78
79
80
81
82
83
84

85
86
87
88
89
90
91
    return 0
  }

  method Generate_Select_Datatype {} {
    set ::tool::ui::datatype::regen 0
    set nspace [my clay get namespace datatype]
    set default [my clay get namespace default]


    set buffer [string map [list %NSPACE% $nspace] {
  set info [my config dump]
  set datatype {}
  foreach param {datatype type field widget storage} {
    if {[set v [dict getnull $info $param]] ne {}} {
      if {[info exists ::oo::dialect::cname(%NSPACE%::${v})]} {
        return $::oo::dialect::cname(%NSPACE%::${v})
................................................................................
    }
    append buffer \n "  " [list return [info commands ${nspace}::${default}]]
    return $buffer
  }

  method Select_Datatype {} {
    set body [my Generate_Select_Datatype]

    oo::define ::tool::ui::datatype method Select_Datatype {} $body
    return [my Select_Datatype]
  }

  method value_display {} {
    my variable displayvalue
    if {![info exists displayvalue]} {