feat(tool): lorem ipsum generator

This commit is contained in:
Corentin Thomasset 2022-04-14 00:00:29 +02:00
parent 1134e0b822
commit 5dcb2ed95c
No known key found for this signature in database
GPG key ID: DBD997E935996158
4 changed files with 286 additions and 0 deletions

View file

@ -12,6 +12,7 @@ import { tool as gitMemo } from './git-memo';
import { tool as baseConverter } from './integer-base-converter';
import { tool as urlEncoder } from './url-encoder';
import { tool as randomPortGenerator } from './random-port-generator';
import { tool as loremIpsumGenerator } from './lorem-ipsum-generator';
export const toolsByCategory: ToolCategory[] = [
{
@ -34,6 +35,11 @@ export const toolsByCategory: ToolCategory[] = [
icon: LockOpen,
components: [gitMemo, randomPortGenerator],
},
{
name: 'Text',
icon: LockOpen,
components: [loremIpsumGenerator],
},
];
export const tools = toolsByCategory.flatMap(({ components }) => components);

View file

@ -0,0 +1,11 @@
import { AlignJustified } from '@vicons/tabler';
import type { ITool } from '../Tool';
export const tool: ITool = {
name: 'Lorem ipsum generator',
path: '/lorem-ipsum-generator',
description: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content',
keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'],
component: () => import('./lorem-ipsum-generator.vue'),
icon: AlignJustified,
};

View file

@ -0,0 +1,214 @@
import { randFromArray } from '@/utils/random';
const vocabulary = [
'a',
'ac',
'accumsan',
'ad',
'adipiscing',
'aenean',
'aliquam',
'aliquet',
'amet',
'ante',
'aptent',
'arcu',
'at',
'auctor',
'bibendum',
'blandit',
'class',
'commodo',
'condimentum',
'congue',
'consectetur',
'consequat',
'conubia',
'convallis',
'cras',
'cubilia',
'cum',
'curabitur',
'curae',
'dapibus',
'diam',
'dictum',
'dictumst',
'dignissim',
'dolor',
'donec',
'dui',
'duis',
'egestas',
'eget',
'eleifend',
'elementum',
'elit',
'enim',
'erat',
'eros',
'est',
'et',
'etiam',
'eu',
'euismod',
'facilisi',
'faucibus',
'felis',
'fermentum',
'feugiat',
'fringilla',
'fusce',
'gravida',
'habitant',
'habitasse',
'hac',
'hendrerit',
'himenaeos',
'iaculis',
'id',
'imperdiet',
'in',
'inceptos',
'integer',
'interdum',
'ipsum',
'justo',
'lacinia',
'lacus',
'laoreet',
'lectus',
'leo',
'ligula',
'litora',
'lobortis',
'lorem',
'luctus',
'maecenas',
'magna',
'magnis',
'malesuada',
'massa',
'mattis',
'mauris',
'metus',
'mi',
'molestie',
'mollis',
'montes',
'morbi',
'mus',
'nam',
'nascetur',
'natoque',
'nec',
'neque',
'netus',
'nisi',
'nisl',
'non',
'nostra',
'nulla',
'nullam',
'nunc',
'odio',
'orci',
'ornare',
'parturient',
'pellentesque',
'penatibus',
'per',
'pharetra',
'phasellus',
'placerat',
'platea',
'porta',
'porttitor',
'posuere',
'potenti',
'praesent',
'pretium',
'primis',
'proin',
'pulvinar',
'purus',
'quam',
'quis',
'quisque',
'rhoncus',
'ridiculus',
'risus',
'rutrum',
'sagittis',
'sapien',
'scelerisque',
'sed',
'sem',
'semper',
'senectus',
'sit',
'sociis',
'sociosqu',
'sodales',
'sollicitudin',
'suscipit',
'suspendisse',
'taciti',
'tellus',
'tempor',
'tempus',
'tincidunt',
'torquent',
'tortor',
'turpis',
'ullamcorper',
'ultrices',
'ultricies',
'urna',
'varius',
'vehicula',
'vel',
'velit',
'venenatis',
'vestibulum',
'vitae',
'vivamus',
'viverra',
'volutpat',
'vulputate',
];
const firstSentence = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
const generateSentence = (length: number) => {
const sentence = Array.from({ length })
.map(() => randFromArray(vocabulary))
.join(' ');
return sentence.charAt(0).toUpperCase() + sentence.slice(1) + '.';
};
export function generateLoremIpsum({
paragraphCount = 1,
sentencePerParagraph = 3,
wordCount = 10,
startWithLoremIpsum = true,
asHTML = false,
}: {
paragraphCount?: number;
sentencePerParagraph?: number;
wordCount?: number;
startWithLoremIpsum?: boolean;
asHTML?: boolean;
}) {
const paragraphs = Array.from({ length: paragraphCount }).map(() => Array.from({ length: sentencePerParagraph }).map(() => generateSentence(wordCount)));
if (startWithLoremIpsum) {
paragraphs[0][0] = firstSentence;
}
if (asHTML) {
return `<p>${paragraphs.map((s) => s.join(' ')).join('</p>\n\n<p>')}</p>`;
}
return paragraphs.map((s) => s.join(' ')).join('\n\n');
}

View file

@ -0,0 +1,55 @@
<template>
<n-card>
<n-form-item label="Paragraphs" :show-feedback="false" label-width="200" label-placement="left">
<n-slider v-model:value="paragraphs" :step="1" :min="1" :max="20" />
</n-form-item>
<n-form-item label="Sentences per paragraph" :show-feedback="false" label-width="200" label-placement="left">
<n-slider v-model:value="sentences" range :step="1" :min="1" :max="50" />
</n-form-item>
<n-form-item label="Words per sentence" :show-feedback="false" label-width="200" label-placement="left">
<n-slider v-model:value="words" range :step="1" :min="1" :max="50" />
</n-form-item>
<n-form-item label="Start with lorem ipsum ?" :show-feedback="false" label-width="200" label-placement="left">
<n-switch v-model:value="startWithLoremIpsum" />
</n-form-item>
<n-form-item label="As html ?" :show-feedback="false" label-width="200" label-placement="left">
<n-switch v-model:value="asHTML" />
</n-form-item>
<br>
<n-input :value="loremIpsumText" type="textarea" placeholder="Your lorem ipsum..." autosize readonly />
<br>
<br>
<n-space justify="center">
<n-button @click="copy" secondary autofocus>Copy</n-button>
</n-space>
</n-card>
</template>
<script setup lang="ts">
import { useCopy } from '@/composable/copy';
import { ref, computed } from 'vue'
import { generateLoremIpsum } from './lorem-ipsum-generator.service'
import { randIntFromInterval } from '@/utils/random'
const paragraphs = ref(1)
const sentences = ref([3, 8])
const words = ref([8, 15])
const startWithLoremIpsum = ref(true)
const asHTML = ref(false)
const loremIpsumText = computed(() => generateLoremIpsum({
paragraphCount: paragraphs.value,
asHTML: asHTML.value,
sentencePerParagraph: randIntFromInterval(sentences.value[0], sentences.value[1]),
wordCount: randIntFromInterval(words.value[0], words.value[1]),
startWithLoremIpsum: startWithLoremIpsum.value
}))
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' })
</script>
<style lang="less" scoped>
</style>