randSentence
Generates whole sentences and returns count of them as strings. Each one is a subject and something said about it, written the way the language writes it: the particle a Korean noun asks for, the article an Italian noun opens on, the second position a German verb holds. With output: 'detail' it reports the phrases it used instead.
import { randSentence } from 'randino';
randSentence();
// ['The satin ranger dances in the plush harborside.']import 'package:randino/randino.dart';
randSentence();
// ['The satin ranger dances in the plush harborside.']from randino import rand_sentence
rand_sentence()
# ['The satin ranger dances in the plush harborside.']The words are the same everyday vocabulary randWord draws from, and person names are never used. What a sentence adds to them is the grammar: see Sentences for how the shapes and the verbs decide what can stand where.
Options
Every option is optional, and the defaults are what the empty call above uses.
| Option | Type | Default | Description |
|---|---|---|---|
language | WordLanguageOptionWordLanguage?WordLanguageOption | 'all'null"all" | Language of the generated sentences. 'all'null"all" mixes every supported language, picking one per sentence. |
theme | WordThemeOptionWordTheme?WordThemeOption | 'all'null"all" | What the sentence's subject is about. See Themes. |
type | SentenceTypeOptionSet<SentenceType>?SentenceTypeOption | drawn | What the sentence is doing. See Asking, exclaiming, trailing off. |
quote | SentenceQuoteSentenceQuote?SentenceQuote | None | —nullNone | Which marks a quoted line takes. See Dialogue and thought. |
style | SentenceStyle | drawn | The speech level it is written at. See The speech level. |
shape | SentenceShapeOptionSentenceShape?SentenceShapeOption | 'all'null"all" | How much the sentence says. See How much it says. |
slots | SentenceSlotOptionSet<SentenceSlot>?SentenceSlotOption | 'all'null"all" | Which parts it carries beside the subject. See Picking the shape, Counting, and money and A day and a time. |
include | string | string[]List<String>str | Sequence[str] | —const []() | Words every sentence has to contain. See Words it has to contain. |
sentences | numberintint | 1 | How many sentences one result holds. See More than one sentence. |
tense | SentenceTenseSentenceTense?SentenceTense | None | drawn | When it happened. See When it happened. |
story | SentenceStorySentenceStory?SentenceStory | None | drawn | Which story a result of several sentences tells. See More than one sentence. |
includeNameincludeNameinclude_name | booleanboolbool | drawn | Write a person's name where the sentence has room for one. See A person's name. |
count | numberintint | 1 | How many sentences to return. Clamped to 0 … 10000. |
realism | RandRealism | <Lang js="'real'" dart="RandRealism.real" py="\"real\"" /> | real uses real words, invented builds words that only read like the language, and mixed decides per word. The grammar stays real either way. |
vocabulary | RandVocabulary | <Lang js="'common'" dart="RandVocabulary.common" py="\"common\"" /> | How common the nouns have to be — the subject, the object, the place, the thing a story is about: basic, common or full. A sentence is read, so it keeps to the words people use unless asked otherwise. See Common words. |
minLengthminLengthmin_length | numberint?int | None | language | Minimum length in characters, punctuation included. |
maxLengthmaxLengthmax_length | numberint?int | None | language | Maximum length in characters. |
startsWithstartsWithstarts_with | stringString?str | —null"" | Keep only sentences whose first character is this one, and only from a language that writes that character's script. In a language that writes articles, that character is the article's — see below. |
unique | booleanboolbool | falsefalseFalse | Never return the same sentence twice. May return fewer than count. |
output | RandOutputRandOutput | 'value'"value" | Strings, or a SentenceDetail per sentence. Dart has no such parameter — see the detail output. |
random | () => numberRandom?Callable[[], float] | None | —nullNone | Where the randomness comes from — see Choosing the source. Defaults to the platform's ordinary generator. |
Both length bounds are clamped to RAND_SENTENCE_LENGTH_MAXrandSentenceLengthMaxRAND_SENTENCE_LENGTH_MAX per sentence rather than to the ceiling the other generators use. A sentence is many words where a name, a word and a nickname are at most three, and a result of ten of them is allowed ten times that.
Every language
randSentence({ language: 'ko', count: 3 });
// ['베이글은 짜다.', '커다란 조종사가 밀물에서 파란 요구르트를 굽는다.', '기상학자가 다시 톱을 닦는다.']
randSentence({ language: 'ja', count: 3 });
// ['さっき作業着が揺れる。', '昼に紫が派手な海王星で消える。', 'ハンバーガーが暗礁で冷める。']
randSentence({ language: 'zh', count: 3 });
// ['周末肉丸沸腾。', '巨乌贼又品尝朱红椰汁。', '明亮眼球总是移动。']
randSentence({ language: 'de', count: 3 });
// ['Eine junge Umlaufbahn fließt kaum.', 'Ein Nudelgericht kocht.', 'Eine Milz bebt.']
randSentence({ language: 'ru', count: 3 });
// ['Полый коньяк остывает.', 'Тимьян снова вянет.', 'Спутанный юпитер едва светлеет.']randSentence(language: WordLanguage.ko, count: 3);
// [베이글은 짜다., 커다란 조종사가 밀물에서 파란 요구르트를 굽는다., 기상학자가 다시 톱을 닦는다.]
randSentence(language: WordLanguage.ja, count: 3);
// [さっき作業着が揺れる。, 昼に紫が派手な海王星で消える。, ハンバーガーが暗礁で冷める。]
randSentence(language: WordLanguage.zh, count: 3);
// [周末肉丸沸腾。, 巨乌贼又品尝朱红椰汁。, 明亮眼球总是移动。]
randSentence(language: WordLanguage.de, count: 3);
// [Eine junge Umlaufbahn fließt kaum., Ein Nudelgericht kocht., Eine Milz bebt.]
randSentence(language: WordLanguage.ru, count: 3);
// [Полый коньяк остывает., Тимьян снова вянет., Спутанный юпитер едва светлеет.]rand_sentence(language="ko", count=3)
# ['베이글은 짜다.', '커다란 조종사가 밀물에서 파란 요구르트를 굽는다.', '기상학자가 다시 톱을 닦는다.']
rand_sentence(language="ja", count=3)
# ['さっき作業着が揺れる。', '昼に紫が派手な海王星で消える。', 'ハンバーガーが暗礁で冷める。']
rand_sentence(language="zh", count=3)
# ['周末肉丸沸腾。', '巨乌贼又品尝朱红椰汁。', '明亮眼球总是移动。']
rand_sentence(language="de", count=3)
# ['Eine junge Umlaufbahn fließt kaum.', 'Ein Nudelgericht kocht.', 'Eine Milz bebt.']
rand_sentence(language="ru", count=3)
# ['Полый коньяк остывает.', 'Тимьян снова вянет.', 'Спутанный юпитер едва светлеет.']All nine of them, and each writes its own punctuation: 。 closes a Japanese or Chinese sentence, . the rest.
How many phrases a sentence carries
shape picks how many phrases the sentence has, which is the closest thing it has to an expected length. minLength and maxLength bound the characters; this bounds the parts.
randSentence({ language: 'en', shape: 'simple', count: 3 });
// ['The halftrack slides.', 'The pilsner is cold.', 'The blunt canoeing deepens.']
randSentence({ language: 'en', shape: 'detailed', count: 3 });
// ['At night, the oak spreads.', 'The wily steppe brightens quickly.', 'The sprig wilts in the wild sunspot.']
randSentence({ language: 'en', shape: 'complex', count: 3 });
// ['The cheerful naga shares the americano in the sandy steppe.', 'The crab counts the hockey in the planetarium.']randSentence(language: WordLanguage.en, shape: SentenceShape.simple, count: 3);
// [The halftrack slides., The pilsner is cold., The blunt canoeing deepens.]
randSentence(language: WordLanguage.en, shape: SentenceShape.detailed, count: 3);
// [At night, the oak spreads., The wily steppe brightens quickly.]
randSentence(language: WordLanguage.en, shape: SentenceShape.complex, count: 3);
// [The cheerful naga shares the americano in the sandy steppe.]rand_sentence(language="en", shape="simple", count=3)
# ['The halftrack slides.', 'The pilsner is cold.', 'The blunt canoeing deepens.']
rand_sentence(language="en", shape="detailed", count=3)
# ['At night, the oak spreads.', 'The wily steppe brightens quickly.']
rand_sentence(language="en", shape="complex", count=3)
# ['The cheerful naga shares the americano in the sandy steppe.']simple is a subject and its predicate, detailed one phrase more, and complex two or more.
Picking the shape
slots names the parts a shape may carry beside its subject, and the shapes that carry none of them are dropped. A shape qualifies when it uses at least one, so naming two asks for either and leaves the choice to chance.
randSentence({ language: 'en', slots: 'object', count: 3 });
// ['The earthworm warms the nightcap.', 'The timid sorcerer builds the corduroy.']
randSentence({ language: 'en', slots: 'place', count: 3 });
// ['At dawn, the monorail sways in the bronze galaxy.', 'The cosmos darkens in the lunation.']
randSentence({ language: 'en', slots: 'state', count: 3 });
// ['The saffron is vague.', 'The weekend is dark.', 'The resolve is obvious.']
randSentence({ language: 'en', slots: 'none', count: 3 });
// ['The pearly hummus cools.', 'The litter passes.', 'The restless sleigh departs.']randSentence(language: WordLanguage.en, slots: {SentenceSlot.object}, count: 3);
// [The earthworm warms the nightcap., The timid sorcerer builds the corduroy.]
randSentence(language: WordLanguage.en, slots: {SentenceSlot.place}, count: 3);
// [At dawn, the monorail sways in the bronze galaxy.]
randSentence(language: WordLanguage.en, slots: {SentenceSlot.state}, count: 3);
// [The saffron is vague., The weekend is dark., The resolve is obvious.]
// The empty set is what `'none'` spells in the other two packages.
randSentence(language: WordLanguage.en, slots: {}, count: 3);
// [The pearly hummus cools., The litter passes., The restless sleigh departs.]rand_sentence(language="en", slots="object", count=3)
# ['The earthworm warms the nightcap.', 'The timid sorcerer builds the corduroy.']
rand_sentence(language="en", slots="place", count=3)
# ['At dawn, the monorail sways in the bronze galaxy.']
rand_sentence(language="en", slots="state", count=3)
# ['The saffron is vague.', 'The weekend is dark.', 'The resolve is obvious.']
rand_sentence(language="en", slots="none", count=3)
# ['The pearly hummus cools.', 'The litter passes.', 'The restless sleigh departs.']A language answers with what it has. The shapes are the language's own, so not every one of them can answer every request. German declares no object and Russian no place: both would put the noun in a case its own ending has to change for, and the pools hold one form of each word. Asking for one falls back to every shape the language does have, the same way a length range too narrow for a shape is answered with the closest fit rather than with an error.
randSentence({ language: 'de', slots: 'object', count: 3 });
// ['Im Frühling blüht eine Chrysantheme noch.', 'Eine neue Träne bebt.', 'Ein Kefir kühlt.']randSentence(language: WordLanguage.de, slots: {SentenceSlot.object}, count: 3);
// [Im Frühling blüht eine Chrysantheme noch., Eine neue Träne bebt., Ein Kefir kühlt.]rand_sentence(language="de", slots="object", count=3)
# ['Im Frühling blüht eine Chrysantheme noch.', 'Eine neue Träne bebt.', 'Ein Kefir kühlt.']With no language named, the ones that can answer are preferred over the ones that cannot.
How much a state holds
degree is a word in front of a state that says how much of it there is: 무척, very, とても. Every language has a shape that carries one, and the copula the state takes moves in front of it — is very tired, está muy cansado — so a state sentence has somewhere to grow beyond its subject and one word.
randSentence({ language: 'en', slots: 'degree', count: 3 });
// ['James is a little sated.', 'The valuation is terribly vague.', 'Orson is quite splendid.']
randSentence({ language: 'ko', slots: 'degree', count: 3 });
// ['상민은 엄청 졸리다.', '동욱은 퍽 건강하다.', '작은 홍옥은 조금 소중해.']randSentence(language: WordLanguage.en, slots: {SentenceSlot.degree}, count: 3);
// [James is a little sated., The valuation is terribly vague., Orson is quite splendid.]
randSentence(language: WordLanguage.ko, slots: {SentenceSlot.degree}, count: 3);
// [상민은 엄청 졸리다., 동욱은 퍽 건강하다., 작은 홍옥은 조금 소중해.]rand_sentence(language="en", slots="degree", count=3)
# ['James is a little sated.', 'The valuation is terribly vague.', 'Orson is quite splendid.']
rand_sentence(language="ko", slots="degree", count=3)
# ['상민은 엄청 졸리다.', '동욱은 퍽 건강하다.', '작은 홍옥은 조금 소중해.']Going somewhere
destination is where the subject is going, and only a verb that goes somewhere takes one: heads to, gets back to, 향한다, 들어선다, never leaves to the market. It is drawn from the place theme alone, a market or an attic, and never from the sky or the planets that share its class: a fox can sleep under a sky, and cannot walk to one. It is the part a story writes when its hero sets out and when they come home.
randSentence({ language: 'en', slots: 'destination', count: 2 });
// ['The patient eagle returns to the attic.', 'The clever osprey goes to the promenade.']
randSentence({ language: 'ko', slots: 'destination', count: 2 });
// ['농부가 침실로 간다.', '공주가 가볍게 누각에 들어선다.']randSentence(language: WordLanguage.en, slots: {SentenceSlot.destination}, count: 2);
// [The patient eagle returns to the attic., The clever osprey goes to the promenade.]
randSentence(language: WordLanguage.ko, slots: {SentenceSlot.destination}, count: 2);
// [농부가 침실로 간다., 공주가 가볍게 누각에 들어선다.]rand_sentence(language="en", slots="destination", count=2)
# ['The patient eagle returns to the attic.', 'The clever osprey goes to the promenade.']
rand_sentence(language="ko", slots="destination", count=2)
# ['농부가 침실로 간다.', '공주가 가볍게 누각에 들어선다.']Korean picks the particle by the word in front of it here too: 복도로 but 서울로, and 시장으로 after a consonant other than ㄹ. German and Russian declare no destination shape, for the same reason they declare no object and no place.
Counting and money
A shape can carry two more parts, asked for through slots like every other one. A quantity is a noun phrase with a number and the counter its kind takes; money is an amount and what the language counts it in.
randSentence({ language: 'ko', slots: 'quantity', count: 2 });
// ['파란 문어가 녹차 6개를 줍는다.', '파리가 감주 6개를 굽는다.']
randSentence({ language: 'vi', slots: 'quantity', count: 2 });
// ['Kỹ sư hẹp lau 7 cái thư.', '4 chiếc xe nôi chạy.']
randSentence({ language: 'en', slots: 'money', count: 2 });
// ['The silversmith describes 1,000 dollars.', 'The hollow magistrate remembers 500 dollars.']randSentence(language: WordLanguage.ko, slots: {SentenceSlot.quantity}, count: 2);
// [파란 문어가 녹차 6개를 줍는다., 파리가 감주 6개를 굽는다.]
randSentence(language: WordLanguage.vi, slots: {SentenceSlot.quantity}, count: 2);
// [Kỹ sư hẹp lau 7 cái thư., 4 chiếc xe nôi chạy.]
randSentence(language: WordLanguage.en, slots: {SentenceSlot.money}, count: 2);
// [The silversmith describes 1,000 dollars., The hollow magistrate remembers 500 dollars.]rand_sentence(language="ko", slots="quantity", count=2)
# ['파란 문어가 녹차 6개를 줍는다.', '파리가 감주 6개를 굽는다.']
rand_sentence(language="vi", slots="quantity", count=2)
# ['Kỹ sư hẹp lau 7 cái thư.', '4 chiếc xe nôi chạy.']
rand_sentence(language="en", slots="money", count=2)
# ['The silversmith describes 1,000 dollars.', 'The hollow magistrate remembers 500 dollars.']Four languages count, and they are the four with a classifier. The counter comes from the noun's class: 마리 for a creature, 대 for a vehicle, 그루 for a plant. Korean, Japanese and Chinese put the number behind the noun; Vietnamese puts it in front, classifier and all.
| Language | Counts | Names an amount |
|---|---|---|
ko ja zh vi | ✅ | ✅ |
en es it | — | ✅ |
de ru | — | — |
English, Spanish and Italian do not count. A plural rule applied to these pools produces 12 sadnesses, 12 bacons and 12 goggleses, because most nouns in them cannot be counted at all and nothing in the data says which can. A classifier language has no such problem: 슬픔 12가지 is twelve kinds of sadness, and the classifier is what makes the abstraction countable. So the counted shape is exactly the languages that have one.
German and Russian do neither. An amount stands where an object does, and neither declares an object shape, because both would put the noun in a case its own ending has to change for. That is the same rule that has kept them from declaring an object shape all along.
A counted phrase drops its article and takes no modifier: 12 apples, never the 12 red apples. The thousands are grouped the way the language groups them, with , in English, Korean, Japanese and Chinese and . in Vietnamese, Spanish and Italian.
What stands between the digits and what they count is the language's own too. Korean attaches the counter and the currency to the number (6개, 300,000원), and so do Japanese and Chinese, which write no space anywhere. Vietnamese, English, Spanish and Italian keep the space: 6 con, 500 dollars.
A day and a time
Two more parts a shape can carry: a date is what day and a clock what time of day, both written the way the language writes them.
randSentence({ language: 'ko', slots: 'date', count: 2 });
// ['2024년 5월 12일에 촉촉한 모래톱이 깊어지죠.', '비는 2027년 9월 19일입니다.']
randSentence({ language: 'en', slots: 'clock', count: 2 });
// ['At 13:24, the sherbet remains.', 'The torrent is at 3:26.']
randSentence({ language: 'de', slots: 'date', count: 2 });
// ['Ein Pokal ist am 9. November 2028.', 'Ein verworrenes Hockey ist am 7. März 2028.']randSentence(language: WordLanguage.ko, slots: {SentenceSlot.date}, count: 2);
// [2024년 5월 12일에 촉촉한 모래톱이 깊어지죠., 비는 2027년 9월 19일입니다.]
randSentence(language: WordLanguage.en, slots: {SentenceSlot.clock}, count: 2);
// [At 13:24, the sherbet remains., The torrent is at 3:26.]
randSentence(language: WordLanguage.de, slots: {SentenceSlot.date}, count: 2);
// [Ein Pokal ist am 9. November 2028., Ein verworrenes Hockey ist am 7. März 2028.]rand_sentence(language="ko", slots="date", count=2)
# ['2024년 5월 12일에 촉촉한 모래톱이 깊어지죠.', '비는 2027년 9월 19일입니다.']
rand_sentence(language="en", slots="clock", count=2)
# ['At 13:24, the sherbet remains.', 'The torrent is at 3:26.']
rand_sentence(language="de", slots="date", count=2)
# ['Ein Pokal ist am 9. November 2028.', 'Ein verworrenes Hockey ist am 7. März 2028.']A date is word order as much as it is digits. 2026년 9월 5일 runs largest to smallest, ngày 5 tháng 9 năm 2026 runs the other way with a word in front of every part, and 5. September 2026 names its month and puts a full stop after the day. Each language writes its own template, and the five that name their months list them.
Either can stand two ways: as an adverbial (2026년 9월 5일에 사자가 달린다, On September 5, 2026, the lion runs), or as what the sentence equates its subject to (면접은 11시 40분이다., The match is at 11:40.).
The second of those is a copular shape, and it is the only shape with neither a verb nor a state in it. The copula is a predicate like any other. It states the classes its subject may belong to (a thing that happens on a day is an event, not a lion), and it takes the form the level and the mood ask for, so Korean writes 이다, 이야, 이에요 and 입니다 and asks with 이니?.
Where the copula stands is the language's business. Korean and Japanese write it onto the end of what it equates the subject to (11시 40분이다 is one word); English, Chinese, Vietnamese, Spanish, Italian and German write it as a word of its own in front, and keep the preposition the phrase would carry anyway (ist am 5. März).
Russian declares no calendar, so asking for one falls back the way any unanswerable ask does. It equates a subject to a day with a dash rather than a word, and a dash does not change for a question or for a level, so declaring one would be a shape the language cannot write.
Words it has to contain
include lists words every sentence has to hold, each at least once. A word the pools know goes in the phrase it belongs to: a noun becomes the subject, a verb the predicate, an adverb the manner. A word from anywhere else is used as a noun.
randSentence({ language: 'en', include: 'lion', count: 3 });
// ['The genial lion finds the grumpy vest.', 'The noble lion is new.', 'The narrow lion crawls in the ancient pulsar.']
randSentence({ language: 'en', include: ['brave', 'lion', 'quietly'], count: 3 });
// ['The brave lion walks quietly.', 'The brave lion dozes quietly.', 'The brave lion swims quietly.']
randSentence({ language: 'ko', include: ['사자', '조용히'], count: 2 });
// ['눈꽃 사자가 조용히 뻔뻔한 토스터를 옮긴다.', '사자가 조용히 다가온다.']randSentence(language: WordLanguage.en, include: <String>['lion'], count: 3);
// [The genial lion finds the grumpy vest., The noble lion is new.]
randSentence(
language: WordLanguage.en,
include: <String>['brave', 'lion', 'quietly'],
count: 3,
);
// [The brave lion walks quietly., The brave lion dozes quietly.]
randSentence(language: WordLanguage.ko, include: <String>['사자', '조용히'], count: 2);
// [눈꽃 사자가 조용히 뻔뻔한 토스터를 옮긴다., 사자가 조용히 다가온다.]rand_sentence(language="en", include="lion", count=3)
# ['The genial lion finds the grumpy vest.', 'The noble lion is new.']
rand_sentence(language="en", include=["brave", "lion", "quietly"], count=3)
# ['The brave lion walks quietly.', 'The brave lion dozes quietly.']
rand_sentence(language="ko", include=["사자", "조용히"], count=2)
# ['눈꽃 사자가 조용히 뻔뻔한 토스터를 옮긴다.', '사자가 조용히 다가온다.']A word can be more than one thing, and which it becomes depends on the rest. English brave closes a sentence as a predicate and opens a noun phrase as a modifier; asked for beside quietly it takes the modifier slot, because the shape that has a predicate adjective has nowhere to put an adverb.
Two things follow from that. A sentence has room for as many words as it has phrases, so asking for more than the longest shape can carry places what fits and leaves the rest out. And with no language, the languages whose pools actually hold every word you named are preferred, so include: '고양이' produces Korean.
What a sentence does
type says what the sentence is doing: 'statement', 'question', 'exclamation', 'trailing' (a statement that stops rather than ends), plus the two quoted kinds below. Left out, one of the six is drawn per sentence. Name one, a set of them, or 'all'.
That draw is weighted rather than even, because prose is. A statement is far and away the most likely, a line somebody says comes next, and a question or an exclamation is the rarest of the six. Naming a kind yourself still gets you that kind and nothing else.
randSentence({ language: 'en', type: 'question', count: 2 });
// ['Does the delphinium spread in the halfmoon?', 'Does the evening brighten in the obelisk?']
randSentence({ language: 'en', type: 'exclamation', count: 2 });
// ['Well, the chai boils in the mesa!', 'Wow, the loud sinew heals!']
randSentence({ language: 'en', type: 'trailing', count: 2 });
// ['In summer, the amber frappe melts…', 'The zesty dumpling cools…']randSentence(language: WordLanguage.en, type: {SentenceType.question}, count: 2);
// [Does the delphinium spread in the halfmoon?, Does the evening brighten in the obelisk?]
randSentence(language: WordLanguage.en, type: {SentenceType.exclamation}, count: 2);
// [Well, the chai boils in the mesa!, Wow, the loud sinew heals!]
randSentence(language: WordLanguage.en, type: {SentenceType.trailing}, count: 2);
// [In summer, the amber frappe melts…, The zesty dumpling cools…]rand_sentence(language="en", type="question", count=2)
# ['Does the delphinium spread in the halfmoon?', 'Does the evening brighten in the obelisk?']
rand_sentence(language="en", type="exclamation", count=2)
# ['Well, the chai boils in the mesa!', 'Wow, the loud sinew heals!']
rand_sentence(language="en", type="trailing", count=2)
# ['In summer, the amber frappe melts…', 'The zesty dumpling cools…']A question is a shape of its own rather than a mark added to a statement, which is why the do-support is not a branch in the code. English declares a shape whose auxiliary stands in front of the subject, and the verb falls back to its base form. German moves its finite verb to where nothing else stands, Korean changes the ending on the predicate itself, and Japanese, Chinese and Vietnamese add a tag (か, 吗, không) after the whole clause.
| Language | How it asks | |
|---|---|---|
en | do-support, and the base form behind it | Does the delphinium spread? |
de | the finite verb moves to the front | Fliegt ein düsteres Kaninchen sorgsam? |
ko | the ending on the predicate changes | 베고니아가 시드니? |
ja zh vi | a tag after the clause | 侦探在遥远北极星里靠近吗? |
es it ru | the mark alone | ¿El vino vívido se estropea en la sabana? |
In the three languages on the last row the question is the statement, so they declare no question shape and get their statement shapes back. Spanish marks both ends, which is what its ¿ and ¡ are.
An exclamation usually opens on an interjection, because one without anything in front of it is a statement wearing a mark. A statement never opens on one, and a question has its own mark to do the work.
randSentence({ language: 'ko', type: 'exclamation', count: 2 });
// ['저런, 두꺼운 황사가 깊어진다!', '오, 여름에 해뜰녘이 초원에서 짙어진다!']randSentence(language: WordLanguage.ko, type: {SentenceType.exclamation}, count: 2);
// [저런, 두꺼운 황사가 깊어진다!, 오, 여름에 해뜰녘이 초원에서 짙어진다!]rand_sentence(language="ko", type="exclamation", count=2)
# ['저런, 두꺼운 황사가 깊어진다!', '오, 여름에 해뜰녘이 초원에서 짙어진다!']Asking for more than one type decides per sentence, so a paragraph can ask something and then answer it. SentenceDetail.types reports which each one was.
randSentence({ language: 'en', type: 'all', sentences: 3 });
// ['Does the spectrum spread in the cosmic meteor? But does the copper rapture gather? The spectrum remains…']randSentence(language: WordLanguage.en, type: SentenceType.values.toSet(), sentences: 3);
// [Does the spectrum spread in the cosmic meteor? But does the copper rapture gather? The spectrum remains…]rand_sentence(language="en", type="all", sentences=3)
# ['Does the spectrum spread in the cosmic meteor? But does the copper rapture gather? The spectrum remains…']A word you named through include comes out in the form the type asks for: include: '달린다' with type: 'question' writes 달리니?, not 달린다?. The forms are stored beside the plain words rather than instead of them, one for one, which is what makes the translation possible.
The speech level
style is the speech level the sentence is written at. Four of them, which is what a Korean speech level actually is:
| Level | Korean | What it is |
|---|---|---|
'plain' | 해라체 | The voice of a book. Nobody is being addressed. |
'casual' | 해체 (반말) | What you say to someone you are close to. |
'polite' | 해요체 | The same closeness, said politely. The warmest of the four. |
'formal' | 합쇼체 | Polite and at a distance. |
Left out, the level is drawn per result, so two calls are not the same voice twice. Name one and every sentence of the result is written at it.
randSentence({ language: 'ko', style: 'plain', count: 2 });
// ['포도밭이 청량한 별자리에서 물든다.', '주먹이 저린다.']
randSentence({ language: 'ko', style: 'casual', count: 2 });
// ['계란은 고소해.', '노란 카멜레온이 찹쌀떡을 씹어.']
randSentence({ language: 'ko', style: 'polite', count: 2 });
// ['고래 6마리가 어슬렁대죠.', '체온이 떨려요.']
randSentence({ language: 'ko', style: 'formal', count: 2 });
// ['마차가 약국에서 흔들립니다.', '등산복이 서서히 반짝입니다.']randSentence(language: WordLanguage.ko, style: SentenceStyle.plain, count: 2);
// [포도밭이 청량한 별자리에서 물든다., 주먹이 저린다.]
randSentence(language: WordLanguage.ko, style: SentenceStyle.casual, count: 2);
// [계란은 고소해., 노란 카멜레온이 찹쌀떡을 씹어.]
randSentence(language: WordLanguage.ko, style: SentenceStyle.polite, count: 2);
// [고래 6마리가 어슬렁대죠., 체온이 떨려요.]
randSentence(language: WordLanguage.ko, style: SentenceStyle.formal, count: 2);
// [마차가 약국에서 흔들립니다., 등산복이 서서히 반짝입니다.]rand_sentence(language="ko", style="plain", count=2)
# ['포도밭이 청량한 별자리에서 물든다.', '주먹이 저린다.']
rand_sentence(language="ko", style="casual", count=2)
# ['계란은 고소해.', '노란 카멜레온이 찹쌀떡을 씹어.']
rand_sentence(language="ko", style="polite", count=2)
# ['고래 6마리가 어슬렁대죠.', '체온이 떨려요.']
rand_sentence(language="ko", style="formal", count=2)
# ['마차가 약국에서 흔들립니다.', '등산복이 서서히 반짝입니다.']The level reaches the mood as well as the ending. 해체 and 해요체 have no exclamation of their own, since 달려 asks and tells alike and only the mark after it differs. What they do have is an ending that only asks well: 달리지? and 달리죠? invite the listener to agree, so the two levels write 달려 and 달려요 in a statement and draw between the two endings in a question. 해라체 and 합쇼체 do change, and they change differently: 해라체 asks with -니, -나 and -(으)ㄴ가 and exclaims with -구나, -네 and -군, while 합쇼체 turns 달립니다 into 달립니까.
randSentence({ language: 'ko', style: 'plain', type: 'question', count: 2 });
// ['치안판사가 귀여운 당김음을 닦나?', '발랄한 음료가 무지개 별무리에서 끓는가?']
randSentence({ language: 'ko', style: 'plain', type: 'exclamation', count: 2 });
// ['저런, 매콤한 목련이 뿌리내리는구나!', '저런, 어선이 귀여운 그림자에서 달리네!']randSentence(
language: WordLanguage.ko,
style: SentenceStyle.plain,
type: {SentenceType.question},
count: 2,
);
// [치안판사가 귀여운 당김음을 닦나?, 발랄한 음료가 무지개 별무리에서 끓는가?]
randSentence(
language: WordLanguage.ko,
style: SentenceStyle.plain,
type: {SentenceType.exclamation},
count: 2,
);
// [저런, 매콤한 목련이 뿌리내리는구나!, 저런, 어선이 귀여운 그림자에서 달리네!]rand_sentence(language="ko", style="plain", type="question", count=2)
# ['치안판사가 귀여운 당김음을 닦나?', '발랄한 음료가 무지개 별무리에서 끓는가?']
rand_sentence(language="ko", style="plain", type="exclamation", count=2)
# ['저런, 매콤한 목련이 뿌리내리는구나!', '저런, 어선이 귀여운 그림자에서 달리네!']A Korean question has more than one ending, and a pool entry says so. The form pools stay index-aligned with the plain words, which is what lets a required word be translated by its position, and an entry lists its endings with | between them: 달리니|달리나|달리는가 is one verb written three ways. One of them is drawn per sentence.
Japanese has two levels and maps onto the four. 'casual' is its plain form and 'polite' and 'formal' are both 走ります; か does the asking at every level, because it is the frame's tag rather than part of the verb.
The other seven write the same sentence at every level. Spanish, Italian, German and Russian have a T–V distinction, but it lives in the second person and every sentence here is third, so el león corre is what you say to anybody. English has no such form at all. Those seven declare no level, and style changes nothing in them.
Dialogue and thought
'dialogue' and 'thought' are the two types that are not shapes. Both wrap a sentence in the language's own quotation marks, and what they wrap is drawn per line. Somebody speaking asks more often than a page of prose does, and still tells more often than they ask.
randSentence({ language: 'en', type: 'dialogue', count: 2 });
// ['“The stout profit is endless!”', '“Does the blue intuition remain?”']
randSentence({ language: 'ja', type: 'dialogue', count: 2 });
// ['「組版工は速いか?」', '「芒が伸びるか?」']
randSentence({ language: 'en', type: 'thought', count: 2 });
// ['‘Is the tangled kraken restless?’', '‘Does the bronze torch age?’']randSentence(language: WordLanguage.en, type: {SentenceType.dialogue}, count: 2);
// [“The stout profit is endless!”, “Does the blue intuition remain?”]
randSentence(language: WordLanguage.ja, type: {SentenceType.dialogue}, count: 2);
// [「組版工は速いか?」, 「芒が伸びるか?」]
randSentence(language: WordLanguage.en, type: {SentenceType.thought}, count: 2);
// [‘Is the tangled kraken restless?’, ‘Does the bronze torch age?’]rand_sentence(language="en", type="dialogue", count=2)
# ['“The stout profit is endless!”', '“Does the blue intuition remain?”']
rand_sentence(language="ja", type="dialogue", count=2)
# ['「組版工は速いか?」', '「芒が伸びるか?」']
rand_sentence(language="en", type="thought", count=2)
# ['‘Is the tangled kraken restless?’', '‘Does the bronze torch age?’']The marks are the language's, and they are not close to universal. Dialogue takes the first level and thought the second:
| Language | First level | Second level |
|---|---|---|
en ko zh vi | “…” | ‘…’ |
ja | 「…」 | 『…』 |
es it | «…» | “…” |
de | „…“ | ‚…‘ |
ru | «…» | „…“ |
Chinese takes the curly quotes rather than the corner brackets: these pools are written in simplified Chinese, and horizontal simplified text uses “”, while 「」 is what Taiwan and Hong Kong write. German opens low and closes high, which is why its pair is not symmetrical.
quote overrides which pair is used, whatever the type, so a thought can carry the first-level marks and a line of dialogue the second.
randSentence({ language: 'ru', type: 'thought', quote: 'double' });
// ['«Эх, беспокойный торт ненадолго кипит!»']randSentence(language: WordLanguage.ru, type: {SentenceType.thought}, quote: SentenceQuote.double);
// [«Эх, беспокойный торт ненадолго кипит!»]rand_sentence(language="ru", type="thought", quote="double")
# ['«Эх, беспокойный торт ненадолго кипит!»']There is no speech tag. …라고 그는 말했다 needs a speaker, which includeName has, and a verb of speaking, which none of the nine languages' pools hold. What you get is the line, not who said it.
When it happened
tense says when it happened: 'present'SentenceTense.present"present" or 'past'SentenceTense.past"past". Left out, it is drawn per result, so a paragraph is told in one tense from its first sentence to its last.
randSentence({ language: 'en', tense: 'past', count: 3 });
// ['The prosecutor looked around.', 'The impala missed 500 dollars.', '“Was the karst dark?”']
randSentence({ language: 'ko', tense: 'past', count: 3 });
// ['친절한 약사는 뿌듯했다.', '가벼운 무인기가 달렸다.', '아침에 게으른 좀비가 신선한 온수를 마셨다.']randSentence(language: WordLanguage.en, tense: SentenceTense.past, count: 3);
// [The prosecutor looked around., The impala missed 500 dollars., “Was the karst dark?”]
randSentence(language: WordLanguage.ko, tense: SentenceTense.past, count: 3);
// [친절한 약사는 뿌듯했다., 가벼운 무인기가 달렸다., 아침에 게으른 좀비가 신선한 온수를 마셨다.]rand_sentence(language="en", tense="past", count=3)
# ['The prosecutor looked around.', 'The impala missed 500 dollars.', '“Was the karst dark?”']
rand_sentence(language="ko", tense="past", count=3)
# ['친절한 약사는 뿌듯했다.', '가벼운 무인기가 달렸다.', '아침에 게으른 좀비가 신선한 온수를 마셨다.']Every language writes the past the way its own grammar does, and the pools hold the forms rather than a rule guessing at them.
| Language | What changes | Example |
|---|---|---|
en | the verb, and the auxiliary of a question | The lion ran., Did the lion run? |
ko ja | the ending, at every speech level | 달렸다, 달렸어요, 走った, 走りました |
es it | the verb; an adjective keeps its form and the copula moves instead | El cochero guardó la pantufla., Il carro scivolò. |
de | the verb | Ein Smoothie kochte. |
ru | the verb, which then agrees with the subject's gender | Берёза тянулась., Паланкин скользил. |
zh | nothing on the verb; 了 is written after it | 峡谷悄悄地沉寂了。 |
vi | nothing on the verb; đã is written before it | Đại bàng đã tìm quanh. |
A time adverbial follows the tense too. yesterday and 어제 only open a past sentence, tomorrow and 내일 only a present one, and the phases of the day go with either.
A word include named in its statement form is translated into the past the same way it is translated into a question: include: '달린다' with tense: 'past' writes 달렸다, and include: 'runs' writes ran. SentenceDetail.tense reports which tense a result was written in.
More than one sentence
sentences puts more than one sentence in one result. They come back as a single string, count is still how many strings there are, and they tell one short story rather than being that many separate draws.
randSentence({ language: 'en', sentences: 3, count: 2 });
// ['On weekends, the barkeep went to the empty hallway. The barkeep bought the sushi in the hallway. The barkeep came back to the cottage.',
// 'The cathedral brightens. The strange botanist comes back to the pavilion and nods off. At dawn, the cathedral fills up.']
randSentence({ language: 'ko', sentences: 3 });
// ['신비한 항해사가 옥상으로 향했다. 고요한 옥상에서 묵묵히 향긋한 미트볼을 사왔다. 집에 들어섰다.']randSentence(language: WordLanguage.en, sentences: 3, count: 2);
// [On weekends, the barkeep went to the empty hallway. The barkeep bought the sushi in the hallway. The barkeep came back to the cottage.,
// The cathedral brightens. The strange botanist comes back to the pavilion and nods off. At dawn, the cathedral fills up.]
randSentence(language: WordLanguage.ko, sentences: 3);
// [신비한 항해사가 옥상으로 향했다. 고요한 옥상에서 묵묵히 향긋한 미트볼을 사왔다. 집에 들어섰다.]rand_sentence(language="en", sentences=3, count=2)
# ['On weekends, the barkeep went to the empty hallway. The barkeep bought the sushi in the hallway. The barkeep came back to the cottage.',
# 'The cathedral brightens. The strange botanist comes back to the pavilion and nods off. At dawn, the cathedral fills up.']
rand_sentence(language="ko", sentences=3)
# ['신비한 항해사가 옥상으로 향했다. 고요한 옥상에서 묵묵히 향긋한 미트볼을 사왔다. 집에 들어섰다.']The sentences follow a story: things that happen to one subject, the hero, in an order that holds together. Every step of a story says what has to be true of the hero before it and what is true afterwards, so nobody eats before they have something to eat, and a hero who went out comes home before going to sleep. The steps a story cannot do without are always told; the rest fill the sentences that are left, and a step that fits nowhere is left out rather than forced in.
| Story | What happens |
|---|---|
errand | The hero goes somewhere, buys or finds something to eat there, brings it home and eats it. |
meal | The hero is hungry, takes something to eat, eats it and is full. |
search | The hero looks around somewhere, finds a thing, carries it home and puts it away. |
outing | The hero wakes, goes out, spends the day somewhere, comes home tired and rests. |
craft | A person makes a thing, tends it, sells it or hands it over, and is content. |
stroll | The hero goes somewhere, moves about there, and comes home. |
evening | A place quietens, the hero comes home, eats, grows tired and sleeps. |
chores | A person gets up, takes a thing out, sees to it and is content. |
stash | The hero carries a thing somewhere, hides it there and comes home. |
idle | The hero is at a loose end at home, waits, plays and is content. |
waking | A place wakes before the hero does; the hero gets up and the day begins. |
picnic | The hero goes somewhere, gets something to eat there and eats it on the spot. |
mishap | The hero loses what they carried somewhere, looks for it, and may or may not find it. |
visit | The hero goes somewhere, meets somebody and they talk. |
chat | A person goes out, meets somebody, and the two of them talk. The story with the most lines in it. |
watch | The hero goes out, sits down somewhere, and watches what happens around them: a sparrow, a passer-by, the light changing. |
shelter | The weather turns while the hero is out; they wait it out and go on once it passes. |
sketch | Nothing happens to anybody. A place is described, and the things in it do what they do: the wind, the leaves, a bird, the evening. |
passage | A thing, a plant or a place changes over the day, and nobody does anything. |
story names one of them. Left out, it is drawn from the stories the language can tell about the subject you asked for: theme decides who the hero is, so theme: 'animal' is a story about a lion and theme: 'plant' can only be a passage. German and Russian declare no shape with an object, so they tell the stories with nothing in the hero's hands: stroll, outing, evening, idle, waking, watch, shelter, sketch and passage. A result of one sentence tells no story, and SentenceDetail.story says which one a longer result told.
Not every sentence of a story is about the hero. Somebody else turns up in most of them — the person met, a stallholder, a bird on a fence, the weather — and does something of their own, written as what they are and never by a name. And whether anybody speaks is drawn per result: a paragraph may be narrated all the way through, quote a line or two, or be a scene of speech, where the hero goes on after being answered and an exchange runs for several lines. A line is one of five things. A person says what is true of them or what they just did, in the first person, where the language writes one (“배고파요.”, “I went to the market and bought bread.” — a two-clause sentence is one line when both clauses are things the hero could report); they say what they make of the thing in front of them or the place around them, in the third person, which every language can write (“사과가 참 달다!”, «El hospital es precioso.»); they say what somebody else is doing as they see it (“새가 날아가네!”, and what they make of the person beside them is thought rather than said to their face); they ask the person beside them how they are, in the second person, in every language (“배고파?”, “Are you tired?”, ¿Estás cansado?); or somebody answers the line before with one of the language's own replies. Coming home is the one thing said in the language's own words rather than reported — “다녀왔습니다.”, 「ただいま」, “I'm home.” — in every language, since an idiom needs no first person. An answer fits what it answers: “그러게.” goes with a remark, “잘됐다!” with a piece of news, “괜찮아?” with somebody who just said they are tired, “정말?” asks for more, and “응, 조금.” answers a question. An answer is built from no phrase, so SentenceDetail.phrases carries nothing for it, and every line of one result is said at one speech level.
randSentence({ language: 'ko', sentences: 4, story: 'errand', tense: 'past' });
// ['낙타가 터미널로 갔다. 게다가 고요한 터미널에서 사뿐히 신선한 냉면을 봤다. 얼마뒤 냉면을 꺼내고 부리나케 집에 다다랐다. 한낮에 냉면을 먹었다.']
randSentence({ language: 'en', sentences: 4, story: 'meal', includeName: true });
// ['Zoe was starving. Therefore she picked the crisp ceviche. She nibbled the crisp ceviche alone. In the morning, she shouted.']randSentence(language: WordLanguage.ko, sentences: 4, story: SentenceStory.errand, tense: SentenceTense.past);
// [낙타가 터미널로 갔다. 게다가 고요한 터미널에서 사뿐히 신선한 냉면을 봤다. 얼마뒤 냉면을 꺼내고 부리나케 집에 다다랐다. 한낮에 냉면을 먹었다.]
randSentence(language: WordLanguage.en, sentences: 4, story: SentenceStory.meal, includeName: true);
// [Zoe was starving. Therefore she picked the crisp ceviche. She nibbled the crisp ceviche alone. In the morning, she shouted.]rand_sentence(language="ko", sentences=4, story="errand", tense="past")
# ['낙타가 터미널로 갔다. 게다가 고요한 터미널에서 사뿐히 신선한 냉면을 봤다. 얼마뒤 냉면을 꺼내고 부리나케 집에 다다랐다. 한낮에 냉면을 먹었다.']
rand_sentence(language="en", sentences=4, story="meal", include_name=True)
# ['Zoe was starving. Therefore she picked the crisp ceviche. She nibbled the crisp ceviche alone. In the morning, she shouted.']What a story puts on the page stays there. The thing the hero found is the thing they carry home and eat, the place they went to is the place they look around in, and home is home. Two things vary it. A story may have a second thing beside the one it is about — a tool picked up before the making, something looked at on a stall or in the room — which is never what the story needs, so a telling may leave it out. And a story may move on: stroll, outing, search and picnic can go somewhere else partway through, and that place is the story's from then on. A later sentence writes its own article and never describes the noun again, so in the icy hamlet becomes in the hamlet, not in the quiet hamlet and not in the vault. And the thing the sentence before named is referred to rather than named again: the second clause of a joined sentence always refers (끓여서 먹었다, cooked the sausage and ate it), and a whole sentence does so about as often as it names its subject again. Each language refers its own way. Korean, Japanese, Chinese and Vietnamese leave the object out, English writes it, Russian его or её, Spanish and Italian a clitic in front of the verb (la comió), and German names the noun again. The hero is named in the first sentence and then referred to the way a paragraph refers to its subject: named again, stood a pronoun for, or left out where the language leaves a subject out. The one sentence whose subject is not the hero is a change of scene, The cathedral brightens., 우체국이 서서히 조용해졌다., and its subject is the place the story is happening in.
The day only moves forward. A story that opened at dawn goes on in the morning or at midday, never back to the dawn, and the phases it names are a few hours apart rather than a whole day.
Two neighbouring steps are sometimes one sentence, with the second clause written without its subject: 사원에서 멈춰서고 천천히 집에 들어섰다, The broker heads back to the cottage and leans warily, 記念館へ下りる。のんびり家に帰り着いてさらりともたれる。 A language declares how it joins two clauses — Korean's -고 on the first verb, English's and, Japanese's -て — and German declares nothing, so it never joins. The joins come off the length budget like everything else, so a narrow range writes two short sentences where a wide one writes one long one.
A person sometimes speaks. A state sentence about a person — hungry, tired, glad — is now and then a line they say or think rather than a sentence the story narrates: “배고파.”, ‘I am tired.’, 「くたくたです!」. It is quoted, in the first person, at a level a person speaks at whatever the story's own, never the first sentence and never more than twice in one result, and only in the languages that can write a first person without changing the predicate: Korean, Japanese, Chinese, Vietnamese and English. An animal is narrated, and so is everybody in Spanish, Italian, German and Russian. A caller who named type gets those kinds instead.
A person is not a kind of thing. A paragraph about Emma is about Emma: it names her again or stands a pronoun where she was, and never draws somebody else of the same kind. That last one would be a paragraph that quietly becomes about Sophie.
A modifier is chosen for the noun it describes. A drink is hot, clear or fragrant and a mechanic is patient or gentle, rather than either being anything in the language's adjective pool, so 맑은 정비사 and the patient tea do not come out. This holds in a sentence on its own as well as in a story.
And it stays in the register it opened in. Prose about a line never becomes one, so a narrated paragraph never quotes. A quoted one is lines with prose between them: two people talking take turns, and one person saying four things in a row is a paragraph missing everything that happened while they said them. What that prose may not be is a third voice, so it tells rather than asks.
A connective only claims what the two sentences can carry. Each one is tagged by what it says about the sentence in front of it, and three of the four can open any continuation: time passed, here is one more thing, this cuts against that. The fourth cannot. so, therefore, 그러므로 and だから say this sentence follows from the last one, which is only true when the two are about the same thing and this one is telling rather than asking. 그러므로 금빛 하이볼이 식죠? after a sentence about a pretzel is a consequence of nothing.
| Claim | English | Korean | Japanese |
|---|---|---|---|
| one more thing | and then, besides | 그리고, 게다가 | そして, また |
| time passed | meanwhile, later | 이윽고, 마침내 | やがて, その後 |
| against that | but, however | 하지만, 그러나 | しかし, けれども |
| because of that | so, therefore | 그래서, 그러므로 | だから, そこで |
In a story the connective is the story's to choose. A step that follows from the one before it, eating after finding something to eat, may open on so or 그래서; a step that merely comes next opens on later, 이윽고, or on nothing at all.
A language declares only the kinds it can write. German has none for time passed: dann and danach are adverbs, and an adverb in the first position moves the finite verb, so the five coordinating conjunctions are all it can open a clause with.
Nothing in a paragraph is said twice over. A kind the sentence before it already was is less likely each time it comes round again, so a run of questions ends by itself; a verb group is spent before it starts over, rather than closing three of four lines on the same word; a person is named and then left alone; a fresh subject usually comes from the topic's own theme rather than from anywhere in its class; and no two sentences of one result open on the same connective or interjection.
Each language handles the pronoun its own way. English writes it; Korean, Japanese, Chinese, Spanish and Italian leave the subject out entirely, which is what they actually do in a second sentence; German and Russian pick it by the noun's gender. A language whose written pronoun cannot stand for a person names the topic again instead: English he and she need a gender the word pools do not carry, and 그것, それ, 它 and nó are inanimate.
A name is the exception, because it is the one subject that does carry a gender. Philip counts the prime. He forgets it in the supernova. is English standing he where the locksmith could only ever be named again. A language that writes no gendered pronoun is unaffected: Korean drops the subject rather than saying 그것 about somebody.
The length range describes the whole string, whatever the sentence count. It is shared out across the sentences before any of them is drawn, and the last one takes the rounding.
randSentence({ language: 'ko', sentences: 3, minLength: 40, maxLength: 55 });
// ['집사가 골방으로 향했다. 그러자 어두운 골방에서 물을 샀다. 집사가 집에 들어왔다.'] // 44 charactersrandSentence(language: WordLanguage.ko, sentences: 3, minLength: 40, maxLength: 55);
// [집사가 골방으로 향했다. 그러자 어두운 골방에서 물을 샀다. 집사가 집에 들어왔다.] // 44 charactersrand_sentence(language="ko", sentences=3, min_length=40, max_length=55)
# ['집사가 골방으로 향했다. 그러자 어두운 골방에서 물을 샀다. 집사가 집에 들어왔다.'] # 44 charactersinclude goes in the first sentence, which puts each word in the result once rather than once per sentence. sentences is clamped to RAND_SENTENCE_COUNT_MAXrandSentenceCountMaxRAND_SENTENCE_COUNT_MAX, which is ten.
A person's name
Every other generator here keeps person names out on purpose. A nickname is never built from one, and that rule is the whole point of keeping names and words apart. A sentence is the exception: includeNameincludeNameinclude_name writes a generated name where the sentence has room for a person.
Left out, it is a coin flip per result rather than per sentence, because a paragraph either has a person in it or does not. Set it yourself and that answer stands.
randSentence({ language: 'en', includeName: true, count: 3 });
// ['Callum drinks the round rye.', 'Gavin crawls.', 'Veronica paints the plunger neatly.']
randSentence({ language: 'ko', includeName: true, count: 3 });
// ['소한이 날아오른다.', '종현이 심벌즈를 판다.', '은영이 어슬렁댄다.']
randSentence({ language: 'es', includeName: true, count: 3 });
// ['Hilario imagina la duda.', 'Adrián calienta la uva redonda.', 'Santiago rueda.']randSentence(language: WordLanguage.en, includeName: true, count: 3);
// [Callum drinks the round rye., Gavin crawls., Veronica paints the plunger neatly.]
randSentence(language: WordLanguage.ko, includeName: true, count: 3);
// [소한이 날아오른다., 종현이 심벌즈를 판다., 은영이 어슬렁댄다.]
randSentence(language: WordLanguage.es, includeName: true, count: 3);
// [Hilario imagina la duda., Adrián calienta la uva redonda., Santiago rueda.]rand_sentence(language="en", include_name=True, count=3)
# ['Callum drinks the round rye.', 'Gavin crawls.', 'Veronica paints the plunger neatly.']
rand_sentence(language="ko", include_name=True, count=3)
# ['소한이 날아오른다.', '종현이 심벌즈를 판다.', '은영이 어슬렁댄다.']
rand_sentence(language="es", include_name=True, count=3)
# ['Hilario imagina la duda.', 'Adrián calienta la uva redonda.', 'Santiago rueda.']It is a bare given name rather than a full one or a noun phrase: no article, no modifier, and the particle Korean puts after it chosen from its own last character the way any other word's is (소한이, 은영이). It carries the gender it was drawn for, so a Spanish, Italian or Russian predicate agrees with it, as in Celeste è affamata beside Ivano è raro. That gender is the one thing the generator could not read off a name, since a name is in none of the word pools.
A name is shorter than a noun phrase, so a result that writes one cannot reach the top of what the language writes: Yvonne stands where die schlanke Wolke would have. It never falls under the bottom of it either. The shapes are chosen against the name at the high end and against the language's own nouns at the low end, so what sentenceLengthRangesentenceLengthRangesentence_length_range reports holds whoever the subject turns out to be.
A name only stands where a person could. Turning the option on narrows the subject to the themes that name people, so that the sentence has somewhere to put one. A theme you named yourself still wins, and then no name is written at all:
randSentence({ language: 'en', theme: 'animal', includeName: true, count: 2 });
// ['The wildebeest is lazy.', 'Yesterday, the moose stops.']randSentence(language: WordLanguage.en, theme: WordTheme.animal, includeName: true, count: 2);
// [The wildebeest is lazy., Yesterday, the moose stops.]rand_sentence(language="en", theme="animal", include_name=True, count=2)
# ['The wildebeest is lazy.', 'Yesterday, the moose stops.']SentenceDetail.names reports the names a result was written with, and a named subject reports theme: nulltheme: nulltheme=None, because a name belongs to no theme.
It costs 22 KB, whether you use it or not
The option reaches the person-name pools, and a synchronous API has no dynamic import to hide behind, so a bundle that includes randSentence at all includes them. Bundling only randSentence with esbuild and gzipping: 122.5 KB before, 144.5 KB after, +22.0 KB or +18%. The sentence generator already carries the whole word pools, which is 110 KB of that, and the name pools are the 22 KB beside them.
If you never write a name and the size matters, there is nothing to do about it in this version except not to import randSentence.
The detail output
output: 'detail' reports the pieces each sentence was built from instead of returning a string: the phrases in order, what each of them does, the tense, the story, the language, and the subject's theme.
Dart spells this as a second function, randSentenceDetails, because it has no way to make one function's return type depend on an argument. It takes the same parameters as randSentence.
randSentence({ language: 'ko', output: 'detail', count: 1 });
// [{
// sentence: '그리핀이 자줏빛 숲에서 총명한 고량주를 삼킨다.',
// sentences: ['그리핀이 자줏빛 숲에서 총명한 고량주를 삼킨다.'],
// phrases: ['그리핀', '자줏빛 숲', '총명한 고량주', '삼킨다'],
// slots: ['subject', 'place', 'object', 'verb'],
// names: [],
// types: ['statement'],
// tense: 'present',
// story: null,
// language: 'ko',
// theme: 'myth'
// }]randSentenceDetails(language: WordLanguage.ko).first;
// SentenceDetail(그리핀이 자줏빛 숲에서 총명한 고량주를 삼킨다.,
// [그리핀, 자줏빛 숲, 총명한 고량주, 삼킨다], ko, myth)
randSentenceDetails(language: WordLanguage.ko).first.slots;
// [SentenceSlot.subject, SentenceSlot.place, SentenceSlot.object, SentenceSlot.verb]rand_sentence(language="ko", output="detail", count=1)
# [SentenceDetail(sentence='그리핀이 자줏빛 숲에서 총명한 고량주를 삼킨다.',
# sentences=('그리핀이 자줏빛 숲에서 총명한 고량주를 삼킨다.',),
# phrases=('그리핀', '자줏빛 숲', '총명한 고량주', '삼킨다'),
# slots=('subject', 'place', 'object', 'verb'),
# names=(), types=('statement',), tense='present', story=None,
# language='ko', theme='myth')]| Field | Type | Description |
|---|---|---|
sentence | stringStringstr | The finished result, punctuation and all — every sentence of it, joined. |
sentences | string[]List<String>tuple[str, ...] | One entry per sentence. A single entry unless sentences asked for more. |
phrases | string[]List<String>tuple[str, ...] | The phrases it is made of, in order — without the particles. One flat list across every sentence. |
slots | SentenceSlot[]List<SentenceSlot>tuple[SentenceSlot, ...] | What each phrase does, at the same index as phrases. |
names | string[]List<String>tuple[str, ...] | The person names the result was written with, in order. Empty unless includeName asked for them. |
types | SentenceType[]List<SentenceType>tuple[SentenceType, ...] | What each sentence is doing, at the same index as sentences. |
tense | SentenceTense | When it happened. One tense for the whole result. |
story | SentenceStory | nullSentenceStory?SentenceStory | None | The story a result of several sentences told. Null for a result of one. |
language | WordLanguage | The language this sentence was generated in. |
theme | WordTheme | nullWordTheme?WordTheme | None | Theme of the subject — the hero's in a story, and otherwise the first sentence's, which is what the rest stay about. Null when that word is not one the generator knows, a person's name included. |
phrases holds the phrases and nothing else. The particle or preposition that marks one lives in sentence alone, so 그리핀이 … reports 그리핀 and joining the phrases back together does not reproduce the sentence. Read sentence for the finished string, and phrases for what it was built from.
Every sentence has exactly one subject and exactly one predicate, and that predicate is either a verb or a state, never both.
A first character
startsWith keeps the sentences that begin with the character you asked for, and it is met two different ways depending on the language.
A language that writes no article and puts a noun phrase first — Korean, Japanese, Chinese — is steered: the noun is drawn from the words that begin with the character, so nearly every draw lands.
randSentence({ language: 'ko', startsWith: '사', count: 3 });
// ['사자가 달린다.', '사슴이 물을 마신다.', '사과가 익는다.']A language that writes an article, a preposition or an adverbial in front — English, Spanish, Italian, German, Russian — cannot be steered that way, because the first word of the sentence is not the noun. Those are filtered: sentences are drawn as usual and the ones that do not begin with the character are thrown away. A common opening letter comes back quickly; a rare one may come back with fewer results than you asked for, or with none.
randSentence({ language: 'es', startsWith: 'e', count: 3 }); // three, quickly — `el`, `en`
randSentence({ language: 'es', startsWith: 'z', count: 3 }); // []A character the language does not write at all is answered with no results rather than with two scripts in one string. Asking every language narrows to the ones that can, so startsWith: 'ж' draws Russian.
randSentence({ language: 'ko', startsWith: 'Q' }); // []
randSentence({ startsWith: 'ж', count: 2 }); // two Russian sentencesA theme for the subject
theme narrows what the sentence is about, which means its subject; the object and the place are drawn from whatever the verb allows.
randSentence({ language: 'en', theme: 'animal', count: 3 });
// ['The hippo sleeps in the starburst.', 'The sparrow approaches in the lightyear.', 'The puppy swallows the calm springwater briefly.']randSentence(language: WordLanguage.en, theme: WordTheme.animal, count: 3);
// [The hippo sleeps in the starburst., The sparrow approaches in the lightyear.]rand_sentence(language="en", theme="animal", count=3)
# ['The hippo sleeps in the starburst.', 'The sparrow approaches in the lightyear.']Invented words, real grammar
realism decides where the words come from and nothing else. The particles, the articles and the shapes are the language's own at every level, so an invented sentence is still a sentence.
randSentence({ language: 'ko', realism: 'invented', count: 3 });
// ['수줍은 노오가 안개 파저멜을 챙긴다.', '터패가 민다에서 젤보피를 꿈꾼다.', '한겨울 코델피가 뿌리내린다.']randSentence(language: WordLanguage.ko, realism: RandRealism.invented, count: 3);
// [수줍은 노오가 안개 파저멜을 챙긴다., 터패가 민다에서 젤보피를 꿈꾼다.]rand_sentence(language="ko", realism="invented", count=3)
# ['수줍은 노오가 안개 파저멜을 챙긴다.', '터패가 민다에서 젤보피를 꿈꾼다.']See also
- Sentences — the shapes, the noun classes, and what each language can write.
sentenceLengthRange— every length a language's sentences can take.randWord— the vocabulary a sentence is built from, on its own.