Skip to content

A library for wrapping (breaking) long lines of large texts into limited-length lines, based on given options

License

Notifications You must be signed in to change notification settings

mirismaili/text-wrapper

Repository files navigation

npm (scoped) Dependencies Status devDependencies Status Known Vulnerabilities install size
Build Status Coverage Status
Commitizen friendly GitHub forks GitHub stars
GitHub

Text-Wrapper

A library for wrapping (breaking) long lines of large texts into limited-length lines, based on given options


Table of Contents

Installation

  • In a npm project, run:

    npm install text-wrapper
  • In a raw browser-target project, use bundled version:

    <script src=".../bundle.umd.js"></script>

    Download the latest version of bundle.umd.js file from Releases page. There is also an ESM-bundle version that you can use it (just if you know what you do!).

Basic Usage

  1. Get access to wrapper() function:

    // Below line is not required when you import the module in your HTML 
    // using <script> tag. it will be done automatically in that case.
    const text_wrapper_lib = require('text-wrapper')  
    
    const wrapper = text_wrapper_lib.wrapper

    Or through ES6-module-import way:

    import {wrapper} from 'text-wrapper'
  2. Take the job:

    const wrappedOutput = wrapper(tooLongText)

    See: Sample Input / Output


By default, long lines will be broken after 100th character (max) (except white-spaces) (tab-character length will be calculated). You can customize this behavior:

const wrappedOutput = wrapper(tooLongText, {wrapOn: 120})

See Options for other possible customizations.

Sample Input / Output

Below snippet:

const input = 
// (From https://en.wikipedia.org/wiki/Solar_System):
`The Solar System is the gravitationally bound planetary system of the Sun and the objects that orbit it, either directly or indirectly. Of the objects that orbit the Sun directly, the largest are the eight planets, with the remainder being smaller objects, such as the five dwarf planets and small Solar System bodies. Of the objects that orbit the Sun indirectly—the moons—two are larger than the smallest planet, Mercury.

The Solar System formed 4.6 billion years ago from the gravitational collapse of a giant interstellar molecular cloud. The vast majority of the system's mass is in the Sun, with the majority of the remaining mass contained in Jupiter. The four smaller inner planets, Mercury, Venus, Earth and Mars, are terrestrial planets, being primarily composed of rock and metal. The four outer planets are giant planets, being substantially more massive than the terrestrials. The two largest, Jupiter and Saturn, are gas giants, being composed mainly of hydrogen and helium; the two outermost planets, Uranus and Neptune, are ice giants, being composed mostly of substances with relatively high melting points compared with hydrogen and helium, called volatiles, such as water, ammonia and methane. All eight planets have almost circular orbits that lie within a nearly flat disc called the ecliptic.`

console.log(wrapper(input, {wrapOn: 80}))

will out:

sample-output.png

Advanced Usage

Although you can still use wrapper() function without any limitation, but for advanced usage, it's recommended to first make a new instance and then work with its wrap() method. So first:

const TextWrapper = text_wrapper_lib.default

or:

import TextWrapper from 'text-wrapper'

and then instantiate and do the job:

const textWrapper = new TextWrapper()
const wrappedOutput = textWrapper.wrap(inputText)

Options

You can pass your custom options to the constructor:

new TextWrapper(options)

or to the wrapper() function:

wrapper(inputText, options)

Examples

new TextWrapper({
	tabLength: 2,
	wrapOn: 120,
})
new TextWrapper({
	tabLength: 8,
	continuationIndent: '\t',
})
new TextWrapper({
	wrapOn: 95,
	tabLength: 3,
	breakableCharacters: /\W/,   // Any non-word character (equal to [^a-zA-Z0-9_])
	continuationIndent: '    ',  // 4 spaces
})

The meaning of each option + Default values and Data-types

You can find these documentations and information in source-codes as well. This is a Typescript project. Or refer to docs (Thank TypeDoc).

wrapOn: number = 100

This is the most common option. It determines the maximum allowed length of each line. The words exceed this rule will go to the next line. There are some configurable options to say the program how does this work, which are coming ...

Note: Sometimes this is not possible, beacuse there is no breakable character (space, etc) until the limitation (wrapOn value). In these cases, the line will break later, but as soon as possible.

tabLength: number = 4

This determines the max-length that should be considered for tab-characters ('\t'). Notice that the length of each tab-character is depended on its location in its line. For example, if this option is set to 4, then the length of '\tA' will appear 5 and the length of 'A\t' will appear 4.

breakableCharacters: RegExp = /[^\w\xA0]/

Long lines don't break at any where the length is exceeded. But it occurs only on word-boundaries by default. So this options has been set to /[^\w\xA0]/ to be broken on any non-word character (/^\w/ === /[^a-zA-Z0-9_]/) except a special white-space character named non-breakable space ('\xA0').

Note: This RegExp will be tested against only a single character (each time)!

allowedExceedingCharacters: RegExp = /\s/

This determines which characters are allowed to exceed the limitation (after wrapOn value). By default, this has been set to /\s/ to allow any white-space character. new-line-character ('\n') will be ignored, anyway.

Note: This RegExp will be tested against only a single character (each time)!

continuationIndent: string = ''

This value will be added after each line-break ('\n') character that this tool adds to the text. So it appears in the leading of each new line (not the already-present lines).

Unicode support

Unicode character classes are not supported widely, but if you just want distinct between word-characters and non-word characters, add a u flag to breakableCharacters default value:

{ breakableCharacters: /[^\w\xA0]/u }

Note: Unicode-aware regular expressions needs ES2015 at least. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode#Specifications

markers: An advanced way to get access to the process result

In cases, you don't want the final output itself (wrappedText), but you want a pure result of the process, markers is that you want! It's an array of all offsets that input-text needs line-breaks at them (to be wrapped correctly). To better understanding, we can reproduce the final output (wrappedText) using markers in a loop. Suppose you have an inputText, a wrapOptions object and an alreadyPresentIndents and:

const wrapResult = new TextWrapper(wrapOptions).wrap(inputText, alreadyPresentIndents)

const output = wrapResult.wrappedText
const markers = wrapResult.markers

Then:

const indentsN = alreadyPresentIndents + wrapOptions.continuationIndent

let anotherOutput = ''
let a = 0
for (const b of markers) {
    anotherOutput += input.slice(a, b) + '\n' + indentsN
    a = b
}

anotherOutput += input.slice(a)

expect(anotherOutput).toBe(output)

This is one of the unit tests that this library must pass! (See "Reproduce output using markers" in jest/unit/text-wrapper.ts)

Wrap wrapped!

What happens if you double-wrap an input-text? This is another of unit tests in jest/unit/text-wrapper.ts:

test('Wrap wrapped!', () => 
     expect(textWrapper.wrap(output, alreadyIndents).wrappedText).toBe(output))

Debug

This library uses npm debug library (as its only dependency). The API has been completely exported by this library and you have full control over it. To access:

const textWrapperDebug = require('../dist/main.umd.js').debug

Or:

import {debug as textWrapperDebug} from 'text-wrapper'

Then you just need to know debug package. For example, to enable debug-mode (according to this) write:

textWrapperDebug.enable('text-wrapper:*')

Note 1: In this package, debug-mode is disabled by default (see debug.disable() in src/TextWrapper.ts). So even when DEBUG environment-variable is set to * you have no debug output from this package.

Note 2: All debug-namespaces (see debug's docs) start with text-wrapper:.

Technical Overview

#Javascript
#npm

Source:
  https://github.com/mirismaili/text-wrapper

Targets:
  All ES6+ Javascript environments
  Tested on: Node 10, 11, 12 / Chromium: 76

Release 1 (npm):
  https://www.npmjs.com/package/text-wrapper

Release 2 (all):
  https://github.com/mirismaili/text-wrapper/releases

Documentation (full):
  https://mirismaili.github.io/text-wrapper/

Workflow:
  https://github.com/users/mirismaili/projects/1

Distribution-type: library

Executables: none

Most important used technologies:
  ● jest (test framework)
  ● puppeteer (browser-based end-to-end test)
  ● codecov (test-coverage report) - Report
  ● rollup.js (bundle tool)
  ● Typescript
  ● Travis (CI) - Log
  ● commitizen (conventional commits)
  ● semantic-release (automatic version and release manager)

Dependencies #: 1

Dev-dependencies #: 37