Merge e6cb108ae4 into 67094980c9
				
					
				
			This commit is contained in:
		
						commit
						5861d9b9eb
					
				
							
								
								
									
										3
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -145,6 +145,9 @@ declare module '@vue/runtime-core' { | |||||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] |     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||||
|     NMenu: typeof import('naive-ui')['NMenu'] |     NMenu: typeof import('naive-ui')['NMenu'] | ||||||
|     NScrollbar: typeof import('naive-ui')['NScrollbar'] |     NScrollbar: typeof import('naive-ui')['NScrollbar'] | ||||||
|  |     NSpace: typeof import('naive-ui')['NSpace'] | ||||||
|  |     NSpin: typeof import('naive-ui')['NSpin'] | ||||||
|  |     NStatistic: typeof import('naive-ui')['NStatistic'] | ||||||
|     NSlider: typeof import('naive-ui')['NSlider'] |     NSlider: typeof import('naive-ui')['NSlider'] | ||||||
|     NSwitch: typeof import('naive-ui')['NSwitch'] |     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||||
|     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] |     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { describe, expect, it } from 'vitest'; | import { describe, expect, it } from 'vitest'; | ||||||
| import { getStringSizeInBytes } from './text-statistics.service'; | import { getStringSizeInBytes, textStatistics } from './text-statistics.service'; | ||||||
| 
 | 
 | ||||||
| describe('text-statistics', () => { | describe('text-statistics', () => { | ||||||
|   describe('getStringSizeInBytes', () => { |   describe('getStringSizeInBytes', () => { | ||||||
| @ -11,4 +11,155 @@ describe('text-statistics', () => { | |||||||
|       expect(getStringSizeInBytes('aaaaaaaaaa')).toEqual(10); |       expect(getStringSizeInBytes('aaaaaaaaaa')).toEqual(10); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   describe('textStatistics', () => { | ||||||
|  |     it('should return text statistics', () => { | ||||||
|  |       expect(textStatistics('a')).to.deep.eq({ | ||||||
|  |         chars: 1, | ||||||
|  |         chars_digits: 0, | ||||||
|  |         chars_lower: 1, | ||||||
|  |         chars_no_spaces: 1, | ||||||
|  |         chars_puncts: 0, | ||||||
|  |         chars_spaces: 0, | ||||||
|  |         chars_upper: 0, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 1, | ||||||
|  |         words_no_puncs: 1, | ||||||
|  |         read_time: 0.3, | ||||||
|  |         words_uniques: 1, | ||||||
|  |         words_uniques_ci: 1, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics('A')).to.deep.eq({ | ||||||
|  |         chars: 1, | ||||||
|  |         chars_digits: 0, | ||||||
|  |         chars_lower: 0, | ||||||
|  |         chars_no_spaces: 1, | ||||||
|  |         chars_puncts: 0, | ||||||
|  |         chars_spaces: 0, | ||||||
|  |         chars_upper: 1, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 1, | ||||||
|  |         words_no_puncs: 1, | ||||||
|  |         read_time: 0.3, | ||||||
|  |         words_uniques: 1, | ||||||
|  |         words_uniques_ci: 1, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics('a a')).to.deep.eq({ | ||||||
|  |         chars: 3, | ||||||
|  |         chars_digits: 0, | ||||||
|  |         chars_lower: 2, | ||||||
|  |         chars_no_spaces: 2, | ||||||
|  |         chars_puncts: 0, | ||||||
|  |         chars_spaces: 1, | ||||||
|  |         chars_upper: 0, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 2, | ||||||
|  |         words_no_puncs: 2, | ||||||
|  |         read_time: 0.6, | ||||||
|  |         words_uniques: 1, | ||||||
|  |         words_uniques_ci: 1, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics('A a ; 1')).to.deep.eq({ | ||||||
|  |         chars: 7, | ||||||
|  |         chars_digits: 1, | ||||||
|  |         chars_lower: 1, | ||||||
|  |         chars_no_spaces: 4, | ||||||
|  |         chars_puncts: 1, | ||||||
|  |         chars_spaces: 3, | ||||||
|  |         chars_upper: 1, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 4, | ||||||
|  |         words_no_puncs: 3, | ||||||
|  |         read_time: 0.8999999999999999, | ||||||
|  |         words_uniques: 3, | ||||||
|  |         words_uniques_ci: 2, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics('Some sentence! Une autre phrase ? « et avec des chiffres 1234 ! »')).to.deep.eq({ | ||||||
|  |         chars: 65, | ||||||
|  |         chars_digits: 4, | ||||||
|  |         chars_lower: 41, | ||||||
|  |         chars_no_spaces: 52, | ||||||
|  |         chars_puncts: 5, | ||||||
|  |         chars_spaces: 13, | ||||||
|  |         chars_upper: 2, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 3, | ||||||
|  |         words: 14, | ||||||
|  |         words_no_puncs: 10, | ||||||
|  |         read_time: 3, | ||||||
|  |         words_uniques: 10, | ||||||
|  |         words_uniques_ci: 10, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics(`Some sentence! Une autre phrase ? 
 | ||||||
|  |       « et avec des chiffres 1234 ! »`)).to.deep.eq({
 | ||||||
|  |         chars: 72, | ||||||
|  |         chars_digits: 4, | ||||||
|  |         chars_lower: 41, | ||||||
|  |         chars_no_spaces: 52, | ||||||
|  |         chars_puncts: 5, | ||||||
|  |         chars_spaces: 20, | ||||||
|  |         chars_upper: 2, | ||||||
|  |         lines: 2, | ||||||
|  |         sentences: 3, | ||||||
|  |         words: 14, | ||||||
|  |         words_no_puncs: 10, | ||||||
|  |         read_time: 3, | ||||||
|  |         words_uniques: 10, | ||||||
|  |         words_uniques_ci: 10, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics('12 35')).to.deep.eq({ | ||||||
|  |         chars: 5, | ||||||
|  |         chars_digits: 4, | ||||||
|  |         chars_lower: 0, | ||||||
|  |         chars_no_spaces: 4, | ||||||
|  |         chars_puncts: 0, | ||||||
|  |         chars_spaces: 1, | ||||||
|  |         chars_upper: 0, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 2, | ||||||
|  |         words_no_puncs: 2, | ||||||
|  |         read_time: 0.6, | ||||||
|  |         words_uniques: 2, | ||||||
|  |         words_uniques_ci: 2, | ||||||
|  |       }); | ||||||
|  |       expect(textStatistics(' 1 2 3. Other ')).to.deep.eq({ | ||||||
|  |         chars: 14, | ||||||
|  |         chars_digits: 3, | ||||||
|  |         chars_lower: 4, | ||||||
|  |         chars_no_spaces: 9, | ||||||
|  |         chars_puncts: 1, | ||||||
|  |         chars_spaces: 5, | ||||||
|  |         chars_upper: 1, | ||||||
|  |         lines: 1, | ||||||
|  |         sentences: 2, | ||||||
|  |         words: 4, | ||||||
|  |         words_no_puncs: 4, | ||||||
|  |         read_time: 1.2, | ||||||
|  |         words_uniques: 4, | ||||||
|  |         words_uniques_ci: 4, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(textStatistics('Az az er')).to.deep.eq({ | ||||||
|  |         chars: 8, | ||||||
|  |         chars_digits: 0, | ||||||
|  |         chars_lower: 5, | ||||||
|  |         chars_no_spaces: 6, | ||||||
|  |         chars_puncts: 0, | ||||||
|  |         chars_spaces: 2, | ||||||
|  |         chars_upper: 1, | ||||||
|  |         lines: 1, | ||||||
|  |         read_time: 0.8999999999999999, | ||||||
|  |         sentences: 1, | ||||||
|  |         words: 3, | ||||||
|  |         words_no_puncs: 3, | ||||||
|  |         words_uniques: 3, | ||||||
|  |         words_uniques_ci: 2, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,3 +1,24 @@ | |||||||
| export function getStringSizeInBytes(text: string) { | export function getStringSizeInBytes(text: string) { | ||||||
|   return new TextEncoder().encode(text).buffer.byteLength; |   return new TextEncoder().encode(text).buffer.byteLength; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export function textStatistics(text: string) { | ||||||
|  |   const words_no_puncts = text.replace(/\p{P}/ug, '').trim().split(/\s+/); | ||||||
|  |   const read_word_per_minutes = 200; | ||||||
|  |   return { | ||||||
|  |     chars: text.length, | ||||||
|  |     chars_no_spaces: text.replace(/\s+/ug, '').length, | ||||||
|  |     chars_upper: text.replace(/[^\p{Lu}]/ug, '').length, | ||||||
|  |     chars_lower: text.replace(/[^\p{Ll}]/ug, '').length, | ||||||
|  |     chars_digits: text.replace(/\D+/ug, '').length, | ||||||
|  |     chars_puncts: text.replace(/[^\p{P}]/ug, '').length, | ||||||
|  |     chars_spaces: text.replace(/\S/ug, '').length, | ||||||
|  |     words: text.trim().split(/\s+/).length, | ||||||
|  |     read_time: words_no_puncts.length / read_word_per_minutes * 60, | ||||||
|  |     words_no_puncs: words_no_puncts.length, | ||||||
|  |     words_uniques: (new Set(words_no_puncts)).size, | ||||||
|  |     words_uniques_ci: (new Set(words_no_puncts.map(s => s.toLowerCase()))).size, | ||||||
|  |     sentences: (`${text} `).split(/\w\s*[\.!\?][\s\p{P}]*\s/u).filter(s => s && s?.length > 0).length, | ||||||
|  |     lines: text.split(/\r\n|\r|\n/).length, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,19 +1,42 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { getStringSizeInBytes } from './text-statistics.service'; | import { formatMsDuration } from '../eta-calculator/eta-calculator.service'; | ||||||
|  | import { getStringSizeInBytes, textStatistics } from './text-statistics.service'; | ||||||
| import { formatBytes } from '@/utils/convert'; | import { formatBytes } from '@/utils/convert'; | ||||||
| 
 | 
 | ||||||
| const text = ref(''); | const text = ref(''); | ||||||
|  | const stats = computed(() => textStatistics(text.value)); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|   <c-card> |   <c-card> | ||||||
|     <c-input-text v-model:value="text" multiline placeholder="Your text..." rows="5" /> |     <c-input-text v-model:value="text" multiline placeholder="Your text..." rows="5" /> | ||||||
| 
 | 
 | ||||||
|     <div mt-5 flex> |     <n-space mt-3> | ||||||
|       <n-statistic label="Character count" :value="text.length" flex-1 /> |       <n-statistic label="Character count" :value="stats.chars" /> | ||||||
|       <n-statistic label="Word count" :value="text === '' ? 0 : text.split(/\s+/).length" flex-1 /> |       <n-statistic label="Word count" :value="stats.words" /> | ||||||
|       <n-statistic label="Line count" :value="text === '' ? 0 : text.split(/\r\n|\r|\n/).length" flex-1 /> |       <n-statistic label="Sentences count" :value="stats.sentences" /> | ||||||
|       <n-statistic label="Byte size" :value="formatBytes(getStringSizeInBytes(text))" flex-1 /> |       <n-statistic label="Line count" :value="stats.lines" /> | ||||||
|     </div> |       <n-statistic label="Byte size" :value="formatBytes(getStringSizeInBytes(text))" /> | ||||||
|  |     </n-space> | ||||||
|  | 
 | ||||||
|  |     <n-divider /> | ||||||
|  | 
 | ||||||
|  |     <n-space mt-3> | ||||||
|  |       <n-statistic label="Unique Word count" :value="stats.words_uniques" /> | ||||||
|  |       <n-statistic label="Unique Word count (case insensitive)" :value="stats.words_uniques_ci" /> | ||||||
|  |       <n-statistic label="Read Time" :value="formatMsDuration(stats.read_time * 1000)" /> | ||||||
|  |     </n-space> | ||||||
|  | 
 | ||||||
|  |     <n-divider /> | ||||||
|  | 
 | ||||||
|  |     <n-space> | ||||||
|  |       <n-statistic label="Chars (no spaces)" :value="stats.chars_no_spaces" /> | ||||||
|  |       <n-statistic label="Uppercase chars" :value="stats.chars_upper" /> | ||||||
|  |       <n-statistic label="Lowercase chars" :value="stats.chars_lower" /> | ||||||
|  |       <n-statistic label="Digit chars" :value="stats.chars_digits" /> | ||||||
|  |       <n-statistic label="Punctuations" :value="stats.chars_puncts" /> | ||||||
|  |       <n-statistic label="Spaces chars" :value="stats.chars_spaces" /> | ||||||
|  |       <n-statistic label="Word count (no punct)" :value="stats.words_no_puncs" /> | ||||||
|  |     </n-space> | ||||||
|   </c-card> |   </c-card> | ||||||
| </template> | </template> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user