1huddle(n) HUDDLE huddle(n)
2
3
4
5______________________________________________________________________________
6
8 huddle - Create and manipulate huddle object
9
11 package require Tcl 8.4
12
13 package require huddle ?0.3?
14
15 huddle create key value ?key value ...?
16
17 huddle list ?value value ...?
18
19 huddle number number
20
21 huddle string string
22
23 huddle boolean expression to evaluate as true or false
24
25 huddle true
26
27 huddle false
28
29 huddle null
30
31 huddle get object key ?key ...?
32
33 huddle gets object key ?key ...?
34
35 huddle set objectVar key ?key ...? value
36
37 huddle remove object key ?key ...?
38
39 huddle combine object1 object2 ?object3 ...?
40
41 huddle equal object1 object2
42
43 huddle append objectVar key value ?key value ...?
44
45 huddle append objectVar value ?value ...?
46
47 huddle keys object
48
49 huddle llength object
50
51 huddle type object ?key key...?
52
53 huddle strip object
54
55 huddle jsondump object ?offset? ?newline? ?begin_offset?
56
57 huddle compile spec data
58
59 huddle isHuddle object
60
61 huddle checkHuddle object
62
63 huddle to_node object ?tag?
64
65 huddle wrap tag src
66
67 huddle call tag command args
68
69 huddle addType callback
70
71 callback command ?args?
72
73 setting
74
75 get_sub src key
76
77 strip src
78
79 set src key value
80
81 remove src key value
82
83______________________________________________________________________________
84
86 Huddle provides a generic Tcl-based serialization/intermediary format.
87 Currently, each node is wrapped in a tag with simple type information.
88
89 When converting huddle-notation to other serialization formats like
90 JSON or YAML this type information is used to select the proper nota‐
91 tion. And when going from JSON/YAML/... to huddle their notation can
92 be used to select the proper huddle type.
93
94 In that manner huddle can serve as a common intermediary format.
95
96
97 huddle-format: >
98 {HUDDLE {huddle-node}}
99 huddle-node: >
100 {tag content}
101 each content of tag means:
102 s: (content is a) string
103 L: list, each sub node is a huddle-node
104 D: dict, each sub node is a huddle-node
105 confirmed:
106 - JSON
107 - YAML(generally, but cannot discribe YAML-tags)
108 limitation:
109 - cannot discribe aliases from a node to other node.
110
111
112 The huddle package returns data as a Tcl dict. Either the dict package
113 or Tcl 8.5 is required for use.
114
116 huddle create key value ?key value ...?
117 Create a huddle object as a dict. It can contain other huddle
118 objects.
119
120 huddle list ?value value ...?
121 Create a huddle object as a list. It can contain other huddle
122 objects.
123
124 huddle number number
125 Create a huddle object as a number.
126
127 huddle string string
128 Create a huddle object as a string.
129
130 huddle boolean expression to evaluate as true or false
131 Create a huddle object as a boolean evaluating an expression as
132 true or false-
133
134 huddle true
135 Create a huddle object as a boolean true.
136
137 huddle false
138 Create a huddle object as a boolean false.
139
140 huddle null
141 Create a huddle object as a null.
142
143 huddle get object key ?key ...?
144 Almost the same as dict get. Get a sub-object from the huddle
145 object. key can be used to huddle-list's index.
146
147 huddle gets object key ?key ...?
148 Get a sub-object from the huddle object, stripped.
149
150 huddle set objectVar key ?key ...? value
151 Almost the same as dict set. Set a sub-object from the huddle
152 object. key can be used to huddle-list's index.
153
154 huddle remove object key ?key ...?
155 Almost the same as dict remove. Remove a sub-object from the
156 huddle object. key can be used to huddle-list's index.
157
158 huddle combine object1 object2 ?object3 ...?
159 Merging huddle objects given.
160
161
162 % set aa [huddle create a b c d]
163 HUDDLE {D {a {s b} c {s d}}}
164 % set bb [huddle create a k l m]
165 HUDDLE {D {a {s k} l {s m}}}
166 % huddle combine $aa $bb
167 HUDDLE {D {a {s k} c {s d} l {s m}}}
168
169
170 huddle equal object1 object2
171 Comparing two huddle objects recursively. When to equal,
172 returns 1, otherwise 0.
173
174
175 % set aa [huddle create a b c d]
176 HUDDLE {D {a {s b} c {s d}}}
177 % set bb [huddle create c d a b]
178 HUDDLE {D {c {s d} a {s b}}}
179 % huddle equal $aa $bb
180 1
181
182
183 huddle append objectVar key value ?key value ...?
184
185 huddle append objectVar value ?value ...?
186 Appending child elements. When for dicts, giving key/value. When
187 for lists, giving values.
188
189
190 % set aa [huddle create a b c d]
191 HUDDLE {D {a {s b} c {s d}}}
192 % huddle append aa a k l m
193 HUDDLE {D {a {s k} c {s d} l {s m}}}
194 % set bb [huddle list i j k l]
195 HUDDLE {L {{s i} {s j} {s k} {s l}}}
196 % huddle append bb g h i
197 HUDDLE {L {{s i} {s j} {s k} {s l} {s g} {s h} {s i}}}
198
199
200 huddle keys object
201 The same as dict keys.
202
203 huddle llength object
204 The same as llength.
205
206 huddle type object ?key key...?
207 Return the element type of specified by keys. if ?key? is not
208 given, returns the type of root node.
209
210
211 string the node is a tcl's string.
212
213 dict the node is a dict.
214
215 list the node is a list.
216
217 number the node is a number.
218
219 boolean
220 the node is a boolean.
221
222 null the node is a null.
223
224
225 % huddle type {HUDDLE {s str}}
226 string
227 % huddle type {HUDDLE {L {{s a} {s b} {s c}}}}
228 list
229 % huddle type {HUDDLE {D {aa {s b} cc {s d}}}} cc
230 string
231
232
233 huddle strip object
234 Stripped all tags. Converted to normal Tcl's list/dict.
235
236 huddle jsondump object ?offset? ?newline? ?begin_offset?
237 dump a json-stream from the huddle-object.
238
239
240 offset ""
241 begin offset as spaces " ".
242
243 # normal output has some indents. some strings are escaped.
244 % huddle jsondump {HUDDLE {L {{L {{s i} {s baa} {s \\k} {L {{s 1.0} {s true} {s /g} {s h}}} {L {{s g}}}}} {s t}}}}
245 [
246 [
247 "i",
248 "baa",
249 "\\k",
250 [
251 1.0,
252 true,
253 "\/g",
254 "h"
255 ],
256 ["g"]
257 ],
258 "t"
259 ]
260 # stripped output
261 % huddle jsondump {HUDDLE {D {dd {D {bb {D {a {s baa} c {s {d
262 a}}}} cc {D {g {s h}}}}} ee {D {i {s j} k {s 1} j {s { m\a}}}}}}} "" ""
263 {"dd": {"bb": {"a": "baa","c": "d\na"},"cc": {"g": "h"}},"ee": {"i": "j","k": 1,"j": " m\\a"}}
264
265
266 huddle compile spec data
267 construct a huddle object from plain old tcl values. spec is
268 defined as follows:
269
270 string data is simply a string
271
272 list data is a tcl list of strings
273
274 dict data is a tcl dict of strings
275
276 list list
277 data is a tcl list of lists
278
279 list dict
280 data is a tcl list of dicts
281
282 dict xx list
283 data is a tcl dict where the value of key xx is a tcl
284 list
285
286 dict * list
287 data is a tcl dict of lists data is plain old tcl values
288
289 % huddle compile {dict * list} {a {1 2 3} b {4 5}}
290 HUDDLE {D {a {L {{s 1} {s 2} {s 3}}} b {L {{s 4} {s 5}}}}}
291 % huddle compile {dict * {list {dict d list}}} {a {{c 1} {d {2 2 2} e 3}} b {{f 4 g 5}}}
292 HUDDLE {D {a {L {{D {c {s 1}}} {D {d {L {{s 2} {s 2} {s 2}}} e {s 3}}}}} b {L {{D {f {s 4} g {s 5}}}}}}}
293
294
295 huddle isHuddle object
296 if object is a huddle, returns 1. the other, returns 0.
297
298 huddle checkHuddle object
299 if object is not a huddle, rises an error.
300
301 huddle to_node object ?tag?
302 for type-callbacks.
303
304 if object is a huddle, returns root-node. the other, returns
305 [list s $object].
306
307
308 % huddle to_node str
309 s str
310 % huddle to_node str !!str
311 !!str str
312 % huddle to_node {HUDDLE {s str}}
313 s str
314 % huddle to_node {HUDDLE {l {a b c}}}
315 l {a b c}
316
317
318 huddle wrap tag src
319 for type-callbacks.
320
321 Create a huddle object from src with specified tag.
322
323
324 % huddle wrap "" str
325 HUDDLE str
326 % huddle wrap s str
327 HUDDLE {s str}
328
329
330 huddle call tag command args
331 for type-callbacks.
332
333 devolving command to default tag-callback
334
335 huddle addType callback
336 add a user-specified-type/tag to the huddle library. To see
337 "Additional Type".
338
339
340 callback
341 callback function name for additional type.
342
344 The definition of callback for user-type.
345
346 callback command ?args?
347
348 command
349 huddle subcomand which is needed to reply by the call‐
350 back.
351
352 args arguments of subcommand. The number of list of arguments
353 is different for each subcommand.
354
355 The callback procedure shuould reply the following subcommands.
356
357 setting
358 only returns a fixed dict of the type infomation for setting the
359 user-tag.
360
361 type typename
362 typename of the type
363
364 method {method1 method2 method3 ...}
365 method list as huddle subcommand. Then, you can call
366 [huddle method1 ...]
367
368 tag {tag1 child/parent tag2 child/parent ...}
369 tag list for huddle-node as a dict. if the type has
370 child-nodes, use "parent", otherwise use "child".
371
372 get_sub src key
373 returns a sub node specified by key.
374
375 src a node content in huddle object.
376
377 strip src
378 returns stripped node contents. if the type has child nodes,
379 every node must be stripped.
380
381 set src key value
382 sets a sub-node from the tagged-content, and returns self.
383
384 remove src key value
385 removes a sub-node from the tagged-content, and returns self.
386
387 strip must be defined at all types. get_sub must be defined at con‐
388 tainer types. set/remove shuould be defined, if you call them.
389
390
391 # callback sample for my-dict
392 proc my_dict_setting {command args} {
393 switch -- $command {
394 setting { ; # type definition
395 return {
396 type dict
397 method {create keys}
398 tag {d child D parent}
399 constructor create
400 str s
401 }
402 # type: the type-name
403 # method: add methods to huddle's subcommand.
404 # "get_sub/strip/set/remove/equal/append" called by huddle module.
405 # "strip" must be defined at all types.
406 # "get_sub" must be defined at container types.
407 # "set/remove/equal/append" shuould be defined, if you call them.
408 # tag: tag definition("child/parent" word is maybe obsoleted)
409 }
410 get_sub { ; # get a sub-node specified by "key" from the tagged-content
411 foreach {src key} $args break
412 return [dict get $src $key]
413 }
414 strip { ; # strip from the tagged-content
415 foreach {src nop} $args break
416 foreach {key val} $src {
417 lappend result $key [huddle strip $val]
418 }
419 return $result
420 }
421 set { ; # set a sub-node from the tagged-content
422 foreach {src key value} $args break
423 dict set src $key $value
424 return $src
425 }
426 remove { ; # remove a sub-node from the tagged-content
427 foreach {src key value} $args break
428 return [dict remove $src $key]
429 }
430 equal { ; # check equal for each node
431 foreach {src1 src2} $args break
432 if {[llength $src1] != [llength $src2]} {return 0}
433 foreach {key1 val1} $src1 {
434 if {![dict exists $src2 $key1]} {return 0}
435 if {![huddle _equal_subs $val1 [dict get $src2 $key1]]} {return 0}
436 }
437 return 1
438 }
439 append { ; # append nodes
440 foreach {str src list} $args break
441 if {[llength $list] % 2} {error {wrong # args: should be "huddle append objvar ?key value ...?"}}
442 set resultL $src
443 foreach {key value} $list {
444 if {$str ne ""} {
445 lappend resultL $key [huddle to_node $value $str]
446 } else {
447 lappend resultL $key $value
448 }
449 }
450 return [eval dict create $resultL]
451 }
452 create { ; # $args: all arguments after "huddle create"
453 if {[llength $args] % 2} {error {wrong # args: should be "huddle create ?key value ...?"}}
454 set resultL {}
455 foreach {key value} $args {
456 lappend resultL $key [huddle to_node $value]
457 }
458 return [huddle wrap D $resultL]
459 }
460 keys {
461 foreach {src nop} $args break
462 return [dict keys [lindex [lindex $src 1] 1]]
463 }
464 default {
465 error "$command is not callback for dict"
466 }
467 }
468 }
469
470
471
472 # inheritance sample from default dict-callback
473 proc ::yaml::_huddle_mapping {command args} {
474 switch -- $command {
475 setting { ; # type definition
476 return {
477 type dict
478 method {mapping}
479 tag {!!map parent}
480 constructor mapping
481 str !!str
482 }
483 }
484 mapping { ; # $args: all arguments after "huddle mapping"
485 if {[llength $args] % 2} {error {wrong # args: should be "huddle mapping ?key value ...?"}}
486 set resultL {}
487 foreach {key value} $args {
488 lappend resultL $key [huddle to_node $value !!str]
489 }
490 return [huddle wrap !!map $resultL]
491 }
492 default { ; # devolving to default dict-callback
493 return [huddle call D $command $args]
494 }
495 }
496 }
497
498
500 You can add huddle-node types e.g. ::struct::tree. To do so, first,
501 define a callback-procedure for additional tagged-type. The proc get
502 argments as command and ?args?. It has some switch-sections.
503
504 And, addType subcommand will called.
505
506
507 huddle addType my_dict_setting
508
509
511 # create as a dict
512 % set bb [huddle create a b c d]
513 HUDDLE {D {a {s b} c {s d}}}
514
515 # create as a list
516 % set cc [huddle list e f g h]
517 HUDDLE {L {{s e} {s f} {s g} {s h}}}
518 % set bbcc [huddle create bb $bb cc $cc]
519 HUDDLE {D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}}
520 % set folding [huddle list $bbcc p [huddle list q r] s]
521 HUDDLE {L {{D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q} {s r}}} {s s}}}
522
523 # normal Tcl's notation
524 % huddle strip $folding
525 {bb {a b c d} cc {e f g h}} p {q r} s
526
527 # get a sub node
528 % huddle get $folding 0 bb
529 HUDDLE {D {a {s b} c {s d}}}
530 % huddle gets $folding 0 bb
531 a b c d
532
533 # overwrite a node
534 % huddle set folding 0 bb c kkk
535 HUDDLE {L {{D {bb {D {a {s b} c {s kkk}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q} {s r}}} {s s}}}
536
537 # remove a node
538 % huddle remove $folding 2 1
539 HUDDLE {L {{D {bb {D {a {s b} c {s kkk}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q}}} {s s}}}
540 % huddle strip $folding
541 {bb {a b c kkk} cc {e f g h}} p {q r} s
542
543 # dump as a JSON stream
544 % huddle jsondump $folding
545 [
546 {
547 "bb": {
548 "a": "b",
549 "c": "kkk"
550 },
551 "cc": [
552 "e",
553 "f",
554 "g",
555 "h"
556 ]
557 },
558 "p",
559 [
560 "q",
561 "r"
562 ],
563 "s"
564 ]
565
566
568 now printing.
569
571 This document, and the package it describes, will undoubtedly contain
572 bugs and other problems. Please report such in the category huddle of
573 the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. Please
574 also report any ideas for enhancements you may have for either package
575 and/or documentation.
576
577 When proposing code changes, please provide unified diffs, i.e the out‐
578 put of diff -u.
579
580 Note further that attachments are strongly preferred over inlined
581 patches. Attachments can be made by going to the Edit form of the
582 ticket immediately after its creation, and then using the left-most
583 button in the secondary navigation bar.
584
586 yaml
587
589 data exchange, exchange format, huddle, json, parsing, text processing,
590 yaml
591
593 Copyright (c) 2008-2011 KATO Kanryu <kanryu6@users.sourceforge.net>
594 Copyright (c) 2015 Miguel Martínez López <aplicacionamedida@gmail.com>
595
596
597
598
599tcllib 0.3 huddle(n)