├── .gitignore ├── .npmignore ├── NOTICE ├── Makefile ├── CHANGELOG ├── package.json ├── README.md ├── pandoc.js └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | node-pandoc 2 | Copyright 2011 Sam Bisbee 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NODE := `which node nodejs` 2 | 3 | JSHINT_CHECK := ./build/jshint-check.js 4 | 5 | all: hint 6 | 7 | hint: 8 | @@for file in `find . -name "*.js" | grep -v '^\./build/'`; do \ 9 | echo "Hinting: $$file"; \ 10 | ${NODE} ${JSHINT_CHECK} $$file; \ 11 | echo "--------------------------"; \ 12 | done 13 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | node-pandoc Changes 2 | =================== 3 | 4 | Version 0.2.0 5 | ------------- 6 | 7 | Breaking Changes 8 | 9 | * A callback is now required when calling convert(), which was previously not 10 | the case. It makes no sense to run the function without a callback though. 11 | 12 | Fixed Bugs 13 | 14 | * Fixed an off by one error that oddly seems to only be showing up in Node 15 | 0.6.x, but not 0.4.x. 16 | 17 | Version 0.1.0 18 | ------------- 19 | 20 | Initial Release 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Sam Bisbee (http://www.sbisbee.com)", 3 | "name": "pandoc", 4 | "description": "A wrapper around the pandoc tool.", 5 | "version": "0.2.0", 6 | "homepage": "https://github.com/sbisbee/node-pandoc", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/sbisbee/node-pandoc.git" 10 | }, 11 | "main": "pandoc", 12 | "engines": { 13 | "node": ">= 0.4.0" 14 | }, 15 | "dependencies": {}, 16 | "devDependencies": {} 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-pandoc 2 | 3 | Version 0.2.0 4 | 5 | https://github.com/sbisbee/node-pandoc 6 | 7 | A node module that wraps the [Pandoc tool](http://johnmacfarlane.net/pandoc/), 8 | allowing you to covert between markup types in node. 9 | 10 | ## Compatability 11 | 12 | node-pandoc is tested against Node v0.6.x and v0.7.x. 13 | 14 | ## Examples 15 | 16 | At a very basic level this library allows you to convert one markup type into 17 | one or many. Supported markup types depends on how you installed Pandoc. 18 | 19 | ### Convert markdown into HTML 20 | 21 | ```js 22 | var pandoc = require('pandoc'); 23 | 24 | pandoc.convert('markdown', mdText, [ 'html' ], function(result, err) { 25 | console.log(result.html); //outputs html 26 | console.log(result.markdown); //outputs the original markdown 27 | }); 28 | ``` 29 | 30 | ### Convert HTML into reStructredTest and plain text 31 | 32 | ```js 33 | var pandoc = require('pandoc'); 34 | 35 | pandoc.convert('html', htmlText, [ 'rst', 'plain' ], function(result, err) { 36 | console.log(result.rst); //outputs the reStructured Text 37 | console.log(result.plain); //outputs the plain text 38 | console.log(result.html); //outputs the HTML text 39 | }); 40 | ``` 41 | 42 | ### Deal with errors (err is the exit status code from pandoc) 43 | 44 | ```js 45 | var pandoc = require('pandoc'); 46 | 47 | pandoc.convert('invalid', moreInvalid, [], function(result, err) { 48 | if(err) { 49 | console.log('pandoc exited with status code ' + err); 50 | } 51 | else { 52 | //do stuff 53 | } 54 | }); 55 | ``` 56 | 57 | ## License 58 | 59 | node-pandoc is released under the Apache License, version 2.0. See the file 60 | named LICENSE for more information. 61 | 62 | Copyright information is in the [NOTICE](NOTICE) file. 63 | -------------------------------------------------------------------------------- /pandoc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * node-pandoc 3 | * 4 | * This is the main, and currently only, file. It wraps the `pandoc` command 5 | * using node's child_process module. Since we still have to support node 0.4.x 6 | * (latest stable) we have to use spawn instead of fork(). 7 | */ 8 | 9 | var childProcess = require('child_process'); 10 | var spawn = childProcess.spawn; 11 | var exec = childProcess.exec; 12 | 13 | // The global command line args for pandocs. 14 | var globalArgs = { 15 | //what the user provided 16 | provided: null, 17 | 18 | //whether to persist between convert() calls 19 | persist: false, 20 | 21 | //resets back to defaults 22 | reset: function() { 23 | this.provided = null; 24 | this.persist = false; 25 | } 26 | }; 27 | 28 | /* 29 | * type is the input markup's type 30 | * 31 | * input is the input markup 32 | * 33 | * types is an array of markup types to convert to or a single type as a string 34 | * 35 | * callback will be passed an object mapping markup type to markup, unless 36 | * there was an error in which case it gets passed (null, statusCode) 37 | */ 38 | exports.convert = function(type, input, types, callback) { 39 | var res = {}; 40 | var numResponses = 0; 41 | var targetResponses; 42 | 43 | var pandoc; 44 | var args; 45 | 46 | var i; 47 | 48 | if(!type || typeof type !== 'string') { 49 | throw 'Invalid source markup type: must be a string.'; 50 | } 51 | 52 | if(!input || typeof input !== 'string') { 53 | throw 'Invalid markup type: must be a string.'; 54 | } 55 | 56 | if(typeof types !== 'string' && !Array.isArray(types)) { 57 | throw 'Invalid destination types: must be a string or an array of strings.'; 58 | } 59 | 60 | if(types.length <= 0) { 61 | throw 'No destination types provided (empty array).'; 62 | } 63 | 64 | if(typeof callback !== 'function') { 65 | if(callback) { 66 | throw 'Invalid callback provided: must be a function.'; 67 | } 68 | else { 69 | throw 'No callback provided: must be a function.'; 70 | } 71 | } 72 | 73 | //what we're going to send to the callback if there are no pandoc errors 74 | res[type] = input; 75 | 76 | if(typeof types === 'string') { 77 | types = [ types ]; 78 | } 79 | 80 | targetResponses = types.length; 81 | 82 | exec('which pandoc', function(err, stdout) { 83 | var pandocPath; 84 | 85 | if(err) { 86 | throw err; 87 | } 88 | 89 | if(!stdout) { 90 | throw new Error('Cannot find pandoc - is it installed?'); 91 | } 92 | 93 | //strip the newline 94 | pandocPath = stdout.substr(0, stdout.length - 1); 95 | 96 | for(i in types) { 97 | if(types.hasOwnProperty(i)) { 98 | if(typeof types[i] !== 'string') { 99 | throw 'Invalid destination type provided: non-string value found in array.'; 100 | } 101 | 102 | /* 103 | * This if-block filters out the target markup type because we already set 104 | * it on the res object. 105 | */ 106 | if(!res[types[i]]) { 107 | args = globalArgs.provided || []; 108 | args.push('-f', type, '-t', types[i]); 109 | 110 | pandoc = spawn(pandocPath, args); 111 | 112 | //so that we have the target type in scope on('data') - love ya some asynch 113 | pandoc.stdout.targetType = types[i]; 114 | 115 | pandoc.stdout.on('data', function(data) { 116 | //data will be a binary stream if you don't cast it to a string 117 | res[this.targetType] = data + ''; 118 | }); 119 | 120 | pandoc.on('error', function(err) { 121 | callback(null, err); 122 | }); 123 | 124 | pandoc.on('exit', function(code, signal) { 125 | numResponses++; 126 | 127 | if(code !== 0) { 128 | callback(null, code); 129 | } 130 | else if(numResponses === targetResponses) { 131 | callback(res); 132 | } 133 | }); 134 | 135 | //pipe them the input 136 | pandoc.stdin.write(input, 'utf8'); 137 | pandoc.stdin.end(); 138 | 139 | if(!globalArgs.persist) { 140 | globalArgs.reset(); 141 | } 142 | } 143 | } 144 | } 145 | }); 146 | }; 147 | 148 | /* 149 | * args is an array of command line arguments that should be passed to pandoc 150 | * on the next call. If set to a non-array value, then default args will be 151 | * used. The default behavior is that they will be thrown away before the next 152 | * call. 153 | * 154 | * persist is a boolean that when set to true will persist the provided args 155 | * for future calls. 156 | * 157 | * Returns this module so you can chain this funciton with convert(). 158 | */ 159 | exports.args = function(args, persist) { 160 | if(Array.isArray(args)) { 161 | globalArgs.provided = args; 162 | globalArgs.persist = persist; 163 | } 164 | else { 165 | globalArgs.reset(); 166 | } 167 | 168 | return exports; 169 | }; 170 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------