justify cells in tables
							parent
							
								
									3fb524169f
								
							
						
					
					
						commit
						1a552f1225
					
				|  | @ -1,7 +1,9 @@ | ||||||
| const htmlEntities = require('html-entities'); | const htmlEntities = require('html-entities'); | ||||||
|  | const justify = require('justify-text'); | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
| 
 | 
 | ||||||
|  | 	max_column_width: 20, | ||||||
| 	clean(str) { | 	clean(str) { | ||||||
| 		str = str.replace(/<\/?[^>]+(>|$)/g, ""); | 		str = str.replace(/<\/?[^>]+(>|$)/g, ""); | ||||||
| 		str = str.replace(/(\r\n|\n|\r)/gm, ""); | 		str = str.replace(/(\r\n|\n|\r)/gm, ""); | ||||||
|  | @ -54,13 +56,20 @@ module.exports = { | ||||||
| 			for (let c=0;c<n_cols;c++) { | 			for (let c=0;c<n_cols;c++) { | ||||||
| 				let l = items[r][c].length; | 				let l = items[r][c].length; | ||||||
| 				if (l>column_widths[c]) { | 				if (l>column_widths[c]) { | ||||||
|  | 					if (l > this.max_column_width) { | ||||||
|  | 						column_widths[c] = this.max_column_width; | ||||||
|  | 					} | ||||||
|  | 					else { | ||||||
| 						column_widths[c] = l; | 						column_widths[c] = l; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// justify
 | ||||||
| 		for (let r=0;r<n_rows;r++) { | 		for (let r=0;r<n_rows;r++) { | ||||||
| 			for (let c=0;c<n_cols;c++) { | 			for (let c=0;c<n_cols;c++) { | ||||||
| 				items[r][c] = items[r][c].padEnd(column_widths[c], " "); | 				items[r][c] = justify.ljust(items[r][c], column_widths[c], ""); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -645,6 +645,11 @@ | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/justify-text": { | ||||||
|  |       "version": "1.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/justify-text/-/justify-text-1.1.3.tgz", | ||||||
|  |       "integrity": "sha512-iOZ295bkDRnbEx9a+g7zzTZQtBYS0KlsDYpVmCOc66af6ngaoJ4mXdo6ILbyW1HQYHEoIXh1wxJpoKCzzPMXSw==" | ||||||
|  |     }, | ||||||
|     "node_modules/levn": { |     "node_modules/levn": { | ||||||
|       "version": "0.3.0", |       "version": "0.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", |       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", | ||||||
|  |  | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2017 Julian Nicholls | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in all | ||||||
|  | copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  | SOFTWARE. | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | # justify-text | ||||||
|  | 
 | ||||||
|  | This is a simple module, which allows for left or right justifying text | ||||||
|  | in a given width. The padding character can be specified, and it defaults | ||||||
|  | to a space. | ||||||
|  | 
 | ||||||
|  | Numbers are explicily handled now, so they do not need to be converted to | ||||||
|  | a string before passing them to `ljust` or `rjust` any more. | ||||||
|  | 
 | ||||||
|  | If the padding width specified is less than the length of the initial string, | ||||||
|  | no truncation occurs. | ||||||
|  | 
 | ||||||
|  | ## Installation | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | npm install -S justify-text | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | or | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | yarn add justify-text | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Functions | ||||||
|  | 
 | ||||||
|  | `ljust()` and `rjust()` take a string or number, a width to render it in, | ||||||
|  | and an optional padding character, which is a space by default. | ||||||
|  | 
 | ||||||
|  | ``` js | ||||||
|  | ljust(string, width, padding=' ') | ||||||
|  | rjust(string, width, padding=' ') | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Usage | ||||||
|  | 
 | ||||||
|  | ``` js | ||||||
|  | const { ljust, rjust } = require('justify-text'); | ||||||
|  | 
 | ||||||
|  | ljust('text', 7); | ||||||
|  | // => "text   " | ||||||
|  | 
 | ||||||
|  | ljust('text', 6, '0'); | ||||||
|  | // => "text00" | ||||||
|  | 
 | ||||||
|  | rjust('text', 8); | ||||||
|  | // => "    text" | ||||||
|  | 
 | ||||||
|  | rjust('longtext', 7); | ||||||
|  | // => "longtext", i.e. unchanged because it is already more than 7 characters | ||||||
|  | 
 | ||||||
|  | rjust('text', 9, '.'); | ||||||
|  | // => ".....text" | ||||||
|  | 
 | ||||||
|  | rjust(936, 5); | ||||||
|  | // => "  936" | ||||||
|  | 
 | ||||||
|  | ljust(780.25, 8); | ||||||
|  | // => "780.25  " | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## License | ||||||
|  | 
 | ||||||
|  | MIT | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | declare module "justify-text" { | ||||||
|  |   export function ljust(input: string | number, width: number, padding?: string); | ||||||
|  |   export function rjust(input: string | number, width: number, padding?: string); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | function padding(str, width, fillChar) { | ||||||
|  |   const padBytes = width - str.length; | ||||||
|  |   let padding = ''; | ||||||
|  | 
 | ||||||
|  |   for (let i = 0; i < padBytes; ++i) { | ||||||
|  |     padding += fillChar; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return padding; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | exports.ljust = function (str, width = 0, fillChar = ' ') { | ||||||
|  |   str = String(str); | ||||||
|  | 
 | ||||||
|  |   return str + padding(str, width, fillChar); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | exports.rjust = function (str, width = 0, fillChar = ' ') { | ||||||
|  |   str = String(str); | ||||||
|  | 
 | ||||||
|  |   return padding(str, width, fillChar) + str; | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | { | ||||||
|  |   "name": "justify-text", | ||||||
|  |   "version": "1.1.3", | ||||||
|  |   "description": "left or right justify text", | ||||||
|  |   "main": "index.js", | ||||||
|  |   "types": "index.d.ts", | ||||||
|  |   "scripts": { | ||||||
|  |     "test": "jest", | ||||||
|  |     "prepublishOnly": "npm test" | ||||||
|  |   }, | ||||||
|  |   "author": "Julian Nicholls", | ||||||
|  |   "license": "MIT", | ||||||
|  |   "repository": "https://github.com/JulianNicholls/npm-justify-text", | ||||||
|  |   "devDependencies": { | ||||||
|  |     "jest": "^26.4.0" | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,181 @@ | ||||||
|  | const { ljust, rjust } = require('../index'); | ||||||
|  | 
 | ||||||
|  | describe('ljust with strings', () => { | ||||||
|  |   test('empty string', () => { | ||||||
|  |     const str = ljust('', 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('     '); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('empty string with no width specified', () => { | ||||||
|  |     const str = ljust(''); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe(''); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = ljust('one', 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('one  '); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = ljust('two', 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('twoxxxx'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = ljust('three', 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('three'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = ljust('four', 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('four'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('ljust with integers', () => { | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = ljust(999, 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('999  '); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = ljust(4867, 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('4867xxx'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = ljust(789, 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('789'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = ljust(7890, 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('7890'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('ljust with non-integers', () => { | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = ljust(999.8, 7); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('999.8  '); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = ljust(4867.3, 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('4867.3x'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = ljust(789.5, 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('789.5'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = ljust(7890.123, 6); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('7890.123'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('rjust with strings', () => { | ||||||
|  |   test('empty string', () => { | ||||||
|  |     const str = rjust('', 4); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('    '); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('empty string with no width specified', () => { | ||||||
|  |     const str = rjust(''); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe(''); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = rjust('one', 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('  one'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = rjust('two', 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('xxxxtwo'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = rjust('three', 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('three'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = rjust('four', 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('four'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('rjust with integers', () => { | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = rjust(999, 5); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('  999'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = rjust(4867, 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('xxx4867'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = rjust(7890, 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('7890'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = rjust(78901, 3); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('78901'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('rjust with non-integers', () => { | ||||||
|  |   test('space padding', () => { | ||||||
|  |     const str = rjust(999.87, 7); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe(' 999.87'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('character padding', () => { | ||||||
|  |     const str = rjust(486.3, 7, 'x'); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('xx486.3'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No padding required', () => { | ||||||
|  |     const str = rjust(789.58, 6); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('789.58'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('No space for padding', () => { | ||||||
|  |     const str = rjust(7890.1234, 7); | ||||||
|  | 
 | ||||||
|  |     expect(str).toBe('7890.1234'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | @ -15,6 +15,7 @@ | ||||||
|         "express-rate-limit": "^6.0.5", |         "express-rate-limit": "^6.0.5", | ||||||
|         "html-entities": "^2.3.2", |         "html-entities": "^2.3.2", | ||||||
|         "jsdom": "^16.4.0", |         "jsdom": "^16.4.0", | ||||||
|  |         "justify-text": "^1.1.3", | ||||||
|         "turndown": "^7.0.0", |         "turndown": "^7.0.0", | ||||||
|         "url": "^0.11.0" |         "url": "^0.11.0" | ||||||
|       } |       } | ||||||
|  | @ -660,6 +661,11 @@ | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/justify-text": { | ||||||
|  |       "version": "1.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/justify-text/-/justify-text-1.1.3.tgz", | ||||||
|  |       "integrity": "sha512-iOZ295bkDRnbEx9a+g7zzTZQtBYS0KlsDYpVmCOc66af6ngaoJ4mXdo6ILbyW1HQYHEoIXh1wxJpoKCzzPMXSw==" | ||||||
|  |     }, | ||||||
|     "node_modules/levn": { |     "node_modules/levn": { | ||||||
|       "version": "0.3.0", |       "version": "0.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", |       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", | ||||||
|  | @ -1661,6 +1667,11 @@ | ||||||
|         "xml-name-validator": "^3.0.0" |         "xml-name-validator": "^3.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "justify-text": { | ||||||
|  |       "version": "1.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/justify-text/-/justify-text-1.1.3.tgz", | ||||||
|  |       "integrity": "sha512-iOZ295bkDRnbEx9a+g7zzTZQtBYS0KlsDYpVmCOc66af6ngaoJ4mXdo6ILbyW1HQYHEoIXh1wxJpoKCzzPMXSw==" | ||||||
|  |     }, | ||||||
|     "levn": { |     "levn": { | ||||||
|       "version": "0.3.0", |       "version": "0.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", |       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
|     "express-rate-limit": "^6.0.5", |     "express-rate-limit": "^6.0.5", | ||||||
|     "html-entities": "^2.3.2", |     "html-entities": "^2.3.2", | ||||||
|     "jsdom": "^16.4.0", |     "jsdom": "^16.4.0", | ||||||
|  |     "justify-text": "^1.1.3", | ||||||
|     "turndown": "^7.0.0", |     "turndown": "^7.0.0", | ||||||
|     "url": "^0.11.0" |     "url": "^0.11.0" | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue