copytext

A module for accessing a XLSX spreadsheet as a JavaScript object. (Markdown batteries included.)

node-copytext

A node library for accessing a XLSX spreadsheet as a JavaScript object. (Markdown batteries included!) Inspired by the NPR visuals team's copytext library for Python. Works great coupled with group-edited Google Spreadsheet exported as a XLSX file.

  • Access an XLSX spreadsheet as a JavaScript object
  • Great for passing into templates, saving to a file, etc.
  • XLSX spreadsheets can be loaded via path or as a Buffer
  • Support for markdown conversion via the marked library
  • Can process both key/value sheets and table layouts
  • Tested against both node.js and io.js
npm install copytext

If you're looking to do some work on node-copytext itself, clone the repo instead:

git clone https://github.com/rdmurphy/node-copytext.git
cd node-copytext
npm install
npm test # make sure everything already works! 

And you're good to go!

ToolMethod
Grunthttps://github.com/rdmurphy/grunt-copytext
GulpUse copytext directly

copytext can work with both key/value and table layouts. By default, it assumes you're passing it key/value sheets.

Note: With key/value sheets, the processor will only care about content in the first three columns. Anything else will be ignored. (Meaning the other columns are a great place to leave notes!)

corgis_keyvalue.xlsx
Sheet name: CORGIS

  • | - ----- | ----- name | Poky instagram_account | https://instagram.com/poky_corgi/
var copytext = require('copytext');
 
var data = copytext('./corgis_keyvalue.xlsx');
 
console.log(data);
 
// { 
//   'CORGIS': { 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   } 
// } 

To tell copytext to use the table parser instead (known as objectlist), you can pass an object as the second argument to copytext with a key of basetype set to objectlist.

corgis_objectlist.xlsx
Sheet name: CORGIS

nameinstagram_account
Pokyhttps://instagram.com/poky_corgi/
Tibbyhttps://instagram.com/tibbythecorgi/
var copytext = require('copytext');
 
var data = copytext('./corgis_objectlist.xlsx', {
  'basetype': 'objectlist'
});
 
console.log(data);
 
// { 
//   'CORGIS': [{ 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   },{ 
//     'name': 'Tibby', 
//     'instagram_account': 'https://instagram.com/tibbythecorgi/' 
//   }] 
// } 

Have a spreadsheet that uses both layouts? No problem! Just let copytext know which sheets are the exception to the basetype. Overrides are passed in as a list to the options object on the overrides key. Each override should be represented as a key/value object where the key is the name of the sheet, and the value is the name of the processor to be used.

Assume we have the previous example's CORGIS sheet in a spreadsheet plus this sheet:

Sheet name: SHIBA

  • | - ----- | ----- name | Maru instagram_account | https://instagram.com/marutaro/
var copytext = require('copytext');
 
var data = copytext('./husky_keyvalue_corgis_objectlist.xlsx', {
  'basetype': 'objectlist',
  'overrides': {
    'SHIBA': 'keyvalue'
  }
});
 
console.log(data);
 
// { 
//   'CORGIS': [{ 
//     'name': 'Poky', 
//     'instagram_account': 'https://instagram.com/poky_corgi/' 
//   }, 
//   { 
//     'name': 'Tibby', 
//     'instagram_account': 'https://instagram.com/tibbythecorgi/' 
//   }], 
//   'SHIBAS': { 
//     'name': 'Maru', 
//     'instagram_account': 'https://instagram.com/marutaro/' 
//   } 
// } 

The override works in both directions - this would have produced the same result:

var data = copytext('./husky_keyvalue_corgis_objectlist.xlsx', {
  'basetype': 'keyvalue',
  'overrides': {
    'CORGIS': 'objectlist'
  }
});

In key/value sheets, you tell copytext to process the value cell (in column B) as Markdown by putting md or markdown in the cell next to it in column C.

  • | - | - ----- | ----- | ----- name | Poky | instagram_account | https://instagram.com/poky_corgi/ | bio | Pembroke Welsh Corgi living in northern [Ontario, Canada](https://en.wikipedia.org/wiki/Ontario). | markdown

In table/objectlist sheets, the hint is passed in the header row of the table. By adding _md to the end of a column's header label, copytext will know to treat everything in that column as Markdown.

nameinstagram_accountbio_md
Pokyhttps://instagram.com/poky_corgi/Pembroke Welsh Corgi living in northern [Ontario, Canada](https://en.wikipedia.org/wiki/Ontario).
Tibbyhttps://instagram.com/tibbythecorgi/Half lion, half corgi. A pinch of bunny.

This is most useful when working with templates. Here's an example with the excellent Nunjucks library.

var fs = require('fs');
var copytext = require('copytext');
var nunjucks = require('nunjucks');
 
var data = copytext('./data/contacts.xlsx');  // a key/value sheet named CONTACTS 
var res = nunjucks.render('index.html', {DATA: data});

index.html

<ul>
  <li>{{ DATA.CONTACTS.name }}</li>
  <li>{{ DATA.CONTACTS.address }}</li>
  <li>{{ DATA.CONTACTS.phone }}</li>
</ul>

If you pass in a table/objectlist sheet, you can loop through it! (Assume CONTACTS is an objectlist.)

index.html

<ul>
  {% for contact in DATA.CONTACTS %}
  <li>{{ contact.name }} | {{ contact.address }} | {{ contact.phone }}</li>
  {% endfor %}
</ul>

Tests can be run with this command:

npm test

By Ryan Murphy.

Available under the MIT license.