ddao-kwalify 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. data/CHANGES.txt +243 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.txt +61 -0
  4. data/bin/kwalify +13 -0
  5. data/contrib/inline-require +153 -0
  6. data/contrib/kwalify +4159 -0
  7. data/doc-api/classes/CommandOptionError.html +184 -0
  8. data/doc-api/classes/CommandOptionParser.html +325 -0
  9. data/doc-api/classes/Kwalify.html +292 -0
  10. data/doc-api/classes/Kwalify/AssertionError.html +148 -0
  11. data/doc-api/classes/Kwalify/BaseError.html +297 -0
  12. data/doc-api/classes/Kwalify/BaseParser.html +461 -0
  13. data/doc-api/classes/Kwalify/CommandOptionError.html +168 -0
  14. data/doc-api/classes/Kwalify/ErrorHelper.html +223 -0
  15. data/doc-api/classes/Kwalify/HashInterface.html +118 -0
  16. data/doc-api/classes/Kwalify/Json.html +105 -0
  17. data/doc-api/classes/Kwalify/KwalifyError.html +111 -0
  18. data/doc-api/classes/Kwalify/Main.html +339 -0
  19. data/doc-api/classes/Kwalify/MetaValidator.html +448 -0
  20. data/doc-api/classes/Kwalify/Parser.html +155 -0
  21. data/doc-api/classes/Kwalify/PlainYamlParser.html +523 -0
  22. data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +165 -0
  23. data/doc-api/classes/Kwalify/Rule.html +433 -0
  24. data/doc-api/classes/Kwalify/SchemaError.html +148 -0
  25. data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
  26. data/doc-api/classes/Kwalify/Types.html +302 -0
  27. data/doc-api/classes/Kwalify/Util.html +389 -0
  28. data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
  29. data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
  30. data/doc-api/classes/Kwalify/ValidationError.html +148 -0
  31. data/doc-api/classes/Kwalify/Validator.html +381 -0
  32. data/doc-api/classes/Kwalify/Yaml.html +194 -0
  33. data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
  34. data/doc-api/classes/Kwalify/YamlParser.html +542 -0
  35. data/doc-api/classes/Kwalify/YamlSyntaxError.html +119 -0
  36. data/doc-api/classes/Test.html +107 -0
  37. data/doc-api/classes/Test/Unit.html +101 -0
  38. data/doc-api/created.rid +1 -0
  39. data/doc-api/files/__/README_txt.html +172 -0
  40. data/doc-api/files/kwalify/errors_rb.html +114 -0
  41. data/doc-api/files/kwalify/main_rb.html +118 -0
  42. data/doc-api/files/kwalify/messages_rb.html +107 -0
  43. data/doc-api/files/kwalify/meta-validator_rb.html +117 -0
  44. data/doc-api/files/kwalify/parser/base_rb.html +116 -0
  45. data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
  46. data/doc-api/files/kwalify/rule_rb.html +116 -0
  47. data/doc-api/files/kwalify/types_rb.html +114 -0
  48. data/doc-api/files/kwalify/util/assert-text-equal_rb.html +115 -0
  49. data/doc-api/files/kwalify/util/hash-interface_rb.html +114 -0
  50. data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
  51. data/doc-api/files/kwalify/util/option-parser_rb.html +107 -0
  52. data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
  53. data/doc-api/files/kwalify/util/testcase-helper_rb.html +115 -0
  54. data/doc-api/files/kwalify/util_rb.html +107 -0
  55. data/doc-api/files/kwalify/validator_rb.html +117 -0
  56. data/doc-api/files/kwalify/yaml-parser_rb.html +117 -0
  57. data/doc-api/files/kwalify_rb.html +121 -0
  58. data/doc-api/fr_class_index.html +57 -0
  59. data/doc-api/fr_file_index.html +45 -0
  60. data/doc-api/fr_method_index.html +168 -0
  61. data/doc-api/index.html +24 -0
  62. data/doc-api/rdoc-style.css +208 -0
  63. data/doc/docstyle.css +188 -0
  64. data/doc/img/fig01.png +0 -0
  65. data/doc/users-guide.html +2050 -0
  66. data/examples/address-book/Makefile +10 -0
  67. data/examples/address-book/address-book.schema.yaml +45 -0
  68. data/examples/address-book/address-book.yaml +36 -0
  69. data/examples/data-binding/BABEL.data.yaml +63 -0
  70. data/examples/data-binding/BABEL.schema.yaml +31 -0
  71. data/examples/data-binding/Makefile +8 -0
  72. data/examples/data-binding/Rakefile +13 -0
  73. data/examples/data-binding/main.rb +27 -0
  74. data/examples/invoice/Makefile +9 -0
  75. data/examples/invoice/invoice.schema.yaml +43 -0
  76. data/examples/invoice/invoice.yaml +32 -0
  77. data/examples/tapkit/Makefile +10 -0
  78. data/examples/tapkit/main.rb +7 -0
  79. data/examples/tapkit/tapkit.schema.yaml +146 -0
  80. data/examples/tapkit/tapkit.yaml +85 -0
  81. data/lib/kwalify.rb +67 -0
  82. data/lib/kwalify/errors.rb +128 -0
  83. data/lib/kwalify/kwalify.schema.yaml +58 -0
  84. data/lib/kwalify/main.rb +442 -0
  85. data/lib/kwalify/messages.rb +173 -0
  86. data/lib/kwalify/meta-validator.rb +276 -0
  87. data/lib/kwalify/parser/base.rb +127 -0
  88. data/lib/kwalify/parser/yaml.rb +841 -0
  89. data/lib/kwalify/rule.rb +560 -0
  90. data/lib/kwalify/templates/genclass-java.eruby +222 -0
  91. data/lib/kwalify/templates/genclass-php.eruby +104 -0
  92. data/lib/kwalify/templates/genclass-ruby.eruby +113 -0
  93. data/lib/kwalify/types.rb +156 -0
  94. data/lib/kwalify/util.rb +157 -0
  95. data/lib/kwalify/util/assert-text-equal.rb +46 -0
  96. data/lib/kwalify/util/hash-interface.rb +18 -0
  97. data/lib/kwalify/util/hashlike.rb +51 -0
  98. data/lib/kwalify/util/option-parser.rb +220 -0
  99. data/lib/kwalify/util/ordered-hash.rb +57 -0
  100. data/lib/kwalify/util/testcase-helper.rb +112 -0
  101. data/lib/kwalify/validator.rb +282 -0
  102. data/lib/kwalify/yaml-parser.rb +870 -0
  103. data/setup.rb +1585 -0
  104. data/test/Rookbook.yaml +10 -0
  105. data/test/data/users-guide/AddressBook.java.expected +40 -0
  106. data/test/data/users-guide/BABEL.data.yaml +24 -0
  107. data/test/data/users-guide/BABEL.schema.yaml +30 -0
  108. data/test/data/users-guide/ExampleAddressBook.java +47 -0
  109. data/test/data/users-guide/Group.java.expected +24 -0
  110. data/test/data/users-guide/Person.java.expected +44 -0
  111. data/test/data/users-guide/address_book.rb +52 -0
  112. data/test/data/users-guide/address_book.schema.yaml +28 -0
  113. data/test/data/users-guide/address_book.yaml +27 -0
  114. data/test/data/users-guide/answers-schema.yaml +12 -0
  115. data/test/data/users-guide/answers-validator.rb +52 -0
  116. data/test/data/users-guide/babel_genclass.result +26 -0
  117. data/test/data/users-guide/config.schema.yaml +7 -0
  118. data/test/data/users-guide/config.yaml +4 -0
  119. data/test/data/users-guide/document01a.yaml +3 -0
  120. data/test/data/users-guide/document01b.yaml +3 -0
  121. data/test/data/users-guide/document02a.yaml +4 -0
  122. data/test/data/users-guide/document02b.yaml +4 -0
  123. data/test/data/users-guide/document03a.yaml +6 -0
  124. data/test/data/users-guide/document03b.yaml +6 -0
  125. data/test/data/users-guide/document04a.yaml +9 -0
  126. data/test/data/users-guide/document04b.yaml +9 -0
  127. data/test/data/users-guide/document05a.yaml +11 -0
  128. data/test/data/users-guide/document05b.yaml +12 -0
  129. data/test/data/users-guide/document06a.yaml +15 -0
  130. data/test/data/users-guide/document06b.yaml +16 -0
  131. data/test/data/users-guide/document07a.yaml +9 -0
  132. data/test/data/users-guide/document07b.yaml +7 -0
  133. data/test/data/users-guide/document12a.json +10 -0
  134. data/test/data/users-guide/document12b.json +6 -0
  135. data/test/data/users-guide/document13a.yaml +17 -0
  136. data/test/data/users-guide/document14a.yaml +3 -0
  137. data/test/data/users-guide/document14b.yaml +3 -0
  138. data/test/data/users-guide/document15a.yaml +6 -0
  139. data/test/data/users-guide/document15b.yaml +5 -0
  140. data/test/data/users-guide/example_address_book.rb +10 -0
  141. data/test/data/users-guide/example_address_book_java.result +32 -0
  142. data/test/data/users-guide/example_address_book_ruby.result +31 -0
  143. data/test/data/users-guide/genclass_java.result +4 -0
  144. data/test/data/users-guide/howto-validation-with-parsing.rb +28 -0
  145. data/test/data/users-guide/howto-validation.rb +25 -0
  146. data/test/data/users-guide/howto3.rb +6 -0
  147. data/test/data/users-guide/howto3.result +5 -0
  148. data/test/data/users-guide/howto3.yaml +8 -0
  149. data/test/data/users-guide/howto5_databinding.result +111 -0
  150. data/test/data/users-guide/invalid01.result +3 -0
  151. data/test/data/users-guide/invalid02.result +5 -0
  152. data/test/data/users-guide/invalid03.result +5 -0
  153. data/test/data/users-guide/invalid04.result +4 -0
  154. data/test/data/users-guide/invalid05.result +11 -0
  155. data/test/data/users-guide/invalid06.result +4 -0
  156. data/test/data/users-guide/invalid07.result +3 -0
  157. data/test/data/users-guide/invalid08.result +3 -0
  158. data/test/data/users-guide/invalid12.json +8 -0
  159. data/test/data/users-guide/invalid14.result +4 -0
  160. data/test/data/users-guide/invalid15.result +4 -0
  161. data/test/data/users-guide/loadbabel.rb +27 -0
  162. data/test/data/users-guide/loadconfig.rb +16 -0
  163. data/test/data/users-guide/loadconfig.result +6 -0
  164. data/test/data/users-guide/models.rb +22 -0
  165. data/test/data/users-guide/option_ha.result +6 -0
  166. data/test/data/users-guide/option_ha_genclass_java.result +7 -0
  167. data/test/data/users-guide/schema01.yaml +3 -0
  168. data/test/data/users-guide/schema02.yaml +12 -0
  169. data/test/data/users-guide/schema03.yaml +9 -0
  170. data/test/data/users-guide/schema04.yaml +20 -0
  171. data/test/data/users-guide/schema05.yaml +29 -0
  172. data/test/data/users-guide/schema06.yaml +11 -0
  173. data/test/data/users-guide/schema12.json +12 -0
  174. data/test/data/users-guide/schema13.yaml +13 -0
  175. data/test/data/users-guide/schema14.yaml +5 -0
  176. data/test/data/users-guide/schema15.yaml +21 -0
  177. data/test/data/users-guide/valid01.result +2 -0
  178. data/test/data/users-guide/valid02.result +2 -0
  179. data/test/data/users-guide/valid03.result +2 -0
  180. data/test/data/users-guide/valid04.result +2 -0
  181. data/test/data/users-guide/valid05.result +2 -0
  182. data/test/data/users-guide/valid06.result +2 -0
  183. data/test/data/users-guide/valid07.result +2 -0
  184. data/test/data/users-guide/valid08.result +2 -0
  185. data/test/data/users-guide/valid12.result +2 -0
  186. data/test/data/users-guide/valid13.result +2 -0
  187. data/test/data/users-guide/valid14.result +2 -0
  188. data/test/data/users-guide/valid15.result +2 -0
  189. data/test/data/users-guide/validate08.rb +37 -0
  190. data/test/test-action.rb +78 -0
  191. data/test/test-action.yaml +738 -0
  192. data/test/test-databinding.rb +83 -0
  193. data/test/test-databinding.yaml +339 -0
  194. data/test/test-main.rb +157 -0
  195. data/test/test-main.yaml +384 -0
  196. data/test/test-metavalidator.rb +80 -0
  197. data/test/test-metavalidator.yaml +1179 -0
  198. data/test/test-parser-yaml.rb +57 -0
  199. data/test/test-parser-yaml.yaml +1749 -0
  200. data/test/test-rule.rb +26 -0
  201. data/test/test-rule.yaml +317 -0
  202. data/test/test-users-guide.rb +75 -0
  203. data/test/test-validator.rb +95 -0
  204. data/test/test-validator.yaml +986 -0
  205. data/test/test-yaml-parser.rb +47 -0
  206. data/test/test-yaml-parser.yaml +1226 -0
  207. data/test/test.rb +60 -0
  208. metadata +261 -0
@@ -0,0 +1,188 @@
1
+ body {
2
+ background-color:#FFFFFF;
3
+ }
4
+
5
+ .mainbody {
6
+ color:#333333;
7
+ line-height:150%;
8
+ margin: 5px 30px 5px 30px;
9
+ }
10
+
11
+ a:link, a:active, a:hover {
12
+ color:#CC6600;
13
+ }
14
+
15
+ a:visited {
16
+ color:#DD9900;
17
+ }
18
+
19
+ p {
20
+ color:#333333;
21
+ line-height:150%;
22
+ }
23
+
24
+ pre {
25
+ width: 100%;
26
+ line-height:130%;
27
+ white-space:pre;
28
+ }
29
+
30
+ .program {
31
+ border-style:solid;
32
+ border-width:1px;
33
+ border-color:#6699FF;
34
+ color:#333333;
35
+ background-color:#DDEEFF;
36
+ padding:8px 9px 8px 9px;
37
+ margin:0px;
38
+ word-break:break-all;
39
+ }
40
+
41
+ .terminal {
42
+ border-style:solid;
43
+ border-width:1;
44
+ border-color:#999999;
45
+ color:#333333;
46
+ background-color:#E0E0E0;
47
+ padding:9px 10px 9px 10px;
48
+ margin:0px;
49
+ word-break:break-all;
50
+ }
51
+
52
+ .output {
53
+ border-style:solid;
54
+ border-width:1px;
55
+ border-color:#CCCCCC;
56
+ color:#333333;
57
+ background-color:#FFFFFF;
58
+ padding:8px 9px 8px 9px;
59
+ margin:0px;
60
+ word-break:break-all;
61
+ }
62
+
63
+
64
+ .program_caption {
65
+ margin-top: 20px;
66
+ }
67
+
68
+ .terminal_caption {
69
+ margin-top: 20px;
70
+ }
71
+
72
+ .output_caption {
73
+ margin-top: 20px;
74
+ }
75
+
76
+
77
+ ul,ol,dl {
78
+ /* margin:0px; */
79
+ /* padding:0px; */
80
+ color:#333333;
81
+ line-height:140%;
82
+ }
83
+
84
+ .dt2, .dt3 {
85
+ font-weight:bold;
86
+ }
87
+
88
+ .table1 {
89
+ padding:2px;
90
+ color:#333333;
91
+ background-color:#DDDDCC;
92
+ line-height:130%;
93
+ /*
94
+ border-width:1px;
95
+ border-style:solid;
96
+ border-color:#FFFFFF;
97
+ */
98
+ margin:5;
99
+ }
100
+
101
+ .th1, .th2 {
102
+ padding:1px;
103
+ color:#333333;
104
+ /* background-color:#DDDDCC; */
105
+ background-color:#CCCCBB;
106
+ line-height:130%;
107
+ }
108
+
109
+ .td1, .th2 {
110
+ padding:1px;
111
+ color:#333333;
112
+ background-color:#EEEEDD;
113
+ line-height:130%;
114
+ }
115
+
116
+ .caption1, .caption2 {
117
+ /* font-size:x-small; */
118
+ color:#333333;
119
+ }
120
+
121
+ .table2 {
122
+ padding:1px;
123
+ color:#333333;
124
+ background-color:#DDDDCC;
125
+ line-height:130%;
126
+ /*
127
+ border-width:1px;
128
+ border-style:solid;
129
+ border-color:#FFFFFF;
130
+ */
131
+ margin:5;
132
+ }
133
+
134
+ h1, .chapter, .doctitle {
135
+ color:#333333;
136
+ font-weight:bold;
137
+ padding:30px 0px 10px 0px;
138
+ }
139
+
140
+ h2, .section {
141
+ color:#333333;
142
+ font-weight:bold;
143
+ border-style:solid;
144
+ border-color:#6699FF;
145
+ border-width:0px 0px 2px 30px;
146
+ padding:10px 20px 0px 5px;
147
+ }
148
+
149
+ h3, .subsection {
150
+ color:#333333;
151
+ font-weight:bold;
152
+ border-style:solid;
153
+ border-color:#6699FF;
154
+ border-width: 0px 0px 0px 15px;
155
+ padding: 10px 20px 0px 5px;
156
+ }
157
+
158
+ .em {
159
+ font-weight:bold;
160
+ }
161
+
162
+ .toc {
163
+ /* font-size:small; */
164
+ /* line-height:100%; */
165
+ }
166
+
167
+ .footnote {
168
+ font-size:small;
169
+ }
170
+
171
+ .note {
172
+ background-color:#FFFFDD;
173
+ border-style:solid;
174
+ border-width:0px 1px 0px 1px;
175
+ border-color:#DDDD66;
176
+ color:#333300;
177
+ /* font-size:small; */
178
+ line-height:120%;
179
+ padding: 5px 20px 5px 20px;
180
+ }
181
+
182
+ .figure {
183
+ /*
184
+ border-width:1px;
185
+ border-color:#DDDD66;
186
+ white-space:pre;
187
+ */
188
+ }
Binary file
@@ -0,0 +1,2050 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html">
5
+ <title>Kwalify User's Guide (for Ruby)</title>
6
+ <meta name="author" content="makoto kuwata &lt;kwa(at)kuwata-lab.com&gt;">
7
+ <meta name="generator" content="kwaser">
8
+ <meta http-equiv="Content-Style-Type" content="text/css">
9
+ <link rel="stylesheet" href="docstyle.css" type="text/css">
10
+ </head>
11
+ <body>
12
+
13
+ <div class="mainbody">
14
+
15
+ <div align="left"><h1>Kwalify User's Guide (for Ruby)</h1></div>
16
+ <div align="left">
17
+ makoto kuwata &lt;kwa(at)kuwata-lab.com&gt;<br>
18
+ last update: $Date: 2008-01-28 15:27:12 +0900 (Mon, 28 Jan 2008) $<br>
19
+ </div>
20
+
21
+ <a name="preface"></a>
22
+ <h2 class="section1">Preface</h2>
23
+ <p>Kwalify<sup>(<a href="#fnref:1" name="fnlink:1">*1</a>)</sup> is a parser, schema validator, and data binding tool for YAML and JSON.
24
+ Kwalify enables you to handle YAML and JSON more easily and strictly.
25
+ </p>
26
+ <p>Topics:
27
+ </p>
28
+ <ul type="disc">
29
+ <li><a href="#schema">Schema validation for YAML</a> and <a href="#tips-json">JSON</a>
30
+ </li>
31
+ <li><a href="#actions">Class definition generation for Ruby, PHP, and Java</a>
32
+ </li>
33
+ <li><a href="#howto-databinding">Data binding</a>
34
+ </li>
35
+ <li><a href="#howto-preceding">Preceding alias</a>
36
+ </li>
37
+ </ul>
38
+ <div class="footnote">
39
+ <dl compact>
40
+ <dt>(<a name="fnref:1" href="#fnlink:1">*1</a>)</dt>
41
+ <dd>Pronounce as 'Qualify'.</dd>
42
+ </dl>
43
+ </div>
44
+ <a name="toc"></a>
45
+ <h3 class="section2">Table of Contents</h3>
46
+ <ul>
47
+ <li><a href="#preface">Preface</a>
48
+ <ul>
49
+ <li><a href="#toc">Table of Contents</a>
50
+ </li>
51
+ </ul>
52
+ </li>
53
+ <li><a href="#schema">Schema Definition</a>
54
+ <ul>
55
+ <li><a href="#schema-seq">Sequence</a>
56
+ </li>
57
+ <li><a href="#schema-map">Mapping</a>
58
+ </li>
59
+ <li><a href="#schema-seq-of-map">Sequence of Mapping</a>
60
+ </li>
61
+ <li><a href="#schema-map-of-seq">Mapping of Sequence</a>
62
+ </li>
63
+ <li><a href="#schema-rules">Rule and Constraint</a>
64
+ </li>
65
+ <li><a href="#schema-unique">Unique constraint</a>
66
+ </li>
67
+ </ul>
68
+ </li>
69
+ <li><a href="#tips">Tips</a>
70
+ <ul>
71
+ <li><a href="#tips-json">JSON</a>
72
+ </li>
73
+ <li><a href="#tips-anchor">Anchor and Alias</a>
74
+ </li>
75
+ <li><a href="#tips-default">Default of Mapping</a>
76
+ </li>
77
+ <li><a href="#tips-merge">Merging Mappings</a>
78
+ </li>
79
+ </ul>
80
+ </li>
81
+ <li><a href="#howto">How to in Ruby</a>
82
+ <ul>
83
+ <li><a href="#howot-validate">Validation</a>
84
+ </li>
85
+ <li><a href="#howto-parse">Parsing with Validation</a>
86
+ </li>
87
+ <li><a href="#howto-meta">Meta Validation</a>
88
+ </li>
89
+ <li><a href="#howto-hook">Validator#validator_hook()</a>
90
+ </li>
91
+ <li><a href="#howto-preceding">Preceding Alias</a>
92
+ </li>
93
+ <li><a href="#howto-databinding">Data Binding</a>
94
+ </li>
95
+ </ul>
96
+ </li>
97
+ <li><a href="#actions">Actions</a>
98
+ <ul>
99
+ <li><a href="#action-genclass">Class Definition Generation</a>
100
+ <ul>
101
+ <li><a href="#action-genclass-ruby">Ruby Class Definition</a>
102
+ </li>
103
+ <li><a href="#action-genclass-java">Java Class Definition</a>
104
+ </li>
105
+ </ul>
106
+ </li>
107
+ </ul>
108
+ </li>
109
+ <li><a href="#ref">References</a>
110
+ <ul>
111
+ <li><a href="#ref-usage">Usage in Command-Line</a>
112
+ </li>
113
+ </ul>
114
+ </li>
115
+ </ul>
116
+ <br>
117
+
118
+
119
+ <br>
120
+
121
+
122
+ <a name="schema"></a>
123
+ <h2 class="section1">Schema Definition</h2>
124
+ <p>This section describes how to define schema definition of YAML.
125
+ </p>
126
+ <a name="schema-seq"></a>
127
+ <h3 class="section2">Sequence</h3>
128
+ <a name="schema01.yaml"></a>
129
+ <div class="program_caption">
130
+ <code>schema01.yaml</code> : sequence of string</div>
131
+ <pre class="program">type: seq
132
+ sequence:
133
+ - type: str
134
+ </pre>
135
+ <a name="document01a.yaml"></a>
136
+ <div class="program_caption">
137
+ <code>document01a.yaml</code> : valid document example</div>
138
+ <pre class="program">- foo
139
+ - bar
140
+ - baz
141
+ </pre>
142
+ <a name="valid01.result"></a>
143
+ <div class="terminal_caption">
144
+ validate</div>
145
+ <pre class="terminal">$ kwalify -lf schema01.yaml document01a.yaml
146
+ document01a.yaml#0: valid.
147
+ </pre>
148
+ <a name="document01b.yaml"></a>
149
+ <div class="program_caption">
150
+ <code>document01b.yaml</code> : invalid document example</div>
151
+ <pre class="program">- foo
152
+ - 123
153
+ - baz
154
+ </pre>
155
+ <a name="invalid01.result"></a>
156
+ <div class="terminal_caption">
157
+ validate</div>
158
+ <pre class="terminal">$ kwalify -lf schema01.yaml document01b.yaml
159
+ document01b.yaml#0: INVALID
160
+ - (line 2) [/1] '123': not a string.
161
+ </pre>
162
+ <p>Default '<code>type:</code>' is <code>str</code> so you can omit '<code>type: str</code>'.
163
+ </p>
164
+ <br>
165
+
166
+
167
+ <a name="schema-map"></a>
168
+ <h3 class="section2">Mapping</h3>
169
+ <a name="schema02.yaml"></a>
170
+ <div class="program_caption">
171
+ <code>schema02.yaml</code> : mapping of scalar</div>
172
+ <pre class="program">type: map
173
+ mapping:
174
+ "name":
175
+ type: str
176
+ required: yes
177
+ "email":
178
+ type: str
179
+ pattern: /@/
180
+ "age":
181
+ type: int
182
+ "birth":
183
+ type: date
184
+ </pre>
185
+ <a name="document02a.yaml"></a>
186
+ <div class="program_caption">
187
+ <code>document02a.yaml</code> : valid document example</div>
188
+ <pre class="program">name: foo
189
+ email: foo@mail.com
190
+ age: 20
191
+ birth: 1985-01-01
192
+ </pre>
193
+ <a name="valid02.result"></a>
194
+ <div class="terminal_caption">
195
+ validate</div>
196
+ <pre class="terminal">$ kwalify -lf schema02.yaml document02a.yaml
197
+ document02a.yaml#0: valid.
198
+ </pre>
199
+ <a name="document02b.yaml"></a>
200
+ <div class="program_caption">
201
+ <code>document02b.yaml</code> : invalid document example</div>
202
+ <pre class="program">name: foo
203
+ email: foo(at)mail.com
204
+ age: twenty
205
+ birth: Jun 01, 1985
206
+ </pre>
207
+ <a name="invalid02.result"></a>
208
+ <div class="terminal_caption">
209
+ validate</div>
210
+ <pre class="terminal">$ kwalify -lf schema02.yaml document02b.yaml
211
+ document02b.yaml#0: INVALID
212
+ - (line 2) [/email] 'foo(at)mail.com': not matched to pattern /@/.
213
+ - (line 3) [/age] 'twenty': not a integer.
214
+ - (line 4) [/birth] 'Jun 01, 1985': not a date.
215
+ </pre>
216
+ <br>
217
+
218
+
219
+ <a name="schema-seq-of-map"></a>
220
+ <h3 class="section2">Sequence of Mapping</h3>
221
+ <a name="schema03.yaml"></a>
222
+ <div class="program_caption">
223
+ <code>schema03.yaml</code> : sequence of mapping</div>
224
+ <pre class="program">type: seq
225
+ sequence:
226
+ - type: map
227
+ mapping:
228
+ "name":
229
+ type: str
230
+ required: true
231
+ "email":
232
+ type: str
233
+ </pre>
234
+ <a name="document03a.yaml"></a>
235
+ <div class="program_caption">
236
+ <code>document03a.yaml</code> : valid document example</div>
237
+ <pre class="program">- name: foo
238
+ email: foo@mail.com
239
+ - name: bar
240
+ email: bar@mail.net
241
+ - name: baz
242
+ email: baz@mail.org
243
+ </pre>
244
+ <a name="valid03.result"></a>
245
+ <div class="terminal_caption">
246
+ validate</div>
247
+ <pre class="terminal">$ kwalify -lf schema03.yaml document03a.yaml
248
+ document03a.yaml#0: valid.
249
+ </pre>
250
+ <a name="document03b.yaml"></a>
251
+ <div class="program_caption">
252
+ <code>document03b.yaml</code> : invalid document example</div>
253
+ <pre class="program">- name: foo
254
+ email: foo@mail.com
255
+ - naem: bar
256
+ email: bar@mail.net
257
+ - name: baz
258
+ mail: baz@mail.org
259
+ </pre>
260
+ <a name="invalid03.result"></a>
261
+ <div class="terminal_caption">
262
+ validate</div>
263
+ <pre class="terminal">$ kwalify -lf schema03.yaml document03b.yaml
264
+ document03b.yaml#0: INVALID
265
+ - (line 3) [/1] key 'name:' is required.
266
+ - (line 3) [/1/naem] key 'naem:' is undefined.
267
+ - (line 6) [/2/mail] key 'mail:' is undefined.
268
+ </pre>
269
+ <br>
270
+
271
+
272
+ <a name="schema-map-of-seq"></a>
273
+ <h3 class="section2">Mapping of Sequence</h3>
274
+ <a name="schema04.yaml"></a>
275
+ <div class="program_caption">
276
+ <code>schema04.yaml</code> : mapping of sequence of mapping</div>
277
+ <pre class="program">type: map
278
+ mapping:
279
+ "company":
280
+ type: str
281
+ required: yes
282
+ "email":
283
+ type: str
284
+ "employees":
285
+ type: seq
286
+ sequence:
287
+ - type: map
288
+ mapping:
289
+ "code":
290
+ type: int
291
+ required: yes
292
+ "name":
293
+ type: str
294
+ required: yes
295
+ "email":
296
+ type: str
297
+ </pre>
298
+ <a name="document04a.yaml"></a>
299
+ <div class="program_caption">
300
+ <code>document04a.yaml</code> : valid document example</div>
301
+ <pre class="program">company: Kuwata lab.
302
+ email: webmaster@kuwata-lab.com
303
+ employees:
304
+ - code: 101
305
+ name: foo
306
+ email: foo@kuwata-lab.com
307
+ - code: 102
308
+ name: bar
309
+ email: bar@kuwata-lab.com
310
+ </pre>
311
+ <a name="valid04.result"></a>
312
+ <div class="terminal_caption">
313
+ validate</div>
314
+ <pre class="terminal">$ kwalify -lf schema04.yaml document04a.yaml
315
+ document04a.yaml#0: valid.
316
+ </pre>
317
+ <a name="document04b.yaml"></a>
318
+ <div class="program_caption">
319
+ <code>document04b.yaml</code> : invalid document example</div>
320
+ <pre class="program">company: Kuwata Lab.
321
+ email: webmaster@kuwata-lab.com
322
+ employees:
323
+ - code: A101
324
+ name: foo
325
+ email: foo@kuwata-lab.com
326
+ - code: 102
327
+ name: bar
328
+ mail: bar@kuwata-lab.com
329
+ </pre>
330
+ <a name="invalid04.result"></a>
331
+ <div class="terminal_caption">
332
+ validate</div>
333
+ <pre class="terminal">$ kwalify -lf schema04.yaml document04b.yaml
334
+ document04b.yaml#0: INVALID
335
+ - (line 4) [/employees/0/code] 'A101': not a integer.
336
+ - (line 9) [/employees/1/mail] key 'mail:' is undefined.
337
+ </pre>
338
+ <br>
339
+
340
+
341
+ <a name="schema-rules"></a>
342
+ <h3 class="section2">Rule and Constraint</h3>
343
+ <p><code>type:</code>, <code>required:</code>, <code>length</code>, ... are called <strong>constraint</strong> and set of constraints are called <strong>rule</strong>.
344
+ </p>
345
+ <ul type="disc">
346
+ <li>Rule contains 'type:' constraint. If 'type:' is omitted, 'type: str' is used as default.
347
+ </li>
348
+ <li>'sequence:' constraint takes a sequence of rule (the sequence can contain only a rule).
349
+ </li>
350
+ <li>'mapping:' constraint takes a mapping which values are rules.
351
+ </li>
352
+ </ul>
353
+ <div style="align:center;">
354
+ <img src="img/fig01.png" alt="constraints and rules of schema definition." />
355
+ </div>
356
+ <p>The following is a list of constraints.
357
+ </p>
358
+ <dl class="dl3">
359
+ <dt class="dt3"><strong>
360
+ <code>required:</code> </strong></dt>
361
+ <dd class="dd3">
362
+ Value is required when true (default is false).
363
+ This is similar to not-null constraint in RDBMS.
364
+ </dd>
365
+ <dt class="dt3"><strong>
366
+ <code>enum:</code> </strong></dt>
367
+ <dd class="dd3">
368
+ List of available values.
369
+ </dd>
370
+ <dt class="dt3"><strong>
371
+ <code>pattern:</code> </strong></dt>
372
+ <dd class="dd3">
373
+ Specifies regular expression pattern of value.
374
+ </dd>
375
+ <dt class="dt3"><strong>
376
+ <code>type:</code> </strong></dt>
377
+ <dd class="dd3">
378
+ Type of value. The followings are available:
379
+ <ul type="circle">
380
+ <li><code>str</code>
381
+ </li>
382
+ <li><code>int</code>
383
+ </li>
384
+ <li><code>float</code>
385
+ </li>
386
+ <li><code>number</code> (== int or float)
387
+ </li>
388
+ <li><code>text</code> (== str or number)
389
+ </li>
390
+ <li><code>bool</code>
391
+ </li>
392
+ <li><code>date</code>
393
+ </li>
394
+ <li><code>time</code>
395
+ </li>
396
+ <li><code>timestamp</code>
397
+ </li>
398
+ <li><code>seq</code>
399
+ </li>
400
+ <li><code>map</code>
401
+ </li>
402
+ <li><code>scalar</code> (all but seq and map)
403
+ </li>
404
+ <li><code>any</code> (means any data)
405
+ </li>
406
+ </ul>
407
+ </dd>
408
+ <dt class="dt3"><strong>
409
+ <code>range:</code> </strong></dt>
410
+ <dd class="dd3">
411
+ Range of value between max/max-ex and min/min-ex.
412
+ <ul type="circle">
413
+ <li>'max' means 'max-inclusive'.
414
+ </li>
415
+ <li>'min' means 'min-inclusive'.
416
+ </li>
417
+ <li>'max-ex' means 'max-exclusive'.
418
+ </li>
419
+ <li>'min-ex' means 'min-exclusive'.
420
+ </li>
421
+ </ul>
422
+ Type <code>seq</code>, <code>map</code>, <code>bool</code> and <code>any</code> are not available with <code>range:</code>.
423
+ </dd>
424
+ <dt class="dt3"><strong>
425
+ <code>length:</code> </strong></dt>
426
+ <dd class="dd3">
427
+ Range of length of value between max/max-ex and min/min-ex.
428
+ Only type <code>str</code> and <code>text</code> are available with <code>length:</code>.
429
+ </dd>
430
+ <dt class="dt3"><strong>
431
+ <code>assert:</code> </strong></dt>
432
+ <dd class="dd3">
433
+ String which represents validation expression.
434
+ String should contain variable name <code>val</code> which repsents value.
435
+ (This is an experimental function and not supported in Kwartz-java).
436
+ </dd>
437
+ <dt class="dt3"><strong>
438
+ <code>unique:</code> </strong></dt>
439
+ <dd class="dd3">
440
+ Value is unique for mapping or sequence.
441
+ This is similar to unique constraint of RDBMS.
442
+ See the next subsection for detail.
443
+ </dd>
444
+ <dt class="dt3"><strong>
445
+ <code>name:</code> </strong></dt>
446
+ <dd class="dd3">
447
+ Name of schema.
448
+ </dd>
449
+ <dt class="dt3"><strong>
450
+ <code>desc:</code> </strong></dt>
451
+ <dd class="dd3">
452
+ Description. This is not used for validation.
453
+ </dd>
454
+ <dt class="dt3"><strong>
455
+ <code>class:</code> </strong></dt>
456
+ <dd class="dd3">
457
+ Class name. This is for data-binding and is available only with type 'map'.
458
+ This is also used in 'genclass' action.
459
+ </dd>
460
+ <dt class="dt3"><strong>
461
+ <code>default:</code> </strong></dt>
462
+ <dd class="dd3">
463
+ Default value.
464
+ This is only for 'genclass' action, and have no effect to validation and parsing.
465
+ Default value should be scalar and it is not available if <code>type:</code> is <code>map</code> or <code>seq</code>, and also not available when <code>required:</code> is true.
466
+ </dd>
467
+ </dl>
468
+ <a name="schema05.yaml"></a>
469
+ <div class="program_caption">
470
+ <code>schema05.yaml</code> : rule examples</div>
471
+ <pre class="program">type: seq
472
+ sequence:
473
+ -
474
+ type: map
475
+ mapping:
476
+ "name":
477
+ type: str
478
+ required: yes
479
+ "email":
480
+ type: str
481
+ required: yes
482
+ pattern: /@/
483
+ "password":
484
+ type: text
485
+ length: { max: 16, min: 8 }
486
+ "age":
487
+ type: int
488
+ range: { max: 30, min: 18 }
489
+ # or assert: 18 &lt;= val &amp;&amp; val &lt;= 30
490
+ "blood":
491
+ type: str
492
+ enum: [A, B, O, AB]
493
+ "birth":
494
+ type: date
495
+ "memo":
496
+ type: any
497
+ "deleted":
498
+ type: bool
499
+ default: false
500
+ </pre>
501
+ <a name="document05a.yaml"></a>
502
+ <div class="program_caption">
503
+ <code>document05a.yaml</code> : valid document example</div>
504
+ <pre class="program">- name: foo
505
+ email: foo@mail.com
506
+ password: xxx123456
507
+ age: 20
508
+ blood: A
509
+ birth: 1985-01-01
510
+ - name: bar
511
+ email: bar@mail.net
512
+ age: 25
513
+ blood: AB
514
+ birth: 1980-01-01
515
+ </pre>
516
+ <a name="valid05.result"></a>
517
+ <div class="terminal_caption">
518
+ validate</div>
519
+ <pre class="terminal">$ kwalify -lf schema05.yaml document05a.yaml
520
+ document05a.yaml#0: valid.
521
+ </pre>
522
+ <a name="document05b.yaml"></a>
523
+ <div class="program_caption">
524
+ <code>document05b.yaml</code> : invalid document example</div>
525
+ <pre class="program">- name: foo
526
+ email: foo(at)mail.com
527
+ password: xxx123
528
+ age: twenty
529
+ blood: a
530
+ birth: 1985-01-01
531
+ - given-name: bar
532
+ family-name: Bar
533
+ email: bar@mail.net
534
+ age: 15
535
+ blood: AB
536
+ birth: 1980/01/01
537
+ </pre>
538
+ <a name="invalid05.result"></a>
539
+ <div class="terminal_caption">
540
+ validate</div>
541
+ <pre class="terminal">$ kwalify -lf schema05.yaml document05b.yaml
542
+ document05b.yaml#0: INVALID
543
+ - (line 2) [/0/email] 'foo(at)mail.com': not matched to pattern /@/.
544
+ - (line 3) [/0/password] 'xxx123': too short (length 6 &lt; min 8).
545
+ - (line 4) [/0/age] 'twenty': not a integer.
546
+ - (line 5) [/0/blood] 'a': invalid blood value.
547
+ - (line 7) [/1] key 'name:' is required.
548
+ - (line 7) [/1/given-name] key 'given-name:' is undefined.
549
+ - (line 8) [/1/family-name] key 'family-name:' is undefined.
550
+ - (line 10) [/1/age] '15': too small (&lt; min 18).
551
+ - (line 12) [/1/birth] '1980/01/01': not a date.
552
+ </pre>
553
+ <br>
554
+
555
+
556
+ <a name="schema-unique"></a>
557
+ <h3 class="section2">Unique constraint</h3>
558
+ <p>'<code>unique:</code>' constraint is available with elements of sequence or mapping.
559
+ This is equivalent to unique constraint of RDBMS.
560
+ </p>
561
+ <ul type="disc">
562
+ <li>Type of rule which has '<code>unique:</code>' entry must be scalar (str, int, float, ...).
563
+ </li>
564
+ <li>Type of parent rule must be sequence or mapping.
565
+ </li>
566
+ </ul>
567
+ <a name="schema06.yaml"></a>
568
+ <div class="program_caption">
569
+ <code>schema06.yaml</code> : unique constraint entry with mapping and sequence</div>
570
+ <pre class="program">type: seq
571
+ sequence:
572
+ - type: map
573
+ required: yes
574
+ mapping:
575
+ "name": { type: str, required: yes, <strong>unique: yes</strong> }
576
+ "email": { type: str }
577
+ "groups":
578
+ type: seq
579
+ sequence:
580
+ - { type: str, <strong>unique: yes</strong> }
581
+ </pre>
582
+ <a name="document06a.yaml"></a>
583
+ <div class="program_caption">
584
+ <code>document06a.yaml</code> : valid document example</div>
585
+ <pre class="program">- name: foo
586
+ email: admin@mail.com
587
+ groups:
588
+ - users
589
+ - foo
590
+ - admin
591
+ - name: bar
592
+ email: admin@mail.com
593
+ groups:
594
+ - users
595
+ - admin
596
+ - name: baz
597
+ email: baz@mail.com
598
+ groups:
599
+ - users
600
+ </pre>
601
+ <a name="valid06.result"></a>
602
+ <div class="terminal_caption">
603
+ validate</div>
604
+ <pre class="terminal">$ kwalify -lf schema06.yaml document06a.yaml
605
+ document06a.yaml#0: valid.
606
+ </pre>
607
+ <a name="document06b.yaml"></a>
608
+ <div class="program_caption">
609
+ <code>document06b.yaml</code> : invalid document example</div>
610
+ <pre class="program">- name: foo
611
+ email: admin@mail.com
612
+ groups:
613
+ - foo
614
+ - users
615
+ - admin
616
+ - foo
617
+ - name: bar
618
+ email: admin@mail.com
619
+ groups:
620
+ - admin
621
+ - users
622
+ - name: bar
623
+ email: baz@mail.com
624
+ groups:
625
+ - users
626
+ </pre>
627
+ <a name="invalid06.result"></a>
628
+ <div class="terminal_caption">
629
+ validate</div>
630
+ <pre class="terminal">$ kwalify -lf schema06.yaml document06b.yaml
631
+ document06b.yaml#0: INVALID
632
+ - (line 7) [/0/groups/3] 'foo': is already used at '/0/groups/0'.
633
+ - (line 13) [/2/name] 'bar': is already used at '/1/name'.
634
+ </pre>
635
+ <br>
636
+
637
+
638
+ <br>
639
+
640
+
641
+ <a name="tips"></a>
642
+ <h2 class="section1">Tips</h2>
643
+ <a name="tips-json"></a>
644
+ <h3 class="section2">JSON</h3>
645
+ <p><a href="http://www.json.org">JSON</a> is a lightweight data-interchange format, especially useful for JavaScript.
646
+ JSON can be considered as a subset of YAML. It means that YAML parser can parse JSON and Kwalify can validate JSON document.
647
+ </p>
648
+ <a name="schema12.json"></a>
649
+ <div class="program_caption">
650
+ <code>schema12.json</code> : an example schema definition written in JSON format</div>
651
+ <pre class="program">{ "type": "map",
652
+ "required": true,
653
+ "mapping": {
654
+ "name": { "type": "str", "required": true },
655
+ "email": { "type": "str" },
656
+ "age": { "type": "int" },
657
+ "gender": { "type": "str", "enum": ["M", "F"] },
658
+ "favorite": { "type": "seq",
659
+ "sequence": [ { "type": "str" } ]
660
+ }
661
+ }
662
+ }
663
+ </pre>
664
+ <a name="document12a.json"></a>
665
+ <div class="program_caption">
666
+ <code>document12a.json</code> : valid JSON document example</div>
667
+ <pre class="program">{ "name": "Foo",
668
+ "email": "foo@mail.com",
669
+ "age": 20,
670
+ "gender": "F",
671
+ "favorite": [
672
+ "football",
673
+ "basketball",
674
+ "baseball"
675
+ ]
676
+ }
677
+ </pre>
678
+ <a name="valid12.result"></a>
679
+ <div class="terminal_caption">
680
+ validate</div>
681
+ <pre class="terminal">$ kwalify -lf schema12.json document12a.json
682
+ document12a.json#0: valid.
683
+ </pre>
684
+ <a name="document12b.json"></a>
685
+ <div class="program_caption">
686
+ <code>document12b.json</code> : invalid JSON document example</div>
687
+ <pre class="program">{
688
+ "mail": "foo@mail.com",
689
+ "age": twenty,
690
+ "gender": "X",
691
+ "favorite": [ 123, 456 ]
692
+ }
693
+ </pre>
694
+ <a name="invalid12.json"></a>
695
+ <div class="terminal_caption">
696
+ validate</div>
697
+ <pre class="terminal">$ kwalify -lf schema12.json document12b.json
698
+ document12b.json#0: INVALID
699
+ - (line 1) [/] key 'name:' is required.
700
+ - (line 2) [/mail] key 'mail:' is undefined.
701
+ - (line 3) [/age] 'twenty': not a integer.
702
+ - (line 4) [/gender] 'X': invalid gender value.
703
+ - (line 5) [/favorite/0] '123': not a string.
704
+ - (line 5) [/favorite/1] '456': not a string.
705
+ </pre>
706
+ <br>
707
+
708
+
709
+ <a name="tips-anchor"></a>
710
+ <h3 class="section2">Anchor and Alias</h3>
711
+ <p>You can share rules by YAML anchor and alias.
712
+ </p>
713
+ <a name="schema13.yaml"></a>
714
+ <div class="program_caption">
715
+ <code>schema13.yaml</code> : anchor example</div>
716
+ <pre class="program">type: seq
717
+ sequence:
718
+ - <strong>&amp;employee</strong>
719
+ type: map
720
+ mapping:
721
+ "given-name": <strong>&amp;name</strong>
722
+ type: str
723
+ required: yes
724
+ "family-name": <strong>*name</strong>
725
+ "post":
726
+ type: str
727
+ enum: [exective, manager, clerk]
728
+ "supervisor": <strong>*employee</strong>
729
+ </pre>
730
+ <p>Anchor and alias is also available in YAML document.
731
+ </p>
732
+ <a name="document13a.yaml"></a>
733
+ <div class="program_caption">
734
+ <code>document13a.yaml</code> : valid document example</div>
735
+ <pre class="program">- <strong>&amp;foo</strong>
736
+ given-name: foo
737
+ family-name: Foo
738
+ post: exective
739
+ - <strong>&amp;bar</strong>
740
+ given-name: bar
741
+ family-name: Bar
742
+ post: manager
743
+ supervisor: <strong>*foo</strong>
744
+ - given-name: baz
745
+ family-name: Baz
746
+ post: clerk
747
+ supervisor: <strong>*bar</strong>
748
+ - given-name: zak
749
+ family-name: Zak
750
+ post: clerk
751
+ supervisor: <strong>*bar</strong>
752
+ </pre>
753
+ <a name="valid13.result"></a>
754
+ <div class="terminal_caption">
755
+ validate</div>
756
+ <pre class="terminal">$ kwalify -lf schema13.yaml document13a.yaml
757
+ document13a.yaml#0: valid.
758
+ </pre>
759
+ <br>
760
+
761
+
762
+ <a name="tips-default"></a>
763
+ <h3 class="section2">Default of Mapping</h3>
764
+ <p>YAML allows user to specify default value of mapping.
765
+ </p>
766
+ <p>For example, the following YAML document uses default value of mapping.
767
+ </p>
768
+ <pre class="program">A: 10
769
+ B: 20
770
+ <strong>=: -1</strong> # default value
771
+ </pre>
772
+ <p>This is equal to the following Ruby code.
773
+ </p>
774
+ <pre class="program">map = ["A"=&gt;10, "B"=&gt;20]
775
+ map.default = -1
776
+ map
777
+ </pre>
778
+ <p>Kwalify allows user to specify default rule using default value of mapping.
779
+ It is useful when key names are unknown.
780
+ </p>
781
+ <a name="schema14.yaml"></a>
782
+ <div class="program_caption">
783
+ <code>schema14.yaml</code> : default rule example</div>
784
+ <pre class="program">type: map
785
+ mapping:
786
+ <strong>=:</strong> # default rule
787
+ type: number
788
+ range: { max: 1, min: -1 }
789
+ </pre>
790
+ <a name="document14a.yaml"></a>
791
+ <div class="program_caption">
792
+ <code>document14a.yaml</code> : valid document example</div>
793
+ <pre class="program">value1: 0
794
+ value2: 0.5
795
+ value3: -0.9
796
+ </pre>
797
+ <a name="valid14.result"></a>
798
+ <div class="terminal_caption">
799
+ validate</div>
800
+ <pre class="terminal">$ kwalify -lf schema14.yaml document14a.yaml
801
+ document14a.yaml#0: valid.
802
+ </pre>
803
+ <a name="document14b.yaml"></a>
804
+ <div class="program_caption">
805
+ <code>document14b.yaml</code> : invalid document example</div>
806
+ <pre class="program">value1: 0
807
+ value2: 1.1
808
+ value3: -2.0
809
+ </pre>
810
+ <a name="invalid14.result"></a>
811
+ <div class="terminal_caption">
812
+ validate</div>
813
+ <pre class="terminal">$ kwalify -lf schema14.yaml document14b.yaml
814
+ document14b.yaml#0: INVALID
815
+ - (line 2) [/value2] '1.1': too large (&gt; max 1).
816
+ - (line 3) [/value3] '-2.0': too small (&lt; min -1).
817
+ </pre>
818
+ <br>
819
+
820
+
821
+ <a name="tips-merge"></a>
822
+ <h3 class="section2">Merging Mappings</h3>
823
+ <p>YAML allows user to merge mappings.
824
+ </p>
825
+ <pre class="program">- <strong>&amp;a1</strong>
826
+ A: 10
827
+ B: 20
828
+ - <strong>&lt;&lt;: *a1</strong> # merge
829
+ A: 15 # override
830
+ C: 30 # add
831
+ </pre>
832
+ <p>This is equal to the following Ruby code.
833
+ </p>
834
+ <pre class="program">a1 = {"A"=&gt;10, "B"=&gt;20}
835
+ tmp = {}
836
+ tmp.update(a1) # merge
837
+ tmp["A"] = 15 # override
838
+ tmp["C"] = 30 # add
839
+ </pre>
840
+ <p>This feature allows Kwalify to merge rule entries.
841
+ </p>
842
+ <a name="schema15.yaml"></a>
843
+ <div class="program_caption">
844
+ <code>schema15.yaml</code> : merging rule entries example</div>
845
+ <pre class="program">type: map
846
+ mapping:
847
+ "group":
848
+ type: map
849
+ mapping:
850
+ "name": <strong>&amp;name</strong>
851
+ type: str
852
+ required: yes
853
+ "email": <strong>&amp;email</strong>
854
+ type: str
855
+ pattern: /@/
856
+ required: no
857
+ "user":
858
+ type: map
859
+ mapping:
860
+ "name":
861
+ <strong>&lt;&lt;: *name</strong> # merge
862
+ <strong>length: { max: 16 }</strong> # add
863
+ "email":
864
+ <strong>&lt;&lt;: *email</strong> # merge
865
+ <strong>required: yes</strong> # override
866
+ </pre>
867
+ <a name="document15a.yaml"></a>
868
+ <div class="program_caption">
869
+ <code>document15a.yaml</code> : valid document example</div>
870
+ <pre class="program">group:
871
+ name: foo
872
+ email: foo@mail.com
873
+ user:
874
+ name: bar
875
+ email: bar@mail.com
876
+ </pre>
877
+ <a name="valid15.result"></a>
878
+ <div class="terminal_caption">
879
+ validate</div>
880
+ <pre class="terminal">$ kwalify -lf schema15.yaml document15a.yaml
881
+ document15a.yaml#0: valid.
882
+ </pre>
883
+ <a name="document15b.yaml"></a>
884
+ <div class="program_caption">
885
+ <code>document15b.yaml</code> : invalid document example</div>
886
+ <pre class="program">group:
887
+ name: foo
888
+ email: foo@mail.com
889
+ user:
890
+ name: toooooo-looooong-name
891
+ </pre>
892
+ <a name="invalid15.result"></a>
893
+ <div class="terminal_caption">
894
+ validate</div>
895
+ <pre class="terminal">$ kwalify -lf schema15.yaml document15b.yaml
896
+ document15b.yaml#0: INVALID
897
+ - (line 5) [/user] key 'email:' is required.
898
+ - (line 5) [/user/name] 'toooooo-looooong-name': too long (length 21 &gt; max 16).
899
+ </pre>
900
+ <br>
901
+
902
+
903
+ <br>
904
+
905
+
906
+ <a name="howto"></a>
907
+ <h2 class="section1">How to in Ruby</h2>
908
+ <p>This section describes how to use Kwalify in Ruby.
909
+ </p>
910
+ <a name="howot-validate"></a>
911
+ <h3 class="section2">Validation</h3>
912
+ <a name="howto-validation.rb"></a>
913
+ <pre class="program">require 'kwalify'
914
+ #require 'yaml'
915
+
916
+ ## load schema data
917
+ schema = Kwalify::Yaml.load_file('schema.yaml')
918
+ ## or
919
+ #schema = YAML.load_file('schema.yaml')
920
+
921
+ ## create validator
922
+ validator = Kwalify::Validator.new(schema)
923
+
924
+ ## load document
925
+ document = Kwalify::Yaml.load_file('document.yaml')
926
+ ## or
927
+ #document = YAML.load_file('document.yaml')
928
+
929
+ ## validate
930
+ errors = validator.validate(document)
931
+
932
+ ## show errors
933
+ if errors &amp;&amp; !errors.empty?
934
+ for e in errors
935
+ puts "[#{e.path}] #{e.message}"
936
+ end
937
+ end
938
+ </pre>
939
+ <br>
940
+
941
+
942
+ <a name="howto-parse"></a>
943
+ <h3 class="section2">Parsing with Validation</h3>
944
+ <p>From version 0.7, Kwalify supports parsing with validation.
945
+ </p>
946
+ <a name="howto-validation-with-parsing.rb"></a>
947
+ <pre class="program">require 'kwalify'
948
+ #require 'yaml'
949
+
950
+ ## load schema data
951
+ schema = Kwalify::Yaml.load_file('schema.yaml')
952
+ ## or
953
+ #schema = YAML.load_file('schema.yaml')
954
+
955
+ ## create validator
956
+ validator = Kwalify::Validator.new(schema)
957
+
958
+ ## create parser with validator
959
+ ## (if validator is ommitted, no validation executed.)
960
+ parser = Kwalify:::Yaml::Parser.new(validator)
961
+
962
+ ## parse document with validation
963
+ filename = 'document.yaml'
964
+ document = parser.parse_file(filename)
965
+ ## or
966
+ #document = parser.parse(File.read(filename), filename)
967
+
968
+ ## show errors if exist
969
+ errors = parser.errors()
970
+ if errors &amp;&amp; !errors.empty?
971
+ for e in errors
972
+ puts "#{e.linenum}:#{e.column} [#{e.path}] #{e.message}"
973
+ end
974
+ end
975
+ </pre>
976
+ <br>
977
+
978
+
979
+ <a name="howto-meta"></a>
980
+ <h3 class="section2">Meta Validation</h3>
981
+ <p>Meta validator is a validator which validates schema definition.
982
+ The schema definition is placed at 'kwalify/kwalify.schema.yaml'.
983
+ </p>
984
+ <p>Kwalify also provides Kwalify::MetaValidator class which validates
985
+ schema defition.
986
+ </p>
987
+ <pre class="program">require 'kwalify'
988
+
989
+ ## meta validator
990
+ metavalidator = Kwalify::MetaValidator.instance
991
+
992
+ ## validate schema definition
993
+ parser = Kwalify::Yaml::Parser.new(metavalidator)
994
+ errors = parser.parse_file('schema.yaml')
995
+ for e in errors
996
+ puts "#{e.linenum}:#{e.column} [#{e.path}] #{e.message}"
997
+ end if errors &amp;&amp; !errors.empty?
998
+ </pre>
999
+ <p>Meta validation is also available with command-line option '-m'.
1000
+ </p>
1001
+ <pre class="terminal">$ kwalify -m schema1.yaml schema2.yaml ...
1002
+ </pre>
1003
+ <br>
1004
+
1005
+
1006
+ <a name="howto-hook"></a>
1007
+ <h3 class="section2">Validator#validator_hook()</h3>
1008
+ <p>You can extend Kwalify::Validator and override Kwalify::Validator#validator_hook() method.
1009
+ This method is called by Kwalify::Validator#validate().
1010
+ </p>
1011
+ <a name="answers-schema.yaml"></a>
1012
+ <div class="program_caption">
1013
+ answers-schema.yaml : 'name:' is important.</div>
1014
+ <pre class="program">type: map
1015
+ mapping:
1016
+ "answers":
1017
+ type: seq
1018
+ sequence:
1019
+ - type: map
1020
+ <strong>name: Answer</strong>
1021
+ mapping:
1022
+ "name": { type: str, required: yes }
1023
+ "answer": { type: str, required: yes,
1024
+ enum: [good, not bad, bad] }
1025
+ "reason": { type: str }
1026
+ </pre>
1027
+ <a name="answers-validator.rb"></a>
1028
+ <div class="program_caption">
1029
+ answers-validator.rb : validate script for Ruby</div>
1030
+ <pre class="program">#!/usr/bin/env ruby
1031
+
1032
+ require 'kwalify'
1033
+
1034
+ ## validator class for answers
1035
+ class AnswersValidator &lt; Kwalify::Validator
1036
+
1037
+ ## load schema definition
1038
+ @@schema = Kwalify::Yaml.load_file('answers-schema.yaml')
1039
+ ## or
1040
+ ## require 'yaml'
1041
+ ## @@schema = YAML.load_file('answers-schema.yaml')
1042
+
1043
+ def initialize()
1044
+ super(@@schema)
1045
+ end
1046
+
1047
+ ## hook method called by Validator#validate()
1048
+ <strong>def validate_hook(value, rule, path, errors)</strong>
1049
+ <strong>case rule.name</strong>
1050
+ <strong>when 'Answer'</strong>
1051
+ if value['answer'] == 'bad'
1052
+ reason = value['reason']
1053
+ if !reason || reason.empty?
1054
+ msg = "reason is required when answer is 'bad'."
1055
+ errors &lt;&lt; Kwalify::ValidationError.new(msg, path)
1056
+ end
1057
+ end
1058
+ end
1059
+ end
1060
+
1061
+ end
1062
+
1063
+ ## create validator
1064
+ validator = AnswersValidator.new
1065
+
1066
+ ## parse and validate YAML document
1067
+ input = ARGF.read()
1068
+ parser = Kwalify::Yaml::Parser.new(validator)
1069
+ document = parser.parse(input)
1070
+
1071
+ ## show errors
1072
+ errors = parser.errors()
1073
+ if !errors || errors.empty?
1074
+ puts "Valid."
1075
+ else
1076
+ puts "*** INVALID!"
1077
+ for e in errors
1078
+ # e.class == Kwalify::ValidationError
1079
+ puts "#{e.linenum}:#{e.column} [#{e.path}] #{e.message}"
1080
+ end
1081
+ end
1082
+ </pre>
1083
+ <a name="document07a.yaml"></a>
1084
+ <div class="program_caption">
1085
+ <code>document07a.yaml</code> : valid document example</div>
1086
+ <pre class="program">answers:
1087
+ - name: Foo
1088
+ answer: good
1089
+ reason: I like this style.
1090
+ - name: Bar
1091
+ answer: not bad
1092
+ - name: Baz
1093
+ answer: bad
1094
+ reason: I don't like this style.
1095
+ </pre>
1096
+ <a name="valid07.result"></a>
1097
+ <div class="terminal_caption">
1098
+ validate</div>
1099
+ <pre class="terminal">$ ruby answers-validator.rb document07a.yaml
1100
+ Valid.
1101
+ </pre>
1102
+ <a name="document07b.yaml"></a>
1103
+ <div class="program_caption">
1104
+ <code>document07b.yaml</code> : invalid document example</div>
1105
+ <pre class="program">answers:
1106
+ - name: Foo
1107
+ answer: good
1108
+ - name: Bar
1109
+ answer: bad
1110
+ - name: Baz
1111
+ answer: not bad
1112
+ </pre>
1113
+ <a name="invalid07.result"></a>
1114
+ <div class="terminal_caption">
1115
+ validate</div>
1116
+ <pre class="terminal">$ ruby answers-validator.rb document07b.yaml
1117
+ *** INVALID!
1118
+ 4:3 [/answers/1] reason is required when answer is 'bad'.
1119
+ </pre>
1120
+ <p>You can validate some document by a Validator instance because Validator class and Validator#validate() method are stateless. If you use instance variables in custom validator_hook() method, it becomes to be stateful.
1121
+ </p>
1122
+ <br>
1123
+
1124
+
1125
+ <a name="howto-preceding"></a>
1126
+ <h3 class="section2">Preceding Alias</h3>
1127
+ <p>From version 0.7, Kwalify allows aliases to appear before corresponding anchors are now appeared.
1128
+ These aliases are called as 'preceding alias'.
1129
+ </p>
1130
+ <a name="howto3.yaml"></a>
1131
+ <div class="program_caption">
1132
+ howto3.yaml</div>
1133
+ <pre class="program">- name: Foo
1134
+ parent: *bar # preceding alias
1135
+ - &amp;bar
1136
+ name: Bar
1137
+ parent: *baz # preceding alias
1138
+ - &amp;baz
1139
+ name: Baz
1140
+ parent: null
1141
+ </pre>
1142
+ <p>To enable preceding alias, set Kwalify::Yaml::Parser#preceding_alias to true.
1143
+ </p>
1144
+ <a name="howto3.rb"></a>
1145
+ <div class="program_caption">
1146
+ howto3.rb</div>
1147
+ <pre class="program">require 'kwalify'
1148
+ parser = Kwalify::Yaml::Parser.new
1149
+ <strong>parser.preceding_alias = true</strong> # enable preceding alias
1150
+ ydoc = parser.parse_file('howto3.yaml')
1151
+ require 'pp'
1152
+ pp ydoc
1153
+ </pre>
1154
+ <a name="howto3.result"></a>
1155
+ <div class="terminal_caption">
1156
+ result</div>
1157
+ <pre class="terminal">$ ruby howto3.rb
1158
+ [{"name"=&gt;"Foo",
1159
+ "parent"=&gt;{"name"=&gt;"Bar", "parent"=&gt;{"name"=&gt;"Baz", "parent"=&gt;nil}}},
1160
+ {"name"=&gt;"Bar", "parent"=&gt;{"name"=&gt;"Baz", "parent"=&gt;nil}},
1161
+ {"name"=&gt;"Baz", "parent"=&gt;nil}]
1162
+ </pre>
1163
+ <p>Command-line option '-P' also enables preceding alias.
1164
+ </p>
1165
+ <p>Preceding alias is very useful when document is complex.
1166
+ </p>
1167
+ <br>
1168
+
1169
+
1170
+ <a name="howto-databinding"></a>
1171
+ <h3 class="section2">Data Binding</h3>
1172
+ <p>From version 0.7, Kwalify supports data binding.
1173
+ * To enable data binding, set Kwlaify::Yaml::Parser#data_binding to true.
1174
+ * It is required to specify class name in schema definition.
1175
+ (Notice that 'class:' constraint is avaialbe only with rule which type is 'map'.)
1176
+ * Also instance methods '[]', '[]=', and 'keys?' must be defined in the classes.
1177
+ (Including Kwalify::Util::HashLike modules is easy way to define them.)
1178
+ </p>
1179
+ <a name="config.schema.yaml"></a>
1180
+ <div class="program_caption">
1181
+ config.schema.yaml: schema definition file</div>
1182
+ <pre class="program">type: map
1183
+ <strong>class: Config</strong>
1184
+ mapping:
1185
+ "host": { type: str, required: true }
1186
+ "port": { type: int }
1187
+ "user": { type: str, required: true }
1188
+ "pass": { type: str, required: true }
1189
+ </pre>
1190
+ <a name="config.yaml"></a>
1191
+ <div class="program_caption">
1192
+ config.yaml: data file</div>
1193
+ <pre class="program">host: localhost
1194
+ port: 8080
1195
+ user: user1
1196
+ pass: password1
1197
+ </pre>
1198
+ <a name="loadconfig.rb"></a>
1199
+ <div class="program_caption">
1200
+ loadconfig.rb: ruby program</div>
1201
+ <pre class="program">## class definition
1202
+ require 'kwalify/util/hashlike'
1203
+ <strong>class Config</strong>
1204
+ <strong>include Kwalify::Util::HashLike</strong> # defines [], []=, and keys?
1205
+ attr_accessor :host, :posrt, :user, :pass
1206
+ <strong>end</strong>
1207
+ ## create validator object
1208
+ require 'kwalify'
1209
+ schema = Kwalify::Yaml.load_file('config.schema.yaml')
1210
+ validator = Kwalify::Validator.new(schema)
1211
+ ## parse configuration file with data binding
1212
+ parser = Kwalify::Yaml::Parser.new(validator)
1213
+ <strong>parser.data_binding = true</strong> # enable data binding
1214
+ config = parser.parse_file('config.yaml')
1215
+ require 'pp'
1216
+ pp config
1217
+ </pre>
1218
+ <a name="loadconfig.result"></a>
1219
+ <div class="terminal_caption">
1220
+ result</div>
1221
+ <pre class="terminal">$ ruby loadconfig.rb
1222
+ #&lt;Config:
1223
+ @host="localhost",
1224
+ @pass="password1",
1225
+ @port=8080,
1226
+ @user="user1"&gt;
1227
+ </pre>
1228
+ <p>Data binding is available even when data is more complex.
1229
+ Preceding alias is also available.
1230
+ </p>
1231
+ <p>For example, the following data is complex because it uses anchor and alias (including preceding alias).
1232
+ </p>
1233
+ <a name="BABEL.data.yaml"></a>
1234
+ <div class="program_caption">
1235
+ BABEL.data.yaml</div>
1236
+ <pre class="program">teams:
1237
+ - &amp;thechildren
1238
+ name: The Children
1239
+ desc: Level 7 ESPers
1240
+ chief: *minamoto # preceding alias
1241
+ members: [*kaoru, *aoi, *shiho] # preceding aliases
1242
+
1243
+ members:
1244
+ - &amp;minamoto
1245
+ name: Kohichi Minamoto
1246
+ desc: Scientist
1247
+ team: *thechildren
1248
+ - &amp;kaoru
1249
+ name: Kaoru Akashi
1250
+ desc: Psychokino
1251
+ team: *thechildren
1252
+ - &amp;aoi
1253
+ name: Aoi Nogami
1254
+ desc: Teleporter
1255
+ team: *thechildren
1256
+ - &amp;shiho
1257
+ name: Shiho Sannomiya
1258
+ desc: Psycometrer
1259
+ team: *thechildren
1260
+ </pre>
1261
+ <p>Here is the schema definition.
1262
+ (Notice that 'class:' constraint is avaialbe only with rule which type is 'map'.)
1263
+ </p>
1264
+ <a name="BABEL.schema.yaml"></a>
1265
+ <div class="program_caption">
1266
+ BABEL.schema.yaml</div>
1267
+ <pre class="program">type: map
1268
+ required: yes
1269
+ mapping:
1270
+ "teams":
1271
+ type: seq
1272
+ required: yes
1273
+ sequence:
1274
+ - &amp;team
1275
+ type: map
1276
+ required: yes
1277
+ <strong>class: Team</strong>
1278
+ mapping:
1279
+ "name": {type: str, required: yes, unique: yes}
1280
+ "desc": {type: str}
1281
+ "chief": *member # preceding alias
1282
+ "members":
1283
+ type: seq
1284
+ sequence: [*member] # preceding alias
1285
+ "members":
1286
+ type: seq
1287
+ required: yes
1288
+ sequence:
1289
+ - &amp;member
1290
+ type: map
1291
+ required: yes
1292
+ <strong>class: Member</strong>
1293
+ mapping:
1294
+ "name": {type: str, required: yes, unique: yes}
1295
+ "desc": {type: str}
1296
+ "team": *team
1297
+ </pre>
1298
+ <p>It is required to define class 'Team' and 'Member' for data-binding.
1299
+ Command-line option '-a genclass-ruby' will help you to generate class definitions from schema definition.
1300
+ Try 'kwalify -ha genclass-ruby' for more details about 'genclass-ruby' action.
1301
+ </p>
1302
+ <a name="babel_genclass.result"></a>
1303
+ <pre class="terminal">$ kwalify -a genclass-ruby -P -f BABEL.schema.yaml \
1304
+ --hashlike --initialize=false --module=Babel
1305
+ require 'kwalify/util/hashlike'
1306
+
1307
+ module Babel
1308
+
1309
+ ##
1310
+ class Team
1311
+ include Kwalify::Util::HashLike
1312
+ attr_accessor :name # str
1313
+ attr_accessor :desc # str
1314
+ attr_accessor :chief # map
1315
+ attr_accessor :members # seq
1316
+ end
1317
+
1318
+ ##
1319
+ class Member
1320
+ include Kwalify::Util::HashLike
1321
+ attr_accessor :name # str
1322
+ attr_accessor :desc # str
1323
+ attr_accessor :team # map
1324
+ end
1325
+
1326
+ end
1327
+ $ kwalify -a genclass-ruby -P -f BABEL.schema.yaml \
1328
+ --hashlike --initialize=false --module=Babel &gt; models.rb
1329
+ </pre>
1330
+ <p>Here is the ruby program.
1331
+ </p>
1332
+ <a name="loadbabel.rb"></a>
1333
+ <div class="program_caption">
1334
+ loadbabel.rb</div>
1335
+ <pre class="program">require 'kwalify'
1336
+ <strong>require 'models'</strong>
1337
+
1338
+ ## load schema definition
1339
+ schema = Kwalify::Yaml.load_file('BABEL.schema.yaml',
1340
+ :untabify=&gt;true,
1341
+ :preceding_alias=&gt;true)
1342
+
1343
+ ## add module name to 'class:'
1344
+ Kwalify::Util.traverse_schema(schema) do |rulehash|
1345
+ if rulehash['class']
1346
+ rulehash['class'] = 'Babel::' + rulehash['class']
1347
+ end
1348
+ end
1349
+
1350
+ ## create validator
1351
+ validator = Kwalify::Validator.new(schema)
1352
+
1353
+ ## parse with data-binding
1354
+ parser = Kwalify::Yaml::Parser.new(validator)
1355
+ parser.preceding_alias = true
1356
+ <strong>parser.data_binding = true</strong>
1357
+ ydoc = parser.parse_file('BABEL.data.yaml', :untabify=&gt;true)
1358
+
1359
+ ## show document
1360
+ require 'pp'
1361
+ pp ydoc
1362
+ </pre>
1363
+ <a name="howto5_databinding.result"></a>
1364
+ <div class="terminal_caption">
1365
+ result</div>
1366
+ <pre class="terminal">$ ruby loadbabel.rb
1367
+ {"teams"=&gt;
1368
+ [#&lt;Babel::Team:0x53e0f8
1369
+ @chief=
1370
+ #&lt;Babel::Member:0x53d5e0
1371
+ @desc="Scientist",
1372
+ @name="Kohichi Minamoto",
1373
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1374
+ @desc="Level 7 ESPers",
1375
+ @members=
1376
+ [#&lt;Babel::Member:0x53d018
1377
+ @desc="Psychokino",
1378
+ @name="Kaoru Akashi",
1379
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1380
+ #&lt;Babel::Member:0x53ca50
1381
+ @desc="Teleporter",
1382
+ @name="Aoi Nogami",
1383
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1384
+ #&lt;Babel::Member:0x53c488
1385
+ @desc="Psycometrer",
1386
+ @name="Shiho Sannomiya",
1387
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;],
1388
+ @name="The Children"&gt;],
1389
+ "members"=&gt;
1390
+ [#&lt;Babel::Member:0x53d5e0
1391
+ @desc="Scientist",
1392
+ @name="Kohichi Minamoto",
1393
+ @team=
1394
+ #&lt;Babel::Team:0x53e0f8
1395
+ @chief=#&lt;Babel::Member:0x53d5e0 ...&gt;,
1396
+ @desc="Level 7 ESPers",
1397
+ @members=
1398
+ [#&lt;Babel::Member:0x53d018
1399
+ @desc="Psychokino",
1400
+ @name="Kaoru Akashi",
1401
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1402
+ #&lt;Babel::Member:0x53ca50
1403
+ @desc="Teleporter",
1404
+ @name="Aoi Nogami",
1405
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1406
+ #&lt;Babel::Member:0x53c488
1407
+ @desc="Psycometrer",
1408
+ @name="Shiho Sannomiya",
1409
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;],
1410
+ @name="The Children"&gt;&gt;,
1411
+ #&lt;Babel::Member:0x53d018
1412
+ @desc="Psychokino",
1413
+ @name="Kaoru Akashi",
1414
+ @team=
1415
+ #&lt;Babel::Team:0x53e0f8
1416
+ @chief=
1417
+ #&lt;Babel::Member:0x53d5e0
1418
+ @desc="Scientist",
1419
+ @name="Kohichi Minamoto",
1420
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1421
+ @desc="Level 7 ESPers",
1422
+ @members=
1423
+ [#&lt;Babel::Member:0x53d018 ...&gt;,
1424
+ #&lt;Babel::Member:0x53ca50
1425
+ @desc="Teleporter",
1426
+ @name="Aoi Nogami",
1427
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1428
+ #&lt;Babel::Member:0x53c488
1429
+ @desc="Psycometrer",
1430
+ @name="Shiho Sannomiya",
1431
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;],
1432
+ @name="The Children"&gt;&gt;,
1433
+ #&lt;Babel::Member:0x53ca50
1434
+ @desc="Teleporter",
1435
+ @name="Aoi Nogami",
1436
+ @team=
1437
+ #&lt;Babel::Team:0x53e0f8
1438
+ @chief=
1439
+ #&lt;Babel::Member:0x53d5e0
1440
+ @desc="Scientist",
1441
+ @name="Kohichi Minamoto",
1442
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1443
+ @desc="Level 7 ESPers",
1444
+ @members=
1445
+ [#&lt;Babel::Member:0x53d018
1446
+ @desc="Psychokino",
1447
+ @name="Kaoru Akashi",
1448
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1449
+ #&lt;Babel::Member:0x53ca50 ...&gt;,
1450
+ #&lt;Babel::Member:0x53c488
1451
+ @desc="Psycometrer",
1452
+ @name="Shiho Sannomiya",
1453
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;],
1454
+ @name="The Children"&gt;&gt;,
1455
+ #&lt;Babel::Member:0x53c488
1456
+ @desc="Psycometrer",
1457
+ @name="Shiho Sannomiya",
1458
+ @team=
1459
+ #&lt;Babel::Team:0x53e0f8
1460
+ @chief=
1461
+ #&lt;Babel::Member:0x53d5e0
1462
+ @desc="Scientist",
1463
+ @name="Kohichi Minamoto",
1464
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1465
+ @desc="Level 7 ESPers",
1466
+ @members=
1467
+ [#&lt;Babel::Member:0x53d018
1468
+ @desc="Psychokino",
1469
+ @name="Kaoru Akashi",
1470
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1471
+ #&lt;Babel::Member:0x53ca50
1472
+ @desc="Teleporter",
1473
+ @name="Aoi Nogami",
1474
+ @team=#&lt;Babel::Team:0x53e0f8 ...&gt;&gt;,
1475
+ #&lt;Babel::Member:0x53c488 ...&gt;],
1476
+ @name="The Children"&gt;&gt;]}
1477
+ </pre>
1478
+ <br>
1479
+
1480
+
1481
+ <br>
1482
+
1483
+
1484
+ <a name="actions"></a>
1485
+ <h2 class="section1">Actions</h2>
1486
+ <p>Kwalify has the command-line '-a <em>action</em>' which perform a certain action to schema definition.
1487
+ Currently only the following actions are provided.
1488
+ </p>
1489
+ <dl class="dl2">
1490
+ <dt class="dt2">
1491
+ genclass-ruby</dt>
1492
+ <dd class="dd2">
1493
+ <p> Generate class definitions in Ruby.
1494
+ </p>
1495
+ </dd>
1496
+ <dt class="dt2">
1497
+ genclass-java</dt>
1498
+ <dd class="dd2">
1499
+ <p> Generate class definitions in Java.
1500
+ </p>
1501
+ </dd>
1502
+ <dt class="dt2">
1503
+ genclass-php</dt>
1504
+ <dd class="dd2">
1505
+ <p> Generate class definitions in Ruby.
1506
+ </p>
1507
+ </dd>
1508
+ </dl>
1509
+ <p>In fact action name represents template filename.
1510
+ For example, action 'genclass-ruby' invokes template file 'kwalify/templates/genclass-ruby.eruby'.
1511
+ </p>
1512
+ <p>Each action can accept some command-line properties.
1513
+ For example, action 'genclass-ruby' can accept the command-line properties '--module=<em>name</em>', '--parent=<em>name</em>', and so on.
1514
+ Type 'kwalify -h -a <em>action</em>' to show the list of command-line properties the action can accept.
1515
+ </p>
1516
+ <p>It is able to add your on action template file.
1517
+ The command-line option '-I' (template path) will help you.
1518
+ </p>
1519
+ <a name="action-genclass"></a>
1520
+ <h3 class="section2">Class Definition Generation</h3>
1521
+ <p>Command-line option '-a genclass-ruby' or '-a genclass-java' generates class definition
1522
+ automatically from schema definition in Ruby or Java.
1523
+ </p>
1524
+ <p>Assume the following data file and schema definition.
1525
+ </p>
1526
+ <a name="address_book.yaml"></a>
1527
+ <div class="program_caption">
1528
+ <code>address_book.yaml</code> : data file</div>
1529
+ <pre class="program">groups:
1530
+
1531
+ - name: family
1532
+ desc: my family
1533
+
1534
+ - name: friend
1535
+ desc: my friends
1536
+
1537
+ - name: business
1538
+ desc: those who works together
1539
+
1540
+ people:
1541
+
1542
+ - name: Sumire
1543
+ group: family
1544
+ birth: 2000-01-01
1545
+ blood: A
1546
+
1547
+ - name: Shiina
1548
+ group: friend
1549
+ birth: 1995-01-01
1550
+ email: shiina@mail.org
1551
+
1552
+ - name: Sakura
1553
+ group: business
1554
+ email: cherry@mail.net
1555
+ phone: 012-345-6789
1556
+ </pre>
1557
+ <a name="address_book.schema.yaml"></a>
1558
+ <div class="program_caption">
1559
+ <code>address_book.schema.yaml</code> : schema definition file</div>
1560
+ <pre class="program">type: map
1561
+ <strong>class: AddressBook</strong>
1562
+ desc: address-book class
1563
+ mapping:
1564
+ "groups":
1565
+ type: seq
1566
+ sequence:
1567
+ - type: map
1568
+ <strong>class: Group</strong>
1569
+ desc: group class
1570
+ mapping:
1571
+ "name": { type: str, required: yes }
1572
+ "desc": { type: str }
1573
+ "people":
1574
+ type: seq
1575
+ sequence:
1576
+ - type: map
1577
+ <strong>class: Person</strong>
1578
+ desc: person class
1579
+ mapping:
1580
+ "name": { type: str, required: yes }
1581
+ "desc": { type: str }
1582
+ "group": { type: str }
1583
+ "email": { type: str, pattern: '/@/' }
1584
+ "phone": { type: str }
1585
+ "birth": { type: date }
1586
+ "blood": { type: str, enum: [A, B, O, AB] }
1587
+ "deleted": { type: bool, <strong>default: false</strong> }
1588
+ </pre>
1589
+ <a name="action-genclass-ruby"></a>
1590
+ <h4 class="section3">Ruby Class Definition</h4>
1591
+ <div class="terminal_caption">
1592
+ generate class definition</div>
1593
+ <pre class="terminal">$ kwalify <strong>-a genclass-ruby</strong> -tf address_book.schema.yaml &gt; address_book.rb
1594
+ </pre>
1595
+ <a name="address_book.rb"></a>
1596
+ <div class="program_caption">
1597
+ <code>address_book.rb</code> : generated class definition</div>
1598
+ <pre class="program">## address-book class
1599
+ class AddressBook
1600
+ def initialize(hash=nil)
1601
+ if hash.nil?
1602
+ return
1603
+ end
1604
+ @groups = (v=hash['groups']) ? v.map!{|e| e.is_a?(Group) ? e : Group.new(e)} : v
1605
+ @people = (v=hash['people']) ? v.map!{|e| e.is_a?(Person) ? e : Person.new(e)} : v
1606
+ end
1607
+ attr_accessor :groups # seq
1608
+ attr_accessor :people # seq
1609
+ end
1610
+
1611
+ ## group class
1612
+ class Group
1613
+ def initialize(hash=nil)
1614
+ if hash.nil?
1615
+ return
1616
+ end
1617
+ @name = hash['name']
1618
+ @desc = hash['desc']
1619
+ end
1620
+ attr_accessor :name # str
1621
+ attr_accessor :desc # str
1622
+ end
1623
+
1624
+ ## person class
1625
+ class Person
1626
+ def initialize(hash=nil)
1627
+ if hash.nil?
1628
+ @deleted = false
1629
+ return
1630
+ end
1631
+ @name = hash['name']
1632
+ @desc = hash['desc']
1633
+ @group = hash['group']
1634
+ @email = hash['email']
1635
+ @phone = hash['phone']
1636
+ @birth = hash['birth']
1637
+ @blood = hash['blood']
1638
+ @deleted = (v=hash['deleted']).nil? ? false : v
1639
+ end
1640
+ attr_accessor :name # str
1641
+ attr_accessor :desc # str
1642
+ attr_accessor :group # str
1643
+ attr_accessor :email # str
1644
+ attr_accessor :phone # str
1645
+ attr_accessor :birth # date
1646
+ attr_accessor :blood # str
1647
+ attr_accessor :deleted # bool
1648
+ def deleted? ; @deleted ; end
1649
+ end
1650
+ </pre>
1651
+ <a name="example_address_book.rb"></a>
1652
+ <div class="program_caption">
1653
+ <code>example_address_book.rb</code> : example code of using address-book.rb</div>
1654
+ <pre class="program">require 'address_book'
1655
+ require 'yaml'
1656
+ require 'pp'
1657
+
1658
+ str = File.read('address_book.yaml')
1659
+ ydoc = YAML.load(str)
1660
+ <strong>addrbook = AddressBook.new(ydoc)</strong>
1661
+
1662
+ pp <strong>addrbook.groups</strong>
1663
+ pp <strong>addrbook.people</strong>
1664
+ </pre>
1665
+ <a name="example_address_book_ruby.result"></a>
1666
+ <div class="terminal_caption">
1667
+ result</div>
1668
+ <pre class="terminal">$ ruby example_address_book.rb
1669
+ [#&lt;Group:0xddf24 @desc="my family", @name="family"&gt;,
1670
+ #&lt;Group:0xddf10 @desc="my friends", @name="friend"&gt;,
1671
+ #&lt;Group:0xdde84 @desc="those who works together", @name="business"&gt;]
1672
+ [#&lt;Person:0xdefdc
1673
+ @birth=#&lt;Date: 4903089/2,0,2299161&gt;,
1674
+ @blood="A",
1675
+ @deleted=false,
1676
+ @desc=nil,
1677
+ @email=nil,
1678
+ @group="family",
1679
+ @name="Sumire",
1680
+ @phone=nil&gt;,
1681
+ #&lt;Person:0xdee9c
1682
+ @birth=#&lt;Date: 4899437/2,0,2299161&gt;,
1683
+ @blood=nil,
1684
+ @deleted=false,
1685
+ @desc=nil,
1686
+ @email="shiina@mail.org",
1687
+ @group="friend",
1688
+ @name="Shiina",
1689
+ @phone=nil&gt;,
1690
+ #&lt;Person:0xde8e8
1691
+ @birth=nil,
1692
+ @blood=nil,
1693
+ @deleted=false,
1694
+ @desc=nil,
1695
+ @email="cherry@mail.net",
1696
+ @group="business",
1697
+ @name="Sakura",
1698
+ @phone="012-345-6789"&gt;]
1699
+ </pre>
1700
+ <p>Command-line option '<code>-h -a genclass-ruby</code>' shows the commpand-line properties that template can accept.
1701
+ </p>
1702
+ <a name="option_ha.result"></a>
1703
+ <div class="terminal_caption">
1704
+ show command-line properties</div>
1705
+ <pre class="terminal">$ kwalify -ha genclass-ruby
1706
+ --module=name : module name in which class defined
1707
+ --parent=name : parent class name
1708
+ --include=name : module name which all classes include
1709
+ --initialize=false : not print initialize() method
1710
+ --hashlike : include Kwalify::Util::HashLike module
1711
+ </pre>
1712
+ <div class="terminal_caption">
1713
+ example of command-line properties</div>
1714
+ <pre class="terminal">$ kwalify -a genclass-ruby --module=My --hashlike
1715
+ </pre>
1716
+ <p>If command-line property '--hashlike' (== '--hashlike=true') is specified,
1717
+ module Kwalify::Util::HashLike is included for each classes generated.
1718
+ That module is defined in 'kwalify/util/hashlike.rb'
1719
+ </p>
1720
+ <br>
1721
+
1722
+ <a name="action-genclass-java"></a>
1723
+ <h4 class="section3">Java Class Definition</h4>
1724
+ <a name="genclass_java.result"></a>
1725
+ <div class="terminal_caption">
1726
+ generate java class definition</div>
1727
+ <pre class="terminal">$ kwalify <strong>-a genclass-java</strong> -tf address_book.schema.yaml
1728
+ generating ./AddressBook.java...done.
1729
+ generating ./Group.java...done.
1730
+ generating ./Person.java...done.
1731
+ </pre>
1732
+ <a name="AddressBook.java.expected"></a>
1733
+ <div class="program_caption">
1734
+ <code>AddressBook.java</code> : generated class definition</div>
1735
+ <pre class="program">// generated by kwalify from address_book.schema.yaml
1736
+
1737
+ import java.util.*;
1738
+
1739
+ /**
1740
+ * address-book class
1741
+ */
1742
+ public class AddressBook {
1743
+
1744
+ private List _groups;
1745
+ private List _people;
1746
+
1747
+ public AddressBook() {}
1748
+
1749
+ public AddressBook(Map map) {
1750
+ List seq;
1751
+ Object obj;
1752
+ if ((seq = (List)map.get("groups")) != null) {
1753
+ for (int i = 0; i &lt; seq.size(); i++) {
1754
+ if ((obj = seq.get(i)) instanceof Map) {
1755
+ seq.set(i, new Group((Map)obj));
1756
+ }
1757
+ }
1758
+ }
1759
+ _groups = seq;
1760
+ if ((seq = (List)map.get("people")) != null) {
1761
+ for (int i = 0; i &lt; seq.size(); i++) {
1762
+ if ((obj = seq.get(i)) instanceof Map) {
1763
+ seq.set(i, new Person((Map)obj));
1764
+ }
1765
+ }
1766
+ }
1767
+ _people = seq;
1768
+ }
1769
+
1770
+ public List getGroups() { return _groups; }
1771
+ public void setGroups(List groups_) { _groups = groups_; }
1772
+ public List getPeople() { return _people; }
1773
+ public void setPeople(List people_) { _people = people_; }
1774
+ }
1775
+ </pre>
1776
+ <a name="Group.java.expected"></a>
1777
+ <div class="program_caption">
1778
+ <code>Group.java</code> : generated class definition</div>
1779
+ <pre class="program">// generated by kwalify from address_book.schema.yaml
1780
+
1781
+ import java.util.*;
1782
+
1783
+ /**
1784
+ * group class
1785
+ */
1786
+ public class Group {
1787
+
1788
+ private String _name;
1789
+ private String _desc;
1790
+
1791
+ public Group() {}
1792
+
1793
+ public Group(Map map) {
1794
+ _name = (String)map.get("name");
1795
+ _desc = (String)map.get("desc");
1796
+ }
1797
+
1798
+ public String getName() { return _name; }
1799
+ public void setName(String name_) { _name = name_; }
1800
+ public String getDesc() { return _desc; }
1801
+ public void setDesc(String desc_) { _desc = desc_; }
1802
+ }
1803
+ </pre>
1804
+ <a name="Person.java.expected"></a>
1805
+ <div class="program_caption">
1806
+ <code>Person.java</code> : generated class definition</div>
1807
+ <pre class="program">// generated by kwalify from address_book.schema.yaml
1808
+
1809
+ import java.util.*;
1810
+
1811
+ /**
1812
+ * person class
1813
+ */
1814
+ public class Person {
1815
+
1816
+ private String _name;
1817
+ private String _desc;
1818
+ private String _group;
1819
+ private String _email;
1820
+ private String _phone;
1821
+ private Date _birth;
1822
+ private String _blood;
1823
+
1824
+ public Person() {}
1825
+
1826
+ public Person(Map map) {
1827
+ _name = (String)map.get("name");
1828
+ _desc = (String)map.get("desc");
1829
+ _group = (String)map.get("group");
1830
+ _email = (String)map.get("email");
1831
+ _phone = (String)map.get("phone");
1832
+ _birth = (Date)map.get("birth");
1833
+ _blood = (String)map.get("blood");
1834
+ }
1835
+
1836
+ public String getName() { return _name; }
1837
+ public void setName(String name_) { _name = name_; }
1838
+ public String getDesc() { return _desc; }
1839
+ public void setDesc(String desc_) { _desc = desc_; }
1840
+ public String getGroup() { return _group; }
1841
+ public void setGroup(String group_) { _group = group_; }
1842
+ public String getEmail() { return _email; }
1843
+ public void setEmail(String email_) { _email = email_; }
1844
+ public String getPhone() { return _phone; }
1845
+ public void setPhone(String phone_) { _phone = phone_; }
1846
+ public Date getBirth() { return _birth; }
1847
+ public void setBirth(Date birth_) { _birth = birth_; }
1848
+ public String getBlood() { return _blood; }
1849
+ public void setBlood(String blood_) { _blood = blood_; }
1850
+ }
1851
+ </pre>
1852
+ <a name="ExampleAddressBook.java"></a>
1853
+ <div class="program_caption">
1854
+ <code>ExampleAddressBook.java</code> : example code of using *.java</div>
1855
+ <pre class="program">import java.util.*;
1856
+ import kwalify.*;
1857
+
1858
+ public class ExampleAddressBook {
1859
+ public static void main(String args[]) throws Exception {
1860
+ // read schema
1861
+ String schema_str = Util.readFile("address_book.schema.yaml");
1862
+ schema_str = Util.untabify(schema_str);
1863
+ Object schema = new YamlParser(schema_str).parse();
1864
+
1865
+ // read document file
1866
+ String document_str = Util.readFile("address_book.yaml");
1867
+ document_str = Util.untabify(document_str);
1868
+ YamlParser parser = new YamlParser(document_str);
1869
+ Object document = parser.parse();
1870
+
1871
+ // create address book object
1872
+ AddressBook addrbook = new AddressBook((Map)document);
1873
+
1874
+ // show groups
1875
+ List groups = addrbook.getGroups();
1876
+ if (groups != null) {
1877
+ for (Iterator it = groups.iterator(); it.hasNext(); ) {
1878
+ Group group = (Group)it.next();
1879
+ System.out.println("group name: " + group.getName());
1880
+ System.out.println("group desc: " + group.getDesc());
1881
+ System.out.println();
1882
+ }
1883
+ }
1884
+
1885
+ // show people
1886
+ List people = addrbook.getPeople();
1887
+ if (people != null) {
1888
+ for (Iterator it = people.iterator(); it.hasNext(); ) {
1889
+ Person person = (Person)it.next();
1890
+ System.out.println("person name: " + person.getName());
1891
+ System.out.println("person group: " + person.getGroup());
1892
+ System.out.println("person email: " + person.getEmail());
1893
+ System.out.println("person phone: " + person.getPhone());
1894
+ System.out.println("person blood: " + person.getBlood());
1895
+ System.out.println("person birth: " + person.getBirth());
1896
+ System.out.println();
1897
+ }
1898
+ }
1899
+ }
1900
+
1901
+ }
1902
+ </pre>
1903
+ <a name="example_address_book_java.result"></a>
1904
+ <div class="terminal_caption">
1905
+ result</div>
1906
+ <pre class="terminal">$ javac -classpath '.:kwalify.jar' *.java
1907
+ $ java -classpath '.:kwalify.jar' ExampleAddressBook
1908
+ group name: family
1909
+ group desc: my family
1910
+
1911
+ group name: friend
1912
+ group desc: my friends
1913
+
1914
+ group name: business
1915
+ group desc: those who works together
1916
+
1917
+ person name: Sumire
1918
+ person group: family
1919
+ person email: null
1920
+ person phone: null
1921
+ person blood: A
1922
+ person birth: Tue Feb 01 00:00:00 JST 2000
1923
+
1924
+ person name: Shiina
1925
+ person group: friend
1926
+ person email: shiina@mail.org
1927
+ person phone: null
1928
+ person blood: null
1929
+ person birth: Wed Feb 01 00:00:00 JST 1995
1930
+
1931
+ person name: Sakura
1932
+ person group: business
1933
+ person email: cherry@mail.net
1934
+ person phone: 012-345-6789
1935
+ person blood: null
1936
+ person birth: null
1937
+
1938
+ </pre>
1939
+ <p>Command-line option '<code>-h -a genclass-java</code>' shows the commpand-line properties that template can accept.
1940
+ </p>
1941
+ <a name="option_ha_genclass_java.result"></a>
1942
+ <div class="terminal_caption">
1943
+ show command-line properties</div>
1944
+ <pre class="terminal">$ kwalify -ha genclass-java
1945
+ --package=name : package name
1946
+ --extends=name : class name to extend
1947
+ --implements=name,... : interface names to implement
1948
+ --dir=path : directory to locate output file
1949
+ --basedir=path : base directory to locate output file
1950
+ --constructor=false : not print initialize() method
1951
+ </pre>
1952
+ <div class="terminal_caption">
1953
+ example of command-line properties</div>
1954
+ <pre class="terminal">$ kwalify -a genclass-java --package=com.example.my --implements=Serializable --basedir=src
1955
+ </pre>
1956
+ <br>
1957
+
1958
+ <br>
1959
+
1960
+
1961
+ <br>
1962
+
1963
+
1964
+ <a name="ref"></a>
1965
+ <h2 class="section1">References</h2>
1966
+ <a name="ref-usage"></a>
1967
+ <h3 class="section2">Usage in Command-Line</h3>
1968
+ <div class="terminal_caption">
1969
+ </div>
1970
+ <pre class="terminal">### usage1: validate YAML document in command-line
1971
+ $ kwalify -f schema.yaml document.yaml [document2.yaml ...]
1972
+ ### usage2: validate schema definition in command-line
1973
+ $ kwalify -m schema.yaml [schema2.yaml ...]
1974
+ </pre>
1975
+ <p>Command-line options:
1976
+ </p>
1977
+ <dl class="dl3">
1978
+ <dt class="dt3"><strong>
1979
+ <code>-h</code>, <code>--help</code> </strong></dt>
1980
+ <dd class="dd3">
1981
+ Print help message.
1982
+ </dd>
1983
+ <dt class="dt3"><strong>
1984
+ <code>-v</code> </strong></dt>
1985
+ <dd class="dd3">
1986
+ Print version.
1987
+ </dd>
1988
+ <dt class="dt3"><strong>
1989
+ <code>-q</code> </strong></dt>
1990
+ <dd class="dd3">
1991
+ Quiet mode.
1992
+ </dd>
1993
+ <dt class="dt3"><strong>
1994
+ <code>-s</code> </strong></dt>
1995
+ <dd class="dd3">
1996
+ (Obsolete. Use '-q' instead.) Silent mode.
1997
+ </dd>
1998
+ <dt class="dt3"><strong>
1999
+ <code>-f <em>schema.yaml</em></code> </strong></dt>
2000
+ <dd class="dd3">
2001
+ Specify schema definition file.
2002
+ </dd>
2003
+ <dt class="dt3"><strong>
2004
+ <code>-m</code> </strong></dt>
2005
+ <dd class="dd3">
2006
+ Meta-validation of schema definition.
2007
+ </dd>
2008
+ <dt class="dt3"><strong>
2009
+ <code>-t</code> </strong></dt>
2010
+ <dd class="dd3">
2011
+ Expand tab characters to spaces automatically.
2012
+ </dd>
2013
+ <dt class="dt3"><strong>
2014
+ <code>-l</code> </strong></dt>
2015
+ <dd class="dd3">
2016
+ Show linenumber on which error found.
2017
+ </dd>
2018
+ <dt class="dt3"><strong>
2019
+ <code>-E</code> </strong></dt>
2020
+ <dd class="dd3">
2021
+ Show errors in Emacs-compatible style (implies '-l' option).
2022
+ </dd>
2023
+ <dt class="dt3"><strong>
2024
+ <code>-a action</code> </strong></dt>
2025
+ <dd class="dd3">
2026
+ Do action. Currently supported action is 'genclass-ruby' and 'genclass-java'.
2027
+ Try '-ha action' to get help about the action.
2028
+ </dd>
2029
+ <dt class="dt3"><strong>
2030
+ <code>-I path1,path2,...</code> </strong></dt>
2031
+ <dd class="dd3">
2032
+ Template path (for '-a').
2033
+ </dd>
2034
+ <dt class="dt3"><strong>
2035
+ <code>-P</code> </strong></dt>
2036
+ <dd class="dd3">
2037
+ Enable preceding alias.
2038
+ </dd>
2039
+ </dl>
2040
+ <br>
2041
+
2042
+
2043
+ <br>
2044
+
2045
+
2046
+
2047
+ </div>
2048
+
2049
+ </body>
2050
+ </html>