{"id":22916444,"url":"https://github.com/errorname/google-docs-mustaches","last_synced_at":"2025-05-12T17:05:15.472Z","repository":{"id":39261753,"uuid":"170004460","full_name":"Errorname/google-docs-mustaches","owner":"Errorname","description":"📝Interpolate Google Docs files using mustaches and formatters","archived":false,"fork":false,"pushed_at":"2023-01-04T21:41:58.000Z","size":1136,"stargazers_count":28,"open_issues_count":22,"forks_count":12,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-12T17:04:55.626Z","etag":null,"topics":["google-docs","interpolation","javascript","mustaches","pdf","template","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Errorname.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-10T17:23:04.000Z","updated_at":"2024-11-15T11:37:31.000Z","dependencies_parsed_at":"2023-02-02T21:00:53.839Z","dependency_job_id":null,"html_url":"https://github.com/Errorname/google-docs-mustaches","commit_stats":null,"previous_names":["errorname/google-doc-to-pdf"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Errorname%2Fgoogle-docs-mustaches","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Errorname%2Fgoogle-docs-mustaches/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Errorname%2Fgoogle-docs-mustaches/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Errorname%2Fgoogle-docs-mustaches/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Errorname","download_url":"https://codeload.github.com/Errorname/google-docs-mustaches/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253784908,"owners_count":21963899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-docs","interpolation","javascript","mustaches","pdf","template","typescript"],"created_at":"2024-12-14T06:12:54.219Z","updated_at":"2025-05-12T17:05:15.432Z","avatar_url":"https://github.com/Errorname.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](https://raw.githubusercontent.com/Errorname/google-docs-mustaches/master/logo.png)\n\n# google-docs-mustaches\n\n📝Interpolate Google Docs files using mustaches and formatters\n\n[![](https://img.shields.io/npm/v/google-docs-mustaches.svg)](https://www.npmjs.com/package/google-docs-mustaches)\n[![](https://img.shields.io/github/license/Errorname/google-docs-mustaches.svg)](https://github.com/Errorname/google-docs-mustaches/blob/master/LICENSE)\n\n## How does this work?\n\n**google-docs-mustaches** will execute requests to the [Google Drive](https://developers.google.com/drive/api/v3/about-sdk) and [Google Docs](https://developers.google.com/docs/api/how-tos/overview) APIs to copy the file and interpolate its placeholders using the given data.\n\n## Installation\n\n```sh\nnpm install google-docs-mustaches\n```\n\n## Basic usage\n\nCreate a new Google Doc file and write the following text:\n\n```\nHello {{ firstname }} {{ lastname | uppercase }}!\n\nYou have {{ accounts[0].money }}€ in you account...\n```\n\nThen execute the following code\n\n```js\nimport Mustaches from 'google-docs-mustaches'\n\nconst mustaches = new Mustaches({\n  token: () =\u003e gapi.auth.getToken().access_token\n})\n\n// ID of the template\nconst source = '11rGORd6FRxOGERe7fh6LNQfyB48ZvOgQNH6GScK_FfA'\n\n// ID of the destination folder\nconst destination = '18mcqwbaXS8NOqZjztB3OUQAc5_P8M6-l'\n\nmustaches.interpolate({\n  source,\n  destination,\n  data: {\n    firstname: 'Thibaud',\n    lastname: 'Courtoison',\n    accounts: [{ money: 1500 }]\n  }\n})\n```\n\n## Documentation\n\n- [Constructor](#new-mustachesoptions-constructoroptions)\n- [Interpolate](#mustachesinterpolateoptions-interpolationoptions-id) the file\n- [Discovery](#mustachesdiscoveryoptions-discoveryoptions-placeholder) of the placeholders\n- [Export](#mustachesexportoptions-exportoptions-id) of the file\n- [Read Doc](#mustachesreaddocfile-id-promisegdoc)\n\n### `new Mustaches(options: ConstructorOptions)`\n\n```ts\ntype AccessToken = string\n\ninterface ConstructorOptions {\n  token: () =\u003e Promise\u003cAccessToken\u003e | AccessToken\n}\n```\n\n- `token` will be called at every request to the Google apis.\n\n\u003e **AccessToken** must have the following scopes:\n\u003e\n\u003e - https://www.googleapis.com/auth/drive\n\u003e - https://www.googleapis.com/auth/documents\n\nSee also: [How to retrieve the Google token?](#how-to-retrieve-the-google-token)\n\n### `mustaches.interpolate(options: InterpolationOptions): ID`\n\nThis method will interpolate from the `source` file and put the generated file into the `destination` folder.\n\n```ts\ntype ID = string\n\ninterface InterpolationOptions {\n  source: ID\n  destination?: ID\n  name?: string\n  data: Object\n  formatters?: Formatters\n  strict?: boolean\n}\n\ninterface Formatters {\n  [name: string]: Formatter\n}\n\ntype Formatter = (value: any, ...params: any[]) =\u003e string\n```\n\n- `source` is the ID of the file which will be interpolated.\n- `destination` is the ID of the destination folder where the new file will be put. If no destination is given, the new file will be put next to the `source` file.\n- `name` is the name of the newly created and interpolated google doc file.\n- `data` is the data given for the [interpolation](#interpolation)\n- `formatters` will be used for [interpolation](#interpolation)\n- `strict` indicates whether to use [strict mode](#strict-mode) or not.\n\n### `mustaches.discovery(options: DiscoveryOptions): Placeholder[]`\n\nThis methods returns all the placeholders found in the `source` file. The placeholders will be interpolated to see what would have been the results if `interpolate` was called. This method will **not** mutate your source file, nor create a new one.\n\n```ts\ninterface DiscoveryOptions {\n  source: ID\n  data?: Object\n  formatters?: Formatters\n  strict?: boolean\n}\n```\n\n- `source` is the ID of the file which will be interpolated.\n- `data` is the data given for the [interpolation](#interpolation)\n- `formatters` will be used for [interpolation](#interpolation)\n- `strict` indicates whether to use [strict mode](#strict-mode) or not.\n\n### `mustaches.export(options: ExportOptions): ID`\n\nThis methods will copy a file into the mimeType given in argument. The method will return the id of the newly created file.\n\n```ts\ninterface ExportOptions {\n  file: ID\n  mimeType: MimeType\n  name?: string\n  destination?: ID\n}\n\nenum MimeType {\n  pdf = 'application/pdf',\n  text = 'plain/text'\n}\n```\n\n- `file` is the ID of the file which will be exported.\n- `mimeType` is the type to export the file to.\n- `name` is the name of the newly exported file.\n- `destination` is the ID of the destination folder where the new file will be put. If no destination is given, the new file will be put next to the `file` to given in argument.\n\n### `mustaches.readDoc(file: ID): Promise\u003cGDoc\u003e`\n\nThis method will return the full content of the file.\n\nThis is simply a wrapper of the GDoc API to read the content of the document.\n\n## Interpolation\n\n### Mustaches\n\nThe **double brackets** notation (also known as **mustaches**) is used to define placeholders:\n\n```\nMy name is {{ firstname }}. Nice to meet you!\n```\n\nDuring the interpolation, the placeholder will be replaced with the content of the `options.data` object.\n\n```js\n{\n  firstname: 'Thibaud'\n}\n```\n\n```\nMy name is Thibaud. Nice to meet you!\n```\n\n### Path notation\n\nYou can use **nested objects and arrays** for the interpolation:\n\n```\n{{ pokemons[1].name }}, I choose you!\n```\n\nWith the following `options.data`\n\n```js\n{\n  pokemons: [\n    {\n      name: 'Eevee',\n      level: 12\n    },\n    {\n      name: 'Pikachu',\n      level: 25\n    }\n  ]\n}\n```\n\nWill become:\n\n```\nPikachu, I choose you!\n```\n\n_Warning: If you use an undefined variable as input, it will be resolved as an empty string. See [Strict mode](#strict-mode)_\n\n### Formatters\n\nYou can use **formatters** to print your data and **more complex objects** any way you want.\nIn addition of the input variable, they can accept parameters which can be of the following primitive types: Number, Boolean, String or can be a variable which will be evaluated from `options.data`.\n\nThere is a number of available formatters, but you can also **write your owns** in `options.formatters`.\n\n```\nHi {{ name | uppercase }}. Today is {{ today | printDay('en-US') }}, tomorrow is {{ tomorrow | printDay('en-US') }}.\n```\n\nWith the following `options`:\n\n```js\n{\n  data: {\n    name: \"Courtoison\",\n    today: new Date(),\n    tomorrow: new Date(new Date().setDate(new Date().getDate()+1))\n  },\n  formatters: {\n    printDay: (date, locale) =\u003e date.toLocaleDateString(locale,{weekday: 'long'})\n  }\n}\n```\n\nWill become:\n\n```\nHi COURTOISON. Today is Tuesday, tomorrow is Wednesday.\n```\n\n**Available formatters:**\n\n- **lowercase**: `HeLLo` =\u003e `hello`\n- **uppercase**: `wOrLd` =\u003e `WORLD`\n- **capitalize**: `heLLO wOrlD` =\u003e `Hello World`\n- **money(locale, currencyISO, fractionDigits = 0)**: `1500 | money(\"us\", \"USD\", 2)` =\u003e `$1500.00`. (Currency ISO Codes)[https://en.wikipedia.org/wiki/ISO_4217#Active_codes]\n- **image(width, height)**: Transform an url string to an image\n- _More to come..._\n\n_Warning: If you use an undefined formatter it will be simply ignored, which could lead to unexpected results if you're chaining them. See [Strict mode](#strict-mode)_\n\n### Strict mode\n\nBy default, _google-docs-mustaches_ is failing safely, which means that you don't have to worry about using an undefined variable or an unknown formatter, the generated errors will be catched and treated by the program itself. However, you might face unexpected behaviour if for example, you chain several formatters and one of them is misspelled, it would be ignored and the output of your formatters pipeline won't match your expectations.\n\nTo avoid this, we provide a strict mode for `.interpolate` and `.discovery`. Instead of using an empty string or your fallback when encountering an undefined variable, it will throw an exception, aborting immediately the interpolation of your document.\n\n## How to retrieve the Google token?\n\nIf you are using `google-docs-mustaches` from inside a browser, you can follow [this tutorial](https://developers.google.com/api-client-library/javascript/start/start-js).\n\nIf you are using `google-docs-mustaches` in Node.js, you can follow [this one](https://github.com/googleapis/google-api-nodejs-client#oauth2-client).\n\n\u003e **Note:** Your AccessToken must have the following scopes:\n\u003e\n\u003e - https://www.googleapis.com/auth/drive\n\u003e - https://www.googleapis.com/auth/documents\n\n## Limitations\n\n**google-docs-mustaches** uses Google Drive and Google Docs apis. This means any limitation and changes to those APIs may affect this library.\n\nBelow is a list of the current known limitations:\n\n- There is a 10Mo limit to the `export` method of the Google Drive API. Trying to export a bigger file will result in an HTTP Error. [Source](https://developers.google.com/drive/api/v3/reference/files/export)\n\n## Want to help?\n\nGreat! If you want to contribute to **google-docs-mustaches**, go check out the [Contributor documentation](/dev) to get started!\n\n## Supported environments\n\nWe use [cross-fetch](https://www.npmjs.com/package/cross-fetch) for compatibility with most environment.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferrorname%2Fgoogle-docs-mustaches","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferrorname%2Fgoogle-docs-mustaches","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferrorname%2Fgoogle-docs-mustaches/lists"}