├── .github
└── workflows
│ └── issues.yml
├── README.md
├── index.html
├── parser.js
└── LICENSE
/.github/workflows/issues.yml:
--------------------------------------------------------------------------------
1 | # This file is managed in https://github.com/happyprime/projects
2 | name: Add new issues to Happy Prime project
3 |
4 | on:
5 | issues:
6 | types:
7 | - opened
8 |
9 | jobs:
10 | add-to-project:
11 | uses: happyprime/workflows/.github/workflows/issues.yml@trunk
12 | secrets: inherit
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WPHTML Converter
2 |
3 | WPHTML is a [page](https://happyprime.github.io/wphtml-converter/) that converts WPHTML (WordPress block markup) to its JS/JSON or PHP forms.
4 |
5 | [https://happyprime.github.io/wphtml-converter/](https://happyprime.github.io/wphtml-converter/)
6 |
7 | It parses WPHTML into JS/JSON with a direct [copy](https://github.com/WordPress/gutenberg/blob/b3ea2b6a80ee92f26148899455669c53ae2f49de/packages/block-serialization-default-parser/src/index.js) of Gutenberg's (GPL 2.0 or later licensed) [Block Serialization Default Parser](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-serialization-default-parser).
8 |
9 | ## What is it?
10 |
11 | When first building a template of blocks to be used as part of a block varation or other template, it is useful to do this work in the block editor. This results in markup like:
12 |
13 | ```html
14 |
15 |
An example headline
16 |
17 |
18 |
19 |
An example paragraph.
20 |
21 | ```
22 |
23 | When adding the template to JavaScript in an `innerBlocks` property, it needs to be formatted like:
24 |
25 | ```js
26 | [
27 | 'core/heading',
28 | {
29 | "level": 1,
30 | "style": {
31 | "spacing": {
32 | "margin": {
33 | "top": "var:preset|spacing|30"
34 | }
35 | }
36 | }
37 | },
38 | []
39 | ],
40 | [
41 | 'core/paragraph',
42 | {},
43 | []
44 | ],
45 | ```
46 |
47 | And when adding it to PHP, it needs to be formatted like:
48 |
49 | ```php
50 | array(
51 | 'core/heading',
52 | array(
53 | 'level' => 1,
54 | 'style' => array(
55 | 'spacing' => array(
56 | 'margin' => array(
57 | 'top' => 'var:preset|spacing|30'
58 | )
59 | )
60 | )
61 | ),
62 | array()
63 | ),
64 | array(
65 | 'core/paragraph',
66 | array(),
67 | array()
68 | ),
69 | ```
70 |
71 | As your templates get more complicated, so does this translation—when done manually.
72 |
73 | So, copy some block markup, open [WPHTML Converter](https://happyprime.github.io/wphtml-converter/), paste, and click. 🕺
74 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WPHTML Converter
7 |
8 |
9 |
11 |
12 |
13 |
54 |
55 |
56 |
57 |
58 |
WPHTML Converter
59 |
Convert WordPress block HTML to its JavaScript object or PHP array forms.
\n'
214 | * }
215 | * ];
216 | * ```
217 | * @return {ParsedBlock[]} A block-based representation of the input HTML.
218 | */
219 | export const parse = ( doc ) => {
220 | document = doc;
221 | offset = 0;
222 | output = [];
223 | stack = [];
224 | tokenizer.lastIndex = 0;
225 |
226 | do {
227 | // twiddle our thumbs
228 | } while ( proceed() );
229 |
230 | return output;
231 | };
232 |
233 | /**
234 | * Parses the next token in the input document.
235 | *
236 | * @return {boolean} Returns true when there is more tokens to parse.
237 | */
238 | function proceed() {
239 | const stackDepth = stack.length;
240 | const next = nextToken();
241 | const [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;
242 |
243 | // We may have some HTML soup before the next block.
244 | const leadingHtmlStart = startOffset > offset ? offset : null;
245 |
246 | switch ( tokenType ) {
247 | case 'no-more-tokens':
248 | // If not in a block then flush output.
249 | if ( 0 === stackDepth ) {
250 | addFreeform();
251 | return false;
252 | }
253 |
254 | // Otherwise we have a problem
255 | // This is an error
256 | // we have options
257 | // - treat it all as freeform text
258 | // - assume an implicit closer (easiest when not nesting)
259 |
260 | // For the easy case we'll assume an implicit closer.
261 | if ( 1 === stackDepth ) {
262 | addBlockFromStack();
263 | return false;
264 | }
265 |
266 | // For the nested case where it's more difficult we'll
267 | // have to assume that multiple closers are missing
268 | // and so we'll collapse the whole stack piecewise.
269 | while ( 0 < stack.length ) {
270 | addBlockFromStack();
271 | }
272 | return false;
273 | case 'void-block':
274 | // easy case is if we stumbled upon a void block
275 | // in the top-level of the document.
276 | if ( 0 === stackDepth ) {
277 | if ( null !== leadingHtmlStart ) {
278 | output.push(
279 | Freeform(
280 | document.substr(
281 | leadingHtmlStart,
282 | startOffset - leadingHtmlStart
283 | )
284 | )
285 | );
286 | }
287 | output.push( Block( blockName, attrs, [], '', [] ) );
288 | offset = startOffset + tokenLength;
289 | return true;
290 | }
291 |
292 | // Otherwise we found an inner block.
293 | addInnerBlock(
294 | Block( blockName, attrs, [], '', [] ),
295 | startOffset,
296 | tokenLength
297 | );
298 | offset = startOffset + tokenLength;
299 | return true;
300 |
301 | case 'block-opener':
302 | // Track all newly-opened blocks on the stack.
303 | stack.push(
304 | Frame(
305 | Block( blockName, attrs, [], '', [] ),
306 | startOffset,
307 | tokenLength,
308 | startOffset + tokenLength,
309 | leadingHtmlStart
310 | )
311 | );
312 | offset = startOffset + tokenLength;
313 | return true;
314 |
315 | case 'block-closer':
316 | // If we're missing an opener we're in trouble
317 | // This is an error.
318 | if ( 0 === stackDepth ) {
319 | // We have options
320 | // - assume an implicit opener
321 | // - assume _this_ is the opener
322 | // - give up and close out the document.
323 | addFreeform();
324 | return false;
325 | }
326 |
327 | // If we're not nesting then this is easy - close the block.
328 | if ( 1 === stackDepth ) {
329 | addBlockFromStack( startOffset );
330 | offset = startOffset + tokenLength;
331 | return true;
332 | }
333 |
334 | // Otherwise we're nested and we have to close out the current
335 | // block and add it as a innerBlock to the parent.
336 | const stackTop = /** @type {ParsedFrame} */ ( stack.pop() );
337 | const html = document.substr(
338 | stackTop.prevOffset,
339 | startOffset - stackTop.prevOffset
340 | );
341 | stackTop.block.innerHTML += html;
342 | stackTop.block.innerContent.push( html );
343 | stackTop.prevOffset = startOffset + tokenLength;
344 |
345 | addInnerBlock(
346 | stackTop.block,
347 | stackTop.tokenStart,
348 | stackTop.tokenLength,
349 | startOffset + tokenLength
350 | );
351 | offset = startOffset + tokenLength;
352 | return true;
353 |
354 | default:
355 | // This is an error.
356 | addFreeform();
357 | return false;
358 | }
359 | }
360 |
361 | /**
362 | * Parse JSON if valid, otherwise return null
363 | *
364 | * Note that JSON coming from the block comment
365 | * delimiters is constrained to be an object
366 | * and cannot be things like `true` or `null`
367 | *
368 | * @param {string} input JSON input string to parse
369 | * @return {Object|null} parsed JSON if valid
370 | */
371 | function parseJSON( input ) {
372 | try {
373 | return JSON.parse( input );
374 | } catch ( e ) {
375 | return null;
376 | }
377 | }
378 |
379 | /**
380 | * Finds the next token in the document.
381 | *
382 | * @return {Token} The next matched token.
383 | */
384 | function nextToken() {
385 | // Aye the magic
386 | // we're using a single RegExp to tokenize the block comment delimiters
387 | // we're also using a trick here because the only difference between a
388 | // block opener and a block closer is the leading `/` before `wp:` (and
389 | // a closer has no attributes). we can trap them both and process the
390 | // match back in JavaScript to see which one it was.
391 | const matches = tokenizer.exec( document );
392 |
393 | // We have no more tokens.
394 | if ( null === matches ) {
395 | return [ 'no-more-tokens', '', null, 0, 0 ];
396 | }
397 |
398 | const startedAt = matches.index;
399 | const [
400 | match,
401 | closerMatch,
402 | namespaceMatch,
403 | nameMatch,
404 | attrsMatch /* Internal/unused. */,
405 | ,
406 | voidMatch,
407 | ] = matches;
408 |
409 | const length = match.length;
410 | const isCloser = !! closerMatch;
411 | const isVoid = !! voidMatch;
412 | const namespace = namespaceMatch || 'core/';
413 | const name = namespace + nameMatch;
414 | const hasAttrs = !! attrsMatch;
415 | const attrs = hasAttrs ? parseJSON( attrsMatch ) : {};
416 |
417 | // This state isn't allowed
418 | // This is an error.
419 | if ( isCloser && ( isVoid || hasAttrs ) ) {
420 | // We can ignore them since they don't hurt anything
421 | // we may warn against this at some point or reject it.
422 | }
423 |
424 | if ( isVoid ) {
425 | return [ 'void-block', name, attrs, startedAt, length ];
426 | }
427 |
428 | if ( isCloser ) {
429 | return [ 'block-closer', name, null, startedAt, length ];
430 | }
431 |
432 | return [ 'block-opener', name, attrs, startedAt, length ];
433 | }
434 |
435 | /**
436 | * Adds a freeform block to the output.
437 | *
438 | * @param {number} [rawLength]
439 | */
440 | function addFreeform( rawLength ) {
441 | const length = rawLength ? rawLength : document.length - offset;
442 |
443 | if ( 0 === length ) {
444 | return;
445 | }
446 |
447 | output.push( Freeform( document.substr( offset, length ) ) );
448 | }
449 |
450 | /**
451 | * Adds inner block to the parent block.
452 | *
453 | * @param {ParsedBlock} block
454 | * @param {number} tokenStart
455 | * @param {number} tokenLength
456 | * @param {number} [lastOffset]
457 | */
458 | function addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {
459 | const parent = stack[ stack.length - 1 ];
460 | parent.block.innerBlocks.push( block );
461 | const html = document.substr(
462 | parent.prevOffset,
463 | tokenStart - parent.prevOffset
464 | );
465 |
466 | if ( html ) {
467 | parent.block.innerHTML += html;
468 | parent.block.innerContent.push( html );
469 | }
470 |
471 | parent.block.innerContent.push( null );
472 | parent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;
473 | }
474 |
475 | /**
476 | * Adds block from the stack to the output.
477 | *
478 | * @param {number} [endOffset]
479 | */
480 | function addBlockFromStack( endOffset ) {
481 | const { block, leadingHtmlStart, prevOffset, tokenStart } =
482 | /** @type {ParsedFrame} */ ( stack.pop() );
483 |
484 | const html = endOffset
485 | ? document.substr( prevOffset, endOffset - prevOffset )
486 | : document.substr( prevOffset );
487 |
488 | if ( html ) {
489 | block.innerHTML += html;
490 | block.innerContent.push( html );
491 | }
492 |
493 | if ( null !== leadingHtmlStart ) {
494 | output.push(
495 | Freeform(
496 | document.substr(
497 | leadingHtmlStart,
498 | tokenStart - leadingHtmlStart
499 | )
500 | )
501 | );
502 | }
503 |
504 | output.push( block );
505 | }
506 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | WPHTML Converter
2 |
3 | Copyright 2023, Happy Prime and contributors
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 |
19 | This program is distributed alongside work covered by the following copyright and
20 | permission notices:
21 |
22 | Block Serialization Default Parser is authored by The WordPress Contributors
23 | and licensed as GPL 2.0 or later.
24 |
25 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
26 |
27 | GNU GENERAL PUBLIC LICENSE
28 | Version 2, June 1991
29 |
30 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
31 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 | Everyone is permitted to copy and distribute verbatim copies
33 | of this license document, but changing it is not allowed.
34 |
35 | Preamble
36 |
37 | The licenses for most software are designed to take away your
38 | freedom to share and change it. By contrast, the GNU General Public
39 | License is intended to guarantee your freedom to share and change free
40 | software--to make sure the software is free for all its users. This
41 | General Public License applies to most of the Free Software
42 | Foundation's software and to any other program whose authors commit to
43 | using it. (Some other Free Software Foundation software is covered by
44 | the GNU Lesser General Public License instead.) You can apply it to
45 | your programs, too.
46 |
47 | When we speak of free software, we are referring to freedom, not
48 | price. Our General Public Licenses are designed to make sure that you
49 | have the freedom to distribute copies of free software (and charge for
50 | this service if you wish), that you receive source code or can get it
51 | if you want it, that you can change the software or use pieces of it
52 | in new free programs; and that you know you can do these things.
53 |
54 | To protect your rights, we need to make restrictions that forbid
55 | anyone to deny you these rights or to ask you to surrender the rights.
56 | These restrictions translate to certain responsibilities for you if you
57 | distribute copies of the software, or if you modify it.
58 |
59 | For example, if you distribute copies of such a program, whether
60 | gratis or for a fee, you must give the recipients all the rights that
61 | you have. You must make sure that they, too, receive or can get the
62 | source code. And you must show them these terms so they know their
63 | rights.
64 |
65 | We protect your rights with two steps: (1) copyright the software, and
66 | (2) offer you this license which gives you legal permission to copy,
67 | distribute and/or modify the software.
68 |
69 | Also, for each author's protection and ours, we want to make certain
70 | that everyone understands that there is no warranty for this free
71 | software. If the software is modified by someone else and passed on, we
72 | want its recipients to know that what they have is not the original, so
73 | that any problems introduced by others will not reflect on the original
74 | authors' reputations.
75 |
76 | Finally, any free program is threatened constantly by software
77 | patents. We wish to avoid the danger that redistributors of a free
78 | program will individually obtain patent licenses, in effect making the
79 | program proprietary. To prevent this, we have made it clear that any
80 | patent must be licensed for everyone's free use or not licensed at all.
81 |
82 | The precise terms and conditions for copying, distribution and
83 | modification follow.
84 |
85 | GNU GENERAL PUBLIC LICENSE
86 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
87 |
88 | 0. This License applies to any program or other work which contains
89 | a notice placed by the copyright holder saying it may be distributed
90 | under the terms of this General Public License. The "Program", below,
91 | refers to any such program or work, and a "work based on the Program"
92 | means either the Program or any derivative work under copyright law:
93 | that is to say, a work containing the Program or a portion of it,
94 | either verbatim or with modifications and/or translated into another
95 | language. (Hereinafter, translation is included without limitation in
96 | the term "modification".) Each licensee is addressed as "you".
97 |
98 | Activities other than copying, distribution and modification are not
99 | covered by this License; they are outside its scope. The act of
100 | running the Program is not restricted, and the output from the Program
101 | is covered only if its contents constitute a work based on the
102 | Program (independent of having been made by running the Program).
103 | Whether that is true depends on what the Program does.
104 |
105 | 1. You may copy and distribute verbatim copies of the Program's
106 | source code as you receive it, in any medium, provided that you
107 | conspicuously and appropriately publish on each copy an appropriate
108 | copyright notice and disclaimer of warranty; keep intact all the
109 | notices that refer to this License and to the absence of any warranty;
110 | and give any other recipients of the Program a copy of this License
111 | along with the Program.
112 |
113 | You may charge a fee for the physical act of transferring a copy, and
114 | you may at your option offer warranty protection in exchange for a fee.
115 |
116 | 2. You may modify your copy or copies of the Program or any portion
117 | of it, thus forming a work based on the Program, and copy and
118 | distribute such modifications or work under the terms of Section 1
119 | above, provided that you also meet all of these conditions:
120 |
121 | a) You must cause the modified files to carry prominent notices
122 | stating that you changed the files and the date of any change.
123 |
124 | b) You must cause any work that you distribute or publish, that in
125 | whole or in part contains or is derived from the Program or any
126 | part thereof, to be licensed as a whole at no charge to all third
127 | parties under the terms of this License.
128 |
129 | c) If the modified program normally reads commands interactively
130 | when run, you must cause it, when started running for such
131 | interactive use in the most ordinary way, to print or display an
132 | announcement including an appropriate copyright notice and a
133 | notice that there is no warranty (or else, saying that you provide
134 | a warranty) and that users may redistribute the program under
135 | these conditions, and telling the user how to view a copy of this
136 | License. (Exception: if the Program itself is interactive but
137 | does not normally print such an announcement, your work based on
138 | the Program is not required to print an announcement.)
139 |
140 | These requirements apply to the modified work as a whole. If
141 | identifiable sections of that work are not derived from the Program,
142 | and can be reasonably considered independent and separate works in
143 | themselves, then this License, and its terms, do not apply to those
144 | sections when you distribute them as separate works. But when you
145 | distribute the same sections as part of a whole which is a work based
146 | on the Program, the distribution of the whole must be on the terms of
147 | this License, whose permissions for other licensees extend to the
148 | entire whole, and thus to each and every part regardless of who wrote it.
149 |
150 | Thus, it is not the intent of this section to claim rights or contest
151 | your rights to work written entirely by you; rather, the intent is to
152 | exercise the right to control the distribution of derivative or
153 | collective works based on the Program.
154 |
155 | In addition, mere aggregation of another work not based on the Program
156 | with the Program (or with a work based on the Program) on a volume of
157 | a storage or distribution medium does not bring the other work under
158 | the scope of this License.
159 |
160 | 3. You may copy and distribute the Program (or a work based on it,
161 | under Section 2) in object code or executable form under the terms of
162 | Sections 1 and 2 above provided that you also do one of the following:
163 |
164 | a) Accompany it with the complete corresponding machine-readable
165 | source code, which must be distributed under the terms of Sections
166 | 1 and 2 above on a medium customarily used for software interchange; or,
167 |
168 | b) Accompany it with a written offer, valid for at least three
169 | years, to give any third party, for a charge no more than your
170 | cost of physically performing source distribution, a complete
171 | machine-readable copy of the corresponding source code, to be
172 | distributed under the terms of Sections 1 and 2 above on a medium
173 | customarily used for software interchange; or,
174 |
175 | c) Accompany it with the information you received as to the offer
176 | to distribute corresponding source code. (This alternative is
177 | allowed only for noncommercial distribution and only if you
178 | received the program in object code or executable form with such
179 | an offer, in accord with Subsection b above.)
180 |
181 | The source code for a work means the preferred form of the work for
182 | making modifications to it. For an executable work, complete source
183 | code means all the source code for all modules it contains, plus any
184 | associated interface definition files, plus the scripts used to
185 | control compilation and installation of the executable. However, as a
186 | special exception, the source code distributed need not include
187 | anything that is normally distributed (in either source or binary
188 | form) with the major components (compiler, kernel, and so on) of the
189 | operating system on which the executable runs, unless that component
190 | itself accompanies the executable.
191 |
192 | If distribution of executable or object code is made by offering
193 | access to copy from a designated place, then offering equivalent
194 | access to copy the source code from the same place counts as
195 | distribution of the source code, even though third parties are not
196 | compelled to copy the source along with the object code.
197 |
198 | 4. You may not copy, modify, sublicense, or distribute the Program
199 | except as expressly provided under this License. Any attempt
200 | otherwise to copy, modify, sublicense or distribute the Program is
201 | void, and will automatically terminate your rights under this License.
202 | However, parties who have received copies, or rights, from you under
203 | this License will not have their licenses terminated so long as such
204 | parties remain in full compliance.
205 |
206 | 5. You are not required to accept this License, since you have not
207 | signed it. However, nothing else grants you permission to modify or
208 | distribute the Program or its derivative works. These actions are
209 | prohibited by law if you do not accept this License. Therefore, by
210 | modifying or distributing the Program (or any work based on the
211 | Program), you indicate your acceptance of this License to do so, and
212 | all its terms and conditions for copying, distributing or modifying
213 | the Program or works based on it.
214 |
215 | 6. Each time you redistribute the Program (or any work based on the
216 | Program), the recipient automatically receives a license from the
217 | original licensor to copy, distribute or modify the Program subject to
218 | these terms and conditions. You may not impose any further
219 | restrictions on the recipients' exercise of the rights granted herein.
220 | You are not responsible for enforcing compliance by third parties to
221 | this License.
222 |
223 | 7. If, as a consequence of a court judgment or allegation of patent
224 | infringement or for any other reason (not limited to patent issues),
225 | conditions are imposed on you (whether by court order, agreement or
226 | otherwise) that contradict the conditions of this License, they do not
227 | excuse you from the conditions of this License. If you cannot
228 | distribute so as to satisfy simultaneously your obligations under this
229 | License and any other pertinent obligations, then as a consequence you
230 | may not distribute the Program at all. For example, if a patent
231 | license would not permit royalty-free redistribution of the Program by
232 | all those who receive copies directly or indirectly through you, then
233 | the only way you could satisfy both it and this License would be to
234 | refrain entirely from distribution of the Program.
235 |
236 | If any portion of this section is held invalid or unenforceable under
237 | any particular circumstance, the balance of the section is intended to
238 | apply and the section as a whole is intended to apply in other
239 | circumstances.
240 |
241 | It is not the purpose of this section to induce you to infringe any
242 | patents or other property right claims or to contest validity of any
243 | such claims; this section has the sole purpose of protecting the
244 | integrity of the free software distribution system, which is
245 | implemented by public license practices. Many people have made
246 | generous contributions to the wide range of software distributed
247 | through that system in reliance on consistent application of that
248 | system; it is up to the author/donor to decide if he or she is willing
249 | to distribute software through any other system and a licensee cannot
250 | impose that choice.
251 |
252 | This section is intended to make thoroughly clear what is believed to
253 | be a consequence of the rest of this License.
254 |
255 | 8. If the distribution and/or use of the Program is restricted in
256 | certain countries either by patents or by copyrighted interfaces, the
257 | original copyright holder who places the Program under this License
258 | may add an explicit geographical distribution limitation excluding
259 | those countries, so that distribution is permitted only in or among
260 | countries not thus excluded. In such case, this License incorporates
261 | the limitation as if written in the body of this License.
262 |
263 | 9. The Free Software Foundation may publish revised and/or new versions
264 | of the General Public License from time to time. Such new versions will
265 | be similar in spirit to the present version, but may differ in detail to
266 | address new problems or concerns.
267 |
268 | Each version is given a distinguishing version number. If the Program
269 | specifies a version number of this License which applies to it and "any
270 | later version", you have the option of following the terms and conditions
271 | either of that version or of any later version published by the Free
272 | Software Foundation. If the Program does not specify a version number of
273 | this License, you may choose any version ever published by the Free Software
274 | Foundation.
275 |
276 | 10. If you wish to incorporate parts of the Program into other free
277 | programs whose distribution conditions are different, write to the author
278 | to ask for permission. For software which is copyrighted by the Free
279 | Software Foundation, write to the Free Software Foundation; we sometimes
280 | make exceptions for this. Our decision will be guided by the two goals
281 | of preserving the free status of all derivatives of our free software and
282 | of promoting the sharing and reuse of software generally.
283 |
284 | NO WARRANTY
285 |
286 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
287 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
288 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
289 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
290 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
291 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
292 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
293 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
294 | REPAIR OR CORRECTION.
295 |
296 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
297 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
298 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
299 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
300 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
301 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
302 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
303 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
304 | POSSIBILITY OF SUCH DAMAGES.
305 |
306 | END OF TERMS AND CONDITIONS
307 |
308 | How to Apply These Terms to Your New Programs
309 |
310 | If you develop a new program, and you want it to be of the greatest
311 | possible use to the public, the best way to achieve this is to make it
312 | free software which everyone can redistribute and change under these terms.
313 |
314 | To do so, attach the following notices to the program. It is safest
315 | to attach them to the start of each source file to most effectively
316 | convey the exclusion of warranty; and each file should have at least
317 | the "copyright" line and a pointer to where the full notice is found.
318 |
319 |
320 | Copyright (C)
321 |
322 | This program is free software; you can redistribute it and/or modify
323 | it under the terms of the GNU General Public License as published by
324 | the Free Software Foundation; either version 2 of the License, or
325 | (at your option) any later version.
326 |
327 | This program is distributed in the hope that it will be useful,
328 | but WITHOUT ANY WARRANTY; without even the implied warranty of
329 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
330 | GNU General Public License for more details.
331 |
332 | You should have received a copy of the GNU General Public License along
333 | with this program; if not, write to the Free Software Foundation, Inc.,
334 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
335 |
336 | Also add information on how to contact you by electronic and paper mail.
337 |
338 | If the program is interactive, make it output a short notice like this
339 | when it starts in an interactive mode:
340 |
341 | Gnomovision version 69, Copyright (C) year name of author
342 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
343 | This is free software, and you are welcome to redistribute it
344 | under certain conditions; type `show c' for details.
345 |
346 | The hypothetical commands `show w' and `show c' should show the appropriate
347 | parts of the General Public License. Of course, the commands you use may
348 | be called something other than `show w' and `show c'; they could even be
349 | mouse-clicks or menu items--whatever suits your program.
350 |
351 | You should also get your employer (if you work as a programmer) or your
352 | school, if any, to sign a "copyright disclaimer" for the program, if
353 | necessary. Here is a sample; alter the names:
354 |
355 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
356 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
357 |
358 | , 1 April 1989
359 | Ty Coon, President of Vice
360 |
361 | This General Public License does not permit incorporating your program into
362 | proprietary programs. If your program is a subroutine library, you may
363 | consider it more useful to permit linking proprietary applications with the
364 | library. If this is what you want to do, use the GNU Lesser General
365 | Public License instead of this License.
366 |
367 | WRITTEN OFFER
368 |
369 | The source code for any program binaries or compressed scripts that are
370 | included with WPHTML Converter can be freely obtained at the following URL:
371 |
372 | https://github.com/happyprime/wphtml-converter/
373 |
--------------------------------------------------------------------------------