{"id":15652359,"url":"https://github.com/jvandenaardweg/ssml-split","last_synced_at":"2025-09-02T11:40:42.741Z","repository":{"id":57368991,"uuid":"231319293","full_name":"jvandenaardweg/ssml-split","owner":"jvandenaardweg","description":"Splits SSML strings into batches AWS Polly ánd Google's Text to Speech API can consume","archived":false,"fork":false,"pushed_at":"2020-09-25T10:32:20.000Z","size":651,"stargazers_count":15,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-09T16:45:36.545Z","etag":null,"topics":["alexa","amazon-alexa","aws","aws-polly","google","google-assistant","google-text-to-speech","speech-api","speech-synthesis-markup-language","split","splits-ssml-strings","splitter","ssml","ssml-parsing","text-to-speech","tts","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/jvandenaardweg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-02T06:15:03.000Z","updated_at":"2024-05-16T19:04:29.000Z","dependencies_parsed_at":"2022-09-15T16:04:12.429Z","dependency_job_id":null,"html_url":"https://github.com/jvandenaardweg/ssml-split","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/jvandenaardweg/ssml-split","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jvandenaardweg%2Fssml-split","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jvandenaardweg%2Fssml-split/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jvandenaardweg%2Fssml-split/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jvandenaardweg%2Fssml-split/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jvandenaardweg","download_url":"https://codeload.github.com/jvandenaardweg/ssml-split/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jvandenaardweg%2Fssml-split/sbom","scorecard":{"id":544695,"data":{"date":"2025-08-11","repo":{"name":"github.com/jvandenaardweg/ssml-split","commit":"155368cac567b042fc47c87b53089784bc54d5c5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/18 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/npmpublish.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npmpublish.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/npmpublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npmpublish.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/npmpublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npmpublish.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/npmpublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npmpublish.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/npmpublish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/jvandenaardweg/ssml-split/tests.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   3 out of   3 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 13 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"65 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w7rc-rwvf-8q5r","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-px4h-xg32-q955","Warn: Project is vulnerable to: GHSA-3j8f-xvm3-ffx4","Warn: Project is vulnerable to: GHSA-4p35-cfcx-8653","Warn: Project is vulnerable to: GHSA-7f3x-x4pr-wqhj","Warn: Project is vulnerable to: GHSA-jpp7-7chh-cf67","Warn: Project is vulnerable to: GHSA-q6wq-5p59-983w","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T09:11:18.342Z","repository_id":57368991,"created_at":"2025-08-20T09:11:18.342Z","updated_at":"2025-08-20T09:11:18.342Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273279516,"owners_count":25077317,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["alexa","amazon-alexa","aws","aws-polly","google","google-assistant","google-text-to-speech","speech-api","speech-synthesis-markup-language","split","splits-ssml-strings","splitter","ssml","ssml-parsing","text-to-speech","tts","typescript"],"created_at":"2024-10-03T12:42:09.332Z","updated_at":"2025-09-02T11:40:42.695Z","avatar_url":"https://github.com/jvandenaardweg.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SSML Split\n\nSplits SSML strings into batches AWS Polly ánd Google's Text to Speech API can consume.\n\n[![Build Status](https://img.shields.io/github/workflow/status/jvandenaardweg/ssml-split/Publish%20NPM%20Package)](https://github.com/jvandenaardweg/ssml-split/actions)\n[![NPM Package](https://img.shields.io/npm/dm/ssml-split.svg)](https://npmjs.com/package/ssml-split)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0397a395ee25486395d49ababf9407d9)](https://www.codacy.com/manual/jvandenaardweg/ssml-split?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=jvandenaardweg/ssml-split\u0026amp;utm_campaign=Badge_Grade)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![Twitter Follow](https://img.shields.io/twitter/url/https/twitter.com/jvandenaardweg.svg?style=social\u0026label=Follow%20%40jvandenaardweg)](https://twitter.com/jvandenaardweg)\n\n## Features\n\n*  Splits your large SSML into batches AWS Polly and Google's Text to Speech API can consume.\n*  Makes sure you stay below the API character limitations by configuring a `hardLimit`.\n*  Creates the least possible batch size to limit your requests to the Text to Speech API's.\n*  Will split text at the nearest `.`, `,`, `;` or space. Can be configured.\n*  Sanitizes your SSML by removing new lines, excessive white spaces, and empty tags, resulting in less characters used.\n*  Uses TypeScript so you can enjoy the type safety and documentation that comes with it.\n\nBased on [polly-ssml-split](https://github.com/oleglegun/polly-ssml-split) by [@oleglegun](https://github.com/oleglegun)\n\n## Documentation\n\n*  [Installation](#installation) - Walk through how to install SSML Split.\n*  [Usage](#usage) - Read how SSML Split works with the available options.\n*  [Recommended Options](#recommended-options) - Use these options to get started quickly.\n*  [Contributing](./CONTRIBUTING.md) - Become familiar with how to contribute back to SSML Split\n*  [Code of Conduct](./CODE_OF_CONDUCT.md) - Be a good citizen by following these repository rules\n\n## Installation\nInstall the package with:\n\n```sh\nnpm install ssml-split --save\n```\n\n## Usage\n\nImport the package and set the options. Use the `.split()` method to split your SSML string. You can tweak the `softLimit` to see what works for you. I suggest you keep the `hardLimit` at the limitation limit of the respective API:\n\n```typescript\nimport SSMLSplit from 'ssml-split';\n\nconst ssmlSplit = new SSMLSplit({\n  // The service you are using: \"google\" or \"aws\"\n  synthesizer: 'google',\n  // Finds a possible split moment starting from 4000 characters\n  softLimit: 4000,\n  // Google Text to Speech limitation\n  hardLimit: 5000,\n  // Allow to split large paragraphs, set to false to keep your \u003cp\u003e\u003c/p\u003e intact\n  breakParagraphsAboveHardLimit: true\n});\n\nconst batches = ssmlSplit.split('\u003cspeak\u003eyour long ssml here\u003c/speak\u003e');\n```\n\n\n| Option              | Type | Default                       | Description                                                                           |\n| ------------------- | ---- | ------------------------- | ------------------------------------------------------------------------------------- |\n| `synthesizer` | `string` | `aws`  | Set to which synthesizer you are using. Useful for when you use `breakParagraphsAboveHardLimit`. It allows the library to determine the correct break length, as that differs per synthesizer service. |\n| `softLimit` | `number` | `1500`  | The amount of characters the script will start trying to break-up your SSML in multiple parts. You can tweak this number to see what works for you. |\n| `hardLimit` | `number` | `3000`  | The amount of characters the script should stay below for maximum size per SSML part. If any batch size goes above this, the script will error. This hard limit is the character limit of the AWS or Google API you are using. |\n| `breakParagraphsAboveHardLimit` | `boolean` | `false` | Set to `true` to allow the script to break up large paragraphs by removing the `\u003cp\u003e` and replacing the `\u003c/p\u003e` with a `\u003cbreak strength=\"x-strong\" /\u003e` (for `aws`) or `\u003cbreak strength=\"x-weak\" /\u003e` (for `google`). Which results in the same pause. Requires option `synthesizer` to be set. |\n| `extraSplitChars` | `string` | `,;.` | Characters that can be used as split markers for plain text.\n\n### About: synthesizer\nBy using the option `synthesizer: 'google'` the library will include counting SSML tags characters to determine the best possible split moment. This makes the library also work with Google's Text to Speech API.\n\nFor example:\n`\u003cspeak\u003e\u003cp\u003esome text\u003c/p\u003e\u003c/speak\u003e`\n\nThe default behaviour would count that as 9 characters, which is fine for AWS Polly, but not for Google's Text to Speech API.\n\nWith `synthesizer: 'google'` it will be count as 31 characters, [just like Google's Text to Speech API counts it](https://cloud.google.com/text-to-speech/pricing?hl=en).\n\nThis should prevent you from seeing this error when using Google's Text to Speech API:\n\n```bash\nINVALID_ARGUMENT: 5000 characters limit exceeded.\n```\n\n### About: breakParagraphsAboveHardLimit\nBy adding the option `breakParagraphsAboveHardLimit: true` you allow the script to break up large paragraphs by removing the `\u003cp\u003e` and replacing the `\u003c/p\u003e` with a `\u003cbreak strength=\"x-strong\" /\u003e` for AWS or `\u003cbreak strength=\"x-weak\" /\u003e` for Google. Which results in the same pause. This allows the library to properly split large paragraphs.\n\nUsing this option will result in 20 more characters, per paragraph, to your usage when using Google's Text to Speech API.\n\nIf you work with large paragraphs and you do not use this option, you might run into errors like `SSML tag appeared to be too long`.\n\nUsing this option is recommended when you have SSML length that goes above the `hardLimit`.\n\n### Recommended options\n#### AWS\n```javascript\nnew SSMLSplit({\n  synthesizer: 'aws',\n  softLimit: 2000,\n  hardLimit: 3000, // AWS Polly limitation\n  breakParagraphsAboveHardLimit: true, // optional, but recommended when you have large \u003cp\u003e's\n})\n```\n\n#### Google\n```javascript\nnew SSMLSplit({\n  synthesizer: 'google',\n  softLimit: 4000,\n  hardLimit: 5000, // Google Text to Speech API limitation\n  breakParagraphsAboveHardLimit: true, // optional, but recommended when you have large \u003cp\u003e's\n})\n```\n\n## About\nThe [polly-ssml-split](https://github.com/oleglegun/polly-ssml-split) by [@oleglegun](https://github.com/oleglegun) library already handles splitting of SSML correctly for AWS Polly, but wasn't working properly for Google's Text to Speech. So I just modified the package to fit my needs.\n\n### Changes compared to `polly-ssml-split`:\n*  Added `synthesizer` option to count characters based on the complete SSML tag and not just the included text characters. Which is required if you work with Google's Text to Speech API.\n*  Rewrote the library to use Typescript, so you get correct type checking in your Typescript project.\n*  Removed the `.configure` method and use the class constructor method for it instead.\n*  Added `breakParagraphsAboveHardLimit` options to break up large paragraphs by removing the `\u003cp\u003e` and replacing the `\u003c/p\u003e` with a `\u003cbreak strength=\"x-strong\" /\u003e` for AWS or `\u003cbreak strength=\"x-weak\" /\u003e` for Google. Which results in the same pause. This allows the library to properly split the paragraph and to send less batches to the text to speech API's.\n*  Added more tests using Jest.\n\n## Development\n\nAny contribution is appreciated! Please read our [CONTRIBUTING.md](https://github.com/jvandenaardweg/ssml-split/blob/master/CONTRIBUTING.md) on how to contribute.\n\nUse a test-driven approach when developing new features or fixing bugs.\n\nDevelop:\n\n```bash\n$ npm install\n$ npm run dev\n```\n\nRun tests on file change:\n\n```bash\n$ npm test:watch\n```\n\nBuild Typescript to Javascript:\n```bash\n$ npm run build\n```\n\nRun all tests:\n\n```bash\n$ npm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjvandenaardweg%2Fssml-split","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjvandenaardweg%2Fssml-split","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjvandenaardweg%2Fssml-split/lists"}