vegan-ipsum
Version:
Generates passages of vegan-themed placeholder text suitable for use in web pages, graphics, and more. Works in the browser, NodeJS, and React Native.
717 lines (716 loc) • 18 kB
JavaScript
let commander = require("commander");
let child_process = require("child_process");
//#region src/constants/index.ts
var FORMAT_HTML = "html";
var FORMAT_PLAIN = "plain";
var FORMATS = [FORMAT_HTML, FORMAT_PLAIN];
/**
* An object representing line endings for different platforms.
*
* - `POSIX`: Line ending for POSIX-compliant systems (`\n`).
* - `WIN32`: Line ending for Windows systems (`\r\n`).
*/
var LINE_ENDINGS = {
POSIX: "\n",
WIN32: "\r\n"
};
/**
* An object representing supported platforms.
*
* - `DARWIN`: macOS platform identifier.
* - `LINUX`: Linux platform identifier.
* - `WIN32`: Windows platform identifier.
*/
var SUPPORTED_PLATFORMS = {
DARWIN: "darwin",
LINUX: "linux",
WIN32: "win32"
};
/**
* An object containing regular expressions for validating formats and units.
*
* - `FORMATS`: Matches supported text formats (`plain` or `html`), case-insensitive.
* - `UNITS`: Matches supported unit types (`paragraphs`, `sentences`, `words`), case-insensitive.
*/
var REGEX = {
FORMATS: /^(plain|html)$/i,
UNITS: /^(paragraphs|sentences|words)$/i
};
var UNIT_WORDS = "words";
var UNIT_SENTENCES = "sentences";
var UNIT_PARAGRAPHS = "paragraphs";
//#endregion
//#region src/constants/words.ts
/**
* An array of default lorem ipsum words.
*/
var DEFAULT_WORDS = [
"ad",
"adipisicing",
"aliqua",
"aliquip",
"amet",
"anim",
"aute",
"cillum",
"commodo",
"consectetur",
"consequat",
"culpa",
"cupidatat",
"deserunt",
"do",
"dolor",
"dolore",
"duis",
"ea",
"eiusmod",
"elit",
"enim",
"esse",
"est",
"et",
"eu",
"ex",
"excepteur",
"exercitation",
"fugiat",
"id",
"in",
"incididunt",
"ipsum",
"irure",
"labore",
"laboris",
"laborum",
"Lorem",
"magna",
"minim",
"mollit",
"nisi",
"non",
"nostrud",
"nulla",
"occaecat",
"officia",
"pariatur",
"proident",
"qui",
"quis",
"reprehenderit",
"sint",
"sit",
"sunt",
"tempor",
"ullamco",
"ut",
"velit",
"veniam",
"voluptate"
];
/**
* An array of vegan-related words to accompany the default ones.
*/
var VEGAN_WORDS = [
"plant",
"vegan",
"kindness",
"crueltyfree",
"herbivore",
"compassion",
"earth",
"dairyfree",
"justice",
"respect",
"peace",
"love",
"greens",
"fruit",
"vegetable",
"freedom",
"life",
"rights",
"sanctuary",
"nonviolence",
"care",
"conscious",
"ethics",
"climate",
"truth",
"plants",
"health",
"wholefood",
"clean",
"veggie",
"legumes",
"fiber",
"avocado",
"soy",
"tofu",
"tempeh",
"lentils",
"coconut",
"nutrients",
"plantpower",
"choices",
"saving",
"sustain",
"grain",
"beans",
"peas",
"quinoa",
"broccoli",
"kale",
"lettuce",
"radish",
"basil",
"mint",
"ginger",
"turmeric",
"natural",
"organic",
"kind"
];
/**
* An array of kindness-related words to accompany the default ones.
*/
var KINDNESS_WORDS = [
"kindness",
"compassion",
"empathy",
"mercy",
"respect",
"gentleness",
"care",
"love",
"peace",
"justice",
"fairness",
"awareness",
"forgiveness",
"integrity",
"nonviolence",
"harmony",
"mindfulness",
"humility",
"patience",
"sincerity",
"tolerance",
"understanding",
"altruism",
"grace",
"generosity",
"helpfulness",
"selflessness",
"support",
"comfort",
"sympathy",
"warmth",
"charity",
"unity",
"positivity"
];
/**
* An array of vegan food-related words to accompany the default ones.
*/
var VEGAN_FOOD_WORDS = [
"tofu",
"tempeh",
"soymilk",
"almondmilk",
"oatmilk",
"vegan-burger",
"vegan-cheese",
"jackfruit",
"quinoa",
"bowl",
"lentil",
"soup",
"smoothie",
"nut",
"chia",
"pudding",
"granola",
"plant-based",
"vegan-yogurt",
"vegan-pizza",
"coconut",
"chickpea",
"curry",
"soba",
"noodles",
"pancake",
"avocado",
"toast",
"vegetable"
];
/**
* An array of vegetable-related words to accompany the default ones.
*/
var VEGGIE_WORDS = [
"broccoli",
"kale",
"spinach",
"lettuce",
"cabbage",
"beetroot",
"carrot",
"radish",
"turnip",
"cauliflower",
"zucchini",
"bell",
"pepper",
"cucumber",
"eggplant",
"okra",
"tomato",
"green",
"beans",
"peas",
"sweet",
"potato",
"pumpkin",
"asparagus",
"artichoke",
"brussels",
"sprouts",
"chard",
"fennel",
"leek",
"parsnip",
"celery",
"shallot",
"corn",
"bamboo",
"shoots",
"beet",
"greens",
"mustard",
"scallions",
"radicchio",
"snow",
"onion",
"squash"
];
/**
* Final array combining default lorem ipsum and vegan-themed words.
*/
var WORDS = Array.from(new Set([
...DEFAULT_WORDS,
...VEGAN_WORDS,
...KINDNESS_WORDS,
...VEGAN_FOOD_WORDS,
...VEGGIE_WORDS
]));
//#endregion
//#region src/util/env.ts
/**
* Determines if the current runtime environment is Node.js.
*
* @returns {boolean} `true` if the runtime is Node.js, otherwise `false`.
*/
var isNode = () => {
return typeof module !== "undefined" && !!module.exports;
};
/**
* Determines if the current runtime environment is React Native.
*
* @returns {boolean} `true` if the runtime is React Native, otherwise `false`.
*/
var isReactNative = () => {
try {
return navigator.product === "ReactNative";
} catch (e) {
return false;
}
};
/**
* Determines if the current runtime environment is Windows.
*
* @returns {boolean} `true` if the process is running on a Windows platform, otherwise `false`.
*/
var isWindows = () => {
try {
return process.platform === SUPPORTED_PLATFORMS.WIN32;
} catch (e) {
return false;
}
};
//#endregion
//#region src/util/strings.ts
/**
* Capitalizes the first character of a given string after trimming whitespace.
*
* @param {string} str - The input string to capitalize.
*
* @returns {string} The input string with the first character capitalized.
*/
var capitalize = (str) => {
const trimmed = str.trim();
return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
};
/**
* Creates an array of a specified length, where each element is its index.
*
* @param {number} length - The desired length of the array. Defaults to 0.
*
* @returns {number[]} An array of indexes from 0 to `length - 1`.
*/
var rangeArray = (length = 0) => {
return [...Array(length)].map((_, index) => index);
};
/**
* Creates an array of strings of a specified length, using a provided string generator function.
*
* @param {number} length - The desired length of the array.
* @param {() => string} makeString - A function that generates a string for each element.
*
* @returns {string[]} An array of strings of the specified length.
*/
var fillArrayWith = (length, makeString) => {
return rangeArray(length).map(() => makeString());
};
//#endregion
//#region src/lib/generator.ts
/**
* A class for generating random text (words, sentences, paragraphs).
*/
var Generator = class {
sentencesPerParagraph;
wordsPerSentence;
random;
words;
/**
* Creates an instance of the `Generator` class.
*
* @param {GeneratorOptions} options - Configuration options for the generator.
*
* @throws {Error} If the minimum exceeds the maximum in the provided bounds.
*/
constructor({ sentencesPerParagraph = {
max: 7,
min: 3
}, wordsPerSentence = {
max: 15,
min: 5
}, random, words = WORDS } = {}) {
if (sentencesPerParagraph.min > sentencesPerParagraph.max) throw new Error(`Minimum number of sentences per paragraph (${sentencesPerParagraph.min}) cannot exceed maximum (${sentencesPerParagraph.max}).`);
if (wordsPerSentence.min > wordsPerSentence.max) throw new Error(`Minimum number of words per sentence (${wordsPerSentence.min}) cannot exceed maximum (${wordsPerSentence.max}).`);
this.sentencesPerParagraph = sentencesPerParagraph;
this.words = words;
this.wordsPerSentence = wordsPerSentence;
this.random = random || Math.random;
}
/**
* Generates a random integer between the specified minimum and maximum values.
*
* @param {number} min - The minimum value (inclusive).
* @param {number} max - The maximum value (inclusive).
*
* @returns {number} A random integer between `min` and `max`.
*/
generateRandomInteger(min, max) {
return Math.floor(this.random() * (max - min + 1) + min);
}
/**
* Generates a random sequence of words.
*
* @param {number} [num] - The number of words to generate. If not provided, a random number is used.
*
* @returns {string} A string of randomly generated words.
*/
generateRandomWords(num) {
const { min, max } = this.wordsPerSentence;
return rangeArray(num || this.generateRandomInteger(min, max)).reduce((accumulator) => {
return `${this.pluckRandomWord()} ${accumulator}`;
}, "").trim();
}
/**
* Generates a random sentence.
*
* @param {number} [num] - The number of words in the sentence. If not provided, a random number is used.
*
* @returns {string} A randomly generated sentence.
*/
generateRandomSentence(num) {
return `${capitalize(this.generateRandomWords(num))}.`;
}
/**
* Generates a random paragraph.
*
* @param {number} [num] - The number of sentences in the paragraph. If not provided, a random number is used.
*
* @returns {string} A randomly generated paragraph.
*/
generateRandomParagraph(num) {
const { min, max } = this.sentencesPerParagraph;
return rangeArray(num || this.generateRandomInteger(min, max)).reduce((accumulator) => {
return `${this.generateRandomSentence()} ${accumulator}`;
}, "").trim();
}
/**
* Selects a random word from the word list.
*
* @returns {string} A randomly selected word.
*/
pluckRandomWord() {
const min = 0;
const max = this.words.length - 1;
const index = this.generateRandomInteger(min, max);
return this.words[index];
}
};
//#endregion
//#region src/lib/VeganIpsum.ts
/**
* A class for generating vegan ipsum text in various formats and units.
*/
var VeganIpsum = class {
format;
suffix;
generator;
/**
* Creates an instance of the `VeganIpsum` class.
*
* @param {GeneratorOptions} options - Configuration options for the text generator.
* @param {LoremFormat} format - The format of the generated text (e.g., plain or HTML).
* @param {string} [suffix] - A custom line ending or suffix for the generated text.
*
* @throws {Error} If the provided format is invalid.
*/
constructor(options = {}, format = FORMAT_PLAIN, suffix) {
this.format = format;
this.suffix = suffix;
if (FORMATS.indexOf(format.toLowerCase()) === -1) throw new Error(`${format} is an invalid format. Please use ${FORMATS.join(" or ")}.`);
this.generator = new Generator(options);
this.suffix = suffix;
}
/**
* Determines the appropriate line ending based on the environment and suffix.
*
* @returns {string} The line ending to use.
*/
getLineEnding() {
if (this.suffix) return this.suffix;
if (!isReactNative() && isNode() && isWindows()) return LINE_ENDINGS.WIN32;
return LINE_ENDINGS.POSIX;
}
/**
* Formats a single string based on the specified format (e.g., wraps in HTML tags if needed).
*
* @param {string} str - The string to format.
*
* @returns {string} The formatted string.
*/
formatString(str) {
if (this.format === "html") return `<p>${str}</p>`;
return str;
}
/**
* Formats an array of strings based on the specified format.
*
* @param {string[]} strings - The array of strings to format.
*
* @returns {string[]} The array of formatted strings.
*/
formatStrings(strings) {
return strings.map((str) => this.formatString(str));
}
/**
* Generates a specified number of words and formats them.
*
* @param {number} [num] - The number of words to generate. If not provided, a random number is used.
*
* @returns {string} A formatted string of generated words.
*/
generateWords(num) {
return this.formatString(this.generator.generateRandomWords(num));
}
/**
* Generates a specified number of sentences and formats them.
*
* @param {number} [num] - The number of sentences to generate. If not provided, a random number is used.
*
* @returns {string} A formatted string of generated sentences.
*/
generateSentences(num) {
return this.formatString(this.generator.generateRandomParagraph(num));
}
/**
* Generates a specified number of paragraphs and formats them.
*
* @param {number} num - The number of paragraphs to generate.
*
* @returns {string} A formatted string of generated paragraphs.
*/
generateParagraphs(num) {
const makeString = this.generator.generateRandomParagraph.bind(this.generator);
return this.formatStrings(fillArrayWith(num, makeString)).join(this.getLineEnding());
}
};
//#endregion
//#region src/index.ts
/**
* Generates vegan ipsum text based on the provided parameters.
*
* @param {VeganIpsumParams} params - Configuration options for generating vegan ipsum text.
*
* @returns {string} Generated vegan ipsum text as a string.
*/
var veganIpsum = ({ count = 1, random, format = FORMAT_PLAIN, paragraphLowerBound = 3, paragraphUpperBound = 7, sentenceLowerBound = 5, sentenceUpperBound = 15, units = UNIT_SENTENCES, words = WORDS, suffix = "" } = {}) => {
const lorem = new VeganIpsum({
random,
sentencesPerParagraph: {
max: paragraphUpperBound,
min: paragraphLowerBound
},
words,
wordsPerSentence: {
max: sentenceUpperBound,
min: sentenceLowerBound
}
}, format, suffix);
switch (units) {
case UNIT_PARAGRAPHS: return lorem.generateParagraphs(count);
case UNIT_SENTENCES: return lorem.generateSentences(count);
case UNIT_WORDS: return lorem.generateWords(count);
default: return "";
}
};
//#endregion
//#region src/bin/lib/constants.ts
var DESCRIPTION = "Generates one or more words|sentences|paragraphs";
var USAGE = "3 words [options]";
/**
* An object containing the clipboard copy commands for different platforms.
*
* - `DARWIN`: Command for macOS (`pbcopy`).
* - `LINUX`: Command for Linux (`xclip -selection clipboard`).
* - `WIN32`: Command for Windows (`clip`).
*/
var COPY = {
DARWIN: "pbcopy",
LINUX: "xclip -selection clipboard",
WIN32: "clip"
};
var CANNOT_DETERMINE_PLATFORM = "Could not determine host operating system.";
//#endregion
//#region package.json
var version = "2.0.1";
//#endregion
//#region src/bin/lib/utils.ts
/**
* Retrieves the current process platform.
*
* @returns {string} The process platform (e.g., "darwin", "win32", "linux").
*
* @throws {Error} If the platform cannot be determined.
*/
var getPlatform = () => {
if (!process || typeof process.platform !== "string") throw new Error(CANNOT_DETERMINE_PLATFORM);
return process.platform;
};
/**
* Checks if the given platform is supported.
*
* @param {string} platform - The process platform (e.g., "darwin", "win32", "linux").
*
* @returns {boolean} `true` if the platform is supported, otherwise `false`.
*/
var isSupportedPlatform = (platform) => {
return Object.values(SUPPORTED_PLATFORMS).indexOf(platform.toLowerCase()) !== -1;
};
/**
* Retrieves the appropriate copy command for the specified platform.
*
* @param {string} platform - The process platform (e.g., "darwin", "win32", "linux").
*
* @returns {string} The copy command for the specified platform.
*/
var getCopyCommand = (platform = "") => {
switch (platform.toLowerCase()) {
case SUPPORTED_PLATFORMS.DARWIN: return COPY.DARWIN;
case SUPPORTED_PLATFORMS.WIN32: return COPY.WIN32;
case SUPPORTED_PLATFORMS.LINUX:
default: return COPY.LINUX;
}
};
/**
* Copies the provided text to the clipboard using the platform's native command.
*
* @param {string} text - The text to copy to the clipboard.
*
* @returns {Promise<string>} A promise that resolves with the copied text, or rejects with an error.
*
* @throws {Error} If the platform is not supported or if the copy command fails.
*/
var copyToClipboard = (text) => {
return new Promise((resolve, reject) => {
try {
const platform = getPlatform();
if (isSupportedPlatform(platform) === false) throw new Error(`Copy is not supported for ${platform}`);
(0, child_process.exec)(`echo "${text}" | ${getCopyCommand(platform)}`, (error, _stdout, stderr) => {
if (error) return reject(error);
if (stderr) return reject(new Error(stderr));
return resolve(text);
});
} catch (error) {
return reject(error);
}
});
};
/**
* Retrieves the current version of the package.
*
* @returns {string} The version of the package as defined in `package.json`.
*/
var getVersion = () => version;
//#endregion
//#region src/bin/vegan-ipsum.bin.ts
/**
* CLI program for generating vegan ipsum text.
*
* - Arguments:
* - `count`: The number of units to generate (e.g., words, sentences, or paragraphs).
* - `units`: The type of units to generate (e.g., "words", "sentences", or "paragraphs").
*
* - Options:
* - `-c, --copy`: Copies the generated text to the clipboard.
* - `-f, --format <format>`: Specifies the format of the output (e.g., "plain" or "html").
*/
commander.program.version(getVersion()).usage(USAGE).description(DESCRIPTION).argument("count", "The number of units").argument("units", "Words, sentences, or paragraphs").option("-c --copy", "Copy").addOption(new commander.Option("-f --format <format>", "Format").choices(FORMATS).default(FORMAT_PLAIN)).action(
/**
* Action handler for the CLI program.
*
* @param {string} num - The number of units to generate (default: "1").
* @param {"words" | "word" | "sentences" | "sentence" | "paragraphs" | "paragraph" | undefined} units - The type of units to generate (default: "sentence").
*/
(num = "1", units = "sentences") => {
if (REGEX.UNITS.test(units) === false) {
console.error(`${units} is not valid. Choose from paragraph(s), sentence(s), or word(s).`);
process.exit(1);
}
const count = parseInt(num, 10);
if (!count || count < 1) {
console.error(`${count} is not valid. Choose a number greater than 1.`);
process.exit(1);
}
const output = veganIpsum({
count,
format: commander.program.getOptionValue("format"),
units
});
console.log(output);
if (commander.program.getOptionValue("copy") === true) copyToClipboard(output).then(() => {
console.log("");
console.log("✓ copied");
}).catch((err) => {
console.log(err.message);
});
}
);
commander.program.parse(process.argv);
//#endregion
//# sourceMappingURL=vegan-ipsum.bin.js.map