Mad Libs: Difference between revisions

1,437 bytes added ,  9 years ago
→‎{{header|Pascal}}: Why not enable references to <..> entries within replacement texts. This requires recursion...
(→‎{{header|Pascal}}: Why not enable references to <..> entries within replacement texts. This requires recursion...)
Line 1,133:
A particular feature of Pascal strings is that text[i] gets the i'th character of a string variable ''text'' but copy(text,start,count) is needed for two or more characters. It is not clear whether in <code>if Target[it] = copy(bumf,mark,i - mark + 1) then ...</code> a temporary variable will be made to hold the result of the ''copy'' (as is implied by the name) or whether the comparison will be done "in place". Using <code>if Target[it] = hit then ...</code> ensures that one copy is made but loses the possibility that no copy would be made.
 
There is no checking that (for example) a > follows a <, nor whether spacing within <...> as in < a noun > is to be objected to. Likewise, will <name> differ from <name >? To ensure that, the < and > symbols are made a part of the Target text. Story text cannot employ a < symbol as itself - it would have to be something like "<please type a <>". However, an entertaining extension is to allow the replacement text to contain references to <...> entries which means that < is a reserved symbol even within a replacement text so that it would have to be <please type a less-than symbol>.
<lang Pascal>
Program Madlib; Uses DOS, crt; {See, for example, https://en.wikipedia.org/wiki/Mad_Libs}
Line 1,160:
if Aline = '' then Reading:=false; {Specified that a blank line ends the story.}
End;
 
Procedure Inspect(text: string); Forward;{I'd rather have multi-pass compilation than deal with this.}
 
Procedure Table(it: string); {Check it as a target, and obtain its replacement.}
Line 1,170 ⟶ 1,172:
write('Enter your text for ',it,': '); {Pretty please?}
readln(Replacement[TableCount]); {Thus.}
Inspect(Replacement[TableCount]); {Enable full utilisation.}
End; {of Table.}
 
var InDeep: integer; {Counts inspection recursion.}
Procedure Swallow(Aline: string); {Add a line to the story, and inspect it for <...>.}
Procedure Inspect(text: string); {Look for <...> in text.}
var i: integer; {A stepper.}
var mark: integer; {Fingers the latest < in Aline.}
Begin
inc(InDeep); {Supply an opportunity, and fear the possibilities.}
if StoryLines >= StoryLimit then Croak('Too many lines in the story!'); {Suspicion forever.}
if InDeep > 28 then Croak('Excessive recursion! Inspecting ' + text);
for i:=1 to Length(text) do {Now scan the line for trouble.}
if Alinetext[i] = '<' then mark:=i {Trouble starts here? Just mark its place.}
else if Alinetext[i] = '>' then {Trouble ends here?}
Table(copy(Alinetext,mark,i - mark + 1)); {Deal with it.}
dec(InDeep); {I'm done.}
End; {of Inspect.}
 
Procedure Swallow(Aline: string); {Add a line to the story, and inspect it for <...>.}
Begin
if StoryLines >= StoryLimit then Croak('Too many lines in the story!'); {Suspicion forever.}
inc(StoryLines); {Otherwise, this is safe.}
Story[StoryLines]:=Aline; {So save another line.}
for i:=1 to LengthInspect(Aline) do; {NowLook scanfor theany line for<...> troubleinclusions.}
if Aline[i] = '<' then mark:=i {Trouble starts here? Just mark its place.}
else if Aline[i] = '>' then {Trouble ends here?}
Table(copy(Aline,mark,i - mark + 1)); {Deal with it.}
End; {of Swallow.}
 
var Rolling: integer; {Counts rolling rolls.}
Procedure Roll(bumf: string); {Write a line, with amendments.}
var last,mark: integer; {Fingers for the scan.}
Line 1,191 ⟶ 1,204:
label hic; {Oh dear.}
Begin
inc(Rolling); {Here I go.}
if Rolling > 28 then Croak('Excessive recursion! Rolling ' + bumf); {Self-expansion is out.}
last:=0; {Where the previous text ended.}
for i:=1 to Length(bumf) do {Scan the text.}
Line 1,201 ⟶ 1,216:
if Target[it] = hit then {A match?}
begin {Yes!}
writeRoll(Replacement[it]); {Write this instead.}
goto hic; {There is no "exit loop" style statement.}
end; {"Exit" exits the procedure or function.}
hic:last:=i; {Advance the trailing finger.}
end; {On to the next character.}
WriteLnWrite(copy(bumf,last + 1,Length(bumf) - last)); {Text after the last >, possibly null.}
dec(Rolling); {I'm done.}
if Rolling <= 0 then WriteLn; {And if this is the first level, add a end-of-line.}
End; {of Roll.}
 
Line 1,213 ⟶ 1,230:
var i: integer; {A stepper.}
BEGIN
InDeep:=0; {No inspections yet.}
Rolling:=0; {No output.}
inname:=ParamStr(1); {Perhaps the file name is specified as a run-time parameter.}
if inname = '' then inname:='Madlib.txt'; {If not, this will do.}
Line 1,222 ⟶ 1,241:
END.
</lang>
Example run:
C:\Nicky\Pascal\FILEME~1>MADLIB.EXE
Enter your text for <name>: Jack
Enter your text for <he or she>: He
Enter your text for <noun>: banknote with <name> written on it
Jack went for a walk in the park. He
found a banknote with Jack written on it. Jack decided to take it home.
 
=={{header|Perl}}==
1,220

edits