Mad Libs: Difference between revisions

35,877 bytes added ,  4 months ago
m
m (→‎{{header|Wren}}: Minor tidy)
 
(30 intermediate revisions by 22 users not shown)
Line 26:
 
 
{{Template:Strings}}
;Related tasks:
*   [[Old_lady_swallowed_a_fly]]
*   [[The Twelve Days of Christmas]]
<br><br>
 
== {{header|Ada11l}} ==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V template = ‘<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.’
 
F madlibs(template)
print("The story template is:\n"template)
V fields = sorted(Array(Set(re:‘<[^>]+>’.find_strings(template))))
V values = input("\nInput a comma-separated list of words to replace the following items\n #.: ".format(fields.join(‘,’))).split(‘,’)
V story = template
L(f, v) zip(fields, values)
story = story.replace(f, v)
print("\nThe story becomes:\n\n"story)
 
madlibs(template)</syntaxhighlight>
 
{{out}}
<pre>
The story template is:
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Input a comma-separated list of words to replace the following items
<he or she>,<name>,<noun>: She,Monica L.,cockerel
 
The story becomes:
 
Monica L. went for a walk in the park. She
found a cockerel. Monica L. decided to take it home.
</pre>
 
=={{header|Ada}}==
 
The fun of Mad Libs is not knowing the story ahead of time, so the program reads the story template from a text file. The name of the text file is given as a command line argument.
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Command_Line, String_Helper;
 
procedure Madlib is
Line 66 ⟶ 96:
Ada.Text_IO.Put_Line(Text.Element(I));
end loop;
end Madlib;</langsyntaxhighlight>
 
It uses an auxiliary package String_Helper for simple string functions;
 
<langsyntaxhighlight Adalang="ada">with Ada.Containers.Indefinite_Vectors;
 
package String_Helper is
Line 94 ⟶ 124:
function Get_Vector(Filename: String) return Vector;
 
end String_Helper;</langsyntaxhighlight>
 
Here is the implementation of String_Helper:
 
<langsyntaxhighlight Adalang="ada">with Ada.Strings.Fixed, Ada.Text_IO;
 
package body String_Helper is
Line 148 ⟶ 178:
end Get_Vector;
 
end String_Helper;</langsyntaxhighlight>
 
A sample run (with the story template in t.txt):
Line 163 ⟶ 193:
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">integerfile if;
file f;
data b;
list l;
record r;
 
f_affix(f, "/dev/.stdin");
 
o_text("Enter the blank line terminated story:\n");
 
while (0 < f_b_line(f, .b_line(b)) {
l_append(l, .append(b);
}
 
for (, b in l) {
i = 0;
while (i < l_length(l)) {
integer p, q;
text s, t;
 
bwhile ((p = l_q_datab.place(l,'<')) i^ -1); {
q = b.probe(p, '>');
 
while ((p = b_index(b, '<')) ^ -1) {
q = b_probe(b, p, '>');
if (q ^ -1) {
s = cut(b_stringbq_string(b), p + 1, q - p - 1);
b_erase(b, .erase(p, q);
if (!r_key(r, .key(s)) {
o_text(cat3o_("Replacement for `", s, "':'\n"));
f_line(f, .line(t);
r_put(r, .put(s, t);
}
b_pasteb.paste(b, p, r_query(r, [s)]);
}
}
 
i += 1;
}
 
l.ucall(o_, 0, "\n");</syntaxhighlight>
while (l_length(l)) {
o_text(b_string(l_head(l)));
o_newline();
l_delete(l, 0);
}</lang>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
<langsyntaxhighlight lang="algol68"># Mad Libs style story generation #
 
# gets the story template from the file f. The template terminates with #
Line 336 ⟶ 356:
story( stand in )
 
)</langsyntaxhighlight>
{{out}}
<pre>
Line 349 ⟶ 369:
found a NOTETY STYLE pack. Al decided to take it home.
</pre>
 
 
 
=={{header|AppleScript}}==
 
----
<syntaxhighlight lang="applescript">
<lang AppleScript>
 
set theNoun to the text returned of (display dialog "What is your noun?" default answer "")
Line 365 ⟶ 383:
display dialog thePerson & " went for a walk in the park. " & theGender & " found a " & theNoun & ". " & thePerson & " decided to take it home."
 
</syntaxhighlight>
</lang>
 
=={{header|Applesoft BASIC}}==
<syntaxhighlight lang="gwbasic"> 100 DIM L$(100),W$(50),T$(50)
110 LET M$ = CHR$ (13)
120 FOR L = 1 TO 1E9
130 READ L$(L)
140 IF LEN (L$(L)) THEN NEXT L
150 FOR I = 1 TO L
160 LET M = 0
170 LET N$(0) = ""
180 FOR J = 1 TO LEN (L$(I))
190 LET C$ = MID$ (L$(I),J,1)
200 IF C$ = "<" AND NOT M THEN M = 1:C$ = "":N$(M) = ""
210 IF C$ = ">" AND M THEN GOSUB 300:M = 0:C$ = W$(Z)
220 LET N$(M) = N$(M) + C$
230 NEXT J
240 LET L$(I) = N$(0)
250 NEXT I
260 FOR I = 1 TO L
270 PRINT M$L$(I);
280 NEXT
290 END
300 FOR Z = 0 TO T
310 IF T$(Z) = N$(M) THEN RETURN
320 NEXT Z
330 LET T = Z
340 LET T$(Z) = N$(M)
350 PRINT M$"ENTER A "T$(Z);
360 INPUT "? ";W$(Z)
370 RETURN
380 DATA "<NAME> WENT FOR A WALK IN THE PARK. <HE OR SHE>"
390 DATA "FOUND A <NOUN>. <NAME> DECIDED TO TAKE IT HOME."
990 DATA</syntaxhighlight>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">story: strip input "Enter a story: "
vars: unique map match story {/\|([^\|]+)\|/} 'v -> replace v "|" ""
 
i: 0
while [i < size vars].import [
let vars\[i] input ~"Enter value for <|vars\[i]|>: "
i: i + 1
]
 
print ~story</syntaxhighlight>
 
{{out}}
 
<pre>Enter a story: |name| went for a walk in the park. |heOrShe| found a |noun|. |name| decided to take it home.
Enter value for <name>: Johnny
Enter value for <heOrShe>: He
Enter value for <noun>: chameleon
Johnny went for a walk in the park. He found a chameleon. Johnny decided to take it home.</pre>
 
=={{header|AutoHotkey}}==
Like some other examples, this prompts the user for a text file template.<br/>AutoHotkey is interestingly well suited for this task...
<langsyntaxhighlight AHKlang="ahk">FileSelectFile, filename, , %A_ScriptDir%, Select a Mad Libs template, *.txt
If ErrorLevel
ExitApp ; the user canceled the file selection
Line 381 ⟶ 452:
StringReplace, contents, contents, %match%, %repl%, All
}
MsgBox % contents</langsyntaxhighlight>
{{out|Sample Output}}
<pre>Han Solo went for a walk in the park. She
Line 387 ⟶ 458:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f MAD_LIBS.AWK
BEGIN {
Line 422 ⟶ 493:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 438 ⟶ 509:
found a flower. Barbara decided to take it home.
</pre>
 
=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">
cadena = "<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = instr(cadena, "<")
 
print "La historia: " : print cadena : print
while k
reemplaza = mid(cadena, k, instr(cadena, ">") - k + 1)
print "What should replace "; reemplaza; : input " ", con
while k
cadena = left(cadena, k-1) + con + mid(cadena, k + length(reemplaza), length(cadena))
k = instr(cadena, reemplaza, k)
end while
k = instr(cadena, "<", length(reemplaza))
end while
print : print "La historia final: " : print cadena
end
</syntaxhighlight>
 
 
== {{header|C}} ==
Dealing with c strings can be quite annoying. This solution implements a dynamic string type with simple functionality which makes the actual madlibs logic a bit clearer. A quicker solution would probably circumvent the copying and moving over characters in the string by utilizing a different data structure that could make use of pointers to input data. This would reduce copying, and require less memory, and allocations for.
<syntaxhighlight lang="c">
<lang c>
#include <stdio.h>
#include <stdlib.h>
Line 588 ⟶ 678:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 600 ⟶ 690:
</pre>
 
== {{header|C++}} ==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
using namespace std;
Line 648 ⟶ 738:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
using System.Text;
Line 721 ⟶ 811:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(ns magic.rosetta
(:require [clojure.string :as str]))
 
Line 783 ⟶ 873:
; While Bob Dylan walk, strange man
; appears and gave Bob Dylan a Nobel prize.
</syntaxhighlight>
</lang>
 
=={{header|Commodore BASIC}}==
 
This program in its current form is specific to the Commodore 64 memory map and utilizes the RAM untouched by BASIC beginning at $C000 (49152). This can be adjusted for other Commodore computers by changing the memory starting address which is variable <code>tb</code> in line 15. It also assumes using disk drive device 8 to read the input file.
 
<syntaxhighlight lang="gwbasic">10 rem mad lib for rosetta code
15 dim bf$(100),wd$(50),tg$(50):tb=49152
20 print chr$(147);chr$(14);"Mad Lib Processor":print
25 gosub 1000
30 gosub 100:gosub 250:gosub 300:gosub 400
40 print:print:print "Again? ";:gosub 500:print k$
45 if k$<>"y" then end
50 goto 20
100 tg=1:for i=1 to bp:n$="":mo=0
105 t$=bf$(i)
110 for j=1 to len(t$)
115 ch$=mid$(t$,j,1)
120 if ch$="<" then mo=1:goto 140
125 if ch$=">" then mo=0:gosub 200:n$=n$+wd$:tg$="":goto 140
130 if mo=0 then n$=n$+ch$
135 if mo=1 then tg$=tg$+ch$
140 next j
145 bf$(i)=n$
150 next i
155 return
200 for z=1 to tg
205 if tg$(z)=tg$ then wd$=wd$(z):return
210 next z
215 tg=tg+1:tg$(tg)=tg$
220 print "Enter a ";tg$(tg);:input wd$
225 wd$(tg)=wd$
230 return
250 print chr$(147):print "Processing...":print
255 m=tb:os=0:ns=0:for i=1 to bp-1
260 t$=bf$(i)
265 for c=1 to len(t$):ch$=mid$(t$,c,1)
270 poke m,asc(ch$+chr$(0)):m=m+1:next c
275 next i:rem poke m,32:m=m+1
280 m=m-1:return
300 rem insert cr for word wrap
310 pt=tb:sz=0:ll=0
320 if peek(pt)=32 then gosub 350:if(ll+sz>39) then poke pt,13:ll=-1:sz=0
325 if peek(pt)=13 then ll=-1
330 if pt<>m then pt=pt+1:ll=ll+1:goto 320
340 return
350 rem look ahead to next space
355 nx=pt+1:sz=1
360 if peek(nx)=32 or peek(nx)=13 then return
365 nx=nx+1:sz=sz+1
370 if nx=m then return
375 goto 360
400 rem output memory buffer
401 ln=0:print chr$(147);
410 for i=tb to m:c=peek(i)
420 if c=13 then ln=ln+1
425 print chr$(c);
430 if ln=23 then ln=0:print:gosub 550
440 next i
450 return
500 rem clear buffer, wait for a key
501 get k$:if k$<>"" then 501
505 get k$:if k$="" then 505
510 return
550 rem pause prompt
560 print"[Pause]{CRSR-LEFT 7}";
565 gosub 500
570 print"{SPACE 7}{CRSR-LEFT 7}{CRSR-UP}";
575 return
1000 rem load file
1005 bp=1
1010 print:input "Enter name of file: ";fi$
1020 open 7,8,7,"0:"+fi$+",s,r"
1025 rem gosub 2000
1030 rem if er<>0 then print:gosub 2100:return
1035 get#7,a$
1036 ifa$=chr$(13)thenbf$(bp)=t$+a$:print" ";:t$="":bp=bp+1:goto 1040
1038 t$=t$+a$
1040 if (st and 64)=0 then goto 1035
1049 close 7:gosub 2000
1050 if er=0 then printchr$(147):return
1055 gosub 2100
1060 if er<>0 then goto 1000
1080 return
2000 rem check disk error
2001 open 15,8,15:input#15,er,en$,et$,es$:close15
2010 return
2100 rem print pretty error
2101 ca$=left$(en$,1):ca$=chr$(asc(ca$)+128):en$=ca$+right$(en$,len(en$)-1)
2105 print:print er;"- ";en$;" at .:";et$;" .:";es$
2110 print:print "Press a key.":gosub 500
2115 return</syntaxhighlight>
 
'''Input File'''
 
''Courtroom Drama, Part I''
 
LAWYER: Your honor, I have discovered a witness who can prove, beyond a shadow of a '''&lt;Noun 1&gt;''', that my client is a '''&lt;Adjective 1&gt;'''-man.
 
JUDGE: Call the '''&lt;Noun 2&gt;'''.
 
CLERK: Do you solemnly swear to tell the '''&lt;Adjective 2&gt;''' truth and nothing but the '''&lt;Noun 3&gt;'''?
 
WITNESS: I do.
 
LAWYER: Please state your '''&lt;Adjective 3&gt;''' name and occupation.
 
WITNESS: [hard to understand] My name is '''&lt;Full Name&gt;''' and I am a '''&lt;Noun 4&gt;''' driver.
 
JUDGE: I can't understand you. What is wrong... are you '''&lt;Adjective 4&gt;'''?
 
WITNESS: I forgot my '''&lt;Adjective 5&gt;''' '''&lt;Plural Body Part&gt;'''. They're in my car. (Laughter in the courtroom. Judge raps his '''&lt;Noun 5&gt;''' on his '''&lt;Noun 6&gt;'''.)
 
JUDGE: Order in the court! We'll have a ten-minute recess to allow the witness to get his '''&lt;Adjective 5&gt;''' '''&lt;Plural Body Part&gt;'''.
 
{{output}}
<pre>Mad Lib Processor
 
 
Enter name of file: ? court 1.mdlb
 
Enter a Noun 1? computer
Enter a Adjective 1? greasy
Enter a Noun 2? cow
Enter a Adjective 2? skinny
Enter a Noun 3? pencil
Enter a Adjective 3? sticky
Enter a Full Name? John Q. Smith
Enter a Noun 4? building
Enter a Adjective 4? miniature
Enter a Adjective 5? cold
Enter a Plural Body Part? toes
Enter a Noun 5? lake
Enter a Noun 6? flower
 
Processing...
 
Courtroom Drama, Part I
 
LAWYER: Your honor, I have discovered a
witness who can prove, beyond a shadow
of a computer, that my client is a
greasy-man.
 
JUDGE: Call the cow.
 
CLERK: Do you solemnly swear to tell
the skinny truth and nothing but the
pencil?
 
WITNESS: I do.
 
LAWYER: Please state your sticky name
and occupation.
 
WITNESS: [hard to understand] My name
is John Q. Smith and I am a building
driver.
 
JUDGE: I can't understand you. What is
wrong... are you miniature?
 
WITNESS: I forgot my cold toes. They're
in my car. (Laughter in the courtroom.
Judge raps his lake on his flower.)
 
JUDGE: Order in the court! We'll have a
ten-minute recess to allow the witness
to get his cold toes.
 
 
Again? n
 
ready.
&#9608;</pre>
 
=={{header|D}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="d">import std.stdio, std.regex, std.algorithm, std.string, std.array;
 
void main() {
Line 806 ⟶ 1,070:
 
writeln("\nThe story becomes:\n", story);
}</langsyntaxhighlight>
{{out}}
<pre>Enter a story template, terminated by an empty line:
Line 821 ⟶ 1,085:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">-module(madlib).
-compile(export_all).
 
Line 873 ⟶ 1,137:
lists:foldl(fun ([M],D) ->
dict:store(M,"",D)
end, Dict, Matches).</langsyntaxhighlight>
 
This version can be called via either madlib:main() or madlib:main(File) to read from standard_in or from a file.
Line 880 ⟶ 1,144:
 
{{out}}
<langsyntaxhighlight lang="erlang">68> madlib:main("test.mad").
Please name a <noun>: banana
Please name a <name>: Jack
Line 886 ⟶ 1,150:
Jack went for a walk in the park. She
found a banana. Jack decided to take it home.ok
69> </langsyntaxhighlight>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: formatting io kernel make regexp sequences sets splitting ;
IN: rosetta-code.mad-libs
 
: get-mad-lib ( -- str )
"Enter a mad lib. A blank line signals end of input." print
[
[ "> " write flush readln dup , empty? f t ? ] loop
] { } make harvest "\n" join ;
 
: find-replacements ( str -- seq )
R/ <[\w\s]+>/ all-matching-subseqs members ;
 
: query ( str -- str )
rest but-last "Enter a(n) %s: " printf flush readln ;
 
: replacements ( str seq -- str )
dup [ query ] map [ replace ] 2each ;
 
: mad-libs ( -- )
get-mad-lib dup find-replacements replacements nl print ;
 
MAIN: mad-libs</syntaxhighlight>
{{out}}
<pre>
Enter a mad lib. A blank line signals end of input.
> <name> went for a walk in the park. <he or she>
> found a <noun>. <name> decided to take it home.
>
Enter a(n) name: William
Enter a(n) he or she: he
Enter a(n) noun: crystal
 
William went for a walk in the park. he
found a crystal. William decided to take it home.
</pre>
 
=={{header|Fortran}}==
Line 926 ⟶ 1,227:
written on it. Joseph the lucky decided to take it home.
 
<syntaxhighlight lang="fortran">
<lang Fortran>
MODULE MADLIB !Messing with COMMON is less convenient.
INTEGER MSG,KBD,INF !I/O unit numbers.
Line 1,166 ⟶ 1,467:
CALL WRITESTORY(66)
END
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
Dim As String con, cadena
cadena = "<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
Dim As Integer k = Instr(cadena, "<")
 
Print "La historia: "
Print cadena & Chr(10)
While k
Dim As String reemplaza = Mid(cadena, k, Instr(cadena, ">") - k + 1)
Print "What should replace "; reemplaza; : Input con
While k
cadena = Left(cadena, k-1) & con & Mid(cadena, k + Len(reemplaza))
k = Instr(k, cadena, reemplaza)
Wend
k = Instr(cadena, "<")
Wend
Print Chr(10) & "La historia final: "
Print cadena & Chr(10)
</syntaxhighlight>
 
=={{header|Go}}==
Variance: The fun of Mad Libs is not knowing the story ahead of time, so instead of asking the player to enter the story template, my program asks the player to enter the file name of a story template (with contents presumably unknown to the player.)
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,226 ⟶ 1,548:
return m[p]
}))
}</langsyntaxhighlight>
Sample run:
<pre>
Line 1,242 ⟶ 1,564:
=={{header|Haskell}}==
This will read a template story via stdin with no arguments, or read from a file if given as an argument.
<langsyntaxhighlight Haskelllang="haskell">import System.IO (stdout, hFlush)
 
import System.Environment (getArgs)
Line 1,293 ⟶ 1,615:
nlines_ <- parseText nlines M.empty
putStrLn ""
putStrLn nlines_</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
This just runs with the sample. It would be much more fun with a database of randomly selected story templates.
<syntaxhighlight lang="icon">procedure main()
ml := "<name> went for a walk in the park. There <he or she> _
found a <noun>. <name> decided to take it home." # sample
MadLib(ml) # run it
end
 
link strings
 
procedure MadLib(story)
write("Please provide words for the following:")
V := []
story ? while ( tab(upto('<')), put(V,tab(upto('>')+1)) )
every writes(v := !set(V)," : ") do
story := replace(story,v,read())
write("\nYour MadLib follows:\n",story)
end</syntaxhighlight>
 
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings.icn provides replace]
 
{{out}}
<pre>Please provide words for the following:
<noun> : keys
<he or she> : she
<name> : Goldilocks
 
Your MadLib follows:
Goldilocks went for a walk in the park. There she found a keys. Goldilocks decided to take it home.</pre>
 
=={{header|J}}==
Line 1,299 ⟶ 1,652:
Implementation:
 
<langsyntaxhighlight Jlang="j">require 'general/misc/prompt regex'
 
madlib=:3 :0
Line 1,312 ⟶ 1,665:
end.
t
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> madlib''
Please enter the story template
See http://rosettacode.org/wiki/Mad_Libs for details
Line 1,327 ⟶ 1,680:
Jill went for a walk in the park. she
found a rock. Jill decided to take it home.
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
I tried to fix this... but this is my first one.
This is extremely messy code. There's bound to be a more optimal way of doing this.
 
<langsyntaxhighlight Javalang="java">import java.util.Map*;
import java.util.HashMap;
import java.util.Scanner;
import java.util.StringTokenizer;
 
public class MadLibs {
{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
{
Scanner s=new Scanner(System.in);
String linename, gender, noun;
StringBuffer storybuffer=new StringBuffer();
System.out.print("Enter a name: ");
name = input.next();
//Accept lines until empty line is entered
while(!(line=s.nextLine()).isEmpty())
System.out.print("He or she: ");
storybuffer.append(" "+line);
gender = input.next();
//Remove first space
System.out.print("Enter a noun: ");
storybuffer.delete(0, 1);
noun = input.next();
String story=storybuffer.toString();
//Split
System.out.println("\f" + name + " went for a walk in the park. " + gender + "\nfound a " + noun + ". " + name + " decided to take it home.");
StringTokenizer str=new StringTokenizer(story);
String word;
StringBuffer finalstory=new StringBuffer();
}
}
//Store added elements
</syntaxhighlight>
Map<String,String> hash=new HashMap<String,String>();
while(str.hasMoreTokens())
{
word=str.nextToken();
if(word.contains("<"))
{
String add="";
//Element prompt could be more than one word
if(!word.contains(">"))
{
//Build multi-word prompt
String phrase="";
do{
phrase+=word+" ";
}while(!(word=str.nextToken()).contains(">"));
word=phrase+word;
}
//Account for element placeholder being immediately followed by . or , or whatever.
if(word.charAt(word.length()-1)!='>')
add=word.substring(word.lastIndexOf('>')+1);
//Store id of element in hash table
String id=word.substring(0,word.lastIndexOf('>')+1);
String value;
if(!hash.containsKey(id))
{
//New element
System.out.println("Enter a "+ id);
value=s.nextLine()+add;
hash.put(id, value);
}
//Previously entered element
else
value=hash.get(id);
word=value;
}
finalstory.append(word+" ");
}
System.out.println(finalstory.toString());
s.close();
}
}</lang>
 
{{out}}
<pre>
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Enter a <name>
Champak
Enter a <he or she>
He
Enter a <noun>
hippo
 
Champak went for a walk in the park. He found a hippo. Champak decided to take it home.
 
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
This just runs with the sample. It would be much more fun with a database of randomly selected story templates.
<lang Icon>procedure main()
ml := "<name> went for a walk in the park. There <he or she> _
found a <noun>. <name> decided to take it home." # sample
MadLib(ml) # run it
end
 
link strings
 
procedure MadLib(story)
write("Please provide words for the following:")
V := []
story ? while ( tab(upto('<')), put(V,tab(upto('>')+1)) )
every writes(v := !set(V)," : ") do
story := replace(story,v,read())
write("\nYour MadLib follows:\n",story)
end</lang>
 
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings.icn provides replace]
 
{{out}}
<pre>Please provide words for the following:
<noun> : keys
<he or she> : she
<name> : Goldilocks
 
Your MadLib follows:
Goldilocks went for a walk in the park. There she found a keys. Goldilocks decided to take it home.</pre>
 
=={{header|Julia}}==
Line 1,453 ⟶ 1,714:
{{trans|Python}}
 
<langsyntaxhighlight lang="julia">
function madlibs(template)
println("The story template is:\n", template)
Line 1,471 ⟶ 1,732:
"""
 
madlibs(template)</langsyntaxhighlight>
 
{{out}}
Line 1,488 ⟶ 1,749:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun main(args: Array<String>) {
Line 1,509 ⟶ 1,770:
}
println("\n$story")
}</langsyntaxhighlight>
 
{{out}}
Line 1,528 ⟶ 1,789:
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">temp$="<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = instr(temp$,"<")
while k
Line 1,541 ⟶ 1,802:
print temp$
wait
</syntaxhighlight>
</lang>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">print("Enter a multi-line story (finish with blank line):")
dict, story, line = {}, "", io.read()
while #line>0 do story=story..line.."\n" line=io.read() end
story = story:gsub("(%<.-%>)", function(what)
if dict[what] then return dict[what] end
io.write("Please enter a " .. what .. ": ")
dict[what] = io.read()
return dict[what]
end)
print("\n"..story)</syntaxhighlight>
{{out}}
<pre>Enter a multi-line story (finish with blank line):
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Please enter a <name>: Mark
Please enter a <he or she>: He
Please enter a <noun>: fork
 
Mark went for a walk in the park. He
found a fork. Mark decided to take it home.</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Like some other examples, this prompts the user for a filename for a story template rather than reading the story in from user input.
<langsyntaxhighlight Mathematicalang="mathematica">text = Import[
InputString["Enter the filename of the story template:"]];
answers =
Line 1,555 ⟶ 1,839:
" " <> StringTrim[#, "<" | ">"] <> ":"] &,
Union[StringCases[text, RegularExpression["<[^>]+>"]]]];
Print[StringReplace[text, Normal[answers]]];</langsyntaxhighlight>
{{out}}
<pre>George went for a walk in the park. he
found a car. George decided to take it home.</pre>
 
=={{header|Nanoquery}}==
<syntaxhighlight lang="nanoquery">def madlib(template)
// loop through and find/remove all of the replacements
replacements = {}
ind = 0
while ind < len(template)
// check if we have found a replacement to perform
if template[ind] = "<"
// get the name of the replacement and add it to the list
// if we haven't already encountered it
ind += 1
replace_name = ""
while template[ind] != ">"
replace_name += template[ind]
ind += 1
end while
 
if not replace_name in replacements
replacements.append(replace_name)
end if
ind += 1
else
ind += 1
end if
end while
 
// prompt the user for replacement values
replacement_values = {}
for phrase in replacements
replacement_values.append(input("enter " + phrase + ": "))
end for
println
 
// make replacements and output the story
ind = 0
while ind < len(template)
// check if we have found a replacement to perform
if template[ind] = "<"
// get the name of the replacement
ind += 1
replace_name = ""
while template[ind] != ">"
replace_name += template[ind]
ind += 1
end while
// output the replacement
print replacement_values[replacements[replace_name]]
ind += 1
else
print template[ind]
ind += 1
end if
end while
end madlib
 
madlib("<name> went for a walk in the park. <he or she> " + \
"found a <noun>. <name> decided to take it home.")</syntaxhighlight>
 
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">import rdstdin, re, algorithm, sequtils, strutils
 
#let templ = readLineFromStdin "Enter your story: "
Line 1,577 ⟶ 1,920:
for f,v in zip(fields, values).items:
story = story.replace(f, v)
echo "\nThe story becomes:\n\n", story</langsyntaxhighlight>
Sample run:
<pre>The story template is:
Line 1,593 ⟶ 1,936:
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">: madlibs
| story i word |
Line 1,603 ⟶ 1,946:
]
"Your story :" . story println ;</langsyntaxhighlight>
 
=={{header|Pascal}}==
Line 1,615 ⟶ 1,958:
 
So, no stories involving < symbols, please.
<syntaxhighlight lang="pascal">
<lang Pascal>
Program Madlib; Uses DOS, crt; {See, for example, https://en.wikipedia.org/wiki/Mad_Libs}
{Reads the lines of a story but which also contain <xxx> sequences. For each value of xxx,
Line 1,721 ⟶ 2,064:
for i:=1 to StoryLines do Roll(Story[i]); {Write the amended story.}
END.
</syntaxhighlight>
</lang>
Example run:
C:\Nicky\Pascal\FILEME~1>MADLIB.EXE
Line 1,732 ⟶ 2,075:
=={{header|Perl}}==
Use the name of the file with a story as the parameter to the programme.
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 1,750 ⟶ 2,093:
 
$story =~ s/<(.*?)>/$blanks{$1}/g;
print $story;</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
Set mlfile to the name of a suitable file, if you have one, otherwise it uses the default story.
{{works with|rakudo|2015-09-18}}
<!--<syntaxhighlight lang="phix">-->
Some explanation: <tt>S:g[...] = ...</tt> is a global substitution that returns its result. <tt>%</tt> is an anonymous state variable in which we cache any results of a prompt using the <tt>//=</tt> operator, which assigns only if the left side is undefined. <tt>slurp</tt> reads an entire file from STDIN or as named in the argument list.
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- file i/o, prompt_string</span>
<lang perl6>print S:g[ '<' (.*?) '>' ] = %.{$0} //= prompt "$0? " given slurp;</lang>
<span style="color: #004080;">string</span> <span style="color: #000000;">mlfile</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- eg story.txt</span>
Sample run:
<span style="color: #000000;">mltxt</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mlfile</span><span style="color: #0000FF;">)?</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">read_lines</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mlfile</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">):</span><span style="color: #008000;">"""
<pre>$ madlibs walk
&lt;name&gt; went for a walk in the park. &lt;he or she&gt;
name? Phydeaux
found a &lt;noun&gt;. &lt;name&gt; decided to take it home.
He or She? She
"""</span><span style="color: #0000FF;">)</span>
noun? flea
Phydeaux went for a walk in the park. She
<span style="color: #004080;">sequence</span> <span style="color: #000000;">strings</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">replacements</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
found a flea. Phydeaux decided to take it home.</pre>
<span style="color: #004080;">integer</span> <span style="color: #000000;">startpos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">endpos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">startpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'&lt;'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">endpos</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">startpos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">endpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'&gt;'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">startpos</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">endpos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #008000;">"missing &gt;"</span> <span style="color: #7060A8;">abort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mltxt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">startpos</span><span style="color: #0000FF;">..</span><span style="color: #000000;">endpos</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">strings</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">replacements</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">replacements</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">prompt_string</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Enter replacement for %s:"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">,</span><span style="color: #000000;">replacements</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Enter replacement for <name>:Pete
Enter replacement for <he or she>:He
Enter replacement for <noun>:Rosetta Code Task
Pete went for a walk in the park. He
found a Rosetta Code Task. Pete decided to take it home.
</pre>
Removing all file i/o and prompts to make it pwa/p2js compatible, same final output:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">mltxt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
&lt;name&gt; went for a walk in the park. &lt;he or she&gt;
found a &lt;noun&gt;. &lt;name&gt; decided to take it home.
"""</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">strings</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"&lt;name&gt;"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&lt;he or she&gt;"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&lt;noun&gt;"</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">replacements</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Pete"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"He"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Rosetta Code Task"</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">startpos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">endpos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">startpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'&lt;'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">endpos</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">startpos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">endpos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'&gt;'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">startpos</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">endpos</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"missing &gt;"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mltxt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">startpos</span><span style="color: #0000FF;">..</span><span style="color: #000000;">endpos</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mltxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">,</span><span style="color: #000000;">replacements</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">"<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
true
while
"<" find dup var ini
if
">" find ini - 1 + ini swap slice var replace
"Replace: " replace " with: " chain chain input var with nl
true
while
replace with subst
replace find
endwhile
true
else
false
endif
endwhile
print
</syntaxhighlight>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">import util.
 
go =>
Story = read_story(),
println("Fill in the proper values:"),
nl,
Map = get_info(get_tags(Story)) ,
println("\nHere is the story:\n"),
println(replace_tags(Story,Map)),
nl.
 
read_story() = Story =>
println("Write the story template with <tag> for the tags and finish with an empty line."),
nl,
Story1 = read_line(),
while (Line = read_line(), Line != "")
Story1 := Story1 ++ " " ++ Line
end,
Story = Story1.
 
%
% Get the tags between <...>.
%
get_tags(S) = Tags =>
Len = S.length,
StartPos = [P: {C,P} in zip(S,1..Len), C = '<'],
EndPos = [P: {C,P} in zip(S,1..Len), C = '>'],
Tags = [slice(S,Start,End) : {Start,End} in zip(StartPos,EndPos)].remove_dups().
 
%
% Get the tag info from user and return a map
%
get_info(Tags) = Map =>
Map = new_map(),
foreach(Tag in Tags)
printf("%w: ", Tag),
Map.put(Tag,readln())
end.
 
% Replace all the <tags> with user values.
replace_tags(S,Map) = S =>
foreach(Tag=Value in Map)
S := replace_string(T,Tag,Value)
end.
 
% Picat's replace/3 does not handle substrings well,
% so we roll our own...
replace_string(List,Old,New) = Res =>
Res = copy_term(List),
while (find(Res,Old,_,_))
once(append(Before,Old,After,Res)),
Res := Before ++ New ++ After
end.</syntaxhighlight>
 
{{out}}
<pre>Write the story template with <tag> for the tags and finish with an empty line.
 
<name> went for a walk in the park.
<he or she> found <a or an> <noun>.
<name> decided to take it home.
 
Fill in the proper values:
 
<name>: Snow White
<he or she>: She
<a or an>: an
<noun>: apple
 
Here is the story:
 
Snow White went for a walk in the park. She found an apple. Snow White decided to take it home.</pre>
 
 
=={{header|PicoLisp}}==
This function extends the syntax a bit to be able to express different words with the same description, the syntax is <name:description>, if the description is omitted the name is used instead, keeping backwards compatibility with the syntax used in the task description:
<syntaxhighlight lang="picolisp">(de madlib (Template)
(setq Template (split (chop Template) "<" ">"))
(let (Reps () Text ())
(while Template
(push 'Text (pop 'Template))
(let? Rep (mapcar pack (split (pop 'Template) ":"))
(if (assoc (car Rep) Reps)
(push 'Text (cdr @))
(until (and
(prin "Gimme a(n) " (or (cadr Rep) (car Rep)) ": ")
(clip (in NIL (line)))
(push 'Text @)
(push 'Reps (cons (car Rep) @)) )
(prinl "Huh? I got nothing.") ) ) ) )
(prinl (need 30 '-))
(prinl (flip Text)) ) )
</syntaxhighlight>
 
This runs the example:
<pre>(madlib
"<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home." )
 
Gimme a(n) name: Mr. T
Gimme a(n) he or she: he
Gimme a(n) noun: fool
------------------------------
Mr. T went for a walk in the park. he
found a fool. Mr. T decided to take it home.
</pre>
 
Example with the extended syntax:
<pre>(madlib
"<1:name> went for a walk in the park. <2:he or she>
found a <3:noun (singular)>. <1> decided to take it home.
 
On <4:his or her> way home, <2> found a <5:noun (singular)>,
two <7:noun (plural)> and a <8:noun (singular)>." )
 
Gimme a(n) name: MC Hammer
Gimme a(n) he or she: he
Gimme a(n) noun (singular): pair of baggy pants
Gimme a(n) his or her: his
Gimme a(n) noun (singular): hammer
Gimme a(n) noun (plural): STOP signs
Gimme a(n) noun (singular): clock
------------------------------
MC Hammer went for a walk in the park. he
found a pair of baggy pants. MC Hammer decided to take it home.
 
On his way home, he found a hammer,
two STOP signs and a clock.
</pre>
 
=={{header|Pike}}==
this solution uses readline to make editing more convenient.
<langsyntaxhighlight Pikelang="pike">#!/usr/bin/pike
Stdio.Readline readln = Stdio.Readline();
Line 1,849 ⟶ 2,386:
else add_line(input);
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,883 ⟶ 2,420:
he created PLEAC for all of us to enjoy.
> exit
 
=={{header|PicoLisp}}==
This function extends the syntax a bit to be able to express different words with the same description, the syntax is <name:description>, if the description is omitted the name is used instead, keeping backwards compatibility with the syntax used in the task description:
<lang PicoLisp>(de madlib (Template)
(setq Template (split (chop Template) "<" ">"))
(let (Reps () Text ())
(while Template
(push 'Text (pop 'Template))
(let? Rep (mapcar pack (split (pop 'Template) ":"))
(if (assoc (car Rep) Reps)
(push 'Text (cdr @))
(until (and
(prin "Gimme a(n) " (or (cadr Rep) (car Rep)) ": ")
(clip (in NIL (line)))
(push 'Text @)
(push 'Reps (cons (car Rep) @)) )
(prinl "Huh? I got nothing.") ) ) ) )
(prinl (need 30 '-))
(prinl (flip Text)) ) )
</lang>
 
This runs the example:
<pre>(madlib
"<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home." )
 
Gimme a(n) name: Mr. T
Gimme a(n) he or she: he
Gimme a(n) noun: fool
------------------------------
Mr. T went for a walk in the park. he
found a fool. Mr. T decided to take it home.
</pre>
 
Example with the extended syntax:
<pre>(madlib
"<1:name> went for a walk in the park. <2:he or she>
found a <3:noun (singular)>. <1> decided to take it home.
 
On <4:his or her> way home, <2> found a <5:noun (singular)>,
two <7:noun (plural)> and a <8:noun (singular)>." )
 
Gimme a(n) name: MC Hammer
Gimme a(n) he or she: he
Gimme a(n) noun (singular): pair of baggy pants
Gimme a(n) his or her: his
Gimme a(n) noun (singular): hammer
Gimme a(n) noun (plural): STOP signs
Gimme a(n) noun (singular): clock
------------------------------
MC Hammer went for a walk in the park. he
found a pair of baggy pants. MC Hammer decided to take it home.
 
On his way home, he found a hammer,
two STOP signs and a clock.
</pre>
 
=={{header|PL/I}}==
{{incorrect|PL/I|This seems to hard code the replaceable symbols instead of taking them from the story.}}
<langsyntaxhighlight PLlang="pl/Ii">(stringrange, stringsize): /* 2 Nov. 2013 */
Mad_Libs: procedure options (main);
declare (line, left, right) character (100) varying;
Line 2,012 ⟶ 2,493:
end split;
 
end Mad_Libs;</langsyntaxhighlight>
<pre>
Please type a name:
Line 2,023 ⟶ 2,504:
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function New-MadLibs
{
Line 2,089 ⟶ 2,570:
"`n{0} went for a walk in the park. {1} found a {2}. {0} decided to take it home.`n" -f $Name, $pronoun, $Item
}
</syntaxhighlight>
</lang>
Command line input:
<syntaxhighlight lang="powershell">
<lang PowerShell>
New-MadLibs -Name hank -Male -Item shank
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,099 ⟶ 2,580:
</pre>
Prompt for input:
<syntaxhighlight lang="powershell">
<lang PowerShell>
New-MadLibs
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,118 ⟶ 2,599:
</pre>
Command line input using splatting:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$paramLists = @(@{Name='mary'; Female=$true; Item="little lamb"},
@{Name='hank'; Male=$true; Item="shank"},
Line 2,127 ⟶ 2,608:
New-MadLibs @paramList
}
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,137 ⟶ 2,618:
 
Foo went for a walk in the park. He found a bar. Foo decided to take it home.
</pre>
 
 
=={{header|PureBasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">
If OpenConsole()
cadena$ = "<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = FindString(cadena$, "<")
PrintN("La historia: ")
Print(cadena$ + Chr(10))
While k
reemplaza$ = Mid(cadena$, k, FindString(cadena$, ">") - k + 1)
Print(Chr(10) + "What should replace " + reemplaza$ + " ")
con$ = Input ()
While k
cadena$ = Left(cadena$, k-1) + con$ + Mid(cadena$, k + Len(reemplaza$))
k = FindString(cadena$, reemplaza$, k)
Wend
k = FindString(cadena$, "<")
Wend
PrintN(Chr(10) + "La historia final: ")
PrintN(cadena$)
Input()
CloseConsole()
EndIf
End
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">import re
 
# Optional Python 2.x compatibility
Line 2,159 ⟶ 2,673:
print('\nThe story becomes:\n\n' + story)
 
madlibs(template)</langsyntaxhighlight>
 
{{out}}
Line 2,176 ⟶ 2,690:
=={{header|Racket}}==
Instead of writing the story in the console, it reads from a file given by the player, this is mainly to keep surprise about the final text
<langsyntaxhighlight Racketlang="racket">(define (get-mad-libs file)
(with-input-from-file file
(lambda ()
Line 2,203 ⟶ 2,717:
(string-replace mad-story (car change) (cdr change)))))
 
(play-mad-libs)</langsyntaxhighlight>
 
{{out}} with the story from this page
Line 2,212 ⟶ 2,726:
Don Quixote went for a walk in the park. he
found a Windmill. Don Quixote decided to take it home</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-09-18}}
Some explanation: <tt>S:g[...] = ...</tt> is a global substitution that returns its result. <tt>%</tt> is an anonymous state variable in which we cache any results of a prompt using the <tt>//=</tt> operator, which assigns only if the left side is undefined. <tt>slurp</tt> reads an entire file from STDIN or as named in the argument list.
<syntaxhighlight lang="raku" line>print S:g[ '<' (.*?) '>' ] = %.{$0} //= prompt "$0? " given slurp;</syntaxhighlight>
Sample run:
<pre>$ madlibs walk
name? Phydeaux
He or She? She
noun? flea
Phydeaux went for a walk in the park. She
found a flea. Phydeaux decided to take it home.</pre>
 
=={{header|REBOL}}==
<langsyntaxhighlight lang="rebol">
t: {<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home.}
view layout [a: area wrap t btn "Done" [x: a/text unview]]
parse x [any [to "<" copy b thru ">" (append w: [] b)] to end]
foreach i unique w [replace/all x i ask join i ": "] alert x
</syntaxhighlight>
</lang>
=={{header|Red}}==
While the REBOL GUI version above also works in Red with minor changes, here is a text-only version.
<syntaxhighlight lang="red">phrase: ask "Enter phrase, leave line empty to terminate:^/"
while [not empty? line: input] [append phrase rejoin ["^/" line]]
words: parse phrase [collect [any [to "<" copy b thru ">" keep (b)]]]
foreach w unique words [replace/all phrase w ask rejoin [w ": "]]
print phrase</syntaxhighlight>
{{out}}
Remarkably (with Red 0.6.4 for Windows built 5-Aug-2020/18:58:49+02:00), replacements made in original phrase are dynamically reflected in the display of the phrase entered. Hence first stage of execution yields:
<pre>Enter phrase, leave line empty to terminate:
<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home.
 
<name>: </pre>
...and final output is (so that the last instruction "print phrase" could be omitted):
<pre>Enter phrase, leave line empty to terminate:
As I had nothing to do, I went for a walk in the park. I found a funny task on http://rosettacode.org. As I had nothing to do, I decided to take it home.
 
<name>: As I had nothing to do, I
<he or she>: I
<noun>: funny task on http://rosettacode.org
As I had nothing to do, I went for a walk in the park. I found a funny task on http://rosettacode.org. As I had nothing to do, I decided to take it home.
</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program prompts the user for a template substitutions within a story (MAD LIBS).*/
parse arg iFID . /*allow user to specify the input file.*/
if iFID=='' | iFID=="," then iFID="MAD_LIBS.TXT" /*Not specified? Then use the default.*/
Line 2,256 ⟶ 2,805:
 
say copies('═', 79) /*display a final (output) fence. */
say /*stick a fork in it, we're all done. */</langsyntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[CHANGESTR.REX]].
<br><br>
Line 2,262 ⟶ 2,811:
<pre>
─────────── please enter a word or phrase to replace: name
Mary ◄■■■■■■■■■■ user input
Mary
─────────── please enter a word or phrase to replace: he or she
she ◄■■■■■■■■■■ user input
she
─────────── please enter a word or phrase to replace: noun
little lamb ◄■■■■■■■■■■ user input
little lamb
 
 
Line 2,276 ⟶ 2,825:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
temp="<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = substr(temp,"<")
Line 2,290 ⟶ 2,839:
end
see temp + nl
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">puts "Enter a story, terminated by an empty line:"
story = ""
until (line = gets).chomp.empty?
Line 2,305 ⟶ 2,854:
 
puts
puts story</langsyntaxhighlight>
 
Example
Line 2,320 ⟶ 2,869:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">temp$="<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = instr(temp$,"<")
while k
Line 2,332 ⟶ 2,881:
wend
print temp$
wait</langsyntaxhighlight>
{{out}}
<pre>
Line 2,340 ⟶ 2,889:
Fred went for a walk in the park. he found a cat. Fred decided to take it home.
</pre>
 
=={{header|Rust}}==
{{libheader|regex}}
<syntaxhighlight lang="rust">extern crate regex;
 
use regex::Regex;
use std::collections::HashMap;
use std::io;
 
fn main() {
let mut input_line = String::new();
let mut template = String::new();
 
println!("Please enter a multi-line story template with <parts> to replace, terminated by a blank line.\n");
loop {
io::stdin()
.read_line(&mut input_line)
.expect("The read line failed.");
if input_line.trim().is_empty() {
break;
}
template.push_str(&input_line);
input_line.clear();
}
 
let re = Regex::new(r"<[^>]+>").unwrap();
let mut parts: HashMap<_, _> = re
.captures_iter(&template)
.map(|x| (x.get(0).unwrap().as_str().to_string(), "".to_string()))
.collect();
if parts.is_empty() {
println!("No <parts> to replace.\n");
} else {
for (k, v) in parts.iter_mut() {
println!("Please provide a replacement for {}: ", k);
io::stdin()
.read_line(&mut input_line)
.expect("The read line failed.");
*v = input_line.trim().to_string();
println!();
template = template.replace(k, v);
input_line.clear();
}
}
println!("Resulting story:\n\n{}", template);
}</syntaxhighlight>
{{out}}
<pre>
Please enter a multi-line story template with <parts> to replace, terminated by a blank line.
 
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Please provide a replacement for <name>:
John Wick
 
Please provide a replacement for <he or she>:
He
 
Please provide a replacement for <noun>:
puppy
 
Resulting story:
 
John Wick went for a walk in the park. He
found a puppy. John Wick decided to take it home.
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object MadLibs extends App{
val input = "<name> went for a walk in the park. <he or she>\nfound a <noun>. <name> decided to take it home."
println(input)
Line 2,354 ⟶ 2,971:
println
println(output)
}</langsyntaxhighlight>
{{out}}
<pre><name> went for a walk in the park. <he or she>
Line 2,367 ⟶ 2,984:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: main is func
Line 2,397 ⟶ 3,014:
writeln("The story becomes:");
write(story);
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,416 ⟶ 3,033:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">var story = ARGF.slurp;
 
var blanks = Hash.new;
Line 2,428 ⟶ 3,045:
}
 
print story.gsub(/<(.*?)>/, {|s1| blanks{s1} });</langsyntaxhighlight>
 
=={{header|tbas}}==
<syntaxhighlight lang="qbasic">SUB BETWEEN$(TXT$, LHS$, RHS$, AFTER)
LET LHS = POS(TXT$, LHS$, AFTER)
IF LHS = 0 THEN
'LHS$ NOT FOUND IN TXT$. RETURN EMPTY STRING
RETURN ""
EXIT SUB
END IF
LET RHS = POS(TXT$, RHS$, LHS + LEN(LHS$))
IF RHS = 0 THEN
'NO RHS$ FOUND IMMEDIATELY AFTER LHS$ IN TXT$. RETURN EMPTY STRING.
RETURN ""
EXIT SUB
END IF
RETURN SEG$(TXT$, LHS + LEN(LHS$), RHS-1)
END SUB
 
DECLARE SUB REPLACE$(INTHIS$, FINDTHIS$, WITHTHIS$)
LET T = POS(INTHIS$, FINDTHIS$)
RETURN INTHIS$
IF T <> 0 THEN
MID$(INTHIS$, T, LEN(FINDTHIS$)) = WITHTHIS$
RETURN INTHIS$
END IF
END SUB
 
LET STORY$ = ""
LET STORYLINE$ = ""
WHILE TRUE
LINE INPUT "Enter line of story (empty line to stop)"; STORYLINE$
IF STORYLINE$ = "" THEN
EXIT WHILE
END IF
STORY$ = STORY$ + " " + STORYLINE$
END WHILE
 
WHILE TRUE
LET TXT$ = ""
LET KEY$ = BETWEEN$(STORY$, "<", ">", 0)
IF KEY$ <> "" THEN
PRINT "PLEASE ENTER A " + KEY$;
LINE INPUT TXT$
LET SRCH$ = "<" + KEY$ + ">"
STORY$ = REPLACE$(STORY$, SRCH$, TXT$)
ELSE
EXIT WHILE
END IF
END WHILE
 
PRINT STORY$</syntaxhighlight>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Read the template...
Line 2,453 ⟶ 3,121:
puts [string repeat "-" 70]
puts -nonewline [string map $mapping $content]
puts [string repeat "-" 70]</langsyntaxhighlight>
Sample session:
<pre>
Line 2,472 ⟶ 3,140:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">Function mad_libs(s)
<lang vb>
Do
Function mad_libs(s)
If InStr(1,s,"<") <> 0 Then
Do
If start_position = InStr(1,s,"<") <>+ 0 Then1
start_position end_position = InStr(1,s,"<>") + 1
parse_string = Mid(s,start_position,end_position-start_position)
end_position = InStr(1,s,">")
WScript.StdOut.Write parse_string & "? "
parse_string = Mid(s,start_position,end_position-start_position)
input_string = WScript.StdIn.ReadLine
WScript.StdOut.Write parse_string & "? "
s = Replace(s,"<" & parse_string & ">",input_string)
input_string = WScript.StdIn.ReadLine
Else
s = Replace(s,"<" & parse_string & ">",input_string)
Exit Do
Else
End If
Exit Do
Loop
End If
mad_libs = s
Loop
mad_libs = s
End Function
 
WScript.StdOut.Write mad_libs("<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home.")
WScript.StdOut.WriteLine</syntaxhighlight>
</lang>
 
{{Out}}
<pre>F:\>cscript /nologo mad_libs.vbs
<pre>
F:\>cscript /nologo mad_libs.vbs
name? babe
he or she? she
noun? cat
babe went for a walk in the park. she found a cat. babe decided to take it home.</pre>
 
=={{header|Visual Basic .NET}}==
 
"\<" can be used to escape a "<" outside of a template (the escape is not recognized within a template), and "\>" can be used to escape a ">" inside of a template. Templates can span lines. A possible improvement from a UX standpoint is to check for template validity before beginning to request for substitutions; currently, unclosed templates are only found when they are encountered in the replacement process.
 
<syntaxhighlight lang="vbnet">Imports System.Text
 
Module Program
Private Function GetStory() As String
Dim input As New StringBuilder()
Do
Dim nextLine = Console.ReadLine()
If String.IsNullOrEmpty(nextLine) Then Exit Do
input.AppendLine(nextLine)
Loop
 
Dim story = input.ToString()
Return story
End Function
 
Sub Main()
Dim input As String = GetStory()
 
Dim result As New StringBuilder()
Dim replacements As New Dictionary(Of String, String)
 
For i = 0 To input.Length - 1
Dim curChar = input(i)
 
' For all characters but '<', append it and move on.
If curChar <> "<"c Then
result.Append(curChar)
Else
' If the character before was a backslash, then replace the backslash in the result with a '<' and move on.
If i > 0 AndAlso input(i - 1) = "\"c Then
result(result.Length - 1) = "<"c
Continue For
End If
 
' Search for the first '>' that isn't preceded by a backslash.
Dim closeBracketPos = -1
For ind = i To input.Length - 1
If input(ind) = ">"c AndAlso input(ind - 1) <> "\"c Then
closeBracketPos = ind
Exit For
End If
Next
 
' The search failed to find a '>'.
If closeBracketPos < 0 Then
Console.WriteLine($"ERROR: Template starting at position {i} is not closed.")
Environment.Exit(-1)
End If
 
' The text between the current character and the found '>' character, with escape sequences simplified.
Dim key As String = input.Substring(i + 1, closeBracketPos - i - 1).Replace("\>", ">", StringComparison.Ordinal)
 
Dim subst As String = Nothing
' Ask for and store a replacement value if there isn't already one for the key.
If Not replacements.TryGetValue(key, subst) Then
Console.Write($"Enter a {key}: ")
subst = Console.ReadLine()
replacements.Add(key, subst)
End If
 
result.Append(subst)
i = closeBracketPos
End If
Next
 
Console.WriteLine()
Console.Write(result)
End Sub
End Module</syntaxhighlight>
 
{{out|note=for sample input}}
<pre><name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Enter a name: Foo
Enter a he or she: it
Enter a noun: bar
 
Foo went for a walk in the park. it
found a bar. Foo decided to take it home.</pre>
 
{{out|note=demonstrating additional features}}
<pre><multi-
line
template>
...
\<\< <\>thing<>
...
\> <\<thing>
...
<<<thing>>>
 
Enter a multi-
line
template: foo
Enter a >thing<: bar
Enter a \<thing: baz
Enter a <<thing: qux
 
foo
...
<< bar
...
\> baz
...
qux>></pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-pattern}}
{{libheader|Wren-seq}}
<syntaxhighlight lang="wren">import "io" for Stdin, Stdout
import "./pattern" for Pattern
import "./seq" for Lst
 
System.print("Please enter a multi-line story template terminated by a blank line:\n")
Stdout.flush()
var story = ""
while (true) {
var line = Stdin.readLine()
if (line.isEmpty) break
story = story + line + "\n" // preserve line breaks
}
// identify blanks
var p = Pattern.new("<+0^>>")
var blanks = Lst.distinct(p.findAll(story).map { |m| m.text }.toList)
System.print("Please enter your replacements for the following 'blanks' in the story:")
for (blank in blanks) {
System.write(" %(blank[1..-2]) : ")
Stdout.flush()
var repl = Stdin.readLine()
story = story.replace(blank, repl)
}
System.print("\n%(story)")</syntaxhighlight>
 
{{out}}
<pre>
Please enter a multi-line story template terminated by a blank line:
 
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
 
Please enter your replacements for the following 'blanks' in the story:
name : Archimedes
he or she : He
noun : bath-tub
 
Archimedes went for a walk in the park. He
found a bath-tub. Archimedes decided to take it home.
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">story,line,re:=Data(),"",RegExp("(<[^>]+>)");
do{ line=ask("Story: "); story.write(line,"\n") }while(line);
while(re.search(story,True)){
Line 2,511 ⟶ 3,330:
}
println("-----------------");
story.text.print();</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits