Mercurial > hg > tema
changeset 2:6c41a0b43e58 release_0_3
Tema 0.3 (imported from CVS).
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.cvsignore Tue Feb 19 20:32:17 2008 +0300 1.3 @@ -0,0 +1,1 @@ 1.4 +build
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/COPYING Tue Feb 19 20:32:17 2008 +0300 2.3 @@ -0,0 +1,674 @@ 2.4 + GNU GENERAL PUBLIC LICENSE 2.5 + Version 3, 29 June 2007 2.6 + 2.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 2.8 + Everyone is permitted to copy and distribute verbatim copies 2.9 + of this license document, but changing it is not allowed. 2.10 + 2.11 + Preamble 2.12 + 2.13 + The GNU General Public License is a free, copyleft license for 2.14 +software and other kinds of works. 2.15 + 2.16 + The licenses for most software and other practical works are designed 2.17 +to take away your freedom to share and change the works. By contrast, 2.18 +the GNU General Public License is intended to guarantee your freedom to 2.19 +share and change all versions of a program--to make sure it remains free 2.20 +software for all its users. We, the Free Software Foundation, use the 2.21 +GNU General Public License for most of our software; it applies also to 2.22 +any other work released this way by its authors. You can apply it to 2.23 +your programs, too. 2.24 + 2.25 + When we speak of free software, we are referring to freedom, not 2.26 +price. Our General Public Licenses are designed to make sure that you 2.27 +have the freedom to distribute copies of free software (and charge for 2.28 +them if you wish), that you receive source code or can get it if you 2.29 +want it, that you can change the software or use pieces of it in new 2.30 +free programs, and that you know you can do these things. 2.31 + 2.32 + To protect your rights, we need to prevent others from denying you 2.33 +these rights or asking you to surrender the rights. Therefore, you have 2.34 +certain responsibilities if you distribute copies of the software, or if 2.35 +you modify it: responsibilities to respect the freedom of others. 2.36 + 2.37 + For example, if you distribute copies of such a program, whether 2.38 +gratis or for a fee, you must pass on to the recipients the same 2.39 +freedoms that you received. You must make sure that they, too, receive 2.40 +or can get the source code. And you must show them these terms so they 2.41 +know their rights. 2.42 + 2.43 + Developers that use the GNU GPL protect your rights with two steps: 2.44 +(1) assert copyright on the software, and (2) offer you this License 2.45 +giving you legal permission to copy, distribute and/or modify it. 2.46 + 2.47 + For the developers' and authors' protection, the GPL clearly explains 2.48 +that there is no warranty for this free software. For both users' and 2.49 +authors' sake, the GPL requires that modified versions be marked as 2.50 +changed, so that their problems will not be attributed erroneously to 2.51 +authors of previous versions. 2.52 + 2.53 + Some devices are designed to deny users access to install or run 2.54 +modified versions of the software inside them, although the manufacturer 2.55 +can do so. This is fundamentally incompatible with the aim of 2.56 +protecting users' freedom to change the software. The systematic 2.57 +pattern of such abuse occurs in the area of products for individuals to 2.58 +use, which is precisely where it is most unacceptable. Therefore, we 2.59 +have designed this version of the GPL to prohibit the practice for those 2.60 +products. If such problems arise substantially in other domains, we 2.61 +stand ready to extend this provision to those domains in future versions 2.62 +of the GPL, as needed to protect the freedom of users. 2.63 + 2.64 + Finally, every program is threatened constantly by software patents. 2.65 +States should not allow patents to restrict development and use of 2.66 +software on general-purpose computers, but in those that do, we wish to 2.67 +avoid the special danger that patents applied to a free program could 2.68 +make it effectively proprietary. To prevent this, the GPL assures that 2.69 +patents cannot be used to render the program non-free. 2.70 + 2.71 + The precise terms and conditions for copying, distribution and 2.72 +modification follow. 2.73 + 2.74 + TERMS AND CONDITIONS 2.75 + 2.76 + 0. Definitions. 2.77 + 2.78 + "This License" refers to version 3 of the GNU General Public License. 2.79 + 2.80 + "Copyright" also means copyright-like laws that apply to other kinds of 2.81 +works, such as semiconductor masks. 2.82 + 2.83 + "The Program" refers to any copyrightable work licensed under this 2.84 +License. Each licensee is addressed as "you". "Licensees" and 2.85 +"recipients" may be individuals or organizations. 2.86 + 2.87 + To "modify" a work means to copy from or adapt all or part of the work 2.88 +in a fashion requiring copyright permission, other than the making of an 2.89 +exact copy. The resulting work is called a "modified version" of the 2.90 +earlier work or a work "based on" the earlier work. 2.91 + 2.92 + A "covered work" means either the unmodified Program or a work based 2.93 +on the Program. 2.94 + 2.95 + To "propagate" a work means to do anything with it that, without 2.96 +permission, would make you directly or secondarily liable for 2.97 +infringement under applicable copyright law, except executing it on a 2.98 +computer or modifying a private copy. Propagation includes copying, 2.99 +distribution (with or without modification), making available to the 2.100 +public, and in some countries other activities as well. 2.101 + 2.102 + To "convey" a work means any kind of propagation that enables other 2.103 +parties to make or receive copies. Mere interaction with a user through 2.104 +a computer network, with no transfer of a copy, is not conveying. 2.105 + 2.106 + An interactive user interface displays "Appropriate Legal Notices" 2.107 +to the extent that it includes a convenient and prominently visible 2.108 +feature that (1) displays an appropriate copyright notice, and (2) 2.109 +tells the user that there is no warranty for the work (except to the 2.110 +extent that warranties are provided), that licensees may convey the 2.111 +work under this License, and how to view a copy of this License. If 2.112 +the interface presents a list of user commands or options, such as a 2.113 +menu, a prominent item in the list meets this criterion. 2.114 + 2.115 + 1. Source Code. 2.116 + 2.117 + The "source code" for a work means the preferred form of the work 2.118 +for making modifications to it. "Object code" means any non-source 2.119 +form of a work. 2.120 + 2.121 + A "Standard Interface" means an interface that either is an official 2.122 +standard defined by a recognized standards body, or, in the case of 2.123 +interfaces specified for a particular programming language, one that 2.124 +is widely used among developers working in that language. 2.125 + 2.126 + The "System Libraries" of an executable work include anything, other 2.127 +than the work as a whole, that (a) is included in the normal form of 2.128 +packaging a Major Component, but which is not part of that Major 2.129 +Component, and (b) serves only to enable use of the work with that 2.130 +Major Component, or to implement a Standard Interface for which an 2.131 +implementation is available to the public in source code form. A 2.132 +"Major Component", in this context, means a major essential component 2.133 +(kernel, window system, and so on) of the specific operating system 2.134 +(if any) on which the executable work runs, or a compiler used to 2.135 +produce the work, or an object code interpreter used to run it. 2.136 + 2.137 + The "Corresponding Source" for a work in object code form means all 2.138 +the source code needed to generate, install, and (for an executable 2.139 +work) run the object code and to modify the work, including scripts to 2.140 +control those activities. However, it does not include the work's 2.141 +System Libraries, or general-purpose tools or generally available free 2.142 +programs which are used unmodified in performing those activities but 2.143 +which are not part of the work. For example, Corresponding Source 2.144 +includes interface definition files associated with source files for 2.145 +the work, and the source code for shared libraries and dynamically 2.146 +linked subprograms that the work is specifically designed to require, 2.147 +such as by intimate data communication or control flow between those 2.148 +subprograms and other parts of the work. 2.149 + 2.150 + The Corresponding Source need not include anything that users 2.151 +can regenerate automatically from other parts of the Corresponding 2.152 +Source. 2.153 + 2.154 + The Corresponding Source for a work in source code form is that 2.155 +same work. 2.156 + 2.157 + 2. Basic Permissions. 2.158 + 2.159 + All rights granted under this License are granted for the term of 2.160 +copyright on the Program, and are irrevocable provided the stated 2.161 +conditions are met. This License explicitly affirms your unlimited 2.162 +permission to run the unmodified Program. The output from running a 2.163 +covered work is covered by this License only if the output, given its 2.164 +content, constitutes a covered work. This License acknowledges your 2.165 +rights of fair use or other equivalent, as provided by copyright law. 2.166 + 2.167 + You may make, run and propagate covered works that you do not 2.168 +convey, without conditions so long as your license otherwise remains 2.169 +in force. You may convey covered works to others for the sole purpose 2.170 +of having them make modifications exclusively for you, or provide you 2.171 +with facilities for running those works, provided that you comply with 2.172 +the terms of this License in conveying all material for which you do 2.173 +not control copyright. Those thus making or running the covered works 2.174 +for you must do so exclusively on your behalf, under your direction 2.175 +and control, on terms that prohibit them from making any copies of 2.176 +your copyrighted material outside their relationship with you. 2.177 + 2.178 + Conveying under any other circumstances is permitted solely under 2.179 +the conditions stated below. Sublicensing is not allowed; section 10 2.180 +makes it unnecessary. 2.181 + 2.182 + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 2.183 + 2.184 + No covered work shall be deemed part of an effective technological 2.185 +measure under any applicable law fulfilling obligations under article 2.186 +11 of the WIPO copyright treaty adopted on 20 December 1996, or 2.187 +similar laws prohibiting or restricting circumvention of such 2.188 +measures. 2.189 + 2.190 + When you convey a covered work, you waive any legal power to forbid 2.191 +circumvention of technological measures to the extent such circumvention 2.192 +is effected by exercising rights under this License with respect to 2.193 +the covered work, and you disclaim any intention to limit operation or 2.194 +modification of the work as a means of enforcing, against the work's 2.195 +users, your or third parties' legal rights to forbid circumvention of 2.196 +technological measures. 2.197 + 2.198 + 4. Conveying Verbatim Copies. 2.199 + 2.200 + You may convey verbatim copies of the Program's source code as you 2.201 +receive it, in any medium, provided that you conspicuously and 2.202 +appropriately publish on each copy an appropriate copyright notice; 2.203 +keep intact all notices stating that this License and any 2.204 +non-permissive terms added in accord with section 7 apply to the code; 2.205 +keep intact all notices of the absence of any warranty; and give all 2.206 +recipients a copy of this License along with the Program. 2.207 + 2.208 + You may charge any price or no price for each copy that you convey, 2.209 +and you may offer support or warranty protection for a fee. 2.210 + 2.211 + 5. Conveying Modified Source Versions. 2.212 + 2.213 + You may convey a work based on the Program, or the modifications to 2.214 +produce it from the Program, in the form of source code under the 2.215 +terms of section 4, provided that you also meet all of these conditions: 2.216 + 2.217 + a) The work must carry prominent notices stating that you modified 2.218 + it, and giving a relevant date. 2.219 + 2.220 + b) The work must carry prominent notices stating that it is 2.221 + released under this License and any conditions added under section 2.222 + 7. This requirement modifies the requirement in section 4 to 2.223 + "keep intact all notices". 2.224 + 2.225 + c) You must license the entire work, as a whole, under this 2.226 + License to anyone who comes into possession of a copy. This 2.227 + License will therefore apply, along with any applicable section 7 2.228 + additional terms, to the whole of the work, and all its parts, 2.229 + regardless of how they are packaged. This License gives no 2.230 + permission to license the work in any other way, but it does not 2.231 + invalidate such permission if you have separately received it. 2.232 + 2.233 + d) If the work has interactive user interfaces, each must display 2.234 + Appropriate Legal Notices; however, if the Program has interactive 2.235 + interfaces that do not display Appropriate Legal Notices, your 2.236 + work need not make them do so. 2.237 + 2.238 + A compilation of a covered work with other separate and independent 2.239 +works, which are not by their nature extensions of the covered work, 2.240 +and which are not combined with it such as to form a larger program, 2.241 +in or on a volume of a storage or distribution medium, is called an 2.242 +"aggregate" if the compilation and its resulting copyright are not 2.243 +used to limit the access or legal rights of the compilation's users 2.244 +beyond what the individual works permit. Inclusion of a covered work 2.245 +in an aggregate does not cause this License to apply to the other 2.246 +parts of the aggregate. 2.247 + 2.248 + 6. Conveying Non-Source Forms. 2.249 + 2.250 + You may convey a covered work in object code form under the terms 2.251 +of sections 4 and 5, provided that you also convey the 2.252 +machine-readable Corresponding Source under the terms of this License, 2.253 +in one of these ways: 2.254 + 2.255 + a) Convey the object code in, or embodied in, a physical product 2.256 + (including a physical distribution medium), accompanied by the 2.257 + Corresponding Source fixed on a durable physical medium 2.258 + customarily used for software interchange. 2.259 + 2.260 + b) Convey the object code in, or embodied in, a physical product 2.261 + (including a physical distribution medium), accompanied by a 2.262 + written offer, valid for at least three years and valid for as 2.263 + long as you offer spare parts or customer support for that product 2.264 + model, to give anyone who possesses the object code either (1) a 2.265 + copy of the Corresponding Source for all the software in the 2.266 + product that is covered by this License, on a durable physical 2.267 + medium customarily used for software interchange, for a price no 2.268 + more than your reasonable cost of physically performing this 2.269 + conveying of source, or (2) access to copy the 2.270 + Corresponding Source from a network server at no charge. 2.271 + 2.272 + c) Convey individual copies of the object code with a copy of the 2.273 + written offer to provide the Corresponding Source. This 2.274 + alternative is allowed only occasionally and noncommercially, and 2.275 + only if you received the object code with such an offer, in accord 2.276 + with subsection 6b. 2.277 + 2.278 + d) Convey the object code by offering access from a designated 2.279 + place (gratis or for a charge), and offer equivalent access to the 2.280 + Corresponding Source in the same way through the same place at no 2.281 + further charge. You need not require recipients to copy the 2.282 + Corresponding Source along with the object code. If the place to 2.283 + copy the object code is a network server, the Corresponding Source 2.284 + may be on a different server (operated by you or a third party) 2.285 + that supports equivalent copying facilities, provided you maintain 2.286 + clear directions next to the object code saying where to find the 2.287 + Corresponding Source. Regardless of what server hosts the 2.288 + Corresponding Source, you remain obligated to ensure that it is 2.289 + available for as long as needed to satisfy these requirements. 2.290 + 2.291 + e) Convey the object code using peer-to-peer transmission, provided 2.292 + you inform other peers where the object code and Corresponding 2.293 + Source of the work are being offered to the general public at no 2.294 + charge under subsection 6d. 2.295 + 2.296 + A separable portion of the object code, whose source code is excluded 2.297 +from the Corresponding Source as a System Library, need not be 2.298 +included in conveying the object code work. 2.299 + 2.300 + A "User Product" is either (1) a "consumer product", which means any 2.301 +tangible personal property which is normally used for personal, family, 2.302 +or household purposes, or (2) anything designed or sold for incorporation 2.303 +into a dwelling. In determining whether a product is a consumer product, 2.304 +doubtful cases shall be resolved in favor of coverage. For a particular 2.305 +product received by a particular user, "normally used" refers to a 2.306 +typical or common use of that class of product, regardless of the status 2.307 +of the particular user or of the way in which the particular user 2.308 +actually uses, or expects or is expected to use, the product. A product 2.309 +is a consumer product regardless of whether the product has substantial 2.310 +commercial, industrial or non-consumer uses, unless such uses represent 2.311 +the only significant mode of use of the product. 2.312 + 2.313 + "Installation Information" for a User Product means any methods, 2.314 +procedures, authorization keys, or other information required to install 2.315 +and execute modified versions of a covered work in that User Product from 2.316 +a modified version of its Corresponding Source. The information must 2.317 +suffice to ensure that the continued functioning of the modified object 2.318 +code is in no case prevented or interfered with solely because 2.319 +modification has been made. 2.320 + 2.321 + If you convey an object code work under this section in, or with, or 2.322 +specifically for use in, a User Product, and the conveying occurs as 2.323 +part of a transaction in which the right of possession and use of the 2.324 +User Product is transferred to the recipient in perpetuity or for a 2.325 +fixed term (regardless of how the transaction is characterized), the 2.326 +Corresponding Source conveyed under this section must be accompanied 2.327 +by the Installation Information. But this requirement does not apply 2.328 +if neither you nor any third party retains the ability to install 2.329 +modified object code on the User Product (for example, the work has 2.330 +been installed in ROM). 2.331 + 2.332 + The requirement to provide Installation Information does not include a 2.333 +requirement to continue to provide support service, warranty, or updates 2.334 +for a work that has been modified or installed by the recipient, or for 2.335 +the User Product in which it has been modified or installed. Access to a 2.336 +network may be denied when the modification itself materially and 2.337 +adversely affects the operation of the network or violates the rules and 2.338 +protocols for communication across the network. 2.339 + 2.340 + Corresponding Source conveyed, and Installation Information provided, 2.341 +in accord with this section must be in a format that is publicly 2.342 +documented (and with an implementation available to the public in 2.343 +source code form), and must require no special password or key for 2.344 +unpacking, reading or copying. 2.345 + 2.346 + 7. Additional Terms. 2.347 + 2.348 + "Additional permissions" are terms that supplement the terms of this 2.349 +License by making exceptions from one or more of its conditions. 2.350 +Additional permissions that are applicable to the entire Program shall 2.351 +be treated as though they were included in this License, to the extent 2.352 +that they are valid under applicable law. If additional permissions 2.353 +apply only to part of the Program, that part may be used separately 2.354 +under those permissions, but the entire Program remains governed by 2.355 +this License without regard to the additional permissions. 2.356 + 2.357 + When you convey a copy of a covered work, you may at your option 2.358 +remove any additional permissions from that copy, or from any part of 2.359 +it. (Additional permissions may be written to require their own 2.360 +removal in certain cases when you modify the work.) You may place 2.361 +additional permissions on material, added by you to a covered work, 2.362 +for which you have or can give appropriate copyright permission. 2.363 + 2.364 + Notwithstanding any other provision of this License, for material you 2.365 +add to a covered work, you may (if authorized by the copyright holders of 2.366 +that material) supplement the terms of this License with terms: 2.367 + 2.368 + a) Disclaiming warranty or limiting liability differently from the 2.369 + terms of sections 15 and 16 of this License; or 2.370 + 2.371 + b) Requiring preservation of specified reasonable legal notices or 2.372 + author attributions in that material or in the Appropriate Legal 2.373 + Notices displayed by works containing it; or 2.374 + 2.375 + c) Prohibiting misrepresentation of the origin of that material, or 2.376 + requiring that modified versions of such material be marked in 2.377 + reasonable ways as different from the original version; or 2.378 + 2.379 + d) Limiting the use for publicity purposes of names of licensors or 2.380 + authors of the material; or 2.381 + 2.382 + e) Declining to grant rights under trademark law for use of some 2.383 + trade names, trademarks, or service marks; or 2.384 + 2.385 + f) Requiring indemnification of licensors and authors of that 2.386 + material by anyone who conveys the material (or modified versions of 2.387 + it) with contractual assumptions of liability to the recipient, for 2.388 + any liability that these contractual assumptions directly impose on 2.389 + those licensors and authors. 2.390 + 2.391 + All other non-permissive additional terms are considered "further 2.392 +restrictions" within the meaning of section 10. If the Program as you 2.393 +received it, or any part of it, contains a notice stating that it is 2.394 +governed by this License along with a term that is a further 2.395 +restriction, you may remove that term. If a license document contains 2.396 +a further restriction but permits relicensing or conveying under this 2.397 +License, you may add to a covered work material governed by the terms 2.398 +of that license document, provided that the further restriction does 2.399 +not survive such relicensing or conveying. 2.400 + 2.401 + If you add terms to a covered work in accord with this section, you 2.402 +must place, in the relevant source files, a statement of the 2.403 +additional terms that apply to those files, or a notice indicating 2.404 +where to find the applicable terms. 2.405 + 2.406 + Additional terms, permissive or non-permissive, may be stated in the 2.407 +form of a separately written license, or stated as exceptions; 2.408 +the above requirements apply either way. 2.409 + 2.410 + 8. Termination. 2.411 + 2.412 + You may not propagate or modify a covered work except as expressly 2.413 +provided under this License. Any attempt otherwise to propagate or 2.414 +modify it is void, and will automatically terminate your rights under 2.415 +this License (including any patent licenses granted under the third 2.416 +paragraph of section 11). 2.417 + 2.418 + However, if you cease all violation of this License, then your 2.419 +license from a particular copyright holder is reinstated (a) 2.420 +provisionally, unless and until the copyright holder explicitly and 2.421 +finally terminates your license, and (b) permanently, if the copyright 2.422 +holder fails to notify you of the violation by some reasonable means 2.423 +prior to 60 days after the cessation. 2.424 + 2.425 + Moreover, your license from a particular copyright holder is 2.426 +reinstated permanently if the copyright holder notifies you of the 2.427 +violation by some reasonable means, this is the first time you have 2.428 +received notice of violation of this License (for any work) from that 2.429 +copyright holder, and you cure the violation prior to 30 days after 2.430 +your receipt of the notice. 2.431 + 2.432 + Termination of your rights under this section does not terminate the 2.433 +licenses of parties who have received copies or rights from you under 2.434 +this License. If your rights have been terminated and not permanently 2.435 +reinstated, you do not qualify to receive new licenses for the same 2.436 +material under section 10. 2.437 + 2.438 + 9. Acceptance Not Required for Having Copies. 2.439 + 2.440 + You are not required to accept this License in order to receive or 2.441 +run a copy of the Program. Ancillary propagation of a covered work 2.442 +occurring solely as a consequence of using peer-to-peer transmission 2.443 +to receive a copy likewise does not require acceptance. However, 2.444 +nothing other than this License grants you permission to propagate or 2.445 +modify any covered work. These actions infringe copyright if you do 2.446 +not accept this License. Therefore, by modifying or propagating a 2.447 +covered work, you indicate your acceptance of this License to do so. 2.448 + 2.449 + 10. Automatic Licensing of Downstream Recipients. 2.450 + 2.451 + Each time you convey a covered work, the recipient automatically 2.452 +receives a license from the original licensors, to run, modify and 2.453 +propagate that work, subject to this License. You are not responsible 2.454 +for enforcing compliance by third parties with this License. 2.455 + 2.456 + An "entity transaction" is a transaction transferring control of an 2.457 +organization, or substantially all assets of one, or subdividing an 2.458 +organization, or merging organizations. If propagation of a covered 2.459 +work results from an entity transaction, each party to that 2.460 +transaction who receives a copy of the work also receives whatever 2.461 +licenses to the work the party's predecessor in interest had or could 2.462 +give under the previous paragraph, plus a right to possession of the 2.463 +Corresponding Source of the work from the predecessor in interest, if 2.464 +the predecessor has it or can get it with reasonable efforts. 2.465 + 2.466 + You may not impose any further restrictions on the exercise of the 2.467 +rights granted or affirmed under this License. For example, you may 2.468 +not impose a license fee, royalty, or other charge for exercise of 2.469 +rights granted under this License, and you may not initiate litigation 2.470 +(including a cross-claim or counterclaim in a lawsuit) alleging that 2.471 +any patent claim is infringed by making, using, selling, offering for 2.472 +sale, or importing the Program or any portion of it. 2.473 + 2.474 + 11. Patents. 2.475 + 2.476 + A "contributor" is a copyright holder who authorizes use under this 2.477 +License of the Program or a work on which the Program is based. The 2.478 +work thus licensed is called the contributor's "contributor version". 2.479 + 2.480 + A contributor's "essential patent claims" are all patent claims 2.481 +owned or controlled by the contributor, whether already acquired or 2.482 +hereafter acquired, that would be infringed by some manner, permitted 2.483 +by this License, of making, using, or selling its contributor version, 2.484 +but do not include claims that would be infringed only as a 2.485 +consequence of further modification of the contributor version. For 2.486 +purposes of this definition, "control" includes the right to grant 2.487 +patent sublicenses in a manner consistent with the requirements of 2.488 +this License. 2.489 + 2.490 + Each contributor grants you a non-exclusive, worldwide, royalty-free 2.491 +patent license under the contributor's essential patent claims, to 2.492 +make, use, sell, offer for sale, import and otherwise run, modify and 2.493 +propagate the contents of its contributor version. 2.494 + 2.495 + In the following three paragraphs, a "patent license" is any express 2.496 +agreement or commitment, however denominated, not to enforce a patent 2.497 +(such as an express permission to practice a patent or covenant not to 2.498 +sue for patent infringement). To "grant" such a patent license to a 2.499 +party means to make such an agreement or commitment not to enforce a 2.500 +patent against the party. 2.501 + 2.502 + If you convey a covered work, knowingly relying on a patent license, 2.503 +and the Corresponding Source of the work is not available for anyone 2.504 +to copy, free of charge and under the terms of this License, through a 2.505 +publicly available network server or other readily accessible means, 2.506 +then you must either (1) cause the Corresponding Source to be so 2.507 +available, or (2) arrange to deprive yourself of the benefit of the 2.508 +patent license for this particular work, or (3) arrange, in a manner 2.509 +consistent with the requirements of this License, to extend the patent 2.510 +license to downstream recipients. "Knowingly relying" means you have 2.511 +actual knowledge that, but for the patent license, your conveying the 2.512 +covered work in a country, or your recipient's use of the covered work 2.513 +in a country, would infringe one or more identifiable patents in that 2.514 +country that you have reason to believe are valid. 2.515 + 2.516 + If, pursuant to or in connection with a single transaction or 2.517 +arrangement, you convey, or propagate by procuring conveyance of, a 2.518 +covered work, and grant a patent license to some of the parties 2.519 +receiving the covered work authorizing them to use, propagate, modify 2.520 +or convey a specific copy of the covered work, then the patent license 2.521 +you grant is automatically extended to all recipients of the covered 2.522 +work and works based on it. 2.523 + 2.524 + A patent license is "discriminatory" if it does not include within 2.525 +the scope of its coverage, prohibits the exercise of, or is 2.526 +conditioned on the non-exercise of one or more of the rights that are 2.527 +specifically granted under this License. You may not convey a covered 2.528 +work if you are a party to an arrangement with a third party that is 2.529 +in the business of distributing software, under which you make payment 2.530 +to the third party based on the extent of your activity of conveying 2.531 +the work, and under which the third party grants, to any of the 2.532 +parties who would receive the covered work from you, a discriminatory 2.533 +patent license (a) in connection with copies of the covered work 2.534 +conveyed by you (or copies made from those copies), or (b) primarily 2.535 +for and in connection with specific products or compilations that 2.536 +contain the covered work, unless you entered into that arrangement, 2.537 +or that patent license was granted, prior to 28 March 2007. 2.538 + 2.539 + Nothing in this License shall be construed as excluding or limiting 2.540 +any implied license or other defenses to infringement that may 2.541 +otherwise be available to you under applicable patent law. 2.542 + 2.543 + 12. No Surrender of Others' Freedom. 2.544 + 2.545 + If conditions are imposed on you (whether by court order, agreement or 2.546 +otherwise) that contradict the conditions of this License, they do not 2.547 +excuse you from the conditions of this License. If you cannot convey a 2.548 +covered work so as to satisfy simultaneously your obligations under this 2.549 +License and any other pertinent obligations, then as a consequence you may 2.550 +not convey it at all. For example, if you agree to terms that obligate you 2.551 +to collect a royalty for further conveying from those to whom you convey 2.552 +the Program, the only way you could satisfy both those terms and this 2.553 +License would be to refrain entirely from conveying the Program. 2.554 + 2.555 + 13. Use with the GNU Affero General Public License. 2.556 + 2.557 + Notwithstanding any other provision of this License, you have 2.558 +permission to link or combine any covered work with a work licensed 2.559 +under version 3 of the GNU Affero General Public License into a single 2.560 +combined work, and to convey the resulting work. The terms of this 2.561 +License will continue to apply to the part which is the covered work, 2.562 +but the special requirements of the GNU Affero General Public License, 2.563 +section 13, concerning interaction through a network will apply to the 2.564 +combination as such. 2.565 + 2.566 + 14. Revised Versions of this License. 2.567 + 2.568 + The Free Software Foundation may publish revised and/or new versions of 2.569 +the GNU General Public License from time to time. Such new versions will 2.570 +be similar in spirit to the present version, but may differ in detail to 2.571 +address new problems or concerns. 2.572 + 2.573 + Each version is given a distinguishing version number. If the 2.574 +Program specifies that a certain numbered version of the GNU General 2.575 +Public License "or any later version" applies to it, you have the 2.576 +option of following the terms and conditions either of that numbered 2.577 +version or of any later version published by the Free Software 2.578 +Foundation. If the Program does not specify a version number of the 2.579 +GNU General Public License, you may choose any version ever published 2.580 +by the Free Software Foundation. 2.581 + 2.582 + If the Program specifies that a proxy can decide which future 2.583 +versions of the GNU General Public License can be used, that proxy's 2.584 +public statement of acceptance of a version permanently authorizes you 2.585 +to choose that version for the Program. 2.586 + 2.587 + Later license versions may give you additional or different 2.588 +permissions. However, no additional obligations are imposed on any 2.589 +author or copyright holder as a result of your choosing to follow a 2.590 +later version. 2.591 + 2.592 + 15. Disclaimer of Warranty. 2.593 + 2.594 + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 2.595 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 2.596 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 2.597 +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 2.598 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2.599 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 2.600 +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 2.601 +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 2.602 + 2.603 + 16. Limitation of Liability. 2.604 + 2.605 + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 2.606 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 2.607 +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 2.608 +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 2.609 +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 2.610 +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 2.611 +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 2.612 +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 2.613 +SUCH DAMAGES. 2.614 + 2.615 + 17. Interpretation of Sections 15 and 16. 2.616 + 2.617 + If the disclaimer of warranty and limitation of liability provided 2.618 +above cannot be given local legal effect according to their terms, 2.619 +reviewing courts shall apply local law that most closely approximates 2.620 +an absolute waiver of all civil liability in connection with the 2.621 +Program, unless a warranty or assumption of liability accompanies a 2.622 +copy of the Program in return for a fee. 2.623 + 2.624 + END OF TERMS AND CONDITIONS 2.625 + 2.626 + How to Apply These Terms to Your New Programs 2.627 + 2.628 + If you develop a new program, and you want it to be of the greatest 2.629 +possible use to the public, the best way to achieve this is to make it 2.630 +free software which everyone can redistribute and change under these terms. 2.631 + 2.632 + To do so, attach the following notices to the program. It is safest 2.633 +to attach them to the start of each source file to most effectively 2.634 +state the exclusion of warranty; and each file should have at least 2.635 +the "copyright" line and a pointer to where the full notice is found. 2.636 + 2.637 + <one line to give the program's name and a brief idea of what it does.> 2.638 + Copyright (C) <year> <name of author> 2.639 + 2.640 + This program is free software: you can redistribute it and/or modify 2.641 + it under the terms of the GNU General Public License as published by 2.642 + the Free Software Foundation, either version 3 of the License, or 2.643 + (at your option) any later version. 2.644 + 2.645 + This program is distributed in the hope that it will be useful, 2.646 + but WITHOUT ANY WARRANTY; without even the implied warranty of 2.647 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.648 + GNU General Public License for more details. 2.649 + 2.650 + You should have received a copy of the GNU General Public License 2.651 + along with this program. If not, see <http://www.gnu.org/licenses/>. 2.652 + 2.653 +Also add information on how to contact you by electronic and paper mail. 2.654 + 2.655 + If the program does terminal interaction, make it output a short 2.656 +notice like this when it starts in an interactive mode: 2.657 + 2.658 + <program> Copyright (C) <year> <name of author> 2.659 + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 2.660 + This is free software, and you are welcome to redistribute it 2.661 + under certain conditions; type `show c' for details. 2.662 + 2.663 +The hypothetical commands `show w' and `show c' should show the appropriate 2.664 +parts of the General Public License. Of course, your program's commands 2.665 +might be different; for a GUI interface, you would use an "about box". 2.666 + 2.667 + You should also get your employer (if you work as a programmer) or school, 2.668 +if any, to sign a "copyright disclaimer" for the program, if necessary. 2.669 +For more information on this, and how to apply and follow the GNU GPL, see 2.670 +<http://www.gnu.org/licenses/>. 2.671 + 2.672 + The GNU General Public License does not permit incorporating your program 2.673 +into proprietary programs. If your program is a subroutine library, you 2.674 +may consider it more useful to permit linking proprietary applications with 2.675 +the library. If this is what you want to do, use the GNU Lesser General 2.676 +Public License instead of this License. But first, please read 2.677 +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/COPYING.LESSER Tue Feb 19 20:32:17 2008 +0300 3.3 @@ -0,0 +1,165 @@ 3.4 + GNU LESSER GENERAL PUBLIC LICENSE 3.5 + Version 3, 29 June 2007 3.6 + 3.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 3.8 + Everyone is permitted to copy and distribute verbatim copies 3.9 + of this license document, but changing it is not allowed. 3.10 + 3.11 + 3.12 + This version of the GNU Lesser General Public License incorporates 3.13 +the terms and conditions of version 3 of the GNU General Public 3.14 +License, supplemented by the additional permissions listed below. 3.15 + 3.16 + 0. Additional Definitions. 3.17 + 3.18 + As used herein, "this License" refers to version 3 of the GNU Lesser 3.19 +General Public License, and the "GNU GPL" refers to version 3 of the GNU 3.20 +General Public License. 3.21 + 3.22 + "The Library" refers to a covered work governed by this License, 3.23 +other than an Application or a Combined Work as defined below. 3.24 + 3.25 + An "Application" is any work that makes use of an interface provided 3.26 +by the Library, but which is not otherwise based on the Library. 3.27 +Defining a subclass of a class defined by the Library is deemed a mode 3.28 +of using an interface provided by the Library. 3.29 + 3.30 + A "Combined Work" is a work produced by combining or linking an 3.31 +Application with the Library. The particular version of the Library 3.32 +with which the Combined Work was made is also called the "Linked 3.33 +Version". 3.34 + 3.35 + The "Minimal Corresponding Source" for a Combined Work means the 3.36 +Corresponding Source for the Combined Work, excluding any source code 3.37 +for portions of the Combined Work that, considered in isolation, are 3.38 +based on the Application, and not on the Linked Version. 3.39 + 3.40 + The "Corresponding Application Code" for a Combined Work means the 3.41 +object code and/or source code for the Application, including any data 3.42 +and utility programs needed for reproducing the Combined Work from the 3.43 +Application, but excluding the System Libraries of the Combined Work. 3.44 + 3.45 + 1. Exception to Section 3 of the GNU GPL. 3.46 + 3.47 + You may convey a covered work under sections 3 and 4 of this License 3.48 +without being bound by section 3 of the GNU GPL. 3.49 + 3.50 + 2. Conveying Modified Versions. 3.51 + 3.52 + If you modify a copy of the Library, and, in your modifications, a 3.53 +facility refers to a function or data to be supplied by an Application 3.54 +that uses the facility (other than as an argument passed when the 3.55 +facility is invoked), then you may convey a copy of the modified 3.56 +version: 3.57 + 3.58 + a) under this License, provided that you make a good faith effort to 3.59 + ensure that, in the event an Application does not supply the 3.60 + function or data, the facility still operates, and performs 3.61 + whatever part of its purpose remains meaningful, or 3.62 + 3.63 + b) under the GNU GPL, with none of the additional permissions of 3.64 + this License applicable to that copy. 3.65 + 3.66 + 3. Object Code Incorporating Material from Library Header Files. 3.67 + 3.68 + The object code form of an Application may incorporate material from 3.69 +a header file that is part of the Library. You may convey such object 3.70 +code under terms of your choice, provided that, if the incorporated 3.71 +material is not limited to numerical parameters, data structure 3.72 +layouts and accessors, or small macros, inline functions and templates 3.73 +(ten or fewer lines in length), you do both of the following: 3.74 + 3.75 + a) Give prominent notice with each copy of the object code that the 3.76 + Library is used in it and that the Library and its use are 3.77 + covered by this License. 3.78 + 3.79 + b) Accompany the object code with a copy of the GNU GPL and this license 3.80 + document. 3.81 + 3.82 + 4. Combined Works. 3.83 + 3.84 + You may convey a Combined Work under terms of your choice that, 3.85 +taken together, effectively do not restrict modification of the 3.86 +portions of the Library contained in the Combined Work and reverse 3.87 +engineering for debugging such modifications, if you also do each of 3.88 +the following: 3.89 + 3.90 + a) Give prominent notice with each copy of the Combined Work that 3.91 + the Library is used in it and that the Library and its use are 3.92 + covered by this License. 3.93 + 3.94 + b) Accompany the Combined Work with a copy of the GNU GPL and this license 3.95 + document. 3.96 + 3.97 + c) For a Combined Work that displays copyright notices during 3.98 + execution, include the copyright notice for the Library among 3.99 + these notices, as well as a reference directing the user to the 3.100 + copies of the GNU GPL and this license document. 3.101 + 3.102 + d) Do one of the following: 3.103 + 3.104 + 0) Convey the Minimal Corresponding Source under the terms of this 3.105 + License, and the Corresponding Application Code in a form 3.106 + suitable for, and under terms that permit, the user to 3.107 + recombine or relink the Application with a modified version of 3.108 + the Linked Version to produce a modified Combined Work, in the 3.109 + manner specified by section 6 of the GNU GPL for conveying 3.110 + Corresponding Source. 3.111 + 3.112 + 1) Use a suitable shared library mechanism for linking with the 3.113 + Library. A suitable mechanism is one that (a) uses at run time 3.114 + a copy of the Library already present on the user's computer 3.115 + system, and (b) will operate properly with a modified version 3.116 + of the Library that is interface-compatible with the Linked 3.117 + Version. 3.118 + 3.119 + e) Provide Installation Information, but only if you would otherwise 3.120 + be required to provide such information under section 6 of the 3.121 + GNU GPL, and only to the extent that such information is 3.122 + necessary to install and execute a modified version of the 3.123 + Combined Work produced by recombining or relinking the 3.124 + Application with a modified version of the Linked Version. (If 3.125 + you use option 4d0, the Installation Information must accompany 3.126 + the Minimal Corresponding Source and Corresponding Application 3.127 + Code. If you use option 4d1, you must provide the Installation 3.128 + Information in the manner specified by section 6 of the GNU GPL 3.129 + for conveying Corresponding Source.) 3.130 + 3.131 + 5. Combined Libraries. 3.132 + 3.133 + You may place library facilities that are a work based on the 3.134 +Library side by side in a single library together with other library 3.135 +facilities that are not Applications and are not covered by this 3.136 +License, and convey such a combined library under terms of your 3.137 +choice, if you do both of the following: 3.138 + 3.139 + a) Accompany the combined library with a copy of the same work based 3.140 + on the Library, uncombined with any other library facilities, 3.141 + conveyed under the terms of this License. 3.142 + 3.143 + b) Give prominent notice with the combined library that part of it 3.144 + is a work based on the Library, and explaining where to find the 3.145 + accompanying uncombined form of the same work. 3.146 + 3.147 + 6. Revised Versions of the GNU Lesser General Public License. 3.148 + 3.149 + The Free Software Foundation may publish revised and/or new versions 3.150 +of the GNU Lesser General Public License from time to time. Such new 3.151 +versions will be similar in spirit to the present version, but may 3.152 +differ in detail to address new problems or concerns. 3.153 + 3.154 + Each version is given a distinguishing version number. If the 3.155 +Library as you received it specifies that a certain numbered version 3.156 +of the GNU Lesser General Public License "or any later version" 3.157 +applies to it, you have the option of following the terms and 3.158 +conditions either of that published version or of any later version 3.159 +published by the Free Software Foundation. If the Library as you 3.160 +received it does not specify a version number of the GNU Lesser 3.161 +General Public License, you may choose any version of the GNU Lesser 3.162 +General Public License ever published by the Free Software Foundation. 3.163 + 3.164 + If the Library as you received it specifies that a proxy can decide 3.165 +whether future versions of the GNU Lesser General Public License shall 3.166 +apply, that proxy's public statement of acceptance of any version is 3.167 +permanent authorization for you to choose that version for the 3.168 +Library.
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/COPYING.apache Tue Feb 19 20:32:17 2008 +0300 4.3 @@ -0,0 +1,202 @@ 4.4 + Apache License 4.5 + Version 2.0, January 2004 4.6 + http://www.apache.org/licenses/ 4.7 + 4.8 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 4.9 + 4.10 + 1. Definitions. 4.11 + 4.12 + "License" shall mean the terms and conditions for use, reproduction, 4.13 + and distribution as defined by Sections 1 through 9 of this document. 4.14 + 4.15 + "Licensor" shall mean the copyright owner or entity authorized by 4.16 + the copyright owner that is granting the License. 4.17 + 4.18 + "Legal Entity" shall mean the union of the acting entity and all 4.19 + other entities that control, are controlled by, or are under common 4.20 + control with that entity. For the purposes of this definition, 4.21 + "control" means (i) the power, direct or indirect, to cause the 4.22 + direction or management of such entity, whether by contract or 4.23 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 4.24 + outstanding shares, or (iii) beneficial ownership of such entity. 4.25 + 4.26 + "You" (or "Your") shall mean an individual or Legal Entity 4.27 + exercising permissions granted by this License. 4.28 + 4.29 + "Source" form shall mean the preferred form for making modifications, 4.30 + including but not limited to software source code, documentation 4.31 + source, and configuration files. 4.32 + 4.33 + "Object" form shall mean any form resulting from mechanical 4.34 + transformation or translation of a Source form, including but 4.35 + not limited to compiled object code, generated documentation, 4.36 + and conversions to other media types. 4.37 + 4.38 + "Work" shall mean the work of authorship, whether in Source or 4.39 + Object form, made available under the License, as indicated by a 4.40 + copyright notice that is included in or attached to the work 4.41 + (an example is provided in the Appendix below). 4.42 + 4.43 + "Derivative Works" shall mean any work, whether in Source or Object 4.44 + form, that is based on (or derived from) the Work and for which the 4.45 + editorial revisions, annotations, elaborations, or other modifications 4.46 + represent, as a whole, an original work of authorship. For the purposes 4.47 + of this License, Derivative Works shall not include works that remain 4.48 + separable from, or merely link (or bind by name) to the interfaces of, 4.49 + the Work and Derivative Works thereof. 4.50 + 4.51 + "Contribution" shall mean any work of authorship, including 4.52 + the original version of the Work and any modifications or additions 4.53 + to that Work or Derivative Works thereof, that is intentionally 4.54 + submitted to Licensor for inclusion in the Work by the copyright owner 4.55 + or by an individual or Legal Entity authorized to submit on behalf of 4.56 + the copyright owner. For the purposes of this definition, "submitted" 4.57 + means any form of electronic, verbal, or written communication sent 4.58 + to the Licensor or its representatives, including but not limited to 4.59 + communication on electronic mailing lists, source code control systems, 4.60 + and issue tracking systems that are managed by, or on behalf of, the 4.61 + Licensor for the purpose of discussing and improving the Work, but 4.62 + excluding communication that is conspicuously marked or otherwise 4.63 + designated in writing by the copyright owner as "Not a Contribution." 4.64 + 4.65 + "Contributor" shall mean Licensor and any individual or Legal Entity 4.66 + on behalf of whom a Contribution has been received by Licensor and 4.67 + subsequently incorporated within the Work. 4.68 + 4.69 + 2. Grant of Copyright License. Subject to the terms and conditions of 4.70 + this License, each Contributor hereby grants to You a perpetual, 4.71 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 4.72 + copyright license to reproduce, prepare Derivative Works of, 4.73 + publicly display, publicly perform, sublicense, and distribute the 4.74 + Work and such Derivative Works in Source or Object form. 4.75 + 4.76 + 3. Grant of Patent License. Subject to the terms and conditions of 4.77 + this License, each Contributor hereby grants to You a perpetual, 4.78 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 4.79 + (except as stated in this section) patent license to make, have made, 4.80 + use, offer to sell, sell, import, and otherwise transfer the Work, 4.81 + where such license applies only to those patent claims licensable 4.82 + by such Contributor that are necessarily infringed by their 4.83 + Contribution(s) alone or by combination of their Contribution(s) 4.84 + with the Work to which such Contribution(s) was submitted. If You 4.85 + institute patent litigation against any entity (including a 4.86 + cross-claim or counterclaim in a lawsuit) alleging that the Work 4.87 + or a Contribution incorporated within the Work constitutes direct 4.88 + or contributory patent infringement, then any patent licenses 4.89 + granted to You under this License for that Work shall terminate 4.90 + as of the date such litigation is filed. 4.91 + 4.92 + 4. Redistribution. You may reproduce and distribute copies of the 4.93 + Work or Derivative Works thereof in any medium, with or without 4.94 + modifications, and in Source or Object form, provided that You 4.95 + meet the following conditions: 4.96 + 4.97 + (a) You must give any other recipients of the Work or 4.98 + Derivative Works a copy of this License; and 4.99 + 4.100 + (b) You must cause any modified files to carry prominent notices 4.101 + stating that You changed the files; and 4.102 + 4.103 + (c) You must retain, in the Source form of any Derivative Works 4.104 + that You distribute, all copyright, patent, trademark, and 4.105 + attribution notices from the Source form of the Work, 4.106 + excluding those notices that do not pertain to any part of 4.107 + the Derivative Works; and 4.108 + 4.109 + (d) If the Work includes a "NOTICE" text file as part of its 4.110 + distribution, then any Derivative Works that You distribute must 4.111 + include a readable copy of the attribution notices contained 4.112 + within such NOTICE file, excluding those notices that do not 4.113 + pertain to any part of the Derivative Works, in at least one 4.114 + of the following places: within a NOTICE text file distributed 4.115 + as part of the Derivative Works; within the Source form or 4.116 + documentation, if provided along with the Derivative Works; or, 4.117 + within a display generated by the Derivative Works, if and 4.118 + wherever such third-party notices normally appear. The contents 4.119 + of the NOTICE file are for informational purposes only and 4.120 + do not modify the License. You may add Your own attribution 4.121 + notices within Derivative Works that You distribute, alongside 4.122 + or as an addendum to the NOTICE text from the Work, provided 4.123 + that such additional attribution notices cannot be construed 4.124 + as modifying the License. 4.125 + 4.126 + You may add Your own copyright statement to Your modifications and 4.127 + may provide additional or different license terms and conditions 4.128 + for use, reproduction, or distribution of Your modifications, or 4.129 + for any such Derivative Works as a whole, provided Your use, 4.130 + reproduction, and distribution of the Work otherwise complies with 4.131 + the conditions stated in this License. 4.132 + 4.133 + 5. Submission of Contributions. Unless You explicitly state otherwise, 4.134 + any Contribution intentionally submitted for inclusion in the Work 4.135 + by You to the Licensor shall be under the terms and conditions of 4.136 + this License, without any additional terms or conditions. 4.137 + Notwithstanding the above, nothing herein shall supersede or modify 4.138 + the terms of any separate license agreement you may have executed 4.139 + with Licensor regarding such Contributions. 4.140 + 4.141 + 6. Trademarks. This License does not grant permission to use the trade 4.142 + names, trademarks, service marks, or product names of the Licensor, 4.143 + except as required for reasonable and customary use in describing the 4.144 + origin of the Work and reproducing the content of the NOTICE file. 4.145 + 4.146 + 7. Disclaimer of Warranty. Unless required by applicable law or 4.147 + agreed to in writing, Licensor provides the Work (and each 4.148 + Contributor provides its Contributions) on an "AS IS" BASIS, 4.149 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 4.150 + implied, including, without limitation, any warranties or conditions 4.151 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 4.152 + PARTICULAR PURPOSE. You are solely responsible for determining the 4.153 + appropriateness of using or redistributing the Work and assume any 4.154 + risks associated with Your exercise of permissions under this License. 4.155 + 4.156 + 8. Limitation of Liability. In no event and under no legal theory, 4.157 + whether in tort (including negligence), contract, or otherwise, 4.158 + unless required by applicable law (such as deliberate and grossly 4.159 + negligent acts) or agreed to in writing, shall any Contributor be 4.160 + liable to You for damages, including any direct, indirect, special, 4.161 + incidental, or consequential damages of any character arising as a 4.162 + result of this License or out of the use or inability to use the 4.163 + Work (including but not limited to damages for loss of goodwill, 4.164 + work stoppage, computer failure or malfunction, or any and all 4.165 + other commercial damages or losses), even if such Contributor 4.166 + has been advised of the possibility of such damages. 4.167 + 4.168 + 9. Accepting Warranty or Additional Liability. While redistributing 4.169 + the Work or Derivative Works thereof, You may choose to offer, 4.170 + and charge a fee for, acceptance of support, warranty, indemnity, 4.171 + or other liability obligations and/or rights consistent with this 4.172 + License. However, in accepting such obligations, You may act only 4.173 + on Your own behalf and on Your sole responsibility, not on behalf 4.174 + of any other Contributor, and only if You agree to indemnify, 4.175 + defend, and hold each Contributor harmless for any liability 4.176 + incurred by, or claims asserted against, such Contributor by reason 4.177 + of your accepting any such warranty or additional liability. 4.178 + 4.179 + END OF TERMS AND CONDITIONS 4.180 + 4.181 + APPENDIX: How to apply the Apache License to your work. 4.182 + 4.183 + To apply the Apache License to your work, attach the following 4.184 + boilerplate notice, with the fields enclosed by brackets "[]" 4.185 + replaced with your own identifying information. (Don't include 4.186 + the brackets!) The text should be enclosed in the appropriate 4.187 + comment syntax for the file format. We also recommend that a 4.188 + file or class name and description of purpose be included on the 4.189 + same "printed page" as the copyright notice for easier 4.190 + identification within third-party archives. 4.191 + 4.192 + Copyright [yyyy] [name of copyright owner] 4.193 + 4.194 + Licensed under the Apache License, Version 2.0 (the "License"); 4.195 + you may not use this file except in compliance with the License. 4.196 + You may obtain a copy of the License at 4.197 + 4.198 + http://www.apache.org/licenses/LICENSE-2.0 4.199 + 4.200 + Unless required by applicable law or agreed to in writing, software 4.201 + distributed under the License is distributed on an "AS IS" BASIS, 4.202 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4.203 + See the License for the specific language governing permissions and 4.204 + limitations under the License. 4.205 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/NOTICE Tue Feb 19 20:32:17 2008 +0300 5.3 @@ -0,0 +1,13 @@ 5.4 +Tema 5.5 +Copyright 2006-2008 Mikhail Kryshen <mikhail@kryshen.pp.ru> 5.6 + 5.7 +This is free software. You may redistribute copies of it under the terms of 5.8 +the GNU Lesser General Public License version 3 or later. 5.9 + 5.10 + 5.11 + 5.12 +Apache Commons CLI 5.13 +Copyright 2001-2007 The Apache Software Foundation 5.14 + 5.15 +This product includes software developed by 5.16 +The Apache Software Foundation (http://www.apache.org/).
6.1 --- a/TODO Thu Dec 14 23:22:05 2006 +0300 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,1 +0,0 @@ 6.4 -if, <, >, =, +, -, *, /
7.1 --- a/build.xml Thu Dec 14 23:22:05 2006 +0300 7.2 +++ b/build.xml Tue Feb 19 20:32:17 2008 +0300 7.3 @@ -1,44 +1,113 @@ 7.4 <?xml version="1.0"?> 7.5 <project name="tema" default="dist" basedir="."> 7.6 - 7.7 + 7.8 + <property name="version" value="0.3"/> 7.9 + 7.10 <property name="src" value="src"/> 7.11 <property name="build" value="build"/> 7.12 <property name="dist" value="dist"/> 7.13 <property name="res" value="res"/> 7.14 <property name="doc" value="doc"/> 7.15 + <property name="lib" value="${dist}/lib"/> 7.16 <property name="jar_file" value="tema.jar"/> 7.17 - 7.18 + 7.19 + <property name="ant_jar" value="/usr/share/java/ant.jar"/> 7.20 + 7.21 + <path id="project.libs"> 7.22 + <fileset dir="${lib}"> 7.23 + <include name="**/*.jar"/> 7.24 + </fileset> 7.25 + </path> 7.26 + 7.27 <target name="init"> 7.28 - <tstamp/> 7.29 - <mkdir dir="${build}"/> 7.30 + <tstamp/> 7.31 + <mkdir dir="${build}"/> 7.32 </target> 7.33 - 7.34 + 7.35 <target name="compile" depends="init"> 7.36 <javac srcdir="${src}" destdir="${build}" 7.37 deprecation="on" optimize="on" debug="on"> 7.38 - <!-- <compilerarg value="-Xlint:unchecked"/> --> 7.39 + <compilerarg value="-Xlint:unchecked"/> 7.40 + <classpath refid="project.libs"/> 7.41 </javac> 7.42 + 7.43 + <copy todir="${build}"> 7.44 + <fileset dir="${res}"/> 7.45 + </copy> 7.46 + </target> 7.47 + 7.48 + <target name="dist" depends="compile"> 7.49 + <jar jarfile="${dist}/${jar_file}" manifest="${src}/Manifest.mf"> 7.50 + <fileset dir="${build}" includes="**/*.class"/> 7.51 + <fileset dir="${build}" includes="**/*.template"/> 7.52 + </jar> 7.53 + </target> 7.54 + 7.55 + <target name="run" depends="compile"> 7.56 + <java classname="kryshen.tema.Tema" fork="true"> 7.57 + <classpath> 7.58 + <pathelement location="${build}"/> 7.59 + <path refid="project.libs"/> 7.60 + </classpath> 7.61 + </java> 7.62 + </target> 7.63 + 7.64 + <target name="run.demo" depends="compile"> 7.65 + <java classname="kryshen.tema.Tema" fork="true"> 7.66 + <classpath> 7.67 + <pathelement location="${build}"/> 7.68 + <path refid="project.libs"/> 7.69 + </classpath> 7.70 + <arg value="-demo"/> 7.71 + </java> 7.72 + </target> 7.73 + 7.74 + <target name="doc.manual" depends="dist"> 7.75 + <taskdef name="tema" 7.76 + classname="kryshen.tema.ant.TemaTask" 7.77 + classpath="${dist}/tema.jar"/> 7.78 + 7.79 + <tema infile="${doc}/manual/manual.tema" 7.80 + outfile="${doc}/manual/manual.html" 7.81 + basedir="${doc}/manual"/> 7.82 </target> 7.83 7.84 - <target name="dist" depends="compile"> 7.85 - <jar jarfile="${dist}/${jar_file}" manifest="${src}/Manifest.mf"> 7.86 - <fileset dir="${build}" includes="**/*.class"/> 7.87 - <fileset dir="${res}" includes="**/*"/> 7.88 - </jar> 7.89 - </target> 7.90 - 7.91 - <target name="javadoc" depends="init"> 7.92 + <target name="doc.api" depends="init"> 7.93 <javadoc destdir="${doc}/api" sourcepath="${src}" 7.94 packagenames="kryshen.tema.*"> 7.95 + <classpath> 7.96 + <path refid="project.libs"/> 7.97 + <pathelement location="${ant_jar}"/> 7.98 + </classpath> 7.99 </javadoc> 7.100 </target> 7.101 - 7.102 - <target name="clean"> 7.103 - <delete> 7.104 - <fileset dir="${build}" includes="**/*.class"/> 7.105 - </delete> 7.106 - <delete file="${dist}/${jar_file}"/> 7.107 - <delete dir="${doc}/api"/> 7.108 + 7.109 + <target name="package.tar" depends="dist,doc.manual,doc.api"> 7.110 + <tar destfile="${dist}/${ant.project.name}-${version}.tar.gz" 7.111 + compression="gzip"> 7.112 + <tarfileset dir="${basedir}" 7.113 + prefix="${ant.project.name}-${version}"> 7.114 + <exclude name="${build}/**"/> 7.115 + <exclude name="misc/**"/> 7.116 + <exclude name="test/**"/> 7.117 + <exclude name="nbproject/**"/> 7.118 + <exclude name="${dist}/${ant.project.name}-*.tar.gz"/> 7.119 + <exclude name="${dist}/tema"/> 7.120 + </tarfileset> 7.121 + <tarfileset dir="${basedir}" 7.122 + prefix="${ant.project.name}-${version}" 7.123 + mode="755"> 7.124 + <include name="${dist}/tema"/> 7.125 + </tarfileset> 7.126 + </tar> 7.127 + </target> 7.128 + 7.129 + <target name="clean" depends="init"> 7.130 + <delete> 7.131 + <fileset dir="${build}" includes="**/*.class"/> 7.132 + </delete> 7.133 + <delete file="${dist}/${jar_file}"/> 7.134 + <delete dir="${doc}/api"/> 7.135 </target> 7.136 7.137 </project>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/dist/.cvsignore Tue Feb 19 20:32:17 2008 +0300 8.3 @@ -0,0 +1,2 @@ 8.4 +tema.jar 8.5 +tema-*.tar.gz
9.1 --- a/dist/biotopes/biotope-top.sql Thu Dec 14 23:22:05 2006 +0300 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,20 +0,0 @@ 9.4 -SELECT t1.*, 9.5 - 9.6 -(SELECT t2.rusname FROM biotopelist AS t2 9.7 -WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) AND 9.8 -Right(t2.rangcode, 8) = '00000000') AS class0, 9.9 - 9.10 -(SELECT t2.rusname FROM biotopelist AS t2 9.11 -WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) AND 9.12 -Right(t2.rangcode, 6) = '000000') AS class1, 9.13 - 9.14 -(SELECT t2.rusname FROM biotopelist AS t2 9.15 -WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) AND 9.16 -Right(t2.rangcode, 4) = '0000') AS class2, 9.17 - 9.18 -(SELECT t2.rusname FROM biotopelist AS t2 9.19 -WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) AND 9.20 -Right(t2.rangcode, 2) = '00') AS class3 9.21 - 9.22 -FROM biotopelist AS t1 9.23 -WHERE Right(t1.rangcode, 2) <> '00' AND rusname
10.1 --- a/dist/biotopes/biotope.sql Thu Dec 14 23:22:05 2006 +0300 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,24 +0,0 @@ 10.4 -SELECT t1.*, 10.5 - 10.6 -(SELECT t2.rusname FROM biotopelist AS t2 10.7 -WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 10.8 -AND Right(t2.rangcode, 8) = '00000000' 10.9 -AND Right(t1.rangcode, 8) <> '00000000') AS class0, 10.10 - 10.11 -(SELECT t2.rusname FROM biotopelist AS t2 10.12 -WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 10.13 -AND Right(t2.rangcode, 6) = '000000' 10.14 -AND Right(t1.rangcode, 6) <> '000000') AS class1, 10.15 - 10.16 -(SELECT t2.rusname FROM biotopelist AS t2 10.17 -WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 10.18 -AND Right(t2.rangcode, 4) = '0000' 10.19 -AND Right(t1.rangcode, 4) <> '0000') AS class2, 10.20 - 10.21 -(SELECT t2.rusname FROM biotopelist AS t2 10.22 -WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 10.23 -AND Right(t2.rangcode, 2) = '00' 10.24 -AND Right(t1.rangcode, 2) <> '00') AS class3 10.25 - 10.26 -FROM biotopelist AS t1 10.27 -WHERE rusname
11.1 --- a/dist/biotopes/biotope.template Thu Dec 14 23:22:05 2006 +0300 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,17 +0,0 @@ 11.4 -<?xml version="1.0" encoding="ISO-8859-5"?> 11.5 -<!DOCTYPE _ SYSTEM "brief.dtd"> 11.6 -<!-- rangcode: <%xml_escape db\rangcode%> --> 11.7 -<_ show="0"> 11.8 - < display="0"> 11.9 - <%optional:<_ ="1" file="<%xml_escape image:maps/<%db\rangcode%>.gif maps/<%db\code%>.png png%>"/>%> 11.10 -<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 11.11 - </> 11.12 - <><%xml_escape db\rusname%></> 11.13 - <><%xml_escape db\class0%></> 11.14 - <1><%xml_escape db\class1%></1> 11.15 - <2><%xml_escape db\class2%></2> 11.16 - <3><%xml_escape db\class3%></3> 11.17 - <_ rows="3"><%xml_cdata db\descript%></_> 11.18 - <_ rows="3"><%xml_cdata db\geobotdescr%></_> 11.19 - <_><%xml_escape db\contributors%></_> 11.20 -</_>
12.1 --- a/dist/biotopes/brief.dtd Thu Dec 14 23:22:05 2006 +0300 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,27 +0,0 @@ 12.4 -<?xml encoding="ISO-8859-5"?> 12.5 -<!ELEMENT _ (?, , , 1, 2, 3, _, _, _)> 12.6 -<!ELEMENT (|_)*> 12.7 -<!ELEMENT EMPTY> 12.8 -<!ELEMENT _ EMPTY> 12.9 -<!ELEMENT (#PCDATA)> 12.10 -<!ELEMENT (#PCDATA)> 12.11 -<!ELEMENT 1 (#PCDATA)> 12.12 -<!ELEMENT 2 (#PCDATA)> 12.13 -<!ELEMENT 3 (#PCDATA)> 12.14 -<!ELEMENT _ (#PCDATA)> 12.15 -<!ELEMENT _ (#PCDATA)> 12.16 -<!ELEMENT _ (#PCDATA)> 12.17 -<!ATTLIST _ show (0|1) "1"> 12.18 -<!ATTLIST 12.19 - display CDATA #FIXED "0"> 12.20 -<!ATTLIST 12.21 - num ID #REQUIRED 12.22 - file CDATA #REQUIRED 12.23 - big CDATA #REQUIRED 12.24 - text CDATA #IMPLIED 12.25 - CDATA #IMPLIED> 12.26 -<!ATTLIST _ 12.27 - num ID #REQUIRED 12.28 - file CDATA #REQUIRED> 12.29 -<!ATTLIST _ rows CDATA #FIXED "3"> 12.30 -<!ATTLIST _ rows CDATA #FIXED "3">
13.1 --- a/dist/biotopes/class.sql Thu Dec 14 23:22:05 2006 +0300 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,7 +0,0 @@ 13.4 -SELECT t1.* 13.5 -FROM biotopelist AS t1 13.6 -WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 13.7 - AND EXISTS 13.8 - (SELECT NULL FROM biotopelist AS t2 13.9 - WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 13.10 - AND Right(t2.rangcode, 8) <> '00000000')
14.1 --- a/dist/biotopes/classes.template Thu Dec 14 23:22:05 2006 +0300 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,5 +0,0 @@ 14.4 -<?xml version="1.0" encoding="ISO-8859-5"?> 14.5 -<><%query:class_sql [%\ 14.6 - <!-- rangcode: <%xml_escape get\rangcode%> --> 14.7 - < id="<%get\NUMBER%>"><%xml_escape db\rusname%></>%]%> 14.8 -</>
15.1 --- a/dist/biotopes/doc/article.txt Thu Dec 14 23:22:05 2006 +0300 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,391 +0,0 @@ 15.4 -* XML- . 15.5 - 15.6 - " 15.7 -" Microsoft Access XML- 15.8 - DbReader. 15.9 - 15.10 - DbReader 15.11 - . 15.12 - 15.13 - . 15.14 - SQL-, 15.15 -. 15.16 - 15.17 - 15.18 -* : 15.19 - 15.20 - <%<_>{:|\}<>%> 15.21 - 15.22 - 15.23 -<_> - , . 15.24 - . 15.25 -<> - , . 15.26 - 15.27 - 15.28 -* : 15.29 - 15.30 - [<_>][<>] 15.31 - 15.32 - 15.33 -<_> - , . 15.34 - . 15.35 -<> - , . 15.36 - . , 15.37 - , . 15.38 - 15.39 - , 15.40 - : 15.41 -: - , 15.42 -\ - . 15.43 - 15.44 - , , 15.45 - , 15.46 - . 15.47 - 15.48 - - . 15.49 - - . , 15.50 - - 15.51 -. 15.52 - 15.53 - '<', '>' '[', ']'. 15.54 - 15.55 - 15.56 -* : 15.57 - 15.58 -: set 15.59 -: <> 15.60 -: <> 15.61 -: <> 15.62 -: <> 15.63 - : 1 15.64 - 15.65 -: get 15.66 -: <> 15.67 -: <>. 15.68 - : 1, , 0 - . 15.69 - 15.70 -: prepare 15.71 -: <> 15.72 -: <> 15.73 -: SQL- <> , 15.74 - <>. 15.75 -: <> 15.76 - : 1 15.77 - 15.78 -: query 15.79 -: <_> <> <1> ... <N> 15.80 -: , 15.81 - prepare. 15.82 - '?'. 15.83 - , <>. 15.84 - <> NUMBER, 15.85 - . , 15.86 - , 15.87 - <> SUPER.<_>. 15.88 - 15.89 -: <> 15.90 - . 15.91 - : . 15.92 - 15.93 -: optional 15.94 -: <> 15.95 -: <>, 15.96 - 0, - . 15.97 - : 1, - , 0 - . 15.98 - 15.99 -: image 15.100 -: <_> <_> <> [<_> [<_>]] 15.101 -: <_> ( 15.102 - "resource_base") 15.103 - , 15.104 - <_>. , 15.105 - . 15.106 -: <_> , - . 15.107 - : 1 , 0 - . 15.108 - 15.109 -: copy 15.110 -: <_> <_> 15.111 -: <_> <_> 15.112 - ( <_> 15.113 - "resource_base"). 15.114 -: <_> , - . 15.115 - : 1 , 0 - . 15.116 - 15.117 -: write 15.118 -: <_> 15.119 -: <> 15.120 -: <> <_>. 15.121 -: <_> , - . 15.122 - : 1 , 0 - . 15.123 - 15.124 -: read 15.125 -: <_> 15.126 -: <_>. 15.127 -: , 15.128 - - . 15.129 - : 1 , 0 - . 15.130 - 15.131 -: include 15.132 -: <_> 15.133 -: <_>. 15.134 -: . 15.135 - : , . 15.136 - 15.137 -: ! 15.138 -: <> 15.139 -: . 15.140 -: . 15.141 - : , . 15.142 - 15.143 -: replace 15.144 -: <1> <2> 15.145 -: <> 15.146 -: , <1> 15.147 - <2>. 15.148 - : , . 15.149 - 15.150 -: xml_escape 15.151 -: <> 15.152 -: <>, 15.153 - '&', '<', '>', '`', '\' 15.154 - XML. 15.155 - : , . 15.156 - 15.157 -: xml_cdata 15.158 -: <> 15.159 -: XML CDATA. 15.160 - : , . 15.161 - 15.162 - DbReader : 15.163 -, Java. 15.164 - 15.165 - 15.166 -* DbReader 15.167 - " " Microsoft Access 15.168 - XML- 15.169 - 15.170 - " 15.171 - " ( ): 15.172 - 15.173 -biotopelist (code, rangcode, rusname, engname, descript, geobotdescr, 15.174 - contributors, descrdate) 15.175 - 15.176 - code - , ; 15.177 - rangcode - ABBCCDDEE, , BB, CC, DD, - 15.178 - , ; 15.179 - rusname, engname, descript, geobotdescr - ; 15.180 - descrdate - . 15.181 - 15.182 -photos (biotope, photo, authphoto) 15.183 - 15.184 - biotope - , code biotopelist; 15.185 - photo - ; 15.186 - authphoto - . 15.187 - 15.188 - xml- biotopelist, 15.189 - , , 15.190 - . 15.191 - 15.192 - xml- 15.193 - DbReader ( biotope.template): 15.194 - 15.195 ----------------------------------------------------------------------- 15.196 -<?xml version="1.0" encoding="ISO-8859-5"?> 15.197 -<!DOCTYPE _ SYSTEM "brief.dtd"> 15.198 -<!-- rangcode: <%xml_escape get\rangcode%> --> 15.199 -<_ show="0"> 15.200 - < display="0"> 15.201 - <%optional:<_ ="1" 15.202 - file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%> 15.203 -<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 15.204 - </> 15.205 - <><%xml_escape get\rusname%></> 15.206 - <><%xml_escape get\class0%></> 15.207 - <1><%xml_escape get\class1%></1> 15.208 - <2><%xml_escape get\class2%></2> 15.209 - <3><%xml_escape get\class3%></3> 15.210 - <_ rows="3"><%xml_cdata get\descript%></_> 15.211 - <_ rows="3"><%xml_cdata get\geobotdescr%></_> 15.212 - <_><%xml_escape get\contributors%></_> 15.213 -</_> 15.214 ----------------------------------------------------------------------- 15.215 - 15.216 - SQL-, 15.217 - rangcode, rusname, class0, class1, class2, 15.218 -class3, descript, geobotdescr contributors ( biotope.sql): 15.219 - 15.220 ----------------------------------------------------------------------- 15.221 -SELECT t1.*, 15.222 - 15.223 -(SELECT t2.rusname FROM biotopelist AS t2 15.224 -WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 15.225 -AND Right(t2.rangcode, 8) = '00000000' 15.226 -AND Right(t1.rangcode, 8) <> '00000000') AS class0, 15.227 - 15.228 -(SELECT t2.rusname FROM biotopelist AS t2 15.229 -WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 15.230 -AND Right(t2.rangcode, 6) = '000000' 15.231 -AND Right(t1.rangcode, 6) <> '000000') AS class1, 15.232 - 15.233 -(SELECT t2.rusname FROM biotopelist AS t2 15.234 -WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 15.235 -AND Right(t2.rangcode, 4) = '0000' 15.236 -AND Right(t1.rangcode, 4) <> '0000') AS class2, 15.237 - 15.238 -(SELECT t2.rusname FROM biotopelist AS t2 15.239 -WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 15.240 -AND Right(t2.rangcode, 2) = '00' 15.241 -AND Right(t1.rangcode, 2) <> '00') AS class3 15.242 - 15.243 -FROM biotopelist AS t1 15.244 -WHERE rusname 15.245 ----------------------------------------------------------------------- 15.246 - 15.247 - biotope.template <%include\photo.template%>, 15.248 - ( photo.template): 15.249 - 15.250 ----------------------------------------------------------------------- 15.251 - < num="<%xml_escape get\NUMBER%>" 15.252 - <%optional:="<%xml_escape get\authphoto%>" %>text="" 15.253 - file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>" 15.254 - big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/> 15.255 ----------------------------------------------------------------------- 15.256 - 15.257 - SQL- 15.258 -(photo.sql): 15.259 - 15.260 ----------------------------------------------------------------------- 15.261 -SELECT * from photos WHERE biotope = ? 15.262 ----------------------------------------------------------------------- 15.263 - 15.264 -, ( classes.template): 15.265 - 15.266 ----------------------------------------------------------------------- 15.267 -<?xml version="1.0" encoding="ISO-8859-5"?> 15.268 -<><%query:class_sql [%\ 15.269 - <!-- rangcode: <%xml_escape get\rangcode%> --> 15.270 - < id="<%get\NUMBER%>"><%xml_escape get\rusname%></>%]%> 15.271 -</> 15.272 ----------------------------------------------------------------------- 15.273 - 15.274 - SQL- (class.sql): 15.275 - 15.276 ----------------------------------------------------------------------- 15.277 -SELECT t1.* 15.278 -FROM biotopelist AS t1 15.279 -WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 15.280 - AND EXISTS 15.281 - (SELECT NULL FROM biotopelist AS t2 15.282 - WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 15.283 - AND Right(t2.rangcode, 8) <> '00000000') 15.284 ----------------------------------------------------------------------- 15.285 - 15.286 -, ( plants.template): 15.287 - 15.288 ----------------------------------------------------------------------- 15.289 -<?xml version="1.0" encoding="ISO-8859-5"?> 15.290 -<><%query:plant_sql [%\ 15.291 - <!-- rangcode: <%xml_escape get\rangcode%> --> 15.292 - <><%xml_escape get\rusname%></>%]%> 15.293 -</> 15.294 ----------------------------------------------------------------------- 15.295 - 15.296 - SQL- (plant.sql): 15.297 - 15.298 ----------------------------------------------------------------------- 15.299 -SELECT t1.* 15.300 -FROM biotopelist AS t1 15.301 -WHERE rusname AND Right(t1.rangcode, 2) <> '00' 15.302 ----------------------------------------------------------------------- 15.303 - 15.304 - DbReader index.template, 15.305 - SQL- 15.306 -: 15.307 - 15.308 ----------------------------------------------------------------------- 15.309 -<%!: 15.310 - <%prepare:biotope_sql <%read\biotope.sql%>%> 15.311 - <%prepare:photo_sql <%read\photo.sql%>%> 15.312 - <%prepare:class_sql <%read\class.sql%>%> 15.313 - <%prepare:plant_sql <%read\plant.sql%>%> 15.314 - 15.315 - <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%> 15.316 - 15.317 - <%write:classes.xml <%include\classes.template%>%> 15.318 - <%write:plants.xml <%include\plants.template%>%> 15.319 -%> 15.320 ----------------------------------------------------------------------- 15.321 - 15.322 - XML-: 15.323 - 15.324 ----------------------------------------------------------------------- 15.325 -<?xml version="1.0" encoding="ISO-8859-5"?> 15.326 -<!DOCTYPE _ SYSTEM "brief.dtd"> 15.327 -<!-- rangcode: E04020302 --> 15.328 -<_ show="0"> 15.329 - < display="0"> 15.330 - < num="1" =" .." text="" 15.331 - file="images/3_1.jpg" 15.332 - big="images/big/3_1.jpg"/> 15.333 - < num="2" =" .." text="" 15.334 - file="images/3_2.jpg" 15.335 - big="images/big/3_2.jpg"/> 15.336 - </> 15.337 - <>Betula sp. - Avenella flexuosa - Polytrichum commune</> 15.338 - <>E. </> 15.339 - <1> </1> 15.340 - <2></2> 15.341 - <3></3> 15.342 - <_ rows="3"><![CDATA[ . 5 - 7 , , , .]]></_> 15.343 - <_ rows="3"></_> 15.344 - <_></_> 15.345 -</_> 15.346 ----------------------------------------------------------------------- 15.347 - 15.348 - 15.349 -* DbReader 15.350 - 15.351 - DbReader Java 15.352 - : 15.353 - 15.354 -ru.karrc.dbreader.DbReader: c . 15.355 -, 15.356 - JDBC, . 15.357 - 15.358 -ru.karrc.dbreader.TemplateParser: , 15.359 - . 15.360 - 15.361 -ru.karrc.dbreader.Function: . 15.362 -DbReader . 15.363 - 15.364 -ru.karrc.dbreader.FunctionDataParser: 15.365 -. , 15.366 -. 15.367 - TemplateParser. 15.368 - 15.369 -ru.karrc.dbreader.Functions: 15.370 - , Function. 15.371 - 15.372 -ru.karrc.dbreader.TemplateParser: , 15.373 - . 15.374 - 15.375 - , , 15.376 - . 15.377 - 15.378 - 15.379 -* . 15.380 - 15.381 - : 8, 15.382 - Java- ( ): 27, 15.383 - : 1311, 15.384 - ( ): 812, 15.385 - : 180. 15.386 - 15.387 - 15.388 -* 15.389 - 15.390 - DbReader, 15.391 - 15.392 - . 15.393 -DbReader " " 15.394 - XML- .
16.1 --- a/dist/biotopes/doc/readme.html Thu Dec 14 23:22:05 2006 +0300 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,86 +0,0 @@ 16.4 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 16.5 - "DTD/xhtml1-transitional.dtd"> 16.6 - 16.7 -<html> 16.8 - 16.9 -<head> 16.10 - <title>DbReader</title> 16.11 - <meta http-equiv="Content-Type" content="text/html; charset=koi8-r" /> 16.12 -</head> 16.13 - 16.14 -<body> 16.15 -<h1>DbReader</h1> 16.16 - 16.17 -<h2> </h2> 16.18 -<ol> 16.19 -<li> .</li> 16.20 - 16.21 -<li> :<br /> 16.22 - Windows 2000: // (ODBC), biotopes-data.mdb.</li> 16.23 - 16.24 -<li> :<br /> 16.25 - dbreader.properties , :<br /> 16.26 - <code>resource: jdbc:odbc:<em></em></code><br /> 16.27 - , ( biotopephotos maps):<br /> 16.28 - <code>resource_base: C:\\biotopes</code><br /> 16.29 -( '\' )</li> 16.30 - 16.31 -<li> :<br /> 16.32 -<code>dbreader.bat</code> <br /> 16.33 -<code>java -jar dbreader.jar</code>.<br /> 16.34 - Java Runtime Environment (JRE) 5.0, <a href="http://java.sun.com/j2se/1.5.0/download.jsp">http://java.sun.com/j2se/1.5.0/download.jsp</a>. , JRE - . 16.35 - 16.36 - :<br /> 16.37 - <code>java -Dru.karrc.dbreader.<em></em>=<em></em> -jar dbreader.jar</code><br /> 16.38 -(: <code>java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar</code>)</li> 16.39 -</ol> 16.40 - 16.41 -<h2> </h2> 16.42 - 16.43 -<p> biotope.sql ( , dbreader.properties), biotope.template, .</p> 16.44 -<p> : <code><%<em>_</em>[:|\]<em></em>%></code>, <em> </em> - , . , .</p> 16.45 - 16.46 -<h3> </h3> 16.47 - 16.48 -<ul> 16.49 - <li><code>:</code> - .</li> 16.50 - <li><code>\</code> - . <code><%</code> <code>%></code> (<code><%\<%%></code> <code><%\%%>></code>).</li> 16.51 -</ul> 16.52 - 16.53 -<h3></h3> 16.54 - 16.55 -<ul> 16.56 - <li><code><%get:<em></em>%></code><br /> 16.57 - .</li> 16.58 - 16.59 - <li><code><%optional:<em></em>%></code><br /> 16.60 - <em></em>, , , .</li> 16.61 - 16.62 - <li><code><%escape:<em></em>%></code><br /> 16.63 - "" ( ).</li> 16.64 - 16.65 - <li><code><%invoke:<em></em>; <em>1</em> <em>2</em> ... <em>N</em>%></code><br /> 16.66 - <em></em>.sql <em></em>.template. '?'.</li> 16.67 - 16.68 - <li><code><%image:<em>_</em> <em>_</em> <em></em> [<em>_</em>] [<em>_</em>]%></code><br /> 16.69 - <em>_</em> ( "resource_base") , <em>_</em>. , . 16.70 - , <code><%image:...%></code> <em>_</em>, - .</li> 16.71 - 16.72 - <li><code><%copy:<em>_</em> <em>_</em>%></code><br /> 16.73 - <em>_</em> ( "resource_base") <em>_</em>. , <code><%copy:...%></code> <em>_</em>, - .</li> 16.74 -</ul> 16.75 - 16.76 -<h3> </h3> 16.77 - 16.78 -<p><code>NUMBER</code> - . 16.79 - , invoke, <code>SUPER.</code> (: <code>SUPER.NUMBER</code>).</p> 16.80 - 16.81 -<h3></h3> 16.82 - 16.83 -<p> name :</p> 16.84 -<p><code><%escape get:name%></code></p> 16.85 - 16.86 -<p align="right"><i><a href="mailto:kryshen@cs.karelia.ru"> </a></i></p> 16.87 - 16.88 -</body> 16.89 -</html>
17.1 --- a/dist/biotopes/doc/readme.txt Thu Dec 14 23:22:05 2006 +0300 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,63 +0,0 @@ 17.4 -text/plain; charset=UTF-8 17.5 - 17.6 -Установка программы 17.7 -------------------- 17.8 - 17.9 -1. Распаковать архив. 17.10 - 17.11 -2. Установить источник данных: 17.12 -в Windows 2000: Панель управления/Администрирование/Источники данных (ODBC), добавить biotopes.mdb. 17.13 - 17.14 -3. Настроить программу: 17.15 -В файле dbreader.properties указать имя, присвоенное источнику данных: 17.16 - "resource: jdbc:odbc:<имя>" 17.17 -и путь к каталогу, относительно которого программа будет искать изображения (содержащий biotopephotos и maps): 17.18 - "resource_base: C:\\biotopes" 17.19 -(символ '\' необходимо дублировать) 17.20 - 17.21 -4. Запуск программы: dbreader.bat или "java -jar dbreader.jar" 17.22 -Для запуска необходима Java Runtime Environment (JRE) 5.0, можно скачать с http://java.sun.com/j2se/1.5.0/download.jsp. Возможно, будет работать и со старыми версиями JRE - не проверял. 17.23 - 17.24 -Все значения файла конфигурации можно переопределять при запуске программы: 17.25 - команда "java -Dru.karrc.dbreader.<ключ>=<значение> -jar dbreader.jar" 17.26 -(например: "java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar") 17.27 - 17.28 - 17.29 -Работа программы 17.30 ----------------- 17.31 - 17.32 -Программа выполняет запрос biotope.sql (или другой, указанный в dbreader.properties), после чего обрабатывает файл biotope.template, заменяя найденные в нем инструкции на результаты их выполнения. 17.33 - 17.34 -Формат инструкций: "<%список_функций[:|\]данные%>", список функций - имена функций разделенные пробелом, список может быть пустым. Если указано несколько функций, они выполняются начиная с последней. 17.35 - 17.36 -Разделители между списком функций и данными: 17.37 -':' - данные будут обрабатываться рекурсивно. 17.38 -'\' - данные будут переданы функции без обработки. Можно использовать для экранирования комбинаций символов "<%" и "%>" ("<%\<%%>" и "<%\%%>>"). 17.39 - 17.40 -Функции: 17.41 -<%get:<имя>%> - заменяется на значение встроенной переменной или колонки запроса. 17.42 - 17.43 -<%optional:<текст>%> 17.44 -Заменяется на <текст>, если в нем найдены инструкции, заменившиеся на непустые строки, иначе заменяется на пустую строку. 17.45 - 17.46 -<%escape:<текст>%> 17.47 -Заменяет в тексте "опасные" символы (таблица замен задается в файле конфигурации). 17.48 - 17.49 -<%invoke:<имя> <парам1> <парам2> ... <парамN>%> 17.50 -Выполняет запрос с параметрами <имя>.sql и заменяется на результаты обработки шаблона <имя>.template. Значения параметров подставляются в запрос вместо символа '?'. 17.51 - 17.52 -<%image:<исх_файл> <кон_файл> <формат> [<макс_ширина>] [<макс_высота>]%> 17.53 -Загружает изображение из файла <исх_файл> (путь определяется относительно конфигурационного параметра "resource_base") и преобразует его в указанный формат, сохраняя результат в <кон_файл>. Если заданы максимальная высота и ширина, большие изображения будут уменьшены. 17.54 -При успешном выполнении, инструкция "<%!image ...%>" будет заменена на значение <кон_файл>, иначе - на пустую строку. 17.55 - 17.56 -<%copy:<исх_файл> <кон_файл>%> 17.57 -Копирует файл <исх_файл> (путь определяется относительно конфигурационного параметра "resource_base"). 17.58 -При успешном выполнении, инструкция "<%!copy ...%>" будет заменена на значение <кон_файл>, иначе - на пустую строку. 17.59 - 17.60 -Встроенные переменные: 17.61 -NUMBER - порядковый номер строки результата выполнения запроса. 17.62 -Чтобы обратиться к переменной запроса, из которого обрабатываемый шаблон был вызван с помощью функции invoke, перед именем переменной нужно добавить "SUPER." (например: "SUPER.NUMBER"). 17.63 - 17.64 -Пример: 17.65 -Следующая инструкция получит значение из столбца name и заменит в нем специальные символы: 17.66 -<%escape get:name%>
18.1 --- a/dist/biotopes/main.template Thu Dec 14 23:22:05 2006 +0300 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,11 +0,0 @@ 18.4 -<%!: 18.5 - <%prepare:biotope_sql <%read\biotope.sql%>%> 18.6 - <%prepare:photo_sql <%read\photo.sql%>%> 18.7 - <%prepare:class_sql <%read\class.sql%>%> 18.8 - <%prepare:plant_sql <%read\plant.sql%>%> 18.9 - 18.10 - <%query:biotope_sql [%\<%write:<%db\code%>.xml <%include\biotope.template%>%> %]%> 18.11 - 18.12 - <%write:classes.xml <%include\classes.template%>%> 18.13 - <%write:plants.xml <%include\plants.template%>%> 18.14 -%>
19.1 --- a/dist/biotopes/photo.sql Thu Dec 14 23:22:05 2006 +0300 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,1 +0,0 @@ 19.4 -SELECT * from photos WHERE biotope = ?
20.1 --- a/dist/biotopes/photo.template Thu Dec 14 23:22:05 2006 +0300 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,3 +0,0 @@ 20.4 - < num="<%number\%>" <%optional:="<%xml_escape db\authphoto%>" %>text="" 20.5 - file="<%xml_escape image:biotopephotos/<%db\photo%> images/<%super.db\code%>_<%number\%>.jpg jpg 300 300%>" 20.6 - big="<%xml_escape copy:biotopephotos/<%db\photo%> images/big/<%super.db\code%>_<%number\%>.jpg%>"/>
21.1 --- a/dist/biotopes/plant.sql Thu Dec 14 23:22:05 2006 +0300 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,3 +0,0 @@ 21.4 -SELECT t1.* 21.5 -FROM biotopelist AS t1 21.6 -WHERE rusname AND Right(t1.rangcode, 2) <> '00'
22.1 --- a/dist/biotopes/plants.template Thu Dec 14 23:22:05 2006 +0300 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,5 +0,0 @@ 22.4 -<?xml version="1.0" encoding="ISO-8859-5"?> 22.5 -<><%query:plant_sql [%\ 22.6 - <!-- rangcode: <%xml_escape db\rangcode%> --> 22.7 - <><%xml_escape db\rusname%></>%]%> 22.8 -</>
23.1 --- a/dist/biotopes/tema.properties Thu Dec 14 23:22:05 2006 +0300 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,22 +0,0 @@ 23.4 -# Data source configuration 23.5 -resource : jdbc:odbc:biotopes-data 23.6 -driver : sun.jdbc.odbc.JdbcOdbcDriver 23.7 - 23.8 -# Base directory for images and files 23.9 -resource_base : C:\\biotopes\\db 23.10 - 23.11 -# Template to start processing with 23.12 -main_template : main.template 23.13 - 23.14 -# File encodings 23.15 -input_encoding : ISO-8859-5 23.16 -output_encoding : ISO-8859-5 23.17 - 23.18 -# Cache templates 23.19 -cache_read : true 23.20 - 23.21 -# Output main_template parsing result to stderr 23.22 -#output : stderr 23.23 - 23.24 -# File to output error messages (redirect stderr) 23.25 -#log : tema.log
24.1 Binary file dist/lib/commons-cli-1.1.jar has changed
25.1 --- a/dist/tema.properties Thu Dec 14 23:22:05 2006 +0300 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,22 +0,0 @@ 25.4 -# Data source configuration 25.5 -# resource : jdbc:odbc:biotopes-data 25.6 -# driver : sun.jdbc.odbc.JdbcOdbcDriver 25.7 - 25.8 -# Base directory for images and files 25.9 -# resource_base : C:\\biotopes\\db 25.10 - 25.11 -# Template to start processing with 25.12 -main_template : main.template 25.13 - 25.14 -# File encodings 25.15 -# input_encoding : UTF-8 25.16 -# output_encoding : UTF-8 25.17 - 25.18 -# Cache templates 25.19 -# cache_read : true 25.20 - 25.21 -# Output main_template parsing result to stderr 25.22 -# output : stderr 25.23 - 25.24 -# File to output error messages (redirect stderr) 25.25 -# log : tema.log
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/doc/.cvsignore Tue Feb 19 20:32:17 2008 +0300 26.3 @@ -0,0 +1,1 @@ 26.4 +api
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/doc/manual/.cvsignore Tue Feb 19 20:32:17 2008 +0300 27.3 @@ -0,0 +1,1 @@ 27.4 +manual.html
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/doc/manual/document.tema Tue Feb 19 20:32:17 2008 +0300 28.3 @@ -0,0 +1,107 @@ 28.4 +[%\ 28.5 + Macro definitions used in manual.tema to generate HTML document. 28.6 +%] 28.7 + 28.8 +[%!\ 28.9 + Create HTML document. 28.10 + Arguments are read in pairs (name value) until "content" name is found. 28.11 + Then follows the document content. 28.12 + 28.13 + TODO: generate TOC. 28.14 +%] 28.15 +<%define#document 28.16 + <%silent while# 28.17 + <%if:<%not equal:<%set:arg <%next_arg:%>%> content%> 28.18 + <%export:<%arg:%> <%next_arg:%>%> 28.19 + %> 28.20 + %>\\ 28.21 +<%if:<%not embedded:%> 28.22 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 28.23 + 28.24 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 28.25 + 28.26 +<head> 28.27 + <title><%html_escape title:%></title> 28.28 + <meta http-equiv="Content-Type" content="text/html; charset=<%charset:%>" /> 28.29 + <meta name="generator" content="<%tema:%>" /> 28.30 +</head> 28.31 + 28.32 +<body> 28.33 +<h1><%html_escape title:%><%optional:<br /><%html_escape subtitle:%>%></h1> 28.34 +%>\ 28.35 +<%html_escape data:%> 28.36 +<%if:<%not embedded:%> 28.37 +</body> 28.38 +</html> 28.39 +%>\ 28.40 +%> 28.41 + 28.42 +<%set:charset iso-8859-1%> 28.43 +<%set:escape <%char:0%>%> 28.44 + 28.45 +[%!\ 28.46 + Create HTML tag. 28.47 +%] 28.48 +<%define#tag <%false:<%escape:%><<%data:%><%escape:%>>%>%> 28.49 + 28.50 +[%!\ 28.51 + Escape special HTML characters (except those preceded with <%escape:%>). 28.52 +%] 28.53 +<%define#html_escape 28.54 + <%replace:<%escape:%> <%:%> 28.55 + <%regex_replace_all:(?<!<%escape:%>)-- – 28.56 + <%regex_replace_all:(?<!<%escape:%>)--- — 28.57 + <%regex_replace_all:(?<!<%escape:%>)< < 28.58 + <%regex_replace_all:(?<!<%escape:%>)> > 28.59 + <%regex_replace_all:(?<!<%escape:%>)& & 28.60 + <%data:%>\\ 28.61 + %>%>%>%>%>%>\ 28.62 +%> 28.63 + 28.64 +<%define#section 28.65 + <%tag:h2<%if:<%first_section:%> <%: class="first"%>%>%><%data:%><%tag:/h2%>\\ 28.66 + <%unset:first_section%>\\ 28.67 +%> 28.68 + 28.69 +<%define#subsection <%tag:h3%><%data:%><%tag:/h3%>%> 28.70 + 28.71 +<%define#par <%tag:p%><%data:%><%tag:/p%>%> 28.72 + 28.73 +<%define#itemize 28.74 +<%tag:ul%> 28.75 +<%while#\ 28.76 + <%tag:li%><%next_arg:%><%tag:/li%> 28.77 +%>\ 28.78 +<%tag:/ul%> 28.79 +%> 28.80 + 28.81 +<%define#code <%tag:code%><%replace:-- <%escape:%>-- <%data:%>%><%tag:/code%>%> 28.82 + 28.83 +<%define#emph <%tag:i%><%data:%><%tag:/i%>%> 28.84 + 28.85 +<%define#link 28.86 + <%silent set:url <%next_arg:%>%>\\ 28.87 + <%tag:a href="<%url:%>"%>\\ 28.88 + <%if_else:<%has_more_data:%> 28.89 + <%data:%> 28.90 + <%url:%>%>\\ 28.91 + <%tag:/a%>\\ 28.92 +%> 28.93 + 28.94 +<%define#function 28.95 + <%silent set:name <%next_arg:%>%>\\ 28.96 + <%silent while# 28.97 + <%set:<%next_arg:%> <%next_arg:%>%> 28.98 + %>\\ 28.99 + <%tag:div%> 28.100 + <%tag:b%><%name:%><%tag:/b%><%tag:br /%> 28.101 + <%tag:/div%> 28.102 + <%optional:<%tag:div style="padding-left:1em; margin-bottom: 0.5em;"%> 28.103 + <%description:%> 28.104 + <%tag:/div%>%> 28.105 + <%tag:div style="padding-left:1em; margin-bottom: 1em;"%> 28.106 + <%optional:<%tag:b%>Arguments:<%tag:/b%> <%arguments:%><%tag:br /%>%> 28.107 + <%optional:<%tag:b%>Data:<%tag:/b%> <%input_data:%><%tag:br /%>%> 28.108 + <%optional:<%tag:b%>Output:<%tag:/b%> <%output:%><%tag:br /%>%> 28.109 + <%tag:/div%> 28.110 +%>
29.1 --- a/doc/manual/index.html Thu Dec 14 23:22:05 2006 +0300 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,358 +0,0 @@ 29.4 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 29.5 - "DTD/xhtml1-transitional.dtd"> 29.6 - 29.7 -<html> 29.8 - 29.9 -<head> 29.10 - <title>Макропроцессор TEMA</title> 29.11 - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 29.12 -</head> 29.13 - 29.14 -<body> 29.15 -<h1>Макропроцессор TEMA</h1> 29.16 - 29.17 -Макропроцессор TEMA обрабатывает заданные шаблоны текстовых файлов и 29.18 -заменяет найденные в них инструкции на результаты их выполнения. 29.19 - 29.20 -<p><b>Формат инструкций</b></p> 29.21 - 29.22 -<blockquote> 29.23 - <code><%<i>список_функций</i>{:|\|`}<i>данные</i>%></code> 29.24 -</blockquote> 29.25 -<p> 29.26 -где<br /> 29.27 - 29.28 -<code><i>список_функций</i></code> - список имен функций, разделенных 29.29 - пробелами. Может быть пустым.<br /> 29.30 -<code><i>данные</i></code> - данные, передаваемые функции. 29.31 -</p> 29.32 - 29.33 -<p><b>Формат данных</b></p> 29.34 - 29.35 -<blockquote> 29.36 - <code> 29.37 - [<i>список_аргументов</i>][<i>текст</i>] 29.38 - </code> 29.39 -</blockquote> 29.40 -<p> 29.41 -где<br /> 29.42 - 29.43 -<code><i>список_аргументов</i></code> - список аргументов функции, разделенных пробелами. 29.44 - Может быть пустым.<br /> 29.45 -<code><i>текст</i></code> - текст, передаваемый функции без разбиения на аргументы. 29.46 - Может быть пустым. Количество аргументов, после которого следует 29.47 - текст, зависит от функции. 29.48 -</p><p> 29.49 -Разделитель между списком функций и данными определяет, как должны 29.50 -обрабатываться данные функции: 29.51 -</p><p> 29.52 -<code>:</code> - рекурсивная обработка,<br /> 29.53 -<code>\</code> или <code>`</code> - передать без обработки. 29.54 -</p><p> 29.55 -Если в списке функций задано две и более функции, они выполняются, 29.56 -начиная с последней, так что каждая функция получает в качестве данных 29.57 -результат выполнения следующей функции. 29.58 -</p><p> 29.59 -Каждая функция имеет код возврата - целое число. Код возврата 29.60 -инструкции - код возврата первой в списке функции. Код возврата, 29.61 -получаемый при обработке текста - сумма кодов возврата обработанных 29.62 -инструкций (как правило, смысл этого значения - количество инструкций, 29.63 -замененных на непустой текст). 29.64 -</p><p> 29.65 -Кроме скобок '<', '>', можно использовать скобки '[', ']'. 29.66 -</p> 29.67 - 29.68 - 29.69 -<h2>Функции</h2> 29.70 - 29.71 -<p><code><b>set</b></code></p> 29.72 - 29.73 -<table> 29.74 -<tr><td>Аргументы:</td> 29.75 -<td><i>имя</i></td></tr> 29.76 - 29.77 -<tr><td>Текст:</td> 29.78 -<td><i>значение</i></td></tr> 29.79 - 29.80 -<tr><td>Действие:</td> 29.81 -<td>Устанавливает значение переменной <i>имя</i>.</td></tr> 29.82 - 29.83 -<tr><td>Результат:</td> 29.84 -<td><i>имя</i></td></tr> 29.85 - 29.86 -<tr><td>Код возврата:</td> 29.87 -<td>1</td></tr> 29.88 -</table> 29.89 - 29.90 -<p><code><b>define</b></code></p> 29.91 - 29.92 -<table> 29.93 -<tr><td>Аргументы:</td> 29.94 -<td><i>имя</i></td></tr> 29.95 - 29.96 -<tr><td>Текст:</td> 29.97 -<td><i>шаблон</i></td></tr> 29.98 - 29.99 -<tr><td>Действие:</td><td>Определяет новую функцию <i>имя</i>, при 29.100 -вызове которой обрабатывается <i>шаблон</i>. При обработке доступны 29.101 -функции <code>nextarg</code> для получения очередного аргумента 29.102 -вызываемой функции и <code>data</code> для получения текста.</td></tr> 29.103 - 29.104 -<tr><td>Результат:</td> 29.105 -<td><i>имя</i></td></tr> 29.106 - 29.107 -<tr><td>Код возврата:</td> 29.108 -<td>1</td></tr> 29.109 -</table> 29.110 - 29.111 -<p><code><b>load</b></code></p> 29.112 - 29.113 -<table> 29.114 -<tr><td>Аргументы:</td> 29.115 -<td><i>имя</i> <i>имя_класса</i></td></tr> 29.116 - 29.117 -<tr><td>Действие:</td> 29.118 - 29.119 -<td>Определяет новую функцию <i>имя</i>. Реализация функции определена 29.120 -Java-классом <i>имя_класса</i>, наследующим класс 29.121 -<code>kryshen.tema.Function</code>.</td></tr> 29.122 - 29.123 -<tr><td>Результат:</td> 29.124 -<td><i>имя</i></td></tr> 29.125 - 29.126 -<tr><td>Код возврата:</td> 29.127 -<td>1</td></tr> 29.128 -</table> 29.129 - 29.130 -<p><code><b>prepare</b></code></p> 29.131 - 29.132 -<table> 29.133 -<tr><td>Аргументы:</td> 29.134 -<td><i>имя</i></td></tr> 29.135 - 29.136 -<tr><td>Текст:</td> 29.137 -<td><i>запрос</i></td></tr> 29.138 - 29.139 -<tr><td>Действие:</td> 29.140 -<td>Подготавливает SQL-запрос <i>запрос</i> для выполнения, записывает 29.141 -подготовленный запрос в переменную <i>имя</i>.</td></tr> 29.142 - 29.143 -<tr><td>Результат:</td> 29.144 -<td><i>имя</i></td></tr> 29.145 - 29.146 -<tr><td>Код возврата:</td> 29.147 -<td>1</td></tr> 29.148 -</table> 29.149 - 29.150 -<p><code><b>query</b></code></p> 29.151 - 29.152 -<table> 29.153 -<tr><td>Аргументы:</td> 29.154 -<td><i>имя_запроса</i> <i>шаблон</i> <i>парам1</i> ... <i>парамN</i></td></tr> 29.155 - 29.156 -<tr><td>Действие:</td> 29.157 -<td>Выполняет запрос с параметрами, подготовленный с помощью функции 29.158 -prepare. Значения параметров подставляются в запрос вместо символа 29.159 -'?'. Значения полей ответа доступны с помощью функции <code>db</code>, 29.160 -как переменные шаблона <i>шаблон</i>. При обработки шаблона также 29.161 -определяется переменная <code>number</code>, содержащая номер текущей 29.162 -строки ответа.</td></tr> 29.163 - 29.164 -<tr><td>Результат:</td> 29.165 -<td>результат обработки шаблона <i>шаблон</i> для каждой строки 29.166 -ответа.</td></tr> 29.167 - 29.168 -<tr><td>Код возврата:</td> 29.169 -<td>Количество полученных строк ответа.</td></tr> 29.170 -</table> 29.171 - 29.172 -<p><code><b>optional</b></code></p> 29.173 - 29.174 -<table> 29.175 -<tr><td>Текст:</td> 29.176 -<td><i>данные</i></td></tr> 29.177 - 29.178 -<tr><td>Результат:</td><td><i>данные</i>, если при обработке данных 29.179 -был получен код возврата отличный от 0, иначе - пустая 29.180 -строка.</td></tr> 29.181 - 29.182 -<tr><td>Код возврата:</td> 29.183 -<td>1, если результат - пустая строка, 0 - иначе.</td></tr> 29.184 -</table> 29.185 - 29.186 -<p><code><b>image</b></code></p> 29.187 - 29.188 -<table> 29.189 -<tr><td>Аргументы:</td> 29.190 -<td><i>исх_файл</i> <i>кон_файл</i> <i>формат</i> [<i>макс_ширина</i> 29.191 -[<i>макс_высота</i>]]</td></tr> 29.192 - 29.193 -<tr><td>Действие:</td> 29.194 -<td>Загружает изображение из файла <i>исх_файл</i> (путь определяется 29.195 -относительно конфигурационного параметра "resource_base") и 29.196 -преобразует его в указанный формат, сохраняя результат в 29.197 -<i>кон_файл</i>. Если заданы максимальная высота и ширина, большие 29.198 -изображения будут уменьшены.</td></tr> 29.199 - 29.200 -<tr><td>Результат:</td> 29.201 -<td><i>кон_файл</i> при успешном выполнении, пустая строка - иначе.</td></tr> 29.202 - 29.203 -<tr><td>Код возврата:</td> 29.204 -<td>1 при успешном выполнении, 0 - иначе.</td></tr> 29.205 -</table> 29.206 - 29.207 - 29.208 -<p><code><b>copy</b></code></p> 29.209 - 29.210 -<table> 29.211 -<tr><td>Аргументы:</td><td><i>исх_файл</i> <i>кон_файл</i></td></tr> 29.212 - 29.213 -<tr><td>Действие:</td><td>Копирует файл <i>исх_файл</i> в файл 29.214 -<i>кон_файл</i> (путь <i>исх_файл</i> определяется относительно 29.215 -конфигурационного параметра "resource_base").</td></tr> 29.216 - 29.217 -<tr><td>Результат:</td><td><i>кон_файл</i> при успешном выполнении, 29.218 -пустая строка - иначе.</td></tr> 29.219 - 29.220 -<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 29.221 -иначе.</td></tr> 29.222 -</table> 29.223 - 29.224 -<p><code><b>write</b></code></p> 29.225 - 29.226 -<table> 29.227 -<tr><td>Аргументы:</td><td><i>имя_файла</i></td></tr> 29.228 - 29.229 -<tr><td>Текст:</td><td><i>данные</i></td></tr> 29.230 - 29.231 -<tr><td>Действие:</td><td>Записывает <i>данные</i> в файл 29.232 -<i>исх_файл</i>.</td></tr> 29.233 - 29.234 -<tr><td>Результат:</td><td><i>кон_файл</i> при успешном выполнении, 29.235 -пустая строка - иначе.</td></tr> 29.236 - 29.237 -<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 29.238 -иначе.</td></tr> 29.239 -</table> 29.240 - 29.241 -<p><code><b>read</b></code></p> 29.242 - 29.243 -<table> 29.244 -<tr><td>Текст:</td><td><i>имя_файла</i></td></tr> 29.245 -<tr><td>Действие:</td><td>Читает файл <i>имя_файла</i>.</td></tr> 29.246 -<tr><td>Результат:</td><td>прочитанные данные при успешном выполнении, 29.247 - пустая строка - иначе.</td></tr> 29.248 -<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 29.249 -иначе.</td></tr> 29.250 -</table> 29.251 - 29.252 -<p><code><b>include</b></code></p> 29.253 - 29.254 -<table> 29.255 -<tr><td>Текст:</td><td><i>имя_файла</i></td></tr> 29.256 -<tr><td>Действие:</td><td>включает шаблон из файла 29.257 -<i>имя_файла</i>.</td></tr> 29.258 -<tr><td>Результат:</td><td>результат обработки шаблона.</td></tr> 29.259 -<tr><td>Код возврата:</td><td>код возврата, полученный при обработке 29.260 -шаблона.</td></tr> 29.261 -</table> 29.262 - 29.263 -<p><code><b>!</b></code></p> 29.264 - 29.265 -<table> 29.266 -<tr><td>Текст:</td><td><i>данные</i></td></tr> 29.267 - 29.268 -<tr><td>Действие:</td><td>нет.</td></tr> 29.269 - 29.270 -<tr><td>Результат:</td><td>нет.</td></tr> 29.271 - 29.272 -<tr><td>Код возврата:</td><td>код возврата, полученный при обработке 29.273 -текста данных.</td></tr> 29.274 -</table> 29.275 - 29.276 -<p><code><b>replace</b></code></p> 29.277 - 29.278 -<table> 29.279 -<tr><td>Аргументы:</td><td><i>стр1</i> <i>стр2</i></td></tr> 29.280 - 29.281 -<tr><td>Текст:</td><td><i>данные</i></td></tr> 29.282 - 29.283 -<tr><td>Результат:</td><td>данные, с замененными вхождениями подстроки 29.284 -<i>стр1</i> на <i>стр2</i>.</td></tr> 29.285 - 29.286 -<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 29.287 -текста данных.</td></tr> 29.288 -</table> 29.289 - 29.290 -<p><code><b>xml_escape</b></code></p> 29.291 - 29.292 -<table> 29.293 -<tr><td>Текст:</td><td><i>данные</i></td></tr> 29.294 -<tr><td>Результат:</td><td>текст <i>данные</i>, в котором символы 29.295 -'&', '<', '>', '`', '\' заменены на соответствующие сущности 29.296 -XML.</td></tr> 29.297 - 29.298 -<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 29.299 -текста данных.</td></tr> 29.300 -</table> 29.301 - 29.302 -<p><code><b>xml_cdata</b></code></p> 29.303 - 29.304 -<table> 29.305 -<tr><td>Текст:</td><td><i>данные</i></td></tr> 29.306 - 29.307 -<tr><td>Результат:</td><td>данные в виде блока XML CDATA.</td></tr> 29.308 - 29.309 -<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 29.310 -текста данных. </td></tr> 29.311 -</table> 29.312 - 29.313 -<p> 29.314 -Макропроцессор TEMA расширяем: возможно добавление в систему новых 29.315 -функций, реализованных в виде классов на языке Java. 29.316 -</p> 29.317 - 29.318 -<h2>Запуск</h2> 29.319 - 29.320 -<p>java -jar tema.jar [<i>опции</i>] 29.321 -</p><p> 29.322 -Опции: 29.323 -</p> 29.324 -<table> 29.325 -<tr><td>-d[emo]</td><td>Демонстрационный режим</td></tr> 29.326 -<tr><td>-v[ersion]</td><td>Вывод версии</td></tr> 29.327 -<tr><td>-h[help] -u[sage]</td><td>Вывод справки</td></tr> 29.328 -</table> 29.329 - 29.330 -<p> 29.331 -При запуске читается файл "tema.properties" из текущего каталога.<br /> 29.332 -Пример файла "tema.properties": 29.333 -</p> 29.334 - 29.335 -<pre> 29.336 -# Настройка источника данных 29.337 -# resource : jdbc:odbc:database 29.338 -# driver : sun.jdbc.odbc.JdbcOdbcDriver 29.339 - 29.340 -# Базовый каталог ресурсов 29.341 -# resource_base : . 29.342 - 29.343 -# Шаблон, с которого начинается обработка 29.344 -main_template : main.template 29.345 - 29.346 -# Кодировки файлов 29.347 -# input_encoding : UTF-8 29.348 -# output_encoding : UTF-8 29.349 - 29.350 -# Кэширование шаблонов 29.351 -# cache_read : true 29.352 - 29.353 -# Вывод результата разбора шаблона main.template в stderr 29.354 -# output : stderr 29.355 - 29.356 -# Вывод сообщений об ошибках в файл 29.357 -# log : dbreader.log 29.358 -</pre> 29.359 - 29.360 -</body> 29.361 -</html>
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/doc/manual/manual.tema Tue Feb 19 20:32:17 2008 +0300 30.3 @@ -0,0 +1,253 @@ 30.4 +[%!\ 30.5 + Tema User Manual. 30.6 +%]\\ 30.7 + 30.8 +<%silent include:document.tema%>\\ 30.9 + 30.10 +<%document: 30.11 + title <%:Tema -- template macro processor%> 30.12 + author <%:Mikhail Kryshen%> 30.13 + content 30.14 + 30.15 +<%section:Introduction%> 30.16 + 30.17 +<%par:Tema is a macro processor and template engine. It reads the input file 30.18 +recursively expanding any macro found in the text.%> 30.19 + 30.20 +<%par:Distinctive features:%> 30.21 +<%itemize: 30.22 + <%:Extensible: implement new functions as Java classes.%> 30.23 + <%:Database access.%> 30.24 + <%:Processes and outputs data as early as possible (function could start 30.25 + to output data before all it's arguments are read and parsed).%> 30.26 + <%:Apache Ant integration.%> 30.27 +%> 30.28 + 30.29 +<%par:Tema macro has the following syntax:%> 30.30 + 30.31 +<%par:[%code\<%function_list{:|#|\|`}[escape]text%>[escape]%]%> 30.32 + 30.33 +<%par:<%code:function_list%> is the list of text-processing functions. 30.34 +Functions will be applied to text in reverse order.%> 30.35 + 30.36 +<%par:<%code:text%> could contain space-separated list of arguments 30.37 +followed by arbitrary data. Number of arguments is determined by the last 30.38 +function in the <%code:function_list%>.%> 30.39 + 30.40 +<%par:<%code\[arg1 arg2...] [data]%>%> 30.41 + 30.42 +<%par:The text is separated from the list of functions by one of the 30.43 +following characters:%> 30.44 + 30.45 +<%itemize: 30.46 + <%\':' -- process text recursively.%> 30.47 + <%\'#' -- parse text but do not replace any embedded macro.%> 30.48 + <%\'\', '`' -- do not parse text (ignore any '<%' sequences).%> 30.49 +%> 30.50 + 30.51 +<%par:<%code:escape%> is either '\' or '\\':%> 30.52 + 30.53 +<%itemize: 30.54 + <%:<%:\%> -- the following newline symbol will be removed;%> 30.55 + <%:<%:\\%> -- the following sequence of the whitespace characters will be removed.%> 30.56 +%> 30.57 + 30.58 +<%par:You could use <%\'[%' and '%]'%> character sequences to denote macro 30.59 +as an alternative to [%\'<%' and '%>'%].%> 30.60 + 30.61 +<%par:Every function returns integer value. The general convention is to 30.62 +return non-zero for successful operation. The value of the macro substitution 30.63 +is the return value of the first function in the function list. The value of 30.64 +any Tema text is the sum value of all macro in the text, except the value of 30.65 +the text without any macro equals -1.%> 30.66 + 30.67 +<%par:Internally, Tema function could be represented by any Java object. 30.68 +Instances of kryshen.tema.Function and kryshen.tema.Context are handled 30.69 +specially. For any other type of object, function output would be the value 30.70 +returned by the method <%code:toString()%>.%> 30.71 + 30.72 +<%section:Built-in functions%> 30.73 + 30.74 +<%par emph:Notice: some functions are not yet described in this manual. 30.75 +For the complete list of built-in functions refer to the API documentation 30.76 +and source code.%> 30.77 + 30.78 +<%function:tema 30.79 + output <%:Tema version%> 30.80 +%> 30.81 + 30.82 +<%function:echo 30.83 + output <%:function data%> 30.84 +%> 30.85 + 30.86 +<%function:! 30.87 + output nothing 30.88 + description <%:Ignores the input text (':' separator works as '#'). 30.89 + Use for commenting (e.g. <%code\[%!\ comment %]%>).%> 30.90 +%> 30.91 + 30.92 +<%function:silent 30.93 + output nothing 30.94 +%> 30.95 + 30.96 +<%function:set 30.97 + arguments <%:definition name%> 30.98 + input_data <%:variable value%> 30.99 + output <%:function data%> 30.100 + description <%:Defines new function as a static variable.%> 30.101 +%> 30.102 + 30.103 +<%function:define 30.104 + arguments <%:name, code%> 30.105 + description <%:\\ 30.106 + Defines new function. 30.107 + Use <%code:next_arg%>, <%code:data%>, and <%code:has_more_data%> 30.108 + functions to access function arguments.%> 30.109 + output <%:name%> 30.110 +%> 30.111 + 30.112 +[%!\ TODO: next_arg, data, has_more_data %]\\ 30.113 + 30.114 +<%function:export 30.115 + arguments <%:definition name%> 30.116 + input_data <%:static variable value (optional)%> 30.117 + output <%:function data%> 30.118 + description <%:Exports the definition to the global (outermost) context.%> 30.119 +%> 30.120 + 30.121 +<%function:unset 30.122 + arguments <%:def1, def2, ...%> 30.123 + output <%:nothing%> 30.124 + description <%:Unsets the definitions.%> 30.125 +%> 30.126 + 30.127 +<%function:invoke 30.128 + arguments <%:function, arg1, arg2, ..., data%> 30.129 + output <%:function output%> 30.130 + description <%:Invokes function.%> 30.131 +%> 30.132 + 30.133 +<%function:load 30.134 + arguments <%:name, class, url1, url2, ...%> 30.135 + output <%:name%> 30.136 + description <%:Instantiate specified class as a Tema function definition. 30.137 + URL arguments are optional.%> 30.138 +%> 30.139 + 30.140 +<%function:super 30.141 + input_data <%:code%> 30.142 + output <%:output generated by the code%> 30.143 + description <%:Evaluates the specified template code in the super-context 30.144 + (i.e. context of the calling function or context executing 30.145 + the database query).%> 30.146 +%> 30.147 + 30.148 +<%function:replace 30.149 + arguments <%:s1, s2, data%> 30.150 + description <%:\\ 30.151 + Replaces all occurrences of <%code:s1%> with <%code:s2%> in data.%> 30.152 +%> 30.153 + 30.154 +[%!\ TODO: all functions defined in Strings.java %]\\ 30.155 + 30.156 +<%subsection:Input / output%> 30.157 + 30.158 +<%function:copy 30.159 + arguments <%:src, dest%> 30.160 + description <%:Copies file <%code:src%> to <%code:dest%>.%> 30.161 + output <%:dest%> 30.162 +%> 30.163 + 30.164 +<%function:write 30.165 + arguments <%:name%> 30.166 + input_data <%:text%> 30.167 + description <%:Writes text to file.%> 30.168 + output <%:name%> 30.169 +%> 30.170 + 30.171 +<%function:read 30.172 + arguments <%:name%> 30.173 + description <%:Reads file.%> 30.174 + output <%:File contents.%> 30.175 +%> 30.176 + 30.177 +<%function:include 30.178 + arguments <%:name%> 30.179 + description <%:Includes template.%> 30.180 + output <%:Result of processing the template.%> 30.181 +%> 30.182 + 30.183 +<%function:file 30.184 + arguments <%:base, name%> 30.185 + output <%:Path constructed from the base directory and file name.%> 30.186 +%> 30.187 + 30.188 +<%subsection:Conditionals%> 30.189 + 30.190 +<%function:optional 30.191 + input_data <%:text%> 30.192 + output <%:Function data if it's value is non-zero or empty text.%> 30.193 +%> 30.194 + 30.195 +<%function:while 30.196 + input_data <%:code%> 30.197 + description <%:Repeatedly outputs it's evaluated data while it has non-zero value.%> 30.198 +%> 30.199 + 30.200 +[%!\ TODO: all functions defined in Control.java %]\\ 30.201 + 30.202 +<%subsection:Database%> 30.203 + 30.204 +<%function:db_connect 30.205 + arguments <%:connection name%> 30.206 + input_data <%:resource%> 30.207 + description <%:Establishes connection with the database. 30.208 + Load the appropriate database driver using the <%code:load%> function 30.209 + before using <%code:db_connect%> 30.210 + (e.g. [%code\<%load:driver sun.jdbc.odbc.JdbcOdbcDriver%>%]).%> 30.211 +%> 30.212 + 30.213 +<%function:db_prepare 30.214 + arguments <%:query name, connection name%> 30.215 + input_data <%:SQL statement%> 30.216 +%> 30.217 + 30.218 +<%function:db_query 30.219 + arguments <%:query, template, arg1, arg2, ...%> 30.220 + description <%:Executes query, evaluating the template for each result row.%> 30.221 +%> 30.222 + 30.223 +<%function:db 30.224 + input_data <%:column name%> 30.225 + output <%:value from the query result.%> 30.226 + description <%:Available in the template for the <%code:db_query%> function.%> 30.227 +%> 30.228 + 30.229 +<%function:db_row 30.230 + output <%:current row number in the result set.%> 30.231 + description <%:Available in the template for the <%code:db_query%> function.%> 30.232 +%> 30.233 + 30.234 +[%!\ TODO: all functions defined in ImageConverter.java %]\\ 30.235 + 30.236 +<%section:Running Tema%> 30.237 + 30.238 +<%par:Change to the dist subdirectory in the distribution package and 30.239 +issue the following command:%> 30.240 + 30.241 +<%par:<%code:java -jar tema.jar [options] [files]%>%> 30.242 + 30.243 +<%par:The following options are recognized:%> 30.244 +<%itemize: 30.245 + <%:<%code:--demo%> --- run demo console with a code example;%> 30.246 + <%:<%code:-h, --help%> --- print help message;%> 30.247 + <%:<%code:--input-encoding <arg>%> --- set the input encoding;%> 30.248 + <%:<%code:--log <arg>%> --- log all error messages to the specified file;%> 30.249 + <%:<%code:-o, --output <arg>%> --- set the output file;%> 30.250 + <%:<%code:--output-encoding <arg>%> --- set the output encoding;%> 30.251 + <%:<%code:-v, --version%> --- print the version information and exit.%> 30.252 +%> 30.253 + 30.254 +<%section:Homepage%> 30.255 + 30.256 +<%par link:http://kryshen.pp.ru/tema/%>
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/misc/biotopes/biotope-top.sql Tue Feb 19 20:32:17 2008 +0300 31.3 @@ -0,0 +1,20 @@ 31.4 +SELECT t1.*, 31.5 + 31.6 +(SELECT t2.rusname FROM biotopelist AS t2 31.7 +WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) AND 31.8 +Right(t2.rangcode, 8) = '00000000') AS class0, 31.9 + 31.10 +(SELECT t2.rusname FROM biotopelist AS t2 31.11 +WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) AND 31.12 +Right(t2.rangcode, 6) = '000000') AS class1, 31.13 + 31.14 +(SELECT t2.rusname FROM biotopelist AS t2 31.15 +WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) AND 31.16 +Right(t2.rangcode, 4) = '0000') AS class2, 31.17 + 31.18 +(SELECT t2.rusname FROM biotopelist AS t2 31.19 +WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) AND 31.20 +Right(t2.rangcode, 2) = '00') AS class3 31.21 + 31.22 +FROM biotopelist AS t1 31.23 +WHERE Right(t1.rangcode, 2) <> '00' AND rusname
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/misc/biotopes/biotope.sql Tue Feb 19 20:32:17 2008 +0300 32.3 @@ -0,0 +1,24 @@ 32.4 +SELECT t1.*, 32.5 + 32.6 +(SELECT t2.rusname FROM biotopelist AS t2 32.7 +WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 32.8 +AND Right(t2.rangcode, 8) = '00000000' 32.9 +AND Right(t1.rangcode, 8) <> '00000000') AS class0, 32.10 + 32.11 +(SELECT t2.rusname FROM biotopelist AS t2 32.12 +WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 32.13 +AND Right(t2.rangcode, 6) = '000000' 32.14 +AND Right(t1.rangcode, 6) <> '000000') AS class1, 32.15 + 32.16 +(SELECT t2.rusname FROM biotopelist AS t2 32.17 +WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 32.18 +AND Right(t2.rangcode, 4) = '0000' 32.19 +AND Right(t1.rangcode, 4) <> '0000') AS class2, 32.20 + 32.21 +(SELECT t2.rusname FROM biotopelist AS t2 32.22 +WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 32.23 +AND Right(t2.rangcode, 2) = '00' 32.24 +AND Right(t1.rangcode, 2) <> '00') AS class3 32.25 + 32.26 +FROM biotopelist AS t1 32.27 +WHERE rusname
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/misc/biotopes/biotope.template Tue Feb 19 20:32:17 2008 +0300 33.3 @@ -0,0 +1,17 @@ 33.4 +<?xml version="1.0" encoding="ISO-8859-5"?> 33.5 +<!DOCTYPE _ SYSTEM "brief.dtd"> 33.6 +<!-- rangcode: <%xml_escape db\rangcode%> --> 33.7 +<_ show="0"> 33.8 + < display="0"> 33.9 + <%optional:<_ ="1" file="<%xml_escape image:maps/<%db\rangcode%>.gif maps/<%db\code%>.png png%>"/>%> 33.10 +<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 33.11 + </> 33.12 + <><%xml_escape db\rusname%></> 33.13 + <><%xml_escape db\class0%></> 33.14 + <1><%xml_escape db\class1%></1> 33.15 + <2><%xml_escape db\class2%></2> 33.16 + <3><%xml_escape db\class3%></3> 33.17 + <_ rows="3"><%xml_cdata db\descript%></_> 33.18 + <_ rows="3"><%xml_cdata db\geobotdescr%></_> 33.19 + <_><%xml_escape db\contributors%></_> 33.20 +</_>
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/misc/biotopes/brief.dtd Tue Feb 19 20:32:17 2008 +0300 34.3 @@ -0,0 +1,27 @@ 34.4 +<?xml encoding="ISO-8859-5"?> 34.5 +<!ELEMENT _ (?, , , 1, 2, 3, _, _, _)> 34.6 +<!ELEMENT (|_)*> 34.7 +<!ELEMENT EMPTY> 34.8 +<!ELEMENT _ EMPTY> 34.9 +<!ELEMENT (#PCDATA)> 34.10 +<!ELEMENT (#PCDATA)> 34.11 +<!ELEMENT 1 (#PCDATA)> 34.12 +<!ELEMENT 2 (#PCDATA)> 34.13 +<!ELEMENT 3 (#PCDATA)> 34.14 +<!ELEMENT _ (#PCDATA)> 34.15 +<!ELEMENT _ (#PCDATA)> 34.16 +<!ELEMENT _ (#PCDATA)> 34.17 +<!ATTLIST _ show (0|1) "1"> 34.18 +<!ATTLIST 34.19 + display CDATA #FIXED "0"> 34.20 +<!ATTLIST 34.21 + num ID #REQUIRED 34.22 + file CDATA #REQUIRED 34.23 + big CDATA #REQUIRED 34.24 + text CDATA #IMPLIED 34.25 + CDATA #IMPLIED> 34.26 +<!ATTLIST _ 34.27 + num ID #REQUIRED 34.28 + file CDATA #REQUIRED> 34.29 +<!ATTLIST _ rows CDATA #FIXED "3"> 34.30 +<!ATTLIST _ rows CDATA #FIXED "3">
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/misc/biotopes/class.sql Tue Feb 19 20:32:17 2008 +0300 35.3 @@ -0,0 +1,7 @@ 35.4 +SELECT t1.* 35.5 +FROM biotopelist AS t1 35.6 +WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 35.7 + AND EXISTS 35.8 + (SELECT NULL FROM biotopelist AS t2 35.9 + WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 35.10 + AND Right(t2.rangcode, 8) <> '00000000')
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/misc/biotopes/classes.template Tue Feb 19 20:32:17 2008 +0300 36.3 @@ -0,0 +1,5 @@ 36.4 +<?xml version="1.0" encoding="ISO-8859-5"?> 36.5 +<><%query:class_sql [%\ 36.6 + <!-- rangcode: <%xml_escape get\rangcode%> --> 36.7 + < id="<%get\NUMBER%>"><%xml_escape db\rusname%></>%]%> 36.8 +</>
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/misc/biotopes/doc/article.txt Tue Feb 19 20:32:17 2008 +0300 37.3 @@ -0,0 +1,391 @@ 37.4 +* XML- . 37.5 + 37.6 + " 37.7 +" Microsoft Access XML- 37.8 + DbReader. 37.9 + 37.10 + DbReader 37.11 + . 37.12 + 37.13 + . 37.14 + SQL-, 37.15 +. 37.16 + 37.17 + 37.18 +* : 37.19 + 37.20 + <%<_>{:|\}<>%> 37.21 + 37.22 + 37.23 +<_> - , . 37.24 + . 37.25 +<> - , . 37.26 + 37.27 + 37.28 +* : 37.29 + 37.30 + [<_>][<>] 37.31 + 37.32 + 37.33 +<_> - , . 37.34 + . 37.35 +<> - , . 37.36 + . , 37.37 + , . 37.38 + 37.39 + , 37.40 + : 37.41 +: - , 37.42 +\ - . 37.43 + 37.44 + , , 37.45 + , 37.46 + . 37.47 + 37.48 + - . 37.49 + - . , 37.50 + - 37.51 +. 37.52 + 37.53 + '<', '>' '[', ']'. 37.54 + 37.55 + 37.56 +* : 37.57 + 37.58 +: set 37.59 +: <> 37.60 +: <> 37.61 +: <> 37.62 +: <> 37.63 + : 1 37.64 + 37.65 +: get 37.66 +: <> 37.67 +: <>. 37.68 + : 1, , 0 - . 37.69 + 37.70 +: prepare 37.71 +: <> 37.72 +: <> 37.73 +: SQL- <> , 37.74 + <>. 37.75 +: <> 37.76 + : 1 37.77 + 37.78 +: query 37.79 +: <_> <> <1> ... <N> 37.80 +: , 37.81 + prepare. 37.82 + '?'. 37.83 + , <>. 37.84 + <> NUMBER, 37.85 + . , 37.86 + , 37.87 + <> SUPER.<_>. 37.88 + 37.89 +: <> 37.90 + . 37.91 + : . 37.92 + 37.93 +: optional 37.94 +: <> 37.95 +: <>, 37.96 + 0, - . 37.97 + : 1, - , 0 - . 37.98 + 37.99 +: image 37.100 +: <_> <_> <> [<_> [<_>]] 37.101 +: <_> ( 37.102 + "resource_base") 37.103 + , 37.104 + <_>. , 37.105 + . 37.106 +: <_> , - . 37.107 + : 1 , 0 - . 37.108 + 37.109 +: copy 37.110 +: <_> <_> 37.111 +: <_> <_> 37.112 + ( <_> 37.113 + "resource_base"). 37.114 +: <_> , - . 37.115 + : 1 , 0 - . 37.116 + 37.117 +: write 37.118 +: <_> 37.119 +: <> 37.120 +: <> <_>. 37.121 +: <_> , - . 37.122 + : 1 , 0 - . 37.123 + 37.124 +: read 37.125 +: <_> 37.126 +: <_>. 37.127 +: , 37.128 + - . 37.129 + : 1 , 0 - . 37.130 + 37.131 +: include 37.132 +: <_> 37.133 +: <_>. 37.134 +: . 37.135 + : , . 37.136 + 37.137 +: ! 37.138 +: <> 37.139 +: . 37.140 +: . 37.141 + : , . 37.142 + 37.143 +: replace 37.144 +: <1> <2> 37.145 +: <> 37.146 +: , <1> 37.147 + <2>. 37.148 + : , . 37.149 + 37.150 +: xml_escape 37.151 +: <> 37.152 +: <>, 37.153 + '&', '<', '>', '`', '\' 37.154 + XML. 37.155 + : , . 37.156 + 37.157 +: xml_cdata 37.158 +: <> 37.159 +: XML CDATA. 37.160 + : , . 37.161 + 37.162 + DbReader : 37.163 +, Java. 37.164 + 37.165 + 37.166 +* DbReader 37.167 + " " Microsoft Access 37.168 + XML- 37.169 + 37.170 + " 37.171 + " ( ): 37.172 + 37.173 +biotopelist (code, rangcode, rusname, engname, descript, geobotdescr, 37.174 + contributors, descrdate) 37.175 + 37.176 + code - , ; 37.177 + rangcode - ABBCCDDEE, , BB, CC, DD, - 37.178 + , ; 37.179 + rusname, engname, descript, geobotdescr - ; 37.180 + descrdate - . 37.181 + 37.182 +photos (biotope, photo, authphoto) 37.183 + 37.184 + biotope - , code biotopelist; 37.185 + photo - ; 37.186 + authphoto - . 37.187 + 37.188 + xml- biotopelist, 37.189 + , , 37.190 + . 37.191 + 37.192 + xml- 37.193 + DbReader ( biotope.template): 37.194 + 37.195 +---------------------------------------------------------------------- 37.196 +<?xml version="1.0" encoding="ISO-8859-5"?> 37.197 +<!DOCTYPE _ SYSTEM "brief.dtd"> 37.198 +<!-- rangcode: <%xml_escape get\rangcode%> --> 37.199 +<_ show="0"> 37.200 + < display="0"> 37.201 + <%optional:<_ ="1" 37.202 + file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%> 37.203 +<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 37.204 + </> 37.205 + <><%xml_escape get\rusname%></> 37.206 + <><%xml_escape get\class0%></> 37.207 + <1><%xml_escape get\class1%></1> 37.208 + <2><%xml_escape get\class2%></2> 37.209 + <3><%xml_escape get\class3%></3> 37.210 + <_ rows="3"><%xml_cdata get\descript%></_> 37.211 + <_ rows="3"><%xml_cdata get\geobotdescr%></_> 37.212 + <_><%xml_escape get\contributors%></_> 37.213 +</_> 37.214 +---------------------------------------------------------------------- 37.215 + 37.216 + SQL-, 37.217 + rangcode, rusname, class0, class1, class2, 37.218 +class3, descript, geobotdescr contributors ( biotope.sql): 37.219 + 37.220 +---------------------------------------------------------------------- 37.221 +SELECT t1.*, 37.222 + 37.223 +(SELECT t2.rusname FROM biotopelist AS t2 37.224 +WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 37.225 +AND Right(t2.rangcode, 8) = '00000000' 37.226 +AND Right(t1.rangcode, 8) <> '00000000') AS class0, 37.227 + 37.228 +(SELECT t2.rusname FROM biotopelist AS t2 37.229 +WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 37.230 +AND Right(t2.rangcode, 6) = '000000' 37.231 +AND Right(t1.rangcode, 6) <> '000000') AS class1, 37.232 + 37.233 +(SELECT t2.rusname FROM biotopelist AS t2 37.234 +WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 37.235 +AND Right(t2.rangcode, 4) = '0000' 37.236 +AND Right(t1.rangcode, 4) <> '0000') AS class2, 37.237 + 37.238 +(SELECT t2.rusname FROM biotopelist AS t2 37.239 +WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 37.240 +AND Right(t2.rangcode, 2) = '00' 37.241 +AND Right(t1.rangcode, 2) <> '00') AS class3 37.242 + 37.243 +FROM biotopelist AS t1 37.244 +WHERE rusname 37.245 +---------------------------------------------------------------------- 37.246 + 37.247 + biotope.template <%include\photo.template%>, 37.248 + ( photo.template): 37.249 + 37.250 +---------------------------------------------------------------------- 37.251 + < num="<%xml_escape get\NUMBER%>" 37.252 + <%optional:="<%xml_escape get\authphoto%>" %>text="" 37.253 + file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>" 37.254 + big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/> 37.255 +---------------------------------------------------------------------- 37.256 + 37.257 + SQL- 37.258 +(photo.sql): 37.259 + 37.260 +---------------------------------------------------------------------- 37.261 +SELECT * from photos WHERE biotope = ? 37.262 +---------------------------------------------------------------------- 37.263 + 37.264 +, ( classes.template): 37.265 + 37.266 +---------------------------------------------------------------------- 37.267 +<?xml version="1.0" encoding="ISO-8859-5"?> 37.268 +<><%query:class_sql [%\ 37.269 + <!-- rangcode: <%xml_escape get\rangcode%> --> 37.270 + < id="<%get\NUMBER%>"><%xml_escape get\rusname%></>%]%> 37.271 +</> 37.272 +---------------------------------------------------------------------- 37.273 + 37.274 + SQL- (class.sql): 37.275 + 37.276 +---------------------------------------------------------------------- 37.277 +SELECT t1.* 37.278 +FROM biotopelist AS t1 37.279 +WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 37.280 + AND EXISTS 37.281 + (SELECT NULL FROM biotopelist AS t2 37.282 + WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 37.283 + AND Right(t2.rangcode, 8) <> '00000000') 37.284 +---------------------------------------------------------------------- 37.285 + 37.286 +, ( plants.template): 37.287 + 37.288 +---------------------------------------------------------------------- 37.289 +<?xml version="1.0" encoding="ISO-8859-5"?> 37.290 +<><%query:plant_sql [%\ 37.291 + <!-- rangcode: <%xml_escape get\rangcode%> --> 37.292 + <><%xml_escape get\rusname%></>%]%> 37.293 +</> 37.294 +---------------------------------------------------------------------- 37.295 + 37.296 + SQL- (plant.sql): 37.297 + 37.298 +---------------------------------------------------------------------- 37.299 +SELECT t1.* 37.300 +FROM biotopelist AS t1 37.301 +WHERE rusname AND Right(t1.rangcode, 2) <> '00' 37.302 +---------------------------------------------------------------------- 37.303 + 37.304 + DbReader index.template, 37.305 + SQL- 37.306 +: 37.307 + 37.308 +---------------------------------------------------------------------- 37.309 +<%!: 37.310 + <%prepare:biotope_sql <%read\biotope.sql%>%> 37.311 + <%prepare:photo_sql <%read\photo.sql%>%> 37.312 + <%prepare:class_sql <%read\class.sql%>%> 37.313 + <%prepare:plant_sql <%read\plant.sql%>%> 37.314 + 37.315 + <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%> 37.316 + 37.317 + <%write:classes.xml <%include\classes.template%>%> 37.318 + <%write:plants.xml <%include\plants.template%>%> 37.319 +%> 37.320 +---------------------------------------------------------------------- 37.321 + 37.322 + XML-: 37.323 + 37.324 +---------------------------------------------------------------------- 37.325 +<?xml version="1.0" encoding="ISO-8859-5"?> 37.326 +<!DOCTYPE _ SYSTEM "brief.dtd"> 37.327 +<!-- rangcode: E04020302 --> 37.328 +<_ show="0"> 37.329 + < display="0"> 37.330 + < num="1" =" .." text="" 37.331 + file="images/3_1.jpg" 37.332 + big="images/big/3_1.jpg"/> 37.333 + < num="2" =" .." text="" 37.334 + file="images/3_2.jpg" 37.335 + big="images/big/3_2.jpg"/> 37.336 + </> 37.337 + <>Betula sp. - Avenella flexuosa - Polytrichum commune</> 37.338 + <>E. </> 37.339 + <1> </1> 37.340 + <2></2> 37.341 + <3></3> 37.342 + <_ rows="3"><![CDATA[ . 5 - 7 , , , .]]></_> 37.343 + <_ rows="3"></_> 37.344 + <_></_> 37.345 +</_> 37.346 +---------------------------------------------------------------------- 37.347 + 37.348 + 37.349 +* DbReader 37.350 + 37.351 + DbReader Java 37.352 + : 37.353 + 37.354 +ru.karrc.dbreader.DbReader: c . 37.355 +, 37.356 + JDBC, . 37.357 + 37.358 +ru.karrc.dbreader.TemplateParser: , 37.359 + . 37.360 + 37.361 +ru.karrc.dbreader.Function: . 37.362 +DbReader . 37.363 + 37.364 +ru.karrc.dbreader.FunctionDataParser: 37.365 +. , 37.366 +. 37.367 + TemplateParser. 37.368 + 37.369 +ru.karrc.dbreader.Functions: 37.370 + , Function. 37.371 + 37.372 +ru.karrc.dbreader.TemplateParser: , 37.373 + . 37.374 + 37.375 + , , 37.376 + . 37.377 + 37.378 + 37.379 +* . 37.380 + 37.381 + : 8, 37.382 + Java- ( ): 27, 37.383 + : 1311, 37.384 + ( ): 812, 37.385 + : 180. 37.386 + 37.387 + 37.388 +* 37.389 + 37.390 + DbReader, 37.391 + 37.392 + . 37.393 +DbReader " " 37.394 + XML- .
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/misc/biotopes/doc/readme.html Tue Feb 19 20:32:17 2008 +0300 38.3 @@ -0,0 +1,86 @@ 38.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 38.5 + "DTD/xhtml1-transitional.dtd"> 38.6 + 38.7 +<html> 38.8 + 38.9 +<head> 38.10 + <title>DbReader</title> 38.11 + <meta http-equiv="Content-Type" content="text/html; charset=koi8-r" /> 38.12 +</head> 38.13 + 38.14 +<body> 38.15 +<h1>DbReader</h1> 38.16 + 38.17 +<h2> </h2> 38.18 +<ol> 38.19 +<li> .</li> 38.20 + 38.21 +<li> :<br /> 38.22 + Windows 2000: // (ODBC), biotopes-data.mdb.</li> 38.23 + 38.24 +<li> :<br /> 38.25 + dbreader.properties , :<br /> 38.26 + <code>resource: jdbc:odbc:<em></em></code><br /> 38.27 + , ( biotopephotos maps):<br /> 38.28 + <code>resource_base: C:\\biotopes</code><br /> 38.29 +( '\' )</li> 38.30 + 38.31 +<li> :<br /> 38.32 +<code>dbreader.bat</code> <br /> 38.33 +<code>java -jar dbreader.jar</code>.<br /> 38.34 + Java Runtime Environment (JRE) 5.0, <a href="http://java.sun.com/j2se/1.5.0/download.jsp">http://java.sun.com/j2se/1.5.0/download.jsp</a>. , JRE - . 38.35 + 38.36 + :<br /> 38.37 + <code>java -Dru.karrc.dbreader.<em></em>=<em></em> -jar dbreader.jar</code><br /> 38.38 +(: <code>java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar</code>)</li> 38.39 +</ol> 38.40 + 38.41 +<h2> </h2> 38.42 + 38.43 +<p> biotope.sql ( , dbreader.properties), biotope.template, .</p> 38.44 +<p> : <code><%<em>_</em>[:|\]<em></em>%></code>, <em> </em> - , . , .</p> 38.45 + 38.46 +<h3> </h3> 38.47 + 38.48 +<ul> 38.49 + <li><code>:</code> - .</li> 38.50 + <li><code>\</code> - . <code><%</code> <code>%></code> (<code><%\<%%></code> <code><%\%%>></code>).</li> 38.51 +</ul> 38.52 + 38.53 +<h3></h3> 38.54 + 38.55 +<ul> 38.56 + <li><code><%get:<em></em>%></code><br /> 38.57 + .</li> 38.58 + 38.59 + <li><code><%optional:<em></em>%></code><br /> 38.60 + <em></em>, , , .</li> 38.61 + 38.62 + <li><code><%escape:<em></em>%></code><br /> 38.63 + "" ( ).</li> 38.64 + 38.65 + <li><code><%invoke:<em></em>; <em>1</em> <em>2</em> ... <em>N</em>%></code><br /> 38.66 + <em></em>.sql <em></em>.template. '?'.</li> 38.67 + 38.68 + <li><code><%image:<em>_</em> <em>_</em> <em></em> [<em>_</em>] [<em>_</em>]%></code><br /> 38.69 + <em>_</em> ( "resource_base") , <em>_</em>. , . 38.70 + , <code><%image:...%></code> <em>_</em>, - .</li> 38.71 + 38.72 + <li><code><%copy:<em>_</em> <em>_</em>%></code><br /> 38.73 + <em>_</em> ( "resource_base") <em>_</em>. , <code><%copy:...%></code> <em>_</em>, - .</li> 38.74 +</ul> 38.75 + 38.76 +<h3> </h3> 38.77 + 38.78 +<p><code>NUMBER</code> - . 38.79 + , invoke, <code>SUPER.</code> (: <code>SUPER.NUMBER</code>).</p> 38.80 + 38.81 +<h3></h3> 38.82 + 38.83 +<p> name :</p> 38.84 +<p><code><%escape get:name%></code></p> 38.85 + 38.86 +<p align="right"><i><a href="mailto:kryshen@cs.karelia.ru"> </a></i></p> 38.87 + 38.88 +</body> 38.89 +</html>
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/misc/biotopes/doc/readme.txt Tue Feb 19 20:32:17 2008 +0300 39.3 @@ -0,0 +1,63 @@ 39.4 +text/plain; charset=UTF-8 39.5 + 39.6 +Установка программы 39.7 +------------------- 39.8 + 39.9 +1. Распаковать архив. 39.10 + 39.11 +2. Установить источник данных: 39.12 +в Windows 2000: Панель управления/Администрирование/Источники данных (ODBC), добавить biotopes.mdb. 39.13 + 39.14 +3. Настроить программу: 39.15 +В файле dbreader.properties указать имя, присвоенное источнику данных: 39.16 + "resource: jdbc:odbc:<имя>" 39.17 +и путь к каталогу, относительно которого программа будет искать изображения (содержащий biotopephotos и maps): 39.18 + "resource_base: C:\\biotopes" 39.19 +(символ '\' необходимо дублировать) 39.20 + 39.21 +4. Запуск программы: dbreader.bat или "java -jar dbreader.jar" 39.22 +Для запуска необходима Java Runtime Environment (JRE) 5.0, можно скачать с http://java.sun.com/j2se/1.5.0/download.jsp. Возможно, будет работать и со старыми версиями JRE - не проверял. 39.23 + 39.24 +Все значения файла конфигурации можно переопределять при запуске программы: 39.25 + команда "java -Dru.karrc.dbreader.<ключ>=<значение> -jar dbreader.jar" 39.26 +(например: "java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar") 39.27 + 39.28 + 39.29 +Работа программы 39.30 +---------------- 39.31 + 39.32 +Программа выполняет запрос biotope.sql (или другой, указанный в dbreader.properties), после чего обрабатывает файл biotope.template, заменяя найденные в нем инструкции на результаты их выполнения. 39.33 + 39.34 +Формат инструкций: "<%список_функций[:|\]данные%>", список функций - имена функций разделенные пробелом, список может быть пустым. Если указано несколько функций, они выполняются начиная с последней. 39.35 + 39.36 +Разделители между списком функций и данными: 39.37 +':' - данные будут обрабатываться рекурсивно. 39.38 +'\' - данные будут переданы функции без обработки. Можно использовать для экранирования комбинаций символов "<%" и "%>" ("<%\<%%>" и "<%\%%>>"). 39.39 + 39.40 +Функции: 39.41 +<%get:<имя>%> - заменяется на значение встроенной переменной или колонки запроса. 39.42 + 39.43 +<%optional:<текст>%> 39.44 +Заменяется на <текст>, если в нем найдены инструкции, заменившиеся на непустые строки, иначе заменяется на пустую строку. 39.45 + 39.46 +<%escape:<текст>%> 39.47 +Заменяет в тексте "опасные" символы (таблица замен задается в файле конфигурации). 39.48 + 39.49 +<%invoke:<имя> <парам1> <парам2> ... <парамN>%> 39.50 +Выполняет запрос с параметрами <имя>.sql и заменяется на результаты обработки шаблона <имя>.template. Значения параметров подставляются в запрос вместо символа '?'. 39.51 + 39.52 +<%image:<исх_файл> <кон_файл> <формат> [<макс_ширина>] [<макс_высота>]%> 39.53 +Загружает изображение из файла <исх_файл> (путь определяется относительно конфигурационного параметра "resource_base") и преобразует его в указанный формат, сохраняя результат в <кон_файл>. Если заданы максимальная высота и ширина, большие изображения будут уменьшены. 39.54 +При успешном выполнении, инструкция "<%!image ...%>" будет заменена на значение <кон_файл>, иначе - на пустую строку. 39.55 + 39.56 +<%copy:<исх_файл> <кон_файл>%> 39.57 +Копирует файл <исх_файл> (путь определяется относительно конфигурационного параметра "resource_base"). 39.58 +При успешном выполнении, инструкция "<%!copy ...%>" будет заменена на значение <кон_файл>, иначе - на пустую строку. 39.59 + 39.60 +Встроенные переменные: 39.61 +NUMBER - порядковый номер строки результата выполнения запроса. 39.62 +Чтобы обратиться к переменной запроса, из которого обрабатываемый шаблон был вызван с помощью функции invoke, перед именем переменной нужно добавить "SUPER." (например: "SUPER.NUMBER"). 39.63 + 39.64 +Пример: 39.65 +Следующая инструкция получит значение из столбца name и заменит в нем специальные символы: 39.66 +<%escape get:name%>
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/misc/biotopes/main.template Tue Feb 19 20:32:17 2008 +0300 40.3 @@ -0,0 +1,11 @@ 40.4 +<%!: 40.5 + <%prepare:biotope_sql <%read\biotope.sql%>%> 40.6 + <%prepare:photo_sql <%read\photo.sql%>%> 40.7 + <%prepare:class_sql <%read\class.sql%>%> 40.8 + <%prepare:plant_sql <%read\plant.sql%>%> 40.9 + 40.10 + <%query:biotope_sql [%\<%write:<%db\code%>.xml <%include\biotope.template%>%> %]%> 40.11 + 40.12 + <%write:classes.xml <%include\classes.template%>%> 40.13 + <%write:plants.xml <%include\plants.template%>%> 40.14 +%>
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/misc/biotopes/photo.sql Tue Feb 19 20:32:17 2008 +0300 41.3 @@ -0,0 +1,1 @@ 41.4 +SELECT * from photos WHERE biotope = ?
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/misc/biotopes/photo.template Tue Feb 19 20:32:17 2008 +0300 42.3 @@ -0,0 +1,3 @@ 42.4 + < num="<%number\%>" <%optional:="<%xml_escape db\authphoto%>" %>text="" 42.5 + file="<%xml_escape image:biotopephotos/<%db\photo%> images/<%super.db\code%>_<%number\%>.jpg jpg 300 300%>" 42.6 + big="<%xml_escape copy:biotopephotos/<%db\photo%> images/big/<%super.db\code%>_<%number\%>.jpg%>"/>
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/misc/biotopes/plant.sql Tue Feb 19 20:32:17 2008 +0300 43.3 @@ -0,0 +1,3 @@ 43.4 +SELECT t1.* 43.5 +FROM biotopelist AS t1 43.6 +WHERE rusname AND Right(t1.rangcode, 2) <> '00'
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/misc/biotopes/plants.template Tue Feb 19 20:32:17 2008 +0300 44.3 @@ -0,0 +1,5 @@ 44.4 +<?xml version="1.0" encoding="ISO-8859-5"?> 44.5 +<><%query:plant_sql [%\ 44.6 + <!-- rangcode: <%xml_escape db\rangcode%> --> 44.7 + <><%xml_escape db\rusname%></>%]%> 44.8 +</>
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/misc/biotopes/tema.properties Tue Feb 19 20:32:17 2008 +0300 45.3 @@ -0,0 +1,22 @@ 45.4 +# Data source configuration 45.5 +resource : jdbc:odbc:biotopes-data 45.6 +driver : sun.jdbc.odbc.JdbcOdbcDriver 45.7 + 45.8 +# Base directory for images and files 45.9 +resource_base : C:\\biotopes\\db 45.10 + 45.11 +# Template to start processing with 45.12 +main_template : main.template 45.13 + 45.14 +# File encodings 45.15 +input_encoding : ISO-8859-5 45.16 +output_encoding : ISO-8859-5 45.17 + 45.18 +# Cache templates 45.19 +cache_read : true 45.20 + 45.21 +# Output main_template parsing result to stderr 45.22 +#output : stderr 45.23 + 45.24 +# File to output error messages (redirect stderr) 45.25 +#log : tema.log
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/misc/manual-ru-old/index.html Tue Feb 19 20:32:17 2008 +0300 46.3 @@ -0,0 +1,370 @@ 46.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 46.5 + "DTD/xhtml1-transitional.dtd"> 46.6 + 46.7 +<html> 46.8 + 46.9 +<head> 46.10 + <title>Макропроцессор TEMA</title> 46.11 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 46.12 +</head> 46.13 + 46.14 +<body> 46.15 +<h1>Макропроцессор TEMA</h1> 46.16 + 46.17 +<p>Макропроцессор TEMA обрабатывает заданные шаблоны текстовых файлов и 46.18 +заменяет найденные в них инструкции на результаты их выполнения. 46.19 +</p><p> 46.20 +Особенности: 46.21 +</p> 46.22 +<ul> 46.23 + <li>Расширяемость: возможно динамически подключать новые функии, 46.24 + реализованные в виде классов на Java.</li> 46.25 + <li>Работа с базами данных: использование SQL-запросов для получения 46.26 + данных.</li> 46.27 + <li>Поточная обработка данных: инструкции обрабатываются по мере 46.28 + чтения текста без необходимости загрузки файла в оперативную память 46.29 + и выполнения полного синтаксического разбора.</li> 46.30 +</ul> 46.31 + 46.32 +<p><b>Формат инструкций</b></p> 46.33 + 46.34 +<blockquote> 46.35 + <code><%<i>список_функций</i>{:|\|`}<i>данные</i>%></code> 46.36 +</blockquote> 46.37 +<p> 46.38 +где<br /> 46.39 + 46.40 +<code><i>список_функций</i></code> - список имен функций, разделенных 46.41 + пробелами. Может быть пустым.<br /> 46.42 +<code><i>данные</i></code> - данные, передаваемые функции. 46.43 +</p> 46.44 + 46.45 +<p><b>Формат данных</b></p> 46.46 + 46.47 +<blockquote> 46.48 + <code> 46.49 + [<i>список_аргументов</i>][<i>текст</i>] 46.50 + </code> 46.51 +</blockquote> 46.52 +<p> 46.53 +где<br /> 46.54 + 46.55 +<code><i>список_аргументов</i></code> - список аргументов функции, разделенных пробелами. 46.56 + Может быть пустым.<br /> 46.57 +<code><i>текст</i></code> - текст, передаваемый функции без разбиения на аргументы. 46.58 + Может быть пустым. Количество аргументов, после которого следует 46.59 + текст, зависит от функции. 46.60 +</p><p> 46.61 +Разделитель между списком функций и данными определяет, как должны 46.62 +обрабатываться данные функции: 46.63 +</p><p> 46.64 +<code>:</code> - рекурсивная обработка,<br /> 46.65 +<code>\</code> или <code>`</code> - передать без обработки. 46.66 +</p><p> 46.67 +Если в списке функций задано две и более функции, они выполняются, 46.68 +начиная с последней, так что каждая функция получает в качестве данных 46.69 +результат выполнения следующей функции. 46.70 +</p><p> 46.71 +Каждая функция имеет код возврата - целое число. Код возврата 46.72 +инструкции - код возврата первой в списке функции. Код возврата, 46.73 +получаемый при обработке текста - сумма кодов возврата обработанных 46.74 +инструкций (как правило, смысл этого значения - количество инструкций, 46.75 +замененных на непустой текст). 46.76 +</p><p> 46.77 +Кроме скобок '<', '>', можно использовать скобки '[', ']'. 46.78 +</p> 46.79 + 46.80 + 46.81 +<h2>Функции</h2> 46.82 + 46.83 +<p><code><b>set</b></code></p> 46.84 + 46.85 +<table> 46.86 +<tr><td>Аргументы:</td> 46.87 +<td><i>имя</i></td></tr> 46.88 + 46.89 +<tr><td>Текст:</td> 46.90 +<td><i>значение</i></td></tr> 46.91 + 46.92 +<tr><td>Действие:</td> 46.93 +<td>Устанавливает значение переменной <i>имя</i>.</td></tr> 46.94 + 46.95 +<tr><td>Результат:</td> 46.96 +<td><i>имя</i></td></tr> 46.97 + 46.98 +<tr><td>Код возврата:</td> 46.99 +<td>1</td></tr> 46.100 +</table> 46.101 + 46.102 +<p><code><b>define</b></code></p> 46.103 + 46.104 +<table> 46.105 +<tr><td>Аргументы:</td> 46.106 +<td><i>имя</i></td></tr> 46.107 + 46.108 +<tr><td>Текст:</td> 46.109 +<td><i>шаблон</i></td></tr> 46.110 + 46.111 +<tr><td>Действие:</td><td>Определяет новую функцию <i>имя</i>, при 46.112 +вызове которой обрабатывается <i>шаблон</i>. При обработке доступны 46.113 +функции <code>nextarg</code> для получения очередного аргумента 46.114 +вызываемой функции и <code>data</code> для получения текста.</td></tr> 46.115 + 46.116 +<tr><td>Результат:</td> 46.117 +<td><i>имя</i></td></tr> 46.118 + 46.119 +<tr><td>Код возврата:</td> 46.120 +<td>1</td></tr> 46.121 +</table> 46.122 + 46.123 +<p><code><b>load</b></code></p> 46.124 + 46.125 +<table> 46.126 +<tr><td>Аргументы:</td> 46.127 +<td><i>имя</i> <i>имя_класса</i></td></tr> 46.128 + 46.129 +<tr><td>Действие:</td> 46.130 + 46.131 +<td>Определяет новую функцию <i>имя</i>. Реализация функции определена 46.132 +Java-классом <i>имя_класса</i>, наследующим класс 46.133 +<code>kryshen.tema.Function</code>.</td></tr> 46.134 + 46.135 +<tr><td>Результат:</td> 46.136 +<td><i>имя</i></td></tr> 46.137 + 46.138 +<tr><td>Код возврата:</td> 46.139 +<td>1</td></tr> 46.140 +</table> 46.141 + 46.142 +<p><code><b>prepare</b></code></p> 46.143 + 46.144 +<table> 46.145 +<tr><td>Аргументы:</td> 46.146 +<td><i>имя</i></td></tr> 46.147 + 46.148 +<tr><td>Текст:</td> 46.149 +<td><i>запрос</i></td></tr> 46.150 + 46.151 +<tr><td>Действие:</td> 46.152 +<td>Подготавливает SQL-запрос <i>запрос</i> для выполнения, записывает 46.153 +подготовленный запрос в переменную <i>имя</i>.</td></tr> 46.154 + 46.155 +<tr><td>Результат:</td> 46.156 +<td><i>имя</i></td></tr> 46.157 + 46.158 +<tr><td>Код возврата:</td> 46.159 +<td>1</td></tr> 46.160 +</table> 46.161 + 46.162 +<p><code><b>query</b></code></p> 46.163 + 46.164 +<table> 46.165 +<tr><td>Аргументы:</td> 46.166 +<td><i>имя_запроса</i> <i>шаблон</i> <i>парам1</i> ... <i>парамN</i></td></tr> 46.167 + 46.168 +<tr><td>Действие:</td> 46.169 +<td>Выполняет запрос с параметрами, подготовленный с помощью функции 46.170 +prepare. Значения параметров подставляются в запрос вместо символа 46.171 +'?'. Значения полей ответа доступны с помощью функции <code>db</code>, 46.172 +как переменные шаблона <i>шаблон</i>. При обработки шаблона также 46.173 +определяется переменная <code>number</code>, содержащая номер текущей 46.174 +строки ответа.</td></tr> 46.175 + 46.176 +<tr><td>Результат:</td> 46.177 +<td>результат обработки шаблона <i>шаблон</i> для каждой строки 46.178 +ответа.</td></tr> 46.179 + 46.180 +<tr><td>Код возврата:</td> 46.181 +<td>Количество полученных строк ответа.</td></tr> 46.182 +</table> 46.183 + 46.184 +<p><code><b>optional</b></code></p> 46.185 + 46.186 +<table> 46.187 +<tr><td>Текст:</td> 46.188 +<td><i>данные</i></td></tr> 46.189 + 46.190 +<tr><td>Результат:</td><td><i>данные</i>, если при обработке данных 46.191 +был получен код возврата отличный от 0, иначе - пустая 46.192 +строка.</td></tr> 46.193 + 46.194 +<tr><td>Код возврата:</td> 46.195 +<td>1, если результат - пустая строка, 0 - иначе.</td></tr> 46.196 +</table> 46.197 + 46.198 +<p><code><b>image</b></code></p> 46.199 + 46.200 +<table> 46.201 +<tr><td>Аргументы:</td> 46.202 +<td><i>исх_файл</i> <i>кон_файл</i> <i>формат</i> [<i>макс_ширина</i> 46.203 +[<i>макс_высота</i>]]</td></tr> 46.204 + 46.205 +<tr><td>Действие:</td> 46.206 +<td>Загружает изображение из файла <i>исх_файл</i> (путь определяется 46.207 +относительно конфигурационного параметра "resource_base") и 46.208 +преобразует его в указанный формат, сохраняя результат в 46.209 +<i>кон_файл</i>. Если заданы максимальная высота и ширина, большие 46.210 +изображения будут уменьшены.</td></tr> 46.211 + 46.212 +<tr><td>Результат:</td> 46.213 +<td><i>кон_файл</i> при успешном выполнении, пустая строка - иначе.</td></tr> 46.214 + 46.215 +<tr><td>Код возврата:</td> 46.216 +<td>1 при успешном выполнении, 0 - иначе.</td></tr> 46.217 +</table> 46.218 + 46.219 + 46.220 +<p><code><b>copy</b></code></p> 46.221 + 46.222 +<table> 46.223 +<tr><td>Аргументы:</td><td><i>исх_файл</i> <i>кон_файл</i></td></tr> 46.224 + 46.225 +<tr><td>Действие:</td><td>Копирует файл <i>исх_файл</i> в файл 46.226 +<i>кон_файл</i> (путь <i>исх_файл</i> определяется относительно 46.227 +конфигурационного параметра "resource_base").</td></tr> 46.228 + 46.229 +<tr><td>Результат:</td><td><i>кон_файл</i> при успешном выполнении, 46.230 +пустая строка - иначе.</td></tr> 46.231 + 46.232 +<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 46.233 +иначе.</td></tr> 46.234 +</table> 46.235 + 46.236 +<p><code><b>write</b></code></p> 46.237 + 46.238 +<table> 46.239 +<tr><td>Аргументы:</td><td><i>имя_файла</i></td></tr> 46.240 + 46.241 +<tr><td>Текст:</td><td><i>данные</i></td></tr> 46.242 + 46.243 +<tr><td>Действие:</td><td>Записывает <i>данные</i> в файл 46.244 +<i>исх_файл</i>.</td></tr> 46.245 + 46.246 +<tr><td>Результат:</td><td><i>кон_файл</i> при успешном выполнении, 46.247 +пустая строка - иначе.</td></tr> 46.248 + 46.249 +<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 46.250 +иначе.</td></tr> 46.251 +</table> 46.252 + 46.253 +<p><code><b>read</b></code></p> 46.254 + 46.255 +<table> 46.256 +<tr><td>Текст:</td><td><i>имя_файла</i></td></tr> 46.257 +<tr><td>Действие:</td><td>Читает файл <i>имя_файла</i>.</td></tr> 46.258 +<tr><td>Результат:</td><td>прочитанные данные при успешном выполнении, 46.259 + пустая строка - иначе.</td></tr> 46.260 +<tr><td>Код возврата:</td><td>1 при успешном выполнении, 0 - 46.261 +иначе.</td></tr> 46.262 +</table> 46.263 + 46.264 +<p><code><b>include</b></code></p> 46.265 + 46.266 +<table> 46.267 +<tr><td>Текст:</td><td><i>имя_файла</i></td></tr> 46.268 +<tr><td>Действие:</td><td>включает шаблон из файла 46.269 +<i>имя_файла</i>.</td></tr> 46.270 +<tr><td>Результат:</td><td>результат обработки шаблона.</td></tr> 46.271 +<tr><td>Код возврата:</td><td>код возврата, полученный при обработке 46.272 +шаблона.</td></tr> 46.273 +</table> 46.274 + 46.275 +<p><code><b>!</b></code></p> 46.276 + 46.277 +<table> 46.278 +<tr><td>Текст:</td><td><i>данные</i></td></tr> 46.279 + 46.280 +<tr><td>Действие:</td><td>нет.</td></tr> 46.281 + 46.282 +<tr><td>Результат:</td><td>нет.</td></tr> 46.283 + 46.284 +<tr><td>Код возврата:</td><td>код возврата, полученный при обработке 46.285 +текста данных.</td></tr> 46.286 +</table> 46.287 + 46.288 +<p><code><b>replace</b></code></p> 46.289 + 46.290 +<table> 46.291 +<tr><td>Аргументы:</td><td><i>стр1</i> <i>стр2</i></td></tr> 46.292 + 46.293 +<tr><td>Текст:</td><td><i>данные</i></td></tr> 46.294 + 46.295 +<tr><td>Результат:</td><td>данные, с замененными вхождениями подстроки 46.296 +<i>стр1</i> на <i>стр2</i>.</td></tr> 46.297 + 46.298 +<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 46.299 +текста данных.</td></tr> 46.300 +</table> 46.301 + 46.302 +<p><code><b>xml_escape</b></code></p> 46.303 + 46.304 +<table> 46.305 +<tr><td>Текст:</td><td><i>данные</i></td></tr> 46.306 +<tr><td>Результат:</td><td>текст <i>данные</i>, в котором символы 46.307 +'&', '<', '>', '`', '\' заменены на соответствующие сущности 46.308 +XML.</td></tr> 46.309 + 46.310 +<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 46.311 +текста данных.</td></tr> 46.312 +</table> 46.313 + 46.314 +<p><code><b>xml_cdata</b></code></p> 46.315 + 46.316 +<table> 46.317 +<tr><td>Текст:</td><td><i>данные</i></td></tr> 46.318 + 46.319 +<tr><td>Результат:</td><td>данные в виде блока XML CDATA.</td></tr> 46.320 + 46.321 +<tr><td>Код возврата:</td><td> код возврата, полученный при обработке 46.322 +текста данных. </td></tr> 46.323 +</table> 46.324 + 46.325 +<p> 46.326 +Макропроцессор TEMA расширяем: возможно добавление в систему новых 46.327 +функций, реализованных в виде классов на языке Java. 46.328 +</p> 46.329 + 46.330 +<h2>Запуск</h2> 46.331 + 46.332 +<p>java -jar tema.jar [<i>опции</i>] 46.333 +</p><p> 46.334 +Опции: 46.335 +</p> 46.336 +<table> 46.337 +<tr><td>-d[emo]</td><td>Демонстрационный режим</td></tr> 46.338 +<tr><td>-v[ersion]</td><td>Вывод версии</td></tr> 46.339 +<tr><td>-h[help] -u[sage]</td><td>Вывод справки</td></tr> 46.340 +</table> 46.341 + 46.342 +<p> 46.343 +При запуске читается файл "tema.properties" из текущего каталога.<br /> 46.344 +Пример файла "tema.properties": 46.345 +</p> 46.346 + 46.347 +<pre> 46.348 +# Настройка источника данных 46.349 +# resource : jdbc:odbc:database 46.350 +# driver : sun.jdbc.odbc.JdbcOdbcDriver 46.351 + 46.352 +# Базовый каталог ресурсов 46.353 +# resource_base : . 46.354 + 46.355 +# Шаблон, с которого начинается обработка 46.356 +main_template : main.template 46.357 + 46.358 +# Кодировки файлов 46.359 +# input_encoding : UTF-8 46.360 +# output_encoding : UTF-8 46.361 + 46.362 +# Кэширование шаблонов 46.363 +# cache_read : true 46.364 + 46.365 +# Вывод результата разбора шаблона main.template в stderr 46.366 +# output : stderr 46.367 + 46.368 +# Вывод сообщений об ошибках в файл 46.369 +# log : dbreader.log 46.370 +</pre> 46.371 + 46.372 +</body> 46.373 +</html>
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/misc/util/header Tue Feb 19 20:32:17 2008 +0300 47.3 @@ -0,0 +1,21 @@ 47.4 +/* 47.5 + * Copyright 2006-2008 Mikhail Kryshen 47.6 + * 47.7 + * This file is part of Tema. 47.8 + * 47.9 + * Tema is free software: you can redistribute it and/or modify it 47.10 + * under the terms of the GNU Lesser General Public License as 47.11 + * published by the Free Software Foundation, either version 3 of the 47.12 + * License, or (at your option) any later version. 47.13 + * 47.14 + * Tema is distributed in the hope that it will be useful, 47.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 47.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 47.17 + * GNU Lesser General Public License for more details. 47.18 + * 47.19 + * You should have received a copy of the 47.20 + * GNU Lesser General Public License along with Tema. 47.21 + * If not, see <http://www.gnu.org/licenses/>. 47.22 + * 47.23 + * $Id: $ 47.24 + */
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/misc/util/header.gpl Tue Feb 19 20:32:17 2008 +0300 48.3 @@ -0,0 +1,20 @@ 48.4 +/* 48.5 + * Copyright (C) 2006, 2007, 2008 Mikhail Kryshen 48.6 + * 48.7 + * This file is part of Tema. 48.8 + * 48.9 + * Tema is free software: you can redistribute it and/or modify it 48.10 + * under the terms of the GNU General Public License as published by 48.11 + * the Free Software Foundation, either version 3 of the License, or 48.12 + * (at your option) any later version. 48.13 + * 48.14 + * Tema is distributed in the hope that it will be useful, 48.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 48.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 48.17 + * GNU General Public License for more details. 48.18 + * 48.19 + * You should have received a copy of the GNU General Public License 48.20 + * along with Tema. If not, see <http://www.gnu.org/licenses/>. 48.21 + * 48.22 + * $Id: header.gpl,v 1.1 2008/02/16 16:56:34 mikhail Exp $ 48.23 + */
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/misc/util/update_headers.pl Tue Feb 19 20:32:17 2008 +0300 49.3 @@ -0,0 +1,36 @@ 49.4 +#!/usr/bin/perl 49.5 + 49.6 +use File::Find; 49.7 + 49.8 +undef $/; 49.9 + 49.10 +my $src = "../../src"; 49.11 +my $header_file = "header"; 49.12 + 49.13 +open (FILE, "$header_file"); 49.14 +my $header = <FILE>; 49.15 +close(FILE); 49.16 + 49.17 +find (\&update_header, $src); 49.18 + 49.19 +sub update_header 49.20 +{ 49.21 + my $code; 49.22 + 49.23 + if ( $File::Find::name !~ /^.*\.java$/ ) 49.24 + { 49.25 + return; 49.26 + } 49.27 + 49.28 + print $File::Find::name."\n"; 49.29 + open(FILE, "$_") or die "error opening file"; 49.30 + 49.31 + $code = <FILE>; 49.32 + $code =~ s|(^[[:space:]]*/\*.*?\*/[[:space:]]*?\n\|^)|$header|s; 49.33 + 49.34 + close(FILE); 49.35 + 49.36 + open(FILE, ">$_") or die "error opening file"; 49.37 + print FILE $code; 49.38 + close(FILE); 49.39 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/nbproject/.cvsignore Tue Feb 19 20:32:17 2008 +0300 50.3 @@ -0,0 +1,1 @@ 50.4 +private
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/nbproject/project.xml Tue Feb 19 20:32:17 2008 +0300 51.3 @@ -0,0 +1,81 @@ 51.4 +<?xml version="1.0" encoding="UTF-8"?> 51.5 +<project xmlns="http://www.netbeans.org/ns/project/1"> 51.6 + <type>org.netbeans.modules.ant.freeform</type> 51.7 + <configuration> 51.8 + <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1"> 51.9 + <!-- Do not use Project Properties customizer when editing this file manually. --> 51.10 + <name>TEMA</name> 51.11 + <properties/> 51.12 + <folders> 51.13 + <source-folder> 51.14 + <label>src</label> 51.15 + <type>java</type> 51.16 + <location>src</location> 51.17 + </source-folder> 51.18 + <source-folder> 51.19 + <label>test</label> 51.20 + <type>java</type> 51.21 + <location>test</location> 51.22 + </source-folder> 51.23 + </folders> 51.24 + <ide-actions> 51.25 + <action name="build"> 51.26 + <target>compile</target> 51.27 + </action> 51.28 + <action name="clean"> 51.29 + <target>clean</target> 51.30 + </action> 51.31 + <action name="javadoc"> 51.32 + <target>doc.api</target> 51.33 + </action> 51.34 + <action name="rebuild"> 51.35 + <target>clean</target> 51.36 + <target>compile</target> 51.37 + </action> 51.38 + <action name="run"> 51.39 + <target>run.demo</target> 51.40 + </action> 51.41 + </ide-actions> 51.42 + <view> 51.43 + <items> 51.44 + <source-folder style="packages"> 51.45 + <label>src</label> 51.46 + <location>src</location> 51.47 + </source-folder> 51.48 + <source-folder style="packages"> 51.49 + <label>test</label> 51.50 + <location>test</location> 51.51 + </source-folder> 51.52 + <source-file> 51.53 + <location>build.xml</location> 51.54 + </source-file> 51.55 + </items> 51.56 + <context-menu> 51.57 + <ide-action name="build"/> 51.58 + <ide-action name="rebuild"/> 51.59 + <ide-action name="clean"/> 51.60 + <ide-action name="javadoc"/> 51.61 + <ide-action name="run"/> 51.62 + <action> 51.63 + <label>Compile manual</label> 51.64 + <target>doc.manual</target> 51.65 + </action> 51.66 + </context-menu> 51.67 + </view> 51.68 + <subprojects/> 51.69 + </general-data> 51.70 + <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2"> 51.71 + <compilation-unit> 51.72 + <package-root>src</package-root> 51.73 + <classpath mode="compile">build:dist/lib/commons-cli-1.1.jar:../../../../../usr/share/java/ant.jar</classpath> 51.74 + <source-level>1.5</source-level> 51.75 + </compilation-unit> 51.76 + <compilation-unit> 51.77 + <package-root>test</package-root> 51.78 + <unit-tests/> 51.79 + <classpath mode="compile">build</classpath> 51.80 + <source-level>1.5</source-level> 51.81 + </compilation-unit> 51.82 + </java-data> 51.83 + </configuration> 51.84 +</project>
52.1 --- a/res/kryshen/tema/demo/demo.template Thu Dec 14 23:22:05 2006 +0300 52.2 +++ b/res/kryshen/tema/demo/demo.template Tue Feb 19 20:32:17 2008 +0300 52.3 @@ -1,25 +1,34 @@ 52.4 -[%!\ TEMA demo template %] 52.5 +[%!\ 52.6 + Tema demo template 52.7 +%]\\ 52.8 52.9 -Вывод текста: 52.10 -test text 52.11 +<%tema:%> 52.12 52.13 -Вывод специальных символов: 52.14 -[%\<%test%>%] 52.15 +Escaping special character sequences: 52.16 +[%\<%test:%>%] 52.17 52.18 -Объявление функции: 52.19 -<%define\test test arg1:[%nextarg:%], test arg2:[%nextarg:%], test data:[%data:%].%> 52.20 +Macro definition: 52.21 +<%define#test 52.22 + arg1:<%next_arg:%>, arg2:<%next_arg:%>, data:<%data:%>.%> 52.23 52.24 -Вызов новой функции: 52.25 -<%test:1 2 3%> 52.26 +Invoke defined macro: 52.27 +<%test:1 2 3 4 5%> 52.28 52.29 -Загрузка функции из класса: 52.30 +Define macro implemented as a Java class: 52.31 <%load\hello kryshen.tema.demo.Hello%> 52.32 52.33 -Выполенение загруженной функции: 52.34 -<%hello\TEMA%> 52.35 +Invoke defined macro: 52.36 +<%hello\Tema%> 52.37 52.38 -Условное выполнение: 52.39 -<%optional:<%true:%>True%> <%optional:<%false:%>False%> 52.40 +Conditional output: 52.41 +<%optional:<%true:%>True%>\ 52.42 +<%optional:<%false:%>False%> 52.43 52.44 -Тестирование xml_escape: 52.45 +Cycle: 52.46 +<%silent define#cycle_test 52.47 + Arguments list: <%while#"<%next_arg:%>" %>\ 52.48 +%>\ 52.49 +<%cycle_test:1 2 3 <%:4 5%>%> 52.50 + 52.51 +Escaping special characters in XML: 52.52 <%xml_escape\x < a & b%>
53.1 --- a/src/Manifest.mf Thu Dec 14 23:22:05 2006 +0300 53.2 +++ b/src/Manifest.mf Tue Feb 19 20:32:17 2008 +0300 53.3 @@ -1,2 +1,3 @@ 53.4 Manifest-Version: 1.0 53.5 Main-Class: kryshen.tema.Tema 53.6 +Class-Path: lib/commons-cli-1.1.jar
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/src/kryshen/tema/Context.java Tue Feb 19 20:32:17 2008 +0300 54.3 @@ -0,0 +1,130 @@ 54.4 +/* 54.5 + * Copyright 2006-2008 Mikhail Kryshen 54.6 + * 54.7 + * This file is part of Tema. 54.8 + * 54.9 + * Tema is free software: you can redistribute it and/or modify it 54.10 + * under the terms of the GNU Lesser General Public License as 54.11 + * published by the Free Software Foundation, either version 3 of the 54.12 + * License, or (at your option) any later version. 54.13 + * 54.14 + * Tema is distributed in the hope that it will be useful, 54.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 54.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54.17 + * GNU Lesser General Public License for more details. 54.18 + * 54.19 + * You should have received a copy of the 54.20 + * GNU Lesser General Public License along with Tema. 54.21 + * If not, see <http://www.gnu.org/licenses/>. 54.22 + * 54.23 + * $Id: Context.java,v 1.11 2008/02/19 16:21:00 mikhail Exp $ 54.24 + */ 54.25 + 54.26 +package kryshen.tema; 54.27 + 54.28 +import java.io.File; 54.29 +import java.util.HashMap; 54.30 +import java.util.Map; 54.31 + 54.32 +/** 54.33 + * Tema template context. 54.34 + * 54.35 + * @author Mikhail Kryshen 54.36 + */ 54.37 +public class Context { 54.38 + private Map<String, Object> definitions = new HashMap<String, Object>(); 54.39 + private Context superContext; 54.40 + private File baseDir; 54.41 + 54.42 + public Context() { 54.43 + this(null, null); 54.44 + } 54.45 + 54.46 + public Context(Context superContext) { 54.47 + this(superContext, null); 54.48 + } 54.49 + 54.50 + public Context(File baseDir) { 54.51 + this(null, baseDir); 54.52 + } 54.53 + 54.54 + public Context(Context superContext, File baseDir) { 54.55 + this.superContext = superContext; 54.56 + this.baseDir = baseDir; 54.57 + 54.58 + definitions.put("this", this); 54.59 + 54.60 + if (superContext != null) 54.61 + definitions.put("super", superContext); 54.62 + } 54.63 + 54.64 + public void clear() { 54.65 + definitions.clear(); 54.66 + } 54.67 + 54.68 + public boolean export(String name) { 54.69 + Object value = definitions.get(name); 54.70 + 54.71 + if (value == null) 54.72 + return false; 54.73 + 54.74 + export(name, value); 54.75 + return true; 54.76 + } 54.77 + 54.78 + public void export(String name, Object value) { 54.79 + if (superContext == null) { 54.80 + set(name, value); 54.81 + return; 54.82 + } 54.83 + 54.84 + definitions.remove(name); 54.85 + superContext.export(name, value); 54.86 + } 54.87 + 54.88 + public Object get(String name) throws TemplateException { 54.89 + Object value = definitions.get(name); 54.90 + 54.91 + if (value == null && superContext != null) 54.92 + return superContext.get(name); 54.93 + 54.94 + return value; 54.95 + } 54.96 + 54.97 + /** 54.98 + * Set the definition value. 54.99 + * 54.100 + * @param name Variable name. 54.101 + * @param value New variable value. 54.102 + */ 54.103 + public void set(String name, Object value) { 54.104 + definitions.put(name, value); 54.105 + } 54.106 + 54.107 + /** 54.108 + * Remove the definition recursively. 54.109 + * 54.110 + * @param name Definition name. 54.111 + * @return true if the definition was found and removed. 54.112 + */ 54.113 + public boolean unset(String name) { 54.114 + if (definitions.remove(name) != null) 54.115 + return true; 54.116 + 54.117 + if (superContext != null) 54.118 + return superContext.unset(name); 54.119 + 54.120 + return false; 54.121 + } 54.122 + 54.123 + /** 54.124 + * Returns base directory which should be used to resolve 54.125 + * relative path names in template. 54.126 + */ 54.127 + public File getBaseDirectory() { 54.128 + if (baseDir == null && superContext != null) 54.129 + return superContext.getBaseDirectory(); 54.130 + 54.131 + return baseDir; 54.132 + } 54.133 +}
55.1 --- a/src/kryshen/tema/Function.java Thu Dec 14 23:22:05 2006 +0300 55.2 +++ b/src/kryshen/tema/Function.java Tue Feb 19 20:32:17 2008 +0300 55.3 @@ -1,33 +1,34 @@ 55.4 /* 55.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 55.6 + * Copyright 2006-2008 Mikhail Kryshen 55.7 * 55.8 - * This program is free software; you can redistribute it and/or modify 55.9 - * it under the terms of the GNU General Public License as published by 55.10 - * the Free Software Foundation; either version 2 of the License, or 55.11 - * (at your option) any later version. 55.12 + * This file is part of Tema. 55.13 * 55.14 - * This program is distributed in the hope that it will be useful, 55.15 + * Tema is free software: you can redistribute it and/or modify it 55.16 + * under the terms of the GNU Lesser General Public License as 55.17 + * published by the Free Software Foundation, either version 3 of the 55.18 + * License, or (at your option) any later version. 55.19 + * 55.20 + * Tema is distributed in the hope that it will be useful, 55.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 55.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 55.23 - * GNU General Public License for more details. 55.24 + * GNU Lesser General Public License for more details. 55.25 * 55.26 - * You should have received a copy of the GNU General Public License 55.27 - * along with this program; if not, write to the Free Software 55.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 55.29 + * You should have received a copy of the 55.30 + * GNU Lesser General Public License along with Tema. 55.31 + * If not, see <http://www.gnu.org/licenses/>. 55.32 * 55.33 - * $Id: Function.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 55.34 + * $Id: Function.java,v 1.13 2008/02/19 16:21:00 mikhail Exp $ 55.35 */ 55.36 55.37 package kryshen.tema; 55.38 55.39 -import java.io.*; 55.40 -import java.util.*; 55.41 -import java.sql.ResultSet; 55.42 +import java.io.IOException; 55.43 +import java.io.Writer; 55.44 55.45 /** 55.46 - * Abstact class for TEMA functions. 55.47 + * Abstact class for Tema functions. 55.48 * 55.49 - * @author Mikhail A. Kryshen 55.50 + * @author Mikhail Kryshen 55.51 */ 55.52 public abstract class Function { 55.53
56.1 --- a/src/kryshen/tema/FunctionDataParser.java Thu Dec 14 23:22:05 2006 +0300 56.2 +++ b/src/kryshen/tema/FunctionDataParser.java Tue Feb 19 20:32:17 2008 +0300 56.3 @@ -1,140 +1,204 @@ 56.4 /* 56.5 - * Copyright (C) 2006 Mikhail A. Kryshen 56.6 + * Copyright 2006-2008 Mikhail Kryshen 56.7 * 56.8 - * This program is free software; you can redistribute it and/or modify 56.9 - * it under the terms of the GNU General Public License as published by 56.10 - * the Free Software Foundation; either version 2 of the License, or 56.11 - * (at your option) any later version. 56.12 + * This file is part of Tema. 56.13 * 56.14 - * This program is distributed in the hope that it will be useful, 56.15 + * Tema is free software: you can redistribute it and/or modify it 56.16 + * under the terms of the GNU Lesser General Public License as 56.17 + * published by the Free Software Foundation, either version 3 of the 56.18 + * License, or (at your option) any later version. 56.19 + * 56.20 + * Tema is distributed in the hope that it will be useful, 56.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 56.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 56.23 - * GNU General Public License for more details. 56.24 + * GNU Lesser General Public License for more details. 56.25 * 56.26 - * You should have received a copy of the GNU General Public License 56.27 - * along with this program; if not, write to the Free Software 56.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 56.29 + * You should have received a copy of the 56.30 + * GNU Lesser General Public License along with Tema. 56.31 + * If not, see <http://www.gnu.org/licenses/>. 56.32 * 56.33 - * $Id: FunctionDataParser.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 56.34 + * $Id: FunctionDataParser.java,v 1.27 2008/02/16 17:56:34 mikhail Exp $ 56.35 */ 56.36 56.37 package kryshen.tema; 56.38 56.39 -import java.io.*; 56.40 -import java.util.*; 56.41 - 56.42 +import java.io.File; 56.43 +import java.io.IOException; 56.44 +import java.io.StringWriter; 56.45 +import java.io.Writer; 56.46 +import java.util.ArrayList; 56.47 +import java.util.List; 56.48 import static kryshen.tema.TemplateParser.Result; 56.49 -import static kryshen.tema.TemplateParser.FunctionData; 56.50 +import static kryshen.tema.TemplateParser.DataFormat; 56.51 +import kryshen.tema.TemplateParser.DataFormat; 56.52 import static kryshen.tema.TemplateParser.Terminator; 56.53 +import kryshen.tema.io.CopyWriter; 56.54 +import kryshen.tema.io.NullWriter; 56.55 +import kryshen.tema.io.TemplateReader; 56.56 56.57 /** 56.58 * Parser for a function data. 56.59 * 56.60 - * @author Mikhail A. Kryshen 56.61 + * @author Mikhail Kryshen 56.62 */ 56.63 public class FunctionDataParser { 56.64 static final char[] ARG_SEPARATORS = TemplateParser.LIST_SEPARATORS; 56.65 - 56.66 + 56.67 private TemplateParser tp; 56.68 - private FunctionData fd; 56.69 + private DataFormat fd; 56.70 private TemplateReader in; 56.71 - 56.72 + 56.73 private boolean available = true; 56.74 - private boolean first = true; 56.75 - 56.76 - FunctionDataParser(TemplateParser tp, FunctionData fd, 56.77 - TemplateReader in) { 56.78 + 56.79 + private int lastReturnCode = 0; 56.80 + 56.81 + FunctionDataParser(TemplateParser tp, DataFormat fd, TemplateReader in) 56.82 + throws IOException, TemplateException { 56.83 this.tp = tp; 56.84 this.fd = fd; 56.85 this.in = in; 56.86 + 56.87 + // Check for empty function data. 56.88 + checkAvailable(); 56.89 } 56.90 - 56.91 - private TemplateParser.Result parseData(Writer out, boolean argument) 56.92 - throws IOException, TemplateException { 56.93 + 56.94 + private void checkAvailable() throws IOException, TemplateException { 56.95 + if (tp.checkCloseBracket(in)) { 56.96 + // Complete parsing the instruction. 56.97 + skipData(); 56.98 + } 56.99 + } 56.100 + 56.101 + private int parseData(Writer out, boolean argument, boolean skip) 56.102 + throws IOException, TemplateException { 56.103 56.104 if (!available) 56.105 throw new TemplateException 56.106 - ("Unexpected end of instruction data.", in); 56.107 - 56.108 + ("Unexpected end of instruction data.", in); 56.109 + 56.110 + DataFormat fd = skip ? this.fd.noCall() : this.fd; 56.111 + 56.112 TemplateParser.Result r; 56.113 - 56.114 - if (fd == FunctionData.RECURSIVE) { 56.115 - r = tp.parse(in, out, true, 56.116 - argument ? ARG_SEPARATORS : null, 56.117 - (argument || !first) ? ARG_SEPARATORS : null); 56.118 - } else if (fd == FunctionData.NONRECURSIVE) { 56.119 - r = tp.parse(in, out, false, 56.120 - argument ? ARG_SEPARATORS : null, 56.121 - (argument || !first) ? ARG_SEPARATORS : null); 56.122 - } else if (fd == FunctionData.SUBFUNCTION && argument) { 56.123 - // Subfunction can pass a list of arguments 56.124 - StringWriter sw = new StringWriter(); 56.125 - tp.parseFunction(in, sw); 56.126 - sw.close(); 56.127 - in = new TemplateReader(new StringReader(sw.toString()), in); 56.128 - fd = FunctionData.NONRECURSIVE; 56.129 - r = parseData(out, true); 56.130 - } else if (fd == FunctionData.SUBFUNCTION) { 56.131 - r = new Result(null, tp.parseFunction(in, out), false); 56.132 + 56.133 +// if (fd.subfunction && argument) { 56.134 +// // Allow subfunction to pass a list of arguments 56.135 +// StringWriter sw = new StringWriter(); 56.136 +// tp.parse(in, sw, fd); 56.137 +// sw.close(); 56.138 +// in = new TemplateReader(new StringReader(sw.toString()), in); 56.139 +// this.fd = DataFormat.VERBATIM; 56.140 +// r = parseData(out, true, false); 56.141 +// } else 56.142 + if (fd.subfunction) { 56.143 + r = tp.parse(in, out, fd); 56.144 + } else if (argument) { 56.145 + // Skip duplicate separators before argument. 56.146 + tp.skip(in, ARG_SEPARATORS); 56.147 + 56.148 + r = tp.parse(in, out, fd, ARG_SEPARATORS); 56.149 + 56.150 + // Skip duplicate separators after argument. 56.151 + if (r.terminator == Terminator.SEPARATOR) { 56.152 + tp.skip(in, ARG_SEPARATORS); 56.153 + checkAvailable(); 56.154 + } 56.155 } else { 56.156 - throw new IllegalArgumentException("Invalid FunctiodData: " + fd); 56.157 + r = tp.parse(in, out, fd, null); 56.158 } 56.159 - 56.160 - if (r.terminator != TemplateParser.Terminator.SEPARATOR) 56.161 + 56.162 + if (r.terminator != Terminator.SEPARATOR) 56.163 available = false; // No more function data available. 56.164 - 56.165 - first = false; 56.166 - return r; 56.167 + 56.168 + lastReturnCode = r.retCode; 56.169 + return r.retCode; 56.170 } 56.171 - 56.172 + 56.173 + /** 56.174 + * Parse function data. 56.175 + */ 56.176 public int parseData(Writer out) throws IOException, TemplateException { 56.177 - return parseData(out, false).retCode; 56.178 + return parseData(out, false, false); 56.179 } 56.180 - 56.181 - public String getData() throws IOException, TemplateException { 56.182 + 56.183 + /** 56.184 + * Skip function data (do not call any functions). 56.185 + */ 56.186 + public void skipData() throws IOException, TemplateException { 56.187 + parseData(NullWriter.INSTANCE, false, true); 56.188 + } 56.189 + 56.190 + /** 56.191 + * Get function data as string. 56.192 + */ 56.193 + public String getData() throws IOException, TemplateException { 56.194 StringWriter sw = new StringWriter(); 56.195 parseData(sw); 56.196 sw.close(); 56.197 return sw.toString(); 56.198 } 56.199 - 56.200 + 56.201 + /** 56.202 + * Parse function data into specified <code>Writer</code>. 56.203 + * Returns copy of the parsed data as string. 56.204 + */ 56.205 + public String getData(Writer out) throws IOException, TemplateException { 56.206 + StringWriter sw = new StringWriter(); 56.207 + parseData(new CopyWriter(sw, out)); 56.208 + sw.close(); 56.209 + return sw.toString(); 56.210 + } 56.211 + 56.212 public int parseNextArg(Writer out) throws IOException, TemplateException { 56.213 - TemplateParser.Result r = parseData(out, true); 56.214 - 56.215 - // Ignore empty arguments. 56.216 - while (r.empty && available) { 56.217 - r = parseData(out, true); 56.218 - } 56.219 - 56.220 - return r.retCode; 56.221 + return parseData(out, true, false); 56.222 } 56.223 - 56.224 - public String getNextArg() throws IOException, TemplateException { 56.225 + 56.226 + public void skipNextArg() throws IOException, TemplateException { 56.227 + parseData(NullWriter.INSTANCE, true, true); 56.228 + } 56.229 + 56.230 + public String getNextArg() throws IOException, TemplateException { 56.231 StringWriter sw = new StringWriter(); 56.232 parseNextArg(sw); 56.233 sw.close(); 56.234 return sw.toString(); 56.235 } 56.236 - 56.237 + 56.238 public List<String> getArgs() throws IOException, TemplateException { 56.239 - List<String> l = new ArrayList<String>(); 56.240 - 56.241 - while (available) { 56.242 - l.add(getNextArg()); 56.243 - } 56.244 - 56.245 - return l; 56.246 + List<String> l = new ArrayList<String>(); 56.247 + 56.248 + while (available) { 56.249 + l.add(getNextArg()); 56.250 + } 56.251 + 56.252 + return l; 56.253 } 56.254 - 56.255 + 56.256 public boolean hasMoreData() { 56.257 return available; 56.258 } 56.259 - 56.260 + 56.261 + public int getLastReturnCode() { 56.262 + return lastReturnCode; 56.263 + } 56.264 + 56.265 public TemplateParser getTemplateParser() { 56.266 return tp; 56.267 } 56.268 56.269 + public Context getContext() { 56.270 + return tp.getContext(); 56.271 + } 56.272 + 56.273 public TemplateReader getTemplateReader() { 56.274 return in; 56.275 } 56.276 + 56.277 + public File createFile(String path) { 56.278 + File file = new File(path); 56.279 + 56.280 + if (file.isAbsolute()) 56.281 + return file; 56.282 + 56.283 + return new File(tp.getContext().getBaseDirectory(), path); 56.284 + } 56.285 }
57.1 --- a/src/kryshen/tema/Functions.java Thu Dec 14 23:22:05 2006 +0300 57.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 57.3 @@ -1,70 +0,0 @@ 57.4 -/* 57.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 57.6 - * 57.7 - * This program is free software; you can redistribute it and/or modify 57.8 - * it under the terms of the GNU General Public License as published by 57.9 - * the Free Software Foundation; either version 2 of the License, or 57.10 - * (at your option) any later version. 57.11 - * 57.12 - * This program is distributed in the hope that it will be useful, 57.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 57.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 57.15 - * GNU General Public License for more details. 57.16 - * 57.17 - * You should have received a copy of the GNU General Public License 57.18 - * along with this program; if not, write to the Free Software 57.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 57.20 - * 57.21 - * $Id: Functions.java,v 1.11 2006/12/14 19:44:31 mikhail Exp $ 57.22 - */ 57.23 - 57.24 -package kryshen.tema; 57.25 - 57.26 -import java.io.*; 57.27 -import java.util.*; 57.28 - 57.29 -import kryshen.tema.functions.*; 57.30 - 57.31 -/** 57.32 - * Standard TEMA functions. 57.33 - * 57.34 - * @author Mikhail A. Kryshen 57.35 - */ 57.36 -public class Functions { 57.37 - // TODO: arithmetics, conditions 57.38 - 57.39 - /** 57.40 - * Register all standard functions. 57.41 - * 57.42 - * @param p TemplateParser to register functions in. 57.43 - */ 57.44 - static void registerAllFunctions(TemplateParser p) { 57.45 - p.registerFunction("!", Standard.NULL_OUTPUT); 57.46 - p.registerFunction("set", Standard.SET); 57.47 - p.registerFunction("load", Standard.LOAD); 57.48 - p.registerFunction("query", Standard.QUERY); 57.49 - p.registerFunction("prepare", Standard.PREPARE); 57.50 - p.registerFunction("replace", Standard.REPLACE); 57.51 - p.registerFunction("xml_escape", Standard.XML_ESCAPE); 57.52 - p.registerFunction("xml_cdata", Standard.XML_CDATA); 57.53 - 57.54 - p.registerFunction("define", Define.DEFINE); 57.55 - 57.56 - p.registerFunction("write", IO.WRITE); 57.57 - p.registerFunction("read", IO.READ); 57.58 - p.registerFunction("include", IO.INCLUDE); 57.59 - p.registerFunction("copy", IO.COPY); 57.60 - 57.61 - p.registerFunction("false", Logics.FALSE); 57.62 - p.registerFunction("true", Logics.TRUE); 57.63 - p.registerFunction("optional", Logics.OPTIONAL); 57.64 - 57.65 - p.registerFunction("image", ImageConverter.IMAGE); 57.66 - 57.67 - /* 57.68 - Other functuons: 57.69 - db - defined in Tema.query(). 57.70 - nextarg, data - defined in Define.invoke(). 57.71 - */ 57.72 - } 57.73 -}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/src/kryshen/tema/GlobalContext.java Tue Feb 19 20:32:17 2008 +0300 58.3 @@ -0,0 +1,95 @@ 58.4 +/* 58.5 + * Copyright 2006-2008 Mikhail Kryshen 58.6 + * 58.7 + * This file is part of Tema. 58.8 + * 58.9 + * Tema is free software: you can redistribute it and/or modify it 58.10 + * under the terms of the GNU Lesser General Public License as 58.11 + * published by the Free Software Foundation, either version 3 of the 58.12 + * License, or (at your option) any later version. 58.13 + * 58.14 + * Tema is distributed in the hope that it will be useful, 58.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 58.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 58.17 + * GNU Lesser General Public License for more details. 58.18 + * 58.19 + * You should have received a copy of the 58.20 + * GNU Lesser General Public License along with Tema. 58.21 + * If not, see <http://www.gnu.org/licenses/>. 58.22 + * 58.23 + * $Id: GlobalContext.java,v 1.16 2008/02/19 16:21:00 mikhail Exp $ 58.24 + */ 58.25 + 58.26 +package kryshen.tema; 58.27 + 58.28 +import java.io.File; 58.29 +import kryshen.tema.functions.Database; 58.30 +import kryshen.tema.functions.Define; 58.31 +import kryshen.tema.functions.IO; 58.32 +import kryshen.tema.functions.ImageConverter; 58.33 +import kryshen.tema.functions.Control; 58.34 +import kryshen.tema.functions.Standard; 58.35 +import kryshen.tema.functions.Strings; 58.36 + 58.37 +/** 58.38 + * Context to hold exported variables and standard Tema definitions. 58.39 + * 58.40 + * @author Mikhail Kryshen 58.41 + */ 58.42 +class GlobalContext extends Context { 58.43 + 58.44 + GlobalContext() { 58.45 + super(new File(System.getProperty("user.dir"))); 58.46 + 58.47 + // Register all standard functions. 58.48 + // TODO: arithmetics 58.49 + 58.50 + set("tema", Standard.TEMA); 58.51 + set("echo", Standard.ECHO); 58.52 + set("", Standard.ECHO); 58.53 + set("!", Standard.SKIP); 58.54 + set("silent", Standard.SILENT); 58.55 + set("set", Standard.SET); 58.56 + set("unset", Standard.UNSET); 58.57 + set("export", Standard.EXPORT); 58.58 + set("assign", Standard.ASSIGN); 58.59 + set("invoke", Standard.INVOKE); 58.60 + set("load", Standard.LOAD); 58.61 + 58.62 + set("to_upper", Strings.TO_UPPER); 58.63 + set("to_lower", Strings.TO_LOWER); 58.64 + set("substring", Strings.SUBSTRING); 58.65 + set("equal", Strings.EQUAL); 58.66 + set("xml_escape", Strings.XML_ESCAPE); 58.67 + set("xml_cdata", Strings.XML_CDATA); 58.68 + set("char", Strings.CHAR); 58.69 + set("replace", Strings.REPLACE); 58.70 + set("regex_match", Strings.REGEX_MATCH); 58.71 + set("regex_replace_first", Strings.REGEX_REPLACE_FIRST); 58.72 + set("regex_replace_all", Strings.REGEX_REPLACE_ALL); 58.73 + 58.74 + set("define", Define.DEFINE); 58.75 + 58.76 + set("write", IO.WRITE); 58.77 + set("read", IO.READ); 58.78 + set("include", IO.INCLUDE); 58.79 + set("copy", IO.COPY); 58.80 + set("file", IO.FILE); 58.81 + 58.82 + set("false", Control.FALSE); 58.83 + set("true", Control.TRUE); 58.84 + set("not", Control.NOT); 58.85 + set("optional", Control.OPTIONAL); 58.86 + set("if", Control.IF); 58.87 + set("if_else", Control.IF_ELSE); 58.88 + set("while", Control.WHILE); 58.89 + 58.90 + set("db_connect", Database.CONNECT); 58.91 + set("db_prepare", Database.PREPARE); 58.92 + set("db_query", Database.QUERY); 58.93 + 58.94 + set("convert_image", ImageConverter.CONVERT_IMAGE); 58.95 + 58.96 + // Other functions are defined in classes Database and Define. 58.97 + } 58.98 +}
59.1 --- a/src/kryshen/tema/Tema.java Thu Dec 14 23:22:05 2006 +0300 59.2 +++ b/src/kryshen/tema/Tema.java Tue Feb 19 20:32:17 2008 +0300 59.3 @@ -1,364 +1,248 @@ 59.4 /* 59.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 59.6 + * Copyright 2006-2008 Mikhail Kryshen 59.7 * 59.8 - * This program is free software; you can redistribute it and/or modify 59.9 - * it under the terms of the GNU General Public License as published by 59.10 - * the Free Software Foundation; either version 2 of the License, or 59.11 - * (at your option) any later version. 59.12 + * This file is part of Tema. 59.13 * 59.14 - * This program is distributed in the hope that it will be useful, 59.15 + * Tema is free software: you can redistribute it and/or modify it 59.16 + * under the terms of the GNU Lesser General Public License as 59.17 + * published by the Free Software Foundation, either version 3 of the 59.18 + * License, or (at your option) any later version. 59.19 + * 59.20 + * Tema is distributed in the hope that it will be useful, 59.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 59.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 59.23 - * GNU General Public License for more details. 59.24 + * GNU Lesser General Public License for more details. 59.25 * 59.26 - * You should have received a copy of the GNU General Public License 59.27 - * along with this program; if not, write to the Free Software 59.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 59.29 + * You should have received a copy of the 59.30 + * GNU Lesser General Public License along with Tema. 59.31 + * If not, see <http://www.gnu.org/licenses/>. 59.32 * 59.33 - * $Id: Tema.java,v 1.17 2006/12/14 19:44:31 mikhail Exp $ 59.34 + * $Id: Tema.java,v 1.42 2008/02/19 17:14:34 mikhail Exp $ 59.35 */ 59.36 59.37 package kryshen.tema; 59.38 59.39 -import java.sql.Driver; 59.40 -import java.sql.DriverManager; 59.41 -import java.sql.Connection; 59.42 -import java.sql.Statement; 59.43 -import java.sql.PreparedStatement; 59.44 -import java.sql.ResultSet; 59.45 -import java.sql.ResultSetMetaData; 59.46 +import java.io.BufferedReader; 59.47 +import java.io.BufferedWriter; 59.48 +import java.io.File; 59.49 +import java.io.FileInputStream; 59.50 +import java.io.FileOutputStream; 59.51 +import java.io.IOException; 59.52 +import java.io.InputStream; 59.53 +import java.io.InputStreamReader; 59.54 +import java.io.OutputStream; 59.55 +import java.io.OutputStreamWriter; 59.56 +import java.io.PrintStream; 59.57 +import java.io.Writer; 59.58 +import java.nio.charset.Charset; 59.59 import java.sql.SQLException; 59.60 - 59.61 -import java.util.Map; 59.62 -import java.util.HashMap; 59.63 -import java.util.Properties; 59.64 -import java.util.List; 59.65 -import java.util.Collections; 59.66 - 59.67 -import java.io.*; 59.68 - 59.69 import kryshen.tema.demo.DemoFrame; 59.70 +import kryshen.tema.io.TemplateReader; 59.71 +import org.apache.commons.cli.CommandLine; 59.72 +import org.apache.commons.cli.CommandLineParser; 59.73 +import org.apache.commons.cli.GnuParser; 59.74 +import org.apache.commons.cli.HelpFormatter; 59.75 +import org.apache.commons.cli.Options; 59.76 +import org.apache.commons.cli.ParseException; 59.77 59.78 /** 59.79 * Tema main class. 59.80 * 59.81 - * @author Mikhail A. Kryshen 59.82 + * @author Mikhail Kryshen 59.83 */ 59.84 public class Tema { 59.85 - public static final String TITLE = "TEMA"; 59.86 - public static final String VERSION = "0.1"; 59.87 - public static final String AUTHOR = "Mikhail A. Kryshen"; 59.88 - 59.89 - private static final String CONFIG_FILE = "tema.properties"; 59.90 - private static final String ENV_PREFIX = "kryshen.tema."; 59.91 - 59.92 - private static Properties config = new Properties(); 59.93 - private static Connection connection = null; 59.94 - 59.95 - private static String inputEncoding; 59.96 - private static String outputEncoding; 59.97 - 59.98 - private static Map<File, String> fileCache = null; 59.99 - 59.100 - public static void main(String[] args) 59.101 - throws IOException, SQLException, 59.102 - ClassNotFoundException, InstantiationException, 59.103 - IllegalAccessException { 59.104 - 59.105 + public static final String TITLE = "Tema"; 59.106 + public static final String VERSION = "0.3"; 59.107 + public static final String AUTHOR = "Mikhail Kryshen"; 59.108 + public static final String COPYRIGHT = 59.109 + "Copyright 2008 Mikhail Kryshen <mikhail@kryshen.pp.ru>"; 59.110 + public static final String LICENSE = 59.111 + "This is free software. " + 59.112 + "You may redistribute copies of it under the terms of" + 59.113 + System.getProperty("line.separator") + 59.114 + "the GNU Lesser General Public License version 3 or later" + 59.115 + System.getProperty("line.separator") + 59.116 + "<http://gnu.org/licenses/lgpl.html>."; 59.117 + 59.118 + private static final String DEFAULT_CHARSET = 59.119 + Charset.defaultCharset().name(); 59.120 + 59.121 + private static String inputEncoding = DEFAULT_CHARSET; 59.122 + private static String outputEncoding = DEFAULT_CHARSET; 59.123 + 59.124 + public static void main(String[] args) 59.125 + throws IOException, SQLException, 59.126 + ClassNotFoundException, InstantiationException, 59.127 + IllegalAccessException { 59.128 + 59.129 boolean demo = false; 59.130 boolean version = false; 59.131 boolean help = false; 59.132 - 59.133 - // Parse arguments. 59.134 - for (int i = 0; i < args.length; i++) { 59.135 - if ("-demo".equals(args[i]) || 59.136 - "-d".equals(args[i])) { 59.137 - demo = true; 59.138 - } else if ("-version".equals(args[i]) || 59.139 - "-v".equals(args[i])) { 59.140 - version = true; 59.141 - } else if ("-help".equals(args[i]) || 59.142 - "-h".equals(args[i]) || 59.143 - "-usage".equals(args[i]) || 59.144 - "-u".equals(args[i])) { 59.145 - help = true; 59.146 - } else { 59.147 - System.err.println("Invalid option: " + args[i]); 59.148 - return; 59.149 - } 59.150 + 59.151 + Options options = new Options(); 59.152 + 59.153 + options.addOption(null, "demo", false, "demo mode"); 59.154 + options.addOption("v", "version", false, 59.155 + "print the version information and exit"); 59.156 + options.addOption("h", "help", false, 59.157 + "print this help message"); 59.158 + options.addOption("o", "output", true, 59.159 + "output file"); 59.160 + options.addOption(null, "log", true, 59.161 + "log all error messages to file"); 59.162 + options.addOption(null, "input-encoding", true, 59.163 + "input encoding"); 59.164 + options.addOption(null, "output-encoding", true, 59.165 + "output encoding"); 59.166 + 59.167 + CommandLineParser parser = new GnuParser(); 59.168 + CommandLine line; 59.169 + 59.170 + try { 59.171 + line = parser.parse(options, args ); 59.172 + } catch (ParseException ex) { 59.173 + System.err.println(ex.getMessage()); 59.174 + System.exit(1); 59.175 + return; // to avoid "not initialized" compile-time errors. 59.176 } 59.177 - 59.178 - if (version || help) { 59.179 - System.err.println(TITLE + " " + VERSION + " by " + AUTHOR); 59.180 - 59.181 - if (help) { 59.182 - PrintStream err = System.err; 59.183 - 59.184 - err.println(); 59.185 - err.println("Usage: tema [OPTIONS]"); 59.186 - err.println(); 59.187 - err.println("Options:"); 59.188 - err.println(" -d[emo] Demo mode"); 59.189 - err.println(" -v[ersion] Print version"); 59.190 - err.println(" -h[help] -u[sage] Print this help message"); 59.191 - } 59.192 + 59.193 + if (line.hasOption("version")) { 59.194 + System.err.println(TITLE + " " + VERSION); 59.195 + System.err.println(COPYRIGHT); 59.196 + System.err.println(LICENSE); 59.197 return; 59.198 } 59.199 - 59.200 - if (demo) { 59.201 - // Run in demo mode. 59.202 + 59.203 + if (line.hasOption("help")) { 59.204 + HelpFormatter formatter = new HelpFormatter(); 59.205 + formatter.printHelp("tema [options] [files]", options); 59.206 + return; 59.207 + } 59.208 + 59.209 + if (line.hasOption("input-encoding")) { 59.210 + inputEncoding = line.getOptionValue("input-encoding"); 59.211 + } 59.212 + 59.213 + if (line.hasOption("output-encoding")) { 59.214 + outputEncoding = line.getOptionValue("output-encoding"); 59.215 + } 59.216 + 59.217 + if (line.hasOption("log")) { 59.218 + System.setErr(new PrintStream 59.219 + (new FileOutputStream(line.getOptionValue("log")))); 59.220 + } 59.221 + 59.222 + if (line.hasOption("demo")) { 59.223 + // Open the demo console. 59.224 DemoFrame df = new DemoFrame(); 59.225 df.pack(); 59.226 df.setVisible(true); 59.227 return; 59.228 } 59.229 - 59.230 - process(); 59.231 + 59.232 + Writer out; 59.233 + 59.234 + if (line.hasOption("output")) { 59.235 + File outfile = new File(line.getOptionValue("output")); 59.236 + out = createFileWriter(outfile); 59.237 + } else { 59.238 + out = new OutputStreamWriter(System.out, outputEncoding) { 59.239 + @Override 59.240 + public void write(int c) throws IOException { 59.241 + super.write(c); 59.242 + if (c == '\r' || c == '\n') 59.243 + flush(); 59.244 + } 59.245 + 59.246 + @Override 59.247 + public void write(char cbuf[], int off, int len) 59.248 + throws IOException { 59.249 + super.write(cbuf, off, len); 59.250 + flush(); 59.251 + } 59.252 + 59.253 + @Override 59.254 + public void write(String str, int off, int len) 59.255 + throws IOException { 59.256 + super.write(str, off, len); 59.257 + flush(); 59.258 + } 59.259 + }; 59.260 + } 59.261 + 59.262 + String[] files = line.getArgs(); 59.263 + 59.264 + if (files.length == 0) { 59.265 + TemplateReader in = createTemplateReader(System.in); 59.266 + if (!process(in, out)) { 59.267 + System.exit(1); 59.268 + } 59.269 + } 59.270 + 59.271 + for (String file: files) { 59.272 + TemplateReader in = createTemplateReader(new File(file)); 59.273 + if (!process(in, out)) { 59.274 + System.exit(1); 59.275 + } 59.276 + } 59.277 + 59.278 + out.close(); 59.279 } 59.280 - 59.281 - /** 59.282 - * Standard execution. 59.283 - */ 59.284 - private static void process() 59.285 - throws IOException, SQLException, 59.286 - ClassNotFoundException, InstantiationException, 59.287 - IllegalAccessException { 59.288 - 59.289 - InputStream configIn = new FileInputStream(CONFIG_FILE); 59.290 - config.load(configIn); 59.291 - configIn.close(); 59.292 + 59.293 + private static boolean process(TemplateReader in, Writer out) 59.294 + throws IOException { 59.295 59.296 - configure(); 59.297 - 59.298 - String main = getProperty("main_template"); 59.299 - String output = getProperty("output"); 59.300 - 59.301 - Writer out; 59.302 - 59.303 - if ("stderr".equals(output)) 59.304 - out = new OutputStreamWriter(System.err); 59.305 - else 59.306 - out = new OutputStreamWriter(System.out); 59.307 - 59.308 - TemplateReader in = createTemplateReader(new File(main)); 59.309 TemplateParser p = new TemplateParser(); 59.310 - TemplateException te = null; 59.311 - 59.312 - try { 59.313 - p.parse(in, out); 59.314 + TemplateException ex = null; 59.315 + 59.316 + p.getContext().set("input_encoding", inputEncoding); 59.317 + p.getContext().set("output_encoding", outputEncoding); 59.318 + 59.319 + try { 59.320 + p.parse(in, out); 59.321 } catch (TemplateException e) { 59.322 - te = e; 59.323 - } finally { 59.324 - in.close(); 59.325 - out.flush(); 59.326 - } 59.327 - 59.328 - if (te != null) { 59.329 - System.err.println(te.getMessage()); 59.330 - if (te.getCause() != null) { 59.331 - System.err.println("Caused by " + te.getCause()); 59.332 + ex = e; 59.333 + } finally { 59.334 + in.close(); 59.335 + } 59.336 + 59.337 + if (ex != null) { 59.338 + System.err.println(ex.getMessage()); 59.339 + if (ex.getCause() != null) { 59.340 + System.err.println("Caused by " + ex.getCause()); 59.341 } 59.342 - } else { 59.343 - System.err.println("Done"); 59.344 + return false; 59.345 } 59.346 + 59.347 + return true; 59.348 } 59.349 - 59.350 - private static void configure() 59.351 - throws IOException, SQLException, IllegalAccessException, 59.352 - ClassNotFoundException, InstantiationException { 59.353 - 59.354 - String logFile = getProperty("log"); 59.355 - if (logFile != null && logFile.length() > 0) 59.356 - System.setErr(new PrintStream(new FileOutputStream(logFile))); 59.357 - 59.358 - if (Boolean.parseBoolean(getProperty("cache_read")) == true) 59.359 - fileCache = new HashMap<File, String>(); 59.360 - 59.361 - inputEncoding = getProperty("input_encoding", "iso-8859-1"); 59.362 - outputEncoding = getProperty("output_encoding", "iso-8859-1"); 59.363 - 59.364 - String resourceProperty = getProperty("resource"); 59.365 - 59.366 - if (resourceProperty != null) { 59.367 - String driverProperty = getProperty("driver"); 59.368 - if (driverProperty != null) { 59.369 - // Register driver. 59.370 - Driver d = (Driver)Class.forName(driverProperty).newInstance(); 59.371 - } 59.372 - 59.373 - // Open connection. 59.374 - connection = DriverManager.getConnection(resourceProperty); 59.375 - } 59.376 + 59.377 + public static BufferedWriter createFileWriter(File file) 59.378 + throws IOException { 59.379 + 59.380 + OutputStream os = new FileOutputStream(file); 59.381 + return new BufferedWriter 59.382 + (new OutputStreamWriter(os, Tema.outputEncoding)); 59.383 } 59.384 - 59.385 59.386 - 59.387 - /** 59.388 - * Get configuration property. 59.389 - */ 59.390 - public static String getProperty(String name) { 59.391 - String value = System.getProperty(ENV_PREFIX + name); 59.392 - if (value != null) return value; 59.393 - return config.getProperty(name); 59.394 + public static BufferedReader createFileReader(File file) 59.395 + throws IOException { 59.396 + 59.397 + InputStream is = new FileInputStream(file); 59.398 + return new BufferedReader 59.399 + (new InputStreamReader(is, Tema.inputEncoding)); 59.400 } 59.401 - 59.402 - /** 59.403 - * Get configuration property. 59.404 - */ 59.405 - public static String getProperty(String name, String fallback) { 59.406 - String value = getProperty(name); 59.407 - if (value != null) return value; 59.408 - return fallback; 59.409 + 59.410 + public static TemplateReader createTemplateReader(File file) 59.411 + throws IOException { 59.412 + 59.413 + return new TemplateReader(createFileReader(file), file.getPath()); 59.414 } 59.415 - 59.416 - /** 59.417 - * Process database query. 59.418 - * 59.419 - * @param templateReader reader for the template 59.420 - * to fill with data. 59.421 - * @param ps query statement to execute. 59.422 - * @param args list of query parameters. 59.423 - * @param superParser invoking object. 59.424 - * @param out Writer to output processed data. 59.425 - * 59.426 - * @return number of processed rows in query result. 59.427 - */ 59.428 - public static int query(TemplateReader templateReader, 59.429 - PreparedStatement ps, 59.430 - List<String> args, 59.431 - TemplateParser superParser, 59.432 - Writer out) 59.433 - throws IOException, SQLException, TemplateException { 59.434 - 59.435 - int i = 1; 59.436 - 59.437 - for (String arg : args) { 59.438 - ps.setString(i++, arg); 59.439 - } 59.440 - 59.441 - ResultSet r = ps.executeQuery(); 59.442 - ResultSetMetaData rm = r.getMetaData(); 59.443 - int columnCount = rm.getColumnCount(); 59.444 - 59.445 - String[] names = new String[columnCount]; 59.446 - 59.447 - for (int j = 0; j < columnCount; j++) { 59.448 - names[j] = rm.getColumnName(j + 1); 59.449 - } 59.450 - 59.451 - final TemplateParser p = new TemplateParser(superParser); 59.452 - final HashMap<String, Object> fields = new HashMap<String, Object>(); 59.453 - 59.454 - p.registerFunction("db", new Function() { 59.455 - public int invoke(FunctionDataParser fdp, 59.456 - final Writer out) 59.457 - throws IOException, TemplateException { 59.458 - 59.459 - String name = fdp.getData(); 59.460 - Object value = fields.get(name); 59.461 - 59.462 - return p.parseValue(value, out); 59.463 - } 59.464 - }); 59.465 - 59.466 - for (i = 1; r.next(); i++) { 59.467 - 59.468 - for (int j = 0; j < columnCount; j++) { 59.469 - Object value = r.getObject(j + 1); 59.470 - if (r.wasNull()) value = null; 59.471 - 59.472 - fields.put(names[j], value); 59.473 - } 59.474 - 59.475 - p.setValue("number", i); 59.476 - p.parse(templateReader, out); 59.477 - templateReader.reset(); 59.478 - fields.clear(); 59.479 - } 59.480 - 59.481 - r.close(); 59.482 - ps.clearParameters(); 59.483 - return i - 1; 59.484 - } 59.485 - 59.486 - public static BufferedWriter createFileWriter(String filename) 59.487 - throws IOException { 59.488 - 59.489 - OutputStream os = new FileOutputStream(filename); 59.490 - return new BufferedWriter 59.491 - (new OutputStreamWriter(os, Tema.outputEncoding)); 59.492 - } 59.493 - 59.494 - public static BufferedReader createFileReader(File file) 59.495 - throws IOException { 59.496 - 59.497 - InputStream is = new FileInputStream(file); 59.498 - return new BufferedReader 59.499 - (new InputStreamReader(is, Tema.inputEncoding)); 59.500 - } 59.501 - 59.502 - public static TemplateReader createTemplateReader(File file) 59.503 - throws IOException { 59.504 - 59.505 - return new TemplateReader 59.506 - (new LineNumberReader(createCachedFileReader(file)), file.getPath()); 59.507 - } 59.508 - 59.509 - /** 59.510 - * Creates StringReader for a cached file if caching is enabled or 59.511 - * a BufferedReader. 59.512 - * 59.513 - * @param file File to read. 59.514 - * @return Reader for a file. 59.515 - */ 59.516 - public static Reader createCachedFileReader(File file) 59.517 - throws IOException { 59.518 + 59.519 + public static TemplateReader createTemplateReader(InputStream in) 59.520 + throws IOException { 59.521 59.522 - if (fileCache != null) return new StringReader(readFile(file)); 59.523 - else return createFileReader(file); 59.524 - } 59.525 - 59.526 - /** 59.527 - * Read text file. 59.528 - * 59.529 - * @return file contents. 59.530 - */ 59.531 - public static String readFile(File file) throws IOException { 59.532 - String data; 59.533 - 59.534 - if (fileCache != null) { 59.535 - data = fileCache.get(file); 59.536 - if (data != null) return data; 59.537 - } 59.538 - 59.539 - Reader r = new BufferedReader(createFileReader(file)); 59.540 - 59.541 - // FIXME: possible overflow (long -> int). 59.542 - StringBuffer sb = new StringBuffer((int)file.length()); 59.543 - 59.544 - try { 59.545 - for (int c = r.read(); c >= 0; c = r.read()) { 59.546 - sb.append((char)c); 59.547 - } 59.548 - } finally { 59.549 - r.close(); 59.550 - } 59.551 - 59.552 - data = sb.toString(); 59.553 - 59.554 - if (fileCache != null) { 59.555 - fileCache.put(file, data); 59.556 - } 59.557 - 59.558 - return data; 59.559 - } 59.560 - 59.561 - /** 59.562 - * Get database connection. 59.563 - * 59.564 - * @return database connection if any was configured. 59.565 - */ 59.566 - public static Connection getDbConnection() { 59.567 - return connection; 59.568 + return new TemplateReader( 59.569 + new InputStreamReader(in, Tema.inputEncoding)); 59.570 } 59.571 }
60.1 --- a/src/kryshen/tema/TemplateException.java Thu Dec 14 23:22:05 2006 +0300 60.2 +++ b/src/kryshen/tema/TemplateException.java Tue Feb 19 20:32:17 2008 +0300 60.3 @@ -1,29 +1,33 @@ 60.4 /* 60.5 - * Copyright (C) 2006 Mikhail A. Kryshen 60.6 + * Copyright 2006-2008 Mikhail Kryshen 60.7 * 60.8 - * This program is free software; you can redistribute it and/or modify 60.9 - * it under the terms of the GNU General Public License as published by 60.10 - * the Free Software Foundation; either version 2 of the License, or 60.11 - * (at your option) any later version. 60.12 + * This file is part of Tema. 60.13 * 60.14 - * This program is distributed in the hope that it will be useful, 60.15 + * Tema is free software: you can redistribute it and/or modify it 60.16 + * under the terms of the GNU Lesser General Public License as 60.17 + * published by the Free Software Foundation, either version 3 of the 60.18 + * License, or (at your option) any later version. 60.19 + * 60.20 + * Tema is distributed in the hope that it will be useful, 60.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 60.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 60.23 - * GNU General Public License for more details. 60.24 + * GNU Lesser General Public License for more details. 60.25 * 60.26 - * You should have received a copy of the GNU General Public License 60.27 - * along with this program; if not, write to the Free Software 60.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 60.29 + * You should have received a copy of the 60.30 + * GNU Lesser General Public License along with Tema. 60.31 + * If not, see <http://www.gnu.org/licenses/>. 60.32 * 60.33 - * $Id: TemplateException.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 60.34 + * $Id: TemplateException.java,v 1.12 2008/02/16 17:56:34 mikhail Exp $ 60.35 */ 60.36 60.37 package kryshen.tema; 60.38 60.39 +import kryshen.tema.io.TemplateReader; 60.40 + 60.41 /** 60.42 * Signals that template parsing fails. 60.43 * 60.44 - * @author Mikhail A. Kryshen 60.45 + * @author Mikhail Kryshen 60.46 */ 60.47 public class TemplateException extends Exception { 60.48 //private String source;
61.1 --- a/src/kryshen/tema/TemplateParser.java Thu Dec 14 23:22:05 2006 +0300 61.2 +++ b/src/kryshen/tema/TemplateParser.java Tue Feb 19 20:32:17 2008 +0300 61.3 @@ -1,296 +1,445 @@ 61.4 /* 61.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 61.6 + * Copyright 2006-2008 Mikhail Kryshen 61.7 * 61.8 - * This program is free software; you can redistribute it and/or modify 61.9 - * it under the terms of the GNU General Public License as published by 61.10 - * the Free Software Foundation; either version 2 of the License, or 61.11 - * (at your option) any later version. 61.12 + * This file is part of Tema. 61.13 * 61.14 - * This program is distributed in the hope that it will be useful, 61.15 + * Tema is free software: you can redistribute it and/or modify it 61.16 + * under the terms of the GNU Lesser General Public License as 61.17 + * published by the Free Software Foundation, either version 3 of the 61.18 + * License, or (at your option) any later version. 61.19 + * 61.20 + * Tema is distributed in the hope that it will be useful, 61.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 61.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 61.23 - * GNU General Public License for more details. 61.24 + * GNU Lesser General Public License for more details. 61.25 * 61.26 - * You should have received a copy of the GNU General Public License 61.27 - * along with this program; if not, write to the Free Software 61.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 61.29 + * You should have received a copy of the 61.30 + * GNU Lesser General Public License along with Tema. 61.31 + * If not, see <http://www.gnu.org/licenses/>. 61.32 * 61.33 - * $Id: TemplateParser.java,v 1.11 2006/12/14 19:44:31 mikhail Exp $ 61.34 + * $Id: TemplateParser.java,v 1.58 2008/02/19 00:20:48 mikhail Exp $ 61.35 */ 61.36 61.37 package kryshen.tema; 61.38 61.39 -import java.io.*; 61.40 -import java.util.*; 61.41 +import java.io.File; 61.42 +import java.io.IOException; 61.43 +import java.io.StringReader; 61.44 +import java.io.Writer; 61.45 +import kryshen.tema.io.TemplateReader; 61.46 61.47 /** 61.48 - * Parser for TEMA templates. 61.49 + * Parser for Tema templates. 61.50 * 61.51 - * @author Mikhail A. Kryshen 61.52 + * @author Mikhail Kryshen 61.53 */ 61.54 public class TemplateParser { 61.55 - // TODO: report non-critical errors and warnings. 61.56 - 61.57 - static final String SUPER_PREFIX = "super."; 61.58 - 61.59 /* Brackets. */ 61.60 - static final char[] BR_LEFT = {'<', '['}; 61.61 - static final char[] BR_RIGHT = {'>', ']'}; 61.62 - 61.63 - static final char BR_IN = '%'; 61.64 + public static final String[] BRACKET_OPEN = {"<%", "[%"}; 61.65 + public static final String[] BRACKET_CLOSE = {"%>", "%]"}; 61.66 + 61.67 + public static final String ESCAPE_NEWLINE = "\\"; 61.68 + public static final String ESCAPE_WHITESPACE = "\\\\"; 61.69 61.70 /* Separators. */ 61.71 - static final char[] REC_DATA_SEPARATORS = {':'}; 61.72 - static final char[] NONREC_DATA_SEPARATORS = {'\\', '`'}; 61.73 - static final char[] LIST_SEPARATORS = {' ', '\t', '\r', '\n'}; 61.74 - 61.75 + public static final char[] REC_DATA_SEPARATORS = {':'}; 61.76 + public static final char[] VERBATIM_DATA_SEPARATORS = {'\\', '`'}; 61.77 + public static final char[] NOCALL_DATA_SEPARATORS = {'#'}; 61.78 + public static final char[] LIST_SEPARATORS = {' ', '\t', '\r', '\n'}; 61.79 + 61.80 /** 61.81 - * Methods of parsing function arguments and data. 61.82 + * Specifies how to parse function arguments and data. 61.83 */ 61.84 - static enum FunctionData { 61.85 - SUBFUNCTION, RECURSIVE, NONRECURSIVE; 61.86 + static enum DataFormat { 61.87 + RECURSIVE(true, false), 61.88 + VERBATIM(false, false), 61.89 + NOCALL(false, false), 61.90 + SUBFUNCTION(true, true), 61.91 + SUBFUNCTION_NOCALL(false, true); 61.92 + 61.93 + public final boolean call; 61.94 + public final boolean subfunction; 61.95 + 61.96 + DataFormat(boolean call, boolean subfunction) { 61.97 + this.call = call; 61.98 + this.subfunction = subfunction; 61.99 + } 61.100 + 61.101 + /** 61.102 + * Returns no-call equivalent to this format. 61.103 + */ 61.104 + public DataFormat noCall() { 61.105 + if (this == RECURSIVE) 61.106 + return NOCALL; 61.107 + 61.108 + if (this == SUBFUNCTION) 61.109 + return SUBFUNCTION_NOCALL; 61.110 + 61.111 + return this; 61.112 + } 61.113 }; 61.114 - 61.115 + 61.116 + /** 61.117 + * Specifies how the template instruction was terminated. 61.118 + */ 61.119 static enum Terminator { 61.120 - EOF, BRACKET, SEPARATOR; 61.121 + EOF, BRACKET, SEPARATOR; 61.122 }; 61.123 - 61.124 + 61.125 + /** 61.126 + * The result of evaluating template instruction. 61.127 + */ 61.128 static class Result { 61.129 - Terminator terminator; 61.130 - int retCode; 61.131 - 61.132 + Terminator terminator; 61.133 + int retCode; 61.134 + 61.135 /** No text had been parsed. */ 61.136 - boolean empty; 61.137 - 61.138 - Result(Terminator terminator, int retCode, boolean empty) { 61.139 + boolean empty; 61.140 + 61.141 + Result(Terminator terminator, int retCode, boolean empty) { 61.142 this.terminator = terminator; 61.143 this.retCode = retCode; 61.144 this.empty = empty; 61.145 } 61.146 - 61.147 + 61.148 Result() { 61.149 this(null, -1, true); 61.150 - } 61.151 - }; 61.152 - 61.153 - private Map<String, Object> variables = new HashMap<String, Object>(); 61.154 - private TemplateParser superParser; 61.155 - 61.156 + } 61.157 + }; 61.158 + 61.159 + protected final Context context; 61.160 + 61.161 private int termBracket = -1; 61.162 - 61.163 + 61.164 public TemplateParser() { 61.165 - this(null); 61.166 + this.context = new Context(new GlobalContext()); 61.167 } 61.168 - 61.169 + 61.170 + public TemplateParser(File baseDir) { 61.171 + this.context = new Context(new GlobalContext(), baseDir); 61.172 + } 61.173 + 61.174 public TemplateParser(TemplateParser superParser) { 61.175 - this.superParser = superParser; 61.176 - 61.177 - Functions.registerAllFunctions(this); 61.178 + this.context = new Context(superParser.context); 61.179 } 61.180 - 61.181 - public void registerFunction(String name, Function f) { 61.182 - variables.put(name, f); 61.183 + 61.184 + public TemplateParser(TemplateParser superParser, File baseDir) { 61.185 + this.context = new Context(superParser.context, baseDir); 61.186 } 61.187 - 61.188 - public int parse(TemplateReader in, Writer out) 61.189 - throws IOException, TemplateException { 61.190 - 61.191 - return parse(in, out, true, null, null).retCode; 61.192 + 61.193 + public TemplateParser(Context context) { 61.194 + this.context = context; 61.195 } 61.196 - 61.197 + 61.198 /** 61.199 - * Parse template. 61.200 + * Parse template 61.201 + * 61.202 + * @param in TemplateReader to read template data. 61.203 + * @param out Writer for the processed data. 61.204 + * @throws IOException if case of I/O error. 61.205 + * @throws TemplateException in case of parsing error (syntax 61.206 + * error or invalid arguments in template instructions). 61.207 + */ 61.208 + public int parse(TemplateReader in, Writer out) 61.209 + throws IOException, TemplateException { 61.210 + return parse(in, out, DataFormat.RECURSIVE, null).retCode; 61.211 + } 61.212 + 61.213 + Result parse(TemplateReader in, Writer out, DataFormat format) 61.214 + throws IOException, TemplateException { 61.215 + return parse(in, out, format, null); 61.216 + } 61.217 + 61.218 + /** 61.219 + * Parse template. 61.220 * 61.221 * @param in TemplateReader to read template data. 61.222 * @param out Writer to write processed data. 61.223 - * @param recursive enables recursive processing. 61.224 - * @param separators characters which terminate parsing block. 61.225 - * @param leading characters to ignore at the beginning of the block. 61.226 + * @param DataFormat specifies parsing mode. 61.227 */ 61.228 - Result parse(TemplateReader in, Writer out, boolean recursive, 61.229 - char[] separators, char[] leading) 61.230 - throws IOException, TemplateException { 61.231 - 61.232 - Result result = new Result(); 61.233 - int lc = -1; 61.234 - 61.235 - while (true) { 61.236 - int c = in.read(); 61.237 + Result parse(TemplateReader in, Writer out, DataFormat format, 61.238 + char[] separators) 61.239 + throws IOException, TemplateException { 61.240 + 61.241 + Result result = new Result(); 61.242 + 61.243 + if (format == DataFormat.SUBFUNCTION || 61.244 + format == DataFormat.SUBFUNCTION_NOCALL) { 61.245 61.246 - if (leading != null && isSeparator(c, leading)) 61.247 - continue; 61.248 - else 61.249 - leading = null; 61.250 - 61.251 - boolean leftBracket = false; 61.252 - int index; 61.253 - 61.254 - for (index = 0; index < BR_LEFT.length; index++) { 61.255 - if (lc == BR_LEFT[index]) { 61.256 - leftBracket = true; 61.257 - break; 61.258 + result.retCode = parseFunction(in, out, format); 61.259 + result.empty = false; 61.260 + return result; 61.261 + } 61.262 + 61.263 + while (true) { 61.264 + if (format != DataFormat.VERBATIM) { 61.265 + int openBracket = matchInput(in, BRACKET_OPEN); 61.266 + 61.267 + if (openBracket >= 0) { 61.268 + if (result.retCode < 0) 61.269 + result.retCode = 0; 61.270 + 61.271 + if (!format.call) { 61.272 + out.write(BRACKET_OPEN[openBracket]); 61.273 + } 61.274 + 61.275 + int tb = termBracket; 61.276 + termBracket = openBracket; 61.277 + result.retCode += Math.abs(parseFunction(in, out, format)); 61.278 + result.empty = false; 61.279 + termBracket = tb; 61.280 + 61.281 + if (!format.call) { 61.282 + out.write(BRACKET_CLOSE[openBracket]); 61.283 + } 61.284 + 61.285 + continue; 61.286 } 61.287 } 61.288 - 61.289 - if (recursive && leftBracket && c == BR_IN) { 61.290 - 61.291 - if (result.retCode < 0) 61.292 - result.retCode = 0; 61.293 - 61.294 - lc = -1; 61.295 - int tb = termBracket; 61.296 - termBracket = BR_RIGHT[index]; 61.297 - result.retCode += parseFunction(in, out); 61.298 - termBracket = tb; 61.299 - 61.300 - } else if (lc == BR_IN && c == termBracket) { 61.301 - 61.302 - lc = -1; 61.303 - result.terminator = Terminator.BRACKET; 61.304 - break; 61.305 - 61.306 - } else { 61.307 - 61.308 - if (lc >= 0) 61.309 - out.write(lc); 61.310 - 61.311 - lc = c; 61.312 - } 61.313 - 61.314 - if (c < 0) { 61.315 - result.terminator = Terminator.EOF; 61.316 - break; 61.317 - } else if (separators != null && isSeparator(c, separators)) { 61.318 + 61.319 + if (matchCloseBracket(in)) { 61.320 + result.terminator = Terminator.BRACKET; 61.321 + skipEscaped(in); 61.322 + break; 61.323 + } 61.324 + 61.325 + int c = in.read(); 61.326 + 61.327 + if (c < 0) { 61.328 +// if (termBracket >= 0) { 61.329 +// throw new TemplateException("Unexpected end of file", in); 61.330 +// } 61.331 + 61.332 + result.terminator = Terminator.EOF; 61.333 + break; 61.334 + } 61.335 + 61.336 + if (separators != null && isSeparator(c, separators)) { 61.337 result.terminator = Terminator.SEPARATOR; 61.338 break; 61.339 } 61.340 - 61.341 + 61.342 + out.write(c); 61.343 result.empty = false; 61.344 - } 61.345 - 61.346 - return result; 61.347 + } 61.348 + 61.349 + return result; 61.350 } 61.351 - 61.352 + 61.353 + /** 61.354 + * Check if the closing bracket sequence follows in the reader. 61.355 + */ 61.356 + boolean checkCloseBracket(TemplateReader in) throws IOException { 61.357 + boolean match = matchCloseBracket(in); 61.358 + 61.359 + if (!match) 61.360 + return false; 61.361 + 61.362 + // Put the matched characters back to the stream 61.363 + in.unread(BRACKET_CLOSE[termBracket].toCharArray()); 61.364 + 61.365 + return true; 61.366 + } 61.367 + 61.368 + private boolean matchCloseBracket(TemplateReader in) 61.369 + throws IOException { 61.370 + 61.371 + if (termBracket < 0) 61.372 + return false; 61.373 + 61.374 + return matchInput(in, BRACKET_CLOSE[termBracket]); 61.375 + } 61.376 + 61.377 + private int matchInput(TemplateReader in, String[] s) 61.378 + throws IOException { 61.379 + for (int i = 0; i < s.length; i++) { 61.380 + if (matchInput(in, s[i])) 61.381 + return i; 61.382 + } 61.383 + 61.384 + return -1; 61.385 + } 61.386 + 61.387 + private boolean matchInput(TemplateReader in, String s) 61.388 + throws IOException { 61.389 + int n = s.length(); 61.390 + for (int k = 0; k < n; k++) { 61.391 + int c = in.read(); 61.392 + 61.393 + if (c != s.charAt(k)) { 61.394 + if (c >= 0) { 61.395 + in.unread(c); 61.396 + } 61.397 + 61.398 + for (int j = k - 1; j >= 0; j--) { 61.399 + in.unread(s.charAt(j)); 61.400 + } 61.401 + 61.402 + return false; 61.403 + } 61.404 + } 61.405 + 61.406 + return true; 61.407 + } 61.408 + 61.409 + void skip(TemplateReader in, char[] chars) throws IOException { 61.410 + readLoop: 61.411 + while (true) { 61.412 + int c = in.read(); 61.413 + 61.414 + if (c < 0) 61.415 + break; 61.416 + 61.417 + for (int i = 0; i < chars.length; i++) { 61.418 + if (c == chars[i]) 61.419 + continue readLoop; 61.420 + } 61.421 + 61.422 + in.unread(c); 61.423 + break; 61.424 + } 61.425 + } 61.426 + 61.427 + private void skipEscaped(TemplateReader in) throws IOException { 61.428 + if (matchInput(in, ESCAPE_WHITESPACE)) { 61.429 + int c = in.read(); 61.430 + 61.431 + if (c < 0) 61.432 + return; 61.433 + 61.434 + if (!Character.isWhitespace(c)) { 61.435 + in.unread(c); 61.436 + in.unread(ESCAPE_WHITESPACE.toCharArray()); 61.437 + return; 61.438 + } 61.439 + 61.440 + do { 61.441 + c = in.read(); 61.442 + } while (Character.isWhitespace(c)); 61.443 + 61.444 + if (c >= 0) 61.445 + in.unread(c); 61.446 + 61.447 + return; 61.448 + } 61.449 + 61.450 + matchInput(in, 61.451 + new String[] { 61.452 + ESCAPE_NEWLINE + "\r\n", 61.453 + ESCAPE_NEWLINE + "\r", 61.454 + ESCAPE_NEWLINE + "\n"}); 61.455 + } 61.456 + 61.457 boolean isSeparator(int c, char[] separators) { 61.458 for (char p : separators) { 61.459 if (c == p) return true; 61.460 } 61.461 - 61.462 + 61.463 return false; 61.464 } 61.465 - 61.466 - int parseFunction(TemplateReader in, Writer out) 61.467 - throws IOException, TemplateException { 61.468 + 61.469 + private int parseFunction(TemplateReader in, Writer out, DataFormat fd) 61.470 + throws IOException, TemplateException { 61.471 61.472 - StringBuffer sb = new StringBuffer(); 61.473 + StringBuffer sb = new StringBuffer(); 61.474 61.475 - while (true) { 61.476 - int c = in.read(); 61.477 + while (true) { 61.478 + if (termBracket >= 0 && 61.479 + matchInput(in, BRACKET_CLOSE[termBracket])) { 61.480 + throw new TemplateException( 61.481 + "Unexpected end of instruction", in); 61.482 + } 61.483 + 61.484 + int c = in.read(); 61.485 + 61.486 + if (c < 0) 61.487 + throw new TemplateException("Unexpected end of file.", in); 61.488 + 61.489 + if (!fd.call) 61.490 + out.write(c); 61.491 61.492 if (isSeparator(c, LIST_SEPARATORS)) { 61.493 - return invokeFunction(sb.toString(), 61.494 - FunctionData.SUBFUNCTION, 61.495 - in, out); 61.496 + return invoke( 61.497 + fd.call ? sb.toString() : "true", 61.498 + fd.call ? 61.499 + DataFormat.SUBFUNCTION : 61.500 + DataFormat.SUBFUNCTION_NOCALL, 61.501 + in, out); 61.502 } else if (isSeparator(c, REC_DATA_SEPARATORS)) { 61.503 - return invokeFunction(sb.toString(), 61.504 - FunctionData.RECURSIVE, 61.505 - in, out); 61.506 - } else if (isSeparator(c, NONREC_DATA_SEPARATORS)) { 61.507 - return invokeFunction(sb.toString(), 61.508 - FunctionData.NONRECURSIVE, 61.509 - in, out); 61.510 - } else if (c < 0) { 61.511 - throw new TemplateException("Unexpected end of file.", in); 61.512 + skipEscaped(in); 61.513 + return invoke( 61.514 + fd.call ? sb.toString() : "true", 61.515 + fd.call ? 61.516 + DataFormat.RECURSIVE : 61.517 + DataFormat.NOCALL, 61.518 + in, out); 61.519 + } else if (isSeparator(c, VERBATIM_DATA_SEPARATORS)) { 61.520 + return invoke( 61.521 + fd.call ? sb.toString() : "true", 61.522 + DataFormat.VERBATIM, in, out); 61.523 + } else if (isSeparator(c, NOCALL_DATA_SEPARATORS)) { 61.524 + skipEscaped(in); 61.525 + return invoke( 61.526 + fd.call ? sb.toString() : "true", 61.527 + DataFormat.NOCALL, in, out); 61.528 } else { 61.529 - sb.append((char)c); 61.530 - } 61.531 - } 61.532 + sb.append((char)c); 61.533 + } 61.534 + } 61.535 } 61.536 - 61.537 - int parseValue(Object value, Writer out) throws IOException { 61.538 + 61.539 + public int parseValue(Object value, Writer out) throws IOException { 61.540 if (value == null) 61.541 return 0; 61.542 - 61.543 + 61.544 String svalue = value.toString(); 61.545 61.546 if (svalue == null || svalue.length() == 0) 61.547 return 0; 61.548 - 61.549 + 61.550 out.write(svalue); 61.551 return 1; 61.552 } 61.553 - 61.554 - private int invokeFunction(String name, FunctionData fd, 61.555 - TemplateReader in, Writer out) 61.556 - throws IOException, TemplateException { 61.557 - 61.558 + 61.559 + private int invoke(String name, DataFormat fd, 61.560 + TemplateReader in, Writer out) 61.561 + throws IOException, TemplateException { 61.562 + 61.563 FunctionDataParser fdp = new FunctionDataParser(this, fd, in); 61.564 - 61.565 - if ("".equals(name)) { 61.566 - return fdp.parseData(out); 61.567 - } 61.568 + 61.569 + int r = invoke(name, fdp, out); 61.570 61.571 - Object value = getValue(name); 61.572 - int r; 61.573 - 61.574 - if (value instanceof Function) { 61.575 - r = ((Function) value).invoke(fdp, out); 61.576 - } else { 61.577 - r = parseValue(value, out); 61.578 + if (fdp.hasMoreData()) { 61.579 + /* Skip remaining function data. */ 61.580 + fdp.skipData(); 61.581 } 61.582 - 61.583 - if (fdp.hasMoreData()) { 61.584 - /* Skip remaining function data. */ 61.585 - fdp.parseData(new Writer() { 61.586 - public void close() {} 61.587 - public void flush() {} 61.588 - public void write(char[] cbuf, int off, int len) {} 61.589 - }); 61.590 - } 61.591 - 61.592 - return r; 61.593 + 61.594 + return r; 61.595 } 61.596 - 61.597 - public Object getValue(String name) throws TemplateException { 61.598 - Object value = variables.get(name); 61.599 - if (value != null) return value; 61.600 - 61.601 - if (superParser != null) { 61.602 - if (name.startsWith(SUPER_PREFIX)) 61.603 - return superParser.getValue 61.604 - (name.substring(SUPER_PREFIX.length())); 61.605 - else 61.606 - return superParser.getValue(name); 61.607 - } 61.608 - 61.609 - return null; 61.610 + 61.611 + public int invoke(String name, FunctionDataParser fdp, Writer out) 61.612 + throws IOException, TemplateException { 61.613 + Object value = context.get(name); 61.614 + 61.615 + if (value instanceof Function) { 61.616 + return ((Function) value).invoke(fdp, out); 61.617 + } 61.618 + 61.619 + if (value instanceof Context) { 61.620 + String code = fdp.getData(); 61.621 + 61.622 + if (fdp.getLastReturnCode() == 0) 61.623 + return 0; 61.624 + 61.625 + TemplateParser parser = new TemplateParser((Context) value); 61.626 + return parser.parse( 61.627 + new TemplateReader(new StringReader(code)), out); 61.628 + } 61.629 + 61.630 + return parseValue(value, out); 61.631 } 61.632 - 61.633 - public void setValue(String name, Object value) { 61.634 - variables.put(name, value); 61.635 - } 61.636 - 61.637 - public void clearValues() { 61.638 - variables.clear(); 61.639 - Functions.registerAllFunctions(this); 61.640 - } 61.641 - 61.642 - // TEST 61.643 - public static void main(String[] args) 61.644 - throws IOException, TemplateException { 61.645 - 61.646 - TemplateParser p = new TemplateParser(); 61.647 - 61.648 - TemplateReader in = 61.649 - new TemplateReader 61.650 - (new LineNumberReader 61.651 - (new FileReader("parser.in")), "parser.in"); 61.652 - 61.653 - FileWriter out = new FileWriter("parser.out"); 61.654 - 61.655 - p.parse(in, out); 61.656 - 61.657 - in.close(); 61.658 - out.close(); 61.659 + 61.660 + public Context getContext() { 61.661 + return context; 61.662 } 61.663 }
62.1 --- a/src/kryshen/tema/TemplateReader.java Thu Dec 14 23:22:05 2006 +0300 62.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 62.3 @@ -1,64 +0,0 @@ 62.4 -/* 62.5 - * Copyright (C) 2006 Mikhail A. Kryshen 62.6 - * 62.7 - * This program is free software; you can redistribute it and/or modify 62.8 - * it under the terms of the GNU General Public License as published by 62.9 - * the Free Software Foundation; either version 2 of the License, or 62.10 - * (at your option) any later version. 62.11 - * 62.12 - * This program is distributed in the hope that it will be useful, 62.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 62.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 62.15 - * GNU General Public License for more details. 62.16 - * 62.17 - * You should have received a copy of the GNU General Public License 62.18 - * along with this program; if not, write to the Free Software 62.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 62.20 - * 62.21 - * $Id: TemplateReader.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 62.22 - */ 62.23 - 62.24 -package kryshen.tema; 62.25 - 62.26 -import java.io.Reader; 62.27 -import java.io.LineNumberReader; 62.28 -import java.io.FilterReader; 62.29 -import java.io.IOException; 62.30 - 62.31 -/** 62.32 - * Reader for TEMA templates. Stores data source name (commonly 62.33 - * filename) and tracks line numbers for error reporting. 62.34 - * 62.35 - * @author Mikhail A. Kryshen 62.36 - */ 62.37 -public class TemplateReader extends FilterReader { 62.38 - private String source = null; 62.39 - 62.40 - private LineNumberReader lnReader = null; 62.41 - private TemplateReader parentReader = null; 62.42 - 62.43 - public TemplateReader(LineNumberReader in, String source) { 62.44 - super(in); 62.45 - this.lnReader = in; 62.46 - this.source = source; 62.47 - } 62.48 - 62.49 - public TemplateReader(Reader in, TemplateReader parent) { 62.50 - super(in); 62.51 - this.source = source; 62.52 - } 62.53 - 62.54 - public String getSource() { 62.55 - if (source != null) 62.56 - return source; 62.57 - 62.58 - return parentReader.getSource(); 62.59 - } 62.60 - 62.61 - public int getLineNumber() { 62.62 - if (lnReader != null) 62.63 - return lnReader.getLineNumber(); 62.64 - 62.65 - return parentReader.getLineNumber(); 62.66 - } 62.67 -}
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/src/kryshen/tema/ant/TemaTask.java Tue Feb 19 20:32:17 2008 +0300 63.3 @@ -0,0 +1,145 @@ 63.4 +/* 63.5 + * Copyright 2006-2008 Mikhail Kryshen 63.6 + * 63.7 + * This file is part of Tema. 63.8 + * 63.9 + * Tema is free software: you can redistribute it and/or modify it 63.10 + * under the terms of the GNU Lesser General Public License as 63.11 + * published by the Free Software Foundation, either version 3 of the 63.12 + * License, or (at your option) any later version. 63.13 + * 63.14 + * Tema is distributed in the hope that it will be useful, 63.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 63.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 63.17 + * GNU Lesser General Public License for more details. 63.18 + * 63.19 + * You should have received a copy of the 63.20 + * GNU Lesser General Public License along with Tema. 63.21 + * If not, see <http://www.gnu.org/licenses/>. 63.22 + * 63.23 + * $Id: TemaTask.java,v 1.17 2008/02/17 23:58:01 mikhail Exp $ 63.24 + */ 63.25 + 63.26 +package kryshen.tema.ant; 63.27 + 63.28 +import java.io.BufferedReader; 63.29 +import java.io.BufferedWriter; 63.30 +import java.io.File; 63.31 +import java.io.FileReader; 63.32 +import java.io.FileWriter; 63.33 +import java.io.IOException; 63.34 +import java.io.Writer; 63.35 +import java.util.ArrayList; 63.36 +import java.util.Collection; 63.37 +import kryshen.tema.TemplateException; 63.38 +import kryshen.tema.TemplateParser; 63.39 +import kryshen.tema.io.NullWriter; 63.40 +import kryshen.tema.io.TemplateReader; 63.41 +import org.apache.tools.ant.BuildException; 63.42 +import org.apache.tools.ant.Task; 63.43 + 63.44 +/** 63.45 + * Tema support for ant. 63.46 + * 63.47 + * @author Mikhail Kryshen 63.48 + */ 63.49 +public class TemaTask extends Task { 63.50 + 63.51 + public static class Variable { 63.52 + private String name; 63.53 + private String value; 63.54 + 63.55 + public void setName(String name) { 63.56 + this.name = name; 63.57 + } 63.58 + 63.59 + public void setValue(String value) { 63.60 + this.value = value; 63.61 + } 63.62 + 63.63 + public void setPath(File file) { 63.64 + this.value = file.getAbsolutePath(); 63.65 + } 63.66 + } 63.67 + 63.68 + private File basedir = null; 63.69 + 63.70 + private File infile = null; 63.71 + private File outfile = null; 63.72 + 63.73 + private Collection<Variable> variables = new ArrayList<Variable>(); 63.74 + 63.75 + @Override 63.76 + public void execute() throws BuildException { 63.77 + if (basedir == null) { 63.78 + basedir = getProject().getBaseDir(); 63.79 + } 63.80 + 63.81 + if (infile == null) { 63.82 + throw new BuildException("no infile specified", getLocation()); 63.83 + } 63.84 + 63.85 + try { 63.86 + executeTema(); 63.87 + } catch (IOException e) { 63.88 + throw new BuildException(e); 63.89 + } catch (TemplateException e) { 63.90 + throw new BuildException(e); 63.91 + } 63.92 + } 63.93 + 63.94 + private void executeTema() throws IOException, TemplateException { 63.95 + TemplateParser parser = new TemplateParser(basedir); 63.96 + 63.97 + for (Variable var : variables) { 63.98 + if (var.name == null) { 63.99 + throw new BuildException( 63.100 + "no name specified for variable", getLocation()); 63.101 + } 63.102 + 63.103 + if (var.value == null) { 63.104 + throw new BuildException( 63.105 + "no value specified for variable", getLocation()); 63.106 + } 63.107 + 63.108 + parser.getContext().set(var.name, var.value); 63.109 + } 63.110 + 63.111 + TemplateReader in = new TemplateReader( 63.112 + new BufferedReader(new FileReader(infile)), 63.113 + infile.getName()); 63.114 + try { 63.115 + Writer out; 63.116 + 63.117 + if (outfile != null) { 63.118 + out = new BufferedWriter(new FileWriter(outfile)); 63.119 + } else { 63.120 + out = NullWriter.INSTANCE; 63.121 + } 63.122 + 63.123 + try { 63.124 + parser.parse(in, out); 63.125 + } finally { 63.126 + out.close(); 63.127 + } 63.128 + } finally { 63.129 + in.close(); 63.130 + } 63.131 + } 63.132 + 63.133 + public void setBasedir(File basedir) { 63.134 + this.basedir = basedir; 63.135 + } 63.136 + 63.137 + public void setInfile(File infile) { 63.138 + this.infile = infile; 63.139 + } 63.140 + 63.141 + public void setOutfile(File outfile) { 63.142 + this.outfile = outfile; 63.143 + } 63.144 + 63.145 + public void addVariable(Variable variable) { 63.146 + variables.add(variable); 63.147 + } 63.148 +}
64.1 --- a/src/kryshen/tema/demo/DemoFrame.java Thu Dec 14 23:22:05 2006 +0300 64.2 +++ b/src/kryshen/tema/demo/DemoFrame.java Tue Feb 19 20:32:17 2008 +0300 64.3 @@ -1,181 +1,228 @@ 64.4 /* 64.5 - * Copyright (C) 2006 Mikhail A. Kryshen 64.6 + * Copyright 2006-2008 Mikhail Kryshen 64.7 * 64.8 - * This program is free software; you can redistribute it and/or modify 64.9 - * it under the terms of the GNU General Public License as published by 64.10 - * the Free Software Foundation; either version 2 of the License, or 64.11 - * (at your option) any later version. 64.12 + * This file is part of Tema. 64.13 * 64.14 - * This program is distributed in the hope that it will be useful, 64.15 + * Tema is free software: you can redistribute it and/or modify it 64.16 + * under the terms of the GNU Lesser General Public License as 64.17 + * published by the Free Software Foundation, either version 3 of the 64.18 + * License, or (at your option) any later version. 64.19 + * 64.20 + * Tema is distributed in the hope that it will be useful, 64.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 64.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 64.23 - * GNU General Public License for more details. 64.24 + * GNU Lesser General Public License for more details. 64.25 * 64.26 - * You should have received a copy of the GNU General Public License 64.27 - * along with this program; if not, write to the Free Software 64.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 64.29 + * You should have received a copy of the 64.30 + * GNU Lesser General Public License along with Tema. 64.31 + * If not, see <http://www.gnu.org/licenses/>. 64.32 * 64.33 - * $Id: DemoFrame.java,v 1.3 2006/12/14 15:59:48 mikhail Exp $ 64.34 + * $Id: DemoFrame.java,v 1.13 2008/02/16 17:38:03 mikhail Exp $ 64.35 */ 64.36 64.37 package kryshen.tema.demo; 64.38 64.39 -import java.awt.*; 64.40 -import java.awt.event.*; 64.41 -import java.io.*; 64.42 +import java.awt.Button; 64.43 +import java.awt.FlowLayout; 64.44 +import java.awt.Font; 64.45 +import java.awt.Frame; 64.46 +import java.awt.GridBagConstraints; 64.47 +import java.awt.GridBagLayout; 64.48 +import java.awt.Insets; 64.49 +import java.awt.Label; 64.50 +import java.awt.Panel; 64.51 +import java.awt.TextArea; 64.52 +import java.awt.event.ActionEvent; 64.53 +import java.awt.event.ActionListener; 64.54 +import java.awt.event.WindowAdapter; 64.55 +import java.awt.event.WindowEvent; 64.56 +import java.io.BufferedReader; 64.57 +import java.io.IOException; 64.58 +import java.io.InputStreamReader; 64.59 +import java.io.Reader; 64.60 +import java.io.StringReader; 64.61 +import java.io.StringWriter; 64.62 import java.net.URL; 64.63 - 64.64 -import kryshen.tema.*; 64.65 +import kryshen.tema.TemplateParser; 64.66 +import kryshen.tema.io.TemplateReader; 64.67 64.68 /** 64.69 - * TEMA demonstation console. 64.70 + * Tema demonstation console. 64.71 */ 64.72 public class DemoFrame extends Frame { 64.73 + private static final Font TEXT_FONT = 64.74 + new Font("monospaced", Font.PLAIN, 12); 64.75 + 64.76 private TextArea input; 64.77 private TextArea output; 64.78 private TextArea error; 64.79 64.80 + private String sample; 64.81 + 64.82 public DemoFrame() { 64.83 - super("TEMA demo console"); 64.84 - 64.85 + super("Tema demo console"); 64.86 + 64.87 GridBagLayout gbl = new GridBagLayout(); 64.88 - 64.89 + 64.90 GridBagConstraints c = new GridBagConstraints(); 64.91 - 64.92 + 64.93 setLayout(gbl); 64.94 - 64.95 - input = new TextArea(25, 40); 64.96 + 64.97 + input = new TextArea(28, 50); 64.98 input.setEditable(true); 64.99 - 64.100 - output = new TextArea(25, 40); 64.101 + input.setFont(TEXT_FONT); 64.102 + 64.103 + output = new TextArea(28, 50); 64.104 output.setEditable(false); 64.105 - 64.106 - error = new TextArea(5, 80); 64.107 + output.setFont(TEXT_FONT); 64.108 + 64.109 + error = new TextArea(5, 90); 64.110 error.setEditable(false); 64.111 - 64.112 + error.setFont(TEXT_FONT); 64.113 + 64.114 Label l; 64.115 - 64.116 + 64.117 c.insets = new Insets(3, 3, 3, 3); 64.118 c.fill = GridBagConstraints.BOTH; 64.119 c.gridwidth = GridBagConstraints.RELATIVE; 64.120 - 64.121 - l = new Label("Enter your code and click \"Process\"."); 64.122 - 64.123 + 64.124 + l = new Label("Enter your code and press \"Process\"."); 64.125 + 64.126 gbl.setConstraints(l, c); 64.127 add(l); 64.128 - 64.129 + 64.130 Panel buttons = new Panel(); 64.131 buttons.setLayout(new FlowLayout(FlowLayout.LEFT)); 64.132 64.133 Button process = new Button("Process"); 64.134 Button clear = new Button("Clear"); 64.135 + Button reset = new Button("Reset"); 64.136 Button close = new Button("Close"); 64.137 - 64.138 + 64.139 buttons.add(process); 64.140 buttons.add(clear); 64.141 + buttons.add(reset); 64.142 buttons.add(close); 64.143 - 64.144 - c.gridwidth = GridBagConstraints.REMAINDER; 64.145 - 64.146 + 64.147 + c.gridwidth = GridBagConstraints.REMAINDER; 64.148 + 64.149 gbl.setConstraints(buttons, c); 64.150 add(buttons); 64.151 - 64.152 + 64.153 c.fill = GridBagConstraints.BOTH; 64.154 c.anchor = GridBagConstraints.CENTER; 64.155 c.gridwidth = GridBagConstraints.RELATIVE; 64.156 - 64.157 + 64.158 l = new Label("Input:"); 64.159 - 64.160 + 64.161 gbl.setConstraints(l, c); 64.162 add(l); 64.163 - 64.164 - c.gridwidth = GridBagConstraints.REMAINDER; 64.165 - 64.166 + 64.167 + c.gridwidth = GridBagConstraints.REMAINDER; 64.168 + 64.169 l = new Label("Output:"); 64.170 - 64.171 + 64.172 gbl.setConstraints(l, c); 64.173 add(l); 64.174 - 64.175 - c.gridwidth = GridBagConstraints.RELATIVE; 64.176 - 64.177 + 64.178 + c.gridwidth = GridBagConstraints.RELATIVE; 64.179 + c.weightx = 1.0; 64.180 + c.weighty = 1.0; 64.181 + 64.182 gbl.setConstraints(input, c); 64.183 add(input); 64.184 - 64.185 - c.gridwidth = GridBagConstraints.REMAINDER; 64.186 - 64.187 + 64.188 + c.gridwidth = GridBagConstraints.REMAINDER; 64.189 + 64.190 gbl.setConstraints(output, c); 64.191 add(output); 64.192 - 64.193 + 64.194 + c.weightx = 0.0; 64.195 + c.weighty = 0.0; 64.196 + 64.197 l = new Label("Errors:"); 64.198 - 64.199 + 64.200 gbl.setConstraints(l, c); 64.201 add(l); 64.202 - 64.203 + 64.204 + c.weightx = 1.0; 64.205 + c.weighty = 0.25; 64.206 + 64.207 gbl.setConstraints(error, c); 64.208 - add(error); 64.209 - 64.210 + add(error); 64.211 + 64.212 process.addActionListener(new ActionListener() { 64.213 - public void actionPerformed(ActionEvent e) { 64.214 - process(); 64.215 - } 64.216 - }); 64.217 - 64.218 + public void actionPerformed(ActionEvent e) { 64.219 + process(); 64.220 + } 64.221 + }); 64.222 + 64.223 clear.addActionListener(new ActionListener() { 64.224 - public void actionPerformed(ActionEvent e) { 64.225 - error.setText(""); 64.226 - output.setText(""); 64.227 - input.setText(""); 64.228 - 64.229 - } 64.230 - }); 64.231 - 64.232 + public void actionPerformed(ActionEvent e) { 64.233 + error.setText(""); 64.234 + output.setText(""); 64.235 + input.setText(""); 64.236 + input.requestFocus(); 64.237 + } 64.238 + }); 64.239 + 64.240 + reset.addActionListener(new ActionListener() { 64.241 + public void actionPerformed(ActionEvent e) { 64.242 + error.setText(""); 64.243 + output.setText(""); 64.244 + input.setText(sample); 64.245 + } 64.246 + }); 64.247 + 64.248 close.addActionListener(new ActionListener() { 64.249 - public void actionPerformed(ActionEvent e) { 64.250 - dispose(); 64.251 - } 64.252 - }); 64.253 - 64.254 + public void actionPerformed(ActionEvent e) { 64.255 + dispose(); 64.256 + } 64.257 + }); 64.258 + 64.259 addWindowListener(new WindowAdapter() { 64.260 - public void windowClosing(WindowEvent e) { 64.261 - dispose(); 64.262 - } 64.263 - }); 64.264 + public void windowClosing(WindowEvent e) { 64.265 + dispose(); 64.266 + } 64.267 + }); 64.268 64.269 URL source = getClass().getResource("demo.template"); 64.270 StringBuffer buffer = new StringBuffer(); 64.271 - 64.272 + 64.273 try { 64.274 Reader in = new BufferedReader 64.275 - (new InputStreamReader(source.openStream(), "UTF-8")); 64.276 + (new InputStreamReader(source.openStream(), "UTF-8")); 64.277 64.278 for (int ch = in.read(); ch >= 0; ch = in.read()) { 64.279 buffer.append((char)ch); 64.280 } 64.281 - 64.282 + 64.283 in.close(); 64.284 } catch (IOException e) { 64.285 e.printStackTrace(); 64.286 } 64.287 64.288 - input.setText(buffer.toString()); 64.289 + sample = buffer.toString(); 64.290 + 64.291 + input.setText(sample); 64.292 } 64.293 - 64.294 + 64.295 private void process() { 64.296 String s = input.getText(); 64.297 64.298 - TemplateReader tr = new TemplateReader 64.299 - (new LineNumberReader(new StringReader(s)), "input"); 64.300 + TemplateReader tr = new TemplateReader(new StringReader(s), "input"); 64.301 TemplateParser tp = new TemplateParser(); 64.302 StringWriter sw = new StringWriter(); 64.303 - 64.304 + 64.305 error.setText(""); 64.306 - 64.307 + 64.308 try { 64.309 tp.parse(tr, sw); 64.310 } catch (Exception e) { 64.311 error.setText(e.toString()); 64.312 + e.printStackTrace(); 64.313 } 64.314 - 64.315 + 64.316 output.setText(sw.toString()); 64.317 } 64.318 }
65.1 --- a/src/kryshen/tema/demo/Hello.java Thu Dec 14 23:22:05 2006 +0300 65.2 +++ b/src/kryshen/tema/demo/Hello.java Tue Feb 19 20:32:17 2008 +0300 65.3 @@ -1,21 +1,23 @@ 65.4 /* 65.5 - * Copyright (C) 2006 Mikhail A. Kryshen 65.6 + * Copyright 2006-2008 Mikhail Kryshen 65.7 * 65.8 - * This program is free software; you can redistribute it and/or modify 65.9 - * it under the terms of the GNU General Public License as published by 65.10 - * the Free Software Foundation; either version 2 of the License, or 65.11 - * (at your option) any later version. 65.12 + * This file is part of Tema. 65.13 * 65.14 - * This program is distributed in the hope that it will be useful, 65.15 + * Tema is free software: you can redistribute it and/or modify it 65.16 + * under the terms of the GNU Lesser General Public License as 65.17 + * published by the Free Software Foundation, either version 3 of the 65.18 + * License, or (at your option) any later version. 65.19 + * 65.20 + * Tema is distributed in the hope that it will be useful, 65.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 65.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 65.23 - * GNU General Public License for more details. 65.24 + * GNU Lesser General Public License for more details. 65.25 * 65.26 - * You should have received a copy of the GNU General Public License 65.27 - * along with this program; if not, write to the Free Software 65.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 65.29 + * You should have received a copy of the 65.30 + * GNU Lesser General Public License along with Tema. 65.31 + * If not, see <http://www.gnu.org/licenses/>. 65.32 * 65.33 - * $Id: Hello.java,v 1.2 2006/12/14 14:39:24 mikhail Exp $ 65.34 + * $Id: Hello.java,v 1.9 2008/02/16 17:56:34 mikhail Exp $ 65.35 */ 65.36 65.37 package kryshen.tema.demo; 65.38 @@ -27,7 +29,7 @@ 65.39 /** 65.40 * Example function implementation. 65.41 * 65.42 - * @author Mikhail A. Kryshen 65.43 + * @author Mikhail Kryshen 65.44 */ 65.45 public class Hello extends Function { 65.46 public Hello() {} 65.47 @@ -36,8 +38,6 @@ 65.48 throws IOException, TemplateException { 65.49 65.50 out.write("Hello, "); 65.51 - fdp.parseData(out); 65.52 - 65.53 - return 1; 65.54 + return fdp.parseData(out); 65.55 } 65.56 }
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/src/kryshen/tema/functions/Control.java Tue Feb 19 20:32:17 2008 +0300 66.3 @@ -0,0 +1,166 @@ 66.4 +/* 66.5 + * Copyright 2006-2008 Mikhail Kryshen 66.6 + * 66.7 + * This file is part of Tema. 66.8 + * 66.9 + * Tema is free software: you can redistribute it and/or modify it 66.10 + * under the terms of the GNU Lesser General Public License as 66.11 + * published by the Free Software Foundation, either version 3 of the 66.12 + * License, or (at your option) any later version. 66.13 + * 66.14 + * Tema is distributed in the hope that it will be useful, 66.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 66.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 66.17 + * GNU Lesser General Public License for more details. 66.18 + * 66.19 + * You should have received a copy of the 66.20 + * GNU Lesser General Public License along with Tema. 66.21 + * If not, see <http://www.gnu.org/licenses/>. 66.22 + * 66.23 + * $Id: Control.java,v 1.18 2008/02/19 16:21:00 mikhail Exp $ 66.24 + */ 66.25 + 66.26 +package kryshen.tema.functions; 66.27 + 66.28 +import java.io.IOException; 66.29 +import java.io.StringReader; 66.30 +import java.io.StringWriter; 66.31 +import java.io.Writer; 66.32 +import kryshen.tema.Function; 66.33 +import kryshen.tema.FunctionDataParser; 66.34 +import kryshen.tema.TemplateException; 66.35 +import kryshen.tema.TemplateParser; 66.36 +import kryshen.tema.io.NullWriter; 66.37 +import kryshen.tema.io.TemplateReader; 66.38 + 66.39 +/** 66.40 + * Logical and conditional functions. 66.41 + * 66.42 + * @author Mikhail Kryshen 66.43 + */ 66.44 +public class Control { 66.45 + 66.46 + /** 66.47 + * Copy input to output and return zero value. 66.48 + */ 66.49 + public static final Function FALSE = 66.50 + new Function() { 66.51 + public int invoke(FunctionDataParser fdp, Writer out) 66.52 + throws IOException, TemplateException { 66.53 + 66.54 + if (fdp.hasMoreData()) 66.55 + fdp.parseData(out); 66.56 + 66.57 + return 0; 66.58 + } 66.59 + }; 66.60 + 66.61 + /** 66.62 + * Copy input to output and return non-zero value. 66.63 + */ 66.64 + public static final Function TRUE = 66.65 + new Function() { 66.66 + public int invoke(FunctionDataParser fdp, Writer out) 66.67 + throws IOException, TemplateException { 66.68 + 66.69 + if (fdp.hasMoreData()) 66.70 + fdp.parseData(out); 66.71 + 66.72 + return 1; 66.73 + } 66.74 + }; 66.75 + 66.76 + /** 66.77 + * Outputs it's data if it has non-zero value. 66.78 + */ 66.79 + public static final Function OPTIONAL = new Function() { 66.80 + public int invoke(FunctionDataParser fdp, Writer out) 66.81 + throws IOException, TemplateException { 66.82 + 66.83 + StringWriter sw = new StringWriter(); 66.84 + int s = fdp.parseData(sw); 66.85 + sw.close(); 66.86 + String data = sw.toString(); 66.87 + 66.88 + if (s != 0) { 66.89 + out.write(data); 66.90 + return 1; 66.91 + } else { 66.92 + return 0; 66.93 + } 66.94 + } 66.95 + }; 66.96 + 66.97 + /** 66.98 + * Logical negation (applied to the return value). 66.99 + */ 66.100 + public static final Function NOT = new Function() { 66.101 + public int invoke(FunctionDataParser fdp, Writer out) 66.102 + throws IOException, TemplateException { 66.103 + 66.104 + return (fdp.parseData(out) == 0) ? 1 : 0; 66.105 + } 66.106 + }; 66.107 + 66.108 + public static final Function IF = new Function() { 66.109 + public int invoke(FunctionDataParser fdp, Writer out) 66.110 + throws IOException, TemplateException { 66.111 + 66.112 + int value = fdp.parseNextArg(NullWriter.INSTANCE); 66.113 + 66.114 + if (value != 0) { 66.115 + return fdp.parseData(out); 66.116 + } 66.117 + 66.118 + return 0; 66.119 + } 66.120 + }; 66.121 + 66.122 + public static final Function IF_ELSE = new Function() { 66.123 + public int invoke(FunctionDataParser fdp, Writer out) 66.124 + throws IOException, TemplateException { 66.125 + 66.126 + int value = fdp.parseNextArg(NullWriter.INSTANCE); 66.127 + 66.128 + if (value != 0) { 66.129 + return fdp.parseNextArg(out); 66.130 + } else { 66.131 + fdp.skipNextArg(); 66.132 + return fdp.parseData(out); 66.133 + } 66.134 + } 66.135 + }; 66.136 + 66.137 + /** 66.138 + * Outputs it's evaluated data while the evaluation result is non-zero. 66.139 + */ 66.140 + public static final Function WHILE = new Function() { 66.141 + public int invoke(FunctionDataParser fdp, final Writer out) 66.142 + throws IOException, TemplateException { 66.143 + 66.144 + String data = fdp.getData(); 66.145 + StringReader dataReader = new StringReader(data); 66.146 + 66.147 + TemplateParser parser = fdp.getTemplateParser(); 66.148 + 66.149 + int r = 0; // summarized return value 66.150 + int e = 0; // evaluation value 66.151 + 66.152 + while (true) { 66.153 + StringWriter sw = new StringWriter(); 66.154 + 66.155 + e = parser.parse(new TemplateReader(dataReader), sw); 66.156 + 66.157 + if (e == 0) 66.158 + break; 66.159 + 66.160 + r += Math.abs(e); 66.161 + out.write(sw.toString()); 66.162 + dataReader.reset(); 66.163 + } 66.164 + 66.165 + dataReader.close(); 66.166 + return r; 66.167 + } 66.168 + }; 66.169 +}
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/src/kryshen/tema/functions/Database.java Tue Feb 19 20:32:17 2008 +0300 67.3 @@ -0,0 +1,208 @@ 67.4 +/* 67.5 + * Copyright 2006-2008 Mikhail Kryshen 67.6 + * 67.7 + * This file is part of Tema. 67.8 + * 67.9 + * Tema is free software: you can redistribute it and/or modify it 67.10 + * under the terms of the GNU Lesser General Public License as 67.11 + * published by the Free Software Foundation, either version 3 of the 67.12 + * License, or (at your option) any later version. 67.13 + * 67.14 + * Tema is distributed in the hope that it will be useful, 67.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 67.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 67.17 + * GNU Lesser General Public License for more details. 67.18 + * 67.19 + * You should have received a copy of the 67.20 + * GNU Lesser General Public License along with Tema. 67.21 + * If not, see <http://www.gnu.org/licenses/>. 67.22 + * 67.23 + * $Id: Database.java,v 1.12 2008/02/17 23:58:01 mikhail Exp $ 67.24 + */ 67.25 + 67.26 +package kryshen.tema.functions; 67.27 + 67.28 +import java.io.IOException; 67.29 +import java.io.Reader; 67.30 +import java.io.StringReader; 67.31 +import java.io.Writer; 67.32 +import java.sql.Connection; 67.33 +import java.sql.DriverManager; 67.34 +import java.sql.PreparedStatement; 67.35 +import java.sql.ResultSet; 67.36 +import java.sql.ResultSetMetaData; 67.37 +import java.sql.SQLException; 67.38 +import java.util.HashMap; 67.39 +import java.util.List; 67.40 +import kryshen.tema.Context; 67.41 +import kryshen.tema.Function; 67.42 +import kryshen.tema.FunctionDataParser; 67.43 +import kryshen.tema.TemplateException; 67.44 +import kryshen.tema.TemplateParser; 67.45 +import kryshen.tema.io.TemplateReader; 67.46 + 67.47 +/** 67.48 + * Data access functions. 67.49 + * 67.50 + * @author Mikhail Kryshen 67.51 + */ 67.52 +public class Database { 67.53 + /* db_connect:connection_name resource */ 67.54 + public static final Function CONNECT = new Function() { 67.55 + public int invoke(FunctionDataParser fdp, Writer out) 67.56 + throws IOException, TemplateException { 67.57 + 67.58 + String arg0 = fdp.getNextArg(); 67.59 + String data = fdp.getData(); 67.60 + 67.61 + Connection connection; 67.62 + 67.63 + try { 67.64 + connection = DriverManager.getConnection(data); 67.65 + } catch (SQLException e) { 67.66 + throw new TemplateException 67.67 + (e.getMessage(), e, fdp.getTemplateReader()); 67.68 + } 67.69 + 67.70 + fdp.getContext().set(arg0, connection); 67.71 + 67.72 + out.write(arg0); 67.73 + return 1; 67.74 + } 67.75 + }; 67.76 + 67.77 + /* db_prepare:qury_name connection sql_statement */ 67.78 + public static final Function PREPARE = new Function() { 67.79 + public int invoke(FunctionDataParser fdp, Writer out) 67.80 + throws IOException, TemplateException { 67.81 + 67.82 + String arg0 = fdp.getNextArg(); // resulting variable 67.83 + String arg1 = fdp.getNextArg(); // connection 67.84 + String data = fdp.getData(); // statement 67.85 + 67.86 + Connection connection; 67.87 + PreparedStatement statement; 67.88 + 67.89 + try { 67.90 + connection = (Connection) fdp.getContext().get(arg1); 67.91 + statement = connection.prepareStatement(data); 67.92 + } catch (ClassCastException e) { 67.93 + throw new TemplateException 67.94 + (e.getMessage(), e, fdp.getTemplateReader()); 67.95 + } catch (SQLException e) { 67.96 + throw new TemplateException 67.97 + (e.getMessage(), e, fdp.getTemplateReader()); 67.98 + } 67.99 + 67.100 + fdp.getContext().set(arg0, statement); 67.101 + 67.102 + out.write(arg0); 67.103 + return 1; 67.104 + } 67.105 + }; 67.106 + 67.107 + /* db_query:sql_query template arg1 arg2 ... argN */ 67.108 + public static final Function QUERY = new Function() { 67.109 + public int invoke(FunctionDataParser fdp, Writer out) 67.110 + throws IOException, TemplateException { 67.111 + 67.112 + String query = fdp.getNextArg(); 67.113 + String template = fdp.getNextArg(); 67.114 + List<String> args = fdp.getArgs(); 67.115 + 67.116 + TemplateParser tp = fdp.getTemplateParser(); 67.117 + Context context = fdp.getContext(); 67.118 + 67.119 + try { 67.120 + PreparedStatement statement = 67.121 + (PreparedStatement) context.get(query); 67.122 + return query(template, fdp.getTemplateReader(), 67.123 + statement, args, tp, out); 67.124 + } catch (ClassCastException e) { 67.125 + throw new TemplateException 67.126 + (e.getMessage(), e, fdp.getTemplateReader()); 67.127 + } catch (SQLException e) { 67.128 + throw new TemplateException 67.129 + (e.getMessage(), e, fdp.getTemplateReader()); 67.130 + } 67.131 + } 67.132 + }; 67.133 + 67.134 + /** 67.135 + * Process database query. 67.136 + * 67.137 + * @param template template to fill with data. 67.138 + * @param parentReader parent TemplateReader. 67.139 + * @param ps query statement to execute. 67.140 + * @param args list of query parameters. 67.141 + * @param superParser invoking object. 67.142 + * @param out Writer to output processed data. 67.143 + * 67.144 + * @return number of processed rows in query result. 67.145 + */ 67.146 + private static int query(String template, 67.147 + TemplateReader parentReader, 67.148 + PreparedStatement ps, 67.149 + List<String> args, 67.150 + TemplateParser superParser, 67.151 + Writer out) 67.152 + throws IOException, SQLException, TemplateException { 67.153 + 67.154 + int i = 1; 67.155 + 67.156 + for (String arg : args) { 67.157 + ps.setString(i++, arg); 67.158 + } 67.159 + 67.160 + ResultSet resultSet = ps.executeQuery(); 67.161 + ResultSetMetaData metaData = resultSet.getMetaData(); 67.162 + int columnCount = metaData.getColumnCount(); 67.163 + 67.164 + String[] names = new String[columnCount]; 67.165 + 67.166 + for (int j = 0; j < columnCount; j++) { 67.167 + names[j] = metaData.getColumnName(j + 1); 67.168 + } 67.169 + 67.170 + final TemplateParser p = new TemplateParser(superParser); 67.171 + final HashMap<String, Object> fields = new HashMap<String, Object>(); 67.172 + 67.173 + p.getContext().set("db", new Function() { 67.174 + public int invoke(FunctionDataParser fdp, 67.175 + final Writer out) 67.176 + throws IOException, TemplateException { 67.177 + 67.178 + String name = fdp.getData(); 67.179 + Object value = fields.get(name); 67.180 + 67.181 + return p.parseValue(value, out); 67.182 + } 67.183 + }); 67.184 + 67.185 + Reader input = new StringReader(template); 67.186 + 67.187 + for (i = 1; resultSet.next(); i++) { 67.188 + 67.189 + for (int j = 0; j < columnCount; j++) { 67.190 + Object value = resultSet.getObject(j + 1); 67.191 + if (resultSet.wasNull()) value = null; 67.192 + 67.193 + fields.put(names[j], value); 67.194 + } 67.195 + 67.196 + p.getContext().set("db_row", i); 67.197 + 67.198 + TemplateReader tr = new TemplateReader(input, parentReader); 67.199 + 67.200 + p.parse(tr, out); 67.201 + 67.202 + input.reset(); 67.203 + fields.clear(); 67.204 + } 67.205 + 67.206 + resultSet.close(); 67.207 + input.close(); 67.208 + ps.clearParameters(); 67.209 + return i - 1; 67.210 + } 67.211 +}
68.1 --- a/src/kryshen/tema/functions/Define.java Thu Dec 14 23:22:05 2006 +0300 68.2 +++ b/src/kryshen/tema/functions/Define.java Tue Feb 19 20:32:17 2008 +0300 68.3 @@ -1,84 +1,126 @@ 68.4 /* 68.5 - * Copyright (C) 2006 Mikhail A. Kryshen 68.6 + * Copyright 2006-2008 Mikhail Kryshen 68.7 * 68.8 - * This program is free software; you can redistribute it and/or modify 68.9 - * it under the terms of the GNU General Public License as published by 68.10 - * the Free Software Foundation; either version 2 of the License, or 68.11 - * (at your option) any later version. 68.12 + * This file is part of Tema. 68.13 * 68.14 - * This program is distributed in the hope that it will be useful, 68.15 + * Tema is free software: you can redistribute it and/or modify it 68.16 + * under the terms of the GNU Lesser General Public License as 68.17 + * published by the Free Software Foundation, either version 3 of the 68.18 + * License, or (at your option) any later version. 68.19 + * 68.20 + * Tema is distributed in the hope that it will be useful, 68.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 68.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 68.23 - * GNU General Public License for more details. 68.24 + * GNU Lesser General Public License for more details. 68.25 * 68.26 - * You should have received a copy of the GNU General Public License 68.27 - * along with this program; if not, write to the Free Software 68.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 68.29 + * You should have received a copy of the 68.30 + * GNU Lesser General Public License along with Tema. 68.31 + * If not, see <http://www.gnu.org/licenses/>. 68.32 * 68.33 - * $Id: Define.java,v 1.7 2006/12/14 14:35:00 mikhail Exp $ 68.34 + * $Id: Define.java,v 1.25 2008/02/17 23:58:01 mikhail Exp $ 68.35 */ 68.36 68.37 package kryshen.tema.functions; 68.38 68.39 -import java.io.*; 68.40 -import java.util.*; 68.41 - 68.42 -import kryshen.tema.*; 68.43 +import java.io.IOException; 68.44 +import java.io.StringReader; 68.45 +import java.io.StringWriter; 68.46 +import java.io.Writer; 68.47 +import kryshen.tema.Context; 68.48 +import kryshen.tema.Function; 68.49 +import kryshen.tema.FunctionDataParser; 68.50 +import kryshen.tema.TemplateException; 68.51 +import kryshen.tema.TemplateParser; 68.52 +import kryshen.tema.io.TemplateReader; 68.53 68.54 /** 68.55 * Define function implementation. 68.56 * 68.57 - * @author Mikhail A. Kryshen 68.58 + * @author Mikhail Kryshen 68.59 */ 68.60 public class Define extends Function { 68.61 public static final Function DEFINE = new Define(); 68.62 - 68.63 + 68.64 public Define() { 68.65 } 68.66 - 68.67 + 68.68 public int invoke(FunctionDataParser fdp, Writer out) 68.69 - throws IOException, TemplateException { 68.70 + throws IOException, TemplateException { 68.71 68.72 - final String arg0 = fdp.getNextArg(); 68.73 - final String data = fdp.getData(); 68.74 - 68.75 + StringWriter nameWriter = new StringWriter(); 68.76 + int r = fdp.parseNextArg(nameWriter); 68.77 + 68.78 + if (r == 0) 68.79 + return 0; 68.80 + 68.81 + StringWriter dataWriter = new StringWriter(); 68.82 + r = fdp.parseData(dataWriter); 68.83 + 68.84 + if (r == 0) 68.85 + return 0; 68.86 + 68.87 + final String name = nameWriter.toString(); 68.88 + final String data = dataWriter.toString(); 68.89 + 68.90 Function newFunction = new Function() { 68.91 - public int invoke(final FunctionDataParser fdp, final Writer out) 68.92 - throws IOException, TemplateException { 68.93 - 68.94 - TemplateParser functionParser = 68.95 - new TemplateParser(fdp.getTemplateParser()); 68.96 - 68.97 - functionParser.registerFunction 68.98 - ("nextarg", new Function() { 68.99 - public int invoke(FunctionDataParser unusedFdp, 68.100 - final Writer out) 68.101 - throws IOException, TemplateException { 68.102 - 68.103 - return fdp.parseNextArg(out); 68.104 - } 68.105 - }); 68.106 - 68.107 - functionParser.registerFunction 68.108 - ("data",new Function() { 68.109 - public int invoke(FunctionDataParser unusedFdp, 68.110 - final Writer out) 68.111 - throws IOException, TemplateException { 68.112 - 68.113 - return fdp.parseData(out); 68.114 - } 68.115 - }); 68.116 - 68.117 - TemplateReader dataReader = new TemplateReader 68.118 - (new StringReader(data), fdp.getTemplateReader()); 68.119 - 68.120 - return functionParser.parse(dataReader, out); 68.121 - } 68.122 - }; 68.123 - 68.124 - fdp.getTemplateParser().registerFunction(arg0, newFunction); 68.125 - 68.126 - out.write(arg0); 68.127 - return 1; 68.128 + public int invoke(final FunctionDataParser fdp1, final Writer out) 68.129 + throws IOException, TemplateException { 68.130 + 68.131 + final TemplateParser functionParser = 68.132 + new TemplateParser(fdp1.getTemplateParser()); 68.133 + 68.134 + final Context functionContext = 68.135 + functionParser.getContext(); 68.136 + 68.137 + functionContext.set 68.138 + ("next_arg", new Function() { 68.139 + public int invoke(FunctionDataParser unusedFdp, 68.140 + final Writer out) 68.141 + throws IOException, TemplateException { 68.142 + 68.143 + if (fdp1.hasMoreData()) 68.144 + return fdp1.parseNextArg(out); 68.145 + 68.146 + return 0; 68.147 + } 68.148 + }); 68.149 + 68.150 + functionContext.set 68.151 + ("data", new Function() { 68.152 + public int invoke(FunctionDataParser unusedFdp, 68.153 + final Writer out) 68.154 + throws IOException, TemplateException { 68.155 + 68.156 + return fdp1.parseData(out); 68.157 + } 68.158 + }); 68.159 + 68.160 + functionContext.set 68.161 + ("has_more_data", new Function() { 68.162 + public int invoke(FunctionDataParser unusedFdp, 68.163 + final Writer out) 68.164 + throws IOException, TemplateException { 68.165 + 68.166 + if (fdp1.hasMoreData()) { 68.167 + out.write("true"); 68.168 + return 1; 68.169 + } 68.170 + 68.171 + out.write("false"); 68.172 + return 0; 68.173 + } 68.174 + }); 68.175 + 68.176 + TemplateReader dataReader = new TemplateReader 68.177 + (new StringReader(data), fdp1.getTemplateReader()); 68.178 + 68.179 + return functionParser.parse(dataReader, out); 68.180 + } 68.181 + }; 68.182 + 68.183 + fdp.getContext().set(name, newFunction); 68.184 + 68.185 + out.write(name); 68.186 + return r; 68.187 } 68.188 }
69.1 --- a/src/kryshen/tema/functions/IO.java Thu Dec 14 23:22:05 2006 +0300 69.2 +++ b/src/kryshen/tema/functions/IO.java Tue Feb 19 20:32:17 2008 +0300 69.3 @@ -1,133 +1,168 @@ 69.4 /* 69.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 69.6 + * Copyright 2006-2008 Mikhail Kryshen 69.7 * 69.8 - * This program is free software; you can redistribute it and/or modify 69.9 - * it under the terms of the GNU General Public License as published by 69.10 - * the Free Software Foundation; either version 2 of the License, or 69.11 - * (at your option) any later version. 69.12 + * This file is part of Tema. 69.13 * 69.14 - * This program is distributed in the hope that it will be useful, 69.15 + * Tema is free software: you can redistribute it and/or modify it 69.16 + * under the terms of the GNU Lesser General Public License as 69.17 + * published by the Free Software Foundation, either version 3 of the 69.18 + * License, or (at your option) any later version. 69.19 + * 69.20 + * Tema is distributed in the hope that it will be useful, 69.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 69.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 69.23 - * GNU General Public License for more details. 69.24 + * GNU Lesser General Public License for more details. 69.25 * 69.26 - * You should have received a copy of the GNU General Public License 69.27 - * along with this program; if not, write to the Free Software 69.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 69.29 + * You should have received a copy of the 69.30 + * GNU Lesser General Public License along with Tema. 69.31 + * If not, see <http://www.gnu.org/licenses/>. 69.32 * 69.33 - * $Id: IO.java,v 1.4 2006/12/14 15:59:49 mikhail Exp $ 69.34 + * $Id: IO.java,v 1.19 2008/02/19 16:21:00 mikhail Exp $ 69.35 */ 69.36 69.37 package kryshen.tema.functions; 69.38 69.39 -import java.io.*; 69.40 -import java.util.*; 69.41 - 69.42 -import kryshen.tema.*; 69.43 +import java.io.File; 69.44 +import java.io.FileInputStream; 69.45 +import java.io.FileOutputStream; 69.46 +import java.io.IOException; 69.47 +import java.io.InputStream; 69.48 +import java.io.OutputStream; 69.49 +import java.io.Reader; 69.50 +import java.io.Writer; 69.51 +import kryshen.tema.Function; 69.52 +import kryshen.tema.FunctionDataParser; 69.53 +import kryshen.tema.Tema; 69.54 +import kryshen.tema.TemplateException; 69.55 +import kryshen.tema.io.TemplateReader; 69.56 69.57 /** 69.58 * I/O functions. 69.59 */ 69.60 public class IO { 69.61 - public static final Function COPY = 69.62 - new Function() { 69.63 - public int invoke(FunctionDataParser fdp, Writer out) 69.64 - throws IOException, TemplateException { 69.65 - 69.66 - String arg0 = fdp.getNextArg(); 69.67 - String arg1 = fdp.getNextArg(); 69.68 - 69.69 - File source = new File 69.70 - (Tema.getProperty("resource_base"), arg0); 69.71 - File dest = new File(arg1); 69.72 - 69.73 - try { 69.74 - copyFile(source, dest); 69.75 - } catch (IOException e) { 69.76 - System.err.println(e); 69.77 - return 0; 69.78 - } 69.79 - out.write(arg1); 69.80 - return 1; 69.81 + /** 69.82 + * Copy files. 69.83 + */ 69.84 + public static final Function COPY = new Function() { 69.85 + public int invoke(FunctionDataParser fdp, Writer out) 69.86 + throws IOException, TemplateException { 69.87 + 69.88 + String arg0 = fdp.getNextArg(); 69.89 + String arg1 = fdp.getNextArg(); 69.90 + 69.91 + File source = fdp.createFile(arg0); 69.92 + File dest = fdp.createFile(arg1); 69.93 + 69.94 + try { 69.95 + copyFile(source, dest); 69.96 + } catch (IOException e) { 69.97 + System.err.println(e); 69.98 + return 0; 69.99 } 69.100 - }; 69.101 - 69.102 - public static final Function WRITE = 69.103 - new Function() { 69.104 - public int invoke(FunctionDataParser fdp, Writer out) 69.105 - throws IOException, TemplateException { 69.106 - 69.107 - String arg0 = fdp.getNextArg(); 69.108 - 69.109 - System.err.println("Writing " + arg0 + "..."); 69.110 - 69.111 - Writer fw; 69.112 - 69.113 - try { 69.114 - fw = Tema.createFileWriter(arg0); 69.115 - } catch (IOException e) { 69.116 - System.err.println(e); 69.117 - //throw new TemplateException(e.getMessage(), e, in); 69.118 - return 0; 69.119 - } 69.120 - 69.121 - try { 69.122 - fdp.parseData(fw); 69.123 - } finally { 69.124 - fw.close(); 69.125 - } 69.126 - 69.127 - out.write(arg0); 69.128 - 69.129 - System.err.println("Saved " + arg0 + "."); 69.130 - return 1; 69.131 + out.write(arg1); 69.132 + return 1; 69.133 + } 69.134 + }; 69.135 + 69.136 + /** 69.137 + * Write data to file. 69.138 + */ 69.139 + public static final Function WRITE = new Function() { 69.140 + public int invoke(FunctionDataParser fdp, Writer out) 69.141 + throws IOException, TemplateException { 69.142 + 69.143 + String arg0 = fdp.getNextArg(); 69.144 + 69.145 + System.err.println("Writing " + arg0 + "..."); 69.146 + 69.147 + Writer fw; 69.148 + 69.149 + try { 69.150 + fw = Tema.createFileWriter(fdp.createFile(arg0)); 69.151 + } catch (IOException e) { 69.152 + System.err.println(e); 69.153 + //throw new TemplateException(e.getMessage(), e, in); 69.154 + return 0; 69.155 } 69.156 - }; 69.157 - 69.158 - public static final Function READ = 69.159 - new Function() { 69.160 - public int invoke(FunctionDataParser fdp, Writer out) 69.161 - throws IOException, TemplateException { 69.162 - 69.163 - String filename = fdp.getData(); 69.164 - String file; 69.165 - 69.166 - try { 69.167 - file = Tema.readFile(new File(filename)); 69.168 - } catch (IOException e) { 69.169 - System.err.println(e); 69.170 - //throw new TemplateException(e.getMessage(), e, in); 69.171 - return 0; 69.172 - } 69.173 - 69.174 - out.write(file); 69.175 - return 1; 69.176 + 69.177 + try { 69.178 + fdp.parseData(fw); 69.179 + } finally { 69.180 + fw.close(); 69.181 } 69.182 - }; 69.183 - 69.184 - public static final Function INCLUDE = 69.185 - new Function() { 69.186 - public int invoke(FunctionDataParser fdp, Writer out) 69.187 - throws IOException, TemplateException { 69.188 - 69.189 - String filename = fdp.getData(); 69.190 - 69.191 - TemplateReader fin; 69.192 - 69.193 - try { 69.194 - fin = Tema.createTemplateReader(new File(filename)); 69.195 - } catch (IOException e) { 69.196 - throw new TemplateException(e.getMessage(), e, 69.197 - fdp.getTemplateReader()); 69.198 - } 69.199 - 69.200 - int r = fdp.getTemplateParser().parse(fin, out); 69.201 - 69.202 - fin.close(); 69.203 - return r; 69.204 + 69.205 + out.write(arg0); 69.206 + 69.207 + return 1; 69.208 + } 69.209 + }; 69.210 + 69.211 + /** 69.212 + * Read from file. 69.213 + */ 69.214 + public static final Function READ = new Function() { 69.215 + public int invoke(FunctionDataParser fdp, Writer out) 69.216 + throws IOException, TemplateException { 69.217 + 69.218 + String filename = fdp.getData(); 69.219 + String file; 69.220 + 69.221 + try { 69.222 + readFile(fdp.createFile(filename), out); 69.223 + } catch (IOException e) { 69.224 + System.err.println(e); 69.225 + //throw new TemplateException(e.getMessage(), e, in); 69.226 + return 0; 69.227 } 69.228 - }; 69.229 - 69.230 + 69.231 + return 1; 69.232 + } 69.233 + }; 69.234 + 69.235 + /** 69.236 + * Evaluate the code read from file. 69.237 + */ 69.238 + public static final Function INCLUDE = new Function() { 69.239 + public int invoke(FunctionDataParser fdp, Writer out) 69.240 + throws IOException, TemplateException { 69.241 + 69.242 + String filename = fdp.getData(); 69.243 + 69.244 + TemplateReader fin; 69.245 + 69.246 + try { 69.247 + fin = Tema.createTemplateReader(fdp.createFile(filename)); 69.248 + } catch (IOException e) { 69.249 + throw new TemplateException(e.getMessage(), e, 69.250 + fdp.getTemplateReader()); 69.251 + } 69.252 + 69.253 + int r = fdp.getTemplateParser().parse(fin, out); 69.254 + 69.255 + fin.close(); 69.256 + return r; 69.257 + } 69.258 + }; 69.259 + 69.260 + /** 69.261 + * Create path from base path and file name. 69.262 + */ 69.263 + public static final Function FILE = new Function() { 69.264 + public int invoke(FunctionDataParser fdp, Writer out) 69.265 + throws IOException, TemplateException { 69.266 + 69.267 + String base = fdp.getNextArg(); 69.268 + String name = fdp.getNextArg(); 69.269 + 69.270 + if (fdp.getLastReturnCode() == 0) 69.271 + return 0; 69.272 + 69.273 + out.write((new File(fdp.createFile(base), name)).getPath()); 69.274 + 69.275 + return fdp.getLastReturnCode(); 69.276 + } 69.277 + }; 69.278 + 69.279 /** 69.280 * Update file (copy if newer). 69.281 * 69.282 @@ -137,27 +172,51 @@ 69.283 * @trows IOException on copying error. 69.284 */ 69.285 private static void copyFile(File src, File dest) throws IOException { 69.286 - System.err.print("Copying " + src + "... "); 69.287 - 69.288 - if (src.lastModified() < dest.lastModified()) { 69.289 - System.err.println(dest + " is up to date."); 69.290 - return; 69.291 - } 69.292 - 69.293 - File parent = dest.getParentFile(); 69.294 - if (parent != null) parent.mkdirs(); 69.295 - 69.296 + System.err.print("Copying " + src + "... "); 69.297 + 69.298 + if (src.lastModified() < dest.lastModified()) { 69.299 + System.err.println(dest + " is up to date."); 69.300 + return; 69.301 + } 69.302 + 69.303 + File parent = dest.getParentFile(); 69.304 + if (parent != null) parent.mkdirs(); 69.305 + 69.306 InputStream in = new FileInputStream(src); 69.307 OutputStream out = new FileOutputStream(dest); 69.308 69.309 + copy(in, out); 69.310 + 69.311 + in.close(); 69.312 + out.close(); 69.313 + } 69.314 + 69.315 + private static void copy(InputStream in, OutputStream out) 69.316 + throws IOException { 69.317 + 69.318 byte[] buffer = new byte[1024]; 69.319 int len; 69.320 + 69.321 while ((len = in.read(buffer)) > 0) { 69.322 out.write(buffer, 0, len); 69.323 } 69.324 - in.close(); 69.325 - out.close(); 69.326 - 69.327 - System.err.println("saved " + dest + "."); 69.328 + } 69.329 + 69.330 + private static void copy(Reader in, Writer out) 69.331 + throws IOException { 69.332 + 69.333 + char[] buffer = new char[1024]; 69.334 + int len; 69.335 + 69.336 + while ((len = in.read(buffer)) > 0) { 69.337 + out.write(buffer, 0, len); 69.338 + } 69.339 + } 69.340 + 69.341 + private static void readFile(File src, Writer out) 69.342 + throws IOException { 69.343 + 69.344 + Reader in = Tema.createFileReader(src); 69.345 + copy(in, out); 69.346 } 69.347 }
70.1 --- a/src/kryshen/tema/functions/ImageConverter.java Thu Dec 14 23:22:05 2006 +0300 70.2 +++ b/src/kryshen/tema/functions/ImageConverter.java Tue Feb 19 20:32:17 2008 +0300 70.3 @@ -1,21 +1,23 @@ 70.4 /* 70.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 70.6 + * Copyright 2006-2008 Mikhail Kryshen 70.7 * 70.8 - * This program is free software; you can redistribute it and/or modify 70.9 - * it under the terms of the GNU General Public License as published by 70.10 - * the Free Software Foundation; either version 2 of the License, or 70.11 - * (at your option) any later version. 70.12 + * This file is part of Tema. 70.13 * 70.14 - * This program is distributed in the hope that it will be useful, 70.15 + * Tema is free software: you can redistribute it and/or modify it 70.16 + * under the terms of the GNU Lesser General Public License as 70.17 + * published by the Free Software Foundation, either version 3 of the 70.18 + * License, or (at your option) any later version. 70.19 + * 70.20 + * Tema is distributed in the hope that it will be useful, 70.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 70.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 70.23 - * GNU General Public License for more details. 70.24 + * GNU Lesser General Public License for more details. 70.25 * 70.26 - * You should have received a copy of the GNU General Public License 70.27 - * along with this program; if not, write to the Free Software 70.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 70.29 + * You should have received a copy of the 70.30 + * GNU Lesser General Public License along with Tema. 70.31 + * If not, see <http://www.gnu.org/licenses/>. 70.32 * 70.33 - * $Id: ImageConverter.java,v 1.4 2006/12/14 19:44:32 mikhail Exp $ 70.34 + * $Id: ImageConverter.java,v 1.13 2008/02/16 17:56:34 mikhail Exp $ 70.35 */ 70.36 70.37 package kryshen.tema.functions; 70.38 @@ -33,11 +35,11 @@ 70.39 /** 70.40 * Convert images to specified format. 70.41 * 70.42 - * @author Mikhail A. Kryshen 70.43 + * @author Mikhail Kryshen 70.44 */ 70.45 public class ImageConverter extends Function { 70.46 70.47 - public static final Function IMAGE = new ImageConverter(); 70.48 + public static final Function CONVERT_IMAGE = new ImageConverter(); 70.49 70.50 public int invoke(FunctionDataParser fdp, Writer out) 70.51 throws IOException, TemplateException { 70.52 @@ -49,14 +51,11 @@ 70.53 Integer.parseInt(fdp.getNextArg()) : -1; 70.54 int arg4 = fdp.hasMoreData() ? 70.55 Integer.parseInt(fdp.getNextArg()) : -1; 70.56 - 70.57 - File source = new File 70.58 - (Tema.getProperty("resource_base"), arg0); 70.59 - 70.60 + 70.61 try { 70.62 convert 70.63 - (source, /* source file */ 70.64 - new File(arg1), /* dest file */ 70.65 + (fdp.createFile(arg0), /* source file */ 70.66 + fdp.createFile(arg1), /* dest file */ 70.67 arg2, /* format */ 70.68 arg3, /* max width */ 70.69 arg4); /* max height */
71.1 --- a/src/kryshen/tema/functions/Logics.java Thu Dec 14 23:22:05 2006 +0300 71.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 71.3 @@ -1,75 +0,0 @@ 71.4 -/* 71.5 - * Copyright (C) 2006 Mikhail A. Kryshen 71.6 - * 71.7 - * This program is free software; you can redistribute it and/or modify 71.8 - * it under the terms of the GNU General Public License as published by 71.9 - * the Free Software Foundation; either version 2 of the License, or 71.10 - * (at your option) any later version. 71.11 - * 71.12 - * This program is distributed in the hope that it will be useful, 71.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 71.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 71.15 - * GNU General Public License for more details. 71.16 - * 71.17 - * You should have received a copy of the GNU General Public License 71.18 - * along with this program; if not, write to the Free Software 71.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 71.20 - * 71.21 - * $Id: Logics.java,v 1.6 2006/12/14 14:39:26 mikhail Exp $ 71.22 - */ 71.23 - 71.24 -package kryshen.tema.functions; 71.25 - 71.26 -import java.io.*; 71.27 -import java.util.*; 71.28 - 71.29 -import kryshen.tema.*; 71.30 - 71.31 -/** 71.32 - * Logical and conditional functions. 71.33 - * 71.34 - * @author Mikhail A. Kryshen 71.35 - */ 71.36 -public class Logics { 71.37 - public static final Function FALSE = 71.38 - new Function() { 71.39 - public int invoke(FunctionDataParser fdp, Writer out) 71.40 - throws IOException, TemplateException { 71.41 - 71.42 - fdp.parseData(out); 71.43 - return 0; 71.44 - } 71.45 - }; 71.46 - 71.47 - public static final Function TRUE = 71.48 - new Function() { 71.49 - public int invoke(FunctionDataParser fdp, Writer out) 71.50 - throws IOException, TemplateException { 71.51 - 71.52 - fdp.parseData(out); 71.53 - return 1; 71.54 - } 71.55 - }; 71.56 - 71.57 - /** 71.58 - * Outputs it's data it has non-zero value. 71.59 - */ 71.60 - public static final Function OPTIONAL = 71.61 - new Function() { 71.62 - public int invoke(FunctionDataParser fdp, Writer out) 71.63 - throws IOException, TemplateException { 71.64 - 71.65 - StringWriter sw = new StringWriter(); 71.66 - int s = fdp.parseData(sw); 71.67 - sw.close(); 71.68 - String data = sw.toString(); 71.69 - 71.70 - if (s != 0) { 71.71 - out.write(data); 71.72 - return 1; 71.73 - } else { 71.74 - return 0; 71.75 - } 71.76 - } 71.77 - }; 71.78 -}
72.1 --- a/src/kryshen/tema/functions/ReplaceWriter.java Thu Dec 14 23:22:05 2006 +0300 72.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 72.3 @@ -1,154 +0,0 @@ 72.4 -/* 72.5 - * Copyright (C) 2006 Mikhail A. Kryshen 72.6 - * 72.7 - * This program is free software; you can redistribute it and/or modify 72.8 - * it under the terms of the GNU General Public License as published by 72.9 - * the Free Software Foundation; either version 2 of the License, or 72.10 - * (at your option) any later version. 72.11 - * 72.12 - * This program is distributed in the hope that it will be useful, 72.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 72.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 72.15 - * GNU General Public License for more details. 72.16 - * 72.17 - * You should have received a copy of the GNU General Public License 72.18 - * along with this program; if not, write to the Free Software 72.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 72.20 - * 72.21 - * $Id: ReplaceWriter.java,v 1.2 2006/12/14 14:39:26 mikhail Exp $ 72.22 - */ 72.23 - 72.24 -package kryshen.tema.functions; 72.25 - 72.26 -import java.io.Writer; 72.27 -import java.io.FilterWriter; 72.28 -import java.io.IOException; 72.29 - 72.30 -import java.util.LinkedList; 72.31 -import java.util.Iterator; 72.32 - 72.33 -/** 72.34 - * FilterWriter which replaces characters with escape strings. 72.35 - * 72.36 - * @author Mikhail A. Kryshen 72.37 - */ 72.38 -class ReplaceWriter extends FilterWriter { 72.39 - private String[] patterns; 72.40 - private String[] replaces; 72.41 - 72.42 - private String prefix; 72.43 - private String postfix; 72.44 - 72.45 - private int maxPatternLength = 0; 72.46 - 72.47 - /** Have this Writer processed any data? */ 72.48 - private boolean processedData = false; 72.49 - 72.50 - private StringBuffer buffer = new StringBuffer(); 72.51 - 72.52 - public ReplaceWriter(Writer w, String pattern, String replace) { 72.53 - this(w, new String[]{pattern}, new String[]{replace}); 72.54 - } 72.55 - 72.56 - public ReplaceWriter(Writer w, String pattern, String replace, 72.57 - String prefix, String postfix) { 72.58 - 72.59 - this(w, new String[]{pattern}, new String[]{replace}, 72.60 - prefix, postfix); 72.61 - } 72.62 - 72.63 - public ReplaceWriter(Writer w, String[] patterns, String[] replaces) { 72.64 - this(w, patterns, replaces, null, null); 72.65 - } 72.66 - 72.67 - public ReplaceWriter(Writer w, String[] patterns, String[] replaces, 72.68 - String prefix, String postfix) { 72.69 - super(w); 72.70 - 72.71 - this.patterns = patterns; 72.72 - this.replaces = replaces; 72.73 - 72.74 - this.prefix = prefix; 72.75 - this.postfix = postfix; 72.76 - 72.77 - for (int i = 0; i < patterns.length; i++) { 72.78 - int length = patterns[i].length(); 72.79 - if (length > maxPatternLength) 72.80 - maxPatternLength = length; 72.81 - } 72.82 - } 72.83 - 72.84 - private boolean processBuffer(int minLength) throws IOException { 72.85 - if (buffer.length() == 0) return false; 72.86 - 72.87 - if (!processedData) { 72.88 - if (prefix != null) 72.89 - super.write(prefix, 0, prefix.length()); 72.90 - processedData = true; 72.91 - } 72.92 - 72.93 - int k; 72.94 - for (k = 0; minLength + k < buffer.length(); k++) { 72.95 - for (int i = 0; i < patterns.length; i++) { 72.96 - String pattern = patterns[i]; 72.97 - int length = pattern.length(); 72.98 - 72.99 - if (length + k > buffer.length()) 72.100 - continue; 72.101 - 72.102 - boolean match = true; 72.103 - 72.104 - for (int j = 0; j < length; j++) { 72.105 - if (pattern.charAt(j) != buffer.charAt(j + k)) { 72.106 - match = false; 72.107 - break; 72.108 - } 72.109 - } 72.110 - 72.111 - if (match) { 72.112 - super.write(buffer.substring(0, k), 0, k); 72.113 - buffer.delete(0, k + length); 72.114 - super.write(replaces[i], 0, replaces[i].length()); 72.115 - return true; 72.116 - } 72.117 - } 72.118 - } 72.119 - 72.120 - super.write(buffer.substring(0, k), 0, k); 72.121 - buffer.delete(0, k); 72.122 - 72.123 - return false; 72.124 - } 72.125 - 72.126 - public void write(int c) throws IOException { 72.127 - buffer.append((char)c); 72.128 - processBuffer(maxPatternLength); 72.129 - } 72.130 - 72.131 - public void write(char[] cbuf, int off, int len) throws IOException { 72.132 - for (int i = off; i < off + len; i++) { 72.133 - buffer.append(cbuf[i]); 72.134 - } 72.135 - processBuffer(maxPatternLength); 72.136 - } 72.137 - 72.138 - public void write(String str, int off, int len) throws IOException { 72.139 - buffer.append(str.substring(off, off + len)); 72.140 - processBuffer(maxPatternLength); 72.141 - } 72.142 - 72.143 - public void finish() throws IOException { 72.144 - while (processBuffer(0)); 72.145 - 72.146 -// super.write(buffer.toString(), 0, buffer.length()); 72.147 -// buffer.delete(0, buffer.length()); 72.148 - 72.149 - if (processedData && postfix != null) 72.150 - super.write(postfix, 0, postfix.length()); 72.151 - } 72.152 - 72.153 - public void close() throws IOException { 72.154 - finish(); 72.155 - super.close(); 72.156 - } 72.157 -}
73.1 --- a/src/kryshen/tema/functions/Standard.java Thu Dec 14 23:22:05 2006 +0300 73.2 +++ b/src/kryshen/tema/functions/Standard.java Tue Feb 19 20:32:17 2008 +0300 73.3 @@ -1,258 +1,259 @@ 73.4 /* 73.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 73.6 + * Copyright 2006-2008 Mikhail Kryshen 73.7 * 73.8 - * This program is free software; you can redistribute it and/or modify 73.9 - * it under the terms of the GNU General Public License as published by 73.10 - * the Free Software Foundation; either version 2 of the License, or 73.11 - * (at your option) any later version. 73.12 + * This file is part of Tema. 73.13 * 73.14 - * This program is distributed in the hope that it will be useful, 73.15 + * Tema is free software: you can redistribute it and/or modify it 73.16 + * under the terms of the GNU Lesser General Public License as 73.17 + * published by the Free Software Foundation, either version 3 of the 73.18 + * License, or (at your option) any later version. 73.19 + * 73.20 + * Tema is distributed in the hope that it will be useful, 73.21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 73.22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 73.23 - * GNU General Public License for more details. 73.24 + * GNU Lesser General Public License for more details. 73.25 * 73.26 - * You should have received a copy of the GNU General Public License 73.27 - * along with this program; if not, write to the Free Software 73.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 73.29 + * You should have received a copy of the 73.30 + * GNU Lesser General Public License along with Tema. 73.31 + * If not, see <http://www.gnu.org/licenses/>. 73.32 * 73.33 - * $Id: Standard.java,v 1.5 2006/12/14 14:39:26 mikhail Exp $ 73.34 + * $Id: Standard.java,v 1.34 2008/02/19 17:32:17 mikhail Exp $ 73.35 */ 73.36 73.37 package kryshen.tema.functions; 73.38 73.39 -import java.io.*; 73.40 -import java.util.*; 73.41 -import java.net.*; 73.42 - 73.43 -import java.sql.SQLException; 73.44 -import java.sql.PreparedStatement; 73.45 - 73.46 -import kryshen.tema.*; 73.47 +import java.io.IOException; 73.48 +import java.io.Writer; 73.49 +import java.net.URL; 73.50 +import java.net.URLClassLoader; 73.51 +import java.util.ArrayList; 73.52 +import java.util.List; 73.53 +import kryshen.tema.Context; 73.54 +import kryshen.tema.Function; 73.55 +import kryshen.tema.FunctionDataParser; 73.56 +import kryshen.tema.Tema; 73.57 +import kryshen.tema.TemplateException; 73.58 +import kryshen.tema.io.NullWriter; 73.59 73.60 /** 73.61 * Standard TEMA functions. 73.62 */ 73.63 public class Standard { 73.64 - public static final Function SET = 73.65 - new Function() { 73.66 - public int invoke(FunctionDataParser fdp, Writer out) 73.67 + 73.68 + /** 73.69 + * Output Tema version. 73.70 + */ 73.71 + public static final Function TEMA = new Function() { 73.72 + public int invoke(FunctionDataParser fdp, Writer out) 73.73 + throws IOException, TemplateException { 73.74 + out.write(Tema.TITLE + " " + Tema.VERSION 73.75 + /*+ " by " + Tema.AUTHOR*/); 73.76 + return 1; 73.77 + } 73.78 + }; 73.79 + 73.80 + /** 73.81 + * Define static variable. 73.82 + */ 73.83 + public static final Function SET = new Function() { 73.84 + public int invoke(FunctionDataParser fdp, Writer out) 73.85 + throws IOException, TemplateException { 73.86 + 73.87 + String name = fdp.getNextArg(); 73.88 + 73.89 + if (fdp.getLastReturnCode() == 0) 73.90 + return 0; 73.91 + 73.92 + String data = fdp.getData(out); 73.93 + fdp.getContext().set(name, data); 73.94 + 73.95 + return fdp.getLastReturnCode(); 73.96 + } 73.97 + }; 73.98 + 73.99 + /** 73.100 + * Recursively remove definition. 73.101 + */ 73.102 + public static final Function UNSET = new Function() { 73.103 + public int invoke(FunctionDataParser fdp, Writer out) 73.104 + throws IOException, TemplateException { 73.105 + 73.106 + int r = 0; 73.107 + 73.108 + while (fdp.hasMoreData()) { 73.109 + String name = fdp.getNextArg(); 73.110 + 73.111 + if (fdp.getLastReturnCode() == 0) 73.112 + continue; 73.113 + 73.114 + if (fdp.getContext().unset(name)) 73.115 + r++; 73.116 + } 73.117 + 73.118 + return r; 73.119 + } 73.120 + }; 73.121 + 73.122 + /** 73.123 + * Export variable to the global (outermost) context. 73.124 + */ 73.125 + public static final Function EXPORT = new Function() { 73.126 + public int invoke(FunctionDataParser fdp, 73.127 + final Writer out) 73.128 throws IOException, TemplateException { 73.129 - 73.130 - String arg0 = fdp.getNextArg(); 73.131 - String arg1 = fdp.getData(); 73.132 + 73.133 + String name = fdp.getNextArg(); 73.134 + 73.135 + if (fdp.getLastReturnCode() == 0) 73.136 + return 0; 73.137 + 73.138 + // Set and export. 73.139 + if (fdp.hasMoreData()) { 73.140 + Object value = fdp.getData(out); 73.141 73.142 - fdp.getTemplateParser().setValue(arg0, arg1); 73.143 - 73.144 - out.write(arg0); 73.145 - return 1; 73.146 + fdp.getContext().export(name, value); 73.147 + return fdp.getLastReturnCode(); 73.148 } 73.149 - }; 73.150 - 73.151 - /* prepare:qury_name sql_statement */ 73.152 - public static final Function PREPARE = 73.153 - new Function() { 73.154 - public int invoke(FunctionDataParser fdp, Writer out) 73.155 - throws IOException, TemplateException { 73.156 - 73.157 - String arg0 = fdp.getNextArg(); 73.158 - String data = fdp.getData(); 73.159 - 73.160 - PreparedStatement statement; 73.161 - 73.162 - try { 73.163 - statement = Tema.getDbConnection() 73.164 - .prepareStatement(data); 73.165 - } catch (SQLException e) { 73.166 - throw new TemplateException 73.167 - (e.getMessage(), e, fdp.getTemplateReader()); 73.168 - } 73.169 - 73.170 - fdp.getTemplateParser().setValue(arg0, statement); 73.171 - 73.172 - out.write(arg0); 73.173 - return 1; 73.174 - } 73.175 - }; 73.176 - 73.177 - /* query:sql_query template arg1 arg2 ... argN */ 73.178 - public static final Function QUERY = 73.179 - new Function() { 73.180 - public int invoke(FunctionDataParser fdp, Writer out) 73.181 - throws IOException, TemplateException { 73.182 - 73.183 - String arg0 = fdp.getNextArg(); 73.184 - String arg1 = fdp.getNextArg(); 73.185 - List<String> args = fdp.getArgs(); 73.186 - 73.187 - TemplateParser tp = fdp.getTemplateParser(); 73.188 - 73.189 - TemplateReader tr = 73.190 - new TemplateReader(new StringReader(arg1), 73.191 - fdp.getTemplateReader()); 73.192 - 73.193 - try { 73.194 - return Tema.query 73.195 - (tr, (PreparedStatement)tp.getValue(arg0), 73.196 - args, tp, out); 73.197 - } catch (SQLException e) { 73.198 - throw new TemplateException 73.199 - (e.getMessage(), e, fdp.getTemplateReader()); 73.200 - } 73.201 - } 73.202 - }; 73.203 - 73.204 - public static final Function REPLACE = 73.205 - new Function() { 73.206 - public int invoke(FunctionDataParser fdp, Writer out) 73.207 - throws IOException, TemplateException { 73.208 - 73.209 - String arg0 = fdp.getNextArg(); 73.210 - String arg1 = fdp.getNextArg(); 73.211 - 73.212 - ReplaceWriter rw = new ReplaceWriter(out, arg0, arg1); 73.213 - 73.214 - int ret = fdp.parseData(rw); 73.215 - rw.finish(); 73.216 - return ret; 73.217 - } 73.218 - }; 73.219 - 73.220 - public static final Function LOAD = 73.221 - 73.222 - new Function() { 73.223 - public int invoke(FunctionDataParser fdp, Writer out) 73.224 - throws IOException, TemplateException { 73.225 - 73.226 - final String name = fdp.getNextArg(); 73.227 - final String className = fdp.getNextArg(); 73.228 - 73.229 - List<URL> urls = new ArrayList<URL>(1); 73.230 - 73.231 - while (fdp.hasMoreData()) { 73.232 - urls.add(new URL(fdp.getNextArg())); 73.233 - } 73.234 - 73.235 - ClassLoader loader = this.getClass().getClassLoader(); 73.236 - 73.237 - if (urls.size() > 0) { 73.238 - loader = new URLClassLoader 73.239 - (urls.toArray(new URL[0]), loader); 73.240 - } 73.241 - 73.242 - Class<Function> functionClass; 73.243 - Function function; 73.244 - 73.245 - try { 73.246 - functionClass = loadFunctionClass(loader, className); 73.247 - } catch (ClassNotFoundException e) { 73.248 - throw new TemplateException 73.249 - ("Class not found", e, fdp.getTemplateReader()); 73.250 - } catch (ClassCastException e) { 73.251 - throw new TemplateException 73.252 - ("Not a function class", e, fdp.getTemplateReader()); 73.253 - } 73.254 - 73.255 - try { 73.256 - function = functionClass.newInstance(); 73.257 - } catch (InstantiationException e) { 73.258 - throw new TemplateException 73.259 - ("Could not load class", e, fdp.getTemplateReader()); 73.260 - } catch (IllegalAccessException e) { 73.261 - throw new TemplateException 73.262 - ("Could not load class", e, fdp.getTemplateReader()); 73.263 - } 73.264 - 73.265 - fdp.getTemplateParser().registerFunction(name, function); 73.266 - 73.267 - 73.268 + 73.269 + // Only export. 73.270 + if (fdp.getContext().export(name)) { 73.271 out.write(name); 73.272 return 1; 73.273 } 73.274 - }; 73.275 + 73.276 + return 0; 73.277 + } 73.278 + }; 73.279 + 73.280 + /** 73.281 + * Copy macro definitions. 73.282 + */ 73.283 + public static final Function ASSIGN = new Function() { 73.284 + public int invoke(FunctionDataParser fdp, Writer out) 73.285 + throws IOException, TemplateException { 73.286 73.287 - public static final Function NULL_OUTPUT = 73.288 - new Function() { 73.289 - public int invoke(FunctionDataParser fdp, Writer out) 73.290 - throws IOException, TemplateException { 73.291 + String name1 = fdp.getNextArg(); 73.292 73.293 - /* Write nothing. */ 73.294 - return fdp.parseData(new Writer() { 73.295 - public void close() {} 73.296 - public void flush() {} 73.297 - public void write(char[] cbuf, int off, int len) {} 73.298 - }); 73.299 + if (fdp.getLastReturnCode() == 0) 73.300 + return 0; 73.301 + 73.302 + String name2 = fdp.getData(); 73.303 + 73.304 + if (fdp.getLastReturnCode() == 0) 73.305 + return 0; 73.306 + 73.307 + Context context = fdp.getContext(); 73.308 + Object value = context.get(name2); 73.309 + 73.310 + if (value == null) 73.311 + return 0; 73.312 + 73.313 + context.set(name1, value); 73.314 + 73.315 + return 1; 73.316 + } 73.317 + }; 73.318 + 73.319 + /** 73.320 + * Invoke function specified by name. 73.321 + */ 73.322 + public static final Function INVOKE = new Function() { 73.323 + public int invoke(FunctionDataParser fdp, Writer out) 73.324 + throws IOException, TemplateException { 73.325 + 73.326 + String name = fdp.getNextArg(); 73.327 + 73.328 + if (fdp.getLastReturnCode() == 0) 73.329 + return 0; 73.330 + 73.331 + return fdp.getTemplateParser().invoke(name, fdp, out); 73.332 + } 73.333 + }; 73.334 + 73.335 + /** 73.336 + * Create definiton as a new Java object. 73.337 + */ 73.338 + public static final Function LOAD = new Function() { 73.339 + public int invoke(FunctionDataParser fdp, Writer out) 73.340 + throws IOException, TemplateException { 73.341 + 73.342 + final String name = fdp.getNextArg(); 73.343 + final String className = fdp.getNextArg(); 73.344 + 73.345 + List<URL> urls = new ArrayList<URL>(1); 73.346 + 73.347 + while (fdp.hasMoreData()) { 73.348 + urls.add(new URL(fdp.getNextArg())); 73.349 } 73.350 - }; 73.351 - 73.352 - public static final Function XML_ESCAPE = 73.353 - new Function() { 73.354 - public int invoke(FunctionDataParser fdp, Writer out) 73.355 - throws IOException, TemplateException { 73.356 - 73.357 - final String[] chars = {"&", "<", ">", "`", "\""}; 73.358 - final String[] escape = {"&", "<", ">", "'", """}; 73.359 - 73.360 - ReplaceWriter rw = new ReplaceWriter(out, chars, escape); 73.361 - 73.362 - int ret = fdp.parseData(rw); 73.363 - rw.finish(); 73.364 - return ret; 73.365 + 73.366 + ClassLoader loader = this.getClass().getClassLoader(); 73.367 + 73.368 + if (urls.size() > 0) { 73.369 + loader = new URLClassLoader 73.370 + (urls.toArray(new URL[0]), loader); 73.371 } 73.372 - }; 73.373 - 73.374 - public static final Function XML_CDATA = 73.375 - new Function() { 73.376 - public int invoke(FunctionDataParser fdp, Writer out) 73.377 - throws IOException, TemplateException { 73.378 - 73.379 - ReplaceWriter rw = new ReplaceWriter 73.380 - (out, "]]>", "]]]><![CDATA[]>", "<![CDATA[", "]]>"); 73.381 - 73.382 - int ret = fdp.parseData(rw); 73.383 - rw.finish(); 73.384 - return ret; 73.385 + 73.386 + Class<?> loadedClass; 73.387 + Object instance; 73.388 + 73.389 + try { 73.390 + loadedClass = loader.loadClass(className); 73.391 + } catch (ClassNotFoundException e) { 73.392 + throw new TemplateException 73.393 + ("Class not found", e, fdp.getTemplateReader()); 73.394 } 73.395 - }; 73.396 - 73.397 - 73.398 - @SuppressWarnings("unchecked") 73.399 - private static Class<Function> loadFunctionClass 73.400 - (ClassLoader loader, String className) 73.401 - throws ClassNotFoundException { 73.402 - 73.403 - return (Class<Function>)loader.loadClass(className); 73.404 - } 73.405 - 73.406 + 73.407 + try { 73.408 + instance = loadedClass.newInstance(); 73.409 + } catch (InstantiationException e) { 73.410 + throw new TemplateException 73.411 + ("Could not load class", e, fdp.getTemplateReader()); 73.412 + } catch (IllegalAccessException e) { 73.413 + throw new TemplateException 73.414 + ("Could not load class", e, fdp.getTemplateReader()); 73.415 + } 73.416 + 73.417 + fdp.getContext().set(name, instance); 73.418 + 73.419 + out.write(name); 73.420 + return 1; 73.421 + } 73.422 + }; 73.423 + 73.424 + public static final Function ECHO = new Function() { 73.425 + public int invoke(FunctionDataParser fdp, Writer out) 73.426 + throws IOException, TemplateException { 73.427 + 73.428 + if (!fdp.hasMoreData()) 73.429 + return 0; 73.430 + 73.431 + return fdp.parseData(out); 73.432 + } 73.433 + }; 73.434 + 73.435 /** 73.436 - * Update file (copy if newer). 73.437 - * 73.438 - * @param src source file. 73.439 - * @param dest destination file. 73.440 - * 73.441 - * @trows IOException on copying error. 73.442 + * Process arguments, but output nothing. 73.443 */ 73.444 - private static void copyFile(File src, File dest) throws IOException { 73.445 - System.err.print("Copying " + src + "... "); 73.446 - 73.447 - if (src.lastModified() < dest.lastModified()) { 73.448 - System.err.println(dest + " is up to date."); 73.449 - return; 73.450 - } 73.451 - 73.452 - File parent = dest.getParentFile(); 73.453 - if (parent != null) parent.mkdirs(); 73.454 - 73.455 - InputStream in = new FileInputStream(src); 73.456 - OutputStream out = new FileOutputStream(dest); 73.457 - 73.458 - byte[] buffer = new byte[1024]; 73.459 - int len; 73.460 - while ((len = in.read(buffer)) > 0) { 73.461 - out.write(buffer, 0, len); 73.462 + public static final Function SILENT = new Function() { 73.463 + public int invoke(FunctionDataParser fdp, Writer out) 73.464 + throws IOException, TemplateException { 73.465 + 73.466 + if (!fdp.hasMoreData()) 73.467 + return 0; 73.468 + 73.469 + return fdp.parseData(NullWriter.INSTANCE); 73.470 } 73.471 - in.close(); 73.472 - out.close(); 73.473 - 73.474 - System.err.println("saved " + dest + "."); 73.475 - } 73.476 + }; 73.477 + 73.478 + /** 73.479 + * Skip arguments. 73.480 + */ 73.481 + public static final Function SKIP = new Function() { 73.482 + public int invoke(FunctionDataParser fdp, Writer out) 73.483 + throws IOException, TemplateException { 73.484 + 73.485 + // Ignore arguments. 73.486 + return 0; 73.487 + } 73.488 + }; 73.489 }
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/src/kryshen/tema/functions/Strings.java Tue Feb 19 20:32:17 2008 +0300 74.3 @@ -0,0 +1,225 @@ 74.4 +/* 74.5 + * Copyright 2006-2008 Mikhail Kryshen 74.6 + * 74.7 + * This file is part of Tema. 74.8 + * 74.9 + * Tema is free software: you can redistribute it and/or modify it 74.10 + * under the terms of the GNU Lesser General Public License as 74.11 + * published by the Free Software Foundation, either version 3 of the 74.12 + * License, or (at your option) any later version. 74.13 + * 74.14 + * Tema is distributed in the hope that it will be useful, 74.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 74.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 74.17 + * GNU Lesser General Public License for more details. 74.18 + * 74.19 + * You should have received a copy of the 74.20 + * GNU Lesser General Public License along with Tema. 74.21 + * If not, see <http://www.gnu.org/licenses/>. 74.22 + * 74.23 + * $Id: Strings.java,v 1.13 2008/02/16 17:38:03 mikhail Exp $ 74.24 + */ 74.25 + 74.26 +package kryshen.tema.functions; 74.27 + 74.28 +import java.io.IOException; 74.29 +import java.io.Writer; 74.30 +import kryshen.tema.Function; 74.31 +import kryshen.tema.FunctionDataParser; 74.32 +import kryshen.tema.TemplateException; 74.33 +import kryshen.tema.io.ReplaceWriter; 74.34 + 74.35 +/** 74.36 + * Functions for string manipulation. 74.37 + */ 74.38 +public class Strings { 74.39 + public static final Function TO_UPPER = new Function() { 74.40 + public int invoke(FunctionDataParser fdp, Writer out) 74.41 + throws IOException, TemplateException { 74.42 + 74.43 + String data = fdp.getData(); 74.44 + out.write(data.toUpperCase()); 74.45 + return fdp.getLastReturnCode(); 74.46 + } 74.47 + }; 74.48 + 74.49 + public static final Function TO_LOWER = new Function() { 74.50 + public int invoke(FunctionDataParser fdp, Writer out) 74.51 + throws IOException, TemplateException { 74.52 + 74.53 + String data = fdp.getData(); 74.54 + out.write(data.toLowerCase()); 74.55 + return fdp.getLastReturnCode(); 74.56 + } 74.57 + }; 74.58 + 74.59 + public static final Function SUBSTRING = new Function() { 74.60 + public int invoke(FunctionDataParser fdp, Writer out) 74.61 + throws IOException, TemplateException { 74.62 + 74.63 + String is = fdp.getNextArg(); 74.64 + String js = fdp.getNextArg(); 74.65 + 74.66 + String data = fdp.getData(); 74.67 + 74.68 + try { 74.69 + if (js.equals("$")) { 74.70 + out.write(data.substring(Integer.parseInt(is))); 74.71 + } else { 74.72 + out.write(data.substring( 74.73 + Integer.parseInt(is), 74.74 + Integer.parseInt(js))); 74.75 + } 74.76 + } catch (NumberFormatException e) { 74.77 + throw new TemplateException( 74.78 + e.toString(), e, fdp.getTemplateReader()); 74.79 + } catch (IndexOutOfBoundsException e) { 74.80 + throw new TemplateException( 74.81 + e.toString(), e, fdp.getTemplateReader()); 74.82 + } 74.83 + 74.84 + return fdp.getLastReturnCode(); 74.85 + } 74.86 + }; 74.87 + 74.88 + public static final Function REPLACE = new Function() { 74.89 + public int invoke(FunctionDataParser fdp, Writer out) 74.90 + throws IOException, TemplateException { 74.91 + 74.92 + String arg0 = fdp.getNextArg(); 74.93 + String arg1 = fdp.getNextArg(); 74.94 + 74.95 + ReplaceWriter rw = new ReplaceWriter(out, arg0, arg1); 74.96 + 74.97 + int ret = fdp.parseData(rw); 74.98 + rw.finish(); 74.99 + return ret; 74.100 + } 74.101 + }; 74.102 + 74.103 + public static final Function XML_ESCAPE = new Function() { 74.104 + public int invoke(FunctionDataParser fdp, Writer out) 74.105 + throws IOException, TemplateException { 74.106 + 74.107 + final String[] chars = {"&", "<", ">", "`", "\""}; 74.108 + final String[] escape = {"&", "<", ">", "'", """}; 74.109 + 74.110 + ReplaceWriter rw = new ReplaceWriter(out, chars, escape); 74.111 + 74.112 + int ret = fdp.parseData(rw); 74.113 + rw.finish(); 74.114 + return ret; 74.115 + } 74.116 + }; 74.117 + 74.118 + public static final Function XML_CDATA = new Function() { 74.119 + public int invoke(FunctionDataParser fdp, Writer out) 74.120 + throws IOException, TemplateException { 74.121 + 74.122 + ReplaceWriter rw = new ReplaceWriter 74.123 + (out, "]]>", "]]]><![CDATA[]>", "<![CDATA[", "]]>"); 74.124 + 74.125 + int ret = fdp.parseData(rw); 74.126 + rw.finish(); 74.127 + return ret; 74.128 + } 74.129 + }; 74.130 + 74.131 + public static final Function REGEX_MATCH = new Function() { 74.132 + public int invoke(FunctionDataParser fdp, Writer out) 74.133 + throws IOException, TemplateException { 74.134 + 74.135 + String regex = fdp.getNextArg(); 74.136 + String data = fdp.getData(out); 74.137 + 74.138 + if (data.matches(regex)) { 74.139 + return 1; 74.140 + } 74.141 + 74.142 + return 0; 74.143 + } 74.144 + }; 74.145 + 74.146 + public static final Function REGEX_REPLACE_FIRST = new Function() { 74.147 + public int invoke(FunctionDataParser fdp, Writer out) 74.148 + throws IOException, TemplateException { 74.149 + 74.150 + String regex = fdp.getNextArg(); 74.151 + String replacement = fdp.getNextArg(); 74.152 + String data = fdp.getData(); 74.153 + 74.154 + if (fdp.getLastReturnCode() == 0) 74.155 + return 0; 74.156 + 74.157 + out.write(data.replaceFirst(regex, replacement)); 74.158 + 74.159 + return fdp.getLastReturnCode(); 74.160 + } 74.161 + }; 74.162 + 74.163 + public static final Function REGEX_REPLACE_ALL = new Function() { 74.164 + public int invoke(FunctionDataParser fdp, Writer out) 74.165 + throws IOException, TemplateException { 74.166 + 74.167 + String regex = fdp.getNextArg(); 74.168 + String replacement = fdp.getNextArg(); 74.169 + String data = fdp.getData(); 74.170 + 74.171 + if (fdp.getLastReturnCode() == 0) 74.172 + return 0; 74.173 + 74.174 + out.write(data.replaceAll(regex, replacement)); 74.175 + 74.176 + return fdp.getLastReturnCode(); 74.177 + } 74.178 + }; 74.179 + 74.180 + public static final Function EQUAL = new Function() { 74.181 + public int invoke(FunctionDataParser fdp, Writer out) 74.182 + throws IOException, TemplateException { 74.183 + 74.184 + String s1 = fdp.getNextArg(); 74.185 + 74.186 + while (fdp.hasMoreData()) { 74.187 + String s2 = fdp.getNextArg(); 74.188 + 74.189 + if (!s1.equals(s2)) { 74.190 + return 0; 74.191 + } 74.192 + 74.193 + s1 = s2; 74.194 + } 74.195 + 74.196 + return 1; 74.197 + } 74.198 + }; 74.199 + 74.200 + public static final Function CHAR = new Function() { 74.201 + public int invoke(FunctionDataParser fdp, Writer out) 74.202 + throws IOException, TemplateException { 74.203 + 74.204 + if (!fdp.hasMoreData()) 74.205 + return 0; 74.206 + 74.207 + do { 74.208 + String s = fdp.getNextArg(); 74.209 + int code; 74.210 + 74.211 + try { 74.212 + if (s.startsWith("0x")) { 74.213 + code = Integer.parseInt(s.substring(2), 16); 74.214 + } else { 74.215 + code = Integer.parseInt(s); 74.216 + } 74.217 + } catch (NumberFormatException e) { 74.218 + throw new TemplateException(e.getMessage(), e, 74.219 + fdp.getTemplateReader()); 74.220 + } 74.221 + 74.222 + out.write(code); 74.223 + } while (fdp.hasMoreData()); 74.224 + 74.225 + return 1; 74.226 + } 74.227 + }; 74.228 +}
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/src/kryshen/tema/io/CopyWriter.java Tue Feb 19 20:32:17 2008 +0300 75.3 @@ -0,0 +1,69 @@ 75.4 +/* 75.5 + * Copyright 2006-2008 Mikhail Kryshen 75.6 + * 75.7 + * This file is part of Tema. 75.8 + * 75.9 + * Tema is free software: you can redistribute it and/or modify it 75.10 + * under the terms of the GNU Lesser General Public License as 75.11 + * published by the Free Software Foundation, either version 3 of the 75.12 + * License, or (at your option) any later version. 75.13 + * 75.14 + * Tema is distributed in the hope that it will be useful, 75.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 75.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 75.17 + * GNU Lesser General Public License for more details. 75.18 + * 75.19 + * You should have received a copy of the 75.20 + * GNU Lesser General Public License along with Tema. 75.21 + * If not, see <http://www.gnu.org/licenses/>. 75.22 + * 75.23 + * $Id: CopyWriter.java,v 1.7 2008/02/16 17:56:34 mikhail Exp $ 75.24 + */ 75.25 + 75.26 +package kryshen.tema.io; 75.27 + 75.28 +import java.io.IOException; 75.29 +import java.io.Writer; 75.30 + 75.31 +/** 75.32 + * Copies it's output to several writers. 75.33 + * 75.34 + * @author Mikhail Kryshen 75.35 + */ 75.36 +public class CopyWriter extends Writer { 75.37 + private final Writer[] writers; 75.38 + 75.39 + public CopyWriter(Writer... writers) { 75.40 + this.writers = writers; 75.41 + } 75.42 + 75.43 + public void write(char[] cbuf, int off, int len) throws IOException { 75.44 + for (Writer w : writers) { 75.45 + w.write(cbuf, off, len); 75.46 + } 75.47 + } 75.48 + 75.49 + public void write(int c) throws IOException { 75.50 + for (Writer w : writers) { 75.51 + w.write(c); 75.52 + } 75.53 + } 75.54 + 75.55 + public void write(String str, int off, int len) throws IOException { 75.56 + for (Writer w : writers) { 75.57 + w.write(str, off, len); 75.58 + } 75.59 + } 75.60 + 75.61 + public void flush() throws IOException { 75.62 + for (Writer w : writers) { 75.63 + w.flush(); 75.64 + } 75.65 + } 75.66 + 75.67 + public void close() throws IOException { 75.68 + for (Writer w : writers) { 75.69 + w.close(); 75.70 + } 75.71 + } 75.72 +}
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/src/kryshen/tema/io/NullWriter.java Tue Feb 19 20:32:17 2008 +0300 76.3 @@ -0,0 +1,46 @@ 76.4 +/* 76.5 + * Copyright 2006-2008 Mikhail Kryshen 76.6 + * 76.7 + * This file is part of Tema. 76.8 + * 76.9 + * Tema is free software: you can redistribute it and/or modify it 76.10 + * under the terms of the GNU Lesser General Public License as 76.11 + * published by the Free Software Foundation, either version 3 of the 76.12 + * License, or (at your option) any later version. 76.13 + * 76.14 + * Tema is distributed in the hope that it will be useful, 76.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 76.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 76.17 + * GNU Lesser General Public License for more details. 76.18 + * 76.19 + * You should have received a copy of the 76.20 + * GNU Lesser General Public License along with Tema. 76.21 + * If not, see <http://www.gnu.org/licenses/>. 76.22 + * 76.23 + * $Id: NullWriter.java,v 1.6 2008/02/16 17:38:03 mikhail Exp $ 76.24 + */ 76.25 + 76.26 +package kryshen.tema.io; 76.27 + 76.28 +import java.io.Writer; 76.29 + 76.30 +/** 76.31 + * No-op writer. 76.32 + * 76.33 + * @author Mikhail Kryshen 76.34 + */ 76.35 +public class NullWriter extends Writer{ 76.36 + public static final NullWriter INSTANCE = new NullWriter(); 76.37 + 76.38 + private NullWriter() { 76.39 + } 76.40 + 76.41 + public void close() { 76.42 + } 76.43 + 76.44 + public void flush() { 76.45 + } 76.46 + 76.47 + public void write(char[] cbuf, int off, int len) { 76.48 + } 76.49 +}
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/src/kryshen/tema/io/ReplaceWriter.java Tue Feb 19 20:32:17 2008 +0300 77.3 @@ -0,0 +1,153 @@ 77.4 +/* 77.5 + * Copyright 2006-2008 Mikhail Kryshen 77.6 + * 77.7 + * This file is part of Tema. 77.8 + * 77.9 + * Tema is free software: you can redistribute it and/or modify it 77.10 + * under the terms of the GNU Lesser General Public License as 77.11 + * published by the Free Software Foundation, either version 3 of the 77.12 + * License, or (at your option) any later version. 77.13 + * 77.14 + * Tema is distributed in the hope that it will be useful, 77.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 77.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 77.17 + * GNU Lesser General Public License for more details. 77.18 + * 77.19 + * You should have received a copy of the 77.20 + * GNU Lesser General Public License along with Tema. 77.21 + * If not, see <http://www.gnu.org/licenses/>. 77.22 + * 77.23 + * $Id: ReplaceWriter.java,v 1.8 2008/02/19 16:21:00 mikhail Exp $ 77.24 + */ 77.25 + 77.26 +package kryshen.tema.io; 77.27 + 77.28 +import java.io.Writer; 77.29 +import java.io.FilterWriter; 77.30 +import java.io.IOException; 77.31 + 77.32 +/** 77.33 + * FilterWriter which replaces characters with escape strings. 77.34 + * 77.35 + * @author Mikhail Kryshen 77.36 + */ 77.37 +public class ReplaceWriter extends FilterWriter { 77.38 + private String[] patterns; 77.39 + private String[] replaces; 77.40 + 77.41 + private String prefix; 77.42 + private String postfix; 77.43 + 77.44 + private int maxPatternLength = 0; 77.45 + 77.46 + /** Have this Writer processed any data? */ 77.47 + private boolean processedData = false; 77.48 + 77.49 + private StringBuffer buffer = new StringBuffer(); 77.50 + 77.51 + public ReplaceWriter(Writer w, String pattern, String replace) { 77.52 + this(w, new String[]{pattern}, new String[]{replace}); 77.53 + } 77.54 + 77.55 + public ReplaceWriter(Writer w, String pattern, String replace, 77.56 + String prefix, String postfix) { 77.57 + 77.58 + this(w, new String[]{pattern}, new String[]{replace}, 77.59 + prefix, postfix); 77.60 + } 77.61 + 77.62 + public ReplaceWriter(Writer w, String[] patterns, String[] replaces) { 77.63 + this(w, patterns, replaces, null, null); 77.64 + } 77.65 + 77.66 + public ReplaceWriter(Writer w, String[] patterns, String[] replaces, 77.67 + String prefix, String postfix) { 77.68 + super(w); 77.69 + 77.70 + this.patterns = patterns; 77.71 + this.replaces = replaces; 77.72 + 77.73 + this.prefix = prefix; 77.74 + this.postfix = postfix; 77.75 + 77.76 + for (int i = 0; i < patterns.length; i++) { 77.77 + int length = patterns[i].length(); 77.78 + if (length > maxPatternLength) 77.79 + maxPatternLength = length; 77.80 + } 77.81 + } 77.82 + 77.83 + private boolean processBuffer(int minLength) throws IOException { 77.84 + if (buffer.length() == 0) return false; 77.85 + 77.86 + if (!processedData) { 77.87 + if (prefix != null) 77.88 + super.write(prefix, 0, prefix.length()); 77.89 + processedData = true; 77.90 + } 77.91 + 77.92 + int k; 77.93 + for (k = 0; minLength + k < buffer.length(); k++) { 77.94 + for (int i = 0; i < patterns.length; i++) { 77.95 + String pattern = patterns[i]; 77.96 + int length = pattern.length(); 77.97 + 77.98 + if (length + k > buffer.length()) 77.99 + continue; 77.100 + 77.101 + boolean match = true; 77.102 + 77.103 + for (int j = 0; j < length; j++) { 77.104 + if (pattern.charAt(j) != buffer.charAt(j + k)) { 77.105 + match = false; 77.106 + break; 77.107 + } 77.108 + } 77.109 + 77.110 + if (match) { 77.111 + super.write(buffer.substring(0, k), 0, k); 77.112 + buffer.delete(0, k + length); 77.113 + super.write(replaces[i], 0, replaces[i].length()); 77.114 + return true; 77.115 + } 77.116 + } 77.117 + } 77.118 + 77.119 + super.write(buffer.substring(0, k), 0, k); 77.120 + buffer.delete(0, k); 77.121 + 77.122 + return false; 77.123 + } 77.124 + 77.125 + public void write(int c) throws IOException { 77.126 + buffer.append((char)c); 77.127 + processBuffer(maxPatternLength); 77.128 + } 77.129 + 77.130 + public void write(char[] cbuf, int off, int len) throws IOException { 77.131 + for (int i = off; i < off + len; i++) { 77.132 + buffer.append(cbuf[i]); 77.133 + } 77.134 + processBuffer(maxPatternLength); 77.135 + } 77.136 + 77.137 + public void write(String str, int off, int len) throws IOException { 77.138 + buffer.append(str.substring(off, off + len)); 77.139 + processBuffer(maxPatternLength); 77.140 + } 77.141 + 77.142 + public void finish() throws IOException { 77.143 + while (processBuffer(0)); 77.144 + 77.145 +// super.write(buffer.toString(), 0, buffer.length()); 77.146 +// buffer.delete(0, buffer.length()); 77.147 + 77.148 + if (processedData && postfix != null) 77.149 + super.write(postfix, 0, postfix.length()); 77.150 + } 77.151 + 77.152 + public void close() throws IOException { 77.153 + finish(); 77.154 + super.close(); 77.155 + } 77.156 +}
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/src/kryshen/tema/io/TemplateReader.java Tue Feb 19 20:32:17 2008 +0300 78.3 @@ -0,0 +1,102 @@ 78.4 +/* 78.5 + * Copyright 2006-2008 Mikhail Kryshen 78.6 + * 78.7 + * This file is part of Tema. 78.8 + * 78.9 + * Tema is free software: you can redistribute it and/or modify it 78.10 + * under the terms of the GNU Lesser General Public License as 78.11 + * published by the Free Software Foundation, either version 3 of the 78.12 + * License, or (at your option) any later version. 78.13 + * 78.14 + * Tema is distributed in the hope that it will be useful, 78.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 78.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 78.17 + * GNU Lesser General Public License for more details. 78.18 + * 78.19 + * You should have received a copy of the 78.20 + * GNU Lesser General Public License along with Tema. 78.21 + * If not, see <http://www.gnu.org/licenses/>. 78.22 + * 78.23 + * $Id: TemplateReader.java,v 1.8 2008/02/19 00:20:48 mikhail Exp $ 78.24 + */ 78.25 + 78.26 +package kryshen.tema.io; 78.27 + 78.28 +import java.io.Reader; 78.29 +import java.io.LineNumberReader; 78.30 +import java.io.PushbackReader; 78.31 +import kryshen.tema.TemplateParser; 78.32 + 78.33 +/** 78.34 + * Reader for Tema templates. Stores data source name (commonly 78.35 + * filename) and tracks line numbers for error reporting. 78.36 + * 78.37 + * @author Mikhail Kryshen 78.38 + */ 78.39 +public class TemplateReader extends PushbackReader { 78.40 + static final int UNREAD_BUFFER_SIZE; 78.41 + 78.42 + /* Calculate UNREAD_BUFFER_SIZE value. */ 78.43 + static { 78.44 + int max = 0; 78.45 + 78.46 + for (String s : TemplateParser.BRACKET_OPEN) { 78.47 + max = Math.max(max, s.length()); 78.48 + } 78.49 + 78.50 + for (String s : TemplateParser.BRACKET_CLOSE) { 78.51 + max = Math.max(max, s.length()); 78.52 + } 78.53 + 78.54 + max = Math.max(max, TemplateParser.ESCAPE_NEWLINE.length() + 2); 78.55 + max = Math.max(max, TemplateParser.ESCAPE_WHITESPACE.length()); 78.56 + 78.57 + UNREAD_BUFFER_SIZE = max; 78.58 + } 78.59 + 78.60 + private final String source; 78.61 + private final LineNumberReader lnReader; 78.62 + private final TemplateReader parentReader; 78.63 + 78.64 + public TemplateReader(Reader in) { 78.65 + this(new LineNumberReader(in)); 78.66 + } 78.67 + 78.68 + public TemplateReader(Reader in, String source) { 78.69 + this(new LineNumberReader(in), source); 78.70 + } 78.71 + 78.72 + public TemplateReader(LineNumberReader in) { 78.73 + this(in, ""); 78.74 + } 78.75 + 78.76 + public TemplateReader(LineNumberReader in, String source) { 78.77 + super(in, UNREAD_BUFFER_SIZE); 78.78 + 78.79 + this.parentReader = null; 78.80 + this.lnReader = in; 78.81 + this.source = source; 78.82 + } 78.83 + 78.84 + public TemplateReader(Reader in, TemplateReader parent) { 78.85 + super(in, UNREAD_BUFFER_SIZE); 78.86 + 78.87 + this.parentReader = parent; 78.88 + this.lnReader = null; 78.89 + this.source = null; 78.90 + } 78.91 + 78.92 + public String getSource() { 78.93 + if (source != null) 78.94 + return source; 78.95 + 78.96 + return parentReader.getSource(); 78.97 + } 78.98 + 78.99 + public int getLineNumber() { 78.100 + if (lnReader != null) 78.101 + return lnReader.getLineNumber(); 78.102 + 78.103 + return parentReader.getLineNumber(); 78.104 + } 78.105 +}
79.1 --- a/test/demo Thu Dec 14 23:22:05 2006 +0300 79.2 +++ b/test/demo Tue Feb 19 20:32:17 2008 +0300 79.3 @@ -1,4 +1,4 @@ 79.4 #!/bin/sh 79.5 79.6 #java -jar ../dist/tema.jar 79.7 -java -classpath .:../dist/tema.jar kryshen.tema.Tema 79.8 +java -classpath .:../dist/tema.jar kryshen.tema.Tema main.template
80.1 --- a/test/demo.bat Thu Dec 14 23:22:05 2006 +0300 80.2 +++ b/test/demo.bat Tue Feb 19 20:32:17 2008 +0300 80.3 @@ -1,1 +1,1 @@ 80.4 -java -classpath .:..\dist\tema.jar kryshen.tema.Tema 80.5 +java -classpath .:..\dist\tema.jar kryshen.tema.Tema main.template
81.1 --- a/test/include.template Thu Dec 14 23:22:05 2006 +0300 81.2 +++ b/test/include.template Tue Feb 19 20:32:17 2008 +0300 81.3 @@ -1,1 +1,1 @@ 81.4 -<%define\test test arg1:[%nextarg:%], test arg2:[%nextarg:%], test data:[%data:%].%> 81.5 \ No newline at end of file 81.6 +<%define#test test arg1:<%next_arg:%>, test arg2:<%next_arg:%>, test data:<%data:%>.%> 81.7 \ No newline at end of file
82.1 --- a/test/main.template Thu Dec 14 23:22:05 2006 +0300 82.2 +++ b/test/main.template Tue Feb 19 20:32:17 2008 +0300 82.3 @@ -1,4 +1,4 @@ 82.4 -[%!\ UTF-8 text %] 82.5 +[%!\ UTF-8 text %]\ 82.6 82.7 Вывод текста: 82.8 test text 82.9 @@ -10,7 +10,7 @@ 82.10 <%include:include.template%> 82.11 82.12 Вызов новой функции: 82.13 -<%test:1 2 3%> 82.14 +<%test:1 2 3 4 5%> 82.15 82.16 Тестирование read: 82.17 <%read\include.template%>
83.1 --- a/test/tema.properties Thu Dec 14 23:22:05 2006 +0300 83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 83.3 @@ -1,22 +0,0 @@ 83.4 -# Data source configuration 83.5 -# resource : jdbc:odbc:database 83.6 -# driver : sun.jdbc.odbc.JdbcOdbcDriver 83.7 - 83.8 -# Base directory for images and files 83.9 -# resource_base : . 83.10 - 83.11 -# Template to start processing with 83.12 -main_template : main.template 83.13 - 83.14 -# File encodings 83.15 -input_encoding : UTF-8 83.16 -output_encoding : UTF-8 83.17 - 83.18 -# Cache templates 83.19 -# cache_read : true 83.20 - 83.21 -# Output main_template parsing result to stderr 83.22 -# output : stderr 83.23 - 83.24 -# File to output error messages (redirect stderr) 83.25 -# log : dbreader.log