1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/WorldModelKit/S-msc.html
2020-04-15 23:49:59 +01:00

1202 lines
74 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Output Template</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Extensions</h2><ul>
<li><a href="../basic_inform/index.html">basic_inform</a></li>
<li><a href="../standard_rules/index.html">standard_rules</a></li>
</ul><h2>Kits</h2><ul>
<li><a href="../BasicInformKit/index.html">BasicInformKit</a></li>
<li><a href="../BasicInformExtrasKit/index.html">BasicInformExtrasKit</a></li>
<li><a href="../CommandParserKit/index.html">CommandParserKit</a></li>
<li><a href="../EnglishLanguageKit/index.html">EnglishLanguageKit</a></li>
<li><a href="index.html"><span class="selectedlink">WorldModelKit</span></a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Output Template' generated by 7-->
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">WorldModelKit</a></li><li><b>Output Template</b></li></ul><p class="purpose">This is the superstructure of the file of I6 code output by Inform: from ICL commands at the top down to the signing-off comments at the bottom.</p>
<ul class="toc"><li><a href="S-msc.html#SP1">&#167;1. ICL Commands</a></li><li><a href="S-msc.html#SP2">&#167;2. Identification</a></li><li><a href="S-msc.html#SP3">&#167;3. Constants</a></li><li><a href="S-msc.html#SP4">&#167;4. Global Variables</a></li><li><a href="S-msc.html#SP5">&#167;5. Compass</a></li><li><a href="S-msc.html#SP6">&#167;6. Score and Rankings Table</a></li><li><a href="S-msc.html#SP7">&#167;7. The Old Library</a></li><li><a href="S-msc.html#SP8">&#167;8. Parser</a></li><li><a href="S-msc.html#SP9">&#167;9. Order of Play</a></li><li><a href="S-msc.html#SP10">&#167;10. Activities</a></li><li><a href="S-msc.html#SP11">&#167;11. Object Tree</a></li><li><a href="S-msc.html#SP12">&#167;12. Tables</a></li><li><a href="S-msc.html#SP13">&#167;13. Equations</a></li><li><a href="S-msc.html#SP14">&#167;14. Actions</a></li><li><a href="S-msc.html#SP15">&#167;15. Phrases</a></li><li><a href="S-msc.html#SP16">&#167;16. Rulebooks</a></li><li><a href="S-msc.html#SP17">&#167;17. Scenes</a></li><li><a href="S-msc.html#SP18">&#167;18. The New Library</a></li><li><a href="S-msc.html#SP19">&#167;19. Parsing Tokens</a></li><li><a href="S-msc.html#SP20">&#167;20. Text generation</a></li><li><a href="S-msc.html#SP21">&#167;21. Testing commands</a></li><li><a href="S-msc.html#SP22">&#167;22. I6 Inclusions</a></li><li><a href="S-msc.html#SP23">&#167;23. Entries in constant lists</a></li><li><a href="S-msc.html#SP24">&#167;24. To Phrases</a></li><li><a href="S-msc.html#SP25">&#167;25. Chronology</a></li><li><a href="S-msc.html#SP26">&#167;26. Grammar</a></li><li><a href="S-msc.html#SP27">&#167;27. Deferred Propositions</a></li><li><a href="S-msc.html#SP28">&#167;28. Miscellaneous Loose Ends</a></li><li><a href="S-msc.html#SP29">&#167;29. Block Values</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. ICL Commands. </b>The Inform Control Language is a mini-language for controlling the I6 compiler,
able to set command-line switches, memory settings and so on. I6 ordinarily
discards lines beginning with exclamation marks as comments, but at the very
top of the file, lines beginning <code class="display"><span class="extract">!%</span></code> are read as ICL commands: as soon as
any line (including a blank line) doesn't have this signature, I6 exits
ICL mode.
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Identification. </b>Both of the compiler and template layer, and of the story file to be produced.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Constants. </b></p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Global Variables. </b>These are not the only global variables defined in the template layer:
those needed locally only by single sections (and not used in definitions
of phrases in the Standard Rules, or referred to by Inform directly) are defined
within those sections &mdash; they can be regarded as unimportant implementation
details, subject to change at whim. The variables here, on the other hand,
are more important to understand.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) The first three variables to be defined are special in that they are
significant to very early-style Z-machine interpreters, where they are
used to produce the status line display (hence <code class="display"><span class="extract">sline1</span></code> and <code class="display"><span class="extract">sline2</span></code>).
The first variable must always equal a valid object number, which is why
we &mdash; pretty weirdly &mdash; set it equal to the placeholder object <code class="display"><span class="extract">InformLibrary</span></code>,
which takes no part in play, and is not a valid I7 object. This is not
typesafe in I7 terms, but that doesn't matter because initialisation
will correct it to a typesafe value before any I7 source text can execute.
(<code class="display"><span class="extract">sline1</span></code> and <code class="display"><span class="extract">sline2</span></code> are entirely unused on when we target Glulx.)
Once these variables are defined, the sequence of definition of the rest
is not significant.
</li></ul>
<ul class="items"><li>(2) The <code class="display"><span class="extract">say__*</span></code> are used for the finite state machine used in printing
text, which keeps track of automatic paragraph breaking and the like. For
details see the "Printing.i6t" section.
</li></ul>
<ul class="items"><li>(3) <code class="display"><span class="extract">standard_interpreter</span></code> is used only for the Z-machine VM, and is always
0 for Glulx. For Z, a non-zero value here is the version number of the
{\it Z-Machine Standards Document} which the interpreter claims to support,
in the form (upper byte).(lower). <code class="display"><span class="extract">undo_flag</span></code>, similarly, behaves slightly
differently on the two platforms according to whether they support multiple
consecutive UNDOs. UNDO basically works by taking memory snapshots of the
whole VM ("saving UNDO") to revert to at a later point ("performing UNDO"),
so it is expensive on memory, and traditional VMs can only store a single
memory snapshot &mdash; making two UNDOs in a row, going back two steps,
impossible. Given this, <code class="display"><span class="extract">undo_flag</span></code> has three possible states: 0 means
UNDO is not available at all, 1 means it is not available now because
there is no further saved state to go back to from here, and 2 means it
is available.
</li></ul>
<ul class="items"><li>(4) <code class="display"><span class="extract">deadflag</span></code> in normally 0, or false, meaning play continues; 1 means the
game ended in death; 2 for ended in victory; higher numbers represent
exotic endings. (As from May 2010, the use of 2 for victory is deprecated,
and a separate flag, <code class="display"><span class="extract">story_complete</span></code>, records whether the story is
"complete" in the sense that we don't expect the player to replay.)
<code class="display"><span class="extract">deadflag</span></code> switching state normally triggers an end to rulebook processing,
so is the single most important global variable to the running of a story
file.
</li></ul>
<ul class="items"><li>(5) At present, <code class="display"><span class="extract">time_rate</span></code> is not made use of in I7: if positive, it is
the number of minutes which pass each turn; if negative, the number of
turns which pass each minute. This is quite a neat way to approximate a
wide range of time steps with an integer such that fractions are exact
and we can approximate any duration to a fair accuracy (the worst case
being \(3/4\) minute, where we have to choose between 1 minute or \(1/2\)
minute).
</li></ul>
<ul class="items"><li>(6) Note that <code class="display"><span class="extract">notify_mode</span></code> is irrelevant if the use option "Use no scoring"
is in force: it isn't looked at, and can't be changed, and shouldn't have
an effect anyway since <code class="display"><span class="extract">score</span></code> will never be altered.
</li></ul>
<ul class="items"><li>(7) <code class="display"><span class="extract">player</span></code> is a variable, not a constant, since the focus of play can
change. <code class="display"><span class="extract">SACK_OBJECT</span></code> is likewise an unexpected variable: in the I6
library, there could only be one player's holdall, a single rucksack-like
possession which had to be the value of the constant <code class="display"><span class="extract">SACK_OBJECT</span></code>. Here we
define <code class="display"><span class="extract">SACK_OBJECT</span></code> as a global variable instead, the value of which is
the player's holdall currently in use. <code class="display"><span class="extract">visibility_ceiling</span></code> is the
highest object in the tree visible from the player's point of view:
usually the room, but sometimes nothing (in darkness), and sometimes a
closed non-transparent container.
</li></ul>
<ul class="items"><li>(8) See "OrderOfPlay.i6t" for the meaning of action variables.
</li></ul>
<ul class="items"><li>(9) This is a slate of global variables used by the parser to give some
context to the general parsing routines (GPRs) which it calls; in the I6
design, any object can provide its own GPR, in the form of a <code class="display"><span class="extract">parse_name</span></code>
property. GPRs are in effect parser plug-ins, and I7 makes extensive use
of them.
</li></ul>
<ul class="items"><li>(10) Similarly, variables for the parser to give context to another sort
of plug-in routine: a scope filter. I7 uses these too.
</li></ul>
<ul class="items"><li>(11) The <code class="display"><span class="extract">move_*</span></code> variables are specific to the <code class="display"><span class="extract">##Going</span></code> action.
</li></ul>
<ul class="items"><li>(12) These variables hold current settings for listing objects and,
more elaborately, performing room descriptions.
</li></ul>
<ul class="items"><li>(13) The current colour scheme is stored in variables in order that it can
be saved in the save game state, and changed correctly on an UNDO: if it
were a transient state inside the VM interpreter's screen model, then a
RESTORE or UNDO will upset what the original author may have intended the
appearance of text in particular scenes to be. (Cf. Adam Cadre's I6 patch
<code class="display"><span class="extract">L61007</span></code>.)
</li></ul>
<ul class="items"><li>(14) These pixel dimensions are used both for the Glulx and v6 Z-machines,
but not for the more commonly used versions 5 or 8, whose screen model is
based on character cells.
</li></ul>
<pre class="display">
<span class="comment"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">location</span><span class="plain"> = </span><span class="identifier">InformLibrary</span><span class="plain">; </span><span class="comment">does not = I7 "location": see below</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">sline1</span><span class="plain">; </span><span class="identifier">Global</span><span class="plain"> </span><span class="identifier">sline2</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">undo_flag</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">story_complete</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">resurrect_please</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">not_yet_in_play</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; </span><span class="comment">set false when first command received</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">turns</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">= I7 "turn count"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">the_time</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">= I7 "time of day"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">time_rate</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">NUMBER_SCENES_CREATED</span><span class="plain"> = </span><span class="identifier">ICOUNT_SCENE</span><span class="plain">;</span>
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain"> = (</span><span class="identifier">NUMBER_SCENES_CREATED</span><span class="plain">+2);</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">scene_started</span><span class="plain"> --&gt; </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">scene_ended</span><span class="plain"> --&gt; </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">scene_status</span><span class="plain"> --&gt; </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">scene_endings</span><span class="plain"> --&gt; </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">scene_latest_ending</span><span class="plain"> --&gt; </span><span class="identifier">SCENE_ARRAY_SIZE</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:6"><a href="#fn:6" rel="footnote">6</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">score</span><span class="plain">; </span><span class="comment">= I7 "score"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">last_score</span><span class="plain">; </span><span class="comment">= I7 "last notified score"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">notify_mode</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">score notification on or off</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">left_hand_status_line</span><span class="plain"> = </span><span class="identifier">T_SL_Location</span><span class="plain">; </span><span class="comment">= I7 "left hand status line"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">right_hand_status_line</span><span class="plain"> = </span><span class="identifier">T_SL_Score_Moves</span><span class="plain">; </span><span class="comment">= I7 "right hand status line"</span>
<span class="comment"><sup id="fnref:7"><a href="#fn:7" rel="footnote">7</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">player</span><span class="plain">; </span><span class="comment">= I7 "player"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">real_location</span><span class="plain">; </span><span class="comment">= I7 "location"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">visibility_ceiling</span><span class="plain">; </span><span class="comment">highest object in tree visible to player</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">visibility_levels</span><span class="plain">; </span><span class="comment">distance in tree to that</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">SACK_OBJECT</span><span class="plain">; </span><span class="comment">current player's holdall item in use</span>
<span class="comment"><sup id="fnref:8"><a href="#fn:8" rel="footnote">8</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">act_requester</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">actor</span><span class="plain">; </span><span class="comment">= I7 "person asked" = I7 "person reaching"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">actors_location</span><span class="plain">; </span><span class="comment">like real_location, but for the actor</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">actor_location</span><span class="plain">; </span><span class="comment">= I7 "actor-location"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">action</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">meta</span><span class="plain">; </span><span class="comment">action is out of world</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">inp1</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">inp2</span><span class="plain">;</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">multiple_object</span><span class="plain"> --&gt; </span><span class="identifier">MATCH_LIST_WORDS</span><span class="plain">; </span><span class="comment">multiple-object list (I6 table array)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">toomany_flag</span><span class="plain">; </span><span class="comment">multiple-object list overflowed</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multiflag</span><span class="plain">; </span><span class="comment">multiple-object being processed</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">multiple_object_item</span><span class="plain">; </span><span class="comment">item currently being processed in multiple-object list</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">noun</span><span class="plain">; </span><span class="comment">= I7 "noun"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">second</span><span class="plain">; </span><span class="comment">= I7 "second noun"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">keep_silent</span><span class="plain">; </span><span class="comment">true if current action is being tried silently</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">etype</span><span class="plain">; </span><span class="comment">parser error number if command not recognised</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">trace_actions</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">untouchable_object</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">untouchable_silence</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">touch_persona</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">special_word</span><span class="plain">; </span><span class="comment">dictionary address of first word in "[text]" token</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">consult_from</span><span class="plain">; </span><span class="comment">word number of start of "[text]" token</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">consult_words</span><span class="plain">; </span><span class="comment">number of words in "[text]" token</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parsed_number</span><span class="plain">; </span><span class="comment">value from any token not an object</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">special_number1</span><span class="plain">; </span><span class="comment">first value, if token not an object</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">special_number2</span><span class="plain">; </span><span class="comment">second value, if token not an object</span>
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">parser_results</span><span class="plain"> --&gt; </span><span class="constant">16</span><span class="plain">; </span><span class="comment">for parser to write its results in</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parser_trace</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">normally 0, but 1 to 5 traces parser workings</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pronoun_word</span><span class="plain">; </span><span class="comment">records which pronoun ("it", "them", ...) caused an error</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">pronoun_obj</span><span class="plain">; </span><span class="comment">and what object it was thought to refer to</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">players_command</span><span class="plain"> = </span><span class="constant">100</span><span class="plain">; </span><span class="comment">= I7 "player's command"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">matched_text</span><span class="plain">; </span><span class="comment">= I7 "matched text"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">understand_as_mistake_number</span><span class="plain">; </span><span class="comment">which form of "Understand... as a mistake"</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">particular_possession</span><span class="plain">; </span><span class="comment">= I7 "particular possession"</span>
<span class="comment"><sup id="fnref:9"><a href="#fn:9" rel="footnote">9</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parser_action</span><span class="plain">; </span><span class="comment">written by the parser for the benefit of GPRs</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parser_one</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parser_two</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">parameters</span><span class="plain">; </span><span class="comment">number of I7 tokens parsed on the current line</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">action_to_be</span><span class="plain">; </span><span class="comment">(if the current line were accepted)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">action_reversed</span><span class="plain">; </span><span class="comment">(parameters would be reversed in order)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">wn</span><span class="plain">; </span><span class="comment">word number within "parse" buffer (from 1)</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">num_words</span><span class="plain">; </span><span class="comment">number of words in buffer</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">verb_word</span><span class="plain">; </span><span class="comment">dictionary address of command verb</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">verb_wordnum</span><span class="plain">; </span><span class="comment">word number of command verb</span>
<span class="comment"><sup id="fnref:10"><a href="#fn:10" rel="footnote">10</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">scope_reason</span><span class="plain"> = </span><span class="identifier">PARSING_REASON</span><span class="plain">; </span><span class="comment">current reason for searching scope</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">scope_token</span><span class="plain">; </span><span class="comment">for "scope=Routine" grammar tokens</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">scope_error</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">scope_stage</span><span class="plain">; </span><span class="comment">1, 2 then 3</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">advance_warning</span><span class="plain">; </span><span class="comment">what a later-named thing will be</span>
<span class="comment">Global reason_code = NULL; ! for the I6 veneer</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">ats_flag</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="comment">for AddToScope routines</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">ats_hls</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:11"><a href="#fn:11" rel="footnote">11</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">move_pushing</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">move_from</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">move_to</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">move_by</span><span class="plain">;</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">move_through</span><span class="plain">;</span>
<span class="comment"><sup id="fnref:12"><a href="#fn:12" rel="footnote">12</a></sup></span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">lookmode</span><span class="plain"> = </span><span class="identifier">TEMPLATE_CONFIGURATION_LOOKMODE</span><span class="plain">; </span><span class="comment">1 = BRIEF, 2 = VERBOSE, 3 = SUPERBRIEF</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">c_style</span><span class="plain">; </span><span class="comment">current list-writer style</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">c_depth</span><span class="plain">; </span><span class="comment">current recursion depth</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">c_iterator</span><span class="plain">; </span><span class="comment">current iteration function</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">lt_value</span><span class="plain"> = </span><span class="identifier">EMPTY_TEXT_VALUE</span><span class="plain">; </span><span class="comment">common value of list_together</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">listing_together</span><span class="plain">; </span><span class="comment">object number of one member of a group being listed together</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">listing_size</span><span class="plain">; </span><span class="comment">size of such a group</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">c_margin</span><span class="plain">; </span><span class="comment">current level of indentation printed by WriteListFrom()</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">inventory_stage</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="comment">1 or 2 according to the context in which list_together uses</span>
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">debug_scenes</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Compass. </b>I6 identified compass directions as being children of the pseudo-object
<code class="display"><span class="extract">Compass</span></code>, so we define it. (Note that <code class="display"><span class="extract">Compass</span></code> is not a valid I7 object,
and is used for no other purpose.) Because of the traditional structure
of language definitions, this needs to come first.
</p>
<pre class="display">
<span class="identifier">Object</span><span class="plain"> </span><span class="identifier">Compass</span><span class="plain"> </span><span class="string">"compass"</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">concealed</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Score and Rankings Table. </b>The following command tells Inform to compile constant definitions for <code class="display"><span class="extract">INITIAL_MAX_SCORE</span></code>
and/or <code class="display"><span class="extract">RANKING_TABLE</span></code>, in cases where there are scores and rankings. If there's
no ranking table, <code class="display"><span class="extract">RANKING_TABLE</span></code> is left undefined, so that we can <code class="display"><span class="extract">#ifdef</span></code> this
possibility later.
</p>
<pre class="display">
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">MAX_SCORE</span><span class="plain"> = </span><span class="identifier">INITIAL_MAX_SCORE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. The Old Library. </b>The I6 library consisted essentially of the parser, the verb routines, and
a pile of utilities and world-modelling code, of which the biggest single
component was the list-writer. The parser lives on below; the verb routines
are gone, with the equivalent functionality having moved upstairs into
I7 source text in the Standard Rules; and the rest of the library largely
lives here:
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Parser. </b>The largest single block of code in the traditional I6 library part of the
template layer is the parser.
</p>
<p class="inwebparagraph">The two pseudo-objects <code class="display"><span class="extract">InformParser</span></code> and <code class="display"><span class="extract">InformLibrary</span></code> are relics of the
object-oriented approach in I6, and are used only very slightly in the
template layer; they are not used at all in I7, and are not valid for the
"object" kind of value.
</p>
<p class="inwebparagraph">The parser includes arrays for typed text and some parsing information
derived from it, and if these should overrun it would cause enigmatic
bugs, as the next arrays in memory would be corrupted: as a tripwire,
the <code class="display"><span class="extract">Protect_I7_Arrays</span></code> array consists of two magic values in sequence.
If it is ever discovered to contain the wrong data, the alarm sounds.
</p>
<pre class="display">
<span class="identifier">Object</span><span class="plain"> </span><span class="identifier">InformParser</span><span class="plain"> </span><span class="string">"(Inform Parser)"</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">proper</span><span class="plain">;</span>
<span class="plain">[ </span><span class="identifier">ParserError</span><span class="plain"> </span><span class="identifier">error_type</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">error_type</span><span class="plain">) </span><span class="identifier">PrintSingleParagraph</span><span class="plain">(</span><span class="identifier">error_type</span><span class="plain">);</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
<span class="identifier">Object</span><span class="plain"> </span><span class="identifier">InformLibrary</span><span class="plain"> </span><span class="string">"(Inform Library)"</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">proper</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Order of Play. </b>The <code class="display"><span class="extract">Main</span></code> routine, where execution begins, and the primitive rules in the
principal rulebooks.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Activities. </b>These are numbered upwards from 0 in order of creation. The following arrays
taken together provide, for each activity number: (i) the rulebook numbers
for the before, for, and after stages of the activity, and (ii) a flag
indicating whether the activity is "future action"-capable, that is, is
a parsing activity allowed to make use of the action which conjecturally
might result from the current grammar line being parsed. (This is called
the "action to be", hence "atb".)
</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Object Tree. </b>The I6 object tree contains <code class="display"><span class="extract">Class</span></code> definitions as well as objects, but
we precede both with a pseudo-object called <code class="display"><span class="extract">property_numberspace_forcer</span></code>.
It does nothing except to ensure that properties are declared in I6 in the
same sequence as I7 (which need not otherwise happen); it plays no part
in play, and is not a valid I7 "object" value.
</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Tables. </b>The initial state of the I6 arrays corresponding to each I7 table: see
"Tables.i6t" for details.
</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Equations. </b>Routines to evaluate from equations.
</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. Actions. </b></p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Phrases. </b>The following innocent-looking commands tell Inform to compile I6 definitions
for all of the rules which are not I6-written primitives, and also for
adjective definitions, so it results in a fairly enormous cataract of code.
</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Rulebooks. </b>The literally hundreds of rulebooks are set up here. (In the end a rulebook
is only a (word) array of rule addresses, terminated with a <code class="display"><span class="extract">NULL</span></code>.)
</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Scenes. </b></p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. The New Library. </b>The gleaming, aluminium and glass extension to the library: almost all of it
material new in I7 usage.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Parsing Tokens. </b>GPRs, scope and noun filters to be used in grammar lines, but no actual
grammar lines as yet.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. Text generation. </b></p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Testing commands. </b></p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. I6 Inclusions. </b>This paragraph contains no code, by default: it's a hook on which to hang
verbatim I6 material.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Entries in constant lists. </b>Well: most of them, anyway. In particular, all of those which are lists of
texts with substitution will be swept up, which is important for timing
reasons. A second round later on will catch any later ones.
</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. To Phrases. </b>We now compile all of the remaining code in the source text: the "To..."
phrases and all of their attendant text routines, loop-over-scope routines
and so on.
</p>
<p class="inwebparagraph">We now have to be quite careful about the sequence of events. Compiling the
text routines is an irrevocable step, after which we must not compile any
new text with substitutions. On the other hand we mustn't leave it any later,
because a text substitution might contain references to the past, or involve
propositions which must be deferred into routines.
</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. Chronology. </b>Similarly, this is where we wrap up all references to past tenses: after this
point, we cannot safely compile any I7 condition in the past tense.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. Grammar. </b>This is the trickiest matter of timing. We had to leave the grammar lines
until now because the past-tense code above might have needed to investigate
whether the player's command matched a given pattern at some time in the
past (a case which arose naturally in one of the example games, so which
should not be dismissed as an aberration). This is therefore the earliest
point at which we can know for sure that no further grammar lines are
needed.
</p>
<pre class="display">
<span class="plain">[ </span><span class="identifier">UnknownVerb</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEMPLATE_CONFIGURATION_BITMAP</span><span class="plain"> &amp; </span><span class="identifier">NO_VERB_VERB_DEFINED_TCBIT</span><span class="plain">) {</span>
<span class="identifier">verb_wordnum</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="character">'no.verb'</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
<span class="plain">[ </span><span class="identifier">PrintVerb</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEMPLATE_CONFIGURATION_BITMAP</span><span class="plain"> &amp; </span><span class="identifier">NO_VERB_VERB_DEFINED_TCBIT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">v</span><span class="plain"> == </span><span class="character">'no.verb'</span><span class="plain">) { </span><span class="reserved">print</span><span class="plain"> </span><span class="string">"do something to"</span><span class="plain">; </span><span class="reserved">rtrue</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="reserved">rfalse</span><span class="plain">;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. Deferred Propositions. </b>Most conditions, such as "the score is 10", and descriptions, such as
"open doors which are in lighted rooms", are translated by Inform into
propositions in a form of predicate calculus. Sometimes these can be
compiled immediately to I6 code, but other times they involve complicated
searches and have to be "deferred" into special routines which will
perform them. This is where we compile those routines.
</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. Miscellaneous Loose Ends. </b>And we still aren't done, because we still have:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) Routines which switch between possible interpretations of phrases
by performing run-time type checking. (Note that these cannot involve
grammar, or the past tenses, or text substitutions, or deferred propositions.)
</li></ul>
<ul class="items"><li>(2) Arrays holding constant lists, such as <code class="display"><span class="extract">{2, 3, 4}</span></code>, if any.
</li></ul>
<ul class="items"><li>(3) The string constants, named in the pattern <code class="display"><span class="extract">SC_*</span></code>, in alphabetical order.
(This ensures that their packed addresses will have unsigned comparison
ordering equivalent to alphabetical order.)
</li></ul>
<ul class="items"><li>(4) "Stub" I6 constants for property names where properties aren't used,
to prevent them causing errors if they are referred to in code but not
actually present in any object (as can easily happen with extensions
presenting optional features which the user chooses not to employ).
</li></ul>
<ul class="items"><li>(5) Counters are used to allocate cells of storage to inline phrases which
need a permanent state associated with them: see the Standard Rules. Since
all I7 source text has been compiled by now, we know the final values of
the counters, and therefore the amount of storage we need to allocate.
</li></ul>
<ul class="items"><li>(6) Similarly, each "quotation" box needs its own cell of memory.
</li></ul>
<pre class="display">
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">Runtime_Quotations_Displayed</span><span class="plain"> --&gt; </span><span class="identifier">CCOUNT_QUOTATIONS</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. Block Values. </b>These are values which are pointers to more elaborate data on the memory heap,
rather than values in themselves: they point to "blocks". A section of code
handles the heap, and there is then one further section to support each of
the kinds of value in question.
</p>
<pre class="display">
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Sections.)</i></li><li><a href="S-gll.html">Continue with 'Glulx Template'</a></li></ul><hr class="tocbar">
<!--End of weave-->
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script type="text/javascript">
(function() {
(function($) {
return $.bigfoot = function(options) {
var addBreakpoint, baseFontSize, bigfoot, buttonHover, calculatePixelDimension, cleanFootnoteLinks, clickButton, createPopover, defaults, deleteEmptyOrHR, escapeKeypress, footnoteInit, getSetting, makeDefaultCallbacks, popoverStates, positionTooltip, removeBackLinks, removeBreakpoint, removePopovers, replaceWithReferenceAttributes, repositionFeet, roomCalc, settings, touchClick, unhoverFeet, updateSetting, viewportDetails;
bigfoot = void 0;
defaults = {
actionOriginalFN: "hide",
activateCallback: function() {},
activateOnHover: false,
allowMultipleFN: false,
anchorPattern: /(fn|footnote|note)[:\-_\d]/gi,
anchorParentTagname: 'sup',
breakpoints: {},
deleteOnUnhover: false,
footnoteParentClass: 'footnote',
footnoteTagname: 'li',
hoverDelay: 250,
numberResetSelector: void 0,
popoverDeleteDelay: 300,
popoverCreateDelay: 100,
positionContent: true,
preventPageScroll: true,
scope: false,
useFootnoteOnlyOnce: true,
contentMarkup: "<aside class=\"bigfoot-footnote is-positioned-bottom\" data-footnote-number=\"{{FOOTNOTENUM}}\" data-footnote-identifier=\"{{FOOTNOTEID}}\" alt=\"Footnote {{FOOTNOTENUM}}\"> <div class=\"bigfoot-footnote__wrapper\"> <div class=\"bigfoot-footnote__content\"> {{FOOTNOTECONTENT}} </div></div> <div class=\"bigfoot-footnote__tooltip\"></div> </aside>",
buttonMarkup: "<div class='bigfoot-footnote__container'> <button class=\"bigfoot-footnote__button\" id=\"{{SUP:data-footnote-backlink-ref}}\" data-footnote-number=\"{{FOOTNOTENUM}}\" data-footnote-identifier=\"{{FOOTNOTEID}}\" alt=\"See Footnote {{FOOTNOTENUM}}\" rel=\"footnote\" data-bigfoot-footnote=\"{{FOOTNOTECONTENT}}\"> <svg class=\"bigfoot-footnote__button__circle\" viewbox=\"0 0 6 6\" preserveAspectRatio=\"xMinYMin\"><circle r=\"3\" cx=\"3\" cy=\"3\" fill=\"white\"></circle></svg> <svg class=\"bigfoot-footnote__button__circle\" viewbox=\"0 0 6 6\" preserveAspectRatio=\"xMinYMin\"><circle r=\"3\" cx=\"3\" cy=\"3\" fill=\"white\"></circle></svg> <svg class=\"bigfoot-footnote__button__circle\" viewbox=\"0 0 6 6\" preserveAspectRatio=\"xMinYMin\"><circle r=\"3\" cx=\"3\" cy=\"3\" fill=\"white\"></circle></svg> </button></div>"
};
settings = $.extend(defaults, options);
popoverStates = {};
footnoteInit = function() {
var $curResetElement, $currentLastFootnoteLink, $footnoteAnchors, $footnoteButton, $lastResetElement, $parent, $relevantFNLink, $relevantFootnote, finalFNLinks, footnoteButton, footnoteButtonSearchQuery, footnoteContent, footnoteIDNum, footnoteLinks, footnoteNum, footnotes, i, _i, _ref, _results;
footnoteButtonSearchQuery = settings.scope ? "" + settings.scope + " a[href*=\"#\"]" : "a[href*=\"#\"]";
$footnoteAnchors = $(footnoteButtonSearchQuery).filter(function() {
var $this, relAttr;
$this = $(this);
relAttr = $this.attr("rel");
if (relAttr === "null" || (relAttr == null)) {
relAttr = "";
}
return ("" + ($this.attr("href")) + relAttr).match(settings.anchorPattern) && $this.closest("[class*=" + settings.footnoteParentClass + "]:not(a):not(" + settings.anchorParentTagname + ")").length < 1;
});
footnotes = [];
footnoteLinks = [];
finalFNLinks = [];
cleanFootnoteLinks($footnoteAnchors, footnoteLinks);
$(footnoteLinks).each(function() {
var $closestFootnoteEl, relatedFN;
relatedFN = $(this).data("footnote-ref").replace(/[:.+~*\]\[]/g, "\\$&");
if (settings.useFootnoteOnlyOnce) {
relatedFN = "" + relatedFN + ":not(.footnote-processed)";
}
$closestFootnoteEl = $(relatedFN).closest(settings.footnoteTagname);
if ($closestFootnoteEl.length > 0) {
footnotes.push($closestFootnoteEl.first().addClass("footnote-processed"));
return finalFNLinks.push(this);
}
});
$currentLastFootnoteLink = $("[data-footnote-identifier]:last");
footnoteIDNum = $currentLastFootnoteLink.length < 1 ? 0 : +$currentLastFootnoteLink.data("footnote-identifier");
_results = [];
for (i = _i = 0, _ref = footnotes.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
footnoteContent = removeBackLinks($(footnotes[i]).html().trim(), $(finalFNLinks[i]).data("footnote-backlink-ref"));
footnoteContent = footnoteContent.replace(/"/g, "&quot;").replace(/&lt;/g, "&ltsym;").replace(/&gt;/g, "&gtsym;");
footnoteIDNum += 1;
footnoteButton = "";
$relevantFNLink = $(finalFNLinks[i]);
$relevantFootnote = $(footnotes[i]);
if (settings.numberResetSelector != null) {
$curResetElement = $relevantFNLink.closest(settings.numberResetSelector);
if ($curResetElement.is($lastResetElement)) {
footnoteNum += 1;
} else {
footnoteNum = 1;
}
$lastResetElement = $curResetElement;
} else {
footnoteNum = footnoteIDNum;
}
if (footnoteContent.indexOf("<") !== 0) {
footnoteContent = "<p>" + footnoteContent + "</p>";
}
footnoteButton = settings.buttonMarkup.replace(/\{\{FOOTNOTENUM\}\}/g, footnoteNum).replace(/\{\{FOOTNOTEID\}\}/g, footnoteIDNum).replace(/\{\{FOOTNOTECONTENT\}\}/g, footnoteContent);
footnoteButton = replaceWithReferenceAttributes(footnoteButton, "SUP", $relevantFNLink);
footnoteButton = replaceWithReferenceAttributes(footnoteButton, "FN", $relevantFootnote);
$footnoteButton = $(footnoteButton).insertBefore($relevantFNLink);
$parent = $relevantFootnote.parent();
switch (settings.actionOriginalFN.toLowerCase()) {
case "hide":
$relevantFNLink.addClass("footnote-print-only");
$relevantFootnote.addClass("footnote-print-only");
_results.push(deleteEmptyOrHR($parent));
break;
case "delete":
$relevantFNLink.remove();
$relevantFootnote.remove();
_results.push(deleteEmptyOrHR($parent));
break;
default:
_results.push($relevantFNLink.addClass("footnote-print-only"));
}
}
return _results;
};
cleanFootnoteLinks = function($footnoteAnchors, footnoteLinks) {
var $parent, $supChild, linkHREF, linkID;
if (footnoteLinks == null) {
footnoteLinks = [];
}
$parent = void 0;
$supChild = void 0;
linkHREF = void 0;
linkID = void 0;
$footnoteAnchors.each(function() {
var $child, $this;
$this = $(this);
linkHREF = "#" + ($this.attr("href")).split("#")[1];
$parent = $this.closest(settings.anchorParentTagname);
$child = $this.find(settings.anchorParentTagname);
if ($parent.length > 0) {
linkID = ($parent.attr("id") || "") + ($this.attr("id") || "");
return footnoteLinks.push($parent.attr({
"data-footnote-backlink-ref": linkID,
"data-footnote-ref": linkHREF
}));
} else if ($child.length > 0) {
linkID = ($child.attr("id") || "") + ($this.attr("id") || "");
return footnoteLinks.push($this.attr({
"data-footnote-backlink-ref": linkID,
"data-footnote-ref": linkHREF
}));
} else {
linkID = $this.attr("id") || "";
return footnoteLinks.push($this.attr({
"data-footnote-backlink-ref": linkID,
"data-footnote-ref": linkHREF
}));
}
});
};
deleteEmptyOrHR = function($el) {
var $parent;
$parent = void 0;
if ($el.is(":empty") || $el.children(":not(.footnote-print-only)").length === 0) {
$parent = $el.parent();
if (settings.actionOriginalFN.toLowerCase() === "delete") {
$el.remove();
} else {
$el.addClass("footnote-print-only");
}
return deleteEmptyOrHR($parent);
} else if ($el.children(":not(.footnote-print-only)").length === $el.children("hr:not(.footnote-print-only)").length) {
$parent = $el.parent();
if (settings.actionOriginalFN.toLowerCase() === "delete") {
$el.remove();
} else {
$el.children("hr").addClass("footnote-print-only");
$el.addClass("footnote-print-only");
}
return deleteEmptyOrHR($parent);
}
};
removeBackLinks = function(footnoteHTML, backlinkID) {
var regex;
if (backlinkID.indexOf(' ') >= 0) {
backlinkID = backlinkID.trim().replace(/\s+/g, "|").replace(/(.*)/g, "($1)");
}
regex = new RegExp("(\\s|&nbsp;)*<\\s*a[^#<]*#" + backlinkID + "[^>]*>(.*?)<\\s*/\\s*a>", "g");
return footnoteHTML.replace(regex, "").replace("[]", "");
};
replaceWithReferenceAttributes = function(string, referenceKeyword, $referenceElement) {
var refMatches, refRegex, refReplaceRegex, refReplaceText;
refRegex = new RegExp("\\{\\{" + referenceKeyword + ":([^\\}]*)\\}\\}", "g");
refMatches = void 0;
refReplaceText = void 0;
refReplaceRegex = void 0;
refMatches = refRegex.exec(string);
while (refMatches) {
if (refMatches[1]) {
refReplaceText = $referenceElement.attr(refMatches[1]) || "";
string = string.replace("{{" + referenceKeyword + ":" + refMatches[1] + "}}", refReplaceText);
}
refMatches = refRegex.exec(string);
}
return string;
};
buttonHover = function(event) {
var $buttonHovered, dataIdentifier, otherPopoverSelector;
if (settings.activateOnHover) {
$buttonHovered = $(event.target).closest(".bigfoot-footnote__button");
dataIdentifier = "[data-footnote-identifier=\"" + ($buttonHovered.attr("data-footnote-identifier")) + "\"]";
if ($buttonHovered.hasClass("is-active")) {
return;
}
$buttonHovered.addClass("is-hover-instantiated");
if (!settings.allowMultipleFN) {
otherPopoverSelector = ".bigfoot-footnote:not(" + dataIdentifier + ")";
removePopovers(otherPopoverSelector);
}
createPopover(".bigfoot-footnote__button" + dataIdentifier).addClass("is-hover-instantiated");
}
};
touchClick = function(event) {
var $nearButton, $nearFootnote, $target;
$target = $(event.target);
$nearButton = $target.closest(".bigfoot-footnote__button");
$nearFootnote = $target.closest(".bigfoot-footnote");
if ($nearButton.length > 0) {
event.preventDefault();
clickButton($nearButton);
} else if ($nearFootnote.length < 1) {
if ($(".bigfoot-footnote").length > 0) {
removePopovers();
}
}
};
clickButton = function($button) {
var dataIdentifier;
$button.blur();
dataIdentifier = "data-footnote-identifier=\"" + ($button.attr("data-footnote-identifier")) + "\"";
if ($button.hasClass("changing")) {
return;
} else if (!$button.hasClass("is-active")) {
$button.addClass("changing");
setTimeout((function() {
return $button.removeClass("changing");
}), settings.popoverCreateDelay);
createPopover(".bigfoot-footnote__button[" + dataIdentifier + "]");
$button.addClass("is-click-instantiated");
if (!settings.allowMultipleFN) {
removePopovers(".bigfoot-footnote:not([" + dataIdentifier + "])");
}
} else {
if (!settings.allowMultipleFN) {
removePopovers();
} else {
removePopovers(".bigfoot-footnote[" + dataIdentifier + "]");
}
}
};
createPopover = function(selector) {
var $buttons, $popoversCreated;
$buttons = void 0;
if (typeof selector !== "string" && settings.allowMultipleFN) {
$buttons = selector;
} else if (typeof selector !== "string") {
$buttons = selector.first();
} else if (settings.allowMultipleFN) {
$buttons = $(selector).closest(".bigfoot-footnote__button");
} else {
$buttons = $(selector + ":first").closest(".bigfoot-footnote__button");
}
$popoversCreated = $();
$buttons.each(function() {
var $content, $contentContainer, $this, content;
$this = $(this);
content = void 0;
try {
content = settings.contentMarkup.replace(/\{\{FOOTNOTENUM\}\}/g, $this.attr("data-footnote-number")).replace(/\{\{FOOTNOTEID\}\}/g, $this.attr("data-footnote-identifier")).replace(/\{\{FOOTNOTECONTENT\}\}/g, $this.attr("data-bigfoot-footnote")).replace(/\&gtsym\;/g, "&gt;").replace(/\&ltsym\;/g, "&lt;");
return content = replaceWithReferenceAttributes(content, "BUTTON", $this);
} finally {
$content = $(content);
try {
settings.activateCallback($content, $this);
} catch (_error) {}
$content.insertAfter($buttons);
popoverStates[$this.attr("data-footnote-identifier")] = "init";
$content.attr("bigfoot-max-width", calculatePixelDimension($content.css("max-width"), $content));
$content.css("max-width", 10000);
$contentContainer = $content.find(".bigfoot-footnote__content");
$content.attr("data-bigfoot-max-height", calculatePixelDimension($contentContainer.css("max-height"), $contentContainer));
repositionFeet();
$this.addClass("is-active");
$content.find(".bigfoot-footnote__content").bindScrollHandler();
$popoversCreated = $popoversCreated.add($content);
}
});
setTimeout((function() {
return $popoversCreated.addClass("is-active");
}), settings.popoverCreateDelay);
return $popoversCreated;
};
baseFontSize = function() {
var el, size;
el = document.createElement("div");
el.style.cssText = "display:inline-block;padding:0;line-height:1;position:absolute;visibility:hidden;font-size:1em;";
el.appendChild(document.createElement("M"));
document.body.appendChild(el);
size = el.offsetHeight;
document.body.removeChild(el);
return size;
};
calculatePixelDimension = function(dim, $el) {
if (dim === "none") {
dim = 10000;
} else if (dim.indexOf("rem") >= 0) {
dim = parseFloat(dim) * baseFontSize();
} else if (dim.indexOf("em") >= 0) {
dim = parseFloat(dim) * parseFloat($el.css("font-size"));
} else if (dim.indexOf("px") >= 0) {
dim = parseFloat(dim);
if (dim <= 60) {
dim = dim / parseFloat($el.parent().css("width"));
}
} else if (dim.indexOf("%") >= 0) {
dim = parseFloat(dim) / 100;
}
return dim;
};
$.fn.bindScrollHandler = function() {
if (!settings.preventPageScroll) {
return $(this);
}
$(this).on("DOMMouseScroll mousewheel", function(event) {
var $popover, $this, delta, height, prevent, scrollHeight, scrollTop, up;
$this = $(this);
scrollTop = $this.scrollTop();
scrollHeight = $this[0].scrollHeight;
height = parseInt($this.css("height"));
$popover = $this.closest(".bigfoot-footnote");
if ($this.scrollTop() > 0 && $this.scrollTop() < 10) {
$popover.addClass("is-scrollable");
}
if (!$popover.hasClass("is-scrollable")) {
return;
}
delta = event.type === "DOMMouseScroll" ? event.originalEvent.detail * -40 : event.originalEvent.wheelDelta;
up = delta > 0;
prevent = function() {
event.stopPropagation();
event.preventDefault();
event.returnValue = false;
return false;
};
if (!up && -delta > scrollHeight - height - scrollTop) {
$this.scrollTop(scrollHeight);
$popover.addClass("is-fully-scrolled");
return prevent();
} else if (up && delta > scrollTop) {
$this.scrollTop(0);
$popover.removeClass("is-fully-scrolled");
return prevent();
} else {
return $popover.removeClass("is-fully-scrolled");
}
});
return $(this);
};
unhoverFeet = function(e) {
if (settings.deleteOnUnhover && settings.activateOnHover) {
return setTimeout((function() {
var $target;
$target = $(e.target).closest(".bigfoot-footnote, .bigfoot-footnote__button");
if ($(".bigfoot-footnote__button:hover, .bigfoot-footnote:hover").length < 1) {
return removePopovers();
}
}), settings.hoverDelay);
}
};
escapeKeypress = function(event) {
if (event.keyCode === 27) {
return removePopovers();
}
};
removePopovers = function(footnotes, timeout) {
var $buttonsClosed, $linkedButton, $this, footnoteID;
if (footnotes == null) {
footnotes = ".bigfoot-footnote";
}
if (timeout == null) {
timeout = settings.popoverDeleteDelay;
}
$buttonsClosed = $();
footnoteID = void 0;
$linkedButton = void 0;
$this = void 0;
$(footnotes).each(function() {
$this = $(this);
footnoteID = $this.attr("data-footnote-identifier");
$linkedButton = $(".bigfoot-footnote__button[data-footnote-identifier=\"" + footnoteID + "\"]");
if (!$linkedButton.hasClass("changing")) {
$buttonsClosed = $buttonsClosed.add($linkedButton);
$linkedButton.removeClass("is-active is-hover-instantiated is-click-instantiated").addClass("changing");
$this.removeClass("is-active").addClass("disapearing");
return setTimeout((function() {
$this.remove();
delete popoverStates[footnoteID];
return $linkedButton.removeClass("changing");
}), timeout);
}
});
return $buttonsClosed;
};
repositionFeet = function(e) {
var type;
if (settings.positionContent) {
type = e ? e.type : "resize";
$(".bigfoot-footnote").each(function() {
var $button, $contentWrapper, $mainWrap, $this, dataIdentifier, identifier, lastState, marginSize, maxHeightInCSS, maxHeightOnScreen, maxWidth, maxWidthInCSS, positionOnTop, relativeToWidth, roomLeft, totalHeight;
$this = $(this);
identifier = $this.attr("data-footnote-identifier");
dataIdentifier = "data-footnote-identifier=\"" + identifier + "\"";
$contentWrapper = $this.find(".bigfoot-footnote__content");
$button = $this.siblings(".bigfoot-footnote__button");
roomLeft = roomCalc($button);
marginSize = parseFloat($this.css("margin-top"));
maxHeightInCSS = +($this.attr("data-bigfoot-max-height"));
totalHeight = 2 * marginSize + $this.outerHeight();
maxHeightOnScreen = 10000;
positionOnTop = roomLeft.bottomRoom < totalHeight && roomLeft.topRoom > roomLeft.bottomRoom;
lastState = popoverStates[identifier];
if (positionOnTop) {
if (lastState !== "top") {
popoverStates[identifier] = "top";
$this.addClass("is-positioned-top").removeClass("is-positioned-bottom");
$this.css("transform-origin", (roomLeft.leftRelative * 100) + "% 100%");
}
maxHeightOnScreen = roomLeft.topRoom - marginSize - 15;
} else {
if (lastState !== "bottom" || lastState === "init") {
popoverStates[identifier] = "bottom";
$this.removeClass("is-positioned-top").addClass("is-positioned-bottom");
$this.css("transform-origin", (roomLeft.leftRelative * 100) + "% 0%");
}
maxHeightOnScreen = roomLeft.bottomRoom - marginSize - 15;
}
$this.find(".bigfoot-footnote__content").css({
"max-height": Math.min(maxHeightOnScreen, maxHeightInCSS) + "px"
});
if (type === "resize") {
maxWidthInCSS = parseFloat($this.attr("bigfoot-max-width"));
$mainWrap = $this.find(".bigfoot-footnote__wrapper");
maxWidth = maxWidthInCSS;
if (maxWidthInCSS <= 1) {
relativeToWidth = (function() {
var jq, userSpecifiedRelativeElWidth;
userSpecifiedRelativeElWidth = 10000;
if (settings.maxWidthRelativeTo) {
jq = $(settings.maxWidthRelativeTo);
if (jq.length > 0) {
userSpecifiedRelativeElWidth = jq.outerWidth();
}
}
return Math.min(window.innerWidth, userSpecifiedRelativeElWidth);
})();
maxWidth = relativeToWidth * maxWidthInCSS;
}
maxWidth = Math.min(maxWidth, $this.find(".bigfoot-footnote__content").outerWidth() + 1);
$mainWrap.css("max-width", maxWidth + "px");
$this.css({
left: (-roomLeft.leftRelative * maxWidth + parseFloat($button.css("margin-left")) + $button.outerWidth() / 2) + "px"
});
positionTooltip($this, roomLeft.leftRelative);
}
if (parseInt($this.outerHeight()) < $this.find(".bigfoot-footnote__content")[0].scrollHeight) {
return $this.addClass("is-scrollable");
}
});
}
};
positionTooltip = function($popover, leftRelative) {
var $tooltip;
if (leftRelative == null) {
leftRelative = 0.5;
}
$tooltip = $popover.find(".bigfoot-footnote__tooltip");
if ($tooltip.length > 0) {
$tooltip.css("left", "" + (leftRelative * 100) + "%");
}
};
roomCalc = function($el) {
var elHeight, elLeftMargin, elWidth, leftRoom, topRoom, w;
elLeftMargin = parseFloat($el.css("margin-left"));
elWidth = parseFloat($el.outerWidth()) - elLeftMargin;
elHeight = parseFloat($el.outerHeight());
w = viewportDetails();
topRoom = $el.offset().top - w.scrollY + elHeight / 2;
leftRoom = $el.offset().left - w.scrollX + elWidth / 2;
return {
topRoom: topRoom,
bottomRoom: w.height - topRoom,
leftRoom: leftRoom,
rightRoom: w.width - leftRoom,
leftRelative: leftRoom / w.width,
topRelative: topRoom / w.height
};
};
viewportDetails = function() {
var $window;
$window = $(window);
return {
width: window.innerWidth,
height: window.innerHeight,
scrollX: $window.scrollLeft(),
scrollY: $window.scrollTop()
};
};
addBreakpoint = function(size, trueCallback, falseCallback, deleteDelay, removeOpen) {
var falseDefaultPositionSetting, minMax, mqListener, mql, query, s, trueDefaultPositionSetting;
if (deleteDelay == null) {
deleteDelay = settings.popoverDeleteDelay;
}
if (removeOpen == null) {
removeOpen = true;
}
mql = void 0;
minMax = void 0;
s = void 0;
if (typeof size === "string") {
s = size.toLowerCase() === "iphone" ? "<320px" : size.toLowerCase() === "ipad" ? "<768px" : size;
minMax = s.charAt(0) === ">" ? "min" : s.charAt(0) === "<" ? "max" : null;
query = minMax ? "(" + minMax + "-width: " + (s.substring(1)) + ")" : s;
mql = window.matchMedia(query);
} else {
mql = size;
}
if (mql.media && mql.media === "invalid") {
return {
added: false,
mq: mql,
listener: null
};
}
trueDefaultPositionSetting = minMax === "min";
falseDefaultPositionSetting = minMax === "max";
trueCallback = trueCallback || makeDefaultCallbacks(removeOpen, deleteDelay, trueDefaultPositionSetting, function($popover) {
return $popover.addClass("is-bottom-fixed");
});
falseCallback = falseCallback || makeDefaultCallbacks(removeOpen, deleteDelay, falseDefaultPositionSetting, function() {});
mqListener = function(mq) {
if (mq.matches) {
trueCallback(removeOpen, bigfoot);
} else {
falseCallback(removeOpen, bigfoot);
}
};
mql.addListener(mqListener);
mqListener(mql);
settings.breakpoints[size] = {
added: true,
mq: mql,
listener: mqListener
};
return settings.breakpoints[size];
};
makeDefaultCallbacks = function(removeOpen, deleteDelay, position, callback) {
return function(removeOpen, bigfoot) {
var $closedPopovers;
$closedPopovers = void 0;
if (removeOpen) {
$closedPopovers = bigfoot.close();
bigfoot.updateSetting("activateCallback", callback);
}
return setTimeout((function() {
bigfoot.updateSetting("positionContent", position);
if (removeOpen) {
return bigfoot.activate($closedPopovers);
}
}), deleteDelay);
};
};
removeBreakpoint = function(target, callback) {
var b, breakpoint, mq, mqFound;
mq = null;
b = void 0;
mqFound = false;
if (typeof target === "string") {
mqFound = settings.breakpoints[target] !== undefined;
} else {
for (b in settings.breakpoints) {
if (settings.breakpoints.hasOwnProperty(b) && settings.breakpoints[b].mq === target) {
mqFound = true;
}
}
}
if (mqFound) {
breakpoint = settings.breakpoints[b || target];
if (callback) {
callback({
matches: false
});
} else {
breakpoint.listener({
matches: false
});
}
breakpoint.mq.removeListener(breakpoint.listener);
delete settings.breakpoints[b || target];
}
return mqFound;
};
updateSetting = function(newSettings, value) {
var oldValue, prop;
oldValue = void 0;
if (typeof newSettings === "string") {
oldValue = settings[newSettings];
settings[newSettings] = value;
} else {
oldValue = {};
for (prop in newSettings) {
if (newSettings.hasOwnProperty(prop)) {
oldValue[prop] = settings[prop];
settings[prop] = newSettings[prop];
}
}
}
return oldValue;
};
getSetting = function(setting) {
return settings[setting];
};
$(document).ready(function() {
footnoteInit();
$(document).on("mouseenter", ".bigfoot-footnote__button", buttonHover);
$(document).on("touchend click", touchClick);
$(document).on("mouseout", ".is-hover-instantiated", unhoverFeet);
$(document).on("keyup", escapeKeypress);
$(window).on("scroll resize", repositionFeet);
return $(document).on("gestureend", function() {
return repositionFeet();
});
});
bigfoot = {
removePopovers: removePopovers,
close: removePopovers,
createPopover: createPopover,
activate: createPopover,
repositionFeet: repositionFeet,
reposition: repositionFeet,
addBreakpoint: addBreakpoint,
removeBreakpoint: removeBreakpoint,
getSetting: getSetting,
updateSetting: updateSetting
};
return bigfoot;
};
})(jQuery);
}).call(this);
</script>
<script type="text/javascript">
$.bigfoot();
</script>
<link href="Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
</main>
</body>
</html>