SITE UNDER CONSTRUCTION

(*) feature not implemented


Home


Manuals

Operator's
        manual(*)

Egg
        language

Hyperstring
        library


Source Code

eggBuilder
        source

Hyperstring
        source

Download
        all source(*)


Other

Open-source
        license

Purchase
        binary(*)

Contact

Life's too short. Start with an egg.

Egg Language

/home/


The Egg Language



The purpose

The purpose of the Egg language is to assist in modular, object-oriented method of creating complex documents. It allows both textual elements and formatting elements stored like objects once and then repeated as needed in multiple parts of the document. The Egg language is wholly independent of the nature of the document. Books, websites, computer software can all benefit from its universal capabilities. I’ll give a few examples:

A book author might prefer to keep certain episodes, descriptions, or names of locales and the book characters defined elsewhere. In the main document of the book he will refer to them by a variable name. It may by an uncommon way to write a novel, but in technical or scientific writing references to quoted material, or passages yet unwritten, are numerous. The technical writer often needs to make references outside of the main text such as indexes, library references, and notes. Those need to be abstracted away from the numbering system of pages and notes, which can only be built once the book is complete. If you ever wrote an article, let alone a lengthy book, that uses numbered notes, you know how much labor is involved in inserting a new note and renumbering all the subsequent ones, both in the main text and in the notes chapter. Similarly, if the chapter names include numbers, these are very hard to maintain by hand when the chapters are moved around. The book author will use Egg language to refer to various moving parts in his book by name so that he can concentrate on creating content.

An Internet publisher of the same book will need to immerse the document which is the book into a framework of paging software, table of content page, furnish the page numbers to footnotes and indexes, and possibly insert advertising insets. The publisher will use Egg language to define the collection of hypertext links, boilerplate content and decorations that constitute the book reader software.

A web designer has to deal with complex and hierarchical HTML and Javascript elements that constitute a website. It is a good approach to define the overall structure of the page: the logo, the menu, the title, the content, the insets, the sidebar, the page header and footer in general terms and refer to them by name only in order to define the general layout. Then each such element can be defined in terms of its components. For example, the menu is a single entity in the general layout, but is itself composed of sections, and the sections – of menu items. The top-down design is commonplace in software development, but in creation of online content one has to combine PHP and Javascript code, straight HTML, cascading style sheets, and server-side includes into a single whole. The Egg language is the unifying methodology that allows to bring object-oriented, technology-independent thinking into website design. It also can replace narrow-purpose technologies such as cascading style sheets and server-side includes. The designer can think in terms of functional elements: logo, menu, content, links, etc., rather than in technological terms of how they are to be implemented.

A computer programmer typically can take advantage of the powerful text organization apparatus of the programming language that he uses. In C or similar languages, for example, there are ways to aggregate variables, encapsulate algorithms in functions, and insert files into the master file by name. However, not every language has similar features. A programmer proficient in Egg might choose to use it as a pre-processor for his software either because the native programming language lacks the organizational features or because he finds the Egg language easier to use with everything he does. One area where Egg would be useful is inserting decorative commenting patterns that some organizations require before certain units of code.

The text that contains elements of the Egg language will be called “Egg book” or simply “book”. When, in this manual, I use the word “book” in its everyday sense I will qualify it, for example, as “natural-language book” or use words such as “document”, or “file”.

All Egg books are in Unicode with UTF-8 encoding preferred.





Egg expressions

An Egg expression (or simply an “egg”) is any text enclosed in “Egg braces”. The default Egg braces are the “curly” braces. So, this is an Egg expression: {x}.

The braces are rarely used in natural-language books, but they are common in computer languages. Later I will explain how to distinguish braces used for Egg variables from any other use. However, if your book is using plenty of braces (for example, because it has C/C++/C# code inside) I recommend to instead redefine the Egg braces as some other pair of Unicode characters or short code words. The eggBuilder application has a function to replace the canonical braces with any symbol you might want. For most people, I think, double braces will work fine: {{x}}. You might consider this pair of characters

«, » (Unicode 00AB, 00BB)

if you have a convenient way to input them.

The Egg expressions can be two kinds: variables and instructions. A variable is something that ultimately is bound to a value. A variable is resolved when it is replaced with that value everywhere in the book. For example, this is a short Egg book:

Someone, quickly, get {x}! – {y} cried. We need to find {x}, before it’s too late!

If, somehow, eggBuilder knows that {x} has value “John” and {y} has value “Elsa”, then our book evaluates as:

Someone, quickly, get John! – Elsa cried. We need to find John, before it’s too late!

The Egg instruction causes eggBuilder to process the book in a certain way. For example, the instruction

{page}

causes a page break to be inserted. You cannot name a variable “page” because there is an instruction with that name. EggBuilder processes this instruction by saving the output file that is its current output file, and open another file with a different page number embedded in the file name. It also increments the current page number.

Another instruction is

{npage}

This, as you might guess, is resolved as the current page number.

There are quite a few instructions, many have complex syntax. This composite instruction, for example, is a three-way conditional block that depends on two variables:

{if: {x}}

John is found in “Bull And Claw”, sound asleep on a bench behind the corner table.

{else if: {y}}

John cannot be found anywhere.

{else}

His name is not John!

{end if}



The eggBuilder application is all about resolving the Egg variables and acting on Egg expressions. The general principle is that everything inside the Egg braces is subject to eggBuilder evaluation of one kind or another; everything outside of the Egg braces is free text that is left unchanged. This is similar to how HTML or other markup languages work.

Let us return to the study of Egg instructions after we study Egg variables.





Variables

To resolve a variable is to find its value. There are several ways to resolve a variable:

  1. The Egg author provides an “equate file” supplementing his book. For example, if his book is in file “book.egg”, the equate file for it should be named “book.init.eq”. The format of the equate file is simple: each equate is an expression of the type

name = value

appearing on its own line. For example, to resolve the example from the previous chapter, the equate file should contain the following two lines:

x = John

y = Elsa



This is not all there is to know about equate files: they can define not individual variables but also arrays and tables. Those will be discussed later.



  1. If a variable is an expression containing other variables, it is resolved after the constituent variables get resolved. For example,



{either {x} or {y}}

resolves as

either John or Peter

, provided that {x} resolves as “John” and {y} resolves as “Peter”.

  1. A variable may be bound by a set expression. For example,

{set: species = dog; epithet = beautiful }

Concerning {species}, they are {epithet} animals.

{end set}

The two eggs evaluate to “dog” and “beautiful” inside the {set…} b- {end set} block. Outside of it they may have values assigned by some other method, or unassigned at all.

  1. A variable may be bound by a loop expression. We shall discuss loops in detail later, but this is an example of a loop-bound variable:



{for x in: 1 to: 10 by: 2}

loop {x};

{end for}

The variable {x} will take value dictated by the loop instruction, and the book will evaluate to

loop 1; loop 3; loop 5; loop 7; loop 9;

  1. Finally, eggBuilder may be unable to evaluate a variable by any of the above methods. Its last resort is simply to ask the author. EggBuilder will build a dialog listing all the unresolved variables in the book, with an input field for each variable. Since the user may define variables in terms of other variables, themselves unresolved, this process may become iterative.



As case 2 implies, variables can nest in other variables. For example, consider this book:

Trust me, this { epithet { color } { model } } has very good gas mileage.

Let us assume there is no equate file for it. What would eggBuilder do with it? We have eggs { color } and {model } inside an outer egg. Eggbuilder must resolve the innermost egg first. So eggBuilder will ask you to define { color } and {model }. It will not ask you to define { epithet { color } { model } } at the same time, because that is a complex variable. Let’s say, you answer

color = red

model = Ford

Now eggBuilder knows what to ask next. It asks, what is { epithet red Ford }? Eggbuilder evaluated the complex outer variable into a simple variable, and now it needs to evaluate the simple variable. When you answer, for example,

epithet red Ford = gorgeous 2012 red Mustang

the book becomes fully evaluated as

Trust me, this gorgeous 2012 red Mustang has very good gas mileage.

But of course you could have given any other answer, canceling all mentioning of the {color} and {model}. The inner variable was merely a way to evaluate the outer variable. Nonsensically, the second answer could have been

epithet red Ford = pogo stick

and you would have ended up with

Trust me, this pogo stick has very good gas mileage.

There is yet another scenario. Instead of reducing nested eggs, we increase nestedness. Instead of answering

epithet red Ford = gorgeous 2012 red Mustang

we could answer

epithet red Ford = gorgeous {year} red Mustang

Now eggBuilder has one more variable to evaluate: {year}. So we’ve opened another round of questions before the book is ready. This can be done for amusement: as several people take turn answering, when the book is eventually evaluated in full, a surprising text might emerge!

The variables are kept on the stack, that is, on an internal data structure correlating variable names with values. There are several ways to nest one book or a book segment inside another; when such nesting occurs, the nested variables are put on top of the existing stack, and when the nested evaluation is complete, the stack is popped so that the nested variables become undefined. For example, case 3 describes a nested loop body. Variable {x} is used inside the loop, where it takes values 1, 3, etc. But what if outside of the loop there was also a variable named {x}? No problem: the “outer” {x} will evaluate outside of the loop, and independently of it, the loop variable will be assigned values by the loop control. The “outer” {x} will be inaccessible inside the loop. But once the loop has been evaluated the “outer” {x} will be, so to say, remembered. That is because variables are evaluated starting with the top of the stack; inside the loop the stack is taller and the top layer contains the value of the loop variable {x}. Once the loop is done and the stack is popped, its top layer is gone and a reference to {x} outside of the loop will be evaluated (or fail to evaluate) with the shortened stack.

A reader familiar with computer languages will recognize this scheme as “scoping” of variables.





Instructions

There is a finite list of keywords used to form instructions. They are case-sensitive. An instruction may have parameters: for example, we have seen a loop instruction with a “from”, “to” and “step” keywords with corresponding values. Some instructions evaluate into a text value to replace the instruction egg. Other instructions cause complex patterns to be inserted in the book (like in the loop example). Parameters are separated from the keyword by an equal sign, and parameters can be listed using comma signs. Space is optional with all punctuation. What follows is a list of instructions, or rather instruction groups, in the order of increasing complexity.



Paging instructions

{page} or {page = N}, where N is any integer.

Directs the eggBuilder to begin a new page. If the N parameter is present, the new page has the indicated number. By default page numbers are 1-based and increase by 1. Paging is implemented by generating several output files, each for a single page. The file names are built upon the same file name stem as the book name, and have the page number embedded in them. Situations when paging is nested are described in a separate chapter. See example at the end of this instruction group.

{npage}

Evaluates as the current page number.

For example, the following book, named “flat_pages.egg”:

page A is {npage}{page}page B is {npage}{page}page C is {npage}

Produces three output files, “flat_pages_0.html”, “flat_pages_1.html”, “flat_pages_2.html”. Their contents are, respectively,

page A is 1

page B is 2

page C is 3



Chapter instructions

{chap} or {chap = N}, where N is any integer.

Directs the eggBuilder to begin a new chapter. If the N parameter is present, the new chapter has the indicated number. The paragraph counter is reset. By default chapter numbers are 1-based. The instruction updates the internal chapter and paragraph counters but has no direct effect on the output.

{nchap}

Evaluates as the current chapter number.

Paragraph instructions

{para} or {para = N}, where N is any integer.

Directs the eggBuilder to begin a new paragraph. If the N parameter is present, the new paragraph has the indicated number. By default paragraph numbers are 1-based. The instruction updates the internal paragraph counter but has no direct effect on the output.

{npara}

Evaluates as the current paragraph number.

{pagecount}

Evaluates to the number of pages in the output.







File instruction

{file = <filename> }, where <filename> is absolute or relative to the project folder name of an Egg book.

This evaluates to the content of the indicated book. EggBuilder will search for an equate file for the book (see back in Variables chapter, case 1). For example if the instruction is {file = include1.egg}, EggBuilder will search for “include1.init.eq” in the same folder. If there is no equate file, the book in the file instruction is evaluated based on the variables already bound to values at that point. If there is an equate file, then its equates are added to the stack for the duration of the evaluation of the file, and then they are popped off the stack.

This is a powerful tool because the file instruction allows us to define independent modules of a book. An author could, for example, start with the following book plan:

{ title }

{ file = foreword.egg }

{ file = introduce_characters.egg }

{ file = {hero}_is_in_love.egg }

{ file = scene_at_the_pond.egg }

{ file = jealousy_and_despair.egg }

{ file = happy_end.egg }

{ file = epilogue.egg }



Now, { title } and { hero } could be filled in the master book’s equate file, something like:

title = Tryst On the Pond

hero = Amoroso


The author can concentrate on creating the 7 files for each chapter. Each chapter will have independent set of its own variables, and it can share the globally defined { title } and { hero } values. Note that variables can be used to evaluate the file names.





Links to pages

{lnkthis =TEXT}

Evaluates to an HTML link (anchor tag) to the page in which it appears. TEXT in all these instructions is the name of the link. For example, if this page outputs as “book_123.html”, the tag will evaluate to <a href=“book_123.html”>TEXT</a>

{lnknext =TEXT}

Evaluates to an HTML link (anchor tag) to the page next following the page in which it appears. If there is no such page, evaluates to whitespace.

{lnkprev =TEXT}

Evaluates to an HTML link (anchor tag) to the page previous to the page in which it appears. If there is no such page, evaluates to whitespace.

{lnkn=N; TEXT}

Evaluates to an HTML link (anchor tag) to the page number N (pages are zero-based internally). If there is no such page, evaluates to whitespace.

{pagecount}

Evaluates to the number of pages in the book.

{pagelast}

Evaluates to the number of the last page in the book. To get to the first page, use {lnkn=0;TEXT}; to get to the last page, use {lnkn={pagelast};TEXT}.



Expressions

Expressions are combination of mutually connected control eggs. An expression has an open and close control eggs. The open egg usually has control parameters separated from the keyword by a colon.

Expressions have associated scopes. A scope is the section of the book where a variable may be defined. If a variable is defined in an expression scope, it is defined inside the scope and undefined outside of it. Expressions, and therefore scopes can be nested. Examples are in the chapter about { set }, but the same scoping rules apply to all expressions.

Simple Blocks

{ block }

<block body>

{ end block }

Blocks can be named:

{ block: <name> }

<block body>

{ end block }

If a block is named, its name is quoted as the block's context.

Blocks are simply a way to define variable scope. They cannot be named, but they can be nested.

The { end block } instruction is not necessary; if it is missing, the set block ends when the block in which it is embedded ends, or when the book ends. In other words, instructions { end set }, { end if }, { else if }, { else }, { end for }, and { end forpage } have an implied { end block } in them for every { block } embedded in them.



Conditional expressions

{if: <predicate1>}

<conditional content>

{end if}

First <predicate1> is evaluated. The predicate can be any expression. It is false if it evaluates to whitespace or to “false”, or is an undefined variable; otherwise, the evaluation is true.

If the predicate evaluates to true, the entire block from the {if…} egg to {end if} egg evaluates as <conditional content>. If the predicate evaluates to false, the entire block from the {if…} egg to {end if} egg evaluates to whitespace.

{if: <predicate1>}

<conditional content>

{else}

<default content>

{end if}

Similar to previous, the entire block from the {if…} egg to {end if} egg evaluates as <conditional content> or as <default content>.



{if: <predicate1>}

<content1>

{else if: <predicate2>}

<content2>

[…]

{else}

<default content>

{end if}

This is the most general form: the predicates are evaluated till one evaluating to true is found; the corresponding <contentN> becomes the evaluation of the entire block.

We call the egg expressions {if…}, {else if…}, {else}, and {end if} conditional blocks. The content between the conditional expressions is called conditional bodies. The entire segment starting with {if…} and ending in {end if} is called conditional expression.

A conditional expression has as many scopes as it has blocks. So, a variable defined in the {if} block is not defined in the corresponding { else if } or {else } blocks.

For example, consider the following book:

{if: predicate1}

Roses are red

{else if: predicate{x}}

Violets are blue

{else}

The future is bleak

{end if}



Let us evaluate it using the following equate file:

predicate2=defined

x=2



What do you think the evaluation will be?

Correct, that book evaluates to “Violets are blue”. That is because predicate{x} evaluates to predicate2, and that variable evaluates to something other than “false”. Note that “defined” itself does not appear anywhere in the evaluated book.

Conditional blocks can be nested, just like in procedural programming languages. Either the predicate appearing in the {if:…} or {else if…} eggs, or the body of the condition between conditional egg expressions can themselves incorporate conditions, sets, or loops.





Set expressions

{set: x = v }

{set: x1 = v1; x2 = v2; […]}

{set: x1 = v1; x2 = v2; […]} <set body> {end set}

The variables x, x1, etc. receive the indicated values till the end of the set block. The { end set } instruction is not necessary; if it is missing, the set block ends when the block in which it is embedded ends, or when the book ends. In other words, instructions { end block }, { end if }, { else if }, { else }, { end for }, and { end forpage } have an implied { end set } in them for every { set… } embedded in them.

This is a simple example.

My Book of Fish.


{set: species = carp}


This is what is known about {species}.


{file = large_freshwater_fish.egg}

{set: species = whale}

Regarding, however, {species}, first we need to point out that it is not fish at all!


{file = water_mammal.egg}


The author has two chapters in separate files. Both use the egg {species} as they supply information about a certain class of creatures in general. He wants to pull both into a book, first talking about carps and then about whales.

This is an example of nested scopes.

{ set: x = Anthony }

{x} is near the beginning of the alphabetical list

{block}

{x} derives from Latin “Antonius”

{set: x = Zachary }

{x} is near the end of the alphabetical list

{end set }

{end block}

{x} has a familiar form “Tony”

( end set }

Here the same variable egg {x} evaluated as “Anthony” in the outer scope, and “Zachary” in the inner scope.



Procedure expressions

Procedures, or procs, are expressions that take arguments. Procedures are not evaluated where they are defined, but when they are called. For example, an author has a certain style of placing images in his book. He always places them centered with the maximum width 600. This is accomplished in HTML by this tag:

<center><img src=image.png width=600></center>

The author would like to not repeat the center and width tags all the time. He wants to define an egg variable for them. But here’s a problem: the image file name is different each time. The author needs an egg that takes an argument, or several arguments. In this case, it will take the image file name as an argument. Such egg expressions, that take arguments, are procedures. This is how you define a procedure:

{ proc define: <proc name> }

<proc body>

{ end proc }

(that is a proc without arguments)


{ proc x define: <proc name> }

<proc body>

{ end proc }

(that is a proc with one arguments)


Or for several arguments:

{ proc x, y [,…] define: <proc name> }

<proc body>

{ end proc }



It is only interesting if <proc body> uses argument eggs {x}, etc. Presumably, <proc body> will expand to different value depending on the value of the argument(s). Procedure definition does not evaluate to anything; it is kept by eggBuilder internally till the proc is called.

This is how you call a proc:

{ <proc name> }

(that is a proc without arguments called)

{ <proc name>: x [, y,…] }

(that is a proc with one or more arguments called)

Let us finish with our example:

{ proc x define: image }

<center><img src={x} width=600></center>

{ end proc }


This can be placed anywhere in the file; it is a proc definition. It cannot be placed inside any other block; it is a good practice to place procedures either in the beginning or the end of the book. The procedure is in scope and available for use anywhere in the file where it is defined, or in the file including the file with the definition. So another recommended practice is to put the procedures in a separate file, and include that file in the book that needs them.

Now any time the author want to insert an image in his preferred style, he would call image:

{image: /images/figure1.png}

There are limitations: the procedure names must be a single word and not be among existing eggBuilder keywords. You are allowed to form the proc name dynamically, so long as it does not evaluate to a keyword or undefined proc.



Procedure Blocks

Earlier, we read about simple blocks: those that have a name or are unnamed. Procedure block all all that simple blocks are, but in addition they have two procs associated with them: start proc and finish proc. The syntax for them is

{ block [: <block-name>] [start: <start-proc name> [: x [, y...]]] [finish : <fin-proc name> [: w [, z]]}

<block body>

{ end block }

The { end block } instruction is not necessary, same as for simple blocks

Note that it is not necessary to have both a start proc and a finish proc. The block procs are called, respectively, right before the body of the block and right after. If either block proc has arguments, those need to be defined in the outer scope of the block.



Triple procs

Elaborating on the procedure blocks, we have a triple proc (“trip” for short). A triple proc is a collection of three procs with the same name. They are useful to define tables or lists. Define them like this:

{ head [x, y, …] define: <trip name> }

<header body>

{ end head }

{ item [x, y, …] define: <trip name> }

<item body>

{ end item }

{ foot [x, y, …] define: <trip name> }

<footer body>

{ end foot }



Then use them like this:

{ head <trip name>[: x, y, ...] }

( item <trip name>[: x, y, …] }

( item <trip name>[: x, y, …] }

( item <trip name>[: x, y, …] }

{ foot <trip name>[: x, y, ...] }

An obvious example is

{ head define: address-book }

<h1>Address Book</h1>

<table><th>Name</th><th>Address</th><th>Phone<th><tr>

{ end head }

{ item name, address, phone define: address-book }

<td>{name}</td><td>{address}</td><td>{phone}</td><tr>

{ end item }

{ foot define: address-book }

</table>

{ end foot }



Now a table of phones and addresses can be expressed:

{ head address-book }

{ item address-book: Swanson, 1600 Maple St, 555-123-4567 }

{ item address-book: Jones, 120 Oak St, 555-123-9876 }

{ foot address-book }



References

A reference is a pair of elements in a book that are in an asymmetrical relationship. A reference always has a base and a destination. These are examples:

  • A footnote is a reference. The base here is the place in the body of the text, where an asterisk or a numerical footnote is indicated. That is the footnote's base. The footnote destination is at the bottom of the page. There, a short (usually) text is placed also marked with an asterisk or the same number. There are many ways to style a footnote: use an asterisk or a few asterisks if there are more than one footnote on the same page; use a little alphabet of asterisks, daggers, crosses and other fancy symbols (that is pretty old-fashioned), use regular numbers, or use Roman numbers.

  • Bibliographic citations are references. A detailed bibliography is provided at the end of the book; in the body of the book abbreviated markers into the bibliography are placed. The styles, again, vary. Sometimes another style of numbering is used (so that bibliographical notes not to be confused with footnotes); sometimes the body contains an abbreviated name of the publication and it refers to the full library listing in the bibliography section. The base is the place where the bibliographical resource is mentioned in the body of your book. The destination is the bibliography in the end.

  • Chapter titles are references. The title logically belongs to the beginning of the chapter. But the table of content (either at the beginning of the book or at the end of it) also mentions the title. The base is the beginning of the chapter, and the destination – the table of content.

  • Subject matter indices are references. Often, especially in technical writing, certain key words are placed at the end of the book in the index section. The place where the key word is used in the body of the book is the base, and the index section is the destination.

  • A cross-reference is a place in the text that points to another place in the book. These are common, for example, in so-called “study” editions of the Bible, when a passage from an New Testament would mention a related chapter and verse in the Old Testament, or an episode in one gospel might mention the same episode told also in another gospel. The base would be an abbreviated chapter and verse citation on the margin of the main text. The destination would be a related text in full elsewhere in the book.



    The base is always something that occurs in the natural flow of a book. The destination is placed somewhere else: at the beginning of the book, or at the end, or at the bottom of a page. The following elements are necessary to form a referemce.

    Reference base

    A reference base is an expression placed in the main flow of the book. The reference base (or simply reference) has the following elements:

  • the keyword, 'ref'

  • the text of the reference is mandatory

  • the destination of the reference precedes the colon; if it is omitted, a default destination at the end of the book is inserted by default.

  • The short text placed at base is preceded by the keyword 'short'; if it is omitted, the sequential number of the reference is printed according to the rules for the destination.

    Example:

    France needs another Charlemagne {ref footnote: Also known as Charles the Great, 748 – 814, first king of France} or at least a decent monarch.

This book fragment will appear, possibly, thus:


France needs another Charlemagneiv or at least another decent monarch.


But at the destination 'footnote', this text will appear:


***

(i) <your first footnote on the page>

(ii) <your second footnote on the page>

(iii) <your third footnote on the page>

(iv) Also known as Charles the Great, 748 – 814, first king of France.


But how do we know that destination 'footnote' is at the bottom of the page and not someplace else; how do we know that the footnotes start with a header consisting of a line with centered three asterisks; how do we know that roman numerals should be used? All that is specified at the two definitions, both with the name 'footnote'.

Reference definition

{ ref n[, s] define: <dest name> }

<ref item>

{ end ref }

Note that we are defining the style of the reference at base. For example, since we want the style to be in superscript roman numeral, we would code:

{ ref n define: footnote }

<sub>{roman: {n}}</sub>

{ end ref }

, where n is the number of the reference (maintained automatically), and roman is a built-in proc converting a positive integer to roman.

Generally, an integer variable n is supplied to ref automatically, but the author can add his own variable, such as the s in the above definition. That is known as the “short” reference: a text that might appear at base instead of the number. For example, in bibliographical reference, at base we might see

One researcher {ref bibliography: Niederhoffer} found that

Here Niederhoffer is a bibliographical key that appears at base as-is:

{ ref n, s define: bibliography }

[{s}]

{ end ref }

While the reference number n is still passed to the ref, it is not used.

So the base will look simply:

One researcher [Niederhoffer] found that

The bibliography destination will have items like:

Niederhoffer: Niederhoffer, P.Q. (2007, July 30). Puzzling crystals confound scientists. Washington Post, pp. C3, C15.

Reference insertion at base

Simply,

{ref <dest-name> [:x,...]}

Destination definition

The destination define is always a trip:

{ head <placement> define: <dest name> }

<dest header>

{ end head }



<placement> is mandatory. Placements are

bot, top, left, right; (these can be combined, e.g. bot, right)

chapterend

bookend

custom (this is the placement that requires destination insertion egg)



{ item n [, s] define: <dest name> }

<item>

{ end item }

{ foot define: <dest name> }

<dest footer>

{ end foot }



In our example:

{ head define: footnote }

<center>***</center><P>

{end head }

{ item n [, s] define: footnote }

({roman: { n }})&nbsp; { s } <br>

{ end item }

Foot is not defined in our simple example. A more elaborate design would be to construct an HTML table so that the reference numbers and the reference text are separated by a tab rather by a space; in that case, the footer will be necessary in order to close the HTML table.

Destination insertion at base

{ head <dest-name> }

This is the only destination marker needed; the processor will insert the items and the foot as necessary. Moreover, if the destination already implies location (like all of them but custom; e.g. footnote is always at the bottom of the page), then there is no need to mark a destination at all.

Loop expressions



Loops define a block that is repeated several times (or once, or none at all), depending on the loop control instruction. The general form is

{ for… }

< loop body >

{ end for }



Loops can nest other loops and they can nest sets and conditionals. The definitions below use variable names x, y, etc. for the loop variables, but of course any simple variable can be used as loop variables. If a loop uses a variable already defined outside of the loop, the homonymous loop variable hides the outer variable inside the loop.

There are several variations of the loop controls. First, there are enumerator loops:

{ for x in: v1, v2, v3, […] }

< loop body >

{ end for }


The loop body is evaluated as many times as there are values following “in:”. The loop variable is {x} and it is bound to each value in turn. Of course, it is only interesting if < loop body > uses variable {x}.



Next, we have numerical loops.

{ for x in: <start> to: <finish>[ by: <step> ] }

< loop body >

{ end for }


The loop body is evaluated as the loop variable iterates from <start> to <finish>. The “by: <step>” expression can be omitted, and step = 1 is assumed. Expressions <start>, <finish> and, if present, <step> must evaluate to integers.

Through equate files, the author can create arrays and tables. Let us take a detour and show how this is done.





Detour: Arrays and tables

To create an array, give it a unique name and define its entries in the equate file:

myArray={array}

cat

dog

sparrow

myArray={end array}


As you can see, the array data appears among other equates in a contiguous block that starts with an equate whose name is the name of the array and the value is {array}; the array block ends when the same name is given value {end array}. The values of the array are listed not in an equate form, but simply one value per file line. The above defines an array of three values.

Whenever an array is defined in the equate file in eggBuilder’s scope, the following variables will be defined globally, anywhere the equate file containing the array is in scope:

{<array name>.N} is bound to the values of the array, where N is an integer between 0 and the size of the array less one. For example, { myArray.2 } evaluates to “sparrow” in our example.

{<array name>.size} is bound to the size of the array. In our example, { myArray.size } evaluates to 3.

{<array name>.last} is bound to the last existing index of the array. In our example, { myArray.last } evaluates to 2, and generally, it is the array size less 1.

A table has two dimensions. This is how tables can be created in the equates file:

myTable={table}

country=USA

language=English

country=Germany

language=German

country=Italy

language=Italian

country=Holland

language=Dutch

myTable={end table}


We see a 2 x 3 table defined here. The name of the table is “myTable”. We see two names appearing, “country and “language”. Therefore our table has two columns by these names. The order of columns is determined by the order in which the columns appear. We see that each column is given three values. That is the number of rows in the table.

It is allowed to leave some table cells undefined. They are assumed to have a whitespace value by default. For example, if the author does not know what language they speak in Holland, he could leave that value out. The table will have an empty string for the language spoken in Holland.

Whenever a table is defined in the equate file in eggBuilder’s scope, the following variables will be defined globally, anywhere the equate file containing the table is in scope:

{ <table name>.colcount } is bound to the number of the table’s columns.

{ <table name>.rowcount } is bound to the number of the table’s rows.

{ <table name>.collast } is bound to the number of the table’s columns.

{ <table name>.rowlast } is bound to the number of the table’s rows.

{ <table name>.COL } is bound to the name of the column number COL (zero-based), for COL ranging from zero to the last defined column. In our example, myTable.0 = country and myTable.1 = language.

{ <table name>.COL.ROW } is bound to the value in column number COL (zero-based) and row number ROW (also zero-based). In our example, myTable.0.1 = Germany and myTable.1.1 = German.





Continuing with loop expressions

Now that an array has been defined through the equates file, an array loop can be written in the book.

{ for x in: <array name> }

< loop body >

{ end for }



Here, <array name> must appear in an array block in the equate file. The following variables will be defined in the loop body:

{x} will be bound to the iterated value in the array. That is, if the array is like in our example, then {x} will be bound to “cat”, then to “dog” and then to “sparrow”.

If a table has been defined, a table loop may be written as follows:

{for x, y in: <table name>}

<loop body>

{end for}



In addition to the global table values, {x} and {y} will be bound to the column number and the row number for each value in the table. Columns are iterated first, so in our example, the data will be grouped by rows: USA, English, Germany, German, etc.

Also the variable {x.y} will be bound to the value in the table (in other words, inside the table loop

<table name>.{x}.{y}

is the same as

{x.y}



Lastly, there is a universal loop control.

{ for x [, y, z…] in: <predicate> }

<loop body>

{ end for }



This is only interesting if the loop variables are used in both <predicate> and the <loop body>.

EggBuilder will go over all equates in its current scope, and see if any values given to the loop variables would allow the predicate to evaluate. The order of output is dictate by the order of the loop variables in the loop control.



For example, suppose the following equates are in scope:



X1 Y2 Z2=def

X0 Y2 Z1=def

X0 Y0 Z1=def



Suppose the universal loop is

{ for x, y, z in: X{x} Y{y} Z{z} }

Z: {z} Y: {y} X: {x}

{ end for }


Observe that the predicate evaluates to “def” for x=1, y=2 and z=2. Therefore, the eggBuilder will bind the loop variables accordingly and evaluate the loop body to:

Z: 2 Y: 2 X: 1

Observe that the predicate also evaluates to non-empty string (it does not matter that it happens to be “def”, any non-blank value would do) for x=0, y=2 and z=1. Therefore, the eggBuilder will bind the loop variables according to this combination and evaluate the loop body to:

Z: 1 Y: 2 X: 0

Finally, there is another combination, x=0, y=0 and z=1. This is the third evaluation of the body:

Z: 1 Y: 0 X: 0

But in what order should eggBuilder iterate? Clearly, eggBuilder should not go by the order of the equates in the file, like we did. Instead, the order of the variables as they appear in the list should determine the order of iterations. Since the variable x is listed first, this is the most significant variable, y is less significant and z is the least significant. Therefore, the proper order is

x

y

z

0

0

1

0

2

1

1

2

2



The output of this loop is

Z: 1 Y: 0 X: 0

Z: 1 Y: 2 X: 0

Z: 2 Y: 2 X: 1





Page loops

Finally, a loop can be organized by page number.

{ forpage x in: <start> to: <finish>[ by: <step> ] }

<pageloop body>

{end forpage}

Pages are numbered internally by zero-based page number. This loop will bind the variable {x} to the page number inside the loop pody.

This is, for example, how a table of content can be organized following a several-page book:

{file = page1}

<center>{npage}</center>

{page}

{file2 = page2}

<center>{npage}</center>

{page}

{file = page 3}

{npage}</center>

{page}

<P>

TABLE OF CONTENT<br>

{forpage p in: 0 to: {pagecount}}

{lnkn={p}; Page {p}}<br>

{end forpage}



This will produce three pages as defined in the three page files. The last page will be a Table of Content



<P>

TABLE OF CONTENT<br>


<a href=flat_pages_with_TOC_0.html>Page 0</a><br>

<a href=flat_pages_with_TOC_1.html>Page 1</a><br>

<a href=flat_pages_with_TOC_2.html>Page 2</a><br>

<a href=flat_pages_with_TOC_3.html>Page 3</a><br>



(“flat_pages_with_TOC” is the project name).

Conclusion

This completes the core Egg language definition. I also plan a set of Egg extensions. The extensions will utilize the linguistic core and provide more targeted functionality. The book publisher extension will offer cross-referencing, foot notes and chapter notes, page numbering options (such as having preface page numbers in Roman numerals, and, of course, page number placement), and a complete online book reader framework.

Other extensions are possible. For example, one day I will produce a general purpose Website generator.

The future looks very bright.





Website material Copyright © Alexey Pismenny, 2014.
eggBuilder software Copyright © Alexey Pismenny, 2002-2014.
All rights reserved.