GAPDoc-1.5.1/0000755000175000017500000000000012174444024011203 5ustar billbillGAPDoc-1.5.1/doc/0000755000175000017500000000000012174444011011744 5ustar billbillGAPDoc-1.5.1/doc/chap3.html0000644000175000017500000027650112026346063013647 0ustar billbill GAP (GAPDoc) - Chapter 3: The Document Type Definition
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

3 The Document Type Definition
 3.1 What is a DTD?
 3.2 Overall Document Structure
 3.3 Sectioning Elements
 3.4 ManSection–a special kind of subsection
 3.5 Cross Referencing and Citations
 3.6 Structural Elements like Lists
 3.7 Types of Text
 3.8 Elements for Mathematical Formulae
 3.9 Everything else

3 The Document Type Definition

In this chapter we first explain what a "document type definition" is and then describe gapdoc.dtd in detail. That file together with the current chapter define how a GAPDoc document has to look like. It can be found in the main directory of the GAPDoc package and it is reproduced in Appendix B.

We do not give many examples in this chapter which is more intended as a formal reference for all GAPDoc elements. Instead we provide an extra document with book name GAPDocExample (also accessible from the GAP online help). This uses all the constructs introduced in this chapter and you can easily compare the source code and how it looks like in the different output formats. Furthermore recall that many basic things about XML markup were already explained by example in the introductory chapter 1.

3.1 What is a DTD?

A document type definition (DTD) is a formal declaration of how an XML document has to be structured. It is itself structured such that programs that handle documents can read it and treat the documents accordingly. There are for example parsers and validity checkers that use the DTD to validate an XML document, see 2.1-14.

The main thing a DTD does is to specify which elements may occur in documents of a certain document type, how they can be nested, and what attributes they can or must have. So, for each element there is a rule.

Note that a DTD can not ensure that a document which is "valid" also makes sense to the converters! It only says something about the formal structure of the document.

For the remaining part of this chapter we have divided the elements of GAPDoc documents into several subsets, each of which will be discussed in one of the next sections.

See the following three subsections to learn by example, how a DTD works. We do not want to be too formal here, but just enable the reader to understand the declarations in gapdoc.dtd. For precise descriptions of the syntax of DTD's see again the official standard in:

  http://www.xml.com/axml/axml.html

3.2 Overall Document Structure

A GAPDoc document contains on its top level exactly one element with name Book. This element is declared in the DTD as follows:

3.2-1 <Book>
<!ELEMENT Book (TitlePage,
                TableOfContents?,
                Body,
                Appendix*,
                Bibliography?,
                TheIndex?)>
<!ATTLIST Book Name CDATA #REQUIRED>

After the keyword ELEMENT and the name Book there is a list in parentheses. This is a comma separated list of names of elements which can occur (in the given order) in the content of a Book element. Each name in such a list can be followed by one of the characters "?", "*" or "+", meaning that the corresponding element can occur zero or one time, an arbitrary number of times, or at least once, respectively. Without such an extra character the corresponding element must occur exactly once. Instead of one name in this list there can also be a list of elements names separated by "|" characters, this denotes any element with one of the names (i.e., "|" means "or").

So, the Book element must contain first a TitlePage element, then an optional TableOfContents element, then a Body element, then zero or more elements of type Appendix, then an optional Bibliography element, and finally an optional element of type TheIndex.

Note that only these elements are allowed in the content of the Book element. No other elements or text is allowed in between. An exception of this is that there may be whitespace between the end tag of one and the start tag of the next element - this should be ignored when the document is processed to some output format. An element like this is called an element with "element content".

The second declaration starts with the keyword ATTLIST and the element name Book. After that there is a triple of whitespace separated parameters (in general an arbitrary number of such triples, one for each allowed attribute name). The first (Name) is the name of an attribute for a Book element. The second (CDATA) is always the same for all of our declarations, it means that the value of the attribute consists of "character data". The third parameter #REQUIRED means that this attribute must be specified with any Book element. Later we will also see optional attributes which are declared as #IMPLIED.

3.2-2 <TitlePage>
<!ELEMENT TitlePage (Title, Subtitle?, Version?, TitleComment?, 
                     Author+, Date?, Address?, Abstract?, Copyright?, 
                     Acknowledgements? , Colophon? )>

Within this element information for the title page is collected. Note that more than one author can be specified. The elements must appear in this order because there is no sensible way to specify in a DTD something like "the following elements may occur in any order but each exactly once".

Before going on with the other elements inside the Book element we explain the elements for the title page.

3.2-3 <Title>
<!ELEMENT Title (%Text;)*>

Here is the last construct you need to understand for reading gapdoc.dtd. The expression "%Text;" is a so-called "parameter entity". It is something like a macro within the DTD. It is defined as follows:

<!ENTITY % Text "%InnerText; | List | Enum | Table">

This means, that every occurrence of "%Text;" in the DTD is replaced by the expression

%InnerText; | List | Enum | Table

which is then expanded further because of the following definition:

<!ENTITY % InnerText "#PCDATA |
                      Alt |
                      Emph | E |
                      Par | P | Br |
                      Keyword | K | Arg | A | Quoted | Q | Code | C | 
                      File | F | Button | B | Package |
                      M | Math | Display | 
                      Example | Listing | Log | Verb |
                      URL | Email | Homepage | Address | Cite | Label | 
                      Ref | Index" > 

These are the only two parameter entities we are using. They expand to lists of element names which are explained in the sequel and the keyword #PCDATA (concatenated with the "or" character "|").

So, the element (Title) is of so-called "mixed content": It can contain parsed character data which does not contain further markup (#PCDATA) or any of the other above mentioned elements. Mixed content must always have the asterisk qualifier (like in Title) such that any sequence of elements (of the above list) and character data can be contained in a Title element.

The %Text; parameter entity is used in all places in the DTD, where "normal text" should be allowed, including lists, enumerations, and tables, but no sectioning elements.

The %InnerText; parameter entity is used in all places in the DTD, where "inner text" should be allowed. This means, that no structures like lists, enumerations, and tables are allowed. This is used for example in headings.

3.2-4 <Subtitle>
<!ELEMENT Subtitle (%Text;)*>

Contains the subtitle of the document.

3.2-5 <Version>
<!ELEMENT Version (#PCDATA|Alt)*>

Note that the version can only contain character data and no further markup elements (except for Alt, which is necessary to resolve the entities described in 2.2-3). The converters will not put the word "Version" in front of the text in this element.

3.2-6 <TitleComment>
<!ELEMENT TitleComment (%Text;)*>

Sometimes a title and subtitle are not sufficient to give a rough idea about the content of a package. In this case use this optional element to specify an additional text for the front page of the book. This text should be short, use the Abstract element (see 3.2-10) for longer explanations.

3.2-7 <Author>
<!ELEMENT Author (%Text;)*>    <!-- There may be more than one Author! -->

As noted in the comment there may be more than one element of this type. This element should contain the name of an author and probably an Email-address and/or WWW-Homepage element for this author, see 3.5-6 and 3.5-7. You can also specify an individual postal address here, instead of using the Address element described below, see 3.2-9.

3.2-8 <Date>
<!ELEMENT Date (#PCDATA)>

Only character data is allowed in this element which gives a date for the document. No automatic formatting is done.

3.2-9 <Address>
<!ELEMENT Address (#PCDATA|Alt|Br)*>

This optional element can be used to specify a postal address of the author or the authors. If there are several authors with different addresses then put the Address elements inside the Author elements.

Use the Br element (see 3.9-3) to mark the line breaks in the usual formatting of the address on a letter.

Note that often it is not necessary to use this element because a postal address is easy to find via a link to a personal web page.

3.2-10 <Abstract>
<!ELEMENT Abstract (%Text;)*>

This element contains an abstract of the whole book.

3.2-11 <Copyright>
<!ELEMENT Copyright (%Text;)*>

This element is used for the copyright notice. Note the &copyright; entity as described in section 2.2-3.

3.2-12 <Acknowledgements>
<!ELEMENT Acknowledgements (%Text;)*>

This element contains the acknowledgements.

3.2-13 <Colophon>
<!ELEMENT Colophon (%Text;)*>

The "colophon" page is used to say something about the history of a document.

3.2-14 <TableOfContents>
<!ELEMENT TableOfContents EMPTY>

This element may occur in the Book element after the TitlePage element. If it is present, a table of contents is generated and inserted into the document. Note that because this element is declared to be EMPTY one can use the abbreviation

<TableOfContents/>

to denote this empty element.

3.2-15 <Bibliography>
<!ELEMENT Bibliography EMPTY>
<!ATTLIST Bibliography Databases CDATA #REQUIRED
                       Style CDATA #IMPLIED>

This element may occur in the Book element after the last Appendix element. If it is present, a bibliography section is generated and inserted into the document. The attribute Databases must be specified, the names of several data files can be specified, separated by commas.

Two kinds of files can be specified in Databases: The first are BibTeX files as defined in [Lam85, Appendix B]. Such files must have a name with extension .bib, and in Databases the name must be given without this extension. The second are files in BibXMLext format as defined in Section 7.2. These files must have an extension .xml and in Databases the full name must be specified.

We suggest to use the BibXMLext format because it allows to produce potentially nicer bibliography entries in text and HTML documents.

A bibliography style may be specified with the Style attribute. The optional Style attribute (for LaTeX output of the document) must also be specified without the .bst extension (the default is alpha). See also section 3.5-3 for a description of the Cite element which is used to include bibliography references into the text.

3.2-16 <TheIndex>
<!ELEMENT TheIndex EMPTY>

This element may occur in the Book element after the Bibliography element. If it is present, an index is generated and inserted into the document. There are elements in GAPDoc which implicitly generate index entries (e.g., Func (3.4-2)) and there is an element Index (3.5-4) for explicitly adding index entries.

3.3 Sectioning Elements

A GAPDoc book is divided into chapters, sections, and subsections. The idea is of course, that a chapter consists of sections, which in turn consist of subsections. However for the sake of flexibility, the rules are not too restrictive. Firstly, text is allowed everywhere in the body of the document (and not only within sections). Secondly, the chapter level may be omitted. The exact rules are described below.

Appendices are a flavor of chapters, occurring after all regular chapters. There is a special type of subsection called "ManSection". This is a subsection devoted to the description of a function, operation or variable. It is analogous to a manpage in the UNIX environment. Usually each function, operation, method, and so on should have its own ManSection.

Cross referencing is done on the level of Subsections, respectively ManSections. The topics in GAP's online help are also pointing to subsections. So, they should not be too long.

We start our description of the sectioning elements "top-down":

3.3-1 <Body>

The Body element marks the main part of the document. It must occur after the TableOfContents element. There is a big difference between inside and outside of this element: Whereas regular text is allowed nearly everywhere in the Body element and its subelements, this is not true for the outside. This has also implications on the handling of whitespace. Outside superfluous whitespace is usually ignored when it occurs between elements. Inside of the Body element whitespace matters because character data is allowed nearly everywhere. Here is the definition in the DTD:

<!ELEMENT Body  ( %Text;| Chapter | Section )*>

The fact that Chapter and Section elements are allowed here leads to the possibility to omit the chapter level entirely in the document. For a description of %Text; see here.

(Remark: The purpose of this element is to make sure that a valid GAPDoc document has a correct overall structure, which is only possible when the top element Book has element content.)

3.3-2 <Chapter>
<!ELEMENT Chapter (%Text;| Heading | Section)*>
<!ATTLIST Chapter Label CDATA #IMPLIED>    <!-- For reference purposes -->

A Chapter element can have a Label attribute, such that this chapter can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the chapter as there is no automatic labelling!

Chapter elements can contain text (for a description of %Text; see here), Section elements, and Heading elements.

The following additional rule cannot be stated in the DTD because we want a Chapter element to have mixed content. There must be exactly one Heading element in the Chapter element, containing the heading of the chapter. Here is its definition:

3.3-3 <Heading>
<!ELEMENT Heading (%InnerText;)*>

This element is used for headings in Chapter, Section, Subsection, and Appendix elements. It may only contain %InnerText; (for a description see here).

Each of the mentioned sectioning elements must contain exactly one direct Heading element (i.e., one which is not contained in another sectioning element).

3.3-4 <Appendix>
<!ELEMENT Appendix (%Text;| Heading | Section)*>
<!ATTLIST Appendix Label CDATA #IMPLIED>   <!-- For reference purposes -->

The Appendix element behaves exactly like a Chapter element (see 3.3-2) except for the position within the document and the numbering. While chapters are counted with numbers (1., 2., 3., ...) the appendices are counted with capital letters (A., B., ...).

Again there is an optional Label attribute used for references.

3.3-5 <Section>
<!ELEMENT Section (%Text;| Heading | Subsection | ManSection)*>
<!ATTLIST Section Label CDATA #IMPLIED>    <!-- For reference purposes -->

A Section element can have a Label attribute, such that this section can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the section as there is no automatic labelling!

Section elements can contain text (for a description of %Text; see here), Heading elements, and subsections.

There must be exactly one direct Heading element in a Section element, containing the heading of the section.

Note that a subsection is either a Subsection element or a ManSection element.

3.3-6 <Subsection>
<!ELEMENT Subsection (%Text;| Heading)*>
<!ATTLIST Subsection Label CDATA #IMPLIED> <!-- For reference purposes -->

The Subsection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the subsection as there is no automatic labelling!

Subsection elements can contain text (for a description of %Text; see here), and Heading elements.

There must be exactly one Heading element in a Subsection element, containing the heading of the subsection.

Another type of subsection is a ManSection, explained now:

3.4 ManSection–a special kind of subsection

ManSections are intended to describe a function, operation, method, variable, or some other technical instance. It is analogous to a manpage in the UNIX environment.

3.4-1 <ManSection>
<!ELEMENT ManSection ( Heading?, 
                      ((Func, Returns?) | (Oper, Returns?) | 
                       (Meth, Returns?) | (Filt, Returns?) | 
                       (Prop, Returns?) | (Attr, Returns?) |
                       Var | Fam | InfoClass)+, Description )>
<!ATTLIST ManSection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT Returns (%Text;)*>
<!ELEMENT Description (%Text;)*>

The ManSection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). But this is probably rarely necessary because the elements Func and so on (explained below) generate automatically labels for cross referencing.

The content of a ManSection element is one or more elements describing certain items in GAP, each of them optionally followed by a Returns element, followed by a Description element, which contains %Text; (see here) describing it. (Remember to include examples in the description as often as possible, see 3.7-10). The classes of items GAPDoc knows of are: functions (Func), operations (Oper), methods (Meth), filters (Filt), properties (Prop), attributes (Attr), variables (Var), families (Fam), and info classes (InfoClass). One ManSection should only describe several of such items when these are very closely related.

Each element for an item corresponding to a GAP function can be followed by a Returns element. In output versions of the document the string "Returns: " will be put in front of the content text. The text in the Returns element should usually be a short hint about the type of object returned by the function. This is intended to give a good mnemonic for the use of a function (together with a good choice of names for the formal arguments).

ManSections are also sectioning elements which count as subsections. Usually there should be no Heading-element in a ManSection, in that case a heading is generated automatically from the first Func-like element. Sometimes this default behaviour does not look appropriate, for example when there are several Func-like elements. For such cases an optional Heading is allowed.

3.4-2 <Func>
<!ELEMENT Func EMPTY>
<!ATTLIST Func Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a function. The Name attribute is required and its value is the name of the function. The value of the Arg attribute (also required) contains the full list of arguments including optional parts, which are denoted by square brackets. The argument names can be separated by whitespace, commas or the square brackets for the optional arguments, like "grp[, elm]" or "xx[y[z] ]". If GAP options are used, this can be followed by a colon : and one or more assignments, like "n[, r]: tries := 100".

The name of the function is also used as label for cross referencing. When the name of the function appears in the text of the document it should always be written with the Ref element, see 3.5-1. This allows to use a unique typesetting style for function names and automatic cross referencing.

If the optional Label attribute is given, it is appended (with a colon : in between) to the name of the function for cross referencing purposes. The text of the label can also appear in the document text. So, it should be a kind of short explanation.

<Func Arg="x[, y]" Name="LibFunc" Label="for my objects"/>

The optional Comm attribute should be a short description of the function, usually at most one line long (this is currently nowhere used).

This element automatically produces an index entry with the name of the function and, if present, the text of the Label attribute as subentry (see also 3.2-16 and 3.5-4).

3.4-3 <Oper>
<!ELEMENT Oper EMPTY>
<!ATTLIST Oper Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of an operation. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

Note that multiple descriptions of the same operation may occur in a document because there may be several declarations in GAP. Furthermore there may be several ManSections for methods of this operation (see 3.4-4) which also use the same name. For reference purposes these must be distinguished by different Label attributes.

3.4-4 <Meth>
<!ELEMENT Meth EMPTY>
<!ATTLIST Meth Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a method. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

Frequently, an operation is implemented by several different methods. Therefore it seems to be interesting to document them independently. This is possible by using the same method name in different ManSections. It is however required that these subsections and those describing the corresponding operation are distinguished by different Label attributes.

3.4-5 <Filt>
<!ELEMENT Filt EMPTY>
<!ATTLIST Filt Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #IMPLIED
               Comm  CDATA #IMPLIED
               Type  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a filter. The first four attributes are used in the same way as in the Func element (see 3.4-2), except that the Arg attribute is optional.

The Type attribute can be any string, but it is thought to be something like "Category" or "Representation".

3.4-6 <Prop>
<!ELEMENT Prop EMPTY>
<!ATTLIST Prop Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a property. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

3.4-7 <Attr>
<!ELEMENT Attr EMPTY>
<!ATTLIST Attr Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of an attribute (in GAP). The attributes are used exactly in the same way as in the Func element (see 3.4-2).

3.4-8 <Var>
<!ELEMENT Var  EMPTY>
<!ATTLIST Var  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document a global variable. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.4-9 <Fam>
<!ELEMENT Fam  EMPTY>
<!ATTLIST Fam  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document a family. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.4-10 <InfoClass>
<!ELEMENT InfoClass EMPTY>
<!ATTLIST InfoClass Name  CDATA #REQUIRED
                    Label CDATA #IMPLIED
                    Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document an info class. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.5 Cross Referencing and Citations

Cross referencing in the GAPDoc system is somewhat different to the usual LaTeX cross referencing in so far, that a reference knows "which type of object" it is referencing. For example a "reference to a function" is distinguished from a "reference to a chapter". The idea of this is, that the markup must contain this information such that the converters can produce better output. The HTML converter can for example typeset a function reference just as the name of the function with a link to the description of the function, or a chapter reference as a number with a link in the other case.

Referencing is done with the Ref element:

3.5-1 <Ref>
<!ELEMENT Ref EMPTY>
<!ATTLIST Ref Func      CDATA #IMPLIED
              Oper      CDATA #IMPLIED
              Meth      CDATA #IMPLIED
              Filt      CDATA #IMPLIED
              Prop      CDATA #IMPLIED
              Attr      CDATA #IMPLIED
              Var       CDATA #IMPLIED
              Fam       CDATA #IMPLIED
              InfoClass CDATA #IMPLIED
              Chap      CDATA #IMPLIED
              Sect      CDATA #IMPLIED
              Subsect   CDATA #IMPLIED
              Appendix  CDATA #IMPLIED
              Text      CDATA #IMPLIED

              Label     CDATA #IMPLIED
              BookName  CDATA #IMPLIED
              Style (Text | Number) #IMPLIED>  <!-- normally automatic -->

The Ref element is defined to be EMPTY. If one of the attributes Func, Oper, Meth, Prop, Attr, Var, Fam, InfoClass, Chap, Sect, Subsect, Appendix is given then there must be exactly one of these, making the reference one to the corresponding object. The Label attribute can be specified in addition to make the reference unique, for example if more than one method with a given name is present. (Note that there is no way to specify in the DTD that exactly one of the first listed attributes must be given, this is an additional rule.)

A reference to a Label element defined below (see 3.5-2) is done by giving the Label attribute and optionally the Text attribute. If the Text attribute is present its value is typeset in place of the Ref element, if linking is possible (for example in HTML). If this is not possible, the section number is typeset. This type of reference is also used for references to tables (see 3.6-5).

An external reference into another book can be specified by using the BookName attribute. In this case the Label attribute or, if this is not given, the function or section like attribute, is used to resolve the reference. The generated reference points to the first hit when asking "?book name: label" inside GAP.

The optional attribute Style can take only the values Text and Number. It can be used with references to sectioning units and it gives a hint to the converter programs, whether an explicit section number is generated or text. Normally all references to sections generate numbers and references to a GAP object generate the name of the corresponding object with some additional link or sectioning information, which is the behavior of Style="Text". In case Style="Number" in all cases an explicit section number is generated. So

<Ref Subsect="Func" Style="Text"/> described in section 
<Ref Subsect="Func" Style="Number"/>

produces: <Func> described in section 3.4-2.

3.5-2 <Label>
<!ELEMENT Label EMPTY>
<!ATTLIST Label Name CDATA #REQUIRED>

This element is used to define a label for referencing a certain position in the document, if this is possible. If an exact reference is not possible (like in a printed version of the document) a reference to the corresponding subsection is generated. The value of the Name attribute must be unique under all Label elements.

3.5-3 <Cite>
<!ELEMENT Cite EMPTY>
<!ATTLIST Cite Key CDATA #REQUIRED
               Where CDATA #IMPLIED>

This element is for bibliography citations. It is EMPTY by definition. The attribute Key is the key for a lookup in a BibTeX database that has to be specified in the Bibliography element (see 3.2-15). The value of the Where attribute specifies the position in the document as in the corresponding LaTeX syntax \cite[Where value]{Key value}.

3.5-4 <Index>
<!ELEMENT Index (%InnerText;|Subkey)*>
<!ATTLIST Index Key    CDATA #IMPLIED
                Subkey CDATA #IMPLIED>
<!ELEMENT Subkey (%InnerText;)*>

This element generates an index entry. The text within the element is typeset in the index entry, which is sorted under the value, that is specified in the Key and Subkey attributes. If they are not specified, the typeset text itself is used as the key.

A subkey can be specified in the simpler version as an attribute, but then no further markup can be used for the subkey. Optionally, the subkey text can be given in a Subkey element, in this case the attribute value is used for sorting but the typeset text is taken from the content of Subkey.

Note that all Func and similar elements automatically generate index entries. If the TheIndex element (3.2-16) is not present in the document all Index elements are ignored.

3.5-5 <URL>
<!ELEMENT URL (#PCDATA|Alt|Link|LinkText)*>  <!-- Link, LinkText
     variant for case where text needs further markup -->
<!ATTLIST URL Text CDATA #IMPLIED>   <!-- This is for output formats
                                          that have links like HTML -->
<!ELEMENT Link     (%InnerText;)*> <!-- the URL -->
<!ELEMENT LinkText (%InnerText;)*> <!-- text for links, can contain markup -->

This element is for references into the internet. It specifies an URL and optionally a text which can be used for a link (like in HTML or PDF versions of the document). This can be specified in two ways: Either the URL is given as element content and the text is given in the optional Text attribute (in this case the text cannot contain further markup), or the element contains the two elements Link and LinkText which in turn contain the URL and the text, respectively. The default value for the text is the URL itself.

3.5-6 <Email>
<!ELEMENT Email (#PCDATA|Alt|Link|LinkText)*>

This element type is the special case of an URL specifying an email address. The content of the element should be the email address without any prefix like "mailto:". This address is typeset by all converters, also without any prefix. In the case of an output document format like HTML the converter can produce a link with a "mailto:" prefix.

3.5-7 <Homepage>
<!ELEMENT Homepage (#PCDATA|Alt|Link|LinkText)*>

This element type is the special case of an URL specifying a WWW-homepage.

3.6 Structural Elements like Lists

The GAPDoc system offers some limited access to structural elements like lists, enumerations, and tables. Although it is possible to use all LaTeX constructs one always has to think about other output formats. The elements in this section are guaranteed to produce something reasonable in all output formats.

3.6-1 <List>
<!ELEMENT List ( ((Mark,Item)|(BigMark,Item)|Item)+ )>
<!ATTLIST List Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

This element produces a list. Each item in the list corresponds to an Item element. Every Item element is optionally preceded by a Mark element. The content of this is used as a marker for the item. Note that this marker can be a whole word or even a sentence. It will be typeset in some emphasized fashion and most converters will provide some indentation for the rest of the item.

The Only and Not attributes can be used to specify, that the list is included into the output by only one type of converter (Only) or all but one type of converter (Not). Of course at most one of the two attributes may occur in one element. The following values are allowed as of now: "LaTeX", "HTML", and "Text". See also the Alt element in 3.9-1 for more about text alternatives for certain converters.

3.6-2 <Mark>
<!ELEMENT Mark ( %InnerText;)*>

This element is used in the List element to mark items. See 3.6-1 for an explanation.

3.6-3 <Item>
<!ELEMENT Item ( %Text;)*>

This element is used in the List, Enum, and Table elements to specify the items. See sections 3.6-1, 3.6-4, and 3.6-5 for further information.

3.6-4 <Enum>
<!ELEMENT Enum ( Item+ )>
<!ATTLIST Enum Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

This element is used like the List element (see 3.6-1) except that the items must not have marks attached to them. Instead, the items are numbered automatically. The same comments about the Only and Not attributes as above apply.

3.6-5 <Table>
<!ELEMENT Table ( Caption?, (Row | HorLine)+ )>
<!ATTLIST Table Label   CDATA #IMPLIED
                Only    CDATA #IMPLIED
                Not     CDATA #IMPLIED
                Align   CDATA #REQUIRED>
                <!-- We allow | and l,c,r, nothing else -->
<!ELEMENT Row   ( Item+ )>
<!ELEMENT HorLine EMPTY>
<!ELEMENT Caption ( %InnerText;)*>

A table in GAPDoc consists of an optional Caption element followed by a sequence of Row and HorLine elements. A HorLine element produces a horizontal line in the table. A Row element consists of a sequence of Item elements as they also occur in List and Enum elements. The Only and Not attributes have the same functionality as described in the List element in 3.6-1.

The Align attribute is written like a LaTeX tabular alignment specifier but only the letters "l", "r", "c", and "|" are allowed meaning left alignment, right alignment, centered alignment, and a vertical line as delimiter between columns respectively.

If the Label attribute is there, one can reference the table with the Ref element (see 3.5-1) using its Label attribute.

Usually only simple tables should be used. If you want a complicated table in the LaTeX output you should provide alternatives for text and HTML output. Note that in HTML-4.0 there is no possibility to interpret the "|" column separators and HorLine elements as intended. There are lines between all columns and rows or no lines at all.

3.7 Types of Text

This section covers the markup of text. Various types of "text" exist. The following elements are used in the GAPDoc system to mark them. They mostly come in pairs, one long name which is easier to remember and a shortcut to make the markup "lighter".

Most of the following elements are thought to contain only character data and no further markup elements. It is however necessary to allow Alt elements to resolve the entities described in section 2.2-3.

3.7-1 <Emph> and <E>
<!ELEMENT Emph (%InnerText;)*>    <!-- Emphasize something -->
<!ELEMENT E    (%InnerText;)*>    <!-- the same as shortcut -->

This element is used to emphasize some piece of text. It may contain %InnerText; (see here).

3.7-2 <Quoted> and <Q>
<!ELEMENT Quoted (%InnerText;)*>   <!-- Quoted (in quotes) text -->
<!ELEMENT Q (%InnerText;)*>        <!-- Quoted text (shortcut) -->

This element is used to put some piece of text into " "-quotes. It may contain %InnerText; (see here).

3.7-3 <Keyword> and <K>
<!ELEMENT Keyword (#PCDATA|Alt)*>  <!-- Keyword -->
<!ELEMENT K (#PCDATA|Alt)*>        <!-- Keyword (shortcut) -->

This element is used to mark something as a keyword. Usually this will be a GAP keyword such as "if" or "for". No further markup elements are allowed within this element except for the Alt element, which is necessary.

3.7-4 <Arg> and <A>
<!ELEMENT Arg (#PCDATA|Alt)*>      <!-- Argument -->
<!ELEMENT A (#PCDATA|Alt)*>        <!-- Argument (shortcut) -->

This element is used inside Descriptions in ManSections to mark something as an argument (of a function, operation, or such). It is guaranteed that the converters typeset those exactly as in the definition of functions. No further markup elements are allowed within this element.

3.7-5 <Code> and <C>
<!ELEMENT Code (#PCDATA|Arg|Alt)*>     <!-- GAP code -->
<!ELEMENT C (#PCDATA|Arg|Alt)*>        <!-- GAP code (shortcut) -->

This element is used to mark something as a piece of code like for example a GAP expression. It is guaranteed that the converters typeset this exactly as in the Listing element (compare section 3.7-9). The only further markup elements allowed within this element are <Arg> elements (see 3.7-4).

3.7-6 <File> and <F>
<!ELEMENT File (#PCDATA|Alt)*>     <!-- Filename -->
<!ELEMENT F (#PCDATA|Alt)*>        <!-- Filename (shortcut) -->

This element is used to mark something as a filename or a pathname in the file system. No further markup elements are allowed within this element.

3.7-7 <Button> and <B>
<!ELEMENT Button (#PCDATA|Alt)*>   <!-- "Button" (also Menu, Key, ...) -->
<!ELEMENT B (#PCDATA|Alt)*>        <!-- "Button" (shortcut) -->

This element is used to mark something as a button. It can also be used for other items in a graphical user interface like menus, menu entries, or keys. No further markup elements are allowed within this element.

3.7-8 <Package>
<!ELEMENT Package (#PCDATA|Alt)*>   <!-- A package name -->

This element is used to mark something as a name of a package. This is for example used to define the entities GAP, XGAP or GAPDoc (see section 2.2-3). No further markup elements are allowed within this element.

3.7-9 <Listing>
<!ELEMENT Listing (#PCDATA)>  <!-- This is just for GAP code listings -->
<!ATTLIST Listing Type CDATA #IMPLIED> <!-- a comment about the type of
                                            listed code, may appear in
                                            output -->

This element is used to embed listings of programs into the document. Only character data and no other elements are allowed in the content. You should not use the character entities described in section 2.2-3 but instead type the characters directly. Only the general XML rules from section 2.1 apply. Note especially the usage of <![CDATA[ sections described there. It is guaranteed that all converters use a fixed width font for typesetting Listing elements. Compare also the usage of the Code and C elements in 3.7-5.

The Type attribute contains a comment about the type of listed code. It may appear in the output.

3.7-10 <Log> and <Example>
<!ELEMENT Example (#PCDATA)>  <!-- This is subject to the automatic 
                                   example checking mechanism -->
<!ELEMENT Log (#PCDATA)>      <!-- This not -->

These two elements behave exactly like the Listing element (see 3.7-9). They are thought for protocols of GAP sessions. The only difference between the two is that Example sections are intended to be subject to an automatic manual checking mechanism used to ensure the correctness of the GAP manual whereas Log is not touched by this (see section 5.4 for checking tools).

To get a good layout of the examples for display in a standard terminal we suggest to use SizeScreen([72]); (see SizeScreen (Reference: SizeScreen)) in your GAP session before producing the content of Example elements.

3.7-11 <Verb>

There is one further type of verbatim-like element.

<!ELEMENT Verb  (#PCDATA)> 

The content of such an element is guaranteed to be put into an output version exactly as it is using some fixed width font. Before the content a new line is started. If the line after the end of the start tag consists of whitespace only then this part of the content is skipped.

This element is intended to be used together with the Alt element to specify pre-formatted ASCII alternatives for complicated Display formulae or Tables.

3.8 Elements for Mathematical Formulae

3.8-1 <Math> and <Display>
<!-- Normal TeX math mode formula -->
<!ELEMENT Math (#PCDATA|A|Arg|Alt)*>   
<!-- TeX displayed math mode formula -->
<!ELEMENT Display (#PCDATA|A|Arg|Alt)*>
<!-- Mode="M" causes <M>-style formatting -->
<!ATTLIST Display Mode CDATA #IMPLIED>

These elements are used for mathematical formulae. As described in section 2.2-2 they correspond to LaTeX's math and display math mode respectively.

The formulae are typed in as in LaTeX, except that the standard XML entities, see 2.1-9 (in particular the characters < and &), must be escaped - either by using the corresponding entities or by enclosing the formula between "<![CDATA[" and "]]>". (The main reference for LaTeX is [Lam85].)

It is also possible to use some unicode characters for mathematical symbols directly, provided that it can be translated by Encode (6.2-2) into "LaTeX" encoding and that SimplifiedUnicodeString (6.2-2) with arguments "latin1" and "single" returns something sensible. Currently, we support entities &CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR; for the corresponding black board bold letters ℂ, ℤ, ℕ,ℙ, ℚ, ℍ and ℝ, respectively.

The only element type that is allowed within the formula elements is the Arg or A element (see 3.7-4), which is used to typeset identifiers that are arguments to GAP functions or operations.

If a Display element has an attribute Mode with value "M", then the formula is formatted as in M elements (see 3.8-2). Otherwise in text and HTML output the formula is shown as LaTeX source code.

For simple formulae (and you should try to make all your formulae simple!) attempt to use the M element or the Mode="M" attribute in Display for which there is a well defined translation into text, which can be used for text and HTML output versions of the document. So, if possible try to avoid the Math elements and Display elements without attribute or provide useful text substitutes for complicated formulae via Alt elements (see 3.9-1 and 3.7-11).

3.8-2 <M>
<!-- Math with well defined translation to text output -->
<!ELEMENT M (#PCDATA|A|Arg|Alt)*>

The "M" element type is intended for formulae in the running text for which there is a sensible text version. For the LaTeX version of a GAPDoc document the M and Math elements are equivalent. The remarks in 3.8-1 about special characters and the Arg element apply here as well. A document which has all formulae enclosed in M elements can be well readable in text terminal output and printed output versions.

Compared to former versions of GAPDoc many more formulae can be put into M elements. Most modern terminal emulations support unicode characters and many mathematical symbols can now be represented by such characters. But even if a terminal can only display ASCII characters, the user will see some not too bad representation of a formula.

As examples, here are some LaTeX macros which have a sensible ASCII translation and are guaranteed to be translated accordingly by text (and HTML) converters (for a full list of handled Macros see RecFields(TEXTMTRANSLATIONS)):

Table: LaTeX macros with special text translation
\ast *
\bf
\bmod mod
\cdot *
\colon :
\equiv =
\geq >=
\germ
\hookrightarrow ->
\iff <=>
\langle <
\ldots ...
\left  
\leq <=
\leftarrow <-
\Leftarrow <=
\limits  
\longrightarrow -->
\Longrightarrow ==>
\mapsto ->
\mathbb  
\mathop  
\mid |
\pmod mod
\prime '
\rangle >
\right  
\rightarrow ->
\Rightarrow =>
\rm, \sf, \textrm, \text
\setminus \
\thinspace
\times x
\to ->
\vert |
\!
\,
\;  
\{ {
\} }

 


In all other macros only the backslash is removed (except for some macros describing more exotic symbols). Whitespace is normalized (to one blank) but not removed. Note that whitespace is not added, so you may want to add a few more spaces than you usually do in your LaTeX documents.

Braces {} are removed in general, however pairs of double braces are converted to one pair of braces. This can be used to write <M>x^{12}</M> for x^12 and <M>x_{{i+1}}</M> for x_{i+1}.

3.9 Everything else

3.9-1 <Alt>

This element is used to specify alternatives for different output formats within normal text. See also sections 3.6-1, 3.6-4, and 3.6-5 for alternatives in lists and tables.

<!ELEMENT Alt (%InnerText;)*>  <!-- This is only to allow "Only" and
                                    "Not" attributes for normal text -->
<!ATTLIST Alt Only CDATA #IMPLIED
              Not  CDATA #IMPLIED>

Of course exactly one of the two attributes must occur in one element. The attribute values must be one word or a list of words, separated by spaces or commas. The words which are currently recognized by the converter programs contained in GAPDoc are: "LaTeX", "HTML", and "Text". If the Only attribute is specified then only the corresponding converter will include the content of the element into the output document. If the Not attribute is specified the corresponding converter will ignore the content of the element. You can use other words to specify special alternatives for other converters of GAPDoc documents.

We fix a rule for handling the content of an Alt element with Only attribute. In their content code for the corresponding output format is included directly. So, in case of HTML the content is HTML code, in case of LaTeX the content is LaTeX code. The converters don't apply any handling of special characters to this content.

Within the element only %InnerText; (see here) is allowed. This is to ensure that the same set of chapters, sections, and subsections show up in all output formats.

3.9-2 <Par> and <P>
<!ELEMENT Par EMPTY>    <!-- this is intentionally empty! -->
<!ELEMENT P EMPTY>      <!-- the same as shortcut  -->

This EMPTY element marks the boundary of paragraphs. Note that an empty line in the input does not mark a new paragraph as opposed to the LaTeX convention.

(Remark: it would be much easier to parse a document and to understand its sectioning and paragraph structure when there was an element whose content is the text of a paragraph. But in practice many paragraph boundaries are implicitly clear which would make it somewhat painful to enclose each paragraph in extra tags. The introduction of the P or Par elements as above delegates this pain to the writer of a conversion program for GAPDoc documents.)

3.9-3 <Br>
 
<!ELEMENT Br EMPTY>     <!-- a forced line break  -->

This element can be used to force a line break in the output versions of a GAPDoc element, it does not start a new paragraph. Please, do not use this instead of a Par element, this would often lead to ugly output versions of your document.

3.9-4 <Ignore>
 
<!ELEMENT Ignore (%Text;| Chapter | Section | Subsection | ManSection |
                  Heading)*>
<!ATTLIST Ignore Remark CDATA #IMPLIED>

This element can appear anywhere. Its content is ignored by the standard converters. It can be used, for example, to include data which are not part of the actual GAPDoc document, like source code, or to make not finished parts of the document invisible.

Of course, one can use special converter programs which extract the contents of Ignore elements. Information on the type of the content can be stored in the optional attribute Remark.

 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/clean0000755000175000017500000000017512026346063012763 0ustar billbill#!/bin/bash rm -f *.{aux,log,dvi,ps,pdf,bbl,ilg,ind,idx,out,html,tex,pnr,txt,blg,toc,six,brf,js,css,lab} gapdocbib.xml.bib GAPDoc-1.5.1/doc/chooser.html0000644000175000017500000000745612026346063014314 0ustar billbill GAPDoc Style Chooser

Setting preferences for GAPDoc manuals

Unfold subsections in menus only by mouse clicks: no (default)     yes

Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

Display side of table of contents within chapters: right (default)     left

Main document font: Helvetica/sans serif (default)     Times/serif

Paragraph formatting: left-right justified (default)     ragged right

Apply settings to last page.

GAPDoc-1.5.1/doc/chapA.txt0000644000175000017500000000653612026346063013537 0ustar billbill A The File 3k+1.xml Here is the complete source of the example GAPDoc document 3k+1.xml discussed in Section 1.2.  3k+1.xml            The <Package>ThreeKPlusOne</Package> Package  Version 42  Dummy Authör  3kplusone@dev.null     ©right; 2000 The Author.

  You can do with this package what you want.

Really.         The 3k+1 Problem 

Theory  Let k \in &NN; be a natural number. We consider the  sequence n(i, k), i \in &NN;, with n(1, k) = k and  else n(i+1, k) = n(i, k) / 2 if n(i, k) is even  and n(i+1, k) = 3 n(i, k) + 1 if n(i, k) is odd. 

It is not known whether for any natural number k \in  &NN; there is an m \in &NN; with n(m, k) = 1. 

  ThreeKPlusOne provides the function to explore this for given  n. If you really want to know something about this  problem, see or  http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/  for more details (and forget this package). 

  
Program  In this section we describe the main function of this package.        This function computes for a natural number k the  beginning of the sequence n(i, k) defined in section  . The sequence stops at the first  1 or at n(max, k), if max is  given.  gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package"      
        
   GAPDoc-1.5.1/doc/chap6_mj.html0000644000175000017500000013577412026346063014346 0ustar billbill GAP (GAPDoc) - Chapter 6: String and Text Utilities
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

6 String and Text Utilities
 6.1 Text Utilities
 6.2 Unicode Strings
 6.3 Print Utilities

6 String and Text Utilities

6.1 Text Utilities

This section describes some utility functions for handling texts within GAP. They are used by the functions in the GAPDoc package but may be useful for other purposes as well. We start with some variables containing useful strings and go on with functions for parsing and reformatting text.

6.1-1 WHITESPACE
‣ WHITESPACE( global variable )
‣ CAPITALLETTERS( global variable )
‣ SMALLLETTERS( global variable )
‣ LETTERS( global variable )
‣ DIGITS( global variable )
‣ HEXDIGITS( global variable )
‣ BOXCHARS( global variable )

These variables contain sets of characters which are useful for text processing. They are defined as follows.

WHITESPACE

" \n\t\r"

CAPITALLETTERS

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

SMALLLETTERS

"abcdefghijklmnopqrstuvwxyz"

LETTERS

concatenation of CAPITALLETTERS and SMALLLETTERS

DIGITS

"0123456789"

HEXDIGITS

"0123456789ABCDEFabcdef"

BOXCHARS

"─│┌┬┐├┼┤└┴┘━┃┏┳┓┣╋┫┗┻┛═║╔╦╗╠╬╣╚╩╝" , these are in UTF-8 encoding, the i-th unicode character is BOXCHARS{[3*i-2..3*i]}.

6.1-2 TextAttr
‣ TextAttr( global variable )

The record TextAttr contains strings which can be printed to change the terminal attribute for the following characters. This only works with terminals which understand basic ANSI escape sequences. Try the following example to see if this is the case for the terminal you are using. It shows the effect of the foreground and background color attributes and of the .bold, .blink, .normal, .reverse and .underscore which can partly be mixed.

extra := ["CSI", "reset", "delline", "home"];;
for t in Difference(RecNames(TextAttr), extra) do
  Print(TextAttr.(t), "TextAttr.", t, TextAttr.reset,"\n");
od;

The suggested defaults for colors 0..7 are black, red, green, brown, blue, magenta, cyan, white. But this may be different for your terminal configuration.

The escape sequence .delline deletes the content of the current line and .home moves the cursor to the beginning of the current line.

for i in [1..5] do 
  Print(TextAttr.home, TextAttr.delline, String(i,-6), "\c"); 
  Sleep(1); 
od;

Whenever you use this in some printing routines you should make it optional. Use these attributes only when UserPreference("UseColorsInTerminal"); returns true.

6.1-3 WrapTextAttribute
‣ WrapTextAttribute( str, attr )( function )

Returns: a string with markup

The argument str must be a text as GAP string, possibly with markup by escape sequences as in TextAttr (6.1-2). This function returns a string which is wrapped by the escape sequences attr and TextAttr.reset. It takes care of markup in the given string by appending attr also after each given TextAttr.reset in str.

gap> str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY");
"XXX\033[32mBLUB\033[0mYYY"
gap> str2 := WrapTextAttribute(str, TextAttr.1);
"\033[31mXXX\033[32mBLUB\033[0m\033[31m\027YYY\033[0m"
gap> str3 := WrapTextAttribute(str, TextAttr.underscore);
"\033[4mXXX\033[32mBLUB\033[0m\033[4m\027YYY\033[0m"
gap> # use Print(str); and so on to see how it looks like.

6.1-4 FormatParagraph
‣ FormatParagraph( str[, len][, flush][, attr][, widthfun] )( function )

Returns: the formatted paragraph as string

This function formats a text given in the string str as a paragraph. The optional arguments have the following meaning:

len

the length of the lines of the formatted text, default is 78 (counted without a visible length of the strings specified in the attr argument)

flush

can be "left", "right", "center" or "both", telling that lines should be flushed left, flushed right, centered or left-right justified, respectively, default is "both"

attr

is a list of two strings; the first is prepended and the second appended to each line of the result (can for example be used for indenting, [" ", ""], or some markup, [TextAttr.bold, TextAttr.reset], default is ["", ""])

widthfun

must be a function which returns the display width of text in str. The default is Length assuming that each byte corresponds to a character of width one. If str is given in UTF-8 encoding one can use WidthUTF8String (6.2-3) here.

This function tries to handle markup with the escape sequences explained in TextAttr (6.1-2) correctly.

gap> str := "One two three four five six seven eight nine ten eleven.";;
gap> Print(FormatParagraph(str, 25, "left", ["/* ", " */"]));           
/* One two three four five */
/* six seven eight nine ten */
/* eleven. */

6.1-5 SubstitutionSublist
‣ SubstitutionSublist( list, sublist, new[, flag] )( function )

Returns: the changed list

This function looks for (non-overlapping) occurrences of a sublist sublist in a list list (compare PositionSublist (Reference: PositionSublist)) and returns a list where these are substituted with the list new.

The optional argument flag can either be "all" (this is the default if not given) or "one". In the second case only the first occurrence of sublist is substituted.

If sublist does not occur in list then list itself is returned (and not a ShallowCopy(list)).

gap> SubstitutionSublist("xababx", "ab", "a");
"xaax"

6.1-6 StripBeginEnd
‣ StripBeginEnd( list, strip )( function )

Returns: changed string

Here list and strip must be lists. This function returns the sublist of list which does not contain the leading and trailing entries which are entries of strip. If the result is equal to list then list itself is returned.

gap> StripBeginEnd(" ,a, b,c,   ", ", ");
"a, b,c"

6.1-7 StripEscapeSequences
‣ StripEscapeSequences( str )( function )

Returns: string without escape sequences

This function returns the string one gets from the string str by removing all escape sequences which are explained in TextAttr (6.1-2). If str does not contain such a sequence then str itself is returned.

6.1-8 RepeatedString
‣ RepeatedString( c, len )( function )
‣ RepeatedUTF8String( c, len )( function )

Here c must be either a character or a string and len is a non-negative number. Then RepeatedString returns a string of length len consisting of copies of c.

In the variant RepeatedUTF8String the argument c is considered as string in UTF-8 encoding, and it can also be specified as unicode string or character, see Unicode (6.2-1). The result is a string in UTF-8 encoding which has visible width len as explained in WidthUTF8String (6.2-3).

gap> RepeatedString('=',51);
"==================================================="
gap> RepeatedString("*=",51);
"*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"
gap> s := "bäh";;
gap> enc := GAPInfo.TermEncoding;;
gap> if enc <> "UTF-8" then s := Encode(Unicode(s, enc), "UTF-8"); fi;
gap> l := RepeatedUTF8String(s, 8);;
gap> u := Unicode(l, "UTF-8");;
gap> Print(Encode(u, enc), "\n");
bähbähbä

6.1-9 NumberDigits
‣ NumberDigits( str, base )( function )

Returns: integer

‣ DigitsNumber( n, base )( function )

Returns: string

The argument str of NumberDigits must be a string consisting only of an optional leading '-' and characters in 0123456789abcdefABCDEF, describing an integer in base base with \(2 \leq \textit{base} \leq 16\). This function returns the corresponding integer.

The function DigitsNumber does the reverse.

gap> NumberDigits("1A3F",16);
6719
gap> DigitsNumber(6719, 16);
"1A3F"

6.1-10 PositionMatchingDelimiter
‣ PositionMatchingDelimiter( str, delim, pos )( function )

Returns: position as integer or fail

Here str must be a string and delim a string with two different characters. This function searches the smallest position r of the character delim[2] in str such that the number of occurrences of delim[2] in str between positions pos+1 and r is by one greater than the corresponding number of occurrences of delim[1].

If such an r exists, it is returned. Otherwise fail is returned.

gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0);
fail
gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1);
2
gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6);
11

6.1-11 WordsString
‣ WordsString( str )( function )

Returns: list of strings containing the words

This returns the list of words of a text stored in the string str. All non-letters are considered as word boundaries and are removed.

gap> WordsString("one_two \n    three!?");
[ "one", "two", "three" ]

6.1-12 Base64String
‣ Base64String( str )( function )
‣ StringBase64( bstr )( function )

Returns: a string

The first function translates arbitrary binary data given as a GAP string into a base 64 encoded string. This encoded string contains only printable ASCII characters and is used in various data transfer protocols (MIME encoded emails, weak password encryption, ...). We use the specification in RFC 2045.

The second function has the reverse functionality. Here we also accept the characters -_ instead of +/ as last two characters. Whitespace is ignored.

gap> b := Base64String("This is a secret!");
"VGhpcyBpcyBhIHNlY3JldCEA="
gap> StringBase64(b);                       
"This is a secret!"

6.2 Unicode Strings

The GAPDoc package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings.

6.2-1 Unicode Strings and Characters
‣ Unicode( list[, encoding] )( operation )
‣ UChar( num )( operation )
‣ IsUnicodeString( filter )
‣ IsUnicodeCharacter( filter )
‣ IntListUnicodeString( ustr )( function )

Unicode characters are described by their codepoint, an integer in the range from \(0\) to \(2^{21}-1\). For details about unicode, see http://www.unicode.org.

The function UChar wraps an integer num into a GAP object lying in the filter IsUnicodeCharacter. Use Int to get the codepoint back. The argument num can also be a GAP character which is then translated to an integer via IntChar (Reference: IntChar).

Unicode produces a GAP object in the filter IsUnicodeString. This is a wrapped list of integers for the unicode characters in the string. The function IntListUnicodeString gives access to this list of integers. Basic list functionality is available for IsUnicodeString elements. The entries are in IsUnicodeCharacter. The argument list for Unicode is either a list of integers or a GAP string. In the latter case an encoding can be specified as string, its default is "UTF-8".

Currently supported encodings can be found in UNICODE_RECODE.NormalizedEncodings (ASCII, ISO-8859-X, UTF-8 and aliases). The encoding "XML" means an ASCII encoding in which non-ASCII characters are specified by XML character entities. The encoding "URL" is for URL-encoded (also called percent-encoded strings, as specified in RFC 3986 (see here). The listed encodings "LaTeX" and aliases cannot be used with Unicode. See the operation Encode (6.2-2) for mapping a unicode string to a GAP string.

gap> ustr := Unicode("a and \366", "latin1");
Unicode("a and \303\266")
gap> ustr = Unicode("a and &#246;", "XML");  
true
gap> IntListUnicodeString(ustr);
[ 97, 32, 97, 110, 100, 32, 246 ]
gap> ustr[7];
'ö'

6.2-2 Encode
‣ Encode( ustr[, encoding] )( operation )

Returns: a GAP string

‣ SimplifiedUnicodeString( ustr[, encoding][, "single"] )( function )

Returns: a unicode string

‣ LowercaseUnicodeString( ustr )( function )

Returns: a unicode string

‣ UppercaseUnicodeString( ustr )( function )

Returns: a unicode string

‣ LaTeXUnicodeTable( global variable )
‣ SimplifiedUnicodeTable( global variable )
‣ LowercaseUnicodeTable( global variable )

The operation Encode translates a unicode string ustr into a GAP string in some specified encoding. The default encoding is "UTF-8".

Supported encodings can be found in UNICODE_RECODE.NormalizedEncodings. Except for some cases mentioned below characters which are not available in the target encoding are substituted by '?' characters.

If the encoding is "URL" (see Unicode (6.2-1)) then an optional argument encreserved can be given, it must be a list of reserved characters which should be percent encoded; the default is to encode only the % character.

The encoding "LaTeX" substitutes non-ASCII characters and LaTeX special characters by LaTeX code as given in an ordered list LaTeXUnicodeTable of pairs [codepoint, string]. If you have a unicode character for which no substitution is contained in that list, you will get a warning and the translation is Unicode(nr). In this case find a substitution and add a corresponding [codepoint, string] pair to LaTeXUnicodeTable using AddSet (Reference: AddSet). Also, please, tell the GAPDoc authors about your addition, such that we can extend the list LaTeXUnicodeTable. (Most of the initial entries were generated from lists in the TeX projects encTeX and ucs.) There are some variants of this encoding:

"LaTeXleavemarkup" does the same translations for non-ASCII characters but leaves the LaTeX special characters (e.g., any LaTeX commands) as they are.

"LaTeXUTF8" does not give a warning about unicode characters without explicit translation, instead it translates the character to its UTF-8 encoding. Make sure to setup your LaTeX document such that all these characters are understood.

"LaTeXUTF8leavemarkup" is a combination of the last two variants.

Note that the "LaTeX" encoding can only be used with Encode but not for the opposite translation with Unicode (6.2-1) (which would need far too complicated heuristics).

The function SimplifiedUnicodeString can be used to substitute many non-ASCII characters by related ASCII characters or strings (e.g., by a corresponding character without accents). The argument ustr and the result are unicode strings, if encoding is "ASCII" then all non-ASCII characters are translated, otherwise only the non-latin1 characters. If the string "single" in an argument then only substitutions are considered which don't make the result string longer. The translations are stored in a sorted list SimplifiedUnicodeTable. Its entries are of the form [codepoint, trans1, trans2, ...]. Here trans1 and so on is either an integer for the codepoint of a substitution character or it is a list of codepoint integers. If you are missing characters in this list and know a sensible ASCII approximation, then add an entry (with AddSet (Reference: AddSet)) and tell the GAPDoc authors about it. (The initial content of SimplifiedUnicodeTable was mainly generated from the "transtab" tables by Markus Kuhn.)

The function LowercaseUnicodeString gets and returns a unicode string and translates each uppercase character to its corresponding lowercase version. This function uses a list LowercaseUnicodeTable of pairs of codepoint integers. This list was generated using the file UnicodeData.txt from the unicode definition (field 14 in each row).

The function UppercaseUnicodeString does the similar translation to uppercase characters.

gap> ustr := Unicode("a and &#246;", "XML");
Unicode("a and \303\266")
gap> SimplifiedUnicodeString(ustr, "ASCII");
Unicode("a and oe")
gap> SimplifiedUnicodeString(ustr, "ASCII", "single");
Unicode("a and o")
gap> ustr2 := UppercaseUnicodeString(ustr);;
gap> Print(Encode(ustr2, GAPInfo.TermEncoding), "\n");
A AND Ö

6.2-3 Lengths of UTF-8 strings
‣ WidthUTF8String( str )( function )
‣ NrCharsUTF8String( str )( function )

Returns: an integer

Let str be a GAP string with text in UTF-8 encoding. There are three "lengths" of such a string which must be distinguished. The operation Length (Reference: Length) returns the number of bytes and so the memory occupied by str. The function NrCharsUTF8String returns the number of unicode characters in str, that is the length of Unicode(str).

In many applications the function WidthUTF8String is more interesting, it returns the number of columns needed by the string if printed to a terminal. This takes into account that some unicode characters are combining characters and that there are wide characters which need two columns (e.g., for Chinese or Japanese). (To be precise: This implementation assumes that there are no control characters in str and uses the character width returned by the wcwidth function in the GNU C-library called with UTF-8 locale.)

gap> # A, German umlaut u, B, zero width space, C, newline
gap> str := Encode( Unicode( "A&#xFC;B&#x200B;C\n", "XML" ) );;
gap> Print(str);
AüB​C
gap> # umlaut u needs two bytes and the zero width space three
gap> Length(str);
9
gap> NrCharsUTF8String(str);
6
gap> # zero width space and newline don't contribute to width
gap> WidthUTF8String(str);
4

6.3 Print Utilities

The following printing utilities turned out to be useful for interactive work with texts in GAP. But they are more general and so we document them here.

6.3-1 PrintTo1
‣ PrintTo1( filename, fun )( function )
‣ AppendTo1( filename, fun )( function )

The argument fun must be a function without arguments. Everything which is printed by a call fun() is printed into the file filename. As with PrintTo (Reference: PrintTo) and AppendTo (Reference: AppendTo) this overwrites or appends to, respectively, a previous content of filename.

These functions can be particularly efficient when many small pieces of text shall be written to a file, because no multiple reopening of the file is necessary.

gap> f := function() local i; 
>   for i in [1..100000] do Print(i, "\n"); od; end;; 
gap> PrintTo1("nonsense", f); # now check the local file `nonsense'

6.3-2 StringPrint
‣ StringPrint( obj1[, obj2[, ...]] )( function )
‣ StringView( obj )( function )

These functions return a string containing the output of a Print or ViewObj call with the same arguments.

This should be considered as a (temporary?) hack. It would be better to have String (Reference: String) methods for all GAP objects and to have a generic Print (Reference: Print)-function which just interprets these strings.

6.3-3 PrintFormattedString
‣ PrintFormattedString( str )( function )

This function prints a string str. The difference to Print(str); is that no additional line breaks are introduced by GAP's standard printing mechanism. This can be used to print lines which are longer than the current screen width. In particular one can print text which contains escape sequences like those explained in TextAttr (6.1-2), where lines may have more characters than visible characters.

6.3-4 Page
‣ Page( ... )( function )
‣ PageDisplay( obj )( function )

These functions are similar to Print (Reference: Print) and Display (Reference: Display), respectively. The difference is that the output is not sent directly to the screen, but is piped into the current pager; see Pager (Reference: Pager).

gap> Page([1..1421]+0);
gap> PageDisplay(CharacterTable("Symmetric", 14));

6.3-5 StringFile
‣ StringFile( filename )( function )
‣ FileString( filename, str[, append] )( function )

The function StringFile returns the content of file filename as a string. This works efficiently with arbitrary (binary or text) files. If something went wrong, this function returns fail.

Conversely the function FileString writes the content of a string str into the file filename. If the optional third argument append is given and equals true then the content of str is appended to the file. Otherwise previous content of the file is deleted. This function returns the number of bytes written or fail if something went wrong.

Both functions are quite efficient, even with large files.

 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/textutil.xml0000644000175000017500000000324012026346063014353 0ustar billbill String and Text Utilities
Text Utilities This section describes some utility functions for handling texts within &GAP;. They are used by the functions in the &GAPDoc; package but may be useful for other purposes as well. We start with some variables containing useful strings and go on with functions for parsing and reformatting text.

<#Include Label="CharsColls"> <#Include Label="TextAttr"> <#Include Label="WrapTextAttribute"> <#Include Label="FormatParagraph"> <#Include Label="SubstitutionSublist"> <#Include Label="StripBeginEnd"> <#Include Label="StripEscapeSequences"> <#Include Label="RepeatedString"> <#Include Label="NumberDigits"> <#Include Label="PositionMatchingDelimiter"> <#Include Label="WordsString"> <#Include Label="Base64String">

Unicode Strings The &GAPDoc; package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings. <#Include Label="Unicode"> <#Include Label="Encode"> <#Include Label="WidthUTF8String">
Print Utilities The following printing utilities turned out to be useful for interactive work with texts in &GAP;. But they are more general and so we document them here. <#Include Label="PrintTo1"> <#Include Label="StringPrint"> <#Include Label="PrintFormattedString"> <#Include Label="Page"> <#Include Label="StringFile">
GAPDoc-1.5.1/doc/chap2.txt0000644000175000017500000004220212026346063013506 0ustar billbill 2 How To Type a GAPDoc Document In this chapter we give a more formal description of what you need to start to type documentation in GAPDoc XML format. Many details were already explained by example in Section 1.2 of the introduction. We do not answer the question How to write a GAPDoc document? in this chapter. You can (hopefully) find an answer to this question by studying the example in the introduction, see 1.2, and learning about more details in the reference Chapter 3. The definite source for all details of the official XML standard with useful annotations is: http://www.xml.com/axml/axml.html Although this document must be quite technical, it is surprisingly well readable. 2.1 General XML Syntax We will now discuss the pieces of text which can occur in a general XML document. We start with those pieces which do not contribute to the actual content of the document. 2.1-1 Head of XML Document Each XML document should have a head which states that it is an XML document in some encoding and which XML-defined language is used. In case of a GAPDoc document this should always look as in the following example.  Example     See 2.1-13 for a remark on the encoding statement. (There may be local entity definitions inside the DOCTYPE statement, see Subsection 2.2-3 below.) 2.1-2 Comments A comment in XML starts with the character sequence . Between these sequences there must not be two adjacent dashes --. 2.1-3 Processing Instructions A processing instruction in XML starts with the character sequence  must not occur within the processing instruction.   And now we turn to those parts of the document which contribute to its actual content. 2.1-4 Names in XML and Whitespace A name in XML (used for element and attribute identifiers, see below) must start with a letter (in the encoding of the document) or with a colon : or underscore _ character. The following characters may also be digits, dots . or dashes -. This is a simplified description of the rules in the standard, which are concerned with lots of unicode ranges to specify what a letter is. Sequences only consisting of the following characters are considered as whitespace: blanks, tabs, carriage return characters and new line characters. 2.1-5 Elements The actual content of an XML document consists of elements. An element has some content with a leading start tag (2.1-6) and a trailing end tag (2.1-7). The content can contain further elements but they must be properly nested. One can define elements whose content is always empty, those elements can also be entered with a single combined tag (2.1-8). 2.1-6 Start Tags A start-tag consists of a less-than-character < directly followed (without whitespace) by an element name (see 2.1-4), optional attributes, optional whitespace, and a greater-than-character >. An attribute consists of some whitespace and then its name followed by an equal sign = which is optionally enclosed by whitespace, and the attribute value, which is enclosed either in single or double quotes. The attribute value may not contain the type of quote used as a delimiter or the character <, the character & may only appear to start an entity, see 2.1-9. We describe in 2.1-11 how to enter special characters in attribute values. Note especially that no whitespace is allowed between the starting < character and the element name. The quotes around an attribute value cannot be omitted. The names of elements and attributes are case sensitive. 2.1-7 End Tags An end tag consists of the two characters . 2.1-8 Combined Tags for Empty Elements Elements which always have empty content can be written with a single tag. This looks like a start tag (see 2.1-6) except that the trailing greater-than-character > is substituted by the two character sequence />. 2.1-9 Entities An entity in XML is a macro for some substitution text. There are two types of entities. A character entity can be used to specify characters in the encoding of the document (can be useful for entering non-ASCII characters which you cannot manage to type in directly). They are entered with a sequence &#, directly followed by either some decimal digits or an x and some hexadecimal digits, directly followed by a semicolon ;. Using such a character entity is just equivalent to typing the corresponding character directly. Then there are references to named entities. They are entered with an ampersand character & directly followed by a name which is directly followed by a semicolon ;. Such entities must be declared somewhere by giving a substitution text. This text is included in the document and the document is parsed again afterwards. The exact rules are a bit subtle but you probably want to use this only in simple cases. Predefined entities for GAPDoc are described in 2.1-10 and 2.2-3. 2.1-10 Special Characters in XML We have seen that the less-than-character < and the ampersand character & start a tag or entity reference in XML. To get these characters into the document text one has to use entity references, namely < to get < and & to get &. Furthermore > must be used to get > when the string ]]> appears in element content (and not as delimiter of a CDATA section explained below). Another possibility is to use a CDATA statement explained in 2.1-12. 2.1-11 Rules for Attribute Values Attribute values can contain entities which are substituted recursively. But except for the entities < or a character entity it is not allowed that a < character is introduced by the substitution (there is no XML parsing for evaluating the attribute value, just entity substitutions). 2.1-12 CDATA Pieces of text which contain many characters which can be misinterpreted as markup can be enclosed by the character sequences . Everything between these sequences is considered as content of the document and is not further interpreted as XML text. All the rules explained so far in this section do not apply to such a part of the document. The only document content which cannot be entered directly inside a CDATA statement is the sequence ]]>. This can be entered as ]]> outside the CDATA statement.  Example  A nesting of tags like is not allowed.  2.1-13 Encoding of an XML Document We suggest to use the UTF-8 encoding for writing GAPDoc XML documents. But the tools described in Chapter 5 also work with ASCII or the various ISO-8859-X encodings (ISO-8859-1 is also called latin1 and covers most special characters for western European languages). 2.1-14 Well Formed and Valid XML Documents We want to mention two further important words which are often used in the context of XML documents. A piece of text becomes a well formed XML document if all the formal rules described in this section are fulfilled. But this says nothing about the content of the document. To give this content a meaning one needs a declaration of the element and corresponding attribute names as well as of named entities which are allowed. Furthermore there may be restrictions how such elements can be nested. This definition of an XML based markup language is done in a document type definition. An XML document which contains only elements and entities declared in such a document type definition and obeys the rules given there is called valid (with respect to this document type definition). The main file of the GAPDoc package is gapdoc.dtd. This contains such a definition of a markup language. We are not going to explain the formal syntax rules for document type definitions in this section. But in Chapter 3 we will explain enough about it to understand the file gapdoc.dtd and so the markup language defined there. 2.2 Entering GAPDoc Documents Here are some additional rules for writing GAPDoc XML documents. 2.2-1 Other special characters As GAPDoc documents are used to produce LaTeX and HTML documents, the question arises how to deal with characters with a special meaning for other applications (for example &, #, $, %, ~, \, {, }, _, ^,   (this is a non-breakable space, ~ in LaTeX) have a special meaning for LaTeX and &, <, > have a special meaning for HTML (and XML). In GAPDoc you can usually just type these characters directly, it is the task of the converter programs which translate to some output format to take care of such special characters. The exceptions to this simple rule are:  & and < must be entered as & and < as explained in 2.1-10.  The content of the GAPDoc elements ,  and  is LaTeX code, see 3.8.  The content of an  element with Only attribute contains code for the specified output type, see 3.9-1. Remark: In former versions of GAPDoc one had to use particular entities for all the special characters mentioned above (&tamp;, &hash;, $, &percent;, ˜, &bslash;, &obrace;, &cbrace;, &uscore;, &circum;, &tlt;, &tgt;). These are no longer needed, but they are still defined for backwards compatibility with older GAPDoc documents. 2.2-2 Mathematical Formulae Mathematical formulae in GAPDoc are typed as in LaTeX. They must be the content of one of three types of GAPDoc elements concerned with mathematical formulae: Math, Display, and M (see Sections 3.8-1 and 3.8-2 for more details). The first two correspond to LaTeX's math mode and display math mode. The last one is a special form of the Math element type, that imposes certain restrictions on the content. On the other hand the content of an M element is processed in a well defined way for text terminal or HTML output. The Display element also has an attribute such that its content is processed as in M elements. Note that the content of these element is LaTeX code, but the special characters < and & for XML must be entered via the entities described in 2.1-10 or by using a CDATA statement, see 2.1-12. 2.2-3 More Entities In GAPDoc there are some more predefined entities: ┌─────────────┬─────────┐ │ &GAP; │ GAP │ ├─────────────┼─────────┤ │ &GAPDoc; │ GAPDoc │ ├─────────────┼─────────┤ │ &TeX; │ TeX │ ├─────────────┼─────────┤ │ &LaTeX; │ LaTeX │ ├─────────────┼─────────┤ │ &BibTeX; │ BibTeX │ ├─────────────┼─────────┤ │ &MeatAxe; │ MeatAxe │ ├─────────────┼─────────┤ │ &XGAP; │ XGAP │ ├─────────────┼─────────┤ │ ©right; │ © │ ├─────────────┼─────────┤ │   │   │ ├─────────────┼─────────┤ │ – │ – │ └─────────────┴─────────┘ Table: Predefined Entities in the GAPDoc system Here   is a non-breakable space character. Additional entities are defined for some mathematical symbols, see 3.8 for more details. One can define further local entities right inside the head (see 2.1-1) of a GAPDoc XML document as in the following example.  Example    text possibly with markup">  ]>  These additional definitions go into the  LeslieLamport \LaTeX: A Document Preparation System Addison-Wesley 1985 0-201-15790-X GAP -- Groups, Algorithms, and Programming, Version 4.4.9 The GAP Group
Aachen, St Andrews
2006 http://www.gap-system.org GAP groups; *; gap; manual
MaxNeunhöffer IO, Bindings for low level C library IO, Version 2.2 http://www-groups.mcs.st-and.ac.uk/~neunhoef/Computer/Software/Gap/io.html 2007 GAP package
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/doc/chap7_mj.html����������������������������������������������������������������������0000644�0001750�0001750�00000166132�12026346063�014337� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
GAP (GAPDoc) - Chapter 7: Utilities for Bibliographies
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

7 Utilities for Bibliographies

7 Utilities for Bibliographies

A standard for collecting references (in particular to mathematical texts) is BibTeX (http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/). A disadvantage of BibTeX is that the format of the data is specified with the use by LaTeX in mind. The data format is less suited for conversion to other document types like plain text or HTML.

In the first section we describe utilities for using data from BibTeX files in GAP.

In the second section we introduce a new XML based data format BibXMLext for bibliographies which seems better suited for other tasks than using it with LaTeX.

Another section will describe utilities to deal with BibXMLext data in GAP.

7.1 Parsing BibTeX Files

Here are functions for parsing, normalizing and printing reference lists in BibTeX format. The reference describing this format is [Lam85, Appendix B].

7.1-1 ParseBibFiles
‣ ParseBibFiles( bibfile1[, bibfile2[, ...]] )( function )
‣ ParseBibStrings( str1[, str2[, ...]] )( function )

Returns: list [list of bib-records, list of abbrevs, list of expansions]

The first function parses the files bibfile1 and so on (if a file does not exist the extension .bib is appended) in BibTeX format and returns a list as follows: [entries, strings, texts]. Here entries is a list of records, one record for each reference contained in bibfile. Then strings is a list of abbreviations defined by @string-entries in bibfile and texts is a list which contains in the corresponding position the full text for such an abbreviation.

The second function does the same, but the input is given as GAP strings str1 and so on.

The records in entries store key-value pairs of a BibTeX reference in the form rec(key1 = value1, ...). The names of the keys are converted to lower case. The type of the reference (i.e., book, article, ...) and the citation key are stored as components .Type and .Label. The records also have a .From field that says that the data are read from a BibTeX source.

As an example consider the following BibTeX file.

@string{ j  = "Important Journal" }
@article{ AB2000, Author=  "Fritz A. First and Sec, X. Y.", 
TITLE="Short", journal = j, year = 2000 }
gap> bib := ParseBibFiles("doc/test.bib");
[ [ rec( From := rec( BibTeX := true ), Label := "AB2000", 
          Type := "article", author := "Fritz A. First and Sec, X. Y."
            , journal := "Important Journal", title := "Short", 
          year := "2000" ) ], [ "j" ], [ "Important Journal" ] ]

7.1-2 NormalizedNameAndKey
‣ NormalizedNameAndKey( namestr )( function )

Returns: list of strings and names as lists

‣ NormalizeNameAndKey( r )( function )

Returns: nothing

The argument namestr must be a string describing an author or a list of authors as described in the BibTeX documentation in [Lam85, Appendix B 1.2]. The function NormalizedNameAndKey returns a list of the form [ normalized name string, short key, long key, names as lists]. The first entry is a normalized form of the input where names are written as "lastname, first name initials". The second and third entry are the name parts of a short and long key for the bibliography entry, formed from the (initials of) last names. The fourth entry is a list of lists, one for each name, where a name is described by three strings for the last name, the first name initials and the first name(s) as given in the input.

Note that the determination of the initials is limited to names where the first letter is described by a single character (and does not contain some markup, say for accents).

The function NormalizeNameAndKey gets as argument r a record for a bibliography entry as returned by ParseBibFiles (7.1-1). It substitutes .author and .editor fields of r by their normalized form, the original versions are stored in fields .authororig and .editororig.

Furthermore a short and a long citation key is generated and stored in components .printedkey (only if no .key is already bound) and .keylong.

We continue the example from ParseBibFiles (7.1-1).

gap> bib := ParseBibFiles("doc/test.bib");;
gap> NormalizedNameAndKey(bib[1][1].author);
[ "First, F. A. and Sec, X. Y.", "FS", "firstsec", 
  [ [ "First", "F. A.", "Fritz A." ], [ "Sec", "X. Y.", "X. Y." ] ] ]
gap> NormalizeNameAndKey(bib[1][1]);
gap> bib[1][1];
rec( From := rec( BibTeX := true ), Label := "AB2000", 
  Type := "article", author := "First, F. A. and Sec, X. Y.", 
  authororig := "Fritz A. First and Sec, X. Y.", 
  journal := "Important Journal", keylong := "firstsec2000", 
  printedkey := "FS00", title := "Short", year := "2000" )

7.1-3 WriteBibFile
‣ WriteBibFile( bibfile, bib )( function )

Returns: nothing

This is the converse of ParseBibFiles (7.1-1). Here bib either must have a format as list of three lists as it is returned by ParseBibFiles (7.1-1). Or bib can be a record as returned by ParseBibXMLextFiles (7.3-4). A BibTeX file bibfile is written and the entries are formatted in a uniform way. All given abbreviations are used while writing this file.

We continue the example from NormalizeNameAndKey (7.1-2). The command

gap> WriteBibFile("nicer.bib", bib);

produces a file nicer.bib as follows:

@string{j = "Important Journal" }

@article{ AB2000,
  author =           {First, F. A. and Sec, X. Y.},
  title =            {Short},
  journal =          j,
  year =             {2000},
  authororig =       {Fritz A. First and Sec, X. Y.},
  keylong =          {firstsec2000},
  printedkey =       {FS00}
}

7.1-4 InfoBibTools
‣ InfoBibTools( info class )

The default level of this info class is 1. Functions like ParseBibFiles (7.1-1), StringBibAs... are then printing some information. You can suppress it by setting the level of InfoBibTools to 0. With level 2 there may be some more information for debugging purposes.

7.2 The BibXMLext Format

Bibliographical data in BibTeX files have the disadvantage that the actual data are given in LaTeX syntax. This makes it difficult to use the data for anything but for LaTeX, say for representations of the data as plain text or HTML. For example: mathematical formulae are in LaTeX $ environments, non-ASCII characters can be specified in many strange ways, and how to specify URLs for links if the output format allows them?

Here we propose an XML data format for bibliographical data which addresses these problems, it is called BibXMLext. In the next section we describe some tools for generating (an approximation to) this data format from BibTeX data, and for using data given in BibXMLext format for various purposes.

The first motivation for this development was the handling of bibliographical data in GAPDoc, but the format and the tools are certainly useful for other purposes as well.

We started from a DTD bibxml.dtd which is publicly available, say from http://bibtexml.sf.net/. This is essentially a reformulation of the definition of the BibTeX format, including several of some widely used further fields. This has already the advantage that a generic XML parser can check the validity of the data entries, for example for missing compulsary fields in entries. We applied the following changes and extensions to define the DTD for BibXMLext, stored in the file bibxmlext.dtd which can be found in the root directory of this GAPDoc package (and in Appendix C):

names

Lists of names in the author and editor fields in BibTeX are difficult to parse. Here they must be given by a sequence of <name>-elements which each contain an optional <first>- and a <last>-element for the first and last names, respectively.

<M> and <Math>

These elements enclose mathematical formulae, the content is LaTeX code (without the $). These should be handled in the same way as the elements with the same names in GAPDoc, see 3.8-2 and 3.8-1. In particular, simple formulae which have a well defined plain text representation can be given in <M>-elements.

Encoding

Note that in XML files we can use the full range of unicode characters, see http://www.unicode.org/. All non-ASCII characters should be specified as unicode characters. This makes dealing with special characters easy for plain text or HTML, only for use with LaTeX some sort of translation is necessary.

<URL>

These elements are allowed everywhere in the text and should be represented by links in converted formats which allow this. It is used in the same way as the element with the same name in GAPDoc, see 3.5-5.

<Alt Only="..."> and <Alt Not="...">

Sometimes information should be given in different ways, depending on the output format of the data. This is possible with the <Alt>-elements with the same definition as in GAPDoc, see 3.9-1.

<C>

This element should be used to protect text from case changes by converters (the extra {} characters in BibTeX title fields).

<string key="..." value="..."/> and <value key="..."/>

The <string>-element defines key-value pairs which can be used in any field via the <value>-element (not only for whole fields but also parts of the text).

<other type="...">

This is a generic element for fields which are otherwise not supported. An arbitrary number of them is allowed for each entry, so any kind of additional data can be added to entries.

<Wrap Name="...">

This generic element is allowed inside all fields. This markup will be just ignored (but not the element content) by our standard tools. But it can be a useful hook for introducing arbitrary further markup (and our tools can easily be extended to handle it).

Extra entities

The DTD defines the standard XML entities (2.1-10 and the entities &nbsp; (non-breakable space), &ndash; and &copyright;. Use &ndash; in page ranges.

For further details of the DTD we refer to the file bibxmlext.dtd itself which is shown in appendix C. That file also recalls some information from the BibTeX documentation on how the standard fields of entries should be used. Which entry types and which fields are supported (and the ordering of the fields which is fixed by a DTD) can be either read off the DTD, or within GAP one can use the function TemplateBibXML (7.3-10) to get templates for the various entry types.

Here is an example of a BibXMLext document:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE file SYSTEM "bibxmlext.dtd">
<file>
<string key="j" value="Important Journal"/>
<entry id="AB2000"><article>
  <author>
    <name><first>Fritz A.</first><last>First</last></name>
    <name><first>X. Y.</first><last>Sec&#x0151;nd</last></name>
  </author>  
  <title>The <Wrap Name="Package"> <C>F</C>ritz</Wrap> package for the 
         formula <M>x^y - l_{{i+1}} \rightarrow \mathbb{R}</M></title>
  <journal><value key="j"/></journal>
  <year>2000</year>
  <number>13</number>
  <pages>13&ndash;25</pages>
  <note>Online data at <URL Text="Bla Bla Publisher">
                  http://www.publish.com/~ImpJ/123#data</URL></note>
  <other type="mycomment">very useful</other>
</article></entry>
</file>

There is a standard XML header and a DOCTYPE declaration refering to the bibxmlext.dtd DTD mentioned above. Local entities could be defined in the DOCTYPE tag as shown in the example in 2.2-3. The actual content of the document is inside a <file>-element, it consists of <string>- and <entry>-elements. Several of the BibXMLext markup features are shown. We will use this input document for some examples below.

7.3 Utilities for BibXMLext data

7.3-1 Translating BibTeX to BibXMLext

First we describe a tool which can translate bibliography entries from BibTeX data to BibXMLext <entry>-elements. It also does some validation of the data. In some cases it is desirable to improve the result by hand afterwards (editing formulae, adding <URL>-elements, translating non-ASCII characters to unicode, ...).

See WriteBibXMLextFile (7.3-5) below for how to write the results to a BibXMLext file.

7.3-2 HeuristicTranslationsLaTeX2XML.Apply
‣ HeuristicTranslationsLaTeX2XML.Apply( str )( function )

Returns: a string

‣ HeuristicTranslationsLaTeX2XML.ApplyFile( fnam[, outnam] )( function )

Returns: nothing

These utilities translate some LaTeX code into text in UTF-8 encoding. The input is given as a string str, or a file name fnam, respectively. The first function returns the translated string. The second function with one argument overwrites the given file with the translated text. Optionally, the translated file content can be written to another file, if its name is given as second argument outnam.

The record HeuristicTranslationsLaTeX2XML mainly contains translations of LaTeX macros for special characters which were found in hundreds of BibTeX entries from MathSciNet. Just look at this record if you want to know how it works. It is easy to extend, and if you have improvements which may be of general interest, please send them to the GAPDoc author.

gap> s := "\\\"u\\'{e}\\`e{\\ss}";;
gap> Print(s, "\n");               
\"u\'{e}\`e{\ss}
gap> Print(HeuristicTranslationsLaTeX2XML.Apply(s),"\n");
üéèß

7.3-3 StringBibAsXMLext
‣ StringBibAsXMLext( bibentry[, abbrvs, vals][, encoding] )( function )

Returns: a string with XML code, or fail

The argument bibentry is a record representing an entry from a BibTeX file, as returned in the first list of the result of ParseBibFiles (7.1-1). The optional two arguments abbrvs and vals can be lists of abbreviations and substitution strings, as returned as second and third list element in the result of ParseBibFiles (7.1-1). The optional argument encoding specifies the character encoding of the string components of bibentry. If this is not given it is checked if all strings are valid UTF-8 encoded strings, in that case it is assumed that the encoding is UTF-8, otherwise the latin1 encoding is assumed.

The function StringBibAsXMLext creates XML code of an <entry>-element in BibXMLext format. The result is in UTF-8 encoding and contains some heuristic translations, like splitting name lists, finding places for <C>-elements, putting formulae in <M>-elements, substituting some characters. The result should always be checked and maybe improved by hand. Some validity checks are applied to the given data, for example if all non-optional fields are given. If this check fails the function returns fail.

If your BibTeX input contains LaTeX markup for special characters, it can be convenient to translate this input with HeuristicTranslationsLaTeX2XML.Apply (7.3-2) or HeuristicTranslationsLaTeX2XML.ApplyFile (7.3-2) before parsing it as BibTeX.

As an example we consider again the short BibTeX file doc/test.bib shown in the example for ParseBibFiles (7.1-1).

gap> bib := ParseBibFiles("doc/test.bib");;
gap> str := StringBibAsXMLext(bib[1][1], bib[2], bib[3]);;
gap> Print(str, "\n");
<entry id="AB2000"><article>
  <author>
    <name><first>Fritz A.</first><last>First</last></name>
    <name><first>X. Y.</first><last>Sec</last></name>
  </author>  
  <title>Short</title>
  <journal><value key="j"/></journal>
  <year>2000</year>
</article></entry>

The following functions allow parsing of data which are already in BibXMLext format.

7.3-4 ParseBibXMLextString
‣ ParseBibXMLextString( str )( function )
‣ ParseBibXMLextFiles( fname1[, fname2[, ...]] )( function )

Returns: a record with fields .entries, .strings and .entities

The first function gets a string str containing a BibXMLext document or a part of it. It returns a record with the three mentioned fields. Here .entries is a list of partial XML parse trees for the <entry>-elements in str. The field .strings is a list of key-value pairs from the <string>-elements in str. And .strings is a list of name-value pairs of the named entities which were used during the parsing.

The second function ParseBibXMLextFiles uses the first on the content of all files given by filenames fname1 and so on. It collects the results in a single record.

As an example we parse the file testbib.xml shown in 7.2.

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> RecFields(bib);
[ "entries", "strings", "entities" ]
gap> bib.entries;
[ <BibXMLext entry: AB2000> ]
gap> bib.strings;
[ [ "j", "Important Journal" ] ]
gap> bib.entities[1]; 
[ "amp", "&#38;#38;" ]

7.3-5 WriteBibXMLextFile
‣ WriteBibXMLextFile( fname, bib )( function )

Returns: nothing

This function writes a BibXMLext file with name fname.

There are three possibilities to specify the bibliography entries in the argument bib. It can be a list of three lists as returned by ParseBibFiles (7.1-1). Or it can be just the first of such three lists in which case the other two lists are assumed to be empty. To all entries of the (first) list the function StringBibAsXMLext (7.3-3) is applied and the resulting strings are written to the result file.

The third possibility is that bib is a record in the format as returned by ParseBibXMLextString (7.3-4) and ParseBibXMLextFiles (7.3-4). In this case the entries for the BibXMLext file are produced with StringXMLElement (5.2-2), and if bib.entities is bound then it is tried to resubstitute parts of the string by the given entities with EntitySubstitution (5.2-3).

As an example we write back the result of the example shown for ParseBibXMLextFiles (7.3-4) to an equivalent XML file.

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> WriteBibXMLextFile("test.xml", bib);

7.3-6 Bibliography Entries as Records

For working with BibXMLext entries we find it convenient to first translate the parse tree of an entry, as returned by ParseBibXMLextFiles (7.3-4), to a record with the field names of the entry as components whose value is the content of the field as string. These strings are generated with respect to a result type. The records are generated by the following function which can be customized by the user.

7.3-7 RecBibXMLEntry
‣ RecBibXMLEntry( entry[, restype][, strings][, options] )( function )

Returns: a record with fields as strings

This function generates a content string for each field of a bibliography entry and assigns them to record components. This content may depend on the requested result type and possibly some given options.

The arguments are as follows: entry is the parse tree of an <entry> element as returned by ParseBibXMLextString (7.3-4) or ParseBibXMLextFiles (7.3-4). The optional argument restype describes the type of the result. This package supports currently the types "BibTeX", "Text" and "HTML". The default is "BibTeX". The optional argument strings must be a list of key-value pairs as returned in the component .strings in the result of ParseBibXMLextString (7.3-4). The argument options must be a record.

If the entry contains an author field then the result will also contain a component .authorAsList which is a list containing for each author a list with three entries of the form [last name, first name initials, first name] (the third entry means the first name as given in the data). Similarly, an editor field is accompanied by a component .editorAsList.

The following options are currently supported.

If options.fullname is bound and set to true then the full given first names for authors and editors will be used, the default is to use the initials of the first names. Also, if options.namefirstlast is bound and set to true then the names are written in the form "first-name(s) last-name", the default is the form "last-name, first-name(s)".

If options.href is bound and set to false then the "BibTeX" type result will not use \href commands. The default is to produce \href commands from <URL>-elements such that LaTeX with the hyperref package can produce links for them.

The content of an <Alt>-element with Only-attribute is included if restype is given in the attribute and ignored otherwise, and vice versa in case of a Not-attribute. If options.useAlt is bound, it must be a list of strings to which restype is added. Then an <Alt>-element with Only-attribute is evaluated if the intersection of options.useAlt and the types given in the attribute is not empty. In case of a Not-attribute the element is evaluated if this intersection is empty.

If restype is "BibTeX" then the string fields in the result will be recoded with Encode (6.2-2) and target "LaTeX". If options.hasLaTeXmarkup is bound and set to true (for example, because the data are originally read from BibTeX files), then the target "LaTeXleavemarkup" will be used.

We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> e := bib.entries[1];; strs := bib.strings;;
gap> Print(RecBibXMLEntry(e, "BibTeX", strs), "\n");
rec(
  From := rec(
      BibXML := true,
      options := rec(
           ),
      type := "BibTeX" ),
  Label := "AB2000",
  Type := "article",
  author := "First, F. A. and Sec{\\H o}nd, X. Y.",
  authorAsList := 
   [ [ "First", "F. A.", "Fritz A." ], 
      [ "Sec\305\221nd", "X. Y.", "X. Y." ] ],
  journal := "Important Journal",
  mycomment := "very useful",
  note := 
   "Online data at \\href {http://www.publish.com/~ImpJ/123#data} {Bla\
 Bla Publisher}",
  number := "13",
  pages := "13{\\textendash}25",
  printedkey := "FS00",
  title := 
   "The  {F}ritz package for the \n         formula $x^y - l_{{i+1}} \
\\rightarrow \\mathbb{R}$",
  year := "2000" )
gap> Print(RecBibXMLEntry(e, "HTML", strs).note, "\n");
Online data at <a href="http://www.publish.com/~ImpJ/123#data">Bla Bla\
 Publisher</a>

7.3-8 AddHandlerBuildRecBibXMLEntry
‣ AddHandlerBuildRecBibXMLEntry( elementname, restype, handler )( function )

Returns: nothing

The argument elementname must be the name of an entry field supported by the BibXMLext format, the name of one of the special elements "C", "M", "Math", "URL" or of the form "Wrap:myname" or any string "mytype" (which then corresponds to entry fields <other type="mytype">). The string "Finish" has an exceptional meaning, see below.

restype is a string describing the result type for which the handler is installed, see RecBibXMLEntry (7.3-7).

For both arguments, elementname and restype, it is also possible to give lists of the described ones for installing several handler at once.

The argument handler must be a function with five arguments of the form handler(entry, r, restype, strings, options). Here entry is a parse tree of a BibXMLext <entry>-element, r is a node in this tree for an element elementname, and restype, strings and options are as explained in RecBibXMLEntry (7.3-7). The function should return a string representing the content of the node r. If elementname is of the form "Wrap:myname" the handler is used for elements of form <Wrap Name="myname">...</Wrap>.

If elementname is "Finish" the handler should look like above except that now r is the record generated by RecBibXMLEntry (7.3-7) just before it is returned. Here the handler should return nothing. It can be used to manipulate the record r, for example for changing the encoding of the strings or for adding some more components.

The installed handler is called by BuildRecBibXMLEntry(entry, r, restype, strings, options). The string for the whole content of an element can be generated by ContentBuildRecBibXMLEntry(entry, r, restype, strings, options).

We continue the example from RecBibXMLEntry (7.3-7) and install a handler for the <Wrap Name="Package">-element such that LaTeX puts its content in a sans serif font.

gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX",
> function(entry,  r, restype,  strings, options)
>   return Concatenation("\\textsf{", ContentBuildRecBibXMLEntry(
>             entry, r, restype,  strings, options), "}");
> end);
gap> 
gap> Print(RecBibXMLEntry(e, "BibTeX", strs).title, "\n");
The \textsf{ {F}ritz} package for the 
         formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$
gap> Print(RecBibXMLEntry(e, "Text", strs).title, "\n");  
The  Fritz package for the 
         formula x^y - l_{i+1} → R
gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", "Ignore");

7.3-9 StringBibXMLEntry
‣ StringBibXMLEntry( entry[, restype][, strings][, options] )( function )

Returns: a string

The arguments of this function have the same meaning as in RecBibXMLEntry (7.3-7) but the return value is a string representing the bibliography entry in a format specified by restype (default is "BibTeX").

Currently, the following cases for restype are supported:

"BibTeX"

A string with BibTeX source code is generated.

"Text"

A text representation of the text is returned. If options.ansi is bound it must be a record. The components must have names Bib_Label, Bib_author, and so on for all fieldnames. The value of each component is a pair of strings which will enclose the content of the field in the result or the first of these strings in which case the default for the second is TextAttr.reset (see TextAttr (6.1-2)). If you give an empty record here, some default ANSI color markup will be used.

"HTML"

An HTML representation of the bibliography entry is returned. The text from each field is enclosed in markup (mostly <span>-elements) with the class attribute set to the field name. This allows a detailed layout of the code via a style sheet file.

We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> e := bib.entries[1];; strs := bib.strings;;
gap> ebib := StringBibXMLEntry(e, "BibTeX", strs);;
gap> PrintFormattedString(ebib);
@article{ AB2000,
  author =           {First, F. A. and Sec{\H o}nd, X. Y.},
  title =            {The  {F}ritz  package  for  the formula $x^y -
                      l_{{i+1}} \rightarrow \mathbb{R}$},
  journal =          {Important Journal},
  number =           {13},
  year =             {2000},
  pages =            {13{\textendash}25},
  note =             {Online          data          at         \href
                      {http://www.publish.com/~ImpJ/123#data}   {Bla
                      Bla Publisher}},
  mycomment =        {very useful},
  printedkey =       {FS00}
}
gap> etxt := StringBibXMLEntry(e, "Text", strs);;      
gap> etxt := SimplifiedUnicodeString(Unicode(etxt), "latin1", "single");;
gap> etxt := Encode(etxt, GAPInfo.TermEncoding);;                        
gap> PrintFormattedString(etxt);
[FS00]  First,  F.  A.  and Second, X. Y., The Fritz package for the
formula  x^y  -  l_{i+1}  ?  R, Important Journal, 13 (2000), 13-25,
(Online        data        at        Bla        Bla        Publisher
(http://www.publish.com/~ImpJ/123#data)).

The following command may be useful to generate completly new bibliography entries in BibXMLext format. It also informs about the supported entry types and field names.

7.3-10 TemplateBibXML
‣ TemplateBibXML( [type] )( function )

Returns: list of types or string

Without an argument this function returns a list of the supported entry types in BibXMLext documents.

With an argument type of one of the supported types the function returns a string which is a template for a corresponding BibXMLext entry. Optional field elements have a * appended. If an element has the word OR appended, then either this element or the next must/can be given, not both. If AND/OR is appended then this and/or the next can/must be given. Elements which can appear several times have a + appended. Places to fill are marked by an X.

gap> TemplateBibXML();
[ "article", "book", "booklet", "conference", "inbook", 
  "incollection", "inproceedings", "manual", "mastersthesis", "misc", 
  "phdthesis", "proceedings", "techreport", "unpublished" ]
gap> Print(TemplateBibXML("inbook"));
<entry id="X"><inbook>
  <author>
    <name><first>X</first><last>X</last></name>+
  </author>OR
  <editor>
    <name><first>X</first><last>X</last></name>+
  </editor>
  <title>X</title>
  <chapter>X</chapter>AND/OR
  <pages>X</pages>
  <publisher>X</publisher>
  <year>X</year>
  <volume>X</volume>*OR
  <number>X</number>*
  <series>X</series>*
  <type>X</type>*
  <address>X</address>*
  <edition>X</edition>*
  <month>X</month>*
  <note>X</note>*
  <key>X</key>*
  <annotate>X</annotate>*
  <crossref>X</crossref>*
  <abstract>X</abstract>*
  <affiliation>X</affiliation>*
  <contents>X</contents>*
  <copyright>X</copyright>*
  <isbn>X</isbn>*OR
  <issn>X</issn>*
  <keywords>X</keywords>*
  <language>X</language>*
  <lccn>X</lccn>*
  <location>X</location>*
  <mrnumber>X</mrnumber>*
  <mrclass>X</mrclass>*
  <mrreviewer>X</mrreviewer>*
  <price>X</price>*
  <size>X</size>*
  <url>X</url>*
  <category>X</category>*
  <other type="X">X</other>*+
</inbook></entry>

7.4 Getting BibTeX entries from MathSciNet

We provide utilities to access the MathSciNet data base from within GAP. One condition for this to work is that the IO-package [Neu07] is available. The other is, of course, that you use these functions from a computer which has access to MathSciNet.

Please note, that the usual license for MathSciNet access does not allow for automated searches in the database. Therefore, only use the SearchMR (7.4-1) function for single queries, as you would do using your webbrowser.

7.4-1 SearchMR
‣ SearchMR( qurec )( function )
‣ SearchMRBib( bib )( function )

Returns: a list of strings, a string or fail

The first function SearchMR provides the same functionality as the Web interface MathSciNet. The query strings must be given as a record, and the following components of this record are recognized: Author, AuthorRelated, Title, ReviewText, Journal, InstitutionCode, Series, MSCPrimSec, MSCPrimary, MRNumber, Anywhere, References and Year.

Furthermore, the component type can be specified. It can be one of "bibtex" (the default if not given), "pdf", "html" and probably others. In the last cases the function returns a string with the correspondig PDF-file or web page from MathSciNet. In the first case the MathSciNet interface returns a web page with BibTeX entries, for convenience this function returns a list of strings, each containing the BibTeX text for a single result entry.

The format of a .Year component can be either a four digit number, optionally preceded by one of the characters '<', '>' or '=', or it can be two four digit numbers separated by a - to specify a year range.

The function SearchMRBib gets a record of a parsed BibTeX entry as input as returned by ParseBibFiles (7.1-1) or ParseBibStrings (7.1-1). It tries to generate some sensible input from this information for SearchMR and calls that function.

gap> ll := SearchMR(rec(Author:="Gauss", Title:="Disquisitiones"));;
gap> ll2 := List(ll, HeuristicTranslationsLaTeX2XML.Apply);;
gap> bib := ParseBibStrings(Concatenation(ll2));;
gap> bibxml := List(bib[1], StringBibAsXMLext);;
gap> bib2 := ParseBibXMLextString(Concatenation(bibxml));;
gap> for b in bib2.entries do 
>          PrintFormattedString(StringBibXMLEntry(b, "Text")); od;     
[Gau95]   Gauss,   C.   F.,  Disquisitiones  arithmeticae,  Academia
Colombiana  de  Ciencias  Exactas  Físicas  y  Naturales,  Colección
Enrique  Pérez  Arbeláez  [Enrique  Pérez  Arbeláez Collection], 10,
Bogotá  (1995),  xliv+495  pages, (Translated from the Latin by Hugo
Barrantes  Campos,  Michael  Josephy  and  Ángel Ruiz Zúñiga, With a
preface by Ruiz Zúñiga).

[Gau86]  Gauss, C. F., Disquisitiones arithmeticae, Springer-Verlag,
New  York  (1986),  xx+472  pages, (Translated and with a preface by
Arthur  A.  Clarke,  Revised  by  William  C.  Waterhouse, Cornelius
Greither and A. W. Grootendorst and with a preface by Waterhouse).

[Gau66]  Gauss,  C. F., Disquisitiones arithmeticae, Yale University
Press, Translated into English by Arthur A. Clarke, S. J, New Haven,
Conn. (1966), xx+472 pages.

 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/manual.pdf0000644000175000017500000206371512026346063013736 0ustar billbill%PDF-1.5 % 161 0 obj << /Length 454 /Filter /FlateDecode >> stream xڽSKo@W19xfޞ(j U`'r.IBYYk-3FX$+L ʙ%h+Y1gWrx9 lnG+=C.4?NhӺIo4P:FHCwRJAt ηS ĔHT.x oVx7V=rճ7`踩r |%k4f틙gI^ƁE>(Kd)Vp ]E! K֊K6|02( Fv}sjBcxTK_V|,w:^']a/ƫdN\d~:vń)> stream xmRn0+x=u" T==e uD;Ȏ @p8 'cZoTFR\%2L0eHِZ|xgulpc`lP=p}QoEP#WczPTçb=~x1D|*K H[·jD*|Լa!ouPe沌j vRuc endstream endobj 212 0 obj << /Length 1169 /Filter /FlateDecode >> stream xZ˒6W$\&GL%U3Y0n ?,elt=܋s_‹ 3Π.Pw'wL;i^`'w_|i@gBьwA@5ioi{zQYMn5WO1/vjp .yߞjm3Op;+R7{7!j] q\56wͫc }"B'AFyH8Vֲh0njb Hnd*(i`ѓH@7 Kk"CFJtl[:HvtP ~aCH(|##K\ f6hRMmy>h]4ʹ9#a OᛉYEKʹ˟ͧѨHj]Ho5T&92W:͜ee]WTA<6@6J5x7G[5n*R^)ߘ"#C Y\\.V4.#R!&ǖ:AMOP,՟kUWj>.l1 X-f[qPߢOl=9œ26[,Mj^.9RhB;W$i \&LpѶ|L&3H4ۇ ؠpT.xrcXqqZ6&oXvZz'B/`L-;]7u#Tc &SK{+@6jeɎL$cAnaB6"6M2VSʼةtqƬ4 tpb*\F4p =c?B֩|ZېOXI\v2]BOԬC `blK D4^dw{Fcǧ!vsq4Q@wd=1΄)#[b5Ww?_K endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 806 /Length 1938 /Filter /FlateDecode >> stream xڵXsH~_яpWH{4[ ";6=Uq$$/eZ% ٪8#zfZY҂YO@RP$5II$T|HOJR~)!0HKưFiMF`0d=kBdE`‚ 7d5y y#j[P!,9I32h/ L: @<G`P J0@N ,$I Фt0P( }.a<} (fFql* oE`pE@r.S=zYm캼ZvqXQWSv>VG[*txƋ#ᗓOH%=s UXǶ\ '}Y_- β;&/xg`v4x^'~G^zQ]gSҗjBrh٢_L:`NcӸk%%-GUʫfpoʋ8QEJQrPp^EU>mO؀ #"Π=P5,߯? ;ηX1 D,ڴi" n+ob qVd-қHuǛ:WU} "qK<*UGmY_f6,/z~9_:;; bR/̝Ȃtvk@cvۏI_x l܅(8 dn7 #ʞ_ͻ`[y|芐qr]%2٬.ё3]'ZG zZ\&qLuGG*>նz8c)so9NqD`PGН:[hVw ~G*8W/p7'TCn2wyw5Eb_WٲǶ,D&Ж:2kG^aXdJyMb$s/dA|w% ~k_mȴPCLX~ hµG{p1g7~nbHK1I(-Yb}OFC 0 p4FPY)l ?Aɬpc< endstream endobj 224 0 obj << /Length 577 /Filter /FlateDecode >> stream xݖ]k0+ti3ٚXGi=(]8%uqu?)m2Ҏ]a_=9B ,gxv H% $m NSRß׫Q#)V\ 5"P?3P`qtsZ(qV QZZ)#^ÈplBƒ_jWyl]POؚ!8rTX@*0uc 欁 ^s@i,7n8^c=rQ.Y!iÈەjM/;O RM܉xuoenLҽ>14-uq:ꥢ141?BNM `̌9a1Va 6{6 |UIu&[jmb{{ǥF(he?V偔oFŽ\T p]Iҟ^_0ͯo&}_ _͟U|l\6Ybeκֵ@Ad`oմ77  endstream endobj 235 0 obj << /Length 2606 /Filter /FlateDecode >> stream xڽY[۸ ~ϯ[噘Eԥoi$NlvvAxl5%=#$A7r_^zgFKEn7Da,Ln/Sv\i+/73PIT$UlUy芺"YS|)Rz"L笨eK\=}g ҥs^JYac<=@8dGޢhi߮~~RWT9g CWՇ.[aWDV cL5yNElov;h&;!4IƎ䷲u~kå% lēB@ );ҝiNxQjÉZ77kSݗ,l\g{%Xh|*&+XݥMjAHN !6WO(x ~L`mfzK/Ȕݚ"wӼ =?@*tI\Oي %[#  8n*#GȈmt;7)7hA 3KS鮠i:f;R ,\ŵ뼴:}VuPt08pB.'ޏ#bg$/Vk-[?bz3#=1ee[R_2k1kM꼌&0O[kSEg=Bi%beע÷Z~~&2pݾt0YE߿}[$PMכ=6f76xoP=%aeHcOoR>IQ"J:U.J4r(uɟsk5ʶAדn63OI͔:څ'Tr#@hs4gm uHJMsϷP"'1kGѐJօeKt=NDƷw} !6ЀAۼqM|Ep('q~OײoSH4n$l F} ʋ4Q o?zT5[{IˆX7Zp-V4G ѥ}S$GYCȍ+a`eɪ$d@kx8i :ێՇ  u}ht{ξ &̟ ( [IDcWffd{ue93h6nQHEPNߧPt3P40ydRL_a.Kt`,$GJv"$d4= $ :FJ#e镛Go|4(X`ώ}^ft O"#cG’4>&X-M/051 fk6C~<BM#1b|,7v@/k{ .'of@' *;;4mx=[jjzs2q'eh)$h{`7p l0j"-hv` +r#tlV= >l aQbtId6Jx]6|׶HXy8`d>/&|n;@f>TYVE6lrӄl;p=H,)>JWd4ۼ"ˡRp&+*0RuY j 0T@f}s&>>ʚ/gGSCtQ#'Lq &C1I i'{Z@E~IS<{x2.~z‘Tp5Q7Q% ( 4K<"zFķkh焣TBІ$H˨;@t6vuRm0GESma[Oa-,iAԕjW&{Y2UCµQs<udE)I̠a=p2 ~|[ 3W=Fܐ&"C] Ӡ""af'+pªg 'QxfJ۹71k;PQ:Tq(AZ]ôl_̈rV?_,xgTĈb^U,TF۰D~}Z2sA?;"&dVo"'N>W߂pzE$ʂfo ?&A_|pwqrn(KPϭcA+J\ʱ&Jwjx"")<kT$/{-wx% tZ=RʘgɄ@e@P>'870}݇!"k;*%CKQ_\|Ч*;^vHtr#;0d@> stream xڽZ[w~`|@F0l:&6njOrv@K͚EwPD+837@&7'_LOοVI4"^2L& Ȕ C廯Oӿ-@p+ Aaf͔$he&oE`b<˛`xoN9/&pT2rrkMCy0%}SÓ: ۢV+'~IgYYNXuޒzT$tw0?&t;fEM"/[7GO_nhis}SIޣn충6ZYMP C(̪==D@ Ak fɇx09F? KU4gHc &t@$`` ǨFIX{5Rcfl(f?||~v*?)Iz̋N$_Fw`#GQ~b+g70(Ŕq!ZP-{v$t3w$r.K7l1I@o>-۱^e˻!N|ĉZkl8J, EmfAls#7P5@7$*[:|f̕fI5$IW"Le+2fR2:؞aZ3v oD2X)/k&QLıõO&0ouv皋lvͯ'`wyϱHIO&{AG,QY| =u|B-`&|bWE $چSl_CTuc9L x꓏\1R," :,PgB!IqpqE-6$! ƀZ=uO(,_{;|AƌPaF$6_r/P璘sPz-`ټmqS7;K%:I"%pnpfNrE hqeE{wn- _50+TmW$tH78 !m=c37Y{l 6WLh,_t\ Zyςmp7X~0KX x|=ə*jg`КDž geJ+ ;-q.;NToR4^- Jl9 >[e%]:,NYCd-ڮ;|ݕv ت*D t<%;YЀNY>R]m_9@.]E5vس/ֆeΈIl h s_b2ćWgX6qz;B75T@0-=5ʄCN~v1W7d$9 n:аztxO bV7UuQbs[JDE^Qy:lj3/;b9ߚy~<-njQNwˬ˝*49!"b}жURF~յAQC%-9eH8il: JMJMτ@ڎ.nZXBCjڃw@`gSI)nYxI <%,I!i@WàQViD}-q\!EAb%ҖZ;vH7Ѳ n}uݲ:<\uaW;C '-T@Xسry#602X1AKYpQ: bs`Jk͊w5 ¿LS_)Yk;UQْ^3O/VWOE tLXT8t:ϋk4g9pkz*Ihө+HF ʙ1q|քW%P('QLJ;c8ҫJ7jVf ~TIj >cgOY዁1TfQ(5{+IhßW TؾěVoݜѨnjuW6622!sokQ!oj8ܻ7k]7KPBǒء`8X(#Ƨ[kav$C%L4*_&I5`bD0́|~{ob(7r 0G6~mj@zF@}rc!` c4'MS-mz:Zu$MuKJ9q7Mژ&r-S4¾*7#:p#{/R;kۓgP?:Sx̔ܘ)ghrDoGU~SԿ"1ĤFW+B@!\)VVC zn 0 wlLP1]ےx4h#hBq&–ƞ%QxHE1+:1n&0$}k*RR>#EF7nuY)VgWYMg`,F=E0.,,\oJMv#ZE 8Nh: ffŪ!xP5"_++fN[Vef9 (/Z'yS%k1/'{Ni#^ap"’1Ԕ֣Ѵbˇbݔ~Sp&/۩Itr)w [mg)dZwptg3>݃ tWLVL!pv6~qU\X?ߺD3m"}F`XǜM;kOq*$9;|]E?|Rf)]6Xp{Wڷu}zqA ұ'[/$3/ҁ=~lԮ_X|ߠUw,/ZU#M%?(Zq`vBҙ9Y@b!5,lz]eEyP<&޳zU6k3{#߄K?]n;1I, ފUOTy% endstream endobj 250 0 obj << /Length 3141 /Filter /FlateDecode >> stream xڵ]s6ݿׇ_߼{{u0tmLi%xQe 6g0Ѫ bn%,.kwfM<O*F0<A&pk)BVy]uG|^7E#Qx UC+DߐF7<񿻆!XEyWbd$LK&7%Աw.H5Tmgy0riEϹ}o:|#kpT}'?2- A<eSuhԙaMl#ӻPvm?͂?/wyC) v {D, 45Yfr-JPN_U; Jv \XEبWG>4e]pxࢡlPAx袧 d"ҏ1=: #JzŦSx&4~Bȣ{ #(d@ lO] > wk%(k'O&Hp;Ez@2q&Cn@mk.;l~x8$.SG|W1#Qv;X}Bb=L=uBCA6_ tŠPPEួin,bI{Migm]:(!NX!j_6m owB┎:TYʽNaYAv1U5 a~y~vV" G#æ]LjC=Yc3j!_ .F-Ae 9-g,ᘀ<8AcU$oƀywM5@s<bhI%z^{UE}3,].'LjvPI_Q'aɶGmѸ>aahG /l1j=Hhݚ[.2[p%O=4I@OuN^Qdga7c\ʹ cæ3P$0Κ9|=TOix\8HEg/c;Ca!bCZ<rG.$'ݴ8ptqW׹Yc{ty]]/ub3| V)&~Zy.ؗI Il I6_ y5{U?|3-Fٻ: ьegzD ;by$>Yզh!SuXȷ-k cs=t4Gi!Ax]U[fC'w4wc^''=8 O|G36 $d a;y&"Ihc})He?m}=#y g$A uM^7>~ݛ bmlW_\rd#F\/5PzRDHF5d\i("DZM_+8r .u:.Vn!wVԯ_YrS5v\df.j.OJn{'WOuT2߳j#Bd衏VAiX 4ںŶm]bt2%#t weVPO|&+vB* ub~?h}Y endstream endobj 258 0 obj << /Length 3414 /Filter /FlateDecode >> stream xڭZoF4^q|NҤk|h8mL*qwfgVv#Kb.w1{wNXq ;O%J8tL?n~U')M,;/)'  ^"X(Ƴ{fL ]zNCKE_"(L Kz]S.BR|V5 D,h1\i2"O4Iv~B %H)0|ZdQ !a{GR )tBa_^~5Rח״9vxʺJmkNjI4gWmD %ã*RPmgWc^VSFXAgElϝXtu9Y+;>?&oo[/xxy>t[(p"z:sO#7v Q v_SU9qOWS%QTLoU+g;PBs<@)xqnf}xb2%a @9bzϛ~WޅsL]H-BҜ_ϒ4(?)&؈ Pwfՙ  d%pEfhcSfVk ag.0!Svv f=.. Ǔ}3cEK︾:R7]?3}GJB.Ik~_[%nP +xev`(KVF}GfY&Tg߂ E;jlݺ ؇޶EiЏFo۾Qͬuhl|Ɲ5]oy]]~nY`Y08-SdU[f{A3V&;Qg2𳅛"O1* )tFj[MlZs':nom@YY.X؝e-M&0 !:W;Oj>"hAx<]o5BWtc:ge[SϼnۂѰ{d0ͪ'98;fM6|(=x%:ڱzL&wK}ETd*nt jc[!*#1jؙ gK$nkt vPtF`5t&B[Fu-1xQ|u ?朆=Hup7heQp &47mj٣WMFR b.e&%C)kݖAQ4ga&|蘐d]|2QӼK6C*,qrQĈt7)CJiNǛLᠵ ,T0=V XcE}ӳZ[ǙKv;)Оw3UWTV0NQP97;$Ak1dYۀn!կnwcoQ}K96K=2dԄN"De.Q;Mr5mӗxTq ,!JVDG_Vc^j@fBfe!Dm8)p:tܤ̨98 3Xg&]ƒ[Б?o0>Mu%ҁgbӆ $Zx%D:L,,[¼^Z` xcwV6ar&.I/ fsb&l]I<\2hB7 e6^i+vڷv1SN)1X!\ƜTB';лxA@X>P<)^q 1vk"/R \-@b[ӵYbG 5H(Cb6_K%C٨6z/N)֪.\P8NZ߮eXm#Rg -z2,۝T*H܄dnz[0O:Kp*`+l7]gSa߾jh1KS˷}5&o PG?\ {ܿ:}I,=}wW}{pƗ> {㦘%D)&n1L9Ĩ~Ju[)}B-j/1 'Y;r_]~Y+.<۶>HOB}Q/sGUTrr޶Z}6 ˮʉ:{q1+@ 13_2^b`߿`2Pݪ|g{ ,> stream xْܶ}bJO܊"@JNeI#nJ~8䘇G ΡUd{m?8;NGD%i{eJǹkׯj;[=pg`'&QV 'h}7Oo*}p ,?aojkV[s8$ Ub3ޗK/D{)"> Vm3U3Y-^g'v#$cC{19uPOڒ6% M=M-#Ip ,:R5Fұs\F 7aW@|SlBq`sy,R hxes;U0N)SjjSEY뀀$1 E҉eI3AT Og"~Iz|8䨨@/[/?=X^8 "e¨lZbҁ/(3@g;!u@`_4cD4wBMu0WiDZ$\mЁA":Ѥ wX X=o@2x|+z{)T$x,qD%b};.r ͲXGxj23ZReFF;|_f %Cd`vm$⋉Iq"3y٪vEMbGl_0cI `T_W뻁GCW4ke 2# Yٟ*8km)3sE R,G6+KV6;o1^G|Vq#.n\-̟ﬖy܋lj`yq=ކģuoC:4bN^p0x5O88 V4-O0&F~6of+)@i=8]uc=?46qn7hSѓ/F0UJ0 g4:L &=*%V>y>4\8ͦ -:XL`յp:]BD]5o&ꖿ[ؤO+|@6{{XIVp2ǁٔ2894&ʹCmd)4ӵ!aLޮ S:`괜$y( P1@+*ּY}H[a]Vo7) c 3YK?IFB&>y(ϰUُ"6?(ڨWלEygQY `f; 8gO{AŽlơ q؎̏{G C`fװvJ\ag A l B`^,U'ʊ+|1`,o1"}1-sՊhq`o^Ҧ)_ʾV4&9& ][KM)r&x18wA <"sc)D1EYVS9h(U0ylwXU^wm"O;"VQ: bn,5{C zP|pk{_}j`އ%M]xt@z;=*Eoɺ"K@ CZnUBuw-Zl@l͸eqM3.\PsQaGF4kz(KUf NH佟L"~3+^v>7x;2Y]K%:W) qs9#cwg3֊lȌ+[V`60v!'s#@}Esr ^6rBc-Ć5ԉOa|`{z!suA>(IZIP'R#'E-#&pL MHn34{ͣ(6'xu{^)J塟XFit[^L^>$9z7rr{ J8 M|p~3k~>_ J\Q i.h)Zh,fiQt P؃ce ^l@q}k]`;!ne>>K ӮzǷEGr>`Br}/OGa(SRlf LσY; "!dk]ϲ Y2,(xqcSq^ 6\StkVXГy;&I4RݎSC2;i)`GQ_VT) 0Y`o%?fg޿5JЈRTMr96N W4#x [ut}gH)j᳔Ͻg \.X݇́6y)Cc=EWH =c$2N0G c BlYM9&|,?, v\ g Rʓ *Q/PК| :?NIy9̅[6VHP u#'tr lޖ#{HsZS8W5oTm-'>sƖG]?UOqǹZg=P%l?" endstream endobj 276 0 obj << /Length 1871 /Filter /FlateDecode >> stream xڭXYܶ~_ʃ@+J%ٮd'$?`I c9tι]Ƈ2+W7o#HΒD`qd"HEq,cz7fsx(g.~[scf@<9DD~lg[2l};POI7oez(J$HH+_~h Zx| K/U4il,d9ힹLK8Ŵf6"ǖ .T3BC4M-oi4}Uj[遖ڑcJCKSxhnÑYp0/"|8+?]H&_}'LFүqF l6Ox :bGStUh3tk u5`pIwGzު)T*>%,v`nFXUƔP. ˣxտgG[s;1+ Yz7d+>{^ $+1#Ed[dwL<*@(DW)Y< מSφֺ]Um rt0y'Rk,LJr0P raGU;* ;wwi^U 1==/vp:n'SG>x&]> stream xڭYm~Ÿ X(R^)$HH(dk IpzaW䌆X+o~UfV+dU~%7?xLW3rs |<-VQfZK\qF0560  t7_6"]GizH-ooOE_6ua.Xm$"E߯7*M_TvIhqM4YX]ˀ\.i3򩠎3@$|^G:-Z˺95=ڢ[^R2kzsG:Y0["LWYCHQ"\*`7?d9|mtpD8m^c<[H07M]5M F .W5M'c MQZF s-Wۡ0:+'صL IYSnGsiIbi@8 C%DQm=ҝDUWuc}W`$H" L M6pټ E-prBJ3?`TIГ8L;X숸]іG_&B{?}3|' UضiiB.Ou >÷kGhGӜj>ꜜmCY7Sv?qNsx#z6Dksc5원N\Pyޱ]daig#FgwvێщJECR}zmェf1 $ƪr$8)1) &͘>AnN'9L5A38u䝠~ r5,nw€B'CIaw cs%*4{ӫs ta|o󲚉a\C*q.yɓS NNgyMIp4 \VDmg܉ŨɃnDO%gcܙ%1rR#,∄H;W޿mYpko3&@3~!u&|s/d'1)P)nT|%4 ECjԦ۴=xY xqO2 7.vg C-HG:JPk(d\`j]-5|_)uwZlxpb =Գ_T2hIBec7,lf`P)h }) մ1_w9`!ԦcV'r^T ~S:ؿpZbeH//cEXLLa9U5T-S: c597z5W');`^rV7.(R&N[ 8Ԁ1 ِ4FSWD;#g2# v ;~*K SO]]74YŠ6Ll\J_ jQ ?:~FW6gXpîK'nEMO. D@<#``kH/s3EoT=L^r aRx EEKO`0933s-IOi9uͲWlO^9uJ[29*(V[H;"bFXCn+1&aWրUP123`^?SXi|,"EEb@ăwR; /?_,zutٟYA!$=&T9! h,cio&f.V;ډ(<:໷W" g?{P2Q.RXH(;KQZX}%g0|gM۬dPau4a,,qBא[VɌ(TUXҜOn1P0{z0|c0uLbIUMO(/]v!xZSA}s6.$c ~)i!(Tz5QȐCg/ٴk6NNltgwvT 8|y&n`2 F N%LYs) џX0ݖ~?H endstream endobj 215 0 obj << /Type /ObjStm /N 100 /First 890 /Length 2371 /Filter /FlateDecode >> stream xڽZ]o\}_ǤCBن-`." Q[2dv}ϹNݻZ~C̙3$Ր4 ejB1E)zC̡[GaOUV+[4iN:4G|IAVc ju+.+b5|w]MߜJpz7Exk̘O}vRs ju"L?< ӓ'|4(?~ZobBaq:2X,ȡLDi1x1R ZI#m pK_Æˑ{s;\ O G/;D>rT)VgGʂ>^"`D0 X rrq "aKrqrb}}(2oajߕNjp;9 R-a79.ř.Õ3ID|ĐJ (!@rRwNFydd3x*097PX#L4$J17ؚF2oDݚ˂6DI,_T0Lf&D_ ՜7yU}lQ)3h,`5vqob92c-LիF$RaYRN?zk5avR+^]?EBHxM˷^msduAӳ'a=y'_/뫓跓=^|mqj>}>?>4'ywk't:Cb Hgu|Bk)uץMy/yiSP'Dn9Ų9xJ@$d[hL8Qv(0 #\cVh'3!-p﵁̈-1>RTd̄<ՙ .e|HH#Z*(xG?y5`f.<`k-ƣbX)#Dg׭0$x<^AP$;8y1N\@JdS.A.7A {݀n>o>1t.!G#%>C[2w'g9g3AdϠnzd7D_i/09G2! etxp00΀6~x{q˗%dz~57gδLI"$O:g%ĸ;Gޝm/xzXA1zz hsŭ6 8MnB7u$4/ٓ˼]#z RL+vzA0@ /mE+69PŃ&'j--X"=%J>2qgj{̶Ͽ~-M>e'CnM4wH@"i5R}50p.7i1|1vS|݌F{J&R"+''%&$|8*"ʕj` "b=nw5ظ~7v_of&M6)';Og .Wd5= du  AY \85$?Onz3-\律qEoy952[y W"<)}<>0b^|x?,݂bGHoǀ$@c;<0D&OTȝ J$Z׵zH#-&@zj-Wg]W /oDH/f z > stream xڥZ8> иz+ ]ٻ8WNKg~D$(G:ywŋ:rB7tnƮNMxwu.~yVEn,b%L(Nx GJ7}W.\iߍ)f:W8_u]8VRxSygVSRГ,+gt-?+MguE͛FS3nuum^16[Ju+-j<7v #̴;dcuC3:2Ԡ2IwIm II]mV44]C;^i-oۃ4Y%P,F VdtLӒ R.̦@(ruԝ ])wUsZj2f6:_`AsfuBu ӍZAx*1=mޢ04E}@ ijlaY9mзsΟZ*qknDXHAȦs'76oxdWvTVosnñxƿ% @9虝K,s\5CG"$d< 0r|8M>N1S⏆nSIXs.=ga5-~r<_' zy0mtH<Om|Ig^):kU@Wf/N&x";6ۨ 7<5ւ = CL/o?c0fD'Щhuδi-‘ bojHYHB?j#&x=1c4Hz5ؘ#YQoVZ`[BWHl8M/v5²}E=BFncOy;َ:fހJ~zM"5ICy ښ<}A$ !KbVd"C'R'22YPŠLx&+}A@17ΘMQ4DFחWsbJj<¡bn\g 9)+&dxTw6u8TM󂒙Q2q*TvsZ`#=JV;TT΋2a̱\b|D,Jv[ltޱά1aDa}5$"mBB8[tz`n KW7"z$XZM.*-1nmCXruq2!!H3F 6' ,sbn]mtZx4L18q6"ͅվhEʆ@%?yS ݯ{6'8~bȪ3( W``?䙩:(O߄`ڰG=? x-z\ĕ9 L==`4k;XH1b0/0EC(WPd|OFfpCP0& Nʴtuvt\D}1^֤`g6or8 T\>]1h+K#ԌS& 灍Z\W@O^/.VP6c# du=57%:Kf)fqUQ,:q!L-CV0 B F#"*TsWBA#Uh֓`?`fjP*դ¦Pe`<f KG9Q2|J׋<.,ۥX;.J J1J@O'LO2m< Vto#QXXhbśLAr"(r(vŧklpɷfޑ14@NjC uOVXqØߛo)UOz,:;ʋ]OȇxG1ls{o? C9P?a$F=}'e_yXeiR_2jL~6^`XrKo **@}3&kgQzz]=ED=?ΧϕsԏO}Oʿ 5K%"?mf,Ԋt?ޮ"j?t|[fK֡甬=75E5t-UpN$A¶dJn@O3|uf ԿWeXpAB;no!ClHWC"?^Iyӡ~)XI|`E1 L{䲯s%'9͸|)LtuuȬI0>1uh 5 endstream endobj 337 0 obj << /Length 3170 /Filter /FlateDecode >> stream xڽk m2+") \\"AtHڂtz^ɕ\E;RO|~PjV_,*B!Rg3 %a1Ebu֐Q^>fw2h]vW-Yo' ,IU =P' #㑗N@G={q~~b,I(e+%*AR.IlB=쪤- +6^!>e=֚Ǟy 霪3["'t0h 7HGoaO==l u@ q؄S6EZ.{Yei& `Kq`gi:7F;-'oj 3rTմݞ&DY|4K󂐩,lVYjޫ'kh;3J\Jǡ)BhC!Pt 8^RWf1mBZPYZ4;64t!37A"`\+2QnOL L9@pnxI²uS_$ im[Je!BkS_ycZ)b&yI"j4.V ƚs;Ct gm_#/R8:A^1vA zRyHka[b[Nf }smmY8iC]*JxhCE˖0޲-0Q~!Ly&ȗ.L?䯟oi+23{PXkd'"T|=Tu%? yzf7ZW69>J8G}G6mWf4 z!cX|z.a ^;Oa1c V|-c̢WktJ'%DxȽFfIe5xkzD9S&IS%UjEB%MqQ5K,UQ,^evbIA\}hK/q2eÄ S:sbe&0Ö(cl>\ gw`ԜcVXdS뷁n 7pU5V*ʻGuBݛ,8j>0;->'A8P>Xb9jKwlSP|;q("AF - i=+z\.w՜QvmHcG*"⊷I;YӕBK(|ևye>^vTpf'y|Isp)zo<EaZ2:LF =:w%,f`n[3] 4Kz *\%^OJ{AeI#O.+NE`eߨL0> stream xڭZsF_!#}뎦tB1PZܙ0l)[2L=Il yڏ;{ΞϞd 0 4<4&a}_]{_o#i-;#AXHa:N #g))-WƘqSJ~`~`6[Xj\ċYS`[GYez}?ĖRfhjV/|>ZcqY8nxζpg< sGJ-!,E2eYQO0:>)>aڒgialy! 9Isg$ 6|Y ňi̸Ɉ]wTa~d_ǖЍpDI$$!6G8"Ābs q|Pb`|Sſ-cem<$g= y Η? #1L#K4qRxhrVޛrA.̖Qb{ڛ!8)eicX;$mY5?!|*)"fO`zewnT ?_\ [3 &bˋ(SW+:jf#i!܇@"HWf :qS#vx ` `2kj5Nu)RWm DdYpM,hsHb-6Lٷ3 D!7}l/9g YS?-20G]2ۮ+W7,yM.J_3pqfP@bۢV&MڊԅTpԅP uHi~ŭ>iWP0w]xZW+^mcͭ3D{ /EHi"$%P;x>Twh]u[GQz=xnku $6葈#뺍2 kHrV?re2N(8,~Ļ"uk]cЄuG`o1L\(fwv5Wۊ8ܱDjw-q6X$wbR?SA[m+pbGvJN>vn'HG|jnǽoT, hEϜя@DP9 ɮ#kv Z[!X-1a K44~:ЁD[Ac^UMU8u GOAVcgndyH\;4e<4uV d.h_ Dn3aW@*|pgjL6 [/W(懎RmZjELX7;&l&DK].0fvyܸ$͓Ƚ\GIF r9LIJ7vb"uSrlFxYa.0lYD.i֣¿O8Oc]wCA(Tzp1 X-Ŏ A-d@|lt@VSPŖ#2";&N9W @Mp?~ {ȡ*~uGsKqA?oxvFn)18BFe؂-`Y9~`}e_?|0\[]8":߁n; 'ELQNl3<$v'/wÏr{~pN]N.'/Q\>`1l90 Chv-zXOۼ3_"WE ? endstream endobj 362 0 obj << /Length 2183 /Filter /FlateDecode >> stream xڕXK6WhOKUYӗ-{J=@$4Ect)s6D<F_#P_ 3;m HpYsJz?`Ief(nE`ȭq+@?)29^*RYܞ-`Fwklxj{R~nz] P+gE3PdӭUxo5I >+}#Ywuc4Y,np- IyqTQY,۶5.EЙ4/^Lr]CBxtnyg}qd4<H~dzpZ+W9ZA)W6Qly, qvՄKEV[cgjE&MV458,+k ϼWBkO> :uZ1@(^ #^v'Vc'<k)4R[AUmPd\ޜh9Ir&qfѤAӵMQgA6$Lv3'm"ʀ¨`7 A36H撀'g71ĹLEp1#5\TV Y9 kƾҞs1Grt Y=/6p|-~1+iS9)je5pʓ4݃a7@ÿ *'?g"yҴ^] gbq!Y N7k˃X Y x.ad(^`EQk#WW-ZTzsFЯa-"c_(N[UT(gH 09Cc04gVtu t ~ r@mw$&;b_hA}u. ^`&"ؐc:Q̹Uq<Ls jdi,fHry0Q3$Hp%mf+?HꇸvA=Aʃ+hRkZ y"Y(Tj gܰb'qFm(ud/0 Ħ=9\hCh23γL(U<_C%WY\55?Q{Cyѡi@5/ e\`K T'8 )#K,+K=Fˋ  @2k[1ㄣ{^go3B$f,)nlxF @ `bWeWDٱny{;kG\0N> stream xڭZݏF߿‡|W4$"EkCٞڒOoG9dk>O?8,৫Wߪd4v Tbm &ß}SFL~La *a&AZgI$%iW.GmjK(W!AP ls`?q&;7j3HFAy=t)HFT|PH H "-hl.y=wtXPڈu{9m9D@9G#H& #CSH0Q ) W68kܼÄT%=`la_*Kv1_%~ha"7HLHMu6礸S1b#T>MRޢW|=e=RBgځ(nm>_}/~ʿ a3h0Ct*e]8ABgD]>_^A?OEI>*XO'>C䚊|>޼9'ŜœB£ $4W3"kLiIcږ1@aTsC; pŢ.e>- b?0G帝= D>td@͒*fIzUܑwA`3~R{2|ffn122K'aN2- $[Uɮْ,瑳ٮ"7X)ܖhT=2$E'ibiIJĀr;Zɜ͇RH\BK}}֫Q8t  SKb.PwN@h"!NB 2+꟥T}K0X+/>ٍTs~)fhD>"KQ2kDwYLꃺ*kBvγ,m- Lew}_,זua^m,r9Y9]eV6SfU<͓̘ͪگ2#( w$e@(2CQ 5pU/]Ml1M~6,oiX[-5^,}Oӆhz*$?kf-ȳuߪci.7Н.OҜrD.T{)0L#vв)Ѐc#68 z~ԯ^4#iTǦYΙ-3>.b@>6HXmSco,>=}NO']@q?BpPe-BzZE?7!+&PJn: {NY7{ju"EPt9i/L]ўE0e YFNF;ksh'^sYwHXz`)H l߬Cf3ž9Xg O7e$gemق MCeCA5 M?k^h$V| 7ޑ݁-*;oKǾ.b,orc{ w⬕;`]?pOǠb+0KfFQpńdx l DC U4.~h D?Og`Di*T}ոGݥqo`)8㤐MHIMIpuڮ-5Pmmnl,xSg[ܖN7I7ndP՛T0LRR ;†HMG2jgpd6Xϖi)?8sŗ@,&6(:l@Q`OG>B\'8)@0ܧpoE7}L$HOAhRp~ ;~xtV6] 11骜S mͅm/W" Se+G(0hG2 #4GNTyC݂\EJB }h񀸕)F,w 뱼s%ϢE˪L(Gh7~4L7h7h2NNd)O ᙈPY^y pb 4//i7*`|[ "j%O{ G%R v(cހ z>/E{YUN_} X-eSu" ٍt? ?3//({I7_6L IO!;Ks5wЇwftKv%0E÷!^x(2`rݗ ٣땽u{ ~g('җqWC5P$BFAM`E&h*N.C]+](Z[F£ U Sؤ 6LEL@GqCQOqO !NLat_'K7 ߞv*^4|h_I$4[?0/# endstream endobj 380 0 obj << /Length 2718 /Filter /FlateDecode >> stream xڭnH_";M8LXd恖hKE:<1ߪnJh;:>U]wWU3 0xu||\Ɓa y0 IV&0OE%aB% ٍণЁN n=QD~ϪDh1Q3syZ7ԛET o˖Y6-YU7i/ˊVY:W=# $ Uz=-'lL˽Dr3{cG߯eAs !&q!=gߛ (%]Έq'\ZL(.O&i[.QNt5YESY̛[ $nhCK=Ca>zQ;fN7sL}$t^_"to@f(<,<ztSjl|€1t(dq0Ad7v"&bF" 4VXX`aϫrq|"Q tLc YV. +g$m5ЙFP?o>oya TCG| =>;CCq& wϳ}}}hs Ne_ӫa6lMT"9*1L9o{DMY /5ͷ=~$BHZAϾ5aFe9.y#I;\9xd7}HyOzE9L 67k,L/aؚM`AH1";E!VL=>$A$W`w1 Ù 6䑯dQ+.磲o`5jiXZg5-Q[TH.n{UTW宸G9{5pMp?&2X' @ĝ%3y:/|6Qro-7^y81l68\N:P EGLcc&pqWB u8)IdExڰ,FnjYq@|ƧswVvL n,H՚ e1t֟'+K.ix47o2zc65ϩou9Fu'ԻٷS좫*j: ]o ywge3/2劾LMxLvU%얲]dU:hg/Ќf)ʈS,T҉&xdҺ.}0:bbr)fکLAm2Ǝr c(9Gþ^ĸECOg%c_L|2b[zo+9W^ȩw]5`TjP2c6RƙJP r>s7?syrh _΄K)vA~U: Bجq58xh? b-t @ B]J;౑ {ոPsl /goޞOt)˒ }O=zµk"xiHTzxI tiMw!Y4D=+NevzV ]F0Yy ߳LG_|qͤp2yYo&:a|?N /3jng ]E@BLKgrBylW Xs ,PXU&}^ + )^d= $D ˄n'+$fuK^BU])| eu GӬT U bav8.ba&%iG"9V>#@y>X(Q1\FÜ3,mh]-A+&!FǜsT_]Veq`z?X ;  endstream endobj 394 0 obj << /Length 2192 /Filter /FlateDecode >> stream xڭZm BA.9͛4 kڸ8|%ֶIf"˶waap8C!a໻7ӻW bybMX`FLǿLxD fRB'dDKpD DE #GU4#C_Of-|ӌMwQ A@ /aXk&Y;&/wV\2\cUj]B"!@޶OxMIfpz Į.6@0"-wJ,Ӫ-:Y'=\0$k!@{_K<C(p' D(ArP +)#@8*x{޾#8/Wgwp(dE(;eP"$j cm0-qo`Is6ʒ&/LNr$s|.Ð}NӲHV^}D#8XC}(H)*'cxմW}+ N}+Uz8W`xo\/C7)@x h8dOGUǛs˵(x4Pvv xcꁧb@rgNQ 8UهY(UndM;󺅂5g!Z\ zT|wJE:ֆ=q1a{CPEDž/їV9ozWPS€baiiIo.kUl5䱶.#M%A2\ΰP$%֢@e793 !ZPkNӲ\|B]m}3>Oe -S) ׸jE*p=.ᕀzX<?\h/B~1zп# /z z`zaKjH 6;`LW!AA%t-b([{7} 4=ZWe8}cQۊE%MbE(_ uwOQ+9`tΟaw endstream endobj 310 0 obj << /Type /ObjStm /N 100 /First 878 /Length 1927 /Filter /FlateDecode >> stream xڽY]o}ׯc|(H[$ze ĒPրL!9 ϐZHAR b/%PR'/-p,AnB((d;)J J RQ whCP;d $ I$@,u0C.`C`ل&RP!|DoAR.BS'IE )`-L bYOoR 4jU4jV ܵ'I]]ޟ];11 #_T|P޳ażg#TJa\U׾"ւ4,AF]䬨z+޸ce\r !oV!мi`(*8V0brAU},kUQaJm rB*@ͪTTO0_sVK)j^i!7W{K7o ״CQw|. f[T*L zcL^A욆ܼ"R1ۂb.2Ki~fhMwo޼X|}8aC\n1AOqi5 q)Ehu*G'%&bNNKK0 |`ٛ=7Xpv7r:\0ݓ0=_~XC=rg,ӷvyco.WΗ=&W?/_>{N^Xk{ήEp..VV릔mޞDbzuş򪏜^L?L?NߞRpY1IM5UfUjLE#G]*`I~5ھ^]D)}zG+4ջåAA}Bx{\I |` VF'9*B,Y-wsrvS xOW!s|0<8_+8EaOS定!%2;Ʃa!œu#ln? ގ~ fQPnByP(2C!oDr2)ۦ-RxȔՁ  MT?ps!lI3ANٺ5.z%W"xu nqH3C,; <AeHsJC$x(}"͑*L=) é7 9lÐ7 9p!Acֆ?WʾqENpȔ"r1{g9GF{'nzTP7ԍ 峲^Z3 Oܳ$H%!"T n`1'gFN)#I <`Zpܩ3mJ늝4Ô60^ Y q͎wIMgxX[.ӑ.ky[>f[>fm֔, 󓪞2lf]gˋ?s9~&)@+jJc}ͼS?NNAs0@O>BUD p8 W%;ΨOhztrgӯOWLㇷotJ_߾z3;=fc:ax\Av'?%+ ݁R818H8j~L;' t$15,RjzˢiQuRꖥ-KmO͛hWYC > stream xڭZmo_P@. lĹ\s^-Q2TE}gv)ъmpwvvvgWU|+؆<-ac l|rM9?2[%  q|sȃg bx`"NtݖzJ6rYҳ@*bt讂8l1c)a XGaGF0hug`K52+|wی\l31f9goZob%<*"y|jR r{JeY>B4w~yYIVOmJND> 68lu۲8FXf %E}J?Ќ hi͟# 7 `7o1hWB#TD4Z9.u$q>i? !޵V$$+].|;(i}+7>wdPC,._A1/ 3?hh@S@ vEV#T4FH9@CK=̠gd=1|~xW?tUD4ڊ rc&M@Z-ɲD.f. >_fMΤ$Y֩9 2<}60`Gv>L~E~-G_*fh F'CC~c)~<xJV&HII 9tۊa0 `Aѩ oe6=ܤPg~[q/\<٦~v 5 9:/̥֐1x eK<) sH(on)eIA?WQe4lI,@cfF({C`IS#T4Fb #s\e1_ZpeG*"-HUƛDCiAr=7]p`WMm;͞dښaOiž`QIxh))#cc faaFo4}k#i LK/f뫏& T'\.Ӈu?\9G~|W%Ĩ ~0Cn[tS{hEJ:uPh!8|0 Ç!JF0J=FaLJdVf9?èa'IU/6Xd߇&؆b2oB/nHH/8Exө z,*;^\g ){R\!JZ򤮷͹Y=<1a֛]U$D P{$ڤst:%s'ܳ0_သx*$?]s^'ta@LJ'yNs x5+5k h8S1Y1 3?~EkѠں 8PpV3q~A3 #c]^Rњ)ΚZi hd&uis>ɫ/w[jP*zmqODw^MݾypDaԃ%!122?.UO[[>NJ3Yem>6bP0742\V+X0zwt♈|kc)[#,^9Wye^f[.vsyS?wRj\9/(b7QH; w_EIHHtMuK xT5CU0&$9 qf /pt ~(3T4nviDrȫC wLp+htr%=(ۆRH|9VW%³0V)}{IΩGz#%d7K)fAmV >$&D K`ukZjઁN&FEZͷن?.‡'~:F(v9s 7N~Y1wL`)pg.mZ\,.sNӘ endstream endobj 437 0 obj << /Length 3220 /Filter /FlateDecode >> stream xڭێ6}bE̒E"@4S$m6q]}mjK^Injd2OfvmN.&$L4e2Ibl9%ۗ_ކDp푀ٍ!MW܁|"q8/QR裈L(֓K>8)X*#׳+nfW LR1Id&/濇"N>]H1N_fZV! E,tVzqrҢ2@!1OǣOZ x&}0$d:gS@8$, @BN-A$!7o0#zH7oOi*@'HkKDG@IxZ6y}=40[3EC]vė$(CEsyAfcꓰYH7eo@ckpfjLuIʴ|*ocG%EQ t%݊ٞ ԰c t2Ev/Żq&X 4%/jS55%!(MQ+ыT>QmY|Mϑv拼*eDԴ%th UnK%_y [gZ&=!pmEO"Cal 6H?G蒈q,@#ɩ fJ$=rI#D@XqX*cTvrhZ)de^*kFP}K9QI*^9,։b䗩͢xmC!:Řƃ׆pꥳ~0. =n} ԣOX[l bQaL,H͌yi}8P[g2ci2K͆ӭ8o!iZK(e6=G˖l/sC]@ug*[4FꥑKS/|nTH?7#32,RCVMf":w`шD}ȪXvr ^⢵6x:QDaJZe}(@sͪ!ԉ4pŚ6~Kzoy4ǽ!{N8SIB`ѓgr4^֟45 XTMVH1:ŢM*W>#3hT yx0E} Ub}F R\$ӟ ir9ơd>N+f^r/Ƌ) {NKtl<<P%Ks|0F: >xiFm'!8_I<4AYD$rddsdgniد|zK;Q2l a ѹ0Ye,:Y~"a"VÆ̀g`LWupRQ2@uXA!Y(qIyhk1Qo(Xwh\JY+>vk e lfn5{hI]<@b)ҥa?JI'd]U @1EM躡U-.xٲK.[`=yQGrdݚ x]`I@YdePp2HΪ J*_d.}[&^o,W KByqWnA!s>)?xBX Sn!#/T9nx2 Onx^O!/?Eo}MO|6yϵЧSrΌ#h)}ӧ] AcZ9qemȶ Ҩuo^ cWHL>yp f1 5N|[MRGE ꀥɖn;ZBusUg&2u۩W qrihyeG!>=GBv3$ BA' tn+p2iFC?)|: \S2,\"τcLx1/f/owo޾y b@Nitɔbsf[i4ǫO&W2e*~"_<5^$< )v`-vFrE*2^E *#CCQG@|A+ιO5^E`@fnp wao}'q7j4H:Eb>0PAY<!o5o5FRƁw9 |s,2TҊ[iږgC,/R/\<;4.k/bAChH endstream endobj 457 0 obj << /Length 2417 /Filter /FlateDecode >> stream xZYo#7~  -"c73A6#`&yhKm[XYZ`|WjJH6X$8{p՛[3$?dT$ʔ1&4 1RXr;jfex|𪻶Rl,n\|)E]p1*3Dx U kw*&n{ch69bH4:ȧcR!EDm+k#]}b8+^jʴEK Qt>y wc%pZeal]C'f*n.070ӬLbpH} -̖9e4!L=,&ϳ/7]{9@*۬+ߺ/RNkZa|'\% T }HhaU}M8*9x:-ot,b` gdx6[*4Ӆ;F35HCHu60btlɛ[bB| k!lN_@ 4$UHcM>)ً%6(γOWAefcjaN|\|9-'hZX5q @ vׁ1 #I>8hӓ (EL I؅ppױie[,, ${uȣMRB\:էm9'[g)@*"4ًlv @Զs  !"L-H*`!h`AM?&f96U6b |AXLRaZL'# Y+cyοV UCl뎤Q <4Ҫc$oH;p/d~4 w^w|O<-p8f+m`Ld3a=nA!nGxOr9ղҧL٭V̇.:x )\Fvۛ~{y9'SfDtv`PQ-ψ3wAh JdAd!u &`G(ƈRyP!"FTK`27$&ek׃l1cm6'5>~ }7f] pMMwnswkon޽PDFɭ *R/&ܬX>W΄ӳ"3 L!;Y܍ي^(gB6Iמ$tpΚm39$c&︊ kQUN_a\bM!#N 9 qrVIZK nQ_*>7& b2{s3FW'+_fъw2pMU>l>8Mg+GK'}S&er灳X;aUe3(?*I@c/@&ć2.ʜF@1 ޮU'>&wSnm{)YSwYPz` @5Ш ΛN U?%H /Āh2).O NG(aRgF@nqU:1 i5t,٦B~ɯ2~Vol߲CMx .Ϊ!ByG k%G#aY2AW [F@jh7Ӵ3#ju-ZmXylkqOD1G.(Ƅ@r*y;.,VO R&87:[ ?<= @C[ɛIM]ӏߞֺ^/Z _yEYC< n_E endstream endobj 472 0 obj << /Length 3076 /Filter /FlateDecode >> stream xڭk۶ f:ѵ74߹ǾtI򁒨cTI*g㻋_;F xpŷϯU,n cftƔ n/W/޾,旿~ZF,1MWk&J.:S-SeXd--zUΊ| X H&r"='oydSL+7|YIOMi5/CƋ%+fG ަQE,ԪW)I~蠼 ^]8I(@xv  'I#/,[3MY~7FTs%SP vUZSdjl̏yDEQ)r'djɸR{;Mqky2fvim2;u8!QRL@^ynWliK01ghᓪ%Pޮ^L/i~iW=*%Û$B )X>#5 ]P^\J3%P<PJURCYM{χϽ y_g{γdMY8*SE|qy4IC#4_8pR4J>d$ JTl27i*6)dN%4tʳ9)y{Y^I>Ox5'7ɺ+v8q6IM f^Zm{5/5E:,6F6AU &ϯƟ~_m|=ۋ^/2HO,|soL1 >Q|H".!B fExmQqh@&ꋫWo~%6 ۋ>?9yv(ѳ<Z(N%Y(8uD"#8zֻ2vu|cojq1áDBn'qdXubxn_u??4:(Se}/lױi_!WR: ɗw뤪ӿ{_u>.?GZ<ӑaZF{q{q:kj~ j7W/&|tXxu8ݕۢiE),yђ .q}6q2vTylՑSvSr>C1͓0!h~@a@>&rO I>j^9+EB Mb}`H$vUCJ.%Da.xiW78*n%p&e3]ڢ0#sJjX\c,O:rpZ,p1WeOۦs }'Nʎd" I{uϔ|󨼰ob'ꕐ6ql((h4njɮ.6CNKq{XSWƼ,*? $TUFL郲L+vڐ6וP3Z`nW)pp7TYBӒ85ӍyJc5S%Ջ%ZuWqB*U{ؒӧq'/\ZPDe8e-팑ϱ"pHN  `ڴHAXY3?2U@rr8jn*f<|@ ٺ -ﲄȐf/#:Lj_&Bd̕ ,w}w]cD>cyt4,㗤ldf^5)!&VUĔ ϬzG5yԣE1[Flȍ>jm򃯠H-~ T +Ut2~ÖN /ǶYy5Ī!p -Xx0bi/y:7Ə0ٰ5z,Wb{hԕ G20_g}@/۝\,4>Tb Bկ@߇ $~,,%dQxe;X08[kR(i,eEIymYb4"_cǯĔFQMժح=?E:m ě|Oui]dҊ~|\5@mox>p*m8V![B+j@tOq') ԚeV"k8~JS6/6ۉ{Dvy Q?pÏ{.[F[<>\9&'k-vrَuIt6Cc'xC1()'K<̋؇ƸTL~n4?hg^GB~DOΩ/1 g3$< x0'2e[GB/K{_$ۺO+,R)]XVhDؐz>,Ɪ֝O $ 3" ii`2^VВݬ ?k]l1@`ΕH27p;DzuX ){f{YоHry5k1H}ཅN*}aD}{ /P:Xay $:OA_(4CGhi$=3wutN\O!O> stream x]s۸ݿ35O\n&$i.qI@I͞D*$u뻋(Jc<b_0n"=ɋKDzI2md їT׿I$8KyJ˕R_\|;0䑈DFV$L'*,N|~8Siݹ \-XjL4>ND8JYNV1Jxٯ뛳sa]>;7Ҍ~t?>]qmd` }8Mli-Z,/n8ELOW?xh)ŌJ,M k*"jnq}_ Hb mќ+y˖~ЎVM>%]%32}+Lg|U9tObΤڍۊ2{ j?fJw;;!*,"![CkFD}ֶu1>|jT2ovhVN \ A" KAAPy 'YI_@ZFG#@c7l#ʂ#jHO(aF햩IJrSx8 8xe̤P&Nofz:dFY ]ݻx/JxxvV4XՌ[#p۰_㋄ԐĜQXZ+qgǹ€զg|^CKCoFI5qS4It'CN ª=$k *Q,NNˠK Qh| HpA صHn4wIνG|B0<"M;Թ%7sg|7tpnRWY^ #6/N} A-CoZC\YzTxWaF[#hZMqVߦ.oucO]]mIfX {p|gO]ۓhS q&|z{}qTȬ(#(!Rpl`_*o+jy;h6HÁCfjE-C҇ Mo&^ĚYwCxXpMBM4/d5hpI} ͺ ^a/j~s)yc$X j 6Z`bx+벥QA vUa0ҵuRQD3K<+:oR%qbe^`Vƌ/6ҵD=˺ZWɖi;ڰTۧбU n|W~:@d 17&UbŻIW|?^kO;],TÒ5L',~wyTn@p0ũy+I:H31O{:]4d\?j?-pbJGN.[l- Qx~xk 0%MbOGnK&zx5GK|W G5g_s$dXACY PKJuf[="f1'6teQ(Js|7ofACBK +rw3Ó4@ zJ+?TAǵ0W-V*{ACi&%q@rSA]4@9ry~.u|&N.0#&Z u{ Oв|)@?T׽Ly; IHGD$#`Z jqEbG t+5OOTtY(/R)%1U<=T9] ?'ga-Ui- P<44=T9]e\0qw,REU%IAģI;@R%1d|d&7v ThTPF?)FW)HPB4vEe ]Y endstream endobj 499 0 obj << /Length 2092 /Filter /FlateDecode >> stream xZmo__d 8 M)v]@{[ږϒoK8%<3*4yLho㋟oM qdp㈒&1 ڄJƳ[C1>7&G].t w;](>LTr)Z^7mO#ҟFRt] gbm&U^GehΗEA,4?e6*sT ,ևl#BeV͋YIFFtNp`e{7orb:%zŔ\8Ζ&٢͌L&UG*&*'@D}HhRm/a[s(oQUO&_TmHXPx;MfFJ~^˄MBLo!p 4[QV}a3Y5 "bz 9A pkHPKYmN {ќN+UXUEk׿IѱX~iv>MD> S@0j2i =bXVҽʰ+$8Q8ACԭklY&TN/dNMX='_`eYP ahyz!#p]## endstream endobj 513 0 obj << /Length 2155 /Filter /FlateDecode >> stream xYKoFW0ȅ~w3x=vN&eIDHBRqߧAiy(q=`H*몮q໳\1()LC@UW@c"-wo\Q"9vF0Ha:^|0 #:ei))-'S*E,UUkLVOi樱Sh[=TZmOUg}xZU.fKqKGsB^2A@M* J-~3wɔ`f{ u1q4a` lvsG~$=_.:.THZ>p9hod鐴AMHx} 6ua[8($'EZ_zLrE=$ ~}?^vo+"9K; խ0ζqDW V nE"&?Y&mN)6MbmlwJZkQ,^biE^H|"W{Gtg(eʔ@ "ӣ|Dq4)C~p"XiӪaXcZ#.SJqJ:ADm吾ƨjD#۩ޅJW:k`EJQA۲tݺ ctbEC#ˍ˶@4МxDgĞeE=`@s?AvoKNY8L&Vd:~ߚ oâ (imXg3[M1,fXY1[qm ԰R{] bkѲt1$bBt!$٣^7kip-wk. '\Ѱ0@6}<0T]\иp姲JV^W]៝@"}0kQ26i7vW 7zh(%HBvq5&mfCRpX XNE3g2!e羺~)&_JIJY`'GgslcRΟ:qGlNtw=Tn j=*{L[~*d!~OiYMZ>}100;N[-60ΟuFA5pċqgkii]6.U\|ܬq)>tU*-.]1 f]v2t-,RYl5"_u; ϽJ?T*89PND>aCvtzs ^۳OQ!G]!UZM}S ;;6 cĹwb4@}?> stream xZ][5}ϯ#8/{,U}>j[{ܛ]vnBԕ:x ~xf :l.w{4_ܼپ|y3qTW/ܾK *[f+e1ڋKtN?ÿآgOJSs9+Ʉ_j6ӈA_br@M4p .kЂBAɼOm|&0=ՠZ xtSZ\W7hj{[遠]@Usp9(57 ϲW׺H,dž#Zx]B#Gޖ8nPO8.ilC6(G8_}RoH~#H;`cvL0{\q̰ ¹a#"6A jA6=e\jAMoI]l6i\2 ؋j& m Xr*;6{fpUpHܵ6YRqؿp>4R®aN("C\p !.8 q\J6G t¡  ̎%0Ǐ+iWNJhZfky>9R|KUV冭* l+q虴[0%J>"090nd۲,N~4{Uw~t%{s=RbBd{[V2J8ث x\1 q'Xx8,c%C [9m;g.IkqS)h\b@`](^̦! $8Rl6^ST9"κ w\̆8kP8N>İ#)fazy+/a&m<.y]we'ؐ8scr:R&őP9ʥ%L;,#[##VPx-uZruN{JǨ=6r> stream xڭZQs۸~g"ɥK$%j;fJK͋DD*g㻋(R"U\.u7'?ONM$"\2NVqk:̂ϣ7g^&<{-M 8KxBC0eNc>9D@"0$ ba2a0]|3%,LLpkG.p`FaB}^fӱ:lmhW)#Y$QDLrEJ\_ߧt,שrsE_bRRS}7H/y/߯ DWn-k1SgQ|~Go.iOu<~gowEqN :, }bkp|{:L`q`&# h`<<~̮zly ļ8=ge.y;! cx߽F8F,/Yk8B}i]SG:s~. QO8m V|ǐê\>3X^ۡL{%B@*f q6UrVU3Y ȽI>i(|֗0a*:`Ζˬx)Hfu~ XTQV :iAZe\/%o z;LV$kWʞB'Ēk^\kH耍UvSjegM*%왔ZZ J$f([}4Q3Y44-q4GEŎ% u":/qCEETQ2΢ }]q!CFW动nS˹_9aD Q6`)-z Y!a^L={ f/Eg{&#>zƕ]+;zϋ5^M^ycH S1"uM[Uy^vPH!!;fΚ=%Z}cՄZ3tNEY$"-E&i 6Z:Z4ֺ-t Sn(d}͆.O.l@1jPϰJ| 'w"ShFRF?NŨ@C81YI "}ԝJ@Av(~zbhDg/6˪)D\B}A89\uPcc,%-]\a%GGb)0ˡ΄ǾV~<p>}SO/Ӡ&YWː-9kF[b.*-R@& Y+IV5w8۳&n3 53x^਴8޾H2`S܁U wNrfAcUo(Oy8/y%^,+g8{VWgA%UJk((+aJgۋO*_qu=PM q&pZ[ɣVJd[ԢU"JwC-ǜv7cpKmF/ft7pf;_9]^W% <[4!FmK]1 d*N%P%U1z =)=+8@}ZQn @*}@ç}֣!]pR:N!VsW*T,W-Y; U@I !6r ϛkW]홯S hSW7LUP䃳ḩW>h,T ljLjar`#u  /y%z1$93Z=NR1'}y߲pGՃUO!L+m uP=z;c\ }QYG+)bͨ endstream endobj 539 0 obj << /Length 2878 /Filter /FlateDecode >> stream xڭZmo_P*"fߗ{=k5h$h ˤOM{gvoD?73\O瓟'_dbcg̯&ºX+;Ƥ̗ϧ_/_dY옣rBaq '3%YKgRlj1j~WәHd ^kj\旫^7S=":/*gyϊRW21&3SQZ|ʣ˩`ѦvBن߲Q@aQ6̦ȀN;5t&VeydQ^XJݟ˹'XDt83?c Mi^UFt꛴ C% \%}Qْ&VP1%Il:՜SS֘pwL*c6?d}=ֳ+cs=4HA sCIh} MW#Se&[g 5˼յ&w:aKy1Ѳ\l^Z.3Ѣ\,yqMs-㐠'@ظ=GŜvUE1EJʘ 5<ꡨOc [SyǥG%4Ó{ cư @=H68+u3;ًG=]qvGmkp2%TdHV.B;ÃYڑJ;Svɸc_292q[1~ m[4A$A"L Y^ ԚYK zp0?^)hH3!?Vb&f`>fp}?Ǜ|qC6X{yQUkHiCM!ęB?D2@c paL!+`EiWcڀXɚ$q":>ޑeB"4| ;@/lu=7"0Ro];x^'popq™u -B_48<Ww+ouEY- x.> 4%=6k ܥkfDŽh*Z4WU{SMNN5BuׄLGs[\lC,ϰ ;d=Wud RnAÆizM1o:%OgDeQx̍ pFدP#B+?Pͯem^v.Vc/7xB#ZR5VK7uyۨg >q~}$wjq'GI`?ttA FZ[hmʋ-ChxZWVD\n]d(rkŋk>lǡ M,#iNB< 8##H4L@БIV߽|!qPe~5qLpvu3@QN1 JPu5FQ|AP4áL"˖UxhE`"==hG)b) ;['Gzk(V[0kz6BP[3WGVo:Cȩ+pIwX,Hr&Z*f2i4q~mn_.6uW\@4a!%N/?'{lϞQ}IK yO|ηOxDvy{/V@ ~ghrN)ߦ#hlX;{LP>DBoң<85~p$uvXuI3$c:^g"+E!M p )M:'pva ,ƖCJAnjHP׏σ<$2z%5zW4㕁&+w3j  o@/ Y9&IaY VթF)_gwݟmAw"6|4b8zo6G( 7[uò*"=ԯllY[nhn74&]dO5G5*7lQjM(*k_ͪ&B̓ۈ 3[aȷKv[Ela]H{ N2c$@${rV_}fX;"1>KQ$z#S7Y2Om ;XMM|b|p&DU|ѯz-Ű(iưڧԫٞJ#VLo{̈́I|Jb3lK +[ Pч<z'-%Ҹg]~?ZLtQ߻Zv*0xX yϩ>1<*LO BLq ZCze`PzuXB 3Wxr?-X.EJ)=(9w&:Gzz뇦^? endstream endobj 553 0 obj << /Length 2462 /Filter /FlateDecode >> stream xڭZ~Ԟ6-\sr9qc-N%R%);*wfwI=H$QvyofH97ߏo}-L(,?p$dd{je2I{ĥΟ\g[iC0q(!tj1Y>.#F)դZ5N@/<4d {zLK؅]+V[vP'uY%!wȧ'|?"<ϲVΖ j677KCnB>^^^)+n%>ZaGqM$ $j&fB hMwcÿ7qCW>}ΐf3;/V[3EU4C"Qkn<~|x/|l*hUyf6 <3=Ci$>1\j=n M%԰%=8 w |b|s?boL0uvv j`Xv"d$,ZO͠;d4.MwlWl6 ?K_-z&e0X\1Nj%XHeS$%vJ+Nn5L9{LH]ard #"CV; ]^ hr+H›5?UUVb9vdGmqĦҢ)6ήmp(l2_MkbiVk՝vm50w WZX+g-~mҡ; .  ӯ´Q^r NոdMdc>Ʒk)Ҝ*Jϓpo65>r!$=nS|֮O&u``Xq)sĜ/ }xJ 'ؚvp@鿡:@˜(!س&2&n BoxM SUk:_ķ 6oۂ픵~o93,) om  ₸`qIX<.u8hRD=HL5 @ lX'%GR$ b* 7;XphFO5?Uvr.Jh$jq W uWޚl~ ) l~L9Eh S+.u_`3vu!S)4z@BMyqvPGCӪ߷lsŀ@?83(vU(/ hPz!2s g2{ᴏ:3ٖf[Wr ֯>l|E,GQ|:d/uz0n7'RƯ?L,V endstream endobj 571 0 obj << /Length 2910 /Filter /FlateDecode >> stream xڽks3 @ tܞ/qƗ&M'N(R!ɏ.H!0z<_,қ~9Rٯg@@"E #d?an*&b\0.ξ'c ތd2 Ў1xSWz!]Vm(J'1$ dIARP Q$LP N]^_vAY  2ӜHM;UYza?A '#:A+Īq b:=؉GQ2EY.0,2҇(O?DeԧfYU65oZW*'Ѵf\YD'C&9 ]䞲P1yS_7l&źO,ЌLt3WR3 (4m&vhk W3*M\ŽN |Hٺn7fMab`rYoUقtl %P& NIH&(~bX 0t BA&2Vd:eo9_46D0hf .h*qmjvl"A-P84e9WP0dfOBr$33qg&_Ѐݦø2pk * DL1P'K/xr O i ;M p2 !Ŋ87/I)gu޶mRo˓D X{)KN dm-3@}p5$Q2Lp/ㆄ{azYuO,V4Rj')I%ao) 5uFHaAO0Φ~"H+==XR~Z4zE "U4 e5sǕMK޵>/f[XRC_$u7]5l!SSB*1Bpۙ"_S4yc{kɪb*ڢV9Iw ʔd+{FYކRfCCOOc <a2]ӽP]8_k;{w5&ٷA=sC"m};㼇}o#l\-.|vzզ@]aL4iL=TܣMOO9i?| t7Nr2[\@Cȫ @lݒFS|G~A~ki"-ia2Zj.35CPacizK:2W{Ǵj&w D&°_5r/"?dh[=j͎V1kN봭T`cR=.ER[!7QC,~y7ޤ+f"L{Ⴝ&+oI<ۛA jLk6ڬBdj%88=\*q:3ٵ]հJc3`B h qܬYX|^s!H 6i.Π6vF*M@=XAO1@fkԔxŃp\-HzB D3{H\9$ڹ MqKմpuBɬݰ\Re-i _6 <!]ReOUfŭWUܫM6(@k۪q-!ؕt%uMMe`TͰ8SSF1MCsG1=cS 6ߏ k,|>ݺJ٦I2\ xS> stream xڵYێ6}" /bw`ޙ $46bK$o-^t؞}0DѬRH9UCoo(A:$ZG4H$J16۟￾*"ipF`8ev f A7AZjF/9H.@JJ/DQ+FJڬ|_Em8+͚iq(ETv f~u &B2Zo> v2';jD",Wwo78_4>Uv_+b)æXMm@,t;(IEZA RqfFHjO!zo~?O+RGLǟ_~YoK"b˥I+]O_!^'\W{J pu OIcNp&ӧ6HYa L`r/UxqILO^m7 N : .Po<7Rflꅩvi[~I+l5N!C(_w7~L`EO{)8UbO(!p9sLfKbCL J438mZ .H1uVV~@;-*/<];R/fyo戇d0.EcS0f¦F=A1/{NLc'Ͳ<;1mNzү1,p5T~{)u ,E/ EV'ua 5K( "P>օ7ŸS{QD7$RCoЁ7._OGA`Ĝm{ [f b3X֠k:R`Za!i ӝ/lfq.0¬ ^f"X*95˼1:׊Wm/0C % bS0@Mmmڵ2@mQ7ĺgW[,CeSa[fB@[ݞ05 8sbp U^s / H+$zr@ۙOCG;BNԤ]KO_$ą;oN>Z^7%K`9;r>߹w`#(zc"MdAvsc{ &SDxEV> stream xڭZs6_4/M 2IS^5zMZe6s}sb/v, `]~az[D9E4uhY4e<<$9h0\3?P t{#!3FV̉2,0YfiQ]D_[b<S/]UW$e]#p4NJ&۫N.Q""+4Sf_x4 rItG"ac >]t +8b+ưd"bmO4E36}6̡PߚxH2F pq Dad{4K, Sg/?\2%`[~?{Sx"50m2Qєh>IeA_5ݍ(|0Ɛ}L&W]-);#9lPmifVb[vcs9}fgk-bD/"0efz4([fl]]ͩUԳJ_R HÔueYleƒ e6DI7z$밎?8غʨRnmRy͂zts% M l48I0ʶcG,#2uh6ޕ9MNy10fdDͶy6e AA4I=4lG c@_ z Ztڱ=t.Nﭷnst+jWdj2K@#@PⲅɩMt=΍xa(ʜO .>+O RgR15ܴ3hG䣣4ŸgtÀ&DKGNtґ" ި{(Mg|d:y!%BTSJz:}Ӑw݇]>_>VeZhEӮ]h(1dv9ZSP9hjVjxAaכMh(OE)mj= 0tt:f[~&zS4\)M 7r([])D m*0һ <щPFnm:|*qiRzҺ*paf|o~=?YHѿC-N>^l.{*o_msm~ХH쁖PDYa ! &E$v%u- kucάEζ钨}xOn6 Ľ_#jǩѯ1ePʔlߠȱ "}шM g0g>^hN&l$]Ó,j8$C;P>o;6 #`_c6Vӏ5Kl[Oo,kD ]2B$t2|~P<ԙ|jF  p_,o6(2 7 @kWPC/I{N0@-ܲ^Gy9RIHpa-ToR 'MK \J@RI_{bZF@ X# R(5pst}~tG`lJ  Vl m6O(4w­X >DBm8!MIԀZfsJ x0KZ90 힢e\G^wJ'րp)z VioP[F@;.5 }֪AF6T} @:/WNjwCR>?hń0wŽh܀/;70Yd MVZWHmrasŻbMz^uݤ(-{4$ O?R]߬>$xT<*Q7aa fPMT·w]̊eP]7ʐ+ߺ᎙lI%cSϽ^W<pzՖnlyY \Ut}&hP|^g{p9oBI?Wzp;;v l]aIR̚[ѬZ!Z4h\|:q'aT6XAb7P@9}$-@;sۿo.'kj$9=T:-3{tx:FbNezѵ iޘaD`c%^ n P&5 nrXde*H#-(ڻ74aE} oCuPDă*cʚ.w^SkfbsE7׌;YI/3 n9N7'r/x߫ Q X|7k} JwPu*)Nl endstream endobj 624 0 obj << /Length 3329 /Filter /FlateDecode >> stream xڽko8{~ C)Q\@MYĽb˱PYIr æS;$Eyv ~=er[7, >"A a̕lp=M1=2"pEND]=&'8瓓p@ 1#h0]\q3 tppf-<#lIJE> }D(XBW1oby:BoլY=F$@ȏKQ0|y!@( HpS@$y0:9;yp6$ hv||~B<v: p7g3hWLn;7 yyQ$?DHL}`5 X{@ɰպӑ˃kPJpZO44QOqv1,Ofԯ ~afAN^Z05ztu(z }]0WK4 f4p5Z_yQ%B5ܖ78&8w\Q ~:.d^{ y [w$8X=(.PҪnIpQeLInZhz-':fVH+}W~_ LLzxBmR%>Os=ijyNy3Td侀*e\O/.#ٺ8'2|]t#L )\x` C围ZeO06u6eh0oa7*Fs0W0-n U\gpbp q$ da8IODC(LQ{L%D:Ыy #aŹjaK-~H_ 0 Xǖ3!FOpOapBNVe4"vG[Q{mpUjiuh@0s8[{~XM:αjcM _`1h6ǂAz["$Z3aq|a){K`̷i@G!ڍB6 r>mZ}!ՇTݒD3"sCdRїW:c=|(ۄ P.$I&ˋO6!M/Wo`\-r8"Ձ<- w9NU*MZQ/.E1#4&C}U&i8 )*֘m#! As/ p9֯/Cp{OEYBQo- ekvj_,p]Rnt! X;m6@b5~ƥrQ;rM2؊ИN[H2 !Ώ6!傤XښXm0 "#pL9? DKNnfP9MVl R2sE\k @rFe|ImЋNtd!7bE2 I"]~'F@@xԹ+tRʖfAEmD#4ldyY<ߥgEvppUM F!}KRJq~>kjzo^#Y@'9>zLiV^sw)S2aZ9k+4@6T&.˗W֊HBOPܘyR#UFA%mx/Cd/ "4^+.vg^@ WEUXP"JL\,3 wTQXK_7KDU`* 4R*P!hH[j]X>?pbCձ.bt ~Z nc#sE͖BfɎ; ɷpe+1UՊ~:~vClG!G4#7w A˂O)i2pS]ݒ ѣy};|:So٬2o βy;mZ,\2TzAf\X)/k0yX_KjU @FJӠk` +~kQ(`z )d7gO8WWÇy8t}h-ken, ވMOf=jf3Z%uEa\4kFXMPF2lyKC2ue Gc>`Ehxg n ە>;9`>TVZAS\gaչL+CP7xpqe)q(6q(v z+  :3{u; K4u߅x6o\.᢮V`D_6\M,EhHH߹htK@E2ܤzvN׹|T2VЉ0`F.s`[Ņu.xx9!׿5;7f7čwӳ)zgk+h|,Ъ*V?w<7W˰9hitҪ4HNs+2<z.8%üw kޡqᵡ5..[\;~\`]C]GWg 2ZrmSHfrqlC֍(-2DhXaPSsqbv(֙KmջX7K{Rd5t T/X%%A7ZmC-5/w>*aOޡQf=ávDkc\涥[MBi7֓%h49|J!/Δ1b £J)LPv|DO9#!tj$EI#ϒF(&Y1]3OB vN*ZFvWI> stream xZ]o} /3)~h+q. TH2Y\)2=$̙ҊjmŸ@ATq6A)E@ŔPZ({ F)TFם j DPQ)/"h!+Po+^:Ɓ(B.G%I1DHV0D8DogPP 6.L'+=a,=G7l`fZx8FoHfdY."RY"ܲ5JM"wF%KnIT0R/5pn`AJHًrà&oιVԲcsd E%7}j?O,DR3X&p i}f|T,E.g=$+)-yΨ\=ϞGJYI\d_Luo=[f } 1㝍(C 1 h*SCXVtf䛁N1wC\0#C=50'I`d›tQ4OV]J"1^B^-gƭP?.{mX?f8z Lk^{yq~]^(iج˴J(vֲ>@˩>`cܷm`P6 #xp]o_/>aί^-?.>\;\-do%PRD%u~~Jl:림DKՇޟ{2r{ohyHYa^u5KhAW˚*?_(ح?]} _WnH*,Q¶9+;*\^m;aS傤CP\raآ̭4pW+MxTi(JU0 ʈ)@>)f }4%1?jgS¸G Oid!hx7-}>7\k1g-FO]\Gc-ǖV6Bm3!p;J(\!v/J /Hhxaw=őn(8-dkf0p 际Vk$`UJSehHC 1Git̑!:㓸Ύ#n+G N vsSe :x .)N@řNq/;NJĦϗklLq`3S#o4tx"[unNIIÖ8,ey΃siOaqMX)"xna! 8[% )/ Jn؊LY@1ƌX;ʕ= VҼhFȳR8gp3omCnS\"<-s@|=|%8_Y4]+"Gn) &'y~'kHd. nKkFG{CSBI]c:ɘ`(X:Q ެ8 '.|$sb#F6{߀wWwy'o;XZc塱и᡼4JIy^9/Dm"H ^Opm, "*P[a A|Rlr0ԗl`#°vSqs8M?Ev] nwqlb:9eOq0ژ#S5a㾣ڒ-2~33?z7e_K_X˕ySWY^k}bI 2U~ nyCaP DHc撇ϥ T@<@Z=*sMt}ZCmlHIEVAx? Jmz ѷݡ%7 3ۋSj¬k1m?*Wff endstream endobj 636 0 obj << /Length 1188 /Filter /FlateDecode >> stream xڍVKs6WHT7%Swc󐙤-NI%:]`AQ$ bw QDǫջ ɒSHA^_~3w7, hD(CqNA\2'ȹ`-xDK1J;Zs*ïqԚ30&K%y2Iuݎ7T vaՎ-u'f_I'7}VQQˮ*vs]*\նzPD$ ֔?+2-3" o,d@Yû#Bs $RԶYQJS:ARȂ5#B$v|IxĂgtUd'\Z٩,oI4k/N NJdN-ДČըq7{>8}b?U\` u2iD$9*$%ښ:NqSThҡ>2psy^f$N>Wu]}@1u_t][uv  9v;w\vۢ6mvJ O$RDBHlM{'zJ庀ֹ0oV΅^nwf噄BOP ĉnLAZ"GNHABS*lk50p@Սq]b+$b @,3$k`Wl0{3L]:)/`kL{dP+ZG}י~D}[p75h;' )0 @;0VbphlDm5%I%w'~R~lJxzU2)/e[)l?"9c .R:h x5#1HlU$gŵq-_Xjmfqf{DQw?PK0x1n<薐MEo3ƒ;b+2},9 x"7ޫު]V%3".\t-(؂; 0} o37K@`{'_#/=E|5{_|{93{ڻF] ^KĢՖ="67==u9X'՚an4p՞/+3`Z endstream endobj 640 0 obj << /Length 2182 /Filter /FlateDecode >> stream xڽ\]o}ׯ>U*H  "m@%&2Yh3{$Uw狼,xxus[ A+[YnVO_/7?|pg% J5 `c_x}UƒRZn/~U+|󇊁zsR 4^n^={`.GKDlj[q> R \3)}O4|{2ʱWn}7Uo:9;5NrI=fмL[0djomG|'m=6N"OBD;qy6n$)oRgyBr8*JBVPJCB&i !9mXn^.5X+)4.BtF9I:҂- G2U6'Ц0Q 'f 4ή1yxG%7Mx:OΉ1A5^h'"YMT܀7q&~^ṯ7qڐIe2G \RHEiPܤ\i2J@BtT}MXEН9CDŽ4qZ̫\!QZ@fI9=iWG (UH@3JxAҐEΈ1gIO*22ni7a z8gV0G!3QJRDTJ4LqzqMIh_pPYs[v'E:#I,ڜo`}12DTFr d JA2Sj!P7mGv<5mY p,+d 4Uگ^& ?%;'Ɯ)NaΩfր6*;m3t=Ijgv Bf0T ]ڤZ꩑5NayC YB9b:f(EN&\;z8} uB*! Ys,ϳF7M!kTLPƳdd3b&0 29?se21>0y`Pɽ<~msb$I|:{'19j9ͭf%OONNc n Ev,7W^\֋MeH"7 /!o#0~U׳a706#o+]n;7mWf֛dg6|+!(D̉u$_w8Z MuSn6\bQ/_a:؎#ͶpU3,[6}wۍyݶ49,ݍuqTr-\B[0-k#m߄rπt? x0hw` >]ׇAM|3zț3,jB 3ba.j|6Wfl oӺx;.+.Iq~v/Mp]gu`Յ8w%y8<Qp%rXuRɪ[>l]8 9gqqQ8Ǡrd1Ӆ/%?4y}y6/nb}Mv_Cdwn<½E}?]WlNo [(Gw] endstream endobj 648 0 obj << /Length 3109 /Filter /FlateDecode >> stream xڭZms_)՞px! "x9'nN3M.ms"*If߻_El4bX,.gW3>43r&ag:6̖E2iod4n\ %Tq~gHP.8I+6_(uV2^TH黫ꂾ7eV$}92E#gǟ~]?~9_xJv CD;('u8O? 9IRjU|m"JH:-H)V_Sܔa~1PǔJX0!B2о2>k~լ_vBpν氯iy[_gm\ҁiд x/DƚYd]c,$ IÜIF N7i^Sitf %ki]R%^iu6 ͳUvi2/vvWtvn2T#sXSdcsOf%Fb;UYW#?*6^)6ދy>wRlct,=s/묪n~r0]r>],Ph`l>g+h2eٍOzWe83̄AJ&#iqѦ)|WvU$lUEP~ '_RǃDfC 8E#,g}/:w,`28u~ӳoS8X<~iL?1x]h1өGz^oz]P/]O>s=3 ^{X/p\Ҿ5u])hUJK~K᳘IIZ39Y.߽}?6 b4 a+@@%۽G 4& OsFibH6eK] pƖmp#oT6ryöͮ$ٕT[˲˛ /0$e_=;Ex7ٛՄ^LU>W- y`m\u_yE?MpZˀ!\g5ĥ# xZ;eWyt5@)XH|sJ lmY\j8qX l%H ![ G)tl#b"j3{_rV.MV{l-b? 1}@n&qDY=}cN<xE#n6t9 YF Wm|ej7(rn)"D62@ɝJqӆv2vLmwƄN.;z˞{zþ a3rM`z.5ܝ.Q#-8avDD( q% .k*60P;ݱS@.`ی=&`"l=Pn$ #arOTDW֮kpkHhۀ\H"8bӆ GEc)dKаhk&rZ,.s,/)V"T} x/.2euiXQ*/0lϽ;Ol-Y 4KM\cSåIxHI]%]BQLBɤ2Xm#[Z1Jp"95@"Չ! \XF>H@s#DEmsɺ}U o`1GZWD4(S" AJ%\JKl$kedI58$tnS84R'Om@.-jӵWiTHNlm&]#(kVYмI#fxӔml*nj:⎸X{1JWU6G $KonӞ gSlaauXyx6<.fS \˞yba?u9;s<9;S ^ h09$>E##Q?G.)8Ɍ(NΗ? O{):(8`.ynDvokW?=Z0d1w>gH1Jr}! sP|CD<,##͔Tb&ӢRkmP&+DCEH._-R=̦\ھJ!ZŎ=dTLf(=Hyᮨ@1X@ieB`]8Jv[:$ٰ[i4whN#a `:OQ_!7\[c3^)}7;[a)&0XP(r1}8(bt;lAݶg(F@yJEW.- %>"> stream xڭVQo6~0 HQ$@$}%jK$/ ߣ81dȻw<2$M^_ M5$%\*E1!IVO۳u>{}55̠<Ph<`3Hɽ,zϙTip&GfIՏMCCK:_Vuތ&Ob! c]Ko&0R;@FhCbR&kr3 +SbISN9X޲_7ә2ZmQ>Q">;,hl QL40hs 9l"*N# cO$T'a$p Kz9>3~ܷqvA%ݸ+qTWݢ3muz4sP|\6P%k T EY-FoNSP*0VZ ̟e?mϲ3__/9n/2s;I ܵ,\٪l3ȭU*": 2[LhͻdWrv*l`k,% 9ZW|CX@2mNyov]W~DF]3ewCEnU+mfCak շmll[0}B5{(44;h;F{]~, ɃŐd1L&}EG s3c*UO>>Yc V"me[.ְ+|q Ow״}ph#riv*l 6:VCG$K d!"?D}y1R_4`9cy[scԶߺ' C@Xٶ ' )[d_Nl5b uu AS%•X|oGGwSy endstream endobj 663 0 obj << /Length 1978 /Filter /FlateDecode >> stream xڭɲ6w" <$^dbݜ(z Ee} nA%h@z^IK-@8"oRa"ty{O}٭A$p;)~݃7 "I3*M~LUU s_5D8X6=oi\R/F.ntӔ辬{,ܓA))29F"-BBA\5(%(L_!› #eCٕh-kꪯ/ 1U;H4R35q蛕U0@A/B`Dszo;ZXOp#jt%Zi9@:(įp (RRKW`g(۲7~K }6ciH2*вl/c #Vo.l؊~61b )Å'!Í6PtZ ۈEWeqKRhHau HֽB{K?K9$o/' nCHD4QZ#F>.GEC+oۚf5Ј}dP%+"O,g?*ޟfkGf5.]!*p }FfwZ*+);Ogݝ\-9uwXu@7 4'Ym'L 4}^5C)mvXWgBQC1~Mә؈1 5v:֏ tQ0oq)NG EPچoCR#1o;"g=X i[[G;J;8 `չu{J ?PȣZd#=$F'Z3hۚ;}i}ĉ(P줶;ŹD&i`2p rp :tl\C_me[>3 B4u&O">~,8*ChZqAӔA;MDMlcMarš ~NpIV Ҁzyzyx<n9d[ͧ٥wm>TM3Ln8Lfȇǃ0v8Tv^ =)Q6DrM3lhL4su>V`E6 IQlU fTCcC`4p.̅,fPɐ~.Js,ωH4NfHy O endstream endobj 673 0 obj << /Length 3146 /Filter /FlateDecode >> stream xڭks6&"D$u&&}L{ӫ=sw%Qԥ(َ}S|v7~{%1L 3:`n׳}tg Oh\2PY\t=0ZH[0Ef~aa8]6ʴ(\Gfz!xϳkif_ j:uV2|VjC𔆦Mlm7U#ТXTJ2;߼\57"ݯ8, uB_ϋLwًoTx z ɼE]~!#U#ভPh3ū4rS%#U%ӔQ" Q2y E~\0x4},rTĢq5!<$  ymųܯN@BO),minTCt$s7}aW# MpiaWmy6RGHϙߴeΉO@;4鈙'0l. tz ]$r,߳Po+o&cZT_ qٙ5= :B! % E՟vK3ѻ~0AQջ7zmؚN4{˩5윭|ĭsR.}l$C7I@?6qso`qש늀ޱ{T#.ǁ˂$\KZ 4x:0aBJQ(zPwIw`atEZܟ`y ͤM!7Yܧ:5OXHU4辔fQig' a,ec &~v$7#s\,ƂTl\pPH uՅt/ӺBI/Lc TZo@jwPw\|NCWHt\kʕI]pͭF+r6jN:ep?3ZO&8SkP(ǔPֻZ =z҈"ZeTӲ4!M.URKn C5 :+@e~A5Io"]>eQMB1Gun|(a3 b7H]&'7ӛ,tz&|ۭeYXp A".}PdG/ꄉ:)S'6,]P CB{#؅?,'߶do^N"{$ (pXw/@9لd/r:Y &|6IوL@9\%}& 1E Gs֛ELqu2L L)=AI|: [!+ uM!1>c|\ԙ8cw_pMu(y+ ވyJd|wTc#.'$(m=B[&ı$ÛGǞsLäZOX5 Vu+nUUwyi)&xu""`{0S; >dYs,i6GU 6=%CfMaS<hY5q|&W7}iL]UX_~>PzG m$t,k画3ۍ,2=ZaxD?ϙQl_3ignL}(=S?PŽ\Qt%Dx_K6BpPE]Q+J3Վ6Sizw(>=6 Y/׆ڷ5ȥ+K@L waQH!|^^<{Ґz}Hɣ/CطQ] 56ml>#u#_ U~6Ĕ B; _$Q`! endstream endobj 683 0 obj << /Length 956 /Filter /FlateDecode >> stream xڽVK6W>@M) R Mi꛻Dpe)3)[lR`h4f&^]lx֊P#4B!%A%ڦh\JVۛ%X9s:CтxD((RaF()[R }gU CC r\2d!Ҡ qLb E]qqM}3 !FjLuA:9k>0eyb-wA0M_g GBB+‡#;{֒ WoSTM l",]o-qMIW4AUeA2fp ~GC%a!it,Mmmvu%[z}S_X;~b~EdOC~{tx_DZ'!9Ut.BsH !uv8b$YUe?Bu͕MК[?حw6NHu^aDljYv؃ŹNr_^*m05T8+8\=O4XёlsO 8BКr,%4m2(ϯ:[C X]$)8Ln妌 γҔŰ3\4&tױc ;/yC2ݷ6s3E/Cޮh FIpgIt4n42Nݳ&lL R?ws1bBdMY*`HGpX_覬iÌeNAO> stream xڽYo8B~8-mEw tAX,$iP/GilpH{.O:9{'9 CxW/^#t]6ݷ^,e`?'q޸YGro E򮶆d]TBsBp԰DC\w 5"kZ7 w2g O0æ1XX-ۗUF|SY:`qt|4IaJD~Vm B?%bcZW"Nwvg[HZCC䶢~k'@9GCgYU -({K, o) :h nm$-*C?vCM^W.[s A~0q:wJ?AMUen),dB/umʶ( c#7UwkyyMc&]6ěֆ`Oڬo R>ӨIxGp7 LmԻ ,{F_KDӓ}֞[$/fRHO0|Ҙ1;]YekT4).=6o$?cJ(w{7p]lw`NjFVW57>)5unܘrzEJ "kGUWMw@ej'4DPPS4!0{sB~>dn܇q؁-816]u9}% KoA)ߺ/yJmn]Cj8Q'8WfMn]5@.S7GRcC><XFt7XjPr4Ql Ժu[0pvl-1 v lXR7<`l(tGz5Z͒ !@P,Gڡ dTkAc29Cc`|"K]Z,vSQi|{8N, WmM:@}@ZDu?z+j1-EzzMi6 =՝1X:w NC-yCwdGVHQEF@tS8kZx7鍡%fsQG洈PCZwnyD,/%.1!}/Lz ;" DictAAh@ERB՘5(=+KOr·H3 iJRK*ڴpz{b-M}!g ؓWW';a پd:`swkvB|; )'@ux̀BsFpU'-=:IPdpIܓHb.nXJ,K I$bdm vj~@rF X/Μqڤd #!_r=jhhϟ;;|dr׽Zi!jsӡT W)t*ؗN?*g4x:*N?>}hU׶m.1ږme.*ɀ*!eezwa,|_g7Gڀw ӏ̕(C2E4[fkp5F3BDw:JSËz)՗Β}SSKm[+aԹn)acnNC=^ o L[S{\7kTbRd%gC%i>yGã42P~QeĔ-l _R c2=3a9sy9@r(:5?f9kǛ'9to'~xfx߀՟[}ѽJp"ihyPCfPYyW#U'M8u;ͽCea`Sl(ɾ\kBʽro3v3d70ٽLqUq)0 pX(r M endstream endobj 713 0 obj << /Length 3385 /Filter /FlateDecode >> stream xڽZ_6O!dfG+mɵH{ Ak!Jr6oCɒ-﮽FvMQpf8ܻ͐ǛWU,nn=LjSڻɼw٧__'8yLÕ#_W^$PJ&M䥫Ag*{;jذ.W%b2RL,Md)s;hV%5ꬩÌGIpO8h5OcLH8!X#t? d;o7*,4|lIkX }kzf wI7u.wrͳ*(>}OCA~nL?zX3~8bUO<|~*d *|l`Q5iZ=Y%J],)r\gLYv |<I^$"Gbρ6C?f\ߴIRWsSW6u. u#C^7E>mU&%lsHԟ&EN_yQOޛ^뤤'4bU3{k67K \(M1V+`)s PsE2 y&'Lc]]v%0I$P)=U/%qTnsHW~SYVhl.0H AsXV*a`U\|Hh)pmsי. ,Lr~_4nHF?9J+-~MOi.wVZ|x] wFq #+hdNVViG@,Tޢ$/<$u>%UҢ9kMRCV57fHL%0n(pTkmr')mRmʹ$3FJ no By&zmM pF P.hmыKnKi@Y$EOuyfm6_hQ ʭdj_nPݶN%hҐ߅fI nѮ6 0@n >A Hr#)Ţ,:,gp3D{ rcۼ,n?Z¾u6]8FY֣ō]8!.s?70ޠ}%mHG Mֶ9zGMy=0OҸ ,[LDv[v kcI4 1f/`/ 1^hm0qѹyA;N;.B)ErsbïF*$ #u:}TrdM#_'Wp RoHֽLʒHycaZiȪQ.i( V;D$ʼn 팆Yl%!_ݮSVi XV -Va;D Bk`")mh)n 54 &F5$ΰPc߄,%?!q ABt;!A<ٰaѩVOaSBӣU"CMв! Q00M-#^)^߻a{zW=ʃr|ЧgvMI.]!js.e(sM܌ > XDk d"/hLlc 0<0,)3Z (DkP&O3uP [BDz3>bΟu` -`8!n\gyTdN,fBI2|YpY-ulW.CBzfFËf{ati|ʨU@ )nW TIPTŘ<"IQRhMM>3BDI`3ŗ;_ѺD8}ffX*.|C2M>[sU]W| B-3a\)̷UYRO- "۸v$"@ "bR=;>^ϦбI{]FjR+}zx^UW?'Of@~KH"*iad @>+A゜š !0L[wbáz \\ ˬ$N=\%sH=W8$d_fI>kINP%N\fI C2awWqe#RҡT2f)x2Y(RFg|8;U|\tN]'5U &$ WJCx"0Ed" <(59]IA#ג!MBls]Վ"d8nS[0z{oR溠Q?LbqXl4OTk?i:9cWwf#j Hyl +'l3Uv xmII ?+M y#-%l|X%ݕk zȣRY֍PŚ*TYfԤ 6C2AB{ #z=[ jMv`J_^0վ })6QR0Z`e1i z*Vߦ ,PE"Oָ wD9:y $+]tZד4۝D.|tmx4ߝw+1tg jr݂O~`j]F8tnrit O";d5\& -+;f?n;&_9M )/9!1L;:s1navaf/5#G,Zڝ w#~fa"N!`0fgڝX J;3UPr]j{WjI5׽βw`$yM~Zk{YK=#g1溻GQ*|zsP4?; endstream endobj 734 0 obj << /Length 3208 /Filter /FlateDecode >> stream xڽ]s6ݿBR3B?zs7^4k|s!D$Uv ɃGX,{Wpˋ/eHX|q]$c*JTb!xf/E!ŒK#@fF]\p H"8]l>?/B&tqmVz$!(R Qgl@Ik2~YV~ ,Zo8m4~|f璫@7mY[h-./頫m.h);s]~ZE6"n](pmŊK]lءb&a l,8hk$UPWl$niz&@sv4kYa׫uS/([`R;!`SED mžѾKqnBWY2&>L,AIL5GTCXy+2`)>iXX(( (,~eFۦ>)d Q<gP15'ZDKà> :_%LhRHn#횶ٲ Ǒf=8|e7].cEƊ(edsV t%5 &TYq$@r3YsSipE~kQ F;ykXbwr{")O8NRp\~N(IaurQSsKMa~X*X \SY<Ƙ12y7gt*c)>˖"1W㥻yS`FxP0>co8e0x0I3~_fr r0o3Ctw2fq+@' 9Đ!{s#O 9*+;ܢٱ+?o馮;<䣏,#&LG֡IC$nOզ*Y7+_&G A宄@* pkSNTf8Hl46ɧ 6 ~:Szt+o#b(!I)ŏքŚ &A46_@HNm@JN)yc"!5)׺ pY&v?֍QSHm56@7MݠuU fvQ`E=躾1ֹlrV3Rw;/Wȍ{{'3LZ7Z$;-VBGMfh~#{d;D v?tK OL/z]&bTᗣ$QC J{e/;SĢW\Mk3m t$\ * Cp8_xq`XFU.ə"A̋r:Gb)&0E#WQ<+lF]:U&bnV);ԅ38(~?vO=z{~Ү3ˑ@䤙i\eܸN7mא pz;|RP>%=`%b`dfra xUb;P$u(RƎ(uۖkx`3YBOy%YdƊN)ҭ=x?VW`)tF<{ݽʏ@̛0[IPRxxp&5 5$bayh#切m'ߌ6ima';[6krS+`@+A3E*{#6E*m[+ǼH>w:eQk |Oylо3d4x> stream xZMϯ1pX/ dH!,bƮW=ΌVݻC %{TM>V=F-dIMVK-ZMR%x-'ZR8ܓYݰ%j5u!0{~"GxYRfbppY\nG'|/ Wo_}Yھy^R6uwqs׃xח06/|wg]s怄\a89ڋOd1*O8j䌠Mݰƚf` )h1ݥ/ԏ,~RRRվա|$IO` c=ŒpLG)H4cC|c-Oz42M/G.3A!ht`DHι=X͎[ I]S3 UQ@"yQrxJgI2e9AbV祆|YsF wAH}S?q`gjU:Lv,G5rIˡ?6>Ѱу4vW%VWi@3>YP˳2JZUu!XUQVmh`j ~? {vؾq@FlT@f4;|e8FPCϥ d(kRh !@nc3-ˡSqr؂~<#`o84Y;vlCw`bU,JD*{ uk(UB)},1!mP z=eā辝q/s;Xİ!ᛅ(|'7F, %EQX_"%4 *jnMr*7nRe;r!FQ E#$ 4дcם'GrmYNP˙,+Rr\A_%N'P%)K-ϭ̭έͭm۽ߊkI$\D+B,B3Yf 2;~ː֔bk3JN$ʠUS-q\ofe)=e7jD{P1ٵ0$TnS!*- !pC,@P~Wh#j%={_<+X6ce%+&*TE(nqga=WIF( a 7d%G7GIev]IW煶󳸓߷s(s(s(s(㡡,]uJFFAMk|\u> #W L$zƁa-NfۑlF=O:A #bj0T5|sE5۠l?,ҡHOQ$,zOehC h]+g1BsD<#AfBEW|H8:1,WCowT endstream endobj 750 0 obj << /Length 3288 /Filter /FlateDecode >> stream xڭZ[۶~_X0.A6ԝqʹ\ZK Iy7q^>h pp!_\-⇳g^haXlX ib0Ɣ^Ż߾6xJF YcL`1;1P8錻@(&^fQҬ.;_I,CWeRP/E:`^KjM^n9ł#jlZaKp.QzRdZ۪'mHs_pJ,lgLJq +`bZw91b< $c%;_)x[U~.DIC 꺪Ϛ&[u܃ޢFNO:d;fM& !(I:LҚFO>IX/>|3+\%(KJطrd6IIKKQ8峥P}H 'z @ O~e/TcV XF`fovؔ7#~\H:vA?2FE,mY --n w*wt({HOY4Pg#'%w#SSH7a&e)E[O? 2Enw(3+C+4!?iHBpeJsP6 *s0):Wp B&NR@#fICuJŔ r`#X]1(ͱ 曤(>А- Eb 9y3G ?XbRɢi):A8=֜j(`7a+K MYF WQ vY5\nCgd8 dE|P6Up4P/K:7 {%9T% WX6 p&^gY;o\#oJeW4N"h%Q!ɯ߲mWlU<ik4 Q<\6>k\/rCJO<$4쪺`&4 W} "_-y6ޯ0*/2N" ѝl*fAOi ƈ&9bX:>Y2ѻDƌC*{Bt{0fDыVA^ u=e7ENG.fV a[7= ܨ8b tƵErvZN3\x~Y Mk˜ {H2DE0Pgͱh Jx'mh q[[B`5J=m[ѹZ}!bcҤMmGgh5˺q(u4JUu'/ I7_YXqў/"4޽k1G;kNC(F_,~='] Bgh a("Aap | 306%5B8OVW#.'4qX b ^8 (`{ NvoNXi v BI .آjt73哋zBm%ܟS@"xQ̜@o-c퓷z{`P Ͳw3-﾿!>)C 8L=HJ C9=O($P3a0>!+<&<:ܖ<ܯϽٟ6o?ڽ:=Z`_+D2 p9B1 @^և:Ztv" <·9*;PJaA+ $">pϚFpU7գ\w=_ @'gws*PY d5 ܖ$h/aAr K'haq`.ƃ޸ 81Uj%?V'oʔCeo_|~~./]0q1| n s]~;>4 'I?==׍~PxyX$@kFA{]vOnvY#o_KS}sV7YQMz'e_}Ӧ\O|VĮ/H.dIDBNL.P$M-YFzdgǏ$ $EJK~oXqv)O.,6/tW.N K 3.A2PQa1Y]) 昘2b"" v.\@g,z&R|4}u[;z LG趍`&Mi"~h|M1 CE^WbhVͱmC|Z+N|fR7묩 9i~I-\|֣Iс$Űj]+A){ Q`u( O:$k`9]lV7"]탮g{dO>T|K}X!G'˻=p"y61fR3 {LוE&d\t(Mnw Q@LnmoB.cAAĠ6w)s>G$Hڦ ̳Ю)\=TFPg'M{>ٙ]4463Dl"0YOƥ-f6V-@@q=P5E,G6n?)W( [TFSG+vN!)ls_4ߪ}u.g{:%HY%#="*i?ւÕWA}F An.cut-b|.})`=v'k8;ufsV`Z?!eh vV"I2}z`"T}Y EsuQvSz }@sGSVaVۭpOGV8[yI:^g;z\a/'9͂ؽo1CŠU%A/4bK<{,n+}bS$j7Ga[n+B,zַ\i/lgƁ냛D> stream xZKs6WiSa I^;l9YCH2Th|#I6ht75`ݰw\[YlXon6"Wq<1nOw޶/W[Ql8S4]r131Ip+fovd1N4.f]~*nf?TmC}{m~+ʪs1ߙŴPnOU.尨+ xKqmϮ?Nv*.th9 ijm3UcN&~ˣ#@@tVlv\RҿVou3"!ߣ-EeOwerHc.7v ݬxG!<ܫr:T<ڬ,%}ꪷ*houC7QO׺Cpl`C pm6Lgm6$Ӭk$Ѽv"$ |9 !54I~';Z~?$MPE_`p{k2DRKOy~+epR0o^ebx'BHsd-q :L 4f51RP sX8+:gT9h87DϪ3|dY\LsFuݜd:gH_I)lK@CL3ʄ/4~F_ Vd,Δ,$PϨ&d]p |?; 0ĎY)8llLBkG?"̣{;wڦ~9iB Kțg곥d,$l6ķћq96:ݏb8` S"kyav0VhwwÙ l:xW#H l |%KLۋat;4d[XtjBHw]3Tx2?U>bI Y-Z6/MMwY|)`%3$exg 7ĉx7 V D >‰NYF&6^TLl $Dhƥ-Eb$Ў3ʛE|$9/qR|:<6R, `8B~8hoˋso%E3̍[C1w%b"|/:dx2e:!Qф\id |H8yRg9kTEM94fYî%`,"<6(b (}U0"Qs |F0Q,UAs{fl^ R#Y4,'Y@+Ȩ,?YD(`B3:kLƉO>xH41<.u@7JY؎ep]}BډH_I%cYv$i[YmȿiNrb/7LliVﶟˆ,?px/Ϧ,e?S/яͰr;< ̍X:Z[\-MЄ`teٽ#$뿎`g֭-}\m.GV͗L6|ًd}6  ?3{,e?()T)T_.POxrU"jB'^9$_䋃ׅp{9|al> stream xYKo8W4%qMboEbdVBd!U,Rȱyd{0Xa/xu%Utv%T}RÛ:_ǫ+xti0=Hᤋm{+ΙVJM$C+7R4ibŴ+VϏapmZ}=$ 5Oc&|{WWZ/6$]89EQHzÃƘ*u0.R!A L,؋JHsƹ oUuW,0Z0j%i;TP?.Y9JzF0h8J&nfud2󝩺%$Jj2Euwn;}gOIP*; uS9iwn =6un%zr6\@?Q[8O﯊rJZ(qJES 6hv֛(@EȐ7+F]uhV+4Ȫk%)<7{0Auِg;Z84M[ .gjjMEH0R5Q Ao&\x +'T<]uUvgڥiX eы-t5Űm% Kp%2c |5h eCŖE#3HtE2ΓnbX8fեĕLޓ/( y& .ҁ`XAVh/puv [a1aJ)1$n<{>Y\$1]&a# ؙ/ څL?  ۦ[4r "z͓M_REa~Nb7Kố@D' ֢Wtc|W!n 8_%dTΐ& ,E@=9 5mvu|$-CR 8NePEht>zl~Iu s"ٙwÊdZD7Ql Yl.7˧*/̳Hzm;OW> 5Nee  ٣)oŘ ,jPvLWV[c]!hxJW8vQU;aLWNL{rSuwoHMTpcM C;3a9˘S tv:-5׆dV-)-QŌ LEG6c=Cc5$g9M$bO`8R7P2 =Q.\$>5 toG5<_Yo8m` ͊09 9}c}.-# Idc t聚{΍_0[~84W:uHuoi[+6#k?FݟH@MKY &#b&F83[ի{S> stream xڽZ[۸~ϯ0RyDRMQ &)iq KF ]rr}g8d)trf`sfHuX}p\&WJ) xP'նXߛ|7E>KKLw "7ӯ6j#CDz#j澗 UOZ{桧* fOMTJyu7azχ:˦6UWRtXҞuvj* mY\~t|=a~`(sj)8m8k=0L M EϰIuIQ Ԟ2$#IZYۗPeIB|j*A+2 ;SaMtAnT(n-|o8Pus)޿W<`2cùQɅdsI6}/\)^~+ۥ-IKZYy geՙ]3#ݨKmn˹mmv&* ҙF Ehx@h\zwM>T_R4 ",I,Lb${6%^fu*K D)R~j[Pӌdl֚'ށJ$YGkD,NK6&',%{xgk3 gեBuy[ǣ%"Փ 3LKHZCpw0ˌh]b'a؁P^~ uMoz2 lWSXU]CmQ jE?:X11){RO+mKk{E$OЗ?fPeF.-*pF;% \Thf̐m[2gM[EeeuA`\HшݎiVG^>b/k72 |/"FD$dXh&h.'pꔽSe]A˙0,@8,TNY0VwE,,$8 %J'X*.ׅ}SU Zq<  Us9Bő Yp[N%&h=rʹ 2˙{ݝv)SDS0ȽG'`Ŷj}~}Vwןo\GyM*7!S٫|*&zͶ2x;UϓK0+:k&JMӠFΕރW'*e? H@޽ڮ9-hI8rps-}CUGsMyxP)`2\xDdc`߱pnLfI! `lj!g|:U,3m m/pQ7a/z`%Y#=61A{`e8[Xi7dnP|)>8$X` eru="\KX :@ U?"0(fx…%Fr;Q4S0apU[gAu ]g ^D7VQvz3xؠ)P-$)Pl tc2X4̧O7~ly-Lnr m+!ڇq= bO *hٹv{3ʫ,Pv.; %Dt._h[ H1-,}IR.KT΃.EfVu5 u7Pn;e$A 4et!8 &Ib YX[cC9e$ pL'4rtYgVR:?չsDtR`Th8nۼ)Cӯ% \54LW'oxAY0S D'hyVPVktfS3&6; X 4~Ǣ4 4)7雂,$P@F5OcHg8SD#b+:TNntZ&,C¿}xbO.{D8X1WJ2/l?IPߜt2dpGT7T= +,TyXqFդZ UMo程j:KtpwRNy$p␋n9=wnkX*@]yqxG mÑh j%z-X'4>ʵ{ P*g oZei6 3.*e|\ERv4OZ쵣6 px3t߆LĂ+ w3߫t7)]`.@rK0a@9XV-HY,W̐3:9bv"s=350G1yRu.ϫ$6# V)=} - u"4%xZĭΠm{5lXewUvf˵1Ϻ,3wUy86-JͶ/p7WMs1A(̦M&6ױ$epN3uonF(ש+ƒk-HҐ[AUlI5Q tMFtUg)J{»et39>#'5d]Ko Rӫft+"]՛Q^0Xm;2n3< %ıu >&enCO'ɻǔ/U?N%nGk[2RME!SjT . nE` ~I]M ɛŜEйft3o}Q`:lp;m6?6Mg`￶7MM ^;Y4;=dGFa4gC%ɏ endstream endobj 814 0 obj << /Length 3320 /Filter /FlateDecode >> stream xZK6W*b37;k{gɺb(#q#Zxv| dO撃x ~!o_ڼNI%B.6w dA&$6-6w7JRh0<0A//kAE GC-Q1M(5ŸOk)`jfMv ?zX+IMtDP7 G$7wt\ڂii+SϴF3mGS>oZ}.uR 1g"ET$5hk]|{|̏mM}bi /`Qd?἗Um~o@Bj4zR0E3C9րeglBa lXӴ7|(w*r5[]c Bjcuw(Z XV TJ̷̀Ij0 bА 1ՍW@ɞϥYhy'KP!`5=t]Z@͒$hu^jUkڙjQJ'\K*:#x),ew4p+)ST*Вz*Z`&!Dòөb #<4P<k^[Pv)V#SAk B;KkJSŨ#M-.i4-n)2qjƜd.xvdsvw9[.-G5KDI/"[{zQ2s 2sx3c8N 3c&(wuBuD>&ҝ/xܐM&ℊg*O& &!?weA?`WE(I7«d a?{BF>iKZ01 ܻ&i4dFNCm=B1A˖>mi.;@04 5qb 1οmr>^cЖ_ҙ1~ `M).DZY+`` Htt*F(L'D<5]e "v()[b,#B.TA*0oC9vg(l3bvr^ b({f$}-\2H 7T3pK*E8me=y˚"c@^g)˦=-aa1E?ڈhh@V:d=QIg;}oGnBQW7FϋI#a)t>N%:e>*HIWĿ䍼L_ al˙RoGo<-$۵0 /eQ6 FLXk)28HIHCHX8G_6!mx %tvNTk듡QreN|n3oߚ]0т^c@}6cx(C1k\'@R+c{8b4CᕍIЙE%LRIJ[6emΜ|_ZaVtJ&A$NPu;9 MV?`[Aر])K+i=qBkB6D>=<7ҽ<15l*vCvD$Bȍ*x9OrRcUX5 1*%ɎC3g a_YM~.׈^Օ`uGFRvtUd/7'Dט7oNpp&N:K5Q@jԒԎr͛uJM\zNo $߂ݮɫwn ejF?hɄw>ދ6߂ 6hQcD3^P ;*X/v[#فn%'8Z7x.mEY{2+a27N([/o2TՍ>.+.wvW.J%0R ^@Mg9jlȽW^g4SQr4ؐ?MEuLe.+q=IGAj&;ԭP`I؈qŒ% $fXr4pŹ9ʙJ'{ܿf{!q_5:yVdQC!eY~!IEi]קzWB%f;'JrCui0 <rj4͐e*VaC=Ws(-O9v!ĩ« |7bL_,@BР2h0#-ܤ>.qGe瀭-wf| ڑg; #Go Zŵ-YBoc! Hg 9d)e1i=+mx.\\0u&( yfhEPvj}W贿nES6aO]̞kOlC}Un@lդt0!*9$7c/=1M~O9?@MG@+ٖۣ:qa:qac_XB 0^:6熣Ή t._˨z \{S0#ѣx@N{EmғB^m#?:>GWd`'Z_Fv0}yS-~ endstream endobj 829 0 obj << /Length 2982 /Filter /FlateDecode >> stream xZK6W|,>6Nl\\@5Ej= 5PJaJ 6@w_7&ܜ6G{L7 ˒odLE&Q'ؼ ~zaO_tC G R(7H biӨC8nOhӞ6ˎ ]dj)ֈlKTܝuEatW}(۝̲?kv5ԃZ1_ O"-C^[wD4Q>'f$㓘W4e}l`i<8&NGb9R&AͲ`Cb8ys*Gnyx 4*h؉^(+Ӗ>őS3:(ak_6u^UxF^Ըu"32>nΊ DDc@> cUӑ8mEs.<qmb8h^|,=D3.Ui4^ X ~~KrK59,쨧([}~+xIF7oEVZw(aF:>| TT2\ a*frr'e}XQ|ϫvPq1,>YW`noCDĢd^'I uߠcpyt5A{P2~s P]b 9$MGf# %l;}J(ogI ɀ/q,Խz}e{TyL8~C5G<*^AHn3&YNp?sblTMIʹ+83 25`/ jp Em`BB]"h6-~|4D゜zd|xt]&̀"55yc ʼ!wT]zo-/;.p5Kye"%,  N7v.` 7u{#$\i'"ك;jK̒;-_Cn1(bUz&!#B!7N$p@Z/- M*Īp3!Fc|\!;Fr{+^M"hK*d<%4*{ Bq8!r; <\OU;ڇ& <6N>G ejH?L@U0;Zih@xX"G#;}h`hTfcÈmǂaU~O ڊdewfP6 ܥcq^e(4h*|r_(S%Vw߻1UE:)rLAoN6S@=J "bY &{X^"jz& ATᏢčc&f'0f>8VԖ֊|j ~eX <XCTcdtGr~ǭzpUHwGΥ;jFLŖYHs ɏc}Cw boۏemԗ▋C)l]ӳwc7? i ^,-}hlؖ]3w]{x9lLZP IxcCoKPo0h H`J[ <^-,pGsgCh$DtܞC02D1q?{c OW ;7)RW͆W%yځt:wsh(ԾPpJ+B6€Hamj'9YLlPpeO7 \,@zi[TX6ʓ4t̝ }BF$Y :{V.~q% NYpM;W~p2Mai{m5˜pND9?,X qkiv][͗j_pZH3rM崻-t\c۱ۭ 1?x"]9X yf57N{Xcok7[VЦ~זE/Hũk6BndM=F_LrrSԁtBR&ݵ兵ٗrw8Wr-Px NϨәYj~{_PK endstream endobj 836 0 obj << /Length 585 /Filter /FlateDecode >> stream xڵVMs0WV)c1iL?p\_ƌh+Axʊp| !EO{ \Ρv֮)* m)SkJӪ%iBH\T91؎FRļkdxgҸ'5{=99e"G|3 i=Wg Ni-FG/g,UY`8{̖5w-y h6's^iWP'Vz=T#ci!/H\{=d5BAJmv$UXՎZJ^$tnh]p6 K"2/ \ӿ=o| WSGܐALNau׼,*q *}U@ig). |fUNilj"LU@L*Z^zɅ~%>"aǬ6=}^ƓƑ endstream endobj 843 0 obj << /Length 2219 /Filter /FlateDecode >> stream xڽk6 23")y4H-qm5JrPUwd/ Q8:6^ླྀxx\&^8qT{T*>/WWK%YD Eχc1Z2`^JŒ("'̈́Ǎc&b-SD*+3--b]B_N؟)~lUt9[M5H>4.t4K6ҕHuGک8h)_#[ӚlKuhЗ~\wVWs/{r(3ukt4QNenݾt/3o -?-euqxe]m3׺؞m2I|a@EIW[\߻-!ohݙ|l's}YT\,oO;$?ʺNt#|zLn~ QwyQPVb.Kd1Ό>f>tkR׳n.M<[]qA^=,v/+/`2Mk4biº]금@u8P(a];yn*bǢÎ)6'X78(Yoa Bpgr;Y iX@COfMo_9 Y*,.x@t=p އ#}ZЯjduYcF"._.0h߻$۟mB|' 7AkhBkzn;[w52'Ȧ1mZFw諃hX?; )7Mw?<۞m m;M]laH߀5M|I_O*^X q5 X`m((RV`EBj-aȧYZ /0bDI7- tྕT[%xNFe?ߏ>CyD, 㞨#8u_!_4u]!+FFW՜D" 7}Oh۹5v.b]Lu2hb 5ݡj݄1`du::]TCH~^aLfv m=Vv"qQufy"n[CCCv6k5"d: 9Ocnpld㽷VMԥ-, 29L)xeHenZ޿(a5Vx ˶od4smgSe=EUB.EHp)XW/SEu"Ep/$Ys.l0\2LCCOeNc| >?dDO:׸yFWGmI q8(?olKZPd4U:`gVַv8B˯^-r/c0L(5:W0JDžR~K| ^ZoMFN4Bm8/|>^brՉj% k SezF {.dþ{r8DqTA NP֊*+9 ٛaZ@F/ 9βjO(K*HRXqmW8;۫ cImzebHK¾f?@څ*;'\wz[2l }*LWDPS6)0N8$ m\2ug1QR1858yQ\$aqtn_yq@|G_OCPG~vh zµh 0U(P2`LZY#Cu$ʩ*.UGL:0f Lm3}WuߏEՙf8}hL auZlo4!Sv %@]S'JM)Nd(߷9>逃gMڲ\GI.{c/tlj/)yζ7Iz/ XmzPRIH`'~ hE"lhc;MM{ZKIȤn:wSoP8aOEnC +7߫@te0ɲ]q[mn~:gFV/b됡A| $xB6,(mS endstream endobj 743 0 obj << /Type /ObjStm /N 100 /First 884 /Length 2228 /Filter /FlateDecode >> stream x՚ooߧ B'-F 98Fɐϰ=[wwFE 䮇p83rsڻkb6(JK<WcׄRv]\ $2F:̐t*9Щ8T:̣QBffRT] jK%X)itlpIapKqoE^Ȗ[.nrhqhT(0J:kffexe֦#t:Ng;5iKJVq%BSu%}RDV6ˡsYht=; Q0*,8YIh:9s~ [)`eb(+hHN:n5F/HXVZ؟puVW5ו.L-X"c]4v i-1: 8Լ3&*Ch6 Uxz<†boa՘doc˜`o2SY)) {\舭ptuvwl{gi~o37'BUb_G<WmċFuIC:SxV ._?_oܹ~^?mg^ݚxfC=ljx~7}OdO%z/YS8CQ%3g*m[:[h6_ ?߫˫_W8>ί٬f_-zX8B{L=zq_{ƾ'6-LlJ*&wz9m^&k^~hCȦ՜6G^N _w7 RĥBS68MN&sbFAcו1(JX M0IB :{:d@t_!LAL #HZھ$do-=Z 9I&c*CfI-F(认\ zm|Ɠ࿤ӊeѵ6#X|d}h#SQ'C OMr--2?Ymru>&_k9ppb-v@&D&%Q.6r!RqOpb+*^9vLhtx GVJ@iO$8V) 3j^48)ދh E+FYQ`RӬ\%ՒYZt-rdڬ\UKJFW/2rY9zwp"`7"T\t]l }Qd,"nۢ\'~9 HeN*B)N&i؆r6wy-Ka0.?e xD}3*<~z}f/G_^6r0bפ$0%L~R}GT/XgiU5[G;9b".Γ3inShH Adm C ,.yoQdg):!@'f&vSHSHSHS6ǩZpQd> stream xڽZ۸ȗ-Çr"wdYV#K$gww3(qТ S9!n%W?vkbR+" UB Wo~7ozZ'+%E*Sn *B2MPa1HFmfs:.;"o=j7<=MmZ/ HΎEGڗƨHay)_.ɌvZ" TUTp-XGfm[hF3K$hR6^Aʤ+H~*1J;:h SDACZUh6Ult뉶=yZu/٬бM_lT~`[%MJ]ݺbf3(ʬlR׷0w33Vb6ޮ۫%9U١Ґߝw]eSs}>`Z@U hKZJ!͠ hnFWI+#%{u:g")_:S$)4{ݘx;31GwDHH ^طY-`bahջMlaknTln8=Mb=f΋==!>R=r -hiexxC[;zӝD3rxWNVB8?hhy<l(H\/ U{v{j&he?}=x46F4ݫWXgMGj9ׯ˶Kz},lvbU:yp&}Z~ }`V{zF۝Rě4:\[Mژ*YQwt&dle%ק\eHڮGڬ\r]pO>GSUeOoRr䉐MkeMf;#7mG#λ6;Ag,N!=¬CQ4#H UXpݹutB T{QmDa7E\;Y:fb .-g4K"ad M 4{C}GݹmaL6`-I-%wcTrDCr-y~Ye):[&:jzxQu-o1H!Nݥ뜆|* 5'[ T[DZsFl:"Ton!*X3i2s<"&C*MBń"`d`G,n/ vX+2RSaQ8$&* -o r H&,J`׶-x7=A44sJ6jD뺡gkPlb}E?-FpH> :/]5_pE)E|j X"|Hr2fd!_(*TpNV-"Px"$B#N ~deY8`<;\u+^%b|?K#{`2ET5:l Abw0vV^ uֲyϲơX|(0# :!Cά w(fqۢ;W=յRGj_ڌP9+?<=CԿHԭ#G}3Y f.q;S'uƀrĭ W%>1CBxg6nl( f/` 'Nv4=tM͝P`'hA/a]س7#HLVnn{ZPo7IEˊCih3`%̊M0QrU z%oJ)K,'`I)ϋ,I0\$#ѬCd5dvp$YN%{@ԓcɪ?^]ʖƐt_6 bVoqAo\%H`KcѸɺ fc DCgcTlgbT~q0XcM >0dMK}:v 1k 񴦐5_tQy)6 =ĩOՙ*El/b.,p> Pnh-[sn֘L(W+9VbEKaTNy{ʃRY?8~)>Kha]Rko,[MLSJ9Jp=-W| `H]5n¯|v@d97Rʛ&t x$@\ G.nב۶9.A$ŗKuLlgե4{pV6 'eθKצ-ظIwdne*X#wt`Z%M,S P] ~yƻ@&vqfFo?Y,]-atz o*&}ZP endstream endobj 868 0 obj << /Length 3084 /Filter /FlateDecode >> stream xڥZB'[7N4i`_IPPJCY}gvf:q{3q#7_mR2<6*E41oooިlJ˜Gp[+\B("ͽE$Tڻ8Tw] PM+On4u]Glͮomy෻0Lu6D[}Ϧx5<^{U5^ϩ}eN+:9^aSN$+OeJiyYj.0AV}(8QW9/pn 6jigÞS{KKQŽ'yic[#{qe[\rι܁FAۡa-[S[vȨk =i n#+M;)5눴Hlb\h7d -%U"R /S(΂\0eKkޡps;'.&qNc}3{Yq:"OpJD u^Fk|AFJ 9̎eDéi[`qnЄ!EŃݵ2mx/8t*ݻ&ieHxbQ_1򂈥D9gT$A L/`;3|K/I/_aKwȑI ngjOSpꉟOfe:Jt/8GxlS2e(tى'!n 34pE$D4 qGd_5BqF!95pZ{jEl֯ax;Yx!&GVMêm%.tIorxNCox0)Q:k{~9s= `gy SG>H) K8w9SX^I$i&q/:^!v/*ȍBp{2hŇU4BO2fwC.0%(v&L5"cWoT9\9`rn<4z==P7Gv$xׄs8&}vg,E v{M>'S[1t1:+jޚ#~v# 70wU8ש2bo@l/< N{? xS-V#udMU+$ɟ鍨9}pL=c,x*xƍ6x`rS;3!xƖw'8O|ARi<}]U+@I_u5q*.c#Sv_ PIw"NA?\F,DGkiW@;+ԝ7'Bjk*dMO ?{E{0s,7ONRDDp7OFvtCR$ԀJ@⼔+rL 7UNuT 5*]qSa\<JNBxT7KQYŴ%:@Tru`DdέhԘ4t~w"a-P/d<9|*z|r=GfZ}i.'nV|4,NV4 F .˅ 7lxaz6˛\5ǘ\!1]F7UZ-P9{W04b:HmEIuhQ]eO]١C.q'cYl}LM:aPgBQmȟ/#*ڽBpW7 9̡\2~% mq7G^# - !4ukCτKɣ =uYJG!ԁSyѻϦBúK] CGoc_ݯpQPO?FEHXM5νHPhKmr M,1_GԐsҪNƔ 8vhTxwXC7{e⫪JgKS4weUvW Vњt\X˕u\5dA+>@sf +"?4k:d@ULŠ+nyP}t&ہgc_dyBAy|<&-q-o3ʣ/[3}wjZIDepi-ǝU=US˫{Hfy=Styu=/NLVhae+;gKVh.L)vvƀT6VKr):vfچ_S^̎:qYY%PrQDo-wjz[5 E2BS]>{xxzz²oE>=ܫ>pƤQҞshF"QCPu}D"Fc-@߉" 4m4mGlYVEh}`[z>E4hD"EDxU}EKHgvQr}NA};~pX!= 竽i"R`#cT&mӝJ o+zq-{LimFxy[>)ARQ\$0TB'<,&(p\JV4?):k`iίr`~ -0fb8>#O01LvRO(5puvkLYi;yMz|?/ endstream endobj 878 0 obj << /Length 2983 /Filter /FlateDecode >> stream xYۼ}>T.b(Ii&"Ƀ"KnwC7g>$p87+z~գg*Z,XmoV2*4Sfݯs[虌VDŽk B+mHh("k"ഐU:Ɵ_nz?Gb5>_m$| E0:e(849~g7šNvYdD/h67mkgoT,j#WL$^M[ Ks(cV.&Ǭ^o #mtLԮ$v0<Ȋ/K D}E_ C֩틯7iC}Ŷ?m߳ixp1"$]؀1~5g܃@U48q0bP?=MYѠJ}ZՄd4d{J`JZ(-]pa/SRI=f#TCZUҤ{#(Ι3c``ebpy-\&e޲zdhp$y^ n& z tm6-Xu}Γ;pjI$n!N~Bmp9"#c_g *=Kz,߀#B l ऍF-#A+޴"xsL󹬚zQxĔ֯_;g-|9HÀgӎEˈ=N is8D88ص_[u:EF1S zXm˶l9 )-\֡x's1Q< |b1E,r_ }j מl_k2tڠ:jtGҝgk?T8ͳ=x4 Z H~');{"qC&{e>x*%VB XXGXt?]t;i/zO{-Yˡ8mѰ@Y}.A6J ? :ajbL“ E5515 -,3k>&(Ymh)iӐ ]B -C"E.sIYtнuĝigNBz8 9vNIP+O;!uv\x(9uGK\Xn}*C-_NWo@aV$[$?M21XN7kSGl- 8xH{]u mkWIa\%7 @DYf}]Z8ѓZސQ'ݐk;o*,~ ?/== )^CղTPQgM7Ȥփ<@$E %y\Cd[9w9obڥ2-ؑLƣJ]~Ep)}93?C[j(詞<|ʑwyR EL++dwjʆ^`'İ Ā q9=j_To!ݗ;_"8S Yf (ȷ(:t[n#K8p:/v`ɚKNi0; v=@مj~YyF&f<rg؊#<75$HvTh}S(_/4*׋o3٧X˶C_!\i؛)'G)Ab/bgZhw[rد;r90rSER!oJܒ_6,j@] P%PO&}KiIqdžF=?Ѐ9ǻ“9zz7zH珠${HطjSz'ZG>X L 'f#slT4ʓBN5DCE( <*Od/ ^撨.sHdpϓ`>Š@DNp)l Se/>ZWcm҂K8?ľ]-gm1'V/zLDPD %]4ԋU>.[[/>wC ?X> stream xY[۸~ϯ02 o(l H 4vQ2=V+K$7I}Mg&}0Lyx.EWw+DJIRVدw]ASF 1&"x֭I7Col73]HCN,(suE>)Ko^lhwo;\rgrcmέNqi  P-x_]i8NRdbEۣ#Zg Uܷp (a9S㜮n;9޷M([r;ea&d$O@[#IćWx.8''jgAр1XM_)aO_qC s2HE6nj2Ar$0+sY~åjxA/s`ܥin!w,fo;ى/$jYDA&d؃SHO$dO}c'[9dže;1)x9-ʷ2"YIXbE׻ivN$/0H'$H "10TɺR/ C};8́Qc4_9ܚI=IJD4pEX^0@b(lG?t&h;!]CpX̦{Հ`dNpR<1oeUZa=l`}qCkCu@V۞N1f@G^L>VTAP˲DkϷ˧P̜=o.QF$LՍ;1X:>U8;GyP <R 1;)ʶu9XuRR]Se79het@CE 3(t4!zo~:Aw7W9|(|7A?hˮ!*EDKz-7j}s<`D%dX0I"IOv<0-gԜ WݖkHt!ļ;vՑ/[o!>\lF}'Ҡٱ>c RZ 6w(sZiT.M#&H.?sHAY{_ՈW- u wHWfR"XѺRR8y NS{:G,^!U}L>@o7K"MG~OLCġm p3MID@<欑qUFd| -2LGRuDsH"?chP|v9,!)yQi/VEt_Pǵ *5^B3Qv<+̯o[#]zNSY(uJ5FZ09Vj,`G{7T X$afq؃ ёf?sfql係yBXxB?XjI.=qS8rjФh ܛ,v`-#v{8 0x %_tB+Zhv-+>lڑ> ̪tZēbD(kv/_CMk]%0 ;UT%&U "\Ֆ1,X(җsV'q O+( K{  raTBI)W|;ݔF\۲4kn[xws]|3NiﴣԈTk,{RBn™QHp^T6~[NCaS~A7t rҙR¼!:@Ttc/N{Ɂvl&%B;OWؾ}9Uj qt(Z!kp D)ts~q#fx&L©0#Y8s_P7n\ђ1B"wp)p@wUeyI}jN,y6ʋ*bC[- 4 HO8|,YHe)?_TG!5ƾc7t˂iUʓ 9F_l[!.`v@k?~,̌w"ڋ9PZvglZXj8dT z4[(&`#y^x/.R)oM]:ڹAX U3CoX1_Rq/8w}爷4I._38N2@;؈7̝{"̮"]v2#xuWZΩ V +`'0$B?oLEYetyC=_ݩ:Ov|M endstream endobj 901 0 obj << /Length 870 /Filter /FlateDecode >> stream xڝVK6Qb.z ٠=E㠇F-6eT7rHh^Glht ev#UdM2Qe!+o{o3FIG;T K0+=h>O jS J~#*5~܏ibreW^xnoDa/b#xQ[܅U*&LcPBm͋lM9U7*)XB4Dn,2U<*F<~AS/󧝚%?4t]WCPlxE}h_f0-8K*6 jWY.n)%-4;y I`w{գu6tڍ( &PFPNG1 /LfнLF$ ?/8˥.j%H^XJ}`Xo4OYP}A-FmWF}\iӮ!'7Cv3i8'K9Mi1aNwOj0Qv @~΢0|uiJ u4咇U^^GR]65mJk5[ev sE-AytPКksߞ?i,:v4߶٠ h >ֈO=%s(I&q9MV;׃q=THϼl%fn4||G1z1Q{=N7{Vx8hX%HSPb%퀿̽\JF] f;5G- Nx\\ >XȄp;̳m_rF h A饂/VM^|КO?KL endstream endobj 906 0 obj << /Length 994 /Filter /FlateDecode >> stream xWM{FWQ٩Ӹ&=h0";>Yէ=_; ;ldz7 ;0܉$NĂȉgGwT&5u, Ӽ<ѫ&w+k5ˬ.2FB$#" Q>e 2"e¢RUjtfBc1' qndChY (;X܀#&:J>EjO=iS>_z._f `tVeZʎ4ϵOBzVXݨ*7R;mA<]|(WfjZ hTVl~u^B,J3ң{.K+UOJ^5 *d/r.h%ۜWYu{q&מ܁ǹ;wj/`Eh-^Awi̴~`Զ%P$h0Nj*{ g?aK#חjǞO2#옼#m+J_/Wbt?> /{WGAeao@8]OֺrI IU!s^Mmf/Uhf%K3mM-\i*LbHVU.EPO,vzi)!a?XԶyh+0Zplyp9'‚BN~I)"x>Flx>z3|z_o&n~,TdϚ%/Uݬl>T>y1.KTtm[3?I#TÑR;,YP<:h9(=zɘPP^%46̕>{!D$p뤴y'm^am endstream endobj 915 0 obj << /Length 2869 /Filter /FlateDecode >> stream xڽZYoH~ /@dXfJ%!8bVC`꯫.zKzo^^={-"/$qHwy0&J^M(r]o^__kyf`0\0=P8ZuȻRPP$ 3?Njz"@!CMb3|^,?l^Oo T+~re k ܐL $tf{ڃ=}r8 +Tv])pWPn0m!rDN`hBrQh%AR*f+{ uM>^FlSpIR~JLIi YnZ)xYlg%b"6P$1WFWIjgZSA…4R}J˦SvQpI(2ČcJq S ƽ)Fs#_pOR_O/?{ QpDO3E΢zOaHDu1KS#$dN:oɩ2h%SΨ_\i+c'~ݑ-w#E^'Y^U]6uwl2$7YjevN^v*ɗVze7Y 9wySvb(E7z]1@GOXt)ݝEy;Bw;^zvdI0]oޚRZ͓mjT;iEP~5K}9گfN|Nn@yRƮݾQ@bg caaW.`KbmmT+ePoy=<6ñ-bvŶf1/֨K7ȭ$fz1#¢#kvL$IyQn) MmᶤM}Ul`p:~|xVh TsA8T,@,}:-٤]Dv4K2_ݲ(0DFf2q;` uw+uWO~A5~ ofh0 R 2-@Cz|Q>0[J{a(‚. _˴22w d+3rf(苆Ɉ&&QBј k 5P ,K ]BҒmoޥk,SӶc1[ApSVR/w%x K0P&{sY^6M"P:gK/weRgEn(* &=jh-ti,M!yCU``.PU-bvdv]i̸q0&j9Ψ^ը)ľhjR B=iܳ, &vSPM"* I G',=tXrXOa0Ǩ!{l 볁+gu~fýAP :IdEb~W6y]LatС=:Ͽ(6 $N-}o*0܂$d$Ul=Po ޗu;/ؒW)ƒNN(A®iic]mG*i'Z”7-+:Mk0K(ieWKgr(iX|Ww`Bؼp&Jعnou!M\.zW,N`Mhh\o̳\oymYyLs<> Z Рh'a”TM4RPNd esDHvO^Z=BT^|sd '&Qmk-hvڐ߂?" :n:;E$umgb.⮨K{Ro^];Jd[TU6 k`D3cI[[6 @Q'L]>d`ݟ#1M0S=Q=RPt2m lh(;44o#(P!Q=vJPǦfU㕁6/!&"2չyCO4OlO>M.r__N)V_s :;Z8ܢC  ^9J٤"T+7hW` gZ 7 ҏAр6އ[k<Ӳ.0q:8lED: $wKT' fY`6CZV~c(*x2OM7>q 1 >|'wO'~"aT J'nyM2>7_M4V -r3u9XXw6l^^g6,B6paO)Z20 endstream endobj 924 0 obj << /Length 2628 /Filter /FlateDecode >> stream xYs8_ݩ~JT;w3{wuC6-:ג?hI8<( @2ч]_\^)%,MLRft%攉OQ&6<%r%\fX$~{؛GBS8ÕSecZ34cJ :6=fF׫5RjHUFu|iF|/Z}cJ3-t˚^! Y8Ab6*(kE9r$5S}ôTٔ(J󬀇w={wDwyOڄDu Maٲ^Ѹ\+w-yo>p%x/75 9IhO}8?Ul2w#dc1',Bj0g9/8Y ƈA@DoZ(.H8$:w9M \O`zvWbδ%+2x%y=xF 73>2uȼnFP6"'l s[iڅ~Hυau(lʳpaF$py`Q]0&JkihH2|ZɖU,o$[ۀ9H>tY (IXfSQ (-ʤ>^qWZ4;'/8W ңW̃ qAX/!)ٺQ%,mˎsc]):jje!Ң󐓖ώ(447pjϵ+B\9^4FwKDp&T 5鎹+8Z:NHE9癈1Lw8_pw-aLs%tWlI=s>"D1lC%KBDd!/4/U`rXxZj>F*Mӿf5N?__y*5"w/nny4y0у)P)&|+5>1`L_G\(^ĺ}tBb R'd)$l Tآ9iۧwVߢekضk|a@ɩfV`2eMӵiOP@xˆz<7J?Xr?(~.OWG?ȿ`aN-Lf@Ab6z't``~l~/GXwZw8 F}K:,7@?|4rtczl2côҨy}o.X˫11R"QL۴+ﱻꞻ}I>*a~k]}y,gd@ ﺂ^IbE~Z=f18|T0g|TuƮZ1mpꣂ?!#CR_UV?C~ tLl@( +(eӚjWv*XU4/\(PQODnmPVlڸg"ꀜbUphv({r+ǡ|!9|Ta;x8N {zk6ߜ DzZ7=J1ÏJ>X@zv/rF?bx HL| {fON<`GC_Y3W5N JFwuH[oEaysb;c4Gfʶ+E`0p< $i&Tdr˸9tٳf-Ycək8u#ao zQ5 :} ;Ѻ3E>xF Ix<8}/{hZen)އ?Z;OGmDKPt7PwEn>`籖N$+ wOu w i]WfOXѡ)ġM[lke>/ʇۯOq# C%7ZxvT{آ9D j7J:I-χrewѫX݆3)^PVGKR [XZ͟^ݮB endstream endobj 935 0 obj << /Length 2247 /Filter /FlateDecode >> stream xZKs6Wp|< ;N7=tDh 8#QD%HɦQqBbb28G8yr-SDZbM"*5\FR@d}ܽyz:{TE# A<!H A1gٙc&c?)F~QGwWѧ1>g3OlXo5뎣1'¼O,W[y8&l 4Lh8DVBB1EbIv6`Tm~e<]gŌ=+c)"Fcbڋ`fH ~e^.$pLv;vklL4!XNNEFj6eJV;X /ZZ &t{ dEݻ C%η.7gk>Iy [ǯ`i=X0\#$6-T1*e#IDF@ǩ{jZov̽BiXKaܺӦ>?t\z,uBSOsp$[|Of"+{dED1ϦOhAaZE_ݨUDU>^/# a5V Na1Rpԝ.ߒҴWeT NZ:AG\c2pD݁ۗ gKDJP OKJQxbAv|YsyS-Rb"._Wd)bpxgػ 뗰=u*!0#"Ýz]z/H"͎4~!ᆇT"ٗnɣqdSG^KJ%$BQvtЧ'MFr4_w0GVfM0k>>Uj;י 1CX[mm{([hZ[$˥ow6O5= Ɗȧ9Fx\җɻ\ wُĂEbp͝K@X,0i@ '(HCa++"#J{iR!cu`H.0›>Gft6BE8![Ne )ʟl+&Ԏ5N`8p(oQ.F;+&=_F{*!ROd1UY!t,ԧP^ &́.?&[ȥ74tn~[v>R *pg${8~l3]C1HtL}6~\[݃B`-~6dtsӥ#0Ƭ2m1F!) EAv,ჸtsf׹u`0U'`F|z>C㋵FI,,$bqHv+UrȎw+SgǷ sR5+!;5 ؾ4+߄klmkCLMKr9M͘,krE{W>ic Aqފ Z^},19}M(A;`qYܦ?m,%,w? 8>J AM0޼=lV! ؾqb~!`c[Qfմ|AolX 6RR +ӇNfoR kOòiZZ+ VP6 8`I~5ayr8$gD7> stream xZo7~_\ɃQ M.w sypNX-#߬%ٕA,9 WUSHREZJ΁S`CKd.!7F[Cц͟@IҢf D :KFs9cTlͼcS*Z LPbRq .4$FƅP!薂0ahW0p0eX[RdhcEZ w*q+UMj;pŝf :CN  J.((C"X4Wگj 9%ﴐ MB&Xn(:şm ^ zO )дaչc}@x}iA;,j+:Xˌ=Gd~B-h`\u &wQE#F5 ,ܩ;TdtM2ђʢq(B<܀&Tu (ܲh܁_n*{P6Ƕzx:-w}ɢ{_{|uZ/7wW,Woׯ|s?'XtˋuxEOL},[ΐ{NNBw^B4|ss/[]9GsmWX8 ݿ_XI}b؟EXvTl=[]{5 ؿ ro.# la~xl0mzuq Cн\~Zm{WwY^_,ozo=_}wS轕,[* ^_cGF &w2uL7F_'MKCC+CC1Ў X+g^U8- c_hy="''?Y׿uǏG럺ݧx vQSU[dPn38%]1z7Sv,%Oѥͨ cVwȢ@`TƴXbq !A"\(Hho]ח?r=:X-hT/ EJ,!Zz!ZE 9NH~HD;Qt{]ޮ/.]o?g#D @-EE&S4WQ1!*4zG@oc_=yLe4B2ݡQG1;6lV6D+ ʾ=f] L"4, 5$K !rS]fTAM+!ׂu|ڨXLq=-293iqۇ[+;&WǗ-RÑKS-p+b'E rI}.JIu3{n&9Qjƴ P^bjhH]C: [bΦrxTdcTxrLsR֙?]1 0P)܋,LŝſSj6(d@(sf>(ſl67p(B=$o}~w(1wܬlTy?gR9Ieʬ , \/U'f7Ǝ> stream xZ[o:~ϯؚ.=@wm>Ł,ˎ#'-KNHH493g$ޜ<{iO@a]<$6&˥w忹x2f_.{j`ugsf;Jl:J7!"7gi)]x6Ba>#_ntAjGdH^ E)[>vt>,eNbJˆ U3waV~^$](KltzZU}[&Yn&fЄٔcDe˔sN9Z{sK?0*0O)M fZ&q!fs⇋h.^)X̩]E' PkړgD8EXS1@ rj"6qN,dngA3|R3A|/ sEƲ('H43aE$fzW42iS `f 6s>26x >`(Rrq .%әemFx3;OOiF a^7 Dx2^`_ ѐr` kxc (]Ac2$ = *I2&LjIN de'#hk̈́4L#pߎX]C7C='3"w}ul҃2)H1~AjH0DSIXd('SNhiRĉs;"`xLzFK(Jw;ǁ4*Bixu~F~2*2$7 ~[ ֭؛,J MQX-` @RwPY#D䂑6+kDna Cnr:8AcLOMY+8؆,BXVL5@v&I8F8:0_q> A)CLiu3@Y΀ p}BV]b'uJ/٢ v3sde 5ll)QEulC \@|h3&lb&T;SS&`m7S6\,P~ɧ9HhF d bl0X-xMR wH~|Qe!Ps>AJhV _8 Z֚jNf՘xEzbjEyu;@Hbq,o>~Wzm+äXr*0o\u\dtIMyț㭛xp40iR?/S`hv0>Ls{/y+0-6ai7ÉH-~^$i =>J%',ߛN^}b^APH.+rVSCqexY9O g @(F Z ?Tp i} ]p}ѹ-f-1}JȮpvOHGٮcl><즶`CVfQ)kKȫ-ݫ=18y"6,3(foUBf%=di+jQbb4 2En߯`0`>aB1˕W׼Df~C X˻gy˵=X;A&)ͤpR;n̵QoKHD43**hrIo.tN2p0<{ChaGЛc퉪O $mSd^Ep & endstream endobj 964 0 obj << /Length 2742 /Filter /FlateDecode >> stream xZkoۺ_y,/g@ONҥz&: LͱE#I8 }YJ(D>=c WcIwNS ֦ZMkS!B!A n%`8@pيpx]4nN 01s{pM!tI-ɿKJ8&|5Yw]Uel'NM6#yu[Z6Ln2T 4lF#hWds;HQ2" 2y^-+(}4@X1~|/󝱩c2/V᭙m3e y 4N ka/4z1QMfAy@7&ukeu]e֭pld\#p0eV<.yF)Q;kÞ6]0eq|u׻p-9K)K/.v Yy5T591n8 W0tOn-OxWwA&Sk&O"Z^'=ng=̤ΏnMi7E̖¢Uocڮ^؝=XÍ)=|^2x0/h* +U4krH3pRZ be:<)$mMMY*_hL7i'DžxZ[mU-^|yV *ʛ!`Ry(wPMyl3Z #0.oy>2l{[xH[1=O aBÈx·glX>mթz_wu;AK oLXʄ L099 Wަ D|o~FtQG3 f99qo7eUci*~൷6TO4T "ZBU+3Sd\+ OLe=Ȣ`p[%J(ABؔ W o<!80nC0"?H2( %r"BWa`؛K9T TT?;|o=Cc=c WJ>K/.p endstream endobj 973 0 obj << /Length 3198 /Filter /FlateDecode >> stream xZ[~(\yq 7SNZk c\qF"jʖ4->,47Μ9Y[շx3bRnv+x;3nuެ}oۛ??z")/7 [،F=a{[sWo'(  -wBn5FI)OmAѳԌ2|zݽ֌֚THukOM[yxq*^{(.JR}#yDNHmGduuU}2p$Ym1KߞkexI6WxIKb D"` )υIca Uq8]. +hN' \5jQ (3Uěxwr{tS t7Ý]T8],{_oƿ.JXPKhMlHHe%x"x^ Un۽_`ca҉ǸWٞ~w: #}M0zv_+J@IjJx˛{PԺK7P,>uV6  %aKlܢlx1yin4hϢ4ա#ŏRj/acNU $uGQEi@fQ0[_ͳMr( $M)f_Ǫn.mOEmVr:!H.Ͽ7Oh W!S> '[T(0z[&bW|7hH&˒NBlhx_ =n:۶nx}穬UˍZwf[i!^0foߍ%}ANM[Snf_* xUYY4֚hYPiT.;pNhZ5(˪D 6/%4)x%C3Bq$g9; 8@i#eS_y%[Qs(\$t7~y]"bXGm!eJ*F @%|Ɨ-rWKD &vyfl怋;5E- mg=\W/h=š_`:Obb"%BL0_ڹGFFh&~if2ӧWjau0(rϟsw*40K#0@BJNOIJ* n `h4 4P$+ʈkЙXtYgiHoB+A'aźeΐNMKK:5Y -B PF1M1ćRwdp1+@X8z% -G0'ğއ07⩌9QvdPK XVu#6kؤ*۬(٣Xf&Y- ,#xB4q( 3<'y_r ne’L슔#35Iz?B?]?Ā$&c-Zhg<9N+dV58cU2t*03i).e^ ~չޟq:j@Oo! gQ@FDc^8 N?HpDsiOMǽQtˣ>j3ElG&er'xr^o`ImuBhF0 h>R -\xlxtZJ 9?!Xȹr@6wެ[pEʐɂ&ݞ[wl=twuu)&Ln:LD4ԅ!;t7ba}̗؝xrVQ/P1%! V_`(&pdg,'*ifx1!^[0z&Yx7yE pfF"H&f-F@2 YC@l> &Nc߿Rq˪>Tzf ˋ;`p%oq#:@T"@+(b͍Je%{}l9baLH9Az<b8{_eG_V=-eb0=_; R$agTH).p?:L6dn2^JwQc5^-i|5+CCʆ W-nM j-.*(5}d7Ch*nb?m(sA;zxe?hp eǪ)z~2NR@vH,ܯTI_ =--AW=t{?ŊmP\,Ll,1p8KP M"k< "/+ЅPj˾ tPT, ʩ xQ0AN L/'s /T= b0(npy]-VQiHb٧HDJ I4t~:0 6+Q.v˥ Mn5G\X. M(D. MP|if0ua '+8~_p|?W=wH "*!D]o G?_ՙw$p+p:<w C=Pla:\y5ʫ+<3a3vW]W7=b05#;^ڊ\wۄ9lK!hcY}*jZFy6ϬQvQꁇGJDsr%wG=Pdr!E|ģ+XEbt΄KJ I/!-nl u a]!6)kDKd5I9CF _}hw Aʳ\ ,떬Q_H̅~*ׁƃݝG>FˎǺPJs8c(Ry9&^VL"9[ $:2ehtpPLΖ&#-\GP~S&>yO endstream endobj 978 0 obj << /Length 2782 /Filter /FlateDecode >> stream xڽZ[o:~ϯZ ,o@A=EM AX8#ɛv"ۑĉ@$Mg> ɏUD' ))ʢˈ$RE*6D{|j2w\Gf`]01zX JX$D땯YU718V-U\d42ЄόPE[seR)[KuTR|S%R*}-yqYјe1Aū)Y^ԮV[XMʩՈ'"Ʀn6c&< /ߞ{qEaMXpeX`!Xƒ2/0$hP̲*0 M[-ZEm.6y#j,P ¶MUV[7y!`u>1"lBَ R}'+ȳ#[zw0Or˿P)'\' ~λp> Y"n&$Ub+G @"LG铰b lL2J8s%CփkPV#3B̡KYigCR"Uz_R}Ҕp~,I3[BKeQ{G>RA< m:jofINb3͎և^}?Y)49pm$(ПA|[1ѳWߗ97vr7~%`ȃ/iǯɯ>q;"vOHd1GGn4\wm_/D NE nR4U;)7+-k2qBϡO,[ v:-Cra@&pp0ns0֭8|O :!(#R ~ N*B Ê- \ȯ͋AO&;2)m ŏC!nqɅ̼sUd7,ƤBE;s%gb72 [bjȮ]fT(Vq̂McXDpm4g+dwZ4- _LA4%ap?Jұr. ' 0ARс\w0gHcW-w,V`RZ\ ?jͻ rBZKH \\caaU5VjYנ!;KpawFG@NJ[LSͭT\,VJ;p6o쀳 xOf:2r(n^< \az7CA8$5٥͍KƐBߕTJě)ZJd;!%'6*migDnf\[v1&t~By?#f  "$5>JGjLH'|áR32 ׉BHX.%M1c*ɋ2+J!ʕɤZỂ7ZxӣYt۞L2DEhYG4z)v?!|^}b=ߐ+lȈ s( rXqx[@r ZWB۲Q }Wtƒvީr;][1\/km=ۏq!u.\OMtf獶yi|k9N{l;͋:$ύf ż. S3p8Æ{7( f{KS3#D%$P!K$dS*g~:` <eO!V|`YoiHL'GZ8V&_1z/dm<y:?ߝ| @S婣OgGP: ۸?cEP"!uGӍ={Pdp@d` $M!|}z;I}ݹ].= 8Tfu*$>3m\_]; Dm7|XoɪN"a{C_%NQQ> stream x]s6ݿ>| ݍ;M2Ks{/g`5E$UvDtbi4.<xdzWoU,ήLGqk8S:8[?WoeR2h":=恈De87JSAkNKy{WEWvBt|E,eĒb 견REuG:"jτ=v5]ѣzѦGkծ 4&˻:з únIYԵH*RRvn TR(PbJ@Q#gͦw׶vJZѦiP:ml)@6y~6\@^M)[clʰ#sަjj,O^bж*G9AZsy諢U/K-jWQ^mYu;Ԉ d`du?QˈLYr.K;wx 2<pauưԋg[R m3s{elоa ftd`gn*x<9K( T$6SLbDA^1fF*L(aWzm #%n֎iy0:3BByy 6r6R)R"-zxMyAG&Lͭ'/(vɣ :B]Qp& 8ӽFi_RFyk}گ|ٕ]-ickP')EUm|p{g! h)Iɟ'hV`ؗ3䛓 j*M[ D 72TBJf&%OfKaiL3ՓHSd)) p%#*c8T BBǚZm%Xz.* :Xմ_xIg/> U/P%^ _E)NjVAMAvɆ?l1^TPB Uk_x_ d-U}K|mR }ՊNh<*"-2"4!ʑʺv9HXq!5ak \~(F7͟Tyխ]0#IJ+`8S֣i;48R-S`EPmTBQ!ٖs?M#`Z-~Ny41M18p >8>l<^&IJv`L 6uJ 9-.b^cuO^7HeAf :_ea(ǨC1x~"SCCBLsgƞ>VGSт'o>]p?c' endstream endobj 997 0 obj << /Length 1453 /Filter /FlateDecode >> stream xڽXKs6Wpr7f3Ù4 ST@}RL˯N hv8Y'84y7`*ɐ0I櫄f %5&2L?C^?*!i8# A MpT8a̘@J 51վ\4EUa[Һ܆զ 37MX2,Z_lQ6c.:<R djVNJM0Ng`~R.ܦiIZEcz9CM}Ƃ(c_;1Hdٚzg VS*Dfs;"EI,VNd5%Ώ\c67yVվ0b$-P2`4Z}@ƔaBXz=8ؙewg.zT|m0ˆJ00$ENLl+g"_x`+Q$!vry% i6!%MmW * q J쐊"xgm] ٳL]t`s:pBVA RDET@ `֮O# km)y~ \Z(L.g*%˸K@^]~AL;0 ]4DPx;{ Y̛y~@vݚW@Kn'592BXs9'Cb;PBA# xnI*E$\oHF?lhx \O^RFae|80~w/; 'Wgqc+&uc/0LH5:y,Q޷3) qapǜ I*fصti5޺ٙhZ[lBj1!I3 I<ç#P)8x=.ǩ}fQkR-a&[.0u.n^mH65 ؽU@7l`r:* 'Q;?k1 $cʋk3^@" rm[^{F"> stream xڭZ[o8~ϯd5ËDttZd4 tm3ZYJrbË.&>4<Ν.n";LЈS"%O(cS"b]?6zךz G(oaw~ØYpC-bE2&~j"osӸu#q!LH!,Ϧmwݑ|%ꛓ|[zo240sΛΗ NɓrDp$C@e(,Kf^ߢu..$ūkX=Pd$iDnt- -@=n0&׺Վ>*Rnn.o7qnDE`ňTYP@62&eGOudqJ$!]lrUƛ=&[2gw…&HO:3<54iu4#PyTŐH$IR "%iIt`Gt.%ۙ*'9OI&`؛Y^|'MY0h([7H?`fҊqNCs^*f%Mxeښ)`~83- 7n0G8!'.P#$@7t4^:w3Y|fGm$6)7/1+YL[?]~K8Hq!/W,b߹f0ɘ&d5.x@^JXv쓫I.N8%}ΑɔPT4}XH-b ng#m{^o(bB2-h&1(hx-SBq`C@l(&ʎҒb5fQCPC\ymKL)NR :\] lv)]5!iKzhoYΘ͚}vm=< mp5j5}5)I@ Ob3JLtB:gYb8E iȞ4pep븛 kTβneO\C^2rs'K)jdzDF j'Ռskzq\Ğ8$Lj hֹ@W\8 ؂FzA*@?L@2Bߐb8ɸ<+Pr1H@CGi`ܫNȽ{E̜mC.kPO)vbq:ŨP$"= -=XH0z)F3Ȇ;"S\RnNuB^QXt>= xDXfb&Kއc\wX //$H:"׮tCWtzk|run!l.cД{UOBҞhd c-K $I"J$RvPHxDew;ؑRPbYyR'g`_bo܉;׍BƯv3}&2=;+u>_& ۼ3_@Ws\|yb"A+>5e}C,S"trkqMTxQDO*Jh.JR+Ror;00nb+[/-b:jsp?KkyC6'7vtNb\g3,A뀿 O9SFhOc%ziɽq> stream xZYo~ $> 7; &ZmH2ꃇDɣbA]]#p0&,yN: hBE7vO-gӻo% M\sfa쿿9+XdX9'<6lyv{G9GD_leĒ$q_NBG PCAМj 4t_t14K˂F$&b@V; Մqc$Qʳ_1~aD#HKf!k.a >ڗO9)]~/U|^6Yh{'?K2zX m'0} Ɖ!L[T Qp?lR>b-ҦZgqHŐ;)o$w۸AprI0+RYnWنJi*5l{uTVͮáuIA ۫D]pńG~J 6d6oЫߛ"  P78"!2fP5 ׊>YEB _P%Y̪&EXɇ&[9fR|pO&/kæW|zzb+̽iXBRb)ZeCqaGMH  AEm^BEn  =U2x99`>&įZ m' sJ#Ă(Eˬٓ#yb3%-[цFe?h'^ ,y̱Ex$F-"DEyJIɪe^ݕ56=.eXm鞽'ϩdՐiza#jC.2>{JtRm96/`P%Z׺.2>Wo<9}v/KpΝ1T;#Ÿ|d#g=ma|O-7꼍1(1q[o'߶R}vYSbqKVߪ<9,UD`-zL 麄 \͂?6Nz}_785&H1 ڄh_UP4|‡RmCy| 3 l1#^!42m)x[B*lV16Ѐ'ݨ}j,xn/',,,*0 8Vfx'77&,t~mi 9۶𰍤v3+$)j\mO,o4n6 hr,䅬Ȫԧaj<\`.QTD fU9ØQJkCd4fY,|BRp6+»-Y6T애Ps4< xk L`"qXÚb"|"j/Rȗ/RtpQէ`'ʄ裯Qtk.Q`="W4PqXIQESî %rV4H6N3I`$ m։B!b6)i^.7ڪޡ@R7Rvsv[*Hu#Xכ+}T]\8^Ho`3*ܴ[0?>̞ko$( ܣOIph*};';h?u&{Z$=3q,q_)W 8Olܷ=ps9m> stream xڽZs _5sZ$6·/wdҜ;I&-RsTl&{.%Jb=}p Žǽ\\^؋Xq=%, "/ OM쿾z6嵌=YLct-HϞ3lOUbiwi?~n2~~]eގ 3)=[9# '򧓈iuƧV8p#@faẩ,wXcaDC9MM-y]5]j<튂E)"TjD@+|l2ϐO2O'ᄀfK΂_3FooWҪq~gKzY@@D 4aG=C4FYtŬ?.>k|9O.哶"8f 6ݲnvEx]4mg]ڧICqJ goX :a\Gϣ:'pV Z&=;9\ϳ! yJbW=PbS9[!0< bt{:)Vӫxv%mh "m o%H%7ԇu.\^'j?RDXe t0Xv;Z ঴W(`$iF7LU3wJY>7EMQG A%us|*W΁+ >MŃ.> +T~xmJ[,Ӌ5bXrL:N-tW-CnRQ2,sQ, UDrQ zS? ~@`i"@fRKݬMn[;w;TK!D8䱭p-Tc;~&źčSopVR/ɤ.]qnqk;pvn 5v"Y,BzӬ6oQ" ii[a,t0#Gk=(IEP@FYԋ&]/Jk?K[cO_o\JU-S 2L6~DK0l,'ns(&?yegsx72e]}5ZvmBPTY,$sBCm{Ln &*UWrD eP386F_8t]^ ^h8Dki~45YUmKhϝXMlNk>]op| :)E5!6oZjsRP؀Gd&nSԛpA2ـIJc[M_VugED.tG;[~VJhus>G > >FP2 (f==7MEH oLQggyA\*|j!\oYi/o dYiQG,]|,.h!pۖр2,2()M({_v%l9dn-dtث.kM3:L] - hr-XWƴa-Y.V'8$ 8ǦdMxf&#דz緍q9I{3h@[wEB偭!ˬ55i meBރ[3@coC1)fX"e"͖M ]I"+mx3p1,wd/h-֣j)۴#t RR_wiڊI/W&0+|tLR1t ˫U` 55]4,r|6(G vq80#dGh|c^oquGh {--2e.m\#G߃om>I-|'su z^y.jU_^ Xv" endstream endobj 1046 0 obj << /Length 2742 /Filter /FlateDecode >> stream xڽZ6("Eiͳ9$wvH֦׺%$Yo3kCVqqo~r&HHc_.7 ""꟯ſvF% Oiz afvb'>w_Z^H4vRiJM\,jC_bdyIvkHX ImU3Eݼr=LnY9~}eD5]DP:\,!k;WWZՆ|sBu(ZCE}V7F\,4~0n jI޽`bݡVJލns.4%niJF`ʕ!"ҜHrZyw|V{HT-MavD |u!-L֪*,/Y*ڷyUfŬ8QwG6yݴBG8y(0mcNm7{z5 m5}0 eȜZQR6ެeQ艉G^F@QplJvgX׃DA'Rdwgv1a)T:V4j7 퀹? R@Cԉ"cy.h>AQ,Ws O#w"N I؁<a2'\4O@RZ%Î!aH l^E pυa@ $B9k%"yގ0dHu;4;4& / ] ?}hjd=)^8*GCNwF`ynBx4. TR (6_J\Wa#,6|ni6{.p}[k?pV6$S;)@r9f ?}L"%id` %QC<./oφ)dL6k7 ,xsV7H84nlx8Vg-eN2fujM> GT㓫۶Q x/H*a.VĻ4ʪ\^;S4)GA-⁌'wpвǜmwB]o1RB e6Y`;e|7YsO-OTȓk ~3 h$)vƵjh6E󆱉Y@H$4l B~G&8YXˊt$3y}[ n]X:O{[}tXD 1&9`EdM.HD]s]K1/lh/Dy%ϓ^X#4'`;|RR(0U>*GSm46 ^,B|3 Se? :w! XI(h?9=OVd xƋIu7Il/@TݛrMqF>@,dafXȮ6CcJ]j0De)-u"t2,Pϒh &M_Kr09?ۛc_X?g*+97;gkEjMb v:dd4[زkc . mjGU0H〯zDafq!F抲zͯ}݉̕~cΖn1Q](Vt"I˙$m1(`I~_G 7Г{l:0;q`Gh8S焻`d9OZa ^ѕ8:~hTfjKܖ02!ph5rZRoɊM[g;|g8?0RW_PZK2G*rbQ긭&BDW*Zm&pҕSaóN5S{7$yU@ѝPPSi!Pg۪*[Rދ3[Pi[UwԢ. p"t:{sɇ::qV|#xbn\]rq@2x&9c|mh?صE:^]0H;H'xGwd[Br%~yJH! \'>LFC$'o˛fl.q16]:Q:>[/~ul;e|Um;0RAi,s3U(G>e{D  {vOVr;%bhXƑ ٸs:{NP 'o> k[:8ļmLuZd06 Logx^Δ|ܶT.WXB iwC lQ#mto1Wî[nb⏭b;/dQdNG:s}̍-[H7Xe &Xw'~eP"z,-O굡 !8~_-^R endstream endobj 1052 0 obj << /Length 2945 /Filter /FlateDecode >> stream xڭZs6BtCԣuWI{wNۻQ,9V+K>Il@PCwGI ΝÝNO*p|\8#iw| }J;ݳ/o7 84] bfq ;WqSJhV=KN2r.,Ɍj5é$_2r')TRL"D1=?-)WviNUZ^ 50ɗͤ"O\ViGdZy@(`jHNN K,NHx7["yz{s:]dyn|ܳ"cܡ֮S9@ ^Y%y.yԶÒT ۡeiS.줇ER1baɚ.گ oqԙln'S;ȢKeIrmDB`.:/q'7ν5w13t,a4B2HXe۳Amz>̳,HXσg }kpG0;+h r%":ܿ,QV. \xbk[@FO YO0~*=MIY }{v `"8фr(8=\<^bWjk#P{LfQHbGvIWq|KyUi$?=([&gEQQ^Ӕ7Ų̣7܇`Rhd\GPR3Yl#4>={.9=8z磨~1LUx8'\3XgEwÀ O"^h{[`hĒGNQYeZt sE8дGC 8Q 7:|.&[Р}0]>8~EKY>w|_2 FuZ2!\zo]8 _R`>YرMcNl0  8a-ł ̗Ydq_igw#*[w:*~7.EwG+y0qT<8TbuC Aw0i]tpStt44=0 CEIH"`\6Bʗۤ< 59..IR` I8㨚}#9Իt !\qdB&DEgin-e6v&w]1D3'~j#21# k wV׋{ ,lR : "!@=.TσZG>g7r/()f\<N9f?zpuJl44C{0]e^Iڸ>FCsE`0\ 8 1̆qvř'ѐ!}dD@_koob+˷au\p6/;3yJ&O\v_:Rysڳ$,|#,ָjMjhGUphq2ɢ22eMLY^^5wv!h[O6a9޵?\Xꓗ㗔u!bЁL-0GjߛR</I0NS2ۤXf;i*'XIhKsz>Nj2nJNURB/-? 'J&r>30.S'M/moTUrOunH­,ڒDl1!Dj&;)o@Uf al)yh57c!pzo6g+o@X\:_c2y(ٰod 8&ej, G]6K'wfffe?]-f@+A 3e1Vv+ wJg>53kC]gTA#3yA526eUA0EJ-ZfiܸOmi|X̪~uNc&Q,-SJָ EAgWˬNS>8M뤼?l)K8: l*Aˬcm@'!zm0ޖvaZu`ׯ7ׯ2R[, j4-tRĆtxcas~w0jL~u )8ܸ'Tݴͳކ HVc]1ʒ5yOztWT`NO%8taW_FP 4go6XE­մD;f#q%|aaW6@s_J!TFuj'| f(A)w (zgna9?-m<@opd)|T n Mh X-~]M+LOpe%VtgoV4dPH <_]!>yMNLq6"qqpֺoJs ޵٧&3WQ089[UyCYKm,P;ź2 Vv>`v]5q@ ,YK4VPyFb VpR\k2 endstream endobj 958 0 obj << /Type /ObjStm /N 100 /First 931 /Length 2202 /Filter /FlateDecode >> stream xڽZMo#W>룿zM 8,t(L.$*{jH.=C15bwuWU=Z\pU#fWcp\#$UFj5ȂdRƩ$B"G+HO$\ӕP5poD\w+ 4_{uq&^MW{j]Z.o|wtVvw>Pu?/9`np{{yP +bW/GدzW/>=_KY]\ ~43ŬoS x>Ӎ:=!r N l~[Ǹ 7{?{\jIuTv d(SU@,z6g MM3,GC˗/a1.of>0 [>'30{l 'y: O'z\iצnՃ/8Uϖ9{˶l<^5s_~Lɳo6$D[j|ԯG{bN>D$=F[݊S8^g)s=\OQ8` < 8[Pzvsۈ+J>[AᰥF.x+zrJ,r/}2.>.)|/&=PL=spʰSdXTHz)6IWOSۧW͊ZT:@/%H:%nƑ4V naQ#d$mmĖS؉&kbw\CFW;1!ͨ6[<<"=p/S'բ㟮u.xWwf9Fp-QZϛ9:)ꇾJj*q}ۉ=٧*P `د'D<@(t綂pCvrQޏ5:([} 6DF ʉ(3O#Y-'vՎp(j}Crh}D`CDW{P9s[e-Gl ty]*2 (kv(`@Q9:id@in"_2j~E*hGÀ)z3Au|%a+'Rg!n9=ګ6({Y7({=c8 *0oːpYk"W{gqT1EJBb(=٫"I|t~bvK> @W,4{ewlq3ȋ0ҳCtY("$0$PqaV>CA>&2ٰP6¦&MMLfkTKV1{Ik6W|9'vv Ύ-cBsF FH%ZRc_XJ@y_CA(nB{-{ugY$HF%":sѹA;ȞL2D ?q퀞 UdaA_iPu@󔪭)(y-YoA ^2Z.:.Z"k~>gr endstream endobj 1070 0 obj << /Length 3297 /Filter /FlateDecode >> stream xڽZmo8_a9@E]oݶ68Vbme'M}7!bi 4%ŗpfh>˓oN._pYMM/)go~|!É, W{@ pK~r)pY4JE8a0:-rӇ^R{'g"oVI^ۮ3O?IPuRzЀL;ef"uUv$8S.<MF,۞D ‚B"GPk?*eXTy ]Zٲ+K)-@zll2Xg=.mra14&0pQ*I-ZA+%Q. ^CɦL:߀.Ĕt R$oW?1$d֎*NsC0|Vv )RKqe8m鶇Dx eA=&DnN<dy=a?v).'7*EETQȄyW B"=<3B|Nʊ:|iIP4%BE`}zK@þag4bEF 7)'_|5lyD؅iSD<+&I,;1 !\s@ȡϴPÙ&T~ ܪ>^_YcC@GoқsWwW?Nvٙ7:?TcCK0ҥb*L;꼣qy2! tda 4 <23!*:igb~ڈƮlk9&J+nc#`W )_ޏ9B0%s|9& l+Y9$j@ ZE3@xs>} >g~NuK>i@ 8R`":nBUtVp8@܏W+ Rn[toւޖ+1ΪHz~/`c|I{d4Mģ6h"[vq h "0 ~MMh^}3i&F]*l4LQ:0Nxll @H꫑TpavkTȈyI4B kpr* LDڠ!Lm3 ,hJP y"҄_ZML<%eX4JXms)e/`I5` >]>9j7DCԦtd쏕;B=ځdessGS'!㝠'_R VQF[0 a0f0!)&51ɋHN)W۪N eL R*29- )UKFh$K(iFo |gH Q :"ʔ(.|Y$fxOZ`&Ac|J-"~$끇#;@cZ9mƎH>ɘLurpcAjqe^ Q3vLTS6 ̍+V܏H9R;7/.BR^09kFf 8dS89Ȝ0i*2l Rb2*@NƶwYs2&bH.e-'`,EmHTވOe ưϼLb+s!\=fnjTíMD:Jڇ[8h pM+UosRйQn˜Jv_WJƯXYKgn^DR:+v:K뺡o Fb$ -Kp*Y<7Hx&=p4*yt[}B[tq\’M' vn}Qot+[Eêmr޾PZ=sJnCZlAu0`3(UE-z%uoXSmplI9 yZ]&U>58z6 #ygG$#ώ_ ; {Nz$'y腻4Ɓd{bi(kihYt= /~߭˾y|5hxS#`kؕ`[1ԨYc4 |8CC@=G ~_;ҾNO`FL!M!t<|!~aߏ u[U5.ڋG90L+28$N/ffm(*:VOBx?&qy&}viq0C1$gғǸ$as^U4l3{8Bg lz?'džD@!ptYFkpY=dog1ai6v8+xumү/Zoۣ endstream endobj 1085 0 obj << /Length 2965 /Filter /FlateDecode >> stream xZ[o~\hWr7I$h&h41>y%9CR&Qe. h7 b'ޟ$a.brr>cF'@24_ɗw4\ a1?08與am>9c$iΜ)lIL1M4bhr:T(-}~=Y|u1^~t >Ix(btDP9׎LD-pi6)+U] XKXKռ΋U304wLf3h|̗Y ݞ|^etfDBOyb1Jt,6X &콰"id!߲zSNVի1 &ΤQ͋rA뼾/lƎgc8] V \Y5jbl-ôiUU^N=Nbx˴S{HCz <̦3ŕ?~Y +"+jj5|G؏(֖L'̋U+\1l2Z oakmF3f袘oZ()=28fәm9(QVQ4PDB|*"+|=¾Qf߉l'*[VfcH0H'C5]yER3lO =C. |F;h"E A7i R~vpn%c-3 w:Wc"$D$ց5@cQi^k46dPGë3Cu3c*M.7uayY\Qk/ׂ|{y5l !/A" ȫFƍ,Hd H&D1aT8~AZ_\_KzqZ;7U (kb㍥chC2~1*+[<{;\QKUF8LE R oQyg/0 ].fы }V: D*w pȏjLb躌Kߥ UA >v̋2{ﳭ̪Ͳ@~.Aܝbxg Ka o~Wf랜d[D$@ ֣9fUY~~^-05K{,3׫p2YaxGN~?B77bx >Y@XMY&B-'ߏEq'z @d4CogS%ܧ6ty|u;+z,Y!BY朾} =C6BǷO#;,DFKC_A,p wXUM}__ S?.97eO^`H[lsgX-џDd'`vV~tJvNӏǮh{0G#9maMT4rw' I<7]$"06yEK;p"wϙ8IL@$ԓg߅/$~1I84׾Y|.:]RlUlʝBs0ɻ6)\Bc,N?Ҷx{ O#;C/'Pv/mR^}N`|>b Kz - wtS12hR﫢 9,Jx!(>FAXczo1py7n+OyNgҦҩh]TU~/L-ZgyqQ˩nh&GCJ ̰%G hm;uZ%-iٓ QK)R.޴.ʳ[Ԥz=4,L]ƦU'j]LcsE'S.s}~P+1U 贄l-ɇ PSjv*,' ^/ld6$itu֮΂髋%/$cG2RW;!4)DOa0p!v*,_[lVnJ0A=C>C.zU*i4;YCAUjjȮNσ!ѷ&[eW3aZEWDtM/ q͂FѾ ӽ޾cģ uY3\͜.صadoK!֕C0F^ 2h9PiO n;ʳS߸1LDgfhj J B5 BcrVf: L^"`=ۣolܪ2GWKk1@]=NiE>հ(\ ?ubsm5M_Eo};%[%${N. ?b@ Txb ]a:]-~LU=@CAdT[&q{xC ~?Bى FX. {K--Iкx&Vrhx[l>C.xԌ;>#L?zrolpj~q2G&9O0.UL^=\eQ =& $Ğ͇xe:BO|jC hNP ځSICWJߤz 5Z9W.Vc3ksƺެmz)b6 ϊя1F~D! ̺VY ³*TLabPO; endstream endobj 1098 0 obj << /Length 3496 /Filter /FlateDecode >> stream xڽZYoG~ׯ Db9lkg(Y aH!33[]=d y Gu_UMNjިd4b8eFǓ@2z~/߭f?z#, װ+ti\+p\DJiׇM>gbծZOVQ]^UkwO5mfI3}(;:ؕ}wUF}ܭ:n[oPs;ȡΫ1SXD#50V(IaŎ;O ]X벩l=7B9:XǸbo\La߹nK43#@"FP?uSYiM}th! ~~}BJةl2 's26T2ʡX͡ 3-oBJc&t{jfi8ik?ͽkι7/EmUjN (X4]Vzڕ |wk<&\[-U~f4ժVRkN$"p;y%JXב*$8n=:%MV #CGqU/9z3?}җG7mi].Oz^L}jjg?`'2X jڻrD[jʰ/H}`kZ 7ʮ;q) L-TDk|R.SSUB,?]cobuKa #v*`OZu´"M0I-^T48jmgH hSOGM<|t{u^bJ 2S-$"vYr& Tǩ&_cvG~=ա|4J됄St Y]8O?*X <$\QLvotE!}OJZ[b%] !I2)ܿ sQk&:,7Su>Y;c1-3KM_N9,JF#$G8=n9B1XQa艥Xz,(Ӆx,Z[`玘Boh6łw$Cp9 JrGXHV(1 `4#tH)c!d"|q*>r&02URًChR%b!6n@uyeE0Gu}SXބU (#fL |fA(Z(zbAO;q*4_dƕ{ T\LӖ76AQ 7̶9#` 9 8 35a0]C0 H"h)-6Kli;Fؽf4nXmWQudd2bU6t_P|Ÿ4-[ H:}VPuqќQlA tb6 +&^شg1g18c~!!຀ _T~؜!]ùG+E#*z7 52 Mu޸{'PƱ: 5$Ulы#}KDDKo"R(%[l`c,쬯pC$»Žc$Splݽ{^{.kfz ^/WRBLR5lNʺpwΞKdNpY ,ɤe4\-fh?ϰ5T9vYY…ޗ,^ 8n?UW&6=Bغc H`}q{b3 +V%)BR8(W%X䊫SHqIî$ICvg(wu0#UƄҧ8&KĨJi %XS (ڱ^Wڭ0QQeB[ n]ŀjwyw,@. 6~̩Ck 8zq}7`Wԅ-t)t :h_$׶0#EWr95hبA]a\  :B nQ5s_pu(}%Vl̓`w宲zw\Pֵ+_ǽ 0QQՙ{acsUp1VGy`a,LrxF(q\0qz.մVjTI" f<b2,{m|Q΀@P$:FִOPeT]Qf_ĩl֢rBݧsuṟYˑ'9 c2agT` DgF+c{Ԛo%X [1>;({Wum<'q/c";v||Zc^_Z;_/.@Cq)fxO AzBXО7_/>B/<,Q MjS(Ѯ FqE[ISXCڋ3kpP4IV0_'<%ܗYDOpPSRVql=|pul㛿Str[j iXZcUVםb!$բ;"b\9ϳ9>r'/r /2ʑ@Ӻgt|&[:LE3wƳ=\G/# 0ݿzAT/Hllʎ 2vɖftk8s~yPϦ* endstream endobj 1109 0 obj << /Length 3239 /Filter /FlateDecode >> stream xڭZms_a󁚊{\3v8mꨓt'1 Ew AJAn٣htg]\ ihʢ(#&Tt5>y/Wo/.% Mr`B-q3ٿ1҈E$fH#ه_h4wo#JDb;rIq$ʨ"HsNhWl??Giyu6]ѹcǐxv1Q\F(P/c yQnB]feU%W3?N?̄?捧,|S~nG?q"$CJyU˪^IgcWI>`a%N?xc >oG-T/ y,'$I|!Em>~W(Fd#KɃFYu-5Ue^O4󋋻;Z_/jK}{nֿ^.WѲD3s L D```ދՖ>MhVvQPN㮔zym@$:]&4pcNUzk-H$ZF3P"LQƅN@Ipߦ6}6`/@ή5}.hw B \!8!O$hmp w@p)qw 4PsDi_v3P6@lͣxvT#< Fkً~?W_>8I@Q;\[5;@HQ 4T?M1[CD.(_fo|uۻ<%EM8XAj]d]n0m61aءaU} ySw sTi6mF\Ɗ@YDoΊ6OD y4a(z]15ΫC׶R*9[\M«vp`S3]}@1lfHLԚ5kk3Y"$x l~nw9ϔryz^uv`QA1N_9%0$Fip#>-BZi:8 = Y{>j4<] k]|h#]1n6mz>;(A> 3iܞc/0«?~d(1"^@1rubG/]V7+1r6t X~UeC}O*{xȝHS@\48,sw~ u_ Wvsq2o)>t##l5-v|zQ)BwpoO澦IsfWuXX=G $*Vh":A(۲‰{n#j%50pBWF{+x/^a]f| .Gmi|Ȍ㘖O=16[/fCXy4|7ᚏ3rB,Gz**kׅf覿›Tue@\?{ٙW' '[Q]8NGܲ \YSmeC AH8H69ћ`-Jq! !+]^19vU[IW\^7o*Ko.$a׼b>Y2Ės&U.U=jB @`{_@{bd7!XJcU@Tui{]ӇZCeJXce tn|0)at V0ú Fg#/f֏?(%^b4q &z.?5KAw; o"Cĺ=G$|pO2*ˢw:xv+zӪ F^xZ-,`k 'nCoo&9yWMGwΪyM f= qiW`dp@M{rk*N }K#4臄DO0\Ҫ`0tSۛa'a^Q>O@`<:QDŽܵ`ƺrVTl؃[xl4P gyIyq z"+8CXrTG';aJ?' QQ Sf xyFy( :|Bt7B01z vP1^M e+j [=ԩ8qLf]NϜaSCʲ3׏18i-+&ڋzˍ! tS/)KWEZ@ $ V-^X #lr$D`TptZ7SŭOFnرɤSjT@Jb[f_,Cn[eM _lM Z~ZԽ)ROvq?vWWD(|+erc;]4€nUzg1w* xNw|bDur7/aaPLh=0W:*v#zDd?ʟ_ OSv,Oíi\I> stream xZms۸_z!x!0mo\L&t`=TIbEʪA# `ɳ'L%*"A<Pxp1 >/~xʀ`6gG 4\7:N(RDcL'?`X"/2 I8r?!jO)"CP"Aϯ*WfQNFLApী"/pD`Al5+޽88#AEx~ky)F`'l6{\U) ;5}]~n>aRoo\=z|j:>B};tѠp8q"}$WbdeUd( +mfL5aTYpk\5'~4n})926 =BC۬B?4mTxHuW֡!-p!9*ư iGB,) c0zcC~A[y #AS$bv8F+-EɑpxVPF؇qh,boDѤhÔʻo;Gvܨɚz4@ׂ21u@:X(sg]5+هf1Zu_qxAc w(\Un*//eJww?hz0_XE/=Ѷ1/ v7 zϵYk(87h(>axU'|Wsm as.KlUfFIdN6&)),4.f K( &!NO P6iQ"5jhq Zupe_5%}HO)SR+RFKzv' UM25^gqZ̒.̻ʀ cJ4`m`Xn'4xZGjtujzWZ9ޮ[t2̳r|8mo پϊTb6.+5>aLɺIbЮ@Q`3uuJ`u89Jc[cJq!zxr+ !*v0a*'9yؚ WezUXj֪oA$傴rcժ5{h &PJlGmA~%k^~ 8bt?8y庚:Ŧ̕2\JAUtf4eMF D6JsucZwJEA0S5U`_] >9xk.Ң نI=h庘 ,׵+]~fӲ9ç2B N#+\ole(!j~vON! ll7ʇ ֚!q:u#-i0OQ p]6t!s|f4udXh,pquq4nN7 ֘6[Yfm/̊ ,bZ%eѸQ0y4}_ApMRBdE۫m޷fN ]IӖHvwƮKI lVQ 9cΚB2!s^[wZaEdAG1 )5Ljz07晶6jjnl2-/T3 <.MB:W4-s.L+q.ZSռ~x~]=Gj_^V\PwCqx]KK,Na-xwxP8ΎyoGM&&y,k /HZWSJl1$ik+Ʊ>3PR")Zi]Du\&sqժ܌Tmy+1;N9|d|Q4DfPo~ н(?$n$H8)?Q$ڌ?i.M߬>i2)?;Hvo,078>FGp o38:9GNIoRV_t_>3ktw(UBDa@RUsbD [s5y۔DXxT14Hk_9C+{`D{& FH0io> stream xڽZooۼO!do䵡G>nOSxvuHAX,yY}ݑlG:5B_OG~wǻ#M]{{y|z2H( @yJMHo:.ZF<%1-``QtB/'>aJ=E8H o:D9|{Q"Ȼ1+f$˼'BЋIfeTAOqNh۹J3ɥJ HHHx҆CC"(¹Lq)pz҂'#¤:֛GhLR|l__6 c0 \yQ{zginAϓ*1T@GR/:XQ(1  U~2ܐ*K7ɬXj~=f\a1"{4*Mp&b˖[Wqgt-Y͓c'ʁ",hPCsQ,ZqSyYtZZG { !Hƾ(mDs)'Lom_#?vm:ni^̶ N\'k` A9+FB8vټB`5=M`7%4M fᲚcP[6)"[; Оe7kH5˚/>Jo(nٯM:82qczc QƦvJ1ChZs=wZF"=U1( 4?&'J4aͻcLJE{_41sC%c4+{廵vSg$B^׬s33y񪨖Q#wq"4kP(ag>6 U[< 1B <C(J/_CN.n:(qmn|׹qbU`$cړ!TSXDl,3V.gt3:j]\֕&s}8&$.! *Wp߫U؀Bu%/ VfI*P0?`'Z7f|Gu(Sc v_mU*(͠`#ީҝ&e2ݜ͂s&Lׇiz|s7D[aH(cRM `MAi]3J4a[M&(kSr}Y:zciC0P7?N=8kJϖZ!msu0SKԡ(ڊ`P@PN1rK$>&VO[Â&@U]Mj&?=pz>R@ N[6$Y= $M-:.{Oݖ? 5H x1KDX eD:B૯M߷Q! $F| 924*h ҁm" @ -Z ̖3^w{o@-OPhdV KȾt-Bc ðd]Og`C;(*^_]b߆{2k endstream endobj 1133 0 obj << /Length 2354 /Filter /FlateDecode >> stream xڭZ[H~_ΎJU2h"-mF<`m: EQ M\\b*HKLuDFH c"YEf_~W?߼|EUD0XpفRA/ MHD$Q+Oqgo"Vѝ7 BDNHG.+1#I)±v{?V痾lNfﯬDgJE1TNJh~Uo=2ZXs$$H""RgUo /E(&0QioutAHx"6$G+"Yt&8 Ѣt$"G&/ 7C3Z.#)&FDٗE5X\ch0GR` 1H)-A$4 h8 \| s0z.JMCRµ9d0<fQ)I*k3^.ZNÏ eTIX~ltH4KHbI|'!-i{@)fPi@1E(H͗m|h/L4.$Gn]Ͷqxpdi('S$y'P?^. *D0gڃe]D@)8pxRZtyWVLhad0]?T;\ ޿i440Q{@mʞ]<- G1$40%^ljT '}? 2!+pv)־̋eY~y1"tQ IHeZ)~| f =XTrnƟ\7]JgȷWm۫ѧ^gM <5_ޘ4(A= b'I ?<i5+<WS$bMu˚0,(H -17?soV#ƳC'KgM麓45o]6{(8{t\q>pa)G҃b&&qr, @g.oyz_0'̐{S[Ln>by4 e]r{hpwӭkn2G u.fH:)5lٗg6a9lf^]Ht!ا\ʱ"2V+@Z' FVժ>s]nWFrhK!\O%U y0yzf&41ax%XgXR.F7 3pݽ϶$=@׵UBT/n!nK'\0XsG=O5Jun (W$E|UPϖʑVl2mr6VLTp=)tܪcx+N0Ra'a6həyC:e|=TYڷ(U @:@p$ @|AfBlm\ྕc<}T TL$ hz, 9[>q-MZC Tll9~V #5>!$w rKs0D{3cڏGUnlKpnC {C8w(Ͻֆr ]e;&P֔,[X.Y4}T+& *t@'UFxz|?ɛd[ꅫ8~6ao|?BeE&j ]{@X˧35wRubvkXHXai*>_`w,~?/ endstream endobj 1143 0 obj << /Length 2677 /Filter /FlateDecode >> stream xڽZ[s۶~%Fq!H=n3I'9IN%N)R!?HI&V& SoQs{Qe"2H˜h}/N/_y1JUv`0=afb{'II0ΗU3ռщp~Ze.Ř$][AB"xRV-Q/t]QH4nSAws= I2p}{8S8+*igD_1'ܩ2pE(B0%̟fG\ߏu񐊒NzP=AI! Xᬙ烒Dw&jq2|`@Nt 7'bjgdʸ M@T.at dS;reWX$S*6(Box4iN7CD9 bvzFcxP@1"Wk͊FWu42 3^0/_dg9R 'ty#[d@^2]cܿFp Th .RmjfSl2slu<3;v $mL"t-$+ ︤XE tMmӵERR[k#JwGe#Ab rQBIcp&CqBY'`3o΍``flVoeXUBK7q| s\73 NXT:=q(o0jX?ŇB0͒*I ;Þِ,$jQNobP۸ IJ,> g>&ذ~8 zaMCLn0K`]Kpк^t oA"aN!cPS;Djd 5,prӆERL ~15Qkeax ;}A=x<7MmHXZV{k_ {JDHΊŲYllw }U@Iγ"E6;+$Գ\56C$D b!QꚓVQIHH$2%])WVsd1Mu1Th]εuQg܍;mZC(E/XYa)sm@+fofZ#s̡nN.L|;P( B:|J D3knZ%sބQ.6&Y6/r_UpIxÊ d"B0X$H %h,b%0t"֨ b7 /@ ('ty,Yk&8~/t,0$e3+_^$˺><&raeV[fu!8}647Xѹcg0H zo: xt@_pz 8+*Ca{f!=?)ş<=¾:[3Nk =3d}Qtʏ3Bk`7.3wQ! LߜGX q(vdRݱ 8J~ brGۜcgC]!@W 3v pfr`$A a#Eh;%> pߴzAgݜ6G1s sAIt;4M&z%CfgȄj/Ȅqd{ge^YR$Κ`afIk

+!e (]{z@) 5tfW"vl}{IJBGWE}[jg%*J̎/k1\#]cm,E9sn[]WWy2ݒv7 tq L,ͱ7eHOAlMxr0ᙨƛ}?&QN!ç r?,V ̱ GTv]{=3?Ew㶿yeۏ]5+uˮ*t--l] "Mr آ UYuR7Udeو$-'%˧h`|/Te8,;>-a$I"ˆ϶e-aF{ ZpY W*|Y=dk> stream xڭZr6}Wzؓ@$Yiع47V$y%HX" Z2,NC {.7A((/"^B3 ޷×G.2'G]1?{o5~yc2F!QVeEF3m%s&/{E)A8;G0Xt;]#{+Wfdy-s_ll<"6V|雗篳eq6,d!}31E6k3Y6ȩ^Qd部qv r޷%` ÃڰGTp o8{ch|y7EĐU0_:h $c>a}B_{wD8QRe2H88o1ib:ABĂ!HpC1^8B0j Yp܁G䰣[e:I:== eU,5c-"Uy?G>*qƕ7ϩεftG mc?w \B ę?2F=Wm\\!CX? 7M>VכNG% *0vPYXр-S t'R&(~X[.2-ا3Ю~5&64ҩ%aQV'nLgHBv:)XߕbIGVw*v(ڙ_F1S}3δ$L3u U}78]﬑8Qg;TLmX.3BMRR5*wj V6 jJEHذnb8lGayƗsyr95US. ΠLlf Fl[aGJ=뺏LH"Ԯ'x˕[AtUQֻ gU5GN݅O"ģRHhND!`ZLf63hVK*vŎH3\SN04: kɧOc~)U3yf#tz(kgd,W u0om0EDh`d-nd: w<Ӝ]L?KҨ,%c-cAx?{E<#QJcL{03}J&7"VRO^ˊ] C Nc9LV2Ji'RT]p}\y|;]_]QYƿMXLi*Lf4XST;g6\1G"Nk"Cj6,ovh_X -Zh1A)$Z!͏l5tF0ފpde5:!tǝEj/W5_NjMj)=pREm(.x;1;(g丳s{xu%Q:R|3U.> stream xڭYvF}W:/s[7V4XK, P%zjb"af}p pz|6 Ϙ2 `vPe*P1ק/ϳw`Ә3 5F-j62"ph1"q͂y2 ]3:V[&5AF`\l@Rd$|JDi(EXfm]mlr䩠⨰Gqi{cl86wA8}X"A TAsBxCuׇߦ> $*WE=!GSWEٲD > WYb[U.I{KÑPthDs5x\Ϋ [F@)QhҖuɶz` zX4|%4ED %A 6K;/,d} #)N=haHFI5ɸW-bt9ȳe%7: g%RbT~c_3mEiSKwi+~^ARKەSyR1H4b(}DR'Ksr&T֒SqQbOƳU?R{il:4_ן[O|۪=>̾7t=20 G\{YGG콿GA@S2@rS (5YLzXmgvWm/QˣMs3%W6wzkӻ~P|}S%GZ+5wK|VA|ح? ϧmŻSf8<ӛaQIg\ձ1p?y9]fPQf[ẈF^ #be$A>us)*P')CYN;K&dK*4.fWv4ș0$H֧nd>z;HAiT-ϐam`R߯{TL0΁#Q_fy~&4sۊ+%6-5w>Fq?5͋}i&OXNtz3 Qm NZ0P>Łѫ?2)3xlo3 &v>Y+0!%s=bZa!Z/VѶyޛ9ļj- ym}Vzs- b`dH,|_mvuQr**lq2f_;vQb$׃03ھH6]؛N73#`c!k04C "# 1r-[wHc;TV5ZR#e~P5` _B7O 95q^7϶C/ endstream endobj 1159 0 obj << /Length 1569 /Filter /FlateDecode >> stream xڽZ[F~ϯpCR3R"dU-Du"/=wc"RKf9gg#G3TeI B`>LP1t|9R'O>_0AW_g*GJ+RZ Fښ%4hF09`C*--}hFu@02TT0m ,O}<^yFU\aa5(6qqsqZg;m15;Eq41ڢJ{8 F*q`(Ujm!&x7=AF¡Db1h w<<"xi m< 1cA☷[ !*Hs<8zvs2G>1AL.lT}ò3F&s3Mlfnsil!,o;VӖ(ѝPHF5 .T6j!E13Ȯ03f :,l(88ԑa1̌(r8 /q6(tts2:%SJFTf0tA"\vdI,[^;3KHA}|3_X.5V&sJ F5 XQCk|`0'L)$KDe;!"QD$0D@Bpv f=+9wq*]:2]#0w&׽x3`3g~Q 9P)q#˷X17徃%}ӏHx&ogP>/L%d^P)xxIΩ3 5Q1X:BhpRؘzF;*Ґf2XLj8X.ĒeigJJH F2q>_f+Ϊ3$оWa)LCF aH`ekm6,[WIw _[(y ܈yEGy=-SWpiv60:$@1HF)E"laG~n\~rEa_^ve% aF"Fg*X"!0jp3 |~MiU9,af%ɐlwdؙJM]CX$&)kx G՝ }l04ER QMD˦`_T8mFj DqD i$)nnvV!Fjw DRn)ZZ}UgH>+.!Kfc:ܯ{ʧ3 8ma(J3,Pf}M *?ޘ0fٟ-WZu1258A'C~sL0oΠ8q0`8O &dI endstream endobj 1164 0 obj << /Length 1860 /Filter /FlateDecode >> stream xڽ]s6+l\8M$omN$KQ=mm 4%D"81N|x+$_&T$JgL$IN__߿xEuB024:[5thݟG#NH "$h5KϿd}`ČN>ZΖ 2B${gH* UÑ"Q",Mr~fgEfv?6:\ z|$,* xKC#1CG(IbCRIS$I(I-Qʫl1k3GRIyء'Chpg%E0~7?~Áh36p!VʇUcMe'2/`: pG8\L#nmzق|`ќЇ+2F8McľHL,ɣHFPa̫}Tt~}uK1a`|0X*.a00SA|bcNcze w3H,ѧT(قPI\fMc-ICeA)J ؞@K)\w{A $GҴMbzWo1M?^@Çznhlyb0}4N9Eq5, 8d)ķ l0zi`"(K j{bm~1`>fj'jp&>l"Hyrw6n>nI W*2Q`aOi=_DǨ[' "}Nq¤7YysWW fy|4!f.}8AaY߆Ť=)9abYZ_7wr:bK.]>  DQu%î`yt\i;j}Ɖ` b mr).5#(0i`i>VH8qf5<" 1# fH(cZ!F{]mx8 S_xz}l8 W_a=z[k`j]p2`1Y CNLFF9a "c=x3 W_e9&vUmӦ5EaY9Gm2[lQu^mc{n>]1T1#`(]#K[2\#m3_*/574s6EǮwm6` i=G*P_JW0!6j],*lTngZ;.×m!5\5JBMX[R;;& ٯyUz'b>tz; 9":R~5-APw҇1q3<,[5G_<5w8G^=ͪҷ4CHȎE'5r2vLC8Z| ؂W9M̩iN͡ Cq"EDUW~wjwT]u=ܝ-Vpֹ;.ݡM -E2Lsu;^Sۡ{ v{n3`>QH !W9Yk~Cuxx\vi]nsytu|x۝gi>u97Fp3/L&; zN7`4FT{!zSLp CU4R)G{\Ano7 FjǢ.}2`ԟY&q*pB endstream endobj 1061 0 obj << /Type /ObjStm /N 100 /First 980 /Length 2135 /Filter /FlateDecode >> stream xZ[o~GxYH:( Xwzx=,$RuMwu]R2 )PPJ@N@Y(S'j`D \DnArJ׳:L) Ke)adX|";PM|bH%fr ?C*.m}K wNQF )=rN=@BP_,  |)~60V_._ Ұ[cMJӠ^ŠϾJfԸS0u]X:*PJ7d0u_0KbPU j"(֪Ha2aj!sur YSʍLC䫰l0# +or"jk(\8M&vJ8-JV,ϩ>JA`JTlk״!WnT;jqg']PPoAu͛G2{8!wAgMusMBB5Lܭ=L[rrzz2|^A~±S1.O?}V0&gFF>j-BJPty axj_O'` ްPy B96}b^/U._'nqvJ|q|su^cag- ɚEp:5;"gY?\bWkv:Jo <v2|yq%Hgx_82ńx0DChXʈߋ7?oÓӾ|u^ =?uaxm<:.~8[z}~qX C,Ka"V ya Ph0Iwarru]z%R\v@5ƒ9:hybf=4ZjH#"%eU #H8%X.LjoGI̊JkT%Ib{:6 ˳ `ϨÑA-̜#c]dhd,#ˈD!j  ~h>բ9FE5j(e߻n\kF7gd]/kDnűPʪD`G uҨM@ Pe | Qz_U;#z#kS To TJK0,7ZIP0jN̚6g.4l.4E]FM)Lr,(\Z0-ѱT@K`3)`izʩ:-mFw +*+&01)C/3R9ygsv{prmu7캓\ۘhcm6gd*ݖV@?H)PU$KP=(YRd+#t5MnI9ّA3'O#+{5ME#: cYQ]> [[|v^,,C`b|Hg}n<'@ф@>Fa)+r$e]f;r‹>vta$6R+y-b&[5-`"M5(jP`&ƃχSyЦ!3C wLO4F3L}4ƻ棿{S:rFE ]-&yς4kNLA߮!SW:( MҤrgLLbt4p†u7l jYϵy)F-y#H"Zz48fWb3\9f>cw.t3?peh+n>oDtAt(b7u7>ة~/KHُXk.MCo؟S96)<-Է B 0WShp'0vs‡] {۹og2~X"#hcIѿp` MˤNvshڑg0H3{At4t4LIwZ{=>V]Y+cK^~Tm",NO˴1]FC"ַ¿?qmҒL2m]𞱎ǟpbmua4H=}f|OP}E endstream endobj 1169 0 obj << /Length 2126 /Filter /FlateDecode >> stream xڭ[]o}ϯЦ(\,)ݤ͢~"+JrS_ߑDJ);a"S3ÙO~:}@!0 U %t~,c4 Ff8#0dUΰfz[ $h(" ^fFLs=rU&H ,ξ4FRh%\[5G!a盻_Aղn~L$&?ɿ~P n2iO狢,]n2kfyt+|zGVPB`KHP50C cdPaS&&U4Td &;%X(:FHOD&W珿ɯ^5|qfHC$_"C${9!$B:=\L #)FKkƀ9QHRD5AFb E"5~{ȓw(^;=oq\H(9%5%&4]QtQ\lJ#25C*)#6"+׹MȅR w'(|dqq91fp)8 7WU' IT_oFl[螪GUXL M2b4JES׍v]3bx|N"vS[KHb6] [TgmYd9 K׶jz6uS .OX!G +GYv_;=ٲ^5Q:ӲV } "9A76z0bZCFllSN͏^2d?P<v.,ITlNbQ_zq79Θ?\! (*(}Y+5΢(ȾCuUikۑɣ!MyvtC#j۬_o<j05Rpc%=s֤M[ P<@S>A(voo.k2z^SC&KAUF;4^GA,* jא%vv=j BAy/t*:]MWbv7Xԥ=:3NIh174a!sX3a#(;}6Kz#7;~b[/xK䈌srEWGN}:Nj b{B˒P Ú1jgA9bTك_$UwrדF@CȨYPkx멲$Me i9D*`}t),= > stream xڭ[koF_X Yp^f8ۺٍX4XSȏK΃G5! ssLFqɻ G1*"^¢"gW~}Qzya9vNb'.G#QD~5Q_Vc2Ǔj! RrnUˬxy{ Rehvj^m29<}/Y삙(6kDz#`$p>O1Go‰1b#O)bRl!)$hw׫]\_0z\T :+ׂ^V(ڴ덹>p`>7 $HHL-7W A1{WS~=+Zzh>P#Χ1AV+3(ӭqW7vSd8Xn:HDd3ku,r$4:f\EEެ q`5?mE'O>(C=t>V85%œ`%Qi ﯾ8٦Q~si-gmǨ9Xn:.RNfLNg]jrݫZ_pq!zpiGcb >N{X1C$ 8ۧn 1Ml1_D?7 [ қ.*账_Qw=PM0L(@Z&ICl0TyU[du8}0ldK9?}rV.ѧ'%FOAA}goLTm*lT_ss|捦k(gU_C 2uLgY 蓔OdK A--Uw%1 iv)-Pe[WYGѧD!)cCĵ :"Wdl\#N$ag)L\)/hO똹1fsteF Xs[An,M1t[D$9(J tɢw.[2+fuUC)J$ANnnC!з I8-op?7ػj۬s)`҂1(pXbv HvX5w%14vw](O\F`>k4A 3t^K[`K2dj׺ݏ0X<afr C8w.P$N1{X1b8,# {ZtE٦wuM ^˅hUJ]ۺs  i&I"۳J?뺚wՙ D]dUB@ g! xqbWT @=H&H$r@ࣶ96d׿TCHv=8\T-Bs1{X1ddx%9Żg 3Y͇')cV 8&i&M l4=]i.={՟IZ]5i|><԰Ӻr߾__(}H&@ĘW~eʠ >xD0P_Lh8WKը'ͫc#YՙgZrSlmjgRp.lëf~̼ sǐOdJPs;Nj[Uzx%XX/.=CFY4FDxr {%Hrӆ^Zf]om/cl#XV.OcPkìI{yJ #(!fwv78:leƨ#"O(9ʳD@I"ms;(`de /}b0iL4G=9V_ }CBz7u}N'hP EqSDS?rSn0t;` xd&q",)hrd?@a}\B3 ^ANvO ~Vjݪ) KfʙQ-B0ɜS~Щ7mn_w٠-nFCPǷlUz7m>^0j >rNS>IMdyW~$ڛ!? oZew=xX'aN{X1b44 }vaϴa)gIP8$Gw?\w6 endstream endobj 1177 0 obj << /Length 2033 /Filter /FlateDecode >> stream xڭZmo6_m GR|ų Zgd]m"ӵPY,m]I픩bZʗ8Üs D8ٷW$hԈ3Ib?]|^OUHc- ,gYPfOfg#)֑$ 1Gp4w?GZEەf5A(^ց"H U3$ リ\OnfO.8ϲ4Z\pJ|NX N(@\Bt98b痳W&>}5yC5GUN. Dƈ* {)DߟK1>'|ztDŽ|^"ANfcH:' exܚG I-Q,1~M kmg`\>5!&b LfI^9bBj`őeYamI `<>捫q(f/~,˷]|Z  Uc<5Þ6sw?Pkvu  |E(7v乽~KuJ,~iY`SâiF9ԋ\Z}t)kkz4' UNo(mmܒŽgDVfn׀ [?kp`*F2#(8)IoӤOo]WkfƭIJc]]y~Bl$)/Zrh`'4 llLlM\/ݭMe:+t}(,mpR.\#EMOQcןgMy| zg&wt]ze4l-/qQ]ػcg1 Wa6I{5uߝ;eR/i6|m\;mLړn:pT8fݍT l7;eVv}Iu%&D(x$NI ycjkuSd}G{G)Y9ˡ&7+p4|{`vZa 5H>mel˜yՑJ7fTXN`SgC'L] am|=- 4e>vo8}R@o2ЧvN ƟtO8V` H%]a>pcg`H>+N1"H{>} #zecU a0`89k7rW~Al~ԗ)92`f/w$QܵʑEi۶R(\!;yn:9K¶Zf[Uen7ݻd>]ɮZan'=olGQi Zf=RRb+GX2٤G4mUW!wL~awiж{kӭɓJ21yB 8HRIP])VOmnT\.iCzWs+ 0"nu\:}<qkL1(٠cpFL8 n\l:kۣB Km}yPtO>> stream xZYoF~`Ppx+pui^h@Ĭ"]k?"r G8Y$8L' I2L2Hp(H&O_?f `-gslPK۟M<"ph1"q͒q2{`ČNn+v5AFH}߁21H_5i.E)tggξ<<T?}ǿaeVO%5p JabUc= 4]yޗ.JW楽yHoG/= KFS$"-It28I滲={~:9n?:8} #)Q QMa/(o+F@J|O}|NB#ORD jgjy߰h }\"%`V3P3 Se)#)ӈi6L NiNF1{8Qp2IEvuF^ _VvUgM01_6R!Ny(0m0V9bq9 Btę$o!/'ǯEfVM޴}Vfk YMO"[fe|v^Ve1Gr`%U hm >z?fur(1׫UK$x[7|`$ףB1B뻟ګ~3z=_~|:Y8SuϪں~=HY=ٻ);gO:'}!Ɲ1{8YT "=p9~|Pͧ' 4JCA Jy`|tY "t &'2qF* Gn NκM8h0J(/#hJJk;yB CZmZSs{QC RK>)L8s_x"gràJ;&76d`h>;3aPͼ}~0`xC5&,B]+vHb^x8D(];ا:e;dd%G$xB.v[ц 9ܘ= ycՈ8 jg}Y-nf?u6/o"{eU/SZwbYlY"e3D4n3j(⮫r>:C͇1p쳆lz=b(QZHwL9.<*ۍQ@8<(?jp"#^_H.OMjjS͜VrӴ+7 q}Hm #^:K`@>%!ҕ%\#JO nq|^"5`@P4x)GSpFJƙR(Oΐ/ʡYw0vuۛMV.EKwV5DzzBhIiroxͥc!x7fnU6o#&SNa" 9wBL endstream endobj 1186 0 obj << /Length 2078 /Filter /FlateDecode >> stream xZmo_^Q nx$׶Cn\sl6nb%^.]?Cc,S=3y' N~/#c!ފQ4Obt;+|r_ˋcx B$VJ ppbpr:vLgh?;Amci % po|ix1;ǼlRhvڴƦ9${0cpC$GxɥBK;.zy,/;t~-U'g <>VH N9C<d"ՐaR XËA%%m)F|ŧO {yfĎ7L8|P#+o;8;7?WK*33)|jUiw(ǷK4ܐ1"0Kiy1Cq >5%{mˁC[2ċ"RBJR,n[Z -.L}0{kV9`meO!CHS8'4. „lh1.Uh^?Z? =~|}Ui^hC,|$3mWr u1+,8_zZ+_w79ve3iFw)@_U<ܐ1!O!kx1D8FS7P{k TtTs$t:TkDu-Y1R$S5Ȝŀ%0"JfƏ+KyuF0ӛj)o }lLO}'*<[,aC֩wN< 6 "Bc[Tueg/ 7}nxg)]۬7-ۢYVN3N`a@4#5qRNF7B8hj1 a<Ƅlt;5CoG7'> stream xŚmoG)*JLiA*Q$DJUm$.>9,`]ewv.,XkyV̀3gu&T&3H$fUq2}?~+l8%[hmuS5y, /,>d ;bv]v>> %11ZL b+3N;V!a3yr#AXA4֬kqW<:p'V&0Z2 5VqCKfIE0!B %Z--@8YcϧA},Վz WC) EheH$e/-H+7Z] A< Рhekí,XK:Mqpx+ a!!N4XL%TW8f1@2=lS 4{ 5 /2`A>4FysLVgCTh~':CL%6:`gW B20䧱GHM!s%;m05X`Q`+ 2 @]_\,\Ϥ u* 8hckm,\J)bk򱔤PR,\UMЦ\a+򡸣0n he=&wFhQ%Z,X$R_(S0I`Ayt Y#Ԇkh1V.PO+1Z6L\Igχc%.g"[w<ɻ Ig$djpltx+aD):> stream xڭYr6}W錜mc9uq}J@IͱD*$3.@ТŐzE=g{]z~p ^q$h\"F#̋ޗQ6;}xuHl'SVmRoV$|`= QAja#"ڹһ1yKb(D2/x+@PCiޝRlXYdirZ,̎4[U=3ѮVɵr뛕c-xY{ =:5~X15L7[}Ip2V/xjrTv̒`DɭMNkd5rBIA/R ̬ߔ*_%i6N dFovkUPd85°@ DQPa,2lkΓ-R7T0@$q\zf8_O>LcȬؕ3j7:+TYv qb1"[9ϲ*.%@&&]6/+X3vϻx FJ6X5:m; D4~,. tHRǠeTp ㅄ(D[;Ȱj0H=^[_@|קq5c B(9^I1Ұ {ǹZ$zw(6eR&wˋ_zupu}e׿7p`#ΐOø@o]e??'{$J|v`˩eP'ls]#$GTG82+ZSA$-AS#ਗjqO$T\R5mժ gqg`e=@]ARxs6hCOP d?0{ZH&[:B{QZ/o\"Bc)CG}2]&enܧu !'p|N:I qu !>be=JŨxE~|n#wmi,%@6pjy$pN”= V9u3SƴLJM6&n%FϘR'u"f$-,g*,&gK26( dv c;.Ps{>{7ZnnZssR7/p{STa"KF=q9;#5T" AcuANѩ d"tVoG_H Hi"6"éA9Ԗ݆]dlgRbPEt4zy9 endstream endobj 1199 0 obj << /Length 1910 /Filter /FlateDecode >> stream xڭZ[o6~ϯкhE-a뼡CEfb-r~-ʳXfh%sx.qp v9HJ*uH yl|Co>?%bRT!dbUj}eMe47.M\7 w23S^.1NacDUeX!G0 c<ӅER>YɢY)]9|}h BD!aH-8ͼ?S5a mf'>$FX8[ƴ 6Iˀ(X_2HKX*#$+tf` "R`H+I 1"Z%0CDAZ;pr _K2Nxr8Ê_W\>''X 9Ȃ}/?|{|vB8DIZv=xM_m!#Uh$Uרgo^W/>Кy\uQQZ@9Gd("=mkj3>Lbt>6ڻWWn3eeV+_^47˸]*S.,u{枙}0fߘ⎲q jCժ4Izڂt]81 o^Y֎] 峘 FbF`i61:Lq|>qA.ҸYY҅([o7eٶ&k˜3YQ|ʪ$a S19`1FD$&maۄ kcQniJ"F ,HCy}/+-1b$cH0'=oc̼HKr؅鉼1s8\G,(Jr@[%u+q,;c=3K {t*ZM>?I8#<զ 5(x6XUV6gw1i*I6>i3PdT"^xzQ@N~k%(2۽iC/;X{Frd;^9ǹ+*SXA;aF yb7vaVCXJA?[PMFLv[&MZ//=Up}}ȑDT@N dx6$O{;A F۝a%}!)8BFG]0Wzjhƴ{tb#2@\B 4\ƩKP؄ ]de>`|tf2Z5 N`6)0NTR[)+28mkC?ae j$nT}|be%<Փc#A|dLah$[{zբk5Y6 a;ܷ= u~jm=He0YW:h#ó˳g}\O.އjJ>*JF9wg7tQF2X =m!0u0έo7sXb0bwg?٫P5AqU2}7#oj>:ƠGecdj(&FyFL=0{l@{Enm~YZTqHݧҬ>k/GطѨ#oJD41DR{|;;` :BGJELn-|gIl淨6Xo`1X M#k/G endstream endobj 1204 0 obj << /Length 2104 /Filter /FlateDecode >> stream xڽZms6_MN'Fכ˸NEB6TIgJ2"09/iX:wg,ξ6VDZb-Vq&#ỴE?*}aWR4rj-:vٯgD u$BLQ>{GXvrݭ&Hsg?FRitJ92$ :iZS7ion㧝GqJa8 a=\V` r^&m|^m<Fg'B[m*5&cgray>BE 8P((LrejSa60$FB(e-7e77&;r:o0'@ χx ^X{bÛ=S`+| L ɧ@1?W9Ip__.._\PywaCZ #JYX 19y R6m |kU2|8(PstL&=Pv,̐a:G6>omp}ƨDMw`$!kڤ̒ʸo]@KiuKr95V$H<@ӧ 8Ym:ܹuXDTrSd 4Qֱ|zpM6dMuxne։+v_w/v~qt2f`ILPl$$Mm #lLl%WۺRJ宁'\*n\jK= LÙ!$i6G` LȠF\Yײ2\l'+ ss`/0%CەW6[殆˯oQLX8a`bYwv-D,㛯mEljT1GYO}4wU *z k3ԿIo-8 9^2H< 먻&y:?Wu1Ǥ5U}PM|/{6pǚ#Ii #9~$){ z.ǟs'eB<2x6 ߧʕTz@EH p~8s {83H(9E ]-s}#iMP]dMϫzVGt |h2pf@bw@ș~`) =KM ׶ma\;_U P'%`%s ws; `nBnct Я 7$oU]#Qץ]s 7FBXYQhɄNAl@5dYmv$p|pR$FOqf.uR:ztp4:-A ɃI7( xnC׼Vpk|@v;;egÈYD/%i?^/aS·Io`}T@{L yw5'%vb}>D"@1y B;ݐi'fM<7OA49Th?(!D17\*z]GFtP`3 Џ@`D`Iia>r=uv໗_m'чY\eeu)/ qL( @Ntc{)Dݵh̯ۼv3~(_[cj|b D8&_ Piea+ajQP rw C %gӸqcāL2b.<;)Ǎ`=PV:Ph/ ʯw_<,,jX endstream endobj 1209 0 obj << /Length 2094 /Filter /FlateDecode >> stream xڵ[]o}`*z2iFR{YtiR"V"$@~|/X'<yϙ{Ͻmgo^tQd7U 2%<4ye5{?Q 6pF`8m :Wg84AĘLflu3/Fn;rՍ&-gꍤ23H8S GLQ4>V#CDoΌ̐\(M'ݕ].e1+~z3]dCYINb`p/(4pO~l{T7]ΛW]TuvC-ڥu;J{ -dGa$%MÎr}ί붨|;_fe)7)cua!kD )hHa;F8LlZzG\T!J.i|1}?y_((xX~Sjn D28RF6ϊ!)K#l̠E;pb ލ?-uk}a'l+>>,2#@$~ U $vr%K֑Qʁ[یhxC!tZ!F_y\ :FQ<Ȑ'J'Z%2ez=!$$3Hm9߯ޯBr tj 5¤.ǛiNl> Pma;PaI}1vw3q:{hJ`uM8hcC"|jWoi,Gm^cPfR`Gt:?5V.-GF8QgB,}g(?,} =/oZNIiz@oB[=RȫĆGV )9)9 Uiȃ|UK:HrpA wo&wkGW'\yڽвmt>}4Үl6y05NrvQUB %ds =B},o 6M;hA_DɼmVkmK]k8a4!#hMBṃkҭ Ǝ]M1v.]7 ҹ(I1dyDD?~z"mvVy_;|r\^_^g!CH( #w+ёO Mdv"E]_~`mW# ! J: "-}P`C]ڦibK7Tep3)깯ͬfX!_.iQ_G蓛|;%]4#=SH H*B-&~"M1(u~< i< HE}V-M&÷(mٿu[uW>-xG4I -u^S#, endstream endobj 1213 0 obj << /Length 1779 /Filter /FlateDecode >> stream xZ[sD~ϯ L|KaiZP`J\[5Rj)t9Veo'Gf}g\="mBgߍϞ&`5&aڂ:qgɻW/ͳW$%)8Y=3⦿}8'Ihb(PkM Ó5IfMB[|G.ף)X)E/ H V D3D!'窱'dbpY|}!,EsW_ͨbv@tէ&EJ2 -7 Q c\"J0L!|rWmMn7&*-+Q[ --J4~c`*5 5;82@%|q˟Ƹ[,E:]3F;QB.Ws:l*}gl(zk0K#nş+)CiJ8&Lî#^ck|HG}414M"-b,oh6hԉF#έ{ ZFZ?qhF;/B6f/`h>;.@[7[:z:᳗H0 fD#h"L`naZ,k/ %SBIXPK2?x 9Zbu&*as͢%ڀ`Ut~V쑢s]JݼN}VAq,e+(JQzJuaiKF PVo{.V<{)Sm o_x--2J `9.0_=<:n(:CrȡdB1XR s0ȺNQLh奚$,H1N<6EfH^Mj(=RWE e`x=I!N[aB*utVʍm(t 7s 6PKH+)J3Fzצ96ʇ K BE]!-)r]lZ"=^)aCKB>^u٩ca8J(Xz(q`hPœOVb]vZhuYeՅWkA}/pD hL.()p 0Ht[# G[ r^8̉ Pr?ؑ6W߿׷p>[U&Np ӏ}ba9Zc|-,ѷXnMV`BM(B'9Oٶ6yph>;BsBQrb^|lOfqC8MR 6 3CVFAC_Y'qz)*t[3u}>7 sUc(Out9V9H(u` Z`Olnl`0G ,pm$w755;sjHMѧIְqZ mך o"@iv0ԥG,A-6JZd_caL 8<bB2X78eTXF"@qt`mc͞vzOf@g㜎Sa(Ƀ1ϔ3Pz!+`u[#o FhL|x8Ā0VT{RE7h$u#Dj #pfjηsvAۏ~d endstream endobj 1217 0 obj << /Length 2343 /Filter /FlateDecode >> stream xڭ[ms۸_~r$kI_tlHI}oB(RB!rg.e83)+Lی 2%*^/>]{3Q~9# sn]`wwW\84A$3E4e'o?e\g[\l}[o$Yr pWfRe߻XӶo^T,uխ߼ nʺ5̉yxBX"AU@6!xٔ4dUw в 219.KiDV2ZS$|0kx3FR!OqD{>;\7nO _П}87ʢ.u}v|aYA]쎚P`CF @ LA4g=aNj]+6moLYy(5`{fLSmע&DJ4)꿛_v٬9n]7.7eF>(B"G*i`1}[< "{>.Nmb3ɨ?KgѨBb@4'I!O|d /(97/2JW.j670+! Ĝ4H1E9U j"P,rת[V+0=8ɠIIAZbW ´XTX_Gd$ܹձ@ѱ݌A< $I4Ddr[7C 16XHS8=B4hCT4e`)ϭ:=CXCD@fC![?)~c5_)7<ĎIP@㫕w}#oqlዶ,su9OX9%_[V1|\Û!ԬiSaB@gtxBJ@\I(9BS~[[[Ƶ(}B k5,~K7}%xBJ8g\Ûa'B' gN}p#Y5l7Rj'iMc7}uf~4kK~dE# IӐ_ò[ 季 mW֦YϵFc[Xgú\g(Prtby0V4.-w~\HݚqZ)^m jK!L+(xO}lHy ^&i &\@v,n8_#'f|?~|h![X3}9F*yxnCGkb]Z7Luȟ[h!f&V WP4\Lޖ]7 bAK ABcyD['/&:>NS7 >' o]]P[zX+|+a!tf21ˮ@Ce]5ل"[pٵj,|nZٙ䍧*W㉂qh!iCK6j))֑pcNc3M g\z[>W)OQN$IN3=ތw^ԡlZ45"KX8'6D&W@, NE!(Q* 燧e`4)tHiQ0AL'$$WiI_ѷ jS?\/}g!䱈(~{|1A7 +dQ$U"2|?M1,J9bءMݶ=$VEW>|6GAt b~o/ă )̈́"&{fjڬJ ]NTqˠQ?97պ(G-Tk endstream endobj 1221 0 obj << /Length 2624 /Filter /FlateDecode >> stream xڵ[[۸~_᧎*JSfXLi[,yEy_ߣ)b,2} ^lx懇dBLbx,̐r!cb^<.߿՛?#M gpF`8^ft~G e IRSXo?~yuMP&Ģ\|GI,2%U a"doK'_UnEwZO/w߶;aS4?mUӏ\凢Z Ԃb * :$O;v $Y$t 卅})6`ճj JmmЪO=XfLSfJyf C.8FA.RD`s픢Qx&bWj]uW_ b˦/eNMWE.Vyc@|Kmf]z>|$u_6t08䥮1ca(TiF;oYqe)8%ь9 [:mBT++V ~ڀN=gnpI!K;5m3d6KK]-?BT9B-ODz]QmmPijl06#2LòxO#eEт#$Z4A>T7gI 2<3mBp%nkz3IA"11m;?dÐJ`gC6]ծxYZuvF@8ZFB5o[ V!SR[( BoKBvd]λ'd\nmoXhSzaW/3 Jc0(D%: 8^u/`%W39$ 9tI,!8E:z^LL5.1='_Ksڔq6oU{ƭ+ar`q}ĨD>HBpq4OT:qo['.]$Ӵ0F+L TT+"Hd]$E)Ěs`Ȇ=[lRզl_mڂv*il+g ۇ3D,t8At ͫ%veNEj[TՐ_ԛ xn٢v.*< r<(#_߶qS \?ݙS^w¯`yWd2u]?tt d%Ha⺗cHcpwSSP?PAy^+J>bB D22!,۱=vnQ~lQAtR``_ _V6`KT[̋Kט$ւ ߐ/SG4LL umAo@{1^*KqM V@VUZl,Я%PM.˻s㬗 ݇¶D2 y;f=EZ5CՔ>֜ލGP9>e9ӝ ۇwe C|kH (L6b$#s]jRba$`SnyU|qG^a-Xb4i$ p9\t`]nEfNotFxhu /#,d Y$Θ g!QMlG9d>vL,x}!"J$u?|Mۄ"deD 1!YvBm@)qmoSe}莱v UkЕdRU7 f [ rbqh$rĥyQM?6W!}ZߝW.K|. GPE/&sǣ]{b>I=c㥼v+gډFbzggBP3h8>$"/%E uXm!i?Wq Lޕ[L.(Vek:sy;^31Y8 :6odj8Ca~JS"m:*6SLeQ P(EURDu/|M"B)ήȄ}ԫ]]^0߫ m׉{bPd T>NC!C=I#6z;i&p ʻZ2<yv}tҨ;e)_B(b"qz7X Xycx0ˁp.s71`F" ƈ3Go7ạ endstream endobj 1225 0 obj << /Length 2725 /Filter /FlateDecode >> stream xڭ[ms6_nʍ$H9'3yv\QeDY)R%);k-H,E T7}/fޞ=~QHDt9rCA|Bt14yW߸|D"Q/(,gYPjљ==[gDG*(0O~aO}rVS"|> F^Q DѝG.%) ؗO>L#:Y,=/RuUJ9eIMY&Wo`YlF@pB}с:*WZ8 u&d/ꏳ8u|'J5i~-4R2=@l%l}OEl[^q;crtMyM2U<9CIV"Z ,"deoLSl0;ݦq2dme*Eg+>c$0:xxZ?!gt݀0 ,ٮk#e`.o߲m6jG,;PkLd r>ЁRFX jLCl:P%>D΁ $<slg ĚRf:-f:h>u6+̼hE'^{@z"}rH@Yj\9qQ٤,q,.Kzi ^;!|X=Ym"&!'ӵ<*8*EInYGQE~%yIַ/*CDrql7 <(Ja ]K3pt^n;t*ʣyFּcBkB59Lp˲J8Ӥ7؜#@ |#3M=E_S=P 7$ y !MU]}w_1>׸:(hr<[oT-c/ry#SQ_x2U9~~jQ*u C[Z'DvWWm<OO*>J.x>j]gysn7bȀSZw>#.]cRVaժ7lj$&65YIL/o()k5 PAbՆaz=Rh{?B EU'Kl* x(FB2!%MgH9NSm tΣ8:ar:Բq!U1?9LV+|ΫouWs|yT@ MWD*< |>tv]y(}0Yh$`YsqXJZs,lXӟzϚ3S0ymF$5'"UmV 5EwRn=e{$ !P={axUdK$N ݤwB&6G^[0 !&xOa-9qNxjv%^j;[VĔy}қЙ?!aXLʞ.ߟ87>z~Z#tV7BmS[WL#FBT GoۘVD,`:EĂ86](4Iz(sP󃹦*w&>+v~*(B.VҞ{Sʊ^/M\Tf|6х kכ8|4z h(|m)YJ<{[5そjPƊ5@cUx{V&0#CqN#uXƩmQW_Б Gbp 3wo\Gz*>ZM F]ɐWxk7ɾផ4e͓c H4t řAm]õ͜qmZ2x徕L>QYv+X@뛴iƶ (}b^ DNLGo,V3H 3g0+"a3*2KNMzKP q7zq?ԔZxvpfyw_SC6~trxU=SjiK7ªNpnZO*I9 E3.8RcPo:p:58aGl:2-oVhZW"|? endstream endobj 1229 0 obj << /Length 2204 /Filter /FlateDecode >> stream xڭ[[s6~`DdM܎;v6M ԒT\w Da }~1VDZbgq&#Ỵ4mwϯ~*"i1 6kjY/:vD u$BLdy8»#bf^M%m'UWfb9ؤ4펓yݛ)v٥ J H1:`70ي}ߎѸ@T ;" 1ʎl{)E'D¡Ku>l~^Zs۾h}`[bgʰirӴ:&B r*CFJl@v&3E:v_}eS+iސ\VpAX)H9sڦy,wǘ3-w8{>wZiݺ26#vIG'(AGQ'iaJ]R/QH%X Lzkn k6NͬI׷WsӗE:IEZyٟM26'yּ!q82Hkk=頻eR|^[])1KzH$S]Y﷜"a:IfO ]X  W&sY el*|UP'bk"w)*JrS< y1Gғ̦F-hN ia & [n\xS~- K$X2(h Ji0et`ƚ#h5 eaHv .ȺIU){tb@ZaƜ1ИΚUZ-b!]UId 4#S:υ0a&`SB̋$KLlXB1 NhRu7ǺJGz"$j 'R¿lE X+z@dgxx@)AH@ 4Ej^s!*T a5BZzp.:ORD&S?3K FD )uxyx.@Ơ2 L!J4h♧M"(c3g9'щA1ԷaȦ ㌬*?~igBAa!Q,(/8['E ec3YjŴ<$Z;=7pPӦ[t,Z endstream endobj 1234 0 obj << /Length 2159 /Filter /FlateDecode >> stream xڭ[]s6}Ng Gvgg7umL:EAIԒT\a^l &(&98qrdzWL' I2'T$J6&,8/?ONF;#Нn:/'g=#ph1"q͒luNfM"Y&g L 2>੆#E(EX˫o^P|E|ᱣnz *#IbUQHڄIfeQU?d0BB$шH~Ԕ/?<?Ƒ2Ia҈.aڠ9Jĩvʿ*ճrQͳ[dFYyV ;^4+bO/(Wi]5_kZԫ<|)`:R G\#)^ӉΫvRԥ]M~~K׳*],mgVmK]U]v@`ʞj$"%Hp_|A^Q_Uڏe^uy۵*V~ VKV V\_pƾhZj`$`dL8Fc:|O`j07WE:B',gH zBzZeՎ.]GEyx0l8[9vVk}N'9@7ϖ֑)Rfqkx`' gJ4F #_Fk`ޓKmu [Zv ׋ܶݮ /H"Xbp"#$e~u92`6qd2YL l#`Of0h؂.!H=xCOb7LɳlX[}hmPlZ^t3ޡ|lἀutp_3IA~ QH 4=$TTqT9FTʼn'gHD5*w`>I"O;|Ie`>K"(,7'y5tX8D% %Tƨ>գI"8CG$1aN{_Be8B(E=q;'(58Ez챩g)$($%Fz$'q S.‘kDiO #8#I2H&~Gۑ H1R4N )G횂 <,}X#% O&zBvOU 1EM8qf۴W NrU7 endstream endobj 1238 0 obj << /Length 1258 /Filter /FlateDecode >> stream xڽYnF}W H@) 88VЋI\D%R$DR2`,/933k"v0)d&pQe*R1 I6]:"lJsF18"&),,:W8#ftukXdec #a4aiWlp>cxw{})5)n?]He/yi?>"HPC.v0|T0$I(#G CS$j#RKD1jTv,H+Xh9FO4,6+'70m)YT^@>6$Qn_~r3GbW")[}0n eڄ n$p % x/>t闛g GS1eZ!+9#!bs`~%q3/oP./Ym'a L&lKfNހ\NB .ɕ0 qp.UU72ͬ!8Lq:+8fNހ\N-:T+G X5 井 e~g*ɦ6 sܭb|cw3#42c OǫeI&8yD_4CSbb5ɖy2)5 ?.jg‡',nvQLX31oT.1}G⣆*C|0@=r >nH(Pk%$ xU2~"~ Uo.UBƁB><"WVA?Bo%!il8ؗe1U endstream endobj 1250 0 obj << /Length 755 /Filter /FlateDecode >> stream xڥT[O0~Wёߝ1@LlCPm u/I$]~㶣!}|n>珑)amɉdD(d0!)'F &%1K7quSʑk]tr"Rd,B↧ fn0֌EԜ_zZWe~>rjg.)=,-DI$Z-)MLV[C^CEp8SyQ˩|qTWY(#S?,FyUFЌ*P-pc̀iH=%K?~+&2a gmւBRBfCHc9-2EcYs&!Fw.2/K!S<T?A,v `?$!2'K1;j*\ن n.xp7N!w?ϛF)Y8>2ڳG2Myws߈7֔?`}J 7V>a`*cϤQή1/@^ %=p3CoU A CU'[4-hs2=A.{/lU%(c;J@1jicDG'wɟOr*ɕ?&:]r/}}@b Ձ?UC)-]>uT%'@UH PI63}<8  endstream endobj 1328 0 obj << /Length 1404 /Filter /FlateDecode >> stream x͚]O8;Z-)*g^FIZ7vR8 Ea<Lʀ<>/g&40c#paY@m! g66.t h(Vd{^erqzC\h_#[_<]?GKJ>UGG,x h"@*#lh#* ,/ ?(m3~y, P]' r>gaoIowa Wޔ r``:XIl"vQ>$z}y{ xL@n)Sb?vWAɲOѻ:muIG`<eAxloӥ1݅rs4.l;+ 78Z%XLoI-P;).}KWeIu%:Ϫ]}vc?EʚmҞ0VKTO=GBxne`:x`>Xe+{D cxdש4́peJ&U J&A,YUe\Z2^^( l-ڡڔ* #~=#}΁4ez?~^ho .h'lei q]y{{m9łtOuǹG)v\ 4^ t /yhYg}\{kD⺚D:8 2~_<^ w^+qkP,h_Y=iXL_TOqXlpSJ@ݶKrI~]5owb׿2kYW@'+L:OErqy&fo;XW9lrx>QDQAEbwi(^ tmkdIyYԭx"šJ{ 弥3tg,yrǁP׹\x\R?(z忥@礩[sʷ(PNPK> stream xZMo[Wp,K ?0 -W(h&Aɰe %u\'эELgyo9b}V)B(e8&r,qȄD]*lBuJVUiSiBr1P2`֯^&Q2Uq2*Y3Ii TM S%S0SH1AjEILj0g#Y4:E'Q/B"z6C4% $6#!HxKW\ʉ1N|oBm.RêI#ɒ+$ :'z?!@&dڵl-P5G l4I]IR`D {[Fh/Pl]$QCJ2bBCWƩR5/ -y`!c$%1Ml`I͹5MS7{*;enAwWJU7oϾ;^.V l{FQо`IXe_0kry~2_S7\g]񇳗ՕUjy}y>ZWOϾ]NkafjmcK`b Z̆^1]^_5?Ïw}1aںΛƑ\bԓ7|tWWzȜswq)>Lx$o 1h5+GA'1cmSbM!$)  }೯²´} uo )iB-ñpGO4-Vm{hoR ۵'5{.O9zaN/7*>S!s%(x7WS] cwlR|2D !]?g<~yoϯ?; /׋W(Go/Wdz_޾y)vӞGC2擓rŸFz.Q]˭97rڽ3Goϋ3a3&$0{&S(Ow6 Ys-6`{7i44҅[t-:;rȹ#玜;rȥ#\:rȥ#\:rȥ#\;rȵ#׎\;rȵ#׎\;rڑ#kG֎Y;vdڑulO-7Bu ]H]](]]ȱ#ǎ;rȱ#ǎ;rȱ#ǎL:2udțTx?8g4{V g#!a?2aE1UG]&F끌dF> RIXӞɃ!T2~„n@L )dsnA P?F~ *$/$՞q3:TJ*e2eʜTÜlH5eYFRCXH֑4}BG2$0e0HHJ ޡ\<Ft s2*9Gګˇz[!p[9PR ۆqHcSB[,u|4aF3vਡvPM$FQ}dD$mF YAgLPF, + %&?S Uڣu0IY֦}sfo/E|#9Sn "MRMƮc#|%hgu%Cԇ7YI 46Y8ݠЗ6FXZ 6N.^p 1z=@ |Ź4VgDh@kS$pjvEGLM~ )$Vo9>N(S= endstream endobj 1422 0 obj << /Length 1675 /Filter /FlateDecode >> stream x͚moHS ݛDlJyӴv867}Ug][iv{r坼f֡=jAm_-/hq9ԁibj?uĞ:3o6:|D& 8npsw{dot`S @2x1=Ѿ#K?q94eM![Ed0ti 9wQ< BVk[5w01 4FK21YD^q.ֻec004vc1݅K"n{D$ct̽(ZDmM%+뵟$j~MyF;Q?v4ďv`$A:fK(GQ`%qdp"`mOt{yQ'"{*6a\6KZ+3JF^3x.s3i60}IP<!@EZ^ TDɄgΝ9QcZ}IKȃ<򠑑TmE Pë0x`:S~\|r^ $LHSOW$rAJp{݋K$/đ^L⅟!Y*-mӡ[/5`ͅˬXyGJ*m^;q3H(Tj~HBc?}R*h 3ҖՄ@J֜B|D"B;bC&0Q1Izt~x㯃w@r.A4hVgtGtV Y}|Date 4 d͜7*HXna}[_SDŽzQIJ M :@n`Tjo](WVcU0_K*n|`# 3`c&JlJ &Hk_0'a@ =GB0c(/דVi~UR:Ps{ʌK0qgmr*vg:5Ωk['r> stream xڽ[K2J& $0^$1p&i3s_g`VwJשLjJV.4;5ٹӒϵreщT% ָobK ԕԦ%q/Uն`56RKI3V W(\YW-*ZT[ j/LuT܃t~V$~B4dW,UZ2ͫxΛd72R+Jd&U$5S×ᙚ!9dl䥮O8V0si3Zꥑ?0ޅy8VktXz]־hN~x1IC[i%i4!4־F_ *t̫ly.8HI`c}`w%A<Ӝ}kE ]VʡKdB\Njz0ǟJwu0XfuREh񁥄/Vy% \p ]{ebD սRTuNXW^E6R;5ޗPڗ2#z_Jϻד%#iRGY2 zxL߼yzp[?7y|Ƿ_9ח?_r+Y?<\>]J2O*CL7٧`ŋt"]S|~>60Q= Ig|Wՙй K@p Ob /&J2Fi/ ygjYrBݡU4T%yT޲yE%F&U1lL[ <~Y̔ T8Tu WBFl|D"mY]zચnd GՈ`Dl^$['C}3'YYuCW#ꊈYꑳ) ܁lJ yAkpLjT\7M])U2Qi(et=rRea4 ĕ^ wϭ3UC1`#PqBy9)d|>ykfv%K=ni89< ہ,|V"n#i0X+UNRM' #=v;+zk@lf#?A8m mK좸?$ :P 9w$x_X]WD]bw=Y[_`U,^F?!ꬅUp Sa0!벢!58 Y89kW@2,Ϡ}< N:󊖴8I?ԾW+ "p6AuTh 74w[0 ³=.ZyT`ƽtHCNR}4g[Ґyvb$Kx (C_R@9J]1LԤ<[ҝ #$۹O86BL9Z+ǀéj|)<|ƚ쪤g%y7?}ݷo3{$<Kӛwɗ̹_?>F-|7_<곗_+\)?y#G~|7w=~ן<[7D@i Ž\/qW+lNmacc1b1o +Xh,e -([P܂r -(܂r -(܂r =({PAكe=(܃r=(܃r=(܃#(<#(<#(Ϡ< 3(Ϡ< 3(Ϡa⭫ ӧÃ*pˆ]U0 ɬϱ -+g} Iћ:kΙJly^W9:9g>l-w_攉-wrvxW#iyydu#xn!㺘νºg;B[{n.>lmZfۭ,fk|5ϖowC\b;+RPm8ϔ81vLa{;IuB&TĆVJw j]eQfW]Fus,6Pb+zm٥?X;( endstream endobj 1453 0 obj << /Length 725 /Filter /FlateDecode >> stream xڵ[o0l.[]MJ(]BhsT5dz-}MػQ Ta"8f stq{}5{~ 0 4PbnT5W#Av@N9S%_7fc첏/R9 ㋇_ _x.X4~ެP?wYk?GTSM f@UW>r53yz PvuwlZM \͉֩iŰo|a5. /4JNsЏAHջW$kzY9RI.6vƋc[-AbG AKSzzQEgතj;9~ R55ekq'5xnp$jHNZ8=~folXӲ9ڻ6ͣuUIm:PIOZq7My\86\Gl}z5O0&kVs2[;ǶD=Ҧ s]g endstream endobj 1472 0 obj << /Length1 1427 /Length2 5941 /Length3 0 /Length 6902 /Filter /FlateDecode >> stream xڍwT}?!")fAm mtҥtJ7(HJH(ݼ3y?}~W_7n#S!eG$D`@@6ń@Qrnn38PEXN 9#/wH ݖ@ߎH @ w t[CÝ]:?x|m_e#` W v"p)x\X0#D;+ |X C{?! ?Єɹf.po) F8; C`p!^G0`z+ݟ蟉_`(#g0b`OG;{`W`1Ca 'FipǬpTEzxX hw~"@ G0P"L[NEo3 J<0_f~(/#!(Dp0`Ap'<h/XP)@G8 gǩaNep_5G?'[w]?eTQADB@(.{gi?GFmOj>?K qxW?4y;?v^Xr#q+oWKև9½<۪D#H\([h}aFp,7;3Bb?/\_6Ap 7&0_)p>Pϝh98I-#"$a8!?-. 1 (Bq=;AɧPpZeQ9#+Q;RlRi^^kQ݀F?!vugvHɔCV)VG*7e}xFlqd}T|Hᡯиa][*m 2h*W'a61ٜr>5ԋC4l/Bu~ҨX];+(ʦ h)m9=]K?7qYٲMFWD:~̏b'hPH9Xd^W}bsӉ[<ж~+,Q%yS$~_4+ |ANaE\yR.f e!V4bbjk"MHJ_vvx!hfKlD^5BU}<k|lXyЭP.L1!nBIGD;{?zBŲ^tU;}C0^ĚLk`l) & ;z]jj6UWaq8"(^TlVJ5-!#|M vJVuZJ7>g?Dr}6K{0I>zөYك .Vyn=.[,eްn`{̳Ǚfo@oC1k@̞t8G~ZX7M>d'p KKbV] fx` w3fդH eUkSfۿJ0Y X''S8{uf/gk}5|W2} EG̕e> . ɓ0+&Ø2(wGs,tt f%Gs`#CBlEBKmg~k\_hN}CĬU,&-$TFm$FvP"c 07{Zg$GD%c;n*|6>iI'}N!ĕÙmwS36`emQ0WMg-4^*88G?'-,;ZkLiV=QœmhXƑE')2&bfvUGЌ;Zο_(:&%$WH_}5^qYhЂO _ĭG^# n!V}zG3jrQ'fZ ^y&Bp67!>hZYco 3IcN|gRjƗӾF?3.>{'I_B62?zZZ" '!in)5gwo]eכ>$kCPlϷXtX} Qh?;YBIډI_Alj'͆D]6Bw9nok񱢍،%1BDF%h0^f8"^ܞAH1i`膁j;;k4oWz˲'OmSj=kg"p'E#vah$ycF/Eq6Ws{zϝA &t:֌NS҂O%>ݰO(m=f5$R=T #؝R[s罿w Y!;y"/dLO=N?Z: ͤO@1^k$/9I-2>q3\Ղ(   3K; ]8ӌ%)qUq܈6 Xlx'p]xB̯[X>9LwGQ[U/GRx)^$; WЎ0fϗw7kwF~KYjZuI)>OzWOurfl>2&NkjG3S Oތ=PLw$}:FϓU~,DPyezXEՇj"qR'z"eZUSyB4YGA^@[C(y^Z`v{ oxB9ws!gmnK{toV{)ۗ(nD7- cR͚*;<{ l򹔇\BNYΕ`FNBAV&UͲk!)o j.tIIRw+/N88tʈP0¼DnRLQ<*ç!W|I9)k&[MNL 2tqy)IJhx}7kͲl[JA.vSjcqY'v4jdm0fd;NPs'܊nK82c.?Kh(/o&krީ^'{uIԴt=MTxESt=*g#m{h`zRM{"TMK>c420)[sa  MKʣ $(1?~ӪDo_ֈ 2LV4[ܼTIv Π]gv*K﮸} ̂ae5 LhuzEz(=Q@D.2-eTd5`xc,3ZHu?R)Mnhǫ2i'\PӐ- 'O3J+jdd{x!d+۬wV^:xޟD66ۧR#=]T}|[A[+cyi}[\9-I'.h}02vXq> C z(^ɼh4^kjHk*)g+>~ S6QOoJuOdSGv|XnP=IH鶵BE]~ <6 0Kl}kS-(¬>k wPs6sPEDIP ס]VFx76=?1ȆReՍ0'Sb&r6ٸ˛4*}gBlX[yT;{U)C),q{ofn6,LkbيN#5S^BE'ߣi#oS}`R^K/?NsHߡu2鮧ؾ(@?(2w_q0 6dםTT?^ei؍)FpqYBum}c3ߡ x|LQb.?ЇLGaSC#&IQ75 A7n|е0 Ty)>? .3?ƠH)߈)p*Պw{>y#חLbLxƥif4pArdvh'!C\ㅆܝ˂g=;O[&iD]e5ʽ͎Jnw=`689EH@\צyngMQaۭd%“@ =-Bb qosE59mےoiϾ'W~|;@"%یk][`//[A\D-V$s?>QnTm&hXr[v|1Zব̢Ջf E4ɷvZ# KnX_,[_G7C~O2\ fPz5R9h Œ}Dv/<4$rUYRP F,/ZtedH2=ЇFa1υuPbJ{vmkE^h<;?C 4aO+ 樂@_^rtOMX8'nyA*۞0r9H) oŚY:D6MLU+Sa尳&7`GrϿ20\fزC`0ClʌcgYe}I^ ގ$&=G(|]JSw6L d3LQ@j8Ϸ2i;AƷd+JR.e&?}<`#Zsx)-%8Su1|V> jlwgI!B) xŗAQh@ma FŇS~<06h=#9O`Lk+OPf#wP|m_Arny&ifAp)r,iKۻEkGI֨գS"h~m#Sm\Q ~9QRhmkP|[Fw 4zd^Rlp%P'3.pe(t?n.6g&` C4GuhQR L<\Pef"L>D?fd"p˻V5@zzYfY^9/v9 >)\<:b{[uwtk=Wl,n=?31Q)9"8'HXiuUfpUkx(o-!|L6ZaLރ`h W,rAWsSArb~xPΧ\J,wbD"/RPs9`!#(&OeWJr65LPkb#ޑ8A搮0 g B* 2bMb Qd^"ڢ7ҢԢ,k\n9=W r4Pxc@i2npX%=KRV!P:~UӅzġ]le\y`[%>n endstream endobj 1474 0 obj << /Length1 1423 /Length2 6195 /Length3 0 /Length 7163 /Filter /FlateDecode >> stream xڍxTS6"Uk.%$!A:H{E@z. ]4E@@s=<3><^ac5 mHO(P20@a~ PCC]Q0$B? PcS1@-$ E%$@(7*P -~:E) ]\ahL/`.p3!Z S  `h ~3j/ P  9CP'd:P9 vh+1a`( qC@Lu&@ pJ'W"w0 F:^0=t5ўh^QHL<l1[ ?P`W ŏqsJ@O cKOsH+;bE{USm"@qQQA vUیtah@`vP ]ݠ~>PP[= A350O#?A_WA׿[,ohHO8O\_'7V]# &GƆ H1P| wO)? -$fB 55ZPjhfF >>C)<]n"Q_L_>聝0e]PdA!QEQf%*[~ `8쐮+1O0-~[1Fg z`7WWHf3?  !C.=6FW:""D/|43U&@*itJ&f|.F=we.梱tC H:15=FR \ $PnW :Pg@s*=:F.c3 z1YWt7C5+gsho^kC?K> Μ38@Kވb9S(Mg-tc_±[1ߚ0 Vox[ZȌTN1z7bH4Vy*Pa0< W۱Sk Y\rn4X8ͅMLfep&a;G) :6 ]5mf__M%!N޶ u!Y)'M3w{wDޓs+k4f\q9qS9*s,q¤y䳆Xڷ$BH(J_-T{!$0tq膢^Ymo7m]4r;l9a [fGb3KF%OyZk*WaL_~ݼ?!^O;Gʦj3# !BxyCH~H#~fik;oD]]~=W! ^ `%0W$1h>Hh`@Xߵ`}E^]謇#EK 70Hw]LuDz!;knZ5zD2ݗ7YehwS^d}P.t<ĭ/D'ȕtWJ2//_+ 6F֦-%t&ߓLή ҿV\[CJ&Mw}Bl=EBZ)Ykޜlv;T1vM9 ]+ L"ڠ'\8Gpґ޿.1$|~E*=[>D 3ѹ YF荓cKFT3{HH@W&Fo{`~v*݀%O2n+ PN8CT^|1aFPW3:q^Ja)71?(;!Fr uA .M})#. :t`C}+>`5ϮhPoT/wJ3-Odymyt2ф:xj V8z.緺ϛ]Eۺ$ kS:ĝcU\$gIG!lUdX؂| =jRGDc uX?76Kl5tnQѳI@VK%/|>z5ph%]o&ñ711y슨,M-NOrҿ?]yf z}e'[cwEq=V3~V6(, |1ĥ 6 =w67{,t2̌ 7vBmIܛ7[7 #zO[n#ģ]Ǧ՞!5(<Zo\ VϼBԣW<3=M]qޓƸ]P6w9na%?>%T)s|YJw?tՙ" 'qăL%vlJeJp,i2aP'%y}([᷸{5wM58O1.pBݮ6lK&Ɉ_]&Q=<޶R\YI=$Qw,xDCv&v_NJļtm2ſ3o$q2ػVvI: + e}&J/T>}\>ck=kOJcGä,M<Ǐb /?|kGV A_ZM m>>6e~2$; "12iu{'鄛.݈A;%}Ehk&'95p.j R?RtA1xxq%V `Y,UKAGˣ}iLtw~̗$I*=pC=0wa.k[QRwr3]d䍣eĉz̼~Ev[1cj[3Ni[:GJ/QX'kqD񔻐>JC=<iW2Y)W6gNNNv(qvMy߫ZpMReO~??Ks׫z9#vRF ä'q;z;k{K> t>^~i 1tӱL3-Wis~j}ε*2zb6=l ;jٳnSb١zb^G!F%wRw>f@d\det$; XlZ~ =tۅ9 +7]]i:^*ӑuFCQ}Uǩ-.\\gx2j9gj! !~P5t!ՠi0uIBU_<{^Yg,Fх.KhXOyۤYTBXΙrFgjI;w4S㋏ۼz i3MYn@UՋ3UF[V&}+LZ^%SU珍d\&Қ.)Kuˇ͟h:>ծhUމP 82^yTjre :GGV?[xA KWA'H7u1d;u+;&>ZSK2q1Zǖ$Lh%ߋ%Ki*y3D^bS8~5I\fÂFΙD ӨW"uo\^RUak 8O}r5yp˓Or4wthR37oI  '1Ln\,۵?v]~UxZ+ө*"j_ >7e* ^D[̖1,';/B~o:\ZSA^XQQ,jksc7 07ZAR~Lk\xZ4ou\}gӔ*essv79k/c/Y}zLhBu"I_VҷOGj?r#hMb䍤=ңZ3sиа5 Lḥ}[ݥنɀi [ߧknaI$~'Wf[7mDBQ$dD龤N9LS }io!i,й>33K=t8`P}.,u%_=dOz=7{{*)oS$[pmqYdg=t76A~|zZЀLd{8QEG[wʭwM\˪-Ʋk"hKud شԂEsxaӏl&z)"?Gy6LĥRJd -yeaE=,uOgs-(4rcPr!EĜ(&>=EU< Us)kw(l.:N̻4`gb~'gT|HdZL"BGdYw=ģzb1ɵ8NS҅Ez<˟夂ڟV \ˮ͝!bt5QjT+w? g}iBA4$3֧"P妥OYB֕G|$mpI][2YAXTҌcBn*7s/뻯 !,Ie/my6t,U8D=DM_+u*j0veqzXg w[?ݍTdE*'^qk`U'}A; æwmeݰKfŅ V,:MAl8Be}nzHwEKOh;zT%>GmJq-G7eKApwcu`fI?p;d^i{i5*k:ϧQ'Zg~Iwۭ]{z} mWW9Y,e,ۣ3ot5J7w"]\Kedo^{"{\.ߔջ+AE.xzQtwkڴ{MwzTmww"[ X}OXn^T9>Xh\JIu/P<`@bh^hIzP0bm iIˋ` uNf(vv$dԝ]=A -+Gd\X![ITCUD~PF[q4Zoہ ׎OL 7O+wX=8޲-lCBckNgs42SҎPyrB^@cǼ-LCNA1Ӌ$H Dy &de)O{DN A9N]w믅Թ_vG9(j qE,i%dti'+yoB8}[λ#>a8DY-3>S"\ RG@3C፴ZrZ[jopW˭YI8gj=ۤuڦbEˌy=P_J7b", -K֋.4_M7^,;qT` fڴ edlclkmmu%VZ4_Iqʙ ˇ8AbuOI7Oe5|H?  endstream endobj 1476 0 obj << /Length1 1412 /Length2 3747 /Length3 0 /Length 4673 /Filter /FlateDecode >> stream xڍwTS[6UP A]B )"M%zv *M "]TAIQ VΞgfg3kA9phr*f0(ʀP8y EE Aa(T&$=o7&aHE(C IdE@Cp b y NEJ0A:rǑ X 0Pq7%(*!Lx(B `DvR| g#}ʀE 8L0#)2:XыMtđpG 6 ~5a/D $cXO :x86S(ĸy @Q&?/,A{9BP۬Et /i8,_J$#~ĜHjP],|N8 a!an*@8% (do\pm`#KpN"˟T7Ӧ?@ʖ0G!( =_I~@8# TFVP.]wa5~?*${ _c# {#U8@/BP,?ONpvÑ`9Ɔ8GGu)dNnGBp x8L;W%9!`d? 8a)s$ 5xeJDcu`!D%@~[Pbǂ?5@EZX:*֛L<aYFIXHȺ(A3=pYոu&-~9p 5T PKyGzUv>zx?76Zx?W>]W\ZVdgF%0]OB<1yy6zTV}z)j`AWkUg9EjS$MKL\\d_ZTMoзfZ}K_ p6SY8l{hg sacVzxˎ0Y^vI)zIEYqm>/h"5`O3d:$JkbJ#KhenQ- _oǽ Qcv W'-k5)K/GR$}8W {ߴu۠-5)C1@ä|lKJ]DOgR.۷e+%e8@J;\'uj[]ڳFǚPove<αA?mq<-w)0xr?NX†"'c΍B5 \|#H%p (iGw(]dTo kөXڕ~UMSw +B,W)ب$rغ_Z9;3!՛ߺTЙ\uq*??P g􏫐 et5RLl^}Qjs olNy^bye7e|՝fѐC\"1A=53xEXĹG;eD=y4s. Lexobq*raዼ6g'|(Blpo&Xe kBvl`Lwq/ :-Q>B4jw8%י+›l4g$:ad.m69\2}d*վnOyԓ5|Gs飢ܯY_Ǣ{Y| q2ۦG/g'4}SG`-hk^%/[,c*;_ ׾amDB2'{iRm*Tgdd|Z%P!0Нi3w幰ȴ 9J&#)3 dI (_vvuftx`ǯ| _!5?~0M㮑]+'NJ|^}AN+G;TA_Va*b2a;;Gh4^C/?Ƹ0}4~^/u4R~L c[STI8b4>'am)f\Qz4cv(hS+=8g'1.Uɽ΃)QN6O'S, ܳo9_xZVݥ֣D^$4FdxH9}"PIP_wGlK$2>4&D>MTWMŪQnSPO,ޗſI_HoxLx;uK)n,5#P!Eh rb&D~saEP!kH)v6PZ]O vu^oDccE2:͈-3pl=aqo.)fgiq4EA\;>RU'xUw2;̱n[#KeO"x-ԾrY41E('ȻzB\Z"z_no8F7_FG 2\Ѷ.B:+<<&"\aD,rtEjcM6%KHǰGܲ6Q!Jig'oŶ$[&;[zd!t ؝'2G k"ʐ.Y(%ېXZ*^xp._ڢ/9^b)h{#;^$qsÄ=N.V$ 55XIAtRB%_9-gJ:!3:;aǰӚrEQC z]Tb sLϵo8ُ` }|Nګ*##MN8K7FWH+lGV%E@\a$وpPѹkηDyh!12%{e(˵ڝw0cUvՉO R\ a9qEDp %.޴12嘋MY5b|vaENAYmw΃'5܅خ2l|j?+4P#yi99î%Y#fqm`2ld5DM0zoVQg\nޤ.0csX%ӛgU~ܓRVsJ(=Μ^.` c=Ѩ?ƽ'\#+҂Oꬹ£[ݱ_P휑c_˻|G+W:N_:NI#]LϢɳmp(Qh]] endstream endobj 1478 0 obj << /Length1 737 /Length2 24109 /Length3 0 /Length 24654 /Filter /FlateDecode >> stream xlspoͲ?vm۶m۶mvcs;;ys[Os3jM2"q{WU/G3&:&zFn*#L^Ռaf P1s01`"^VJ FVvVu[w+K??N*ffWK3@DAQKJ^@)!07s6(ZdL]̨0{SB͜]  '*$ aPٛd%qwu_\5_:{abZ,a?bS7Q?( `jfR `jlVYz:? )W@F:.zV\ĭBlB)`d ~tkȒ 4UQGc|,2M/l5U¿-Љ}g'B\qN{_fV/LmsCLOK@0^n=-6y;j":DQt1 Y e-Jq rF偍_Rgs]%J: z~C,@!d;;D&re) hҕ5"_N 2P)sF*j_j#U?´.h7p#L釡|KO/5 pXF#I ΙsCe! T);$;,*眽IT̚n2IP ]$HXc:J5*_|߁t ꥺIi2:Fbݢ&છf@T\0ŝѶw(6IA۟Uۛn"|{CPD'[fBko0ԀW>Xj1ez厁B..My9 y֟wV:mp$y+w 94==5VūOqhiҖtWf?B& {+ <8l5vt5z.+7D&ocN=xDUF tB+agRE[\? |PpiZ:E?vMiYw2.Q`[h5d Ҕ?^ iWzpl1MQX+GBgs2gÃe~YmH;||7m-s]#p)8/BV85S.\V"v3&.0#IF+M jJmࡧ~7KZ6rMu5X'Wu[XLM)U䔄Dj֤SYjzzU)s$4,Coՠ[!bkQ%E:>r/,O;y:.=N/>$2q 4CdZ^>"yw]I{B4&O>}WT,1|S r¸9jʏ`ɇ2ulv\kokv 09B/  .*˼ ֑Y()_ LoQAe}ёBdDɸ4+im ,w"1ܑ& fvaWfS =iJ=T́'B .pm_ ׻hb(\u74V[<ζ#S"<< +#jXYnNaeGifp'r0|Cf |g_M^w [8UIJA-n=h,L- ::S7{(K*ĉPe¼i%M*)z]x'f'KnJ/c!3yןh v vSvXazUfH^>Qq_5З7 (c;]q!)rxk 'ܲbj҂ql<1lͤz"U 8m窙rK1BLS /줞AV.1'0t.^۵> yk|UUwS8080ːZayx eSCtkz4s]*Ǧ&k28bysP0 "4{ꄤsb^!DaVJz - JM fFEx|"k&ބЛRo[nSaƛ)$[k`ȋGIэ./`dJ\1=;MgO{= 9S5+xY A(Ixt2g[`\f.Mk)!+uGJGێ!7gUʮ> 5+;m@}2qmJIӟxYY"s c^>خJOKTmz%QQ8Wވh!g,6%(nwWSbO!)H ȸ&1kZkmfyܬ]\S)k_c.T|L]g[2@){Ҟ-1?8))sFn[ Bo21jYHK^Dn#+:׾vƥk{#T._Mxp3@gg"Fb̄/[O @A~R<CJ?b0LA7"F%E\@fy5,(6E6ę5p{_]@ݚ-^ӲG޶1mg נDrUPl;^]&̚o gIuS 8M@bm,PtGt&OvZ/)R_/XAtޅj6 -(l!j=`MזX켸hfA f 6kwD Xg]e1:]t,9?T}8Z&&2LNA >WAgG!*I=:=y9g&Rcps  .mJtQŋh{u-ޯs}?Lǵ$:{?/c=Oة~-GL:LN{"\l-`]JY7/R^9:.#oxF@5Ɏ)lMQm1݁ZIn-ٮQ 2yy/Pt{)8SH~]u.2Ϸ/U%LwJ/k+-p W%Ϩ/=Y`HtUYP0S&Qe 'V,p*1&L[>ɾ#Ǿ>|UM(z"m`źFrqV#l:']M-Pjb#cR辔.5_Ȅ/3 QC\lKz̧L*/b=¯vmȱcdb5%uQ\"BXBACgSQJLqKU*!qwQp OɌ\*߼q{TۘSb^]} 0p%۟?o0wpJR|ykAf&{ۛ\HAf8h';SԅQZc%q: ~BRdHB\ݎf,76 ^tY'Vi([|)/9pQۉ\mޅva`PꨯX4E͓kZ`if772#&)f#Ab̞\(;.vnAbyH窦)58E$C&S%.@j{D93|˚_ y#2dHiցf>4dPk'*Qb{=G8ϙpp^+2縟1~I2n">: 5Ny|OwUK,Q&c& @P c5b{c1_XUՕ u1^&HGٞEUf)Cz.q}p8#jjtŸ*+;F㺣-CqtR8]]\ *&(f;I4C?#)R «B2igv N<˚B.kI;C[cg9"H؅vaq/ehj`Җ_\BpOI ~ ! 7ag[Q ͇2ӎM_!03 pK7g^E4hCoVgK 7ykDZ 9 C/`|h틏Ѕg<7J7Ew[I2i?r7F=}~0?yDZv KrY< RsjVɛi'8i1 @#-oKɄQKeLbY+[Dp-vԐDi+@^aQwG]X: fcIpHBa{ 0S7ţ̃@ZKEФ"+YhLE*6vTt Rfֱĸ4 jx5>Eʡ6ak˩ȺTK>-8Z8Wt෩>ؑ_{ OS_8zR/Õ$sn,0Cs2>.8?i3^>~#29)U)T__N/B |4V~I@,kʄG>RYxo&"f@)Y;nl*lYj~x$7DSA W֠<0Y2/%uqL6hJQmq+]K|"ԞkG3Xe P5?>Bȓ1HZ}IV^.Jw p"ˍzk/ȵK!Ƒ meQƽvrEK 3Fk#in;,HKywy+NaڵHS('~A'+*uvL%Cc2 K8"(i^ͦI9("8M:ASyu C31;̛ppH8("&ⵙͬcEvo0UK^e`!FRM pb={6O3۾w|cjs6_ɝFGEWa,^M%éߌ>~'DVK<^^c"}?{KHei1MDHc±-L"Ix>-Yʠ_-㰙^^gxAw2X,k(֒3nٜЌ7A`2)X0 5O\jβgRyiIMΠFYvv5Hubص_(yo{U8U  'ᥓI좺tsenuk Y (/)frĖ-/9G (kyv:glE5u /qv c"-ԔFPȥ7L9& 4֡HNﳘ[pc942yNؒ&$ 3Nw`%g 眚90Ӆ_U>,Tdd POfeUNSBvu;zNuJvL!ɪ*}Ēxw^`Fű=6 UUUCϠu8 avG# j FEm&GFئiOaKC9e=U0sǪz%g@CKLC\פ8$sIrI}ASqgAlp50 OƝk;~Ց$fPzЛ;_Vsvl)*v>_xx`iC-ص[`5#W#AB݉'F5n14)r(/L0hO 54Xe7mu* Pt^p;ELޭiU]Etk qǸZQ_Y9L8sx;&s>/Q u , `.0tAh|Ӧ=MO4T(?Kuow'4WX&-CqGԷ=ۢlm_qVEa\jCZ}22I4&KATwU ĀV"&$)Nai>O_2Orbگ߫փ|+J7}itDlbQ%3l}֙V]K\ ߧG2hI@!61=G q 7iCrhKI׽;j\xQk36Š5 fLu/PǎGlpe)%1*h!$NF,+Et"֐(kOW5zH1:dZv}7]xẰNfDudHаe 7^܈Et8@~#(=m$Žҗ'J\<ݍ4U:}q/Z(g 5 A\)RNpB?ǡ`or1gH7hK߬/.9N4Pz*-_&Q:Տ >nF#`aTڲ8fcBHIiCY倁-nq:VBu]3kRFoacNUvitDX \f,X>d逪(ż>r{`2>`h>j<ub ylȋj$}B6UaYr3Ԅ~Hik,U(h6 ݿ]`^ X?SPG#OI;g9NIg-Xذ'EvH͕s8}-hm{նo[#8W5J- k 6* iex@aV6n|%u/JeNir:F|(j{=deA,};꿴(7?WiK4+9 W7c/ϛv9!{0YՓH 7i5H+~zSb#7&I3b_ S~?ïl|l%aUqI?0eAS9u-o UD֐m05%;ґmVҞ6e 6)|h@A7 Xřrr3sy{Qǁps^/||Vb3c̞in;U+Qljy)ii=cr]H ”;37NĬ{:Ro#:HV8DP d!S~Y| ?& ddꁅF.:[ʳjY(_\<ڡ- py|Ɍ ,ڱ 7Fz3|'",GesQ=%`hɬNv%C16l'W}(hͿrsҟa_6]'嫑yu Y릣07Ï+[cS|ѹ_tO)B%c=Vw2P"9c٬_^X2H?a-8:Y``:=UJ5R@\C2+:e#t^TsmJTZ?ދ@/mT4<vRXcG/q@lK[jǧ pTPmZnFKCC|ң9jH^W ߌ^9dhW')X%vD  v;nL 9{chTlM_cAH.y6ԩ־!z b- Ey/ʲ6uPi:a ܑCM^)GpΟJT˿,j䈡 WkĜ|?%[I_E Bf`۟u-."ji3ZwWMH2sSY[K`haWWf]xs^{6,e8z4 ? %ET {ŁdQ[@}`*kO!4PlPyuCwx7 * tFsu#LEJ(x7ic`Hh߅L܎_VūCU;,2u[[ o:jo*YJ%}Hz CM!H1kf`d%m1-_g7骬&PCM #E7u8WR4W#X67gN>yNGt9k&5{ X|]*? Ԩ~6q"Od{fV#h4cPD1G.5@UENP\T@ N+KfnW-0snK\NŖe Q>6Y2{ȑp1$Ahm4q*=>g$ԃ88d؎ AգȈ̔ Lbep1; 7RK ޢƯeН=*.%3%e4jT+Sff4Aba[C}DhGCsQiM+)/T;m0j7Va3u^0M[D1J^3١ BUv!t5Ur}1Q:9Lks"[\N+*,Z(`kkj떼sL?~7" @)K> oaIX?>5+dj#ݏtRoSpGwb-W`dFW ) 1H/>nWS! zlRw~ɇ G%8 w"zY ]S \cl-j6 [HB3a>ZUk[nGugCHI=u~|O(uڶ"(.A0iT-h+|b3ya,]z a@_iOGzr>o}V43,j7w;UJ"S,2@_ip!f-A^ݡihpjrdZLR܇C\ʜ7B[^VK/#N'<7kYS?%E|}R/-&:V6zW1]kW#8zλv0l}Kb\O¦F%Y:wl'97 DUạ*i3 !>^BDM0t[+ no28'j4]+]Bwԥ$/zE%i=ѿ'L|K4Ny:Ig w2!i > O)apEz4[1:?5]2>ƃ[*'$Aq-_ͼv~ճaB9'tv|ȘmSB/@QҩxF `"LojqX?T׭˿ym1V!G;~-=$:@5 _%[08f$Lhlc&WeSpšg]8yv;S_ F&y F>+qW#cՖo2Eg^R IbK 䀏a:>a]=m08 ~5 EֵY=zk217/ 4 >j9d:W͢i3,^ !ܹa}/gφ]<~yxP1kbdp`f]15`'MaɎ~-dN.N&1 ee gJ\rK Z;R76kA\1 l&n*:7}q-1:(?Cڢ0*ؓ]wvMo .6=n5lkN+yNL[rb^p = -AT StN`%J8f_l!(X"+? 1/GB* I7JRI)q]`5&pRfw@v ZLRER?z#r(/%OTs _Aƣ 3y Q(u4KJK9gvRTM&5F)4q-3';ܑL Ql! +,Q,6ݼfLx+ 7'V6d;",U 0EX0H-Uԑ9B .H a'r7g^YK0Y]dKSb$"[^Mm=J^%0 $b߷pdGRՖ~Xf_g.౷Ncpd@L/>ӭ;養b_ (il(@BH1-I22G$_cZ(RW Uy0}' jUneI~qov#5ND#M=ay[[ 0)ib9y?):SlaoQ cS1!ʡO'sAPZ xp'z8rVzlORS٪KJU'!&5R>te@ؔޡL;eNi 4x /$0^7*03xӦSXHRr ]2B$;%T%)= ~ySUό{L?h# 5=k~22/[ϧ^Tվ?U/an<{#6 _~L7/,} Ose8|0p53\;h%3<̫,(yIph͘4fWRU%[=U&nO*tC!&2 q3"tW7}(RGbfg%1-2fnmῪE4rO0^.22\o̵o_MySp=R5>XϦzr?W첿#x1t!+1(ש2V/c33_z/Hmܡ(S䂟EU T̡dݭ83cD)C*G))/ׇ.DzU߫Cx}aon͕HѩaQ4^|T%AM"mMAn0y$ v8Pu(Ml_kX˹>TȡsѼIE; wLqw:mB{?ed'>yW%\Br3$xh+,Цd/krū]+6NFxXDQjڊ(k=%^б^"@? sIrγ_Ѽ8zπ 506).x }@gWWP`.\ĖZɯ vW{#Qgxo-`lN &qY|{IH6 9(TąNjgfʃ4=#'|uecu翐ƻӦxL=H<~nƣis.bI;`4KZz(K&cvSTcps&3I~%L8 ?Bl}.4QuƼ&#Z1ҹ, -N*=5o P4\{?H:HH%KäYhH[9!FyyOTHE_4^;m%4oݞO+Gԯ0f$iJ9tz9NS &N F§K[2m_<X=Y-~F [5amwVIT` xA2+O.l-?V~yE iޛ1ha7ڮAAi8ujX3澨+pX,h|, ZN^ywd/9JSwn5hмmܱ,NA-z<|d-/D rqd(zBS:FTM7ƿxYw˱ykŃ^(jwĔ{yQ`8;pIETpU{#x8Kɩ`c/>Nff6nw_+)1ԫW3MfJBf& ʓb-"}q$@IB3k_=X8Iєʢl:=؎84a[Dt+hHk_E/ zB26|Woڊl/?>AI#W#4֊]<;u'HeWC<2d쩪keԂZyqq4z rhp?M2QΨc:䆶HT]ZLJ%Z4f.y"HH>'6&6O3H%o"%Ҝ,<6?ImKqXq ls0+[`8}8„T{}^^0f֨(M rǵ9K"N)6q#hM@S4`̼M*ոP/HD{M`H3`܋5" )ITr!hgB,* )OrwfZ+ݕI%rVߠGhd*d:J O{2mc\mdo7?h[Y8e`;ߚ3c2]0s-H"l;S4q)Rϵ (/$!=OC-7XW[J`dkӖvU"-k,L躆 fǗUhАpj: %4]Y*ݑTfA l#Fɺ 47y8cF$ֈF4X})j@z>}k7}L#i54GgC F|ok<ȑfz޹i^KӌkIA9(edR o+PyPU閚͈u(wLrZ5K@]zO`v|^RnB&(Djpl(VRc]rk FOt(ɦ'"N/8@{! б=}DQ& -HN{+8Y'ёԞ3=>vfNNlsAfźAA7]!s?xJk`y8)qmF3bWSz7!(a P$H.Q hCFJ(,#^.71KdNQCI3 ֌x=޻fh 2O?Zh`(zu^>&ƴ^FMJ.aHĈTFKfvs˒ 'nV'-(F]Uoq@3@7pV.i 4R `Sp0_>[J 4[c̃!'yBS_Uݡej1*ASմ o H%^k/s 4o) Ž~…,sRǨdND:׶izTwڡ'0Q(ϲy}$3T0Q!zy;!$5$1(wh;~lsX,Yͱ/#q NqOirY-f%! NW8ɫ@upB6!WbȨ |$>@sqP BTxhDbgnMw~I*?$1OX9n8K\D;)•ΖLbl72RC#?}Z Pگ%"Rf7]IO$?KeK$EOyF1zΈ2{&8j|OsO{-w^Hvǝ$,D]T]SSiĶ1ZmM?k`妧&ľ7cK)zV¦q]漢vCBMBS'Ռd Ar}tӘt,һlnwFq :m}SVRuR466VH/4sorPEr ^L,S$-|-\^'RVcJ˘BT/XvDݮŚ$対P*fxd4 ~L6É 8X7: XV- \ʇnfQ70Gluy^.BY&:uIKGe9 w̱TbYz7Tp$6 yne4@w 4'Y1AE 0%'/>dGSsc=-|MS֛ 0jvDQXaL;ߤ;B] bgh0+Q[=|v w"] kZu">N0|@WrcѢ! uFNÄyOjqţ86g=8?hxBiALx~NkB  n94wcb&8&(i րVʓ)ldu$" |Ӊ-7UlmT7*(VVg]D+ zt h"w9lHS;l&A]K/qC%zYaX%0I3u *5ըLN|phቌ݀5qtL(]1aQ݌yKL״+pd{/;rbڛ{-͂<Fd́ OVsdsdj. o!&1`zx[FIcLC]0%w}vvaXvF`"lڟTR.cMqYXJC3PgvQ{?mW>r*6PqM-7eΣbBPVk_&{6ܞkl%SdT 5 3b<-=RwC썪ToR䞆>DEJŻy~ ^羏w`b}g>ۯ^3lSPY |u YTpA;~c2d%8L%܂_KKb+}2& Cݢ gO"4f&Q C ]YZ6AS}&.Zv4 f鑯Љm ;"oAAxqWUF&q#ue@ߛYz#eCAphSv (.m!R̩%OR;?4L-`aʈ^N>dH_a|R !06=j3G1̮'A9h횂ǔTI1*W*h듭ͭ 2-fìx3KmK&Yυ40:BY DJ|@۩<\q N*SҨe9H`[*RQ@ tJ3g)hci}cCR[4 OD'zω$!Q?N'onpq_jLV z 0C09>@Qm((Q_TI*3WNL}YG1֚2˓9C=g8# CiE7[UPK) E!KjjgEAZҎv,&&"/`u#dGtQ%m6܀R_f{A9)ں O *~>Dt%.$)Jg few7 |Ctśa?xoOV>@ذŪe.v10LZ3 ˓cd.[џ3*uۨ0 rhE I>l;T!$F:E۩gK-)C階k;6]लO|Eԗ \-7lO$Nh$ jߢ\&1}jTEl۝l 7;VǦ 9/~ه 'hߥKLdX:qq<{!OF0ۋ:Jed_l̊+YZP=B}L0R 9ww%DnIHLB?)¸&nS̤qM1ۇ5[ Np9Yf0ҋyZlUW4LO'!]#ٌ6 łmsDo< ~qٻ/QĦh21Cv5?-C_*pd >l&Q%cfAg|7MʿXHTꃍ֋[FW V3KkzTh2nExkxe~=ڴȞVc൦֤ed01voتScO1v_2iNjF we[)d_6pGExGԨ9 EUiψz~9,E;BNZAVhGxUTyY02g.{ ]JM3[^nv@?;zߊթwV̰zﺟ[ 8*%8. =qB*PK픫r)^'qE׍v/@DZ4щTyXXkABvnq 2܅: *wz'R'LJEv 4C(( O/;GOX_!+7sm{۾_+/R%tyTyvSTrkKIk>{m/vN$7?9E-rMphዄ4IK _2[:< .b5YI[ 㶕Cjx9n.zW#"P+^,B4#%,1Dԋ5*XeW)Ak~ V܀c l|^0 J?3(ՀKwRvI7m-lXچ-ϹSHG(tvћoGQp ձwn6yjǔ'pբ=F;SXo9`$>V,?Q#`$GbpSn+)1!"?*u+AV>梩5Qz䬢1eԮKtNIO׍%B_Z D^"J7H~[iQgl (lNAd endstream endobj 1480 0 obj << /Length1 725 /Length2 45200 /Length3 0 /Length 45765 /Filter /FlateDecode >> stream xlcp..JضmɊm۶m۶m^qV~O_}k^㚣GlRB1;[g{FZF:. #TVل nb P602aHvf #j65;k;W #s ?I&&gs @X^ASRN@!. 75q4(Z[d,LlL(v(#;[car7[WG:dEUT*[c?N\D9;:H#?^GHt0c #g- x5lb_?CJ?.r6& a;{gG-_ܻ9Zcoot6 A[cIX]LcV7Ț['NUc;[k?{=zaeu!AiEm-lih? ,Aߎ0?]@a_IE ٹ{21ph,fߤS7ƪweZkhh|%8oUUF൙[mdasck|7_s$Z LN uWq^K+|kw n԰mn#367Yr/kxw#Ư/=يS꒣dj}ÙR ͛lݒbVi4\[ kk*,0vK`iac섒V~o >\3@o ͧ],%)]ţ󗗥'xwV]]!y\wWjQ&Mk+wSzYaKkskb]W|6QUT{dE6R:[!-ؖq^y(y{T"\;иYm9ҭɬa4>gWa sfs쐗 +`᥊i#):ĕ<3LA9hs(~6oݳ ^vV3օ8\eA1x$OQwgR8gro f fD$ZwVXw[0 ro2uAkh!(M NWS5jŬyW,)xGPn1azܯҿ>FRyzvN[?\,;"ʴȎ_; ZH)-݇ugFϑFl"fib3NU6=WoI2jБAÂN'=TdkFffOf20.65 p}Vþ/wz]UmUnRi ]cLjT;f\U:o]M7}=O58ML\ wk޿-&e0D 3YSXWeJB1W)W'aO3S)*8y#RJR#EO8mzIX3 ^r5>n}fN龷.УZrԺ9ibVvA冷^iW ~R6St"ƭ ghC)#]WD)`Ȅ ~tp94!b^e! }`eca^f6.GmYw1946$Fa=D]O&x-rQT(2{Iav"Ɣ$Llˁ^F3[Ex3p~{v|>R-Տ-(mH, o=ܻhSrnxB.Z }uDƻseDf)|鹴&cИ3f^8Mi9~׍.?s=4C"VkxzpyK&1K$*4)_M^kͫC3xvtF~v<ʶ ԦEu%)fYC@XNQM| Z%OP^ٞ[wuyP4z[jцo>JYH乡|_j\ok"ҷLY׻WGBFA }S|bA0xy Fh;sMvEZUvs6UA9άU6?x7>}+ .yb0\e a:;t9ibcFT X܀w30PD(MIWݕ-ng۴G?!-3 'S? _e$]zDb/EIy=o+<,H;q Z;y%Y_HcO$^|BLg# )*vCCGT5g9{:@b2 d#ZПIȕq?L<܄9PP@v"ﲐ?EymfG;0ǧja'M$OI`Ja$ \Nb+?o馳RQ#k~ru&-8"|T\ڃh=R/W7<fh œԧ#W {jxcW v3.vwjGQ{ ȲT}TL ihBv'\Q;k=ҵUW-A!5ȿ:!Â?ի|  Yu?}>$mM=>TLwfF:禦+#Lm$Jn?ZI汻ׯ>{ IUjl5q#^գ,]OdCJmg#+h" T}R^X$x&{ `O?{_}yii`=7v՟CDI*XFTe@5HՠEsA@T\2dX 3;`(Lb̀AeWDV>if)˙ZU:Q l;8%A"< P(4tL}DN"宴5_7 &CyӆC+N$p')p\D"T~Y-2P&K!XŔ&g2t*[fb{-yE.fhjP*+> tryovi ax:8 q'Bç\65m\POCrr6sL*:v!m^[sĔ-Bxa!Tܓ (5a)ź@d_u7ҜƓ>uV#WvVTFJۻ"='y"6O^Yջo>wG,1Kuuic&Ȋ-JS1R6B"'Dq8_X"uwo{w[!kG ^)H@ٯ(:WGX0iz?QPI21433dN2󐲆UZf740Xb8t=Ѹe_C=2L^* ]Mq6dFEj{@D0fhkCƜIIKtll#i6/$+9TTJDN|wJ{XX@'vLu.͟k87=k0k&$DnfKn|xGJxĝ3DDh8bD>$dx_ЌQ!4.]nx_԰zLC1(>ܩ=2JocPsV,r-q?+vל$͕uX*>mߘ" uI,LLMF<̿5+OڥiUinM 6W{DH!G9! :CD°D^ba}n&50^@nVF)E/'{n iy%y~f'I= %4ot߶s{U-7MH".%ŻC{aP!1ݦTn@rx.i[+.Y. ݔͯ>3q\(ƫgV=e#Kav(OF6(;7Tw H]Ugr+r,V(1Uo0:RWE+2(T>k}2IpiQnh3k;b;BC+-ig =8_@=@9|/HJ-a~MEB=Rc Ҷhn~ ?!*n-2\xgJIsp@xoY]? mkbP1)̰mnl:ٌHW%̢ëOʈK]:st~h.Yٱz,!ނ#TB #{S)[K{DX-N3(WW|ZIkF6$f;x Z.H0|YB\,/zăݢAx %/.Y y@CݠR@\W{79:rIITIR"un8mW$|Bbv=2S4-F(6^R'=@imWj0@>v>Pd =3!PX^tWOR/gPZ {m39x![Y3 𛩿 ΡQ nz 5Qoc>ŏ#]v ܙt}'a|1p/ Bډ#y \(XN3]mUި[2|ɩ C;Nd3S*g3Qz@QFYp\aloY̫%HN"A 쐋P(5u\{!=].ҍJ멒8M~ݷA$r wwG$DX}`b˼"AqAY뻓iFWY/ QNLnJ,n4(P[V1E`|͉ fOLIؗ,*riɵJ2[#F*"豭:t6IwTbNZMkk+@tOl_m+[$vuay|=]H}Vw&[}sEL3 ڟ b+|4΄07RSoJPTyWqٶ by^(E+Rt}DZ_M^A85zlnH%tӃ5;ZtiB#}B7KNtqI* !V'B3RaTXY] jQu<;6IN%~MV-W!] my q+u|ʹQc@vnQL8g7UBqOQ5LujEm<7]Avy-6Lg'"#Ιm#Y26R7w kuyxƤ,\N"Fiam+^Đϰ,q,/ RàzS,gі؎HY|2Ι_ iJپD 3uҊe꿴U|UΓ nV9}7Vbfǘڃ_{?GIwM+̹=lKcbE+8T_DBHj48xIJ8bQ@ 9^*V\DNoQ%4-vY jhw6IqH5QV jվAĉh~./<ᘜ$7y}{>E֋%^=Vdܶ{́K5>(RE1ghM;nF>6;)2xo*:5p>ކW蔁Q$3V050Di%"ނ8cn^B渪7#q:8 D4<~ay@AZ,+ KHP _hPjҲD()9Mm2ŅuzBh)$;aL' }I/a"$׳?0^nVTXTKb4,MتJPȃ,=͎OJ;j^+uH)? x;M܏H,K{c,b($58=?fP7w<:?Xm"UJU@zXKSM .Fc&TȓP z T͌Λ[VbxX0w%M9H] Ŧ$zmiKl_sx^"k|9@::lT⺀ƣP"zccZINy(Cg"=5vySHv ΧfP^¹E6ynN)k|\MIS+#/*ޜ蔨͑,H`D㯨$|]P5/&4 ~.Zܛ>1uG̠$s }_@"G(LKZH$*551P-Fr:aGUkk펁2/bC 0f6 в/)Q}Rrhp'jehҶxCBjF# kxaiKb *_bߑ&ELOh:>UJsh2mJ`ߪ⿳`&b]h"mraZ"FazXPGˢ=,6A xH` V*R%d~-Ǻև #[cr"yٽV*k9'X,1BoBBOvl~>}^%?0L2sU/iw'/vnFX>s??%z[oVJse@{H i7|0UF "tý^H)5} ͯ;ul"#D+XP>Ύ ~F|TW, _M蕚EP^!m7OHaEhrewʌP.+PZ]gV. Lhq"JR3d`*o҉I ^ܵaT.<_(Ol8b0We>b8!wujRu uj~ƴz?E׼Ή*Π2Ykfs0q iF9vu6BIԈo:9!"\-$vׇH`%Tr_]pTb3H4#n bf#$X9GG7;mRxa΅Y 9:=6i)V\:&.bH,M>4NJݐw̉W:M ɮWtGWσFzyy)0EL1RAi9Hl+V2Gz<Ĩx(|$0S" ;PCVj}JI:726%|@mV];M׸+GWlSJQ? d}ۭQL\3]\9o-pgp:m$%()R=ZgNTfv5D" ֖̋ލKY"餟%]SWud'n_( /+bvc7wڢ1p ;Hy70riMk=8O@KL&Ii֞9/~|kKUޕ_wZwwkV$07]qӝѯjVhЧVtLgpKَu~/'‘c½{7Ee9G5Ut^ S.CR^{xI ml1k'ybg社\؂tp,{ٺIqb`ad+3WKU )'8C{`r<eJ~oGe }~o|2?{}ɒ֎{`>2QtYW yv\珺i%m k'D re{9j5/_ 1"j\inқyԁw{sUvPԯB=AI[z;Ƭ=s)2XlXڑM=er7Lq9 `,gziDl95w >VR dPHnݞD/ 9MA%;'69~ݲ0VJ=^xG]wv#Ax %h|kҭ?diާ9bݦ{]70JtT$FVeT-.4 tU2kp*VPu T:  P((Cޒm)=y<S sx4#d'4l <w8{ ۉu} 󤓉byojڍĩƧpwz!&lB46(~hN%-X+RuJ-Mn@|߄יffT0;ff'!{i[`t#+T-GUI!T;QD~d`%~#>VNB4<-Wˢ! <hj 1(Ɓfp|:t# ."u,J4+]kKT¿G#ꝃzƐ)I'\gsJdsa c3}d@H?g<ܥ֟=cjX Pj0۝4=d$ Uq&5] ocYԶ!YyGoOcRZ'D/pFGX6EvW]h?$_phHL9{ _߰8dN^%U25"=4 Zgp)&7'ƞ3NJ#4 F^fP743Rz`@)CŦOAE}[y>0(nKXO&oTyRgAXؔ0Q=uMic$E/A778(T6CUq.ofh=~$P&[t?o&Zu>qoss/W{L_\}t$ _f2ŽE"ƫsiΔ:z٭$ QBI$̯I5es@XA$2c5yB2ne#dU٢UxHC3;pi@٢\| gd*"ԉuQC,Ğ&br{C{ r[Wk' 9KG vy7n9CU/ ꗴaG­D[,+=lpv<=4b, =58th mŴP̡(:dd19*mJb)eDV'>獗ZkOp[8X)(;n#L Ď6vɟ5)LGAEn\ْ}d|Qv|:+_fQkUBAj l҅{Vˢq% tn$ufc}I6dn7F,pG&v] Ѕ=C#Tj~_SÓG=-o ǟIzmIAu*ڤpW8'KbTo7<Z JVP佣KyTV=4(Qנ~Ȭŀ9[)I'5`*&N}?isKEWYxע«-?{r]w223̉sU-ZbVsY!5, Jlr֝A!o)4"af6]'*N/eR0ZO#rȔg,+Hxa5mzGnEh7z<d?#24DKP0.PTR\/$eZlh>&|v܀e(bO˙^r#*.XguN8%"-r!%$g򷯼AɷLWWy/8,<`AtaB1LA*CTS+k*04@k={%j(M?dydV|԰VD>u g읽~c/\/O`|nZx?(&tt[M. rlie{n(%LYWUH!` @asBC]}n#]{p T>g=QQX7M0YӀ p`]o>FF4 l#r=Gb}7%k~mjö,H U&On1=LJ l%/"Mi;- y7(k;JYrעUzga߱.Cub 0NGkiU:CmH$% hV{##vW;BF1V~ډz5UBPXy0_JT_dvع\PJͦ5D AƯtNOQ :6H4x/MkG ױ?̓JjA y9vySeR#1i摱3Д"psm1,JDg\\Cv9Sƾ\MIJnbc!~ [ {K'*vܮkđ"9 EyU/~.}]J0g,]fh0E箧d%KzcSVɳ>~\RX4^iHܥLuX m ]8x7 'W2.LK Ea&~*Ω;kֱm۶mٱc۶m۶mc'9WeU0'ǞMf/OgAIQs/7xK׶@WC˹ޔK3xtWj0mG|ѡlUnj4BRk+ٍ)DM,ם)hE1(M?grF:Z]kI&*c.vJkU=A.E'Xi3X0jcJ_xQLNi!q1P6Ė{7ݴ.eʳ5H/a$GIVKDXwwR40Y6Dj4@Cp 3w@B'iT{.zKJJ`K=D_&k_Σfe#1\1 -/|92*IKgfE0rYIl/ϖ1EbZ{pz~i#\JX`qqogNx`+xMUR4M|BԡhOY[&cOT!P\=8g6ۊ%OyOyNM935KgaEf,*{Ⱥ@"#%!U*++7Hc)\: f*_Caqɩ u24`i^m%ټ.`OX|X-(eF*,ШV12Ձ?uh;Z CΌ'ػFOB₁1΀N{;f3X\y_$IZ4JqTȢ>ݲ =-i=͸ u%1y4/fFeO6g0|^lP$UphUJ:xנvSanAQ RX8*kGSGvI Bp P1$`T.8Y2~7X؄\ocz YR8Ft=U8\^^#UX-T6Q~?(jEvØHݝt>7uSEe˧g4\iP5ehX:ZDN)mK-QcOlbx\ܮr`œ]$<h]X ߃=Z=vk9m/ߌ*BE@]vT(C*=yG}& {g^`&=/Noxplޖ#NjOѺ60h\Nzwhgu &gGi ~m±#N?P8O0<|d턠7mfVEs-1yrHid昬Лu[ZɍUҟI4I=Os!jĮ{Dv繉dpy:I?&},[ v+W_☮1ÉͿ؁&2&a#mbCOf7S-|_/ &u@s:Sm;[ˊWm8lG[*T^U҆nӶGw@* đ c(OYFx؈ ~g+Le62z1b}c{yg#Չf";yy)b}~"YVMQ&+6o&=?Cc04V*kkۚǺ7|_4oThr~q= e]WjcZ `#H-2t~K9w UHķE ׸Lby=`}Ig4L%B5G,@p8i֡]y3l#[ |#ŀ 1Ϡ+1mCB·ƞt#F!_0v8˛'`6w1 Eۿv'{PۤK#$“g/*4Y շQy> GL#Y x2SqI~C|ЌIJFq|&2w:@AA;|Pc ;1hUEvEhd1p|mb7iۊF2P`YM^BKVchtCQBƤ9;l+PgM+7A6yKk2W"<_!ƣ50m k/Y\ ѿ=+Z`p6BtF't$Y1xY ◢(1lkn /GgGo{cvǬ VrX0EAMԚ֍>~j>+9 U| G:pBGE#f'顗&yxHr()V/GˢI:+-IE4hٍZbqFC`-n Tb\K-f>jw}jl鱷aj+ lG#6j/1fn&a}q R0d3v|Mȥ$ ڍ 7,Z`žsGDGFur5u<_r / ĄZPR f8yn%Voj[}Hv^eٴ2e5Mt=NZ q8x!P s&xЅF,Hx1>!Lp4fÀ\q3jVn3NQ!pi?rSGȸ+#RiR4&'^/͈‘ăP3,קQ~2ȯoxejG5vN$0-퐄nܡ'ywWhA,k0PpfF tJםѿO7hrrX(B7 CDd=gs} aF.S-~r#-≪! GF,i߽VJϿ>7o1_sDMUNX0 nO+қSG2ϾҔb@?8keiR̠z! O)9x"yu"u.fԔlܭ;1O9lcpT؏qXпGFGA sa ,l/Jz󼧂#^e EOȫW?>Ci"2ndFKq R@ѱ-1u&;D}y2@r<Ǖ?8,+i"`e}+a~م0,SYu5|Y9 Xn.Vt9D墄zh8~D~gIJ,L >12WkYt|*ٱ0a7MgXnk{~S>kX*i0 LYyC9 : )u8HN^N'`zpOBkH7c9|~(ImJR9 'j=S6Y"} v6 a{1ؿTTcM[E#)o#s$/_K4?qF~R_'pagscUdhz gȁqz[\lrEJ6@ѩ$8y~)o2nGP]4EHHv݊0"H1 gÜ(LƙM7\;:wɱ"S(!4(n!e?1‹݇#:C<%nXzЋ,^vo!JX'w|gCdiCT;I6F2$wPv+M:9ˤ7M9KtV-)?$cxqX I,#1rpgPtyKrBeqR߄+ iaWַ5S7'< pʎt{sb3V[k4~nCI`އWCq@no%FTj3 vF7DkCԒ$&򢾄5=)aid eY6;SI%lL8K1D^q3no&,!}+Rl=MF\ F&&Јf*$D@9j?y8$pdVP\?а GȪ1Þ<ߖ ngAIu끢օ&l :{ %j$v 1F8ARkp=?pԮ%HcJIb;"hG 0zz-|x\kJqbgVp,Wst=;?ģZ2G1.`@Ft߸qj]ۻUjQ3ٕvYpH|LG]<>Oj $\cPA|ع>9*xCiz|R!"oKH )oS.lkOpFTδE_/ $ƅ=kdڨX]dP R=;̦f kT $H6MVDއYRET?xm?@oW$@!Wyl|%vG}NtAS3h- Rh[$^B!:t؞V/ {P$mٟp8Br/USc;B#g ^&G5)ZY |lOG;e>;Fn-)>~\A7bipZϡ]t}'b.(A% ļc@a<ccڡ.6a/t0: ( aM jh$+*Y\yKț*r x'z x|s]v;4>7EKgq^%Ǯ?BU(}:&V}X]4,_BTX']vQӡ\R;yv*++ [RSF'&)vqOLj3H 6sX0ri61ݑEM|TOá͜]/#ֈUkUk?F5rpsɫvb sh=zBE"W*ZvDU̽UU~d-;I~ڻʿڨƲw -^m"p$@ ]B"8Mh3gbJ;EKQ "%QnO4+sGF3]fR!S]D1CD!qhSm%R{hÒ@ƷB:2 ql "o05r [ޚ 2s^Jc~of]-X)lG #qF(Pqsw*G IwK#-&ݻY&;s>efHs/e~߈P`&/stHM2%%W2u"K̃DI- ,?&cgFVX޲G|tkN;6n'R˦pj2gH . ^ :{5Yơ@Ȝ%o&o2ҙ> =𼷓-hYwv%-XΫ:ðx|c8J =jZiJW0@IV!N:e2 %!~f^ 'U4}TY"WX]L@Dea+THNUXQۢf7ߦqPўˆB}B oJë+x\h%hO!b9/J~cI xsΝ[+BLH|5^C'J,Ijsʔ/Tw!)(ҩ{\J_?]> _4i\I#B"tMUn2o'}>.QIO:֘nu>o0S%жkai5 Ië.xіWU>-^9ɜ~KZCSmZtbĝ+_@9 -='sƩ{|ޖ S {#qq!kω$W;n >ǼuHc. %|R@ś3vA4r =mmq*m/d5EsH9d݌P[ ?e'j:ʔ/ q5 -;ڊ vȇ,'TBM˝omOMqV39`h%j@$V#} 3|6mYiJO˵ܥ< 7򗢑uO~g!PI0r1 x;_3@Sŵ/(( &OR"{I9^J!O/Z0ߐC'(c w naYfW44ғ>X5&'*o4c9O)[a$+\:T!Vx=V =ues*h`|cNF/D(ץ>jNwBQK9a~"Dhmw[-g޼#vNy긓`sSK@JQ1Xws4fMc3y+%Xx:q`RW=LՄba|LbgG Iv fS鮑DiR$f*ȑwJt:%tP.Z3mwUjg],Fm==@BS @` !9BZaZ0ET_h%-(]F.SpoF Bb`vXglZl'+4COi-O { \s](D~3]˝mE ifuȔQ"r߁[cT - A(CAkĚC!H`{NT} $\j^(5BI~DuC:zrR5W0 ݓC ;%7)uDEfs|q|ID5#bs[5찀\i)st?i`11vS]J6K j Y#壷:@ ]yAPiásr {z FU}+4r [:-p7`nI\Yot[,3A\dtCrSK, ={v(wC5`7/I_0 π^{vH9CmD 1=MS3GO1dMp^/~W}ȟJMk얆 Trx[6 Z#C^$+QYRԁۈH9{v(O;\',^%Di $q룥'בܞ  >npd9rac-r~q[CUæ-raqjYd+*Od(|L7ivRgy9Xrz&xU?5A5Ʀi14^/cnxQHyRۺk=#p` /x?m#pEY1s3D kx&K*3p@VUXmV=g3ɗ{ ;'5u S'[aZ,?b5 0p{Еn|_1xwZ;A3RsAS#{RB{NnΪ?t*b4 ύ$+'{'$2}Ex]W;q`Pl]KX޾O6'aWmJ 2A&#^ F:1P6?˙&9ɐAd6V̹sjƐK\C]5eMZ'A;/@̀KZBEHP9:IKUDUn+Qe9W-w97gwG$,4B G$[.?,i~ C(dJal}ۃ{u2@ I"n!<,YGsYu y {1cF`y 2lqj[Wh+_wjG9; \}5ɜ5 %Kɿ{!E fZF2}kH *Oqg)Sx?Y*YOp^y|Ẍ́ Ot+u@=f&һҎuO(K ]⥝G% Ay9y?R"Gȅc'zOXyiz\W\FshRXL4O$\Otÿ(~U_`s,>(75}+y9<ߺg{nI=@/OYs^/d*09T v&R#@Ru{PҊDtl?=:C~Ǝ E ɀ;iUsp~t &`0n'IaeJj8,JuDFRdLN f4{X\"{\:V|sV9 hdFlFIp`J$h) {pD%ۣL&YPo{o EɤW)4 Q*?z|GM"r=rRSC|̌V tGQ=83t_(3{0z"9?k-ꫥqeWԆzL3Dkӽq+U8Z3}Gx f{*o㿲ڎ.չdi:fFFV"rϽ(3@S Q .ni=yNO.Lkr\MaD&'1j ^ψ(7c۰~JϏtgӀBE ){g2Zwmy8DHz { n!ܓ(/@́(i }8GvƔ[=sr%T4v&`Rʩ^f#HUD8`*U_%@N,g4{Br}npC[KQr6z_UTl#X𕝗hLds>j !L!Q1)|O`H-ًrC,j%uOo#>8-t .c͈ $ [*Z.eC6u%|9AAk\ ZX4hDe- tE_1dPPa>5ᗜxllq~9[IC-튑ה܍ɓ AS>WtEIZ{ۡQQ~ľ(2T6:BIIj&J 7YdhЦj"#>A`ME H؛3JW&?*~W[kcҢ*گN7}w{rLW "I$xϪ+O% 37 LE%Q\~8I\۹Ê}3ϺIε4*՛ k%b!^#+,i6ۺd|abᖠ "?KsڣD.]P/\0a IΠID# +S׹a9dgheV>ٍ[D81 DٖX'0tzlm0/_dm&2rOӪՏ?K=.)ϻ\̓-icfрeLd31& 8"xK}ڄa,}`C6 J*5\vBĚʩzcrR}IVjP h7" GYV\5 L)<{bیf8HH\j\iL|(Oso ]+ϋGњVT`8{!uNXR /зwjGP ȦDȵ8:z!w\ν ^+$%(=ӏPaY- cͽԡZ y:!D S-N8m> ʠА%wje`wnF.[[&l~mFɒc֐Ǐh݁MJxjEF~.XᡑauuK}OcD,+ؤzvlK45WvK:`--CYK< w=hu*=XC} ! f.8o0*(1#$ 8Ur e:N I!+1E4g-U^E ,X]{Jy<@S\̭[6wW6a\nL,_/͗aҹ%A_P*z,=dFx_Lr 2jZyAN9,4![:OMRPRp3*F}{\ܦ!NJmqgД+hFȉgkd L YN] MDs3>W_/z]K h 7㭲GS]hOmbI}e鯭B:զ#M I(|3<&2vژwe]a>}n\ CtUKR!b"NZAJaMhb4JEMmI?^/-QT JQ{a>@O:E1U4D&\U T&Q@&ֹ0?I_B> " & ".C ]PWN@x<^kAn@gܪgn'|(+Bků86(55 1)]0Zp`d+Ǜ@VQGqlDA楱]s@D.lsU~ _9҃9%8G 4Ş1jПIu'oNs-2ilޒz-pnR0V̫cN[lr1tG3WMSL /!1Ѣ gے+wsEI#6&VAN9Pa;?1_# 7\JTwPC5g!&Eڡx{2Pag%s<`}bj <@,L3JTx9/_'݋DNrQdcѪ6B}ċ)үgZLB9}/o{q;axv@swlɕL2 &d#]ۛg`s!,ר1݉:pnEh-"x|| +HE`hAy&RtAbX$ڧ 30y="jXl?-8 9UX)`ֈu #Uy[g62bIbh9lYo֞sp6pİ35Q#ׄd^ntb_ʶ~Xm"̗~! W۹%=*)vҩj0ο0%5c64"P+hzii XyW +@w lO~d!S tT`b:E-!!w sfv&+<^cC"[lJKr=|dk2ȇH#H/T0Ԃ)7OKms1@aZ6>Z1aunqgh$0dDNrw⋿8Ѩ1"uef*۷m*V6AX 9!D %j;,tp"g9r JD2՜A u*bWb+>ylLXG83赀:+˨|LDON=ٟ 񋌃O87ÊлpBqT ?),O w3R)9+=mί}ٗʢҦ/]#V` _>EFWfS" (u6?eprE?}n4 'L1|/RacaFq=yYr(zQx61hǫ^;XmUQCÊgˀK08R\h[xmZ4*(0]T)f8 ~/ 먥-f=&*#^&*zsC6,,Nb; '&=_֣Ai!*Dz6cY>AFZy옱X!~20О[cZ}-\\Ug横?aJ"E\~ z4mzQ&qg_>i)Rӷ@UaOQoT/rTu!-x痨57vUu ͛R=- e{jܮe`p t2..𢣜 `M]c rT"^ wi`:;&!bsˡ<]ī RPvBAjop#df-Vtg61+`>31=9(AnÐ,q<|PmV *F!6wfb^{Nnp9 Id]Nʼ[Tr$eҚQscIJSZ \2}6Zryd}&bV⦷N#?5_}a0OR)5| f.}@ uA-ںIAvUwH d[ܠ:7\:!|eApL3Q ԯUXv)ľ'^潝KբRĂ$F2īMȩ c9#DŽ^H@eF.iT֑PZ^$. Sت@#4j CGSpy۾Q#$lq7Oz;wE͘fw_ ]̄e{PQך%,ȲeTba'kI3:c#>sr&7zPE߷qѦ 1xR;$ щF>GO6qDrgtެ~_˃*ߔ3kf#<V1)x'MG#Z/̀6Bǽ*@ Md06uӺ?Bݱc%4{wXi|vӞ]l1*|8 ikxn@bd/;Ta(_(˂zYS.Q=߹BiPoob͆I>6KbM(&/,Cx`7 {׃7זqW,OjZ\▓S elg\ܐ:&R\ؽܠ-Ar1Wz$T,WG;vd}zngq_qsTTG+dk",n`_Wf0Vğ֙+v3`{mZB)C9* 2qn_z:É9NgCJ z*w !$&CguۓqƢ]~L<Hqv>j@u::,~sں ixuIrA l_ H4UL@GE=9d81<ڏҢ[(Ϸ/ApY颔.~xfŷŷE}M`NvGBtT"A' "|20 ^,xDV>j?OŸ|; M،\'*󭮰Fx q}8XWs}mk* JD $ŦRl/K+euN 5rwe,ηF uD6w>RJ4j|CX.iÒta#4 P4{q-P=DJdĴ e,Ῠmkr&Bfjn;nH>9,Y5[CfZ뱍a"R%)* U!_ y>&W"a7W)oA}jq_B N Vb-y-.D<}ha$30}TAD4uhJ`0q'w&-d4AZȘJvrč3awfkK*ʝ۪LwyMR,3꾳+sdG" sh̡=ܣQFlRZ2:&%(.\޹{]M v{.ܞ.iA{TǗk$M d"zօ\,dLh}1'sHBEdiTJ4N%շ+BҊ(K[ߟ$rgvcw%2;O "d EEwG)W+7v4%=ì|Bb$r|.҃$+KA43H1"yYEk4BҬ4`ٺFT6I\r7Qv⫮1X:~Bk܂U׻# Gg^PW+Cy =.Twk]±dC~͟Tr#Ae`1D)jpz?TZ˰x26\Y}Ji5Gf MV|lhnIS@5h%"8?+3~xgi2썏Bv}e_BѬc ϋHflpS5%ꮸe-l^bC66z+Wkw<'>SC_OV7X@ab:nV=$*s;ED-zvM+fډ+x}x7[w/zz\$ +r v@6.rR2c w:n,g~/~<) Xl喂n-7HI5'y/}s7lל!7_GVEUDiԗ5<7›Jj_ix[ | M.:iB2;(Cq!Of8Xbq'tBt;JweH4Rկs ȥ:QvY RQ&M\̕3P%U\NLn܍fTùjO,< ˂ަ҅C3DT –FW(H{6r X;CD%s=i`X }%>k@wlf3|ƍ5$ C/!t@Ѥ:rMz1+#gx3*8!_ÈoÃ$E~u[YgC*~>X3u1(&O|=(T51jSYKdˀlvoLn>{yy="Eۉ]9)W5"vp Gs x3 . ^SRӦ)2P.淰@F9G g0iMiI!?>R}51JAdmlBT\p1JkWEv.*5sz~~ZSWݔx{n?ů<)nzOB" ]:D2 YnN\ۿm dvIuB|١R,;y=Xܿ˓aMl9LKJ=愢_@I^aX9F@p8n^J0] uγϔCUz4H!ru*e^ӂäC*)ڤ_S%#i%x8m`7K{GŁQՌ+Mx"y`f=MW uSo{M&PdޝZ+iGW5R Űze~۟.O,:YeDZHi7Sh)6YW(ܰKlPI9%Ֆuݜ^K6pc7sw/~zrCYNݸqF˜DAX3;v -h} XU=G=akpK\DֲHonPE泂Wq2LhA#?uTE1e®qHHL ڴ eI!>=.ǷDv88#&})BPTgӑtEgA5T|Q\jȹa.׀륵_Jĝa^t9ьk~zԈAc,nML@Ӓ%x Jl#QTguy*`&(X [mɔJ3N  Β]N@pJUBh7[Jcuqry ױ╽QN#km^61'/>vgor8zǏLYT4W^B*&*lWaH:M 8MzԌNfOAv{N6M9L{}N";h[Y k$`$Pr"SʐJ+RJ<*/Xuh ~5,1iL`#k =@">ZZ]ٖ+Ѵt%"%?z0BQ9eXdpY9LWv7}s(cVJdu=U0~wTz[Ncr4X}m a?jYD&~JP9'170ӎszO *;PCHkcO`z͚o EsҮ-J*Ȋ5v5Ja ?˃ F*KȪZ I l@ 3"FjZzn/*)&WR/9WȹfLUaz\ CCBtzJcV烣K; bV'K?(ViIRKHƧrioL5ZAbIMV=r4\UX* 1?ۡ41#ϮO҂ cx3?Cfdb)&0=>< uMR!y˫Q)@%~[̌Fg~%ۼ(xTW6H7 _ /U1%֚XqD)A=[ƚ ,bȞU] W"C*s,=EV]rÚs$|#x12.ޅ\{0DHtߏG$|/Fnl\`2,R7s˞]_t1G2Gq|ή4)7Aμn0IVsh'lo֮ƶ uĂz?Flom՝|\t,o%6(7=Z$/$+Xb̈́}FFB^O() z'Į^Uh"DeȒuҿ:⡅)Xf40|IIsL ..ig^(,)e#c~e W)+Uls}| tѿs{#-g! $S-ԋ?X(f`y%&r0N9X_]rVKEkgu'fy!;+m?$]*xtt|eGOIojMϠ]"̝FFe r)V<~q܃W2B_ZΓ^|A!-0%e+zV6 ˮo&[[Ll "_cA}G iUOF~c'ب>'7m0 &mu~դp ` /1X|Umi-v]; 0bir{oN&Mxks 7yK׾so/"2♞3Sq ŅH%cv"%4Zg2X:dXlqx0i 4s+hG뀁& OV'`;JƏM/).@<Qzo$,Mg<Q%w)y_˪BƳE}нcs XZ`o[AH_F,{-z$wc.yA~~cЕ,Th|9p6p +RQ~!LU:RI 'Vss1=/7ے'm)*@3/C^'b/"kg8"TwCA noz#ClG%W:yƬDF<1bK/sw|^WZ/EH(Br`df|ZxD[q[d6̢~t#baL T9;!);_DWEd& =Efvە**M/7DHRc{/:rQvx0'Ĩxc`mr _ۙfR2yI%Y ~+!:qߞ#TPI%@dWuMr' d*ӿh&Zqlcf*!}!eIK /Ck,h7] 6A-PEIK;O5T(FE7$7 o(ZUizk* .PʬǖoFG5ihN :cb26 Kӄ<D:ĘH||⿋~0+^|im!_*qhM햔#W"q'aA#%J0˷Xr@' ȷ&=w&_>H;7/Gauu H⋋:vڐNjBoָ^;-k+(r. ю"CyL>*"{.MS#- ]v> stream xlcfͲ-\.۶m~ʶm۶m.[{s=9rke$%uV7eec"PSQadd%`c&%v45tي:r(020100B{8- ()$P64 \<N.t.|ttR65%p0%0X+hJʉP˩ښ:Z(Y dƦNfviٚɉl]MfhgC +"(&/B *L"L`hkB #Ow[g'M5; [2o鿭 LF[h&ikfG>8$015ZƔBԑ@і_ܻ9 zH:C?1Gp(?ju ?MU5#3G/"'&'MAo ֜@> M[o!?_X+-kp'fW0/IܽhXh Y 8|\cGGS[\`25u75^_3Lk -5P^e3{0?ƾWwś 0ݻڕo!23=& ]~-!4~W,xk ec,vq眱@5͒{Q+PƋ$mP9h+NK kz@]8oR׈u$,?hKߢ"(LRX[Sa[#O Kd;lǵ+vx+PyWS>B~Y<[.O*ȸ'^.9YuurHYrEQ"@6#1} gMI͉5ud* |:QUT{d_w',^]R!_Λ&rl`&y2gPgR@`l,nLg9ZXRDž̙ͱC^I.TH/}hא$.+R#+F \36K4<+T~5B&CLYst}L B_*X1Xf+(U Up̓qbٽܸYe0{qmrU- k/3Cdރ[ ?ˎgӏ=&O`e:c'[wIi=LJ]_Ph{;*+Elٌdu"ZyF[`k4#J:ӵDA&mW*gEɍSq,w&H"? ɰ{`7\r'VC< 9AWl_ujnGwIi_aP}qJV<+o.G ` H H;7Ut7P8 mgl9wG1R{Aln KtzFYl$NӳЅuH!-1NXWì} '}J9ITa1&Ӵ싷c ɾ䈯^'NЬTgL嚽]l!;>kmmgJ-Kf0׾#Y3GIݦ)~C]*ykEO)Ew︿4$~wvv-x>uoi9} rwv;X eػAWnkk.}od(Ti |? @=eUQJ ̭n ''2I9D#8a{#Dw >:mnBCYLe)FgI:ء$:}#ќ$qNwtmoFP6jHSˢRU 07 m2="[}]Xx@c˳)262&No!+HLzd*s+kjW/9 /81E 5H__{ mI\3\AF5p~wl3UW+LCȤD DbyBǦt_ff0r4\uݜe^b[%oz+;sL饙]ɶͼrHe Wqa0r he᠕amd08O1we: <`_k +?%5@ j G/%2̬9+ u=lQwbE*xjbB@;={&|ptwD' ̄Qץg,҈"иvDzⲬN"VPAO\O՜xy~,W fppNȥY7I<Φ; \UĢ#wl42\lWPcE7Wr<8(4H*K,yeEI ¨6JZ,qÙ|6 L=^_Tu +&i~j{ %;i@TUN@dwVn'[;K~GM矱d3N-4ƫݶ* :Up8wPAߜ?y.:s''(ns/L;4,:cPN׏&-:ȩBéN*yaM#ٰ]AllYͯ[`k.; B>m5 uC}rw B%N%/>YR=MUB^f$7[ʓ0҆焬&_;EjaпÓ#RMB%w{3 <{mҜN9pGO[_̕E  eg ltQ[FBWCGI {kw 4b._mB;l} |wo'y$B?R{9xUUZlyHAk\!fW }+Xt`d>48ԓt O5JI/7J<=/G&TFj˄A̺75y3T3S~ni" 簃# pXt-^lYJ#3|u&tʨGBNmva(h!p<:?6u`k$5=AO:YPD]_[@]g2L%ҼccOXȹcfeu| աD1.Xh |NV6vTJY*e6_LJGuu*I^]~f͔>t{;( j} PzqCMv)Z`%^;y\P,ii\4G&+i'zDT(c5BeCpC:TzuN1!kmCL dfcEW!{c)~2@۠&#~?Tf`ЧhY9|_6<xى{1]sh{u#%ބl:. e(E~Q5Cn*o.tr%Έ8#tI-9k-7~ʗw\J p)HM ȧ(Fa G¦5Nr|9Mus͏#h%@B0ìgGphm{Q9w=?+0UW h4gM3V0r۝G'Gtl4'uurMw|j;;oYH(9qo!q@UNl}y|גnmXёS:Z/@+ Q?h6Dc˟g&| L4S]nQͽ275B0bjuj ,l<1F>PѬS9Qb^`ib-Y$آc`oQ_@;s~;7×ڰ0cȄn۹٣%NH\+ Opwm-L!+1yW?? )? kfO؟^KSYUP-z]?~lYiuiӍJ`&%pKY}RIRJ(?^ vV6;y~7[N`]^6[fJxرCS% cZ-5jt MO,O~bQ0rIJA},iAte.F>O.6B+F5f{ 30 sjm;BaUwKTnU.N9״[ȶML=SrAS $6cu{G[-B5~fܱ3$^0k98 [kNH%7īxD5aSqC$Bt\;EJF7>dwQ¢b^'2brAhRseKt^EKm`R|sz\]6 V߃Y9(h̫'kAj- >?N}DgjZLƇ2odžCp9~=H$J+z!$*F x*xAwR{4M_If> BBA,Md[+LC&Sf\uYy`1h 3!LLT1 QxɹEhoZΓ)ʦrLtr9swzuѶobẉ7x$3O9 "4Ң_[,& u-M WIX2[U_\'bFR=aD(wӢC<ο~"7V]eH ]\'jC~m\Tpdӳ,`)<յ9x!xLjV:.VQWX6҈h`*KZNQETѩ珅o,{4 5Wq TQ *@p+Z5#WE.G&X~D.|<$D' 1>:}P\c]Ca"{?n C= ։o gxL☖2MA_8KD>8K[Dx r6*.XY7֚ _~OiH3b*aDW@~p4f!,~]CPiԟHJ-"4:?iۿ+N-3RU<3iYPuB}ӎSvsw)R9$ȄW("DJXQ0!> `dM+PbGo^b.LAK^io ;6ND%k@$5'Û>Xe7Vʓ$NP^C^]IOtG~Cs㠫<>6z qS9tGer!L"v :+|O,wi?; ܵtxdlbXK/-nI *J@fpRB};kON:‰j9E U>'z T@s1˪e&UX]S^5K;n٘PX6> a56r^`B.鸿кf!'<ÑOy8 |;V^]fab+]>]J:lhweȝ㭱O=i.l/a?%=JTmF5JUl,`-d!3&,A L ?(J:Yt]Dh܏  Dr4`V_U.1U0R,mc+cc4i5VV֐-anq7;X[ѽZ0[t*ZVj;IKX 6\kWB Y6R:# ɍ3 ձ!vԞUR>?Y8tmtPlw˛?Ɉ`xocVjf|Y@-kt0X6v!Vw><`+lH/",Jx(!{*W=!/=Ae$X!ZMra\0>OH-!?7 _Սo>Xe“ + ;t'{ [qx=l뾩9 q^hEy;nZғH_9{YP^iQ$IEZP vl7Yc&f)XY8X] Vӥ.-UF3G}/ЙBR8Vn`%̺_Ԗ 2 --įsA]F F( ̒ox␺Yfu!YQIgBti଴YU.@<@uIuL!Ί.-x&ːs*qUM8&5-ľINL93{ )101pCzjQ!@_ύDߴEҽm{ն[ }>31{~Tղ.VlIhK:d+nsTq[|$l⾀?kUQXTPuի9k18ٓDDY"0K(.#v|#os3=3%6Ov6X{yk7VKәmO mnt = KmL n_>N}zV1*No9tDc+:{ؙ$hxa}@S0-c3א:!h%;%)7}j4RFC|,'QBB.ȾS ɣQ`*`vfգkv1M0^Ɍ'~L4YPBI"Lz8qG5_,8IlSwxhL#8r; eK6:i/.bi85ﰇ [9'XpZLn~5)bvZ3Z:9ٟ=xTٞGD@g$*ޙش$}kC|,Yi(rw֑M(QW/!lkdY.yb^F/wKI#)"|<@1AWt~AYN'o#Բ}CcCrJPG(UP/i=m>(27F*}Nblnjfz:N gd1 wYץk(Z}P&Dvq1VS*Kt9%+V*KѕlP|'mX7yma3}ő˵׮ٕ=tT;|py* Rli5 $1fzL$R ']A]/56؃zmUt=fO#y+]vpUjbL0*14 wMܐ%/4s dG^Iw͸KN%Wť2CN ;[P5t?8]~W)FGꐭ6gi P]gN 5~'$|Nl}O+$Tޣk|K9?B=ra'ⳇnηX"⁊֔9+^\y=9YM?/XMeV߭j) ,jR-\0`Kl+aoĬb#jI&*2?bC ͟)U=x%N88VzOYUB“ywhե֞Egۖ~pWPWiѨuP9Ye VsRpU%GCJP/LʚWwKTI)b˥tZ5F~&{C!U}OP8^P砱d.qq`2Cf-Y5.t<`K4L)>N3f?ݨέu@s܋eGn)lu+CUu]7Bqb7*%WrQyuԐҊB~ 7S {Ш h+:fKȌ {>altU'k]Cj{ ׭lL}cBE"lOU]SEȬ]C{r'⛕lN>cؠ=b;R6&՛ 6AzN9 K&kQB&StgE6(*]ģq揎~Nbt{}v!20\ 奜dTvj_WtվbUS+>437eѦD A@5Qɬ5mplk{M'_-umv]NS$|&8 pZo,"\-YKL`* m6.N2 xGYJL IhEk. >#괃G #GjfH908g#/~) <T|W"TAnY$\,w?A \.`z`/Edm02\iLp0ctUSܾ¯z.`D\p"mRu x(MF-]u^g|N!qt_,1(Dj}.0LoǪrhڈ;v 5i{{SK\D4:*eLQhx=%9{w-6HoȖ#g )ԌL ᶧa%m=IL/y,MnםjaS䇫sUPv$}vg%°A \+mk~gŒaﱽwΠ?ҚpҚwX /@va=b4SZ3]rx8S/$KQd"s08l'YaD; hz n}y*P)_r ?~!cv$XCv`WRKkIõhWٷG~JheyNSL Teî6}Pq˦g%x#LcX>8'pF|:PwZD HL]t"$JW;.'Ӛa"a $n.>`h҉@]fk:e8g`F "Z@ _߮^U Ж3{~w?)4YhYR/KGWH^~=_dF6x7IxfGnen=7_x"0}ښz&gVŭj>,+mM /Lwku+@"؎d~n->j[nyo ʌYd]+WJ5ч͘d8RT ]9m h rP̆Eoɇjx>EIzFCEv e.R|F蕬#k,_ j.G#հr>N<}Z(ɰ~ËG_V Q8M"Ârj/y~ƛ>d|(.ed .&~1 ,ǶvSL(P瓃ymci -S)G4='/t TpyH- 'lMWPW6Hq"bs2LT V1NV4I9ckqWbU`7 'q/Q.U;~`ѓQoX8w{ࣼOE>na^@3[ `ρ}lXpXL7*V>^ .,<}LQBtGX(wȺCumO4! ];BG_R ќ}MD̔5ڄ/XMٌ d)-ӆxU?$ uIL"mfl u3"VޓHAڛiEfĉ؎%e'ATx55]l1{妙7I dxypi_g5ȉp& 'q_-t;\(vL@l%"qHޅPc>> O?G@"XAنscMOgNgͭ^Cp8+IqչxZ:ܸx=D$*# nL0Rm&G*y:oNh7K^I 4Ts+eT M0h`BZ(K>wceF AxL-QB;X3L'y7hgڋ]\@`Yf^lnQMjtbuP̑+ʳOFK xPR\ˢoH-ץJx3fNuFa_z/nۆǀ;HӌM[9psoȫ9!rT.5QK S>c\׀tFTdHLkSzHh`7pߤqޔ%q0 fīOv aB6oU@98ϝ?Cl`\קAJl~oQJ.R{86Aye"ڙ^4ފV~ڗ(}+B~.nv$C>xm*_,a8aM'2W[p*MJ‰!U(^%x]2Y}0ݼEN7+8K_|.`xq%)x~,DK)2/2+o0/k0>}DzxFDYr($*BhƊs<&th[2`_6:OtsUUXԾۥpS=c #YͿ's6֋okx/r$Iyn-UFIb<pd_Į kO"(rʯ$l))Fbx^ >҂wYV::\TnJE]}D>Cpq\[p]-YxTL$ 0[]loCFRR-*lԗlmh\g/?X㿃o1l4L1&=96D>gς粘S:GH/ӡI{QwmΙ:lX Aˡ%a?-L#)HrBېV}s_v@pDi#zAvgL{RGvYt h>rlug`Tx,v"+9@b'C'%ʐlQR0[ިQk&dm_id6UPF۳DR;L9=>!߃8rDl bm D˞@W&E?]ݭ0gQ\&X_$8h.$жyӂ~Љ9%DŞ "lm)#'jJ cWI[#4xm_ɝp.o||D4UL9f?-x%-U'apdȎ6tʎ]s [)3M)ؠ=.1or,W<_[͊<YWZΏȝn/). hラH.^Uaf_߾@_!UTzd5Lzh)wZ=E $ଫ۫Mwo5u^W3s~R>5G?C<uWX(NPL!](d(66 GkͲ2ӸH T}TDӺ*X3mq9ʹzwqLs"eF,y$(hy2M`]hƗiנT^*H<Ul(Dx {\ِXQsBc8EÕ-PͧmGudR'LWXX~I!E%H^4&CŪ6Zy~|B[e{9 u)gGYZ#g@#qe'?X&w^$z7Jj0WPMhl#gh%@8FUL~U:ODA鲯ӈ7oZ ^wS {[Q?cCMEɻI@ ,cngAI7hbA2~vsO 4ɩ@fueB 7W5C BE\(JdudY8HxI'|yb]4kcԧYfPgWp! y[Ҟ$"q|r%}gutsImOYڅ)9ń4y^eΤ5UW㴇pDd60abz fLR4gu˙'3Ti̯*b-jl8+x샴ɑQ`⓿eҴf״!5,` f8 ,42.dc1o*di ,Wv_ RoWOIʰ !u0ڢ)blml7!, _U+U>%5b和N~t&dYK++yЙ LmZm!}τrJ/2+;S̴z` # P #QgB1[eJ r wk*ydZMٿƯ{r4>vcM[G֊7,|b.TAݵV8>+[[/bL882/wDž }1g7, _2NGdc>^&f!La $gUq(X ֘)Weeln!Oze蠝6"kFJ+K*-&qAG vj5Lg磖>3oH,dT$˗zӘ6_?,Zc _.ˠ=^g=BOkl r#ۓ~&E Zrp8ŠLy2D_9+F\(9S| SIidf<YBryC* }lODX {P13_En/j4 JI|G+s!*EAӕNoD1i 0 av=} y>/5Ȟ߱ 3W~lY#wVߋ[<ɤn%RٜiS1}"{1borGv-Q_?o*a#lvH2Nߤ+ C[T%Pّ@P}N}ġں6S97on,}8l iS^^ν`alX^FE) Aԗ綱,y0)(w%[oR-LB M` taqu[ylѵ W H?m9*L 8_g|L'8Q^vKҌ@V]0:@ZVŧ.)Ӣ7W_a:eyw@2DIk^3a5ĵqvw+6 k oeѿpSx#,.MS7lh/4htľQ!KXo?14jjHO\pD*1UU$L;p8;K|g*چ)ӵn.k;"[?“ɤmdhZSsHhu1qټ+GRpJսQA:C(M"YqkAO/a7ҋvF?97iYW$s`B|JD%N^hq;OZnS BIIioꔜᐑ3{ d\No0 s\ :1|ɢdH ɅڥM5q f}4u$-xN5څkNh# lQh_8 8Y)Hd ۲%LW&pW/fYeߟqL,1)'TlaVhRYpV%_n|>3dh.6&ȖƋ{$Onv goߓ8!)xߗ 9ba@Fxf\£Eķ0.@U8L Ł:.MJdEU<*m&l⒑JDdtKgZ2iӷφBgp0XA ;^v#h rS`pe1u9e_3S$d[ ־b)tWgxQ([ѿNlӕ57+.':+}64x? |fM1ltjXH z%z=lTe1Tec=f,Tc2y&2sw=Byȅ [:U:,F"&UX;4%Ok;p9SJ_4v?0c'rgFJ$0/q줌fkle@ !rX/NJ5\Xc3h<65dfݑ2Ŕdh9ŪƢs3A`V{ng|JVө'cudxYry!eyGMBʁq0HDբϒ=&# uwWJSڍd= c}+FN Q2 Ih۲\O r`q?I|E=K{JJ3W`.|Qw L4I:,y+<7jN>6;NSd}-=B6JϙeÎQtka Vzdc&-cC0~JWS !-'fMU_vn/p@oRZ~5 bm % fmDbq|\s[iWә>5N'nGZ.fB6"`@GHL7ls &V0ukW;[!LI{(ϸVXwԱ^V+)@<#uTqg=Hd5c"XoZHwCn= .Cg ,х.?v,lUy]dg&qOrKOGw+ys1,RjV޿qjʞ3㌴f^%ϛkN33g#kڏ:{Kjpz(R_e A_',4Lz,p&\^0qV组_|- 3a;WwqK 7wg^ZA_du+h/^^FPyfqw5p!s'X_ `9UW*,D΍ D-gN)W~.^lڝÄn/WU):Jga!w*AuOS!Hj2y8`e#9`2{mL\@RXKS1'-N8liKшEݰ?MMB+<n2=8d?k0R%Ǎt~$Z1nCiZ?Sb]U]7Dx[=3Þ*|61Y]T!)o&|'BJ"u[rw4D{Su\еNj<| `y^U E^~;D|2}Vq1NB0m[jO وA:8AnizL[m}"?PrXF5U5 na#; cAehiټ_oE_2>Ůӟ}+rzY}si>;Bl7dJc}JZ#:MT-^C;SxFe!g& n7VdOl{'Ό2azhY('R )F53qq$ϺD0Nve? k *>O.mcS\~2*blS؈ ցǁ>sk#GZcs1-s+džLl7{Z ΃RJud}Rh!?}6.)}X4E|.C ̭92-OrJ!@t3H`^& k`0}n&~ x }k9peХ~5[ -'^jv\cm$bNA,39Љ/3Yh"xOB#yC > |HH m9D]bځer?ڋ>vM}&!^34B~!$BͫƉwDWtzS o qB^謗.d)OI#|{k^E͋DæKCn0C({kcYvjHK=J*aH}Dw PIG!@}y+Rs6j`zՓ~u5^?Onig#?P'p7GVE)C F'ըtv%ɅtTu* ӶZ2ބtF$HfǓ']v"zY\xK;@ A$VWB#]o¯/rӊ2"FR.`.Ic I([079vm&xcZ;Y~VL[^jDWDqE*|肁n$\G 9El7jTɋ D) BMdNJ|tuћi*Cl׽dXvy{nQZ|ӏ;Hd܀'OeSۆ6;dI`hjuL߻9**=m* 26ȥg˻57%dT{E7τ[d$cTjڇ "ޓ 85ɺ[{ۭ)u-lD!};K9 {SUĔ\GH,i)_mѿr`Mzw݈|0V!+(to.䕈rMcNXCƇ52geA #JK&n1 X=_QG,缎  Ď1 d;(0]%B~ $fgՎݶNOLjd?N^S"MOm/ ǁE?;L=ٕ{ָ^P(QdrB 1$Z]ׁ)O >1|7 -҇~ CRHnMZC0 SM)_JJk+I(^Ri݁UNTGaa.. r4~d b a$b >Ah%xmL ftI+rD>!dV=.9<՚An}8TFx!d˓,$:n"&~vNoU1dGS T}D^'8b.˘ Uma Zdҏdh3 +2<b ?bo\r.H?usxKɡ94K 2)]܀fpӰOaE.&d ۙwD ! .K'؆ 's6SL^ĨTjǂPνxƨ U|C{G5f&aXXS瓣ٌ<;~;p w#+b~ Ar<ILBP{Q3Kp!+i ħ36~%ifG!YMPs;W r`N''"Čpz$WpӰVg/]Yj"=7x&Iy bb~G dȵ~[6%ChӾ{*8N̠ 0 B@(eCRXM,ҭ0GR( È>ZSeDGŁ&cRxG j'(L=-鲷6 3:`4̦3\zaRw__ s3) 8<]Ϧ#BhgUN9,caf $C99^5)kI9&sChuHHF,/8(r?sŒH}!޷ G8 &mݾ:FZn>Kn6ptF]/ĩUr}DMrUnd(9\}uP "mhE=g߳/Oz@v$PP=ԓ>#FjNH#h83Dh&$Oצp8w ոby=Cj"NXIƢJ&_r)½rb!T_v_'nr=s {Cm.kEvY$|eZ̸-}R=vr[hȈ)9r@iFY 3ϥŻ/XE*4h|&6m|K w?p x묠5ܢv&*OcJ=16kp_>} K-uڀKMd؏9CXDg1OoA}Vݛ2pSǛZdMkIg7ٗFswPh\+<v<hnWZ9  pJN|HVf,5m%r푯B*swO'dV>Alx`xnlZ 0!\@d(_d-_+hᾷ^hq>dbh[_J2Q os+rjj(1EuR-z)fbWsZ8db8 [*m#:U1itPlЍZޙp޸eY3`h 1{ )ogCj2g|y9pJKj; \~Ls5>*Hh֙(BTJ8[E?O*װ: OgPj D;=9|q&u2(9s/e J -|g^F ,YXË`hy.rT'W m,jԒӋ[p R{!6L|eef;e5A`㈶*oLع(h(\D_竅0ktYQ@6q?%-ќlj wV_<^jIʠO] 2=BG3@| ?[N|0,k:22<1q={f7oOok@2=}@izrXQFx?Dze'5M`& %!uŤIvW\p<:᭭8^m+#W` pg8 αCҝ ~,Tqǐ)&_GS7-8cx7kֿ*_!#BoVO{FC\D/3֚laX+$'2lv "Trҝ#L"Yx{ dZZ_ɜ V|-Ko,}6kZ}y!wa/l13sza8ʓafy-ڪIc`2e\jZ7U"O[48[\<.rN ^k5%l88Xæ{r}ˡS&iHmJ>>P 9΂},*xNVw۵ ZOq5Z&S44܌ >~cb'5r (R J*eg;[׭.w'~%!b^&yuJLaX?5 yb1hZ]솫Ni+=٣o"撪J'/qo!c/A +fRRnBG: kYW-(ګ&Isqp~n%܂2{5Ƈa7I&TXG 9d$`Y>y1oD/ APwǣ`脵bniH؛Avgg&na v?8u@8>y0wډsIH4M#L8m 64) |yrIrH2o؂ a#QޕM*YEوdr= l buJ_{gVܻcLF5.}w2 _TY8 I<^*w+J"mi:fT<]5Nd^ַŐܜK]];p.|s\FP=ۉtz4UȲ~yubctXkD\t4cZ| ] tN|V%\; }7;aSq>)sN9d}*|ح039j~Q wyƈN` !!]0i"#+x(5,܋ש8QX~H<; 1hy[y<8|HXŏ~F Z]*!ȌJ 9S=_d6|Dv2nhȡ/mf ,ȳ)&9pEERe;tм^d$Gp˃֝f"6]iv)4w A.̝}{%5!S$[ߊymjjoC!gt*VxUR%"7{*޺u_rߡ}]cOfo@ߠæR$_t4'Ӽ}HCzd6 bn0%Y'j.ʂ0O@N4E7Y:!R[&'*Gژ{޴40=^KUX[>H4wmݸ'6h%1+e'y^ǯPv=YҥOZ[,((DBcgʀ27ZC.\T 5M1͞MP#2)vVZf!o7S>KBrj@,Y!%3ܓe͡'5ʦXqà}\ԅ m*tahlD,؟=/ pGVJ6ҽHbLQ\URkW-112d`{"/9 wN |0!Pmwi©<(Y@|rܥh5Ş:ʚ!#G+6d!eP[$@<8/A#e>HBRv3Lզ  zCaDRb2ءr$C)7,SI[ Ȼ<*;> p|o$o㛠?DJnO=Us2L ,5ǟ}؃H6z.$0w8m-c_2|y[a:R Ģ@+@clۼݙ`mAڇR [,߿O+zנreqk\vEA?t?#s-cz -T@ 1~Ge\6181DNI<<> b;* Z$#bc}p_e5PZSza4:GA1V̟>Οzz#UrCdA3M&o"{lɇ UcvZ]=pĸoa -BCg ΐD@7am-P܊ǤKƚb vsB fVﯗGkI /]N'FW' ^dLϖ! ohy4;`|SfZmgm`::3kHߏ'Pc\ B[RJv@Hޝ?mBvs^Wc/H+Y*?ܰ;| >"+1%7|ׄ^ KG=\PH;{&]RsڊJn$6݈>ZLV,>S.c&âzqu3^H@3F 8gx8-7Z )I}0ݺwx DZ)­j3sE< .]6,cn0!e^zE^:[Ͳ+0U(k|uYKZ_,7bAq5Tm6yg%0qP >ϟ=ͧVqՃt&EIFsP/`hgD@.)ES!RczMg6g$@^r;x:-gV*ЋW9, +NBo QdG~[f8FtZ pQ:wLnQVJhsVnqjϪlv#7F{AغC7>ՆK4H,(6}Fn6Tr(S$7Cp^2Å1"~REBƃFA3ͩ// oὈD2|۰_#[ Tݹ:`k6?0tw 鈦 Њu?jfclgE ª i $\RK_)-vB/x+Ơ.._(nnN;lir+ںSMAE2'_eӥd+Dy@(o$p?qsxk4]&=ۗlώɧMwqd$ NY͙8yg >B-%03@D 8&'?D$ jY Rs?$UhAԬaQ"[R[0e\kȒO(tDV NTPrI7C:O,/C+LGuqe2OLAFladӶõ$( 9%L+]i#/pQLX)s_vըFb=B;||ApIo%Ck98~heXvog:|W(~đY:z}ayx\h7mLУ4 -/bu>qt?2YʮsW߫5omwNɽ8b/w_TU)ZE2\7`JY\Z_uo0tٳ0ĈY#|*=Q2 uI]i?z?8 Z:Nݳuл5tYL.B-u?zslgdրᶓ{>.᱃YGɱ1}HTimaqIxi_ [5/ӄ4m""jIa0Ԋ=J~q 7[ Ds7%o}U~To"P.o[$ M^>8 Ie%w"lY~Jӫ~p8! df(7:KD߲Ig7{b?o%*ZՀaB+Z=x[Gq-Iq8>ss)quGvok>UQgw%_p*Zi-r{v Շ"f&hD%߭4]뉡O$919$oݚֽC`FV&~^+hG& ݎh^7.3zn_Yaa9N}j N5oTP/Nzln6+J2'͂UףٺBOrjѱNy鎤=P\=y$tZg+ڽ6`F׀w7P,.tGWȲndqp cmոODA -aJH>lT@Λ挧jF=٘c@eW`) LG[)~nΧ{Dr'a,(sЧLf Cʸ@n1GǜXѰRнYF \!0PƇ(TƱo52ƒvo:@G[aC4x-ۚ&:c$= AEI4D "9ЉK? Gqᨬ5!-2AzzRT:5r:W)4xϯ.rIo2ېbj*Y^b~ i^x!uG 0C'mdgjNuXb4neUXV_dF 8\4O$Z|OAZT 0ΔCٻu.yVBL`2 օS!3m6&kx@H {(FyY*3)oxyRn۴}HR2l_wh6L#4i1zrJI;L!5|h nx]|7`=KgPE5|ö%r8cExg[$u61gw4_^y C[XW@>w#Q|֙ݹ÷l:dEsQxTcjH_ޘmͪ,H]ej7pNTƤK̜'IkE[<|WG nWtSnf.l(v1:#^4.kO3P.2EftRihFFv wƈqPIj$^X>+cߝ \Zt,vYWl*]V b.x(^Sϙ46>D2q>wM!ǟe,0[txg75UlBLٕ *)9/Aae#% WT'@ӛ6A=㒘;lC&ܘ| EConoٞDoLүE}/Lc5/T;\M14"YuT\W|2PFe]i{)m WBICCB5hE~+xw啩j3y T."yo9j!;ȋ:ўG6sP-SDPhhӻP9:X{/|蠻zA8BʬYkM=C[~b}ˑxITTE*-v=+PoJ=usEZ+dE@PMYөV1z4y-DgeRzO FFpRyw)ICJcI6-2%kנ OQ+;GS\7|sO#T^,z %2l耬DOtus!3޸*R@_D~~rD-lѫ.dX4rϹ}߽,+N[zI.]7L5= ̙q~0s)P4 R!) }G=c0("FȰ*J*~5)؈ WFӐ8d(__@ذҘ%t"SNcuadc#iV;\h hqlMiC}"GW$ۣ9t68.0i9ҟ9.pFqXTb ] LD@vC ?`8̸,5N-}2# wm=|*.l4y)D*AF +S5",~, "JGcH;!KuIڢ ߎNGi8lU/ֳ>fPO&վV7;*]H#Hצ2yqo %HaȻtҊhmLՂnI3*uu~" su<ׅ(JKpjMY~/`xekjrI?!B(Fr͏(uڑOG)ɰ?*] 9(43ՀE#~-*c9)p13(znEK(aAbP|-2;|^z=%g{GV ֚ȜH P^2R Q}ReH1i+}p%#~+@Q6 l@KG~>ŏv*,9{N)P#_OS %tQ Q{:?w$ ;sGmfe )?lL' 6k9DUJzS-&jC LaSI5zFw­tQ%+&.͡n,H9J QMvM;>߼'> zolCܝFKovcx)v Lf}I-j^ekSf+c!:oMod/;Q.P=ԥȀ|Oe,U ™*I];cqH>8@q6zp X$< :kXBS6C,.Ja؝S"kDy[l]TtxJ=QA=;-ӖsF6AM#rb䘢mZYk $G'?\i {YXhlگ&t)~Jfٳ"7i<Ջ" *elXgkPVd5^1auwܜxp*7!P{ILKi70[ZBV߄qT8_ʨOD6iMES/uܯC GjB.ܔ`k6hAS{N+KJ i}S&̭0)ZJd= @)D :{EϚBٗ2$!K8v D:ȬMd4sׯ8TU?:egoȂ%pqϑ/ 7$2,Qޱ,61OP$un%^.~tܔyrn 0l|*!-^HIMń1=;PtZ/8*uX.xDxUdP?r^23q c>ЩIeT :qn'#985 HB,ظ u7GOwb ,m60Qy~(υB昚eyaI7[3 g[yD}8,{ YrA+[hHu"ɠF^>UV<{l(2 }IgR<{Ȃcɣ>Ah8;;BSswt \*An a z\ٝn[cu]6(]0Mz}<.`p!bs>JJ%3 ^"k>^vcN vlII6Fjhnc=ú{٬XT QkXM݋tfs뵂H4ɄL sZu}33Z"G-H6rA!?`ާaIΉNM;a@7&;;59ֽQoӖsBn=p8Xwe\S,D蓢[[֖A1e`>Hw%E[YҞf{[^dݞDKnzԸy5HF0sBKڤJndZ'jaӑpZU@s'cGj:XsZ6 &q9+WA՟,jjܟWU_ $-kaٞ~ͺJԒ\;^NqS257w$8, W}KY]#o JIL>n0}BAR YŤ/N~YY0RxmvvN.'0%*1ÛN&Z( _7q_1( túh3wdsL*hv̈́( p@: T8pP& 3 ё?xI>[J-3Ea)tjsX{8ys{>{9s0q] 1_ʥBT>;Ƨ,,\{{^4ihյmhEP; =<J~-1T dY4+"~@u^y6˝ӷD/+:JNfg SIPPzurKJK~1쌨&CoNO_*mm'C߬b0afK.|ƨ7nXNMuT"j2}rC!}!ua;xKI~!./@Cp S);{c(D7B=mibʈ5 ޶U6D<]jtgҿ2i0d~^%ABT W'l7,s\eTqd eVǁHeD=&&VVw]:ğ4hwC S45bľ@es2"!ME , e<<m!%D)4skJ F90 ~+ɞ_ Y {*Κ`e=s|b{ aIutxg*H|Y.&V2$&udvQfbo8d%c{;1rELhdepvLx[<!!Ca)#CڒE#gS|k|ya!19xm{˘BunAӆN9_mGӁzaoD]-R I+$oh_?l=NGka#cU9-6e=6 unY heN_ NN^X9JTޫ RǶVPJջo:hss>Q`UX e.& -F!ieoa.A-)27V3/1?ܪ%E,Ǿh~ XCkRuέz#b? P)7ߍo@ Wj~!v g8Fv7ʡ(9 O[2*)"wP%#E!!"gC*GO~N@l| ;M9gP!O+>e%pSUMǨ|@]"w&v9=-Vn!k\PĹ:ss%8zhVX[Dc%,kVrItq2vD! P6CŸ@r/ YiӚ]%gQ]GคD]4~=|D͆1L0Qz`(21$/K*Lljmdn7T2t;2\v"IPHȥ dl)Hc̑SOQ koK "^z9| I dũg3@z?I kt<_H$L8rEn}הkAyV&LCbR*Pɦ˗"SQxq-k>tH1D~nf8Q*sGtɜu[t]U(Z%&FQ W:|`(W Bkd9Vnq8ɦ|a 8My|5^Me DlK%> DŢ[GY[g]_3*krE?dS. uN&j,p_G(7+nĸ[߄ծS=`ȯ޷We(*oVx^2soV~RI >8'!) QN3pE酼x;ÎѠL(:?KBvAj]號=^^۫4ܦŗluCJiOd;>,zj0wD ^2-6~Pc0V GDZE74̈́K2x\\N?]×aFx`Ð@(xʻ,jKDpOݡ|g8Y$tj~zH.X`ޡJpj6f(nd[IRE`{!>?hcbݓzmTeJ۴WVqb'"WrAAA#Gs.mK$u֮j)_'{nݾ')N/CJĆ!^\@",ROTXrD geKiPK`(hiݷw򠬦=t53PoMhuv 㥭םVdž~C &h Z~rQ(=kʺdsVu'[rI`h" </I _Jdq<4 -H`/UKa|[#D+HGMOw!t| B~(57}`hy;d_:L;KjqX.O,4yK'R\qɀSc]YCgB}xlϞZqھLlytwu2Cn0ao3߅:ѽ |IMO?'Hi_-tj\B*#9@&ctjT/4WTt`cQՈ$ҚM]Y[ K)ׁ,_x dbynk5Ա#՜emǜLbŸu ]";8/l'2hw%/ rM*ZTF1@ųhx>=+,F5= 8#oϿdN #Z1N fx[9L_ z5Q5oR\B6-.9~m_-qp{1oϫ=(k76z38&[ݣh.X_O^ھ%䂾D]'߆2,*@ QUR4p?*XC/ߵAs>Jh!돷mc1rǰxpt1)RziҚ[/tI^qjȢ^T:f+QM͒ ?DZqw(!{ &wfr>6cDCP,eF[c ZꚊ5L|3Pk ]g@uuCAߤ.J@ܧx]rBX"֪@1>K{7h/wjQ% Rc@Ni0Z#L{̹Ձ7R[؉ˈX9lq[2_ Ǚ` 3Q6dvC=镓ڦURx[sﭩ@` tka9BhMŘ33^"IT ])ۍ:\FH>ΞՖz|z_̪ D U$⦂HU^^f'(;0Z5.WSJ C٧aYO&WWkn<3 $;POWA O/JKGU=Ⱥ2TkٹETa&b+3[πso/k?Ux c a(RG ҽ@w7l{g"WBξf2c s6 xv: #uEn5Pu0_e,'48ԆJX* q[^m(^[K;xzw=2 ptlF7AQBUY!2%3F7|Khj݄ivr$Ah#u,)%)bS=Xns#8ۀb#JZ)w̋aE޼f> stream xlzSfͶmٶ+۶m۶m۶mruVm}q"n1#92V&=#7@E\UHCF&lfj`/jj 039@`"^VJFVvVu[w+K??E*ffWK3@DAQKJ^@)!07s6(ZdL]̨8{Sqr7{w3g;;TUb" "#{S?.L\]-,[,z&&+_Iٛ;6usoB.P!R `jlVD 5/B1-?!+q+O3SE+vuv3OX?{#gfjfr4gWMmT%ig7q0V4' |9#Wg+O#F_-vcfdб3XX\~E&33O3UP*jp9C5U&?7:VGW88pA|{RmF fp'3Dz8e$JEoM`v&`7QwY39N|LCH;kKTz(pf4uH a !{p7dUAGڅFȧx,n:ੴ0UmK5):]5[ʲHW4.m`?1D x`,5E%FrvqӇ~Hw[R>e`ō-# 4K ɞf[gؼ`gg!2WUM"zý3:EE?D.&:#s: 1PHr#7s@ gbzz1c>sl~GeeXmSn v/ Sam`ADȧMV g *JnuLu{u cŷ+L}BWWnA7 j22e4.V8 ,h:8E J^s5miw&)͌m!BB8d͐p<4nI*bO9w7|V9hA(٠[`P•w5/+Cx'WuD I"/WCTanlU,^;g|.ToK/@MkpuЩrv(^a'>YMfbOx_4g7lgcl={\F*1] R<ܹŝ+̛ƽ~Kv&\~nbnܵzAP[}pF)jd05,&N^7KMƠ:J{yW/D(tI%,5 jȞ SU` 7ƀ+lS.3X8h4e ~C򮿁OQ mߞJTb]41fկ#')AXO 9lWcR]HۼP=Y.&F{oKFq`pa j5>M?%32 E|W7a.O[EM_Ծ&S989L$\/Lݱ($.HNCx4MLsޘtEOVٔmW7y.9v6r?hMT\Yt%(ff^Z '-˿&t*MWcsLiP6ry=SQj(;rfz'b H*J,lea3AN쟌wj᷶1QF*X [aH Z4z^16@mf>S.o =(?Q*o&5㠏yxEk_𪾧Csk.9L|OғE^U(N+8 ;/cٙS8#]EV!ad\u$)DΓHcA6\+ƠhZYtPx&+F82I Ф{Zk;ɢe-M:?PmKZ˫3H jg=lgf!-4iIhv %Z~jK w{i $tNt"xHts4s3AMJanQ7dDdyŧ(? V=\N-ؗ(J %Tu5dV#"0 a7jݍ_1nJ_ vrO1%z6rFL!v"XiYce};o{e uN# ]Ao4.>dʞ;FAHEuѯwQԤdbL$#X4Y6v՘ᡄImq o΋=W<܇>й9"'$>Ǔ9>G%1>L#Qt\x5CrSO @ѹⰞ;454Xۘb koʻri/g^qT?߳N5Bp@s9cD֖j 齁?0 k&?G$2^xKYq݌ۈIªړZ毜#XiǨ$) ˫qc>RWb„t@pA4"ÏҾXw/CzXdV9,i}VvQzGF W*9(]}5YR`byxu jeA1ecک3pV¬=K t@5e&!b=!-c~𙛺M)C7Re:eHv;> [vc-aWE[\fyR+V P)eV" T!_K`֑d#$ҐXK:T\)3VlmҖcj4l{M- T%?&W0N JUM  ԟQ5l?5) e^*)ڎ2b J EB*54b-Bs"{x3~}H䨘2n)A$#/O//$"Yccԛ^֎m"1@&[,|w@'vecPj׊"K=RVi-%eٖO^MRk1B sOT_ܑa {f)@ yS~Z'z(""(*̻;ד# 4h1rƲk@jV~ȴڧݚ}w gO@4e<ܶ Pk` c\DγhoFJ Nk!QNs-mfDB 㨣'cm6$t4߳v qĔ7 OMbC*zȢ_(f[)K 'YK`t-hG!/Z/|xNKn^uW3_OP>OXO,<)Ljb~BҊ =9-NoÉ;2€fNKũ៬gf;\>&qt{xsdSV~\k*L};+k;lm,eZU,f_'_T>ab`X(TE  'aZSҳ](>[UE}j r.gox[%jF{4ɊTh;/OX_6C6 k6k9lvNu4#SV6od2G#(1ʠ"iɄO&`U<7(,xֳ_.m]PW9f PE7 1N$!CjJATίDc1O~A5}j-׋՘4TB!m3:7a't!BS) Fv@ͨz!ǿQ/10rp~w)okI=[g Ӂ(nJ/<]L|Pƛ若]c3۾=YU5Y-F(6Tyr[x$5y TQ9l1Ȫg2nqVOWcro2Ҡඖ{,22`VqUTpLSEP-燤tC|2Sr"40{}]q7lNХo,$VZ^6X9a2BC~A`\Mq.gB t6i82htվOl?GiEՆ7ھNC\-xww[u`$s e}2=S3PAuc[y.I |. 5?Њ[ͭmp nɝLވNYpjlˑuXI A[~!(0XB'W' lrW/Wץqڦ1d %(d@mP`1PL[u>/ȩ5n-R΁d0 SlyK`3O+蒣T e-]jJ*b^ y*qܮۏl(9l2_[ Od{cyGz]NRJ(0&LD48H5z҈]^T!WuAܠ$鴜B5li;=Ԃ9}̞hTgpX޷@wjQ-AÆGNЄ`7t,;:z*ҷNKnFA,I!~R?vY؆&RI`G%3ƶ`X,BIBD^|ZތW:״9 SF6d,UQ.l@`ű<I{36b?Hzjt%G523 Q+e jH} 3ztInȅKʃ˭ն2h5݈iPȈF& qu0slm2:}H-p6kC~Zz~~؈ $PԽzăKw^[pN)ܰ9!F8 I [fQrTBw񰣂܍{)'ȇ)a퇞3.;ʐAOrUBdNCwud3= :EH>\\7AvHIQ6'd%pԷ|ь~JʱFޓM6F;ېvJa+]- 08!pRr7*|@DWd?vqulͮYiIN6G!ؿDIW>\@!5"̪V@?JOYDR+=ĹWA$F9_g/1F&br_ J3$;&imMۆ$m"CW l<ƞI?h s8$9{'j"R^Xn% cf[rO;ǰ'gk/U1F-bRWmkܢ4Lj1ˆbmhBi6'v7$ފ&_QOJ;z7H$9Z/n٥4R[XV@D:-~Q46f,Y6hv1\{bcTNBd$&@1 W<3ZB#E?rafb"u4$ >y)|XV%ʲnz`4* lWe~}l bCڭd=izj+&?ƒ 24GEP>8]=W}O ţTѥBy5e龻vcHp xʎF̜Gv&7~B x&$giVJ\Q9w-z5z_ev@wyE^=nY4˫I`H6t&iʗ;e2#{ϒ>Lΰ ڧVgD<cƇVE oi2Y U7[M2_ {,WcGøx%K*,%u$!2('x7~yeLnz¿2g (T$ʩDAC<-&3UDL[UH !Q 6_7UssbRt]kV=u[%}5ew}p`W5k"Fot/CP `rdtl !!PBDUs9$1PB,`I_jhwD)BC@ ӱ^)u3=,A&x6y<,RZ883Jj4S8vvv mPv+zdT<D*Eͷ>0]yMuoӢ.M<)}@K%D@6[G--eꃔ|p %aFK ;>*z&\; W4D4tvC{qia$.+ƭ5q]CfUD>n6XDe.ǧ\L!{<ǜ+@cO1u ˖Հfɏ[ĦFYB{:e*1)OVsUѲjsLJ؋ǥdr'K#O eQDgm(c3~h1гxѻ|];o?1k^M$l{<"Y:'3_Lӆ ]~g(#D wB\]tZ%1iL|8f.)(pѸ{/sJ󦅳khfY0m5hmiv腌} z&TsGW 'a ANGLgjSz!ju+z [' k&]{١/HtQN4OѰɅs~=f:m?sHGm+W/}0Ʊ.R\A[,Ug{ G")i+5T$0oq͜-ĤP|V8fjrvQN+{8LP*."Xkcӄq YĀEsG LCķc|$cXNjbס8AIj2=h:R:$j4Uk}}lZmi8$;Ƒ4,~X.DF_l6>n6K`GLWtLI(4Vf:~N(qƷnwTQ   NSBf.|uaV<,$f!T=p%XLޖS4>:ڙLּ~t#Gש`vfT.91<\QO\DʚN/Ե)!32qg0sS0N$[&l2}SxEQ2qX=CgD; z:Qek-M?t7; `z8G.sV|nWO;$]zԏ͢Klϖ1"\)FKM%x9${Qh,#[ɴ7 ^N4+˳#*<{=?Z$f\wd@˭3ȸ} Y#T޿?`+\۶l>!$"#I&3͖V5Iy `^@X?\.N34i;L4ryug%㣜p[+mMc>^ |O_h #{ȶkDAa4 .\g lx :~7-r50rsM=*18K7At#[&2){^DX`@v);uTS)c G/|;GMT0Iۿ!K*OU 0=۷2ǰ97녭 1@I{ɤ.Q]nȲDASwq.7B@`V*U)s-~ޑC0zi^ +\~Hh,ZsUdWa~,"ߗ{g,g* = *W־Myqe 27vNM1{;ܙ{و EcTJ֝ SIWpdE 26b6> 79TOja 9jMЄa#f`ؼ]2kn̟ȒPVh%<8l6 F69;G4:HSIYibFJ9`Jҍތ\\{EbN#%W2U6x9F6щ_<&jO[ !6 AIJCv6U٩WL;m!d)(ne)LxH}2"PD1h ИTvCnpiw0 tMҎ1]<?ԙ ?h 0"lG[CM[&EOobmW*rOO.0AR82-* Cu/sʯ{$Cl ;f|zC.BH1v7&ӈՔ8׀įgw, B 3 }i_B{CSmi< r hLyXY1HмM &)7_영 znksb^#3PؘT]-q8ǨFFu~HEo/ 5@{!E]&]`O:7ܦ5{9Yj-F?zBn2u艜l Rպi՜-6H0ٯ oVMݥzCU !V=[IE?Q,MۺD+]ru{j$EKiZښ5ю^?_0Y_]ܨK\ҧP;ϜQDh'1Q_iUpB b> hJp(2b֖F wgl~:%B\b['u8렉v] G6Kß"q*?ʀ Wx^ZLdg $ݙı9?dtY.SƏƑGO%sJzXSbnZVB.ɏfE18KT~tk0o@*_uddH8n"~5Vj`8XԌ9GebC6߹oc=kBj괣>,6޸M-{`/-Jt(7*´#Z}vWG7ZXMޞ2Fj@$0N,WKWO޶/@{+ᙨf0!t*tWXe<7ða[c'dmNQ9CWeU2)f#Ԛ8bRO9q ;_QWs E(n&*y Hqgk7Yia "ƖuqYqJ/,[+O(?3Ni+α h\f''#=D(OXj|6W@w\6!c# E rvY;!\~2 N,)Yq@L;ؗ g;H$?:8{Nvl< :)v#rEBA-mݛ0[y4vL~ !Ph5ׄ^dܳ 5%.NRt6U<ϯă[4ĹcdTrѢYֳҦ<Ep:S|h+Lޗx,3f,l>wq$.z*/tcTܘcZoP4qFzLWa[{+GaB1#(Th 1`!h$)y7D`q*E9ZBr&ξ*ӣDZx-*jN~I*TIeoH-mO3lpi3W+*yiqR,OtE]tA=k}zK]@.KL)u0yk:ddأQjx-S (|]BzÝ K҃ryrD F%HfEWvX+8G? }DGj8Pi(2wN>ּoP)R1 La^A$w!·X, ; 9Xgg͈HĂ۷[Ŭ*҇p25ra[ePKM)u\:(j8X io9,,35405ks Oo*ȱi> [K/ Y04QlXTӝI 4 ir'lQ}yG(R/45}0>s.Fy6C9@G`cSQRBUR~; ]n60(c w]ؖ(}yNu\J_; Q$=A* VN\alJX~<)vb3&|E/Q4!BiZSI)Ah>~GRhLq9a4Xgh Tdy_Zn/^v^nC6"e/- |sCMmiҀB W`1w߻#i)Mm}j%F$H6W޼7 zQG5fA NKg"ZC3\[K+uޝp=L91Hj"h_E D3 .g7CMwf&5+rO)WD}?LĊm6|5 "9Nh+]NBc^+NU7f;w(0 R$d}Zq<M#SΜq~ac BE6w8/w Ļ_%ݞRB,M,չYNj!:+S 7?.],DzXk8R^.d͗gO,M!V0ev6g9oADpZemoM-.xKF6$Qwi w*F"^l 3C}wQ/=XUrEmvaW.z{m+C, Kޡԭ0ZY}Ye?Y:=O}0YYۖmd#"nwL_,?urXPMX3H'XTqeK$zYPe$&tR:|x@c|4PlZ ħ\zg]´2FP^zY] Q%S6SM7i%m>G<u>eÛ d=sx14J&;Ij 5K C,[3/Xh$S ~t> scA )Gn}ቯH2!\wa9hw Tq@+XEіQfo8co^g8JC ē-LfT1w6N "wAHV~D\/0 @UFĻ}C<~ Y VbCDY{/htFCPP#DtE*JFcigl9>>yM>u`W؈{}5QaLmH"v7 ٟF  |DNk|)6S} ;m'j0E<+mXo P"D'oCp? Yt'Hbζ{g?]Ӯ( dm۶m۶um۶m۶m6fi*YYTv^ҥpȈ\<zqWomΒh{?=mQ3z3/9(|m 3jfqi`"1IAfTK  iP!Xh%5Qekk)-o3﬜pDGug*vG#d(?]B,}jhLj Ԃ4G:v}c\Τ!J_=Ci욘&3qϢi6IO >֬uuKܺ۝j(fR`8b/r2ŒZ*}2&cDjl+-xb:1FmsCeG\h#qj@_qӢ+Xw'4Wvd" BqJ,됙&54~#Zobkkw4#$Bkycc58ާDk!PmqWbF/.utq`}>졨+ˎn~8xVc *5C.{q[!I6=S}T/AF";*ʳK&'=~T-XV( 5a'pN V bܷMƒBMs< !F^ޙ>S+r߯6*Vwoђ%-+xa='C\ 1ƥgJ,@W3q`֟NAM UɢW&~I !MOeQU"X$-OwrҎX9ۏj9@6-=vZU9VRIŀTDpδ TrP[PrBd}!}պV4B4S~d&hQK a]&f&1s2Վ~ ͢b! ٠jI{EV8/ 8%$B~&Ϻ"S 9/CdZzF#E;f5π^G;$D":`g]E&-^7!nO9p]~if(^3y=jV &X2vH2W w{4 .vShXw X!գ!!e9ZNyo$2 c:E0‘ȩ>ޛ}; 0,t"e-î 2 Db+[ 3͟ܭR;mġZҤZehRL&!#J*Kd՟헀$)UwPrt(+/uﴡ7@GzK( BKYqY#)\7>ixcGfC}T8B)8LYT,5#X5?Oz2Μ9( S[f(BC79W`Fy2jfzʹtZfvPAfy$lpyn^\ u E+ khZd\V.z5b+k$1,"15eFo g5i}0`X+Z%$pm fm-͌/lja BlG~[}21%끾]03 Z{Bɩ Y禰~WMwX'ٰo쇯; vw] |AY&JTv]`ms&:SY߻UE hErgE< Ⱦ *Xńvtm_9mJAPئAl*S vCȫk@G9b? O ˞K{UT"hׇx$Dݥ$Kco:R(4x=!+"1\1*: ٽLA u6 r+./Uu[6/gc-8UM!te[]K 4cgdZd]K Ƽ-ϲ5p@|xh>(*35KSP[>)y|@K%^71.g3EFvţ- 1'IՄ{h_pbh PXeWk(KU{籆P짡kˡzE HM9t0_x5/e]:sLv\z?t5fҹ:D &@8 6(It2f2l3I!jd gIG&(+j<D~0JA,Y' tvqS26XZ%lfGӲ.5>%[}rcRmTcH0 }ACZύs.Aqk@LQwopnU*l@w)&ΜsK^FeN#,{ *cm@k1upW4;æ'!+Ub(Zb5?݂(h5250V <@2]z}>*&{%^=wjĔZy<ΕTg~|ʄY:,#ΑfҎS:|k2O Z Jۢ<4$71ΫA{Z `PgV9qUW!Vy`Pel.ήYyv窤2.gފe{VP [a*J,[5eT-fd6{AnNO_c8B=r;^IM#=_8'"?}|"9>{} tGHˆ6\Z- h~@H>g)W>Sv~ ?ϒ}kW1!o%A[-u c+D,H&IкsY9&d*Rh@Z8Mx!^!IBV4l\na)~6)Fzar"";Njbi fA$}|h7J) (Uơ-Wmc& CFD,ss{m.A1aCS~BN:DoWF7v= \-;33L[|F?_[9gUnG!Ϥ3 /2 ]a0ٰN u}h=w4(knHwLoAg'M_ׂN?ݻ$AԖJnSqovĐh'*0^{&-U]'Si-sjkԺJˑe\w8r,Vk^hJz@qێ A0Sʣg6oHAj2FHXcK0[%l,[VH6gcx<C773tYdo9I~7_oy„pu-TQH9(YqA\*%E``$]0.Dt{;,yV:a+\~ CRH k^lA07(1!:Dd[]J\]ߟaRCI62uE,*»zIL_ZAi+ex*6?x`E}!g5^%e%Sa&-|9͒1;T}23YLx#>}ѓ]yKr!R3j"앳%V3:HZ g\|Á?)PP2$n沆J^*Ņl=mr$Or$e !' jE"aSbW>NcWv`. <&v?fA l40\(Xe;wiFkeC"D`;*f;Ez vOHEݶ02dX*rJ{P-1.UNVLC{͖iG nHEѳkٻIݛ$v]KSAnq?aE632 ~sa8\.3M2Xlz0zXSF7'0u@w7{-#6SS> ;pA"W[R.X⽰.MT;*usn!tnSPcKrI Y[B9sҜ+mD-pػ5~b!8;oq O4^R_s1]M]׃Du\">a tVtC)j;CV`ze`'SCT|V`qa??nd`y)w\{V;}u˝M_W:UO_z}$'{,/mh@kX,r+Xێ|S;p@VYLZ>侩Jnv0ΌBP$}.MGA&i^-B˟ 㕭Z_&AZr9#%\ QɐMPF$gZk-"l{"< R;è=<XVJ, ={_RS XnW&qy٩+D& nP>mn3DldǙZ[PXɌteSc5ɛ-}l$ XnΑ'YI]|9:иhG*38D9! HxuBiZ\(AU<?T%ؿ}C04p[8JH]|_p`)zYĢ-6S3'HWm/&: 0#1BXY٠%#a9= 95e{Bkආ{f;=7Cg( gUMVNSY}v;Lײu~?{!TKc{J S&'_qvG{ݡA,PU}>.|j7M^*dj?Сe5S,JEX&qzN`ReE)88ҬLo/&\aw84y blA3iڼ6TnL؞,Wd-nz hG4sf_̭}e8 5B ߼xCK Q_۪5f.TMELL5C[GQfީke縜j:ep5;Q}3ķ O^V.ͱShm-c+ %7I"]0)G~ ⸇)ݚo 釒q~~m-eQW3ɸ8qڱ`.oRڰe @-V;c7ka${ r?t]|vXY]NU[GQBo\:}-*T0}n%6=@2%B}0vzHh*Ve]| v4j:mJ4PԶnx}܃ZeuxY9Oa5|61DEf:6q?kijíImB^==qO& ,&IcHn$N18=1LECjǥ5"ާ~<7rlݜmA;cd0Ӆ@:X^\m)Uf(y[i <8JxqUY*Lr^RwͲqюNLjSh#.])L/L5@']!M2dWs։6KԤLjM䕋gl~oܮ&mlR+hwLPf'կ3FxWJT-ڨ$^rʘ }Y{M\Gy5S}ЋZ,ф(Bbe^_Kee߅ǃ p%DU{(LrJ~7_^ iS8UtJvt%B(;H[rCqluTK8_.­`+tXQBP}L`S KV(,xr[ >XMR{ 'EdgdF0tVkwkUU8Ea#e۩Zm e, DchxŽV/ukEHbkW:{ ;KCgQ.w+eQr#ob63G23*s ii܅xM6K>ռFKj@$Pd툖* 'W8_b`RuG: b8 A41,9r_ESqZٻEoL.[mfoBS:N-3C_٪*-LS :$ 3>7+o~*ipK!r2gSf?!dC t xRzc`5U`Bdb@K1> "e8ϋX],^EL;~bnBq8D-n-2&$ TU\:)T@8L{|WByie (wMn]a;IY_oh5^ЅE{DQP`2s\E.0jQ1cLe7'PkzzO^Ǯtq+b ʣ&v@X̦6Ȫqԕ3K _@Jz|֮>dᦱhֽJ8-MI VxFX˾ia@,۟^\ebDβxeծlXZz99޴>eaf QBτm v푚I3Lm1<yP$5-O )wIFL#{ILZsw̯<幢+OQqNUl# EBM^1zkhMݙ qAjk[OyhPq֬UVGs1RҥR`=5W1#z<>xϛ5]-z16t|S3$GI^" o)ya^\@_r ڬ1,X6ePkGs HG$-CQԝ@!x$CIaz)Ys)L>/RkpsL`-掀6%VoWhMT^e<-ڲ8i0|uxɟtiI¯#0}y笈_ QHuVv|S6Fjn^j Iw 63:Fp t%n s::(>@1\Q=?l;>M`W0ߧ(Lϳ[f@ԐZ٭.cwx`/?RJ:@c t+{׎BZ5RPR'`.o=Ḙ>*R'FD*^H FC2~,z$/| {u3^30%R,8>zzy8,Wqlk2t}}tp...QV\Zҋk0<4X6tv_N7GxiB;+eSv4;X|Ӎ5S@3x |{n)MηHa6Yfpi ulqku%@73WDžC H{2̏gewHae| ^)tF{NG*ˋ$ Y##e$fIuRlD=49 T _XGZ}'jK~s% LU=FBnal`B{_0s"֚0&ߍ @d7%Azʰi+*_/%]+Ρ.j䳃Fԇy(9S+RcVF\OdѢTxׄp;P Q+>k04ls(Rj—1ɢg}ä ?F?Τ( }tU"v[j*u|uyX4aBzoցf(N"TCmI8e=mWWǦg{2h FM壘u*1snɱ@v%t1Ǐ ovq,~&O a Əm ڻHIIEԫ<6m8@#`$"}%!A f6)G>NpP^[.Do\CxC%+Zدe&!A<>|k*PHf&6]#"jUPBߠN+X6mY+)g6* N4,)XTF{PRw?;b;? ,#sW3ÒT>0}}f^Zu F2ojQbu35 WvHD՛½Ӹ!j}DJ_|$?YlsRe Y[l{XQ)0f37*> M(",; r8 wrkK_mhG[fTHrDHoZYϒ>n huǠfG/KQ0qi[kC%*{*vs.HZ7"aIj#$@;I68Zźϸ頕%DS YY'p̓%c*֙= Ѐ @ΑnM'5 DSaRևl)\/{/ĺ̾C}[-ٍ:u>Sxl{3>Nb5ˠB.Re[r-wl ,Xf^.'9YNRzudļPr'H=)4Sm;ZB dǿ6>q;k`,Ar:RYi&52VuT SJGx[|C5.dLqο}B뀚L C?@*sXýu} ._}# b+ ,RTyg*KtfI!剜%#6J` b^hAlAɗ&t™|UlO o 1޶z[,|Ygj2Ϳ_͜U^nWtÞ?.2.;Hʭc璙K#"iYJ+f;ऊtٵBuiN (o(yN[}Jd̴]1˞cl+ęaF']PIWMY =g(=K6vÍeZlEUjKGOcvJ< #JY$y[ET5+JQ% Xz'z! oejz%PXWA,O2d*X—in"Zҏk @?3j7\3޳wEK߬Jg "bZwzkNȚ ~,s0"j,hs($dJlM#&4z[2،>'m`2p W. Uyբ'3g"2<|kRpv4#Q@4[XDɒ_ ctBnr;%/ՂZq&3ZP \1cB~3Ǟ8Z@ fh;< ~ 39O\-ݤ[GG@)h]6,"l;zn[=LTU@>`MƢvQ;KPwZn`4Dzeۗro+ #&?u5؉m\/_lZao<}ޢ41Nqk?/4Pz"Kkd.$Iה||O]#Rlމh]3gK.|"Do]vM3ݬ]N|5y]?W0wJ ''e9$!c7䒽kKZM8}[[GТO)ATZfzTO$O5:mSjXttKN:Aq+RwOJa$[VfǏ@~|j@׸ӓ,8%`cO&ֺWQPlF*5D&hcuf&iMxÁp='mkQg Ge]kZP|: vKYu5[Ƙ47P-- 07[fbaa:OIl*ʷ endstream endobj 1486 0 obj << /Length1 725 /Length2 25723 /Length3 0 /Length 26223 /Filter /FlateDecode >> stream xlzcp.m{Ƕmضm'Ol۶m۶mk}9|[gbZc5{Uw:+ۛ021p(*+3pp01C 98[ 8p(020100Bٻ;Z;PQ;Hjm`lacHjgmbadN"sSdbBlnB`jamB $'!!+F@!&B fbkh`M 00"02u2$0s$C`dgkl/NNt&`b1SG;?r"BB:;q61rvWw4cYe?dcA32[9YBK7 [S;MC~hHI`lb`m-k`cB@!dgcp6q$36q%D 5v/B1ؚ#BNn&0OX?{#cblO?vwZzR2BR3N[ؚ(97'2ΎnZ t]tJP͓1cg!`f_t&^{LLLW쌸,S[B}D *fUWW{n,̍b+c]J7ĚLNE`Wl+Շ^bɂ݄9oSMd\H:"1Fu#ĭ->ڊQ#gh~ÚPW#Ι\ސbj' (va~ؚ(& 'ђyA_@dHYā6,eP|\myCZbN >Y.ieZD[S%v_\Vo /.*~Y-p%nu_T#65yo,:HYo׺<[OC}}sT7 AEl$hCAfD4籗}άELWk̔URVF}„ifr!FJNvvs3/ t>!\<7@ZК"YcKTƌ$A~ BۅUBvаK㯈uOcp2\W` ~&d`ҷM_0 q4vI/Wn+%əV9&@叧s9QE # ˳6-0}'KB(]qoz!u^4~v_14zM+T'n0?Dq'fe5G?gj zC7=Ys=}},em!xb\]-W|%wr@k4[O~?Ցj_>$cM|Fs}(3YK>lӤdM|@܂ʃ+[ &*?5I ƋVnF!0bٙE[}n41bL CU ֒+.*i&D]Uo.vum||r#rߗC-NFOkKSnJc|cX;AlBO"y ؁N68jh-)c1_!,r` 6h]?$7VRp \ej@W !%re])3F p䧗0Ea!8TӤ Y[/c;ݘY~&5W=)C~Zz@{ⷨ|-nԋW;4^|ߣ|ݖq&=FHH3^'*٘\_mOɇERAE[abjҟE rv?wfcd>g,oIr^wu)R6ݻ?G/ՙݨy8 'ho/%].rkCäZ (!Rkd,﫫6 S!(ʘXCݠ$ ,{mbYQA1/V^0>YLil" ASswÃP}oB wYoǰhڏ#8mU1^UɓCg&DhfΨŭ?sɵ"ǂ LWe//,wJx>y1kc&wK4ruՔX[Odd&yH(0=N/]*cN4VuppYa΢ljD¨JrW~6oln9zx|6V&CtsՑ籨u܅uD*tR:?`>yӆD%2B|!6DzA]c+7f^v7^+^K ƤU@0;gv<#YUB1~;rD0Wi4+Q&lU;WRx킢 '\t|2`Rq[kՓ<%hڑ(Tw:.du]а \pfCJ̉׋,f.ru,Q'/.-+HG6`ׄ`m bq;k(*˙OHfaLH&+"{#3OU[DT(#rlskQ0JޅS zGJ//αtBܿ23RM@U<\}mD3W6{BxIzw3/!+3ᦅ6rƍgCRo Um-Wa_R[{NZIˠ˹_%'!g=E&d, {uH@T䠏FF܀Xx(?FXr>{*>Z?]2B^M& Ynu̟ϷBivp?G/b,V\k"ҏ@~Ip^&@4ZxB:8ȝS267 曪l$5ujAyD9X#%i'<7`o!a}˓!e+Oi+0fn-uf3!.8e~R)s"={O%1ӌ-F{F(?0%0F svKS#BhѓrXFF"`/<;K.`ڔrN(oaf~,WDQ SnAvRo+U*pw #GM({ZoCZ*"+I5JKX/6p3| KovHwGoTÇ!QB  놷rf (8w.7ᄸ1 O+3!@h'MV ^QEj8Dȁ*[[vW~@ni@Ŵ֋8Hc3WkrwL-E~􄆛ӧİ>%ZB`IvV2Dʍ6s/HZfᏙտ.6qkV }}A._"ߌ{o,q7Wn?A ȓM&jmP+)cKclSx|YZXb&elm ̶jx)R s͊Fk9-i4Dm~V*צmF$;>3VVmp|фe{A0*luv'Rx˭bHV7]υe9Dcr1]f95odUVȿ}|\3~,@\&=]I T['s f8WIҎ"\'zQ bF /XKqb3Tip<0){Y)jQuMp߉*B#$EwtW-AN+jV>-0.ˮ*Qz⵿l\䎅Ί~߄߿vz2s1o[Qm)=@0\9pdrB߉h-Lq{i¦ Dr',W B0q~,WTNS|z[Cގ*\m KRse RHTbw_ʈ)#ԧa hԐ\Q(7.'e$v8&zo Z$\NU<Bu;5O7¶اϵx@6a0pT!lBAaw}R vר>B|)8AQ,ݹ\H*q#/ͻBQhbW쏵d҉HʝV)&&d%>NdհH=ZpYIǺ&6HlҐ~Θ㴀_q?=R$d̫fFhZXHNN*Nz=I6Tvqlr>]FdguTT%+ΣI;"VOuK_sE9({0}^nS_kۤhVi=t[xedPNCӥ^ӔRwݕ"ǝ[Q65Bٛ:t쥃ZxQu+@i߆oܑJP3eT /"./eV@-SyO+=:l%욹%U]&t<~ag;DlxᕻT15(d7>E`| 3eLG>Cm(M1N8uUsQB׋8V<1ຮnhښOvD~VŸ ȺXJ^䍃R$^+wbIgW)F$̠7 SwbM+[{'F[-z@fEC(pmv?U 7Y2sbZL_Phy:rc0 1 TXqd bpI̥?737ё2EىLl,w6FxDWȋ>{7P | ~ D mx01ל:+"86>3qy m9z,WJV9uCm goڗ'3{N.H ;1ws`7P{~p&l*yȵt.ai0j_R)p.HS,VuDiS7eNq%H^B{5D:Մnm{}N`@qaݼ? ԃ!tEE`s4п 5m6̕U[DX"c$ yiK)NpgF,UQmiۄ l\Fm갼ˋ9d}D=8,zڂ8p}iIq{4o÷ T4˯>upI,kWƗ!Ƶ¨Ez.@j_0HgYl: <&q/".(7;ucCYu<#e =j|IcJ<0ejf)A=bB~Ghl i/Ǿǖ1^oXȐvG<.cnDc G'pFv)0K>=4%BFy/xQCj}G<nH҇EȒZL-b/+*DW\\%L{|y|o?BϘhai [akhW3WZ>ꪛDӶ."h/ƫPyNL1AV#Ihk:᠖;<:Йt|z?3f;۫ #OHwy㼫w@% 4*=D@꣠mkp^oO騕OyJNlwyK0xEѨ.1T*`믮G*itfjk28,Ǣ&VEwHj:ATQ>k~sKSLjU6~TPn.la~'y M2,vFʖB.k kk .]-]ԀTdWD5N, HP +n BbhR:li@-#*Gtj~Tu:LjG:ʓ# Ic5a̿Y ğsߤNZ|`JCn]X0EU $~/&'xb"aW-P\ϱFဝwڝf!Dso֤1!ci"c>QXBc-_(&ihJ6QAx9cRNdK|&o1*BInAc[{3?^呫ix8 k .NIeG3vA;+M4+ň,Ev,I`HWDev4T2lUճmqw> 7>4+{6,13ƄVhbp 5CX K5fV7*#uqmn1;3HP;O wAJ5iW/ٕU+d ēF̌Yi5exMb2:RAN}6L-EƦ1TY5iCVE 9 |8^6ڟם.-T9Ub祳#_6+i+5H9sU#kAo&dK,Z.ɋ,±gQjǔ^2`.Ҡ,bZ~e7 K-Rr5o7d`@.e†ɂXBaq?kf5n5^rNh3\wr [=UdXr|IFz*7ppхFxO?y]90 =sW" }nUS!^6ztL^xE*xdD si ^1',j@'TQ87~C)cM%/(6_%M_:gb>L&MQޖW_q{q>6h럚ΟH9V;̏ D$#miKYLJ0Q)}ch %Qs|@Q7Z7A)"lvzn S+bt Ҟ0jD:pDdQ׏;9@u R:Շ| e4cN-5V#@9¬L-Ro8qtp੓_` Y~t+ucFqrK7iҶ9/8wfr#4E\)-vv=Ȧ,8{JJ%1W !%+4sR.m{>L3}/XRA;<+=d-O78Hs%f<}Յ'j_ Jkݧq1A%C;t>3 *+MJMmBTLQC͟UdwlQ>˗Nղ=Nnj)-h$#,\p|Q ʷ¹Q#)Q`doTwl: !X0 M2B %TG+5`&ҫ0~&- 4E'f:E!ݿOx 4Hu uggՆL5+ԕ{I aKt!^wta+&Ek sOhUKv"v>Xrcoi E6+\{z[ts8Aܡl+vHI}W.Ԟ>? @I,bgjoԡ9_RΩbw*/ρ5bKV$1+.7ٯVr]?L  w| *XERv-0kL!N:C+q+9HXF`sLB>L, s2Ӫyk)Iq;՗U܎ dm$ _CMCei?_뵉bnOd]b)j UѾ(2 YW÷–OeNj۩(( 7C-K::,4ύ@<:4W"EZu`Xoya[Z';]UXL.toуS$DOjUṇ[}R oNx*Hǭ^kWZ^_yE PJT̰-vH,&uE`Pvh22n ^18u3QTplq Ib Mw۷OM4vd'doyKu4>kכEni}Rg M"k8Fjd-v}=l_ps4>>`+U>o9+% JŐ&⧼]3#ҿ+7|9hP+PmtY'1Jd!<e& $|߃&+ۯ| ?˨4JR38Wv٣: =HArU{1)^LVeէ&,ǗbЀkF7jcu\*$tKHģR; 9KYT:"U0>q@)}ŦeUt߃t%y$Z~~yGDSar2M+Yryv>'ታ&={B' 2P7"+['٠y]D1>W+B^mtt\ʖT[tUE51WL>7iǎ =@4 GUe'9/ۇCPO3ǡL˹=X2:0 C,ȘD,BÁ*``aϗb6nae|<_,'FAc]0QEy>Lõ|܂6PH5aΠh+b@KSS졜v0[zkq~G#G`˫reΫ@`FuKP pCVaIzHaѧhfkI)f 6-;0 0Z}gUܕibw҃ ?n>|&q /MLT{4c{f/7]inZ*8|nQ\>S,St.Ŭұ*s_[Gsy#:z'HK)"#4dȬO+}`Îbi4 覝 1Z{d~tMVmMYtc ]K0cN62ӭtFS4=_A(:U ,1 mYS2!E*3iR(,fs^Zzm *I|Bo[0@l-huB܁q^o|neؐs}0H8y\b]v7|S]ͯAz f^'>gUEخrtkׂA.!*gk2Z]meLԨ % v]clVRgVeFy׍ iH*vF:v׿cYIۃmG6]~ulT /ǥ*ܤ"BCo2/GT41`+1-gHr32.B&422 &^N2Pr'vn1n' \fj_jAuwmGK  ecpDS 4|~ t9G6%;VmH ,7mr3JMNEa>tW ST)`F`r5K,IR;Sn|mRz=1=f${ s,ËЗۦB7JKhML:q71PQ ;NE=ŋr׬:;D-X|rTt@#΅!@$bSz1n ,ohcv[u&k-FJ%YrfI069Jۀt[h+V:EC)pa~d37TO׀w._{L8eU &B'>Wnل["nH{0Rd mzJ8gBk0%w w[L$g-ήZ 35"piH7nΔV O߅\\ SuY y!D:`*صvxZ(K- FF؋Srvn?{o#sT+iF1Oy 94pw#5R`X3rK$ZS3sO_Ķ w:q.QvpQ` W?!@"d/%1smV]N;Ա76&&y#Qغ`phuRFz\<\+-^Busҍss5;s"K@DSꃒQg'tݲ|o.hCRäڀmyؾdtr4=*Eq~"i`dMbʀI> c%e~> 4qTM֞b}h5xjdk$]H\I&qN^;RN: LN N a)ׄ"CCT.*>y|&G~[<^ع,!Φ^;[Z3o.;VQd;QDA{{J { 7è y [`_8=uPY?7x6)bk߭+Q*U`{<0p\dr6@JޝYR4KMǵ8hr}^>0)Ꮓ8ndv{ẃQGYǛn;vPH{)TJ[:rrlP oSP19${lƖ#~C ,"ŞVoJ9I?ϑ3+N.cHߛ]EN]6?ӇjޝEcpnyQ9".rZV 2̚,=@|e@kV9518ClmEِY(>m7r84`7K^%;25Y+e]gp /5)C'XVf(. fAxN$aZ(r/%߾57=F+fl'Zy_e$AD nIĂV-ͱԷ"ϟOSK[=C=nZtni0攢5|t1sΏTDVIV6^$ ;V =%hoCnE&\/E_Fx<4~I)L&=[]ÞC| _}jzqPE*r:H^fw"`_y#$Tƌ]EhٸbPs>*閊_kQSQA6kڇa[r$D sG+% -ݳ0H4@ܖBdH.WM V} RMr[ bNYF|0nئ,A=> b|%_Oe934 I hUI*!c&L^:JxkOeS8Z3|ß wq )G>^?Uv\'UG։`Opi HT2\8ܝ`UNy< t%PAy躾C:~i7jV#o*N¤ YB<b)m(e]vkQxYUN"N1'H |JOWL!Bhg"q# t:;~s,D Çtï8Twe`Шf 3g[#\D|*" foug T1eK$:*ø`Qˋe۵s7,x q~~Kr"CCaBFoz*mH Q[^_a%ц8H|2ŦgkRذ~@:4 _Xi#d$Wg,ɟҍd353Y ;#9^^G}~R"nKnlo:g[(h#YIk8AeM:sKBW*f/X)g t)[FLH^TeY6Ͳ`sKg"r-X١Kq 8AI/eޒR1=x4[&vB7vAUꑃ7nf0 M,S[&+4F=d 8]瀽)?2R3َy"8f`2N(mr4Cjj;SmZR4NkpHI ]M)m+!mPaWY+fY*B#)FȔ}ʹDKw Ź)yI0T Ex8z:ˣi |7WQ;!:%(8tŠHmϊM?%Y_D6fgnzd M/x<Ғ #%铖#uQ<8c1}JT1}k}2f<'(PR܌{s3^bDb줅aVWҶ  /1mPqZI&A4B|Hw[\ Ar{=/p̈́VХNi -΂w1!a4vi| N^_-W$O_MD_]#d#WGQ$-YI3K~ CN erlQ~&x{1'j- FH˧-?o/'ZQH `X9a)ȭ(9N1Pi(2! gm6*SuM ,|/J7&堞iǺq,58H<5-*E^LYu #'f䴐J3qтZF4$?Wq&kwCBϻNpE_?8{JXоlW `D~Gܚ:v0j-fNm0خZF6&r>)u~aX2Cj,`bV̲]-'73VA:~eV@rfk(s4`oxxwWMblB]]`3ꄮARB;퉗zNlY]2T*Q~;Q=^ɷUT(;n)rr8vW BTCp.2N)x#e1%DFX/y<W 4uCAOHTPRc|ZŒMd*BQ^})hE?|_s_$rYZRi?>[H\"D.P$lZGeE ֎gP)-JCi;@spBKC f;/1&Q:%b9Aݤ}DQz+aPt]M2`XyaCKo},qBEJ-1c+&UzH<jQ`Xs"N}[qI`iU AS]!o/Hqs. "2={ۡn ߃gA1ZW"u+enŁP}qt Tf*3x-{Y\fwDc`geܚU ҃,ώoӼ34B'8zI[_7dv={rSCĵ?l^ǂOĉ$#@#r:of S9{E4$OWNwca#sYad㔻_9# $J%EVn-J46$9j}o}rޥ9zz4"/qXu>f}G z**embcמ \&ӛGoϕbq-2nyAyn~95_eB:ŤXO1YQVb{G9zG3wb ^O]MD`fK 8[e:!^nsףnXuR폂q۽Eq`7R8VܛD6H:̞$vc%97ﺅU:6K꠽犃ޛzRz12R}1>QuFR9c Avצ>j-'a͞拢zN& $ !t4w2~F5*G#ҾRL+f珻Ι&Z1]VPFh #R>cG᣿qĚ`[ mE~oG_7'!/p32@ [ {:mC]yդrnM}݌w&qǃP, u$Q^ݙtU,fRM6tcv4,2!xӫ ڌY>>'`V^A^/6(8TR/RgUkHJ0_ZL`grxL%D; zDk\-ls˩oX|u°DWte?4% HqN /+PEjț#qQ49TV2L/mBH~ a56J?GxT;V-zf 5wj8!)Q~@L;{Л /w3`s8{ԳBIUp![xf`>9LbI T 4'4-7n<_ԥ+\|~~cR`-'-5=;nc#fW._:d:`Oi* ߓv{Rd8<׫G)$:2+H]1 ]FGTkiM7)SZ<ѩ5VҢ p5s|IG5 -Y`1j^"3Z0*Z`KdXV>ӂǬpqxTHY}Du(?2V%a 7oǩp/=&&BGqΞ!/MoXGb\Xehb:SvmEp51?^4wpI6NŕJAƒ[; N ;7h۪)!c{<?y[,Ulߋ= ofUv*쬝5(!;Lv jף:Nj+MJ_ٮh"M@X皺DMN $Hβ T?U< JDe(hADZ(,Iοyn>W]y=v28YFâbh5P俎|.—tYN5~<|Vjm!qyiFhyD!ѓվ4Z'knC,Ҡ [7#v%߾Iˣf)!w(z ij)I8M0ŰN8i 2u{kuuq[iVSzTZߏQMJ jkxƽ AwMel+W3^Q[C w#f)K^[~\^dGfTZZ@\ ՝ ;frMK :B/93*yux!fp&.Ɲ5Sfh+EHD/ܜq7 D~_^> hY B wu}nfrxmwݢ RJCIevP̥C>X 'X9Ѱ#Pw]HF?xv }XexsDl=;I^`{'S"UP15̲ m# rO{I>cPؾDSdl7"D&T 9樃8|3MK.[zrt5ZQ_wH" _mP5r 7TԿb)P|ʡcowc3pD drTNBc:`Ւ` $K/= zG$o?`? v6KQb(,}B9c heA'cjBMa`s.#yZ^:@m ?_ZfP;٘,\r#1 "|wԵ-kTϪH`6XyCԞ=0:FrFW;n>b,ԟl $P*bHnR;^&*F׊o wgR) ƴ^Ü y>␟>Ǥv*ΧՒcfѶ"yc]z[ֆ}%螸1 na:tq$C$HJ.eaa6یP-]ir⚘{٩dA-Oy fϜY#XkMΡpr Qx\>M2oTzm§ ~Fɂ(4xgl :T2m& ۹ҁR"]MfF^^KkZ!fXgvFD]> JmJ%|ȸjlV_*k *kn[<oGUYшm!emDTɯ9Ocq4ȋͣ<ꆕgL[3uT|s1)pL~dLJkNĠ衸 -8h1N4_ QTTc]nv;>fߌK>gĸ|I/,.RfϪDgc`9K-DG؈w` QhOd=ۣ\w.Y33 MG OY}ux,qTRXD&D0xGEV &0umC| 6Q|k{i>>mG(CKWD'CXr?of=t*&KCOSݢ9 ~KE5֣Whg}t;4s $O.؝}%=Gid}du硐vg47-VOâ-MH-.{q]BMԺz>$;mw,0ws`mN]g 6x$ ~2\OBHڰ97X\Q[Ic*kMD 'AE_Sa^nv8! ݴ4-S*gZi24(P;Qt{~?S`Z5)Y)WppTc{cW)Lb8}Ek͛l+4e$x3إ8J%UcdgK!P(~_b|Ӂ"Y6|aIoCUpI7&֫!oӖ #ٱz*,W[]ީo0PU_St߉-@J2}xkB1݇# j|h50[Kӻß۔Ȕ '`Lf6qDBO/d<] /߷L N !NB59TFx7"˒ U1 UPMjew:$4S s:0򖔓('4s-nzy ânH>L|V+abC6ٽc֋ lBa+B>t8Ry?UUK$]k}N/"^h*>o7%mb'i5)]b蕍:b'w+/KyVO+"H]M kék0aDWl$/X'D 6P iH'V#$2uj8^].N[~kIcETY c# cyߟ&cX$u[#W Pmyi:e!GCX$`96Ma3*si]ʒ#l)G3HvGƻ, Ts[ 6-`K $>MTA|5ԑ@LlqؘWZ3i P$ҶH^j7i]O(Sb-D߀j'C IZM !~*qar(i)֡F߈cXiK~Y!֤-X*~&4:է!;칛u?jZd_Iʥb0ɝr-;p8]~,Mʻf .([|{y2/ ׀X ^A*n2 胙;"ǵo~"zsdωxlVg.$Ek4Jotq:2Ft'Kys3&gr~ʚ+s|~ymaR\"%$73kSwup54Hb r֤Ʉv~CT}o1^"^/E?8+|H<^>EF˦=]LiЗp0pi> stream xڭVy8Ϟ=e ٳ c˖%%1fØ3cI[d˾3-Y~S9=;1ss?5B斒P3LIHI+LXK0XR HNy:!G!82h  D'B1pW7@FL\\Oϯ3I, &}(' #A-a0 p#`f Lz=#8` X 0 VX4 'A`_! co pŀ8 p( AxC ]P 1(R')F3GaqXHU͵us~Iaʅ EA;F!Eq`8 pj9P8II`h 7 o,'  @0,C5?[`4};_8, "E'"ՄH]H:E1@2|`3b$`( 0:) G* TD$[[FvWh]oIZ?ޘ #!6?'4M+I i)?p.5 n04~k$A0K @ +s'x+HkѾ$Cyk\j J"*8J)TGVNjW>w4#DayĚYk??a|fI4Syŝ#j޾ZYb>{h{geOΕ9_&cOCg{[kU"xSZ!0ǽUx -WH9%.A-uP,H$HY[m!IMv&R1qx}!;BEH}Dy'`R/Sg3"xrWgX<'?Cݧ)\>Н sz.+|DCjm[GuTozs$7ZvVvѭӗ sFwu[]b.75Qt׷XA rmG^ jȉcۙ.a]E;ǟn1t;)wXx/(UOw&j o{J06cH+6bUe9XϣM7)T fQ逶S`+pϵA [5,uYm'@bW9/^-4 /Ϳ͘QLN<גUㅣm{9r~X,ώ+xFg{$8Du4ݶ+um%ʥese+icgvkPBB\BtZ^UǚW҉kd!:8Sob_ 1L?O}{Bp2IW/;mܮ,{ (\ٻ`yE`MÆ(n0賞}E΁l}B3}um(OВsx,|YVC>L%ㅋN`Io:-{'Q󴉻m wf<b2>F+A͟is j*CJ{ nf"pQ8ڬ6~#Q^n!;y{n pN 㸊K.Em0.6һ]"5uPgyj4e1W}gDAnwJ2bp|y,N'Ke ߣ{Αwƹc+t26c珚ۡuU x(-Zl}QIKE\ׁj0nG2ZQ|W9SV5wo{̫%00+LL?rConenQu i24*4#Ppw7zVmfyn_gٲFխEdk1EJ,~| 1M=<M&#dٌO;8mF_nVNA[g㧫vuZ;"$ːq:+[_ށ}`YXzl.&(?jN-2pvgY)<$G'f%mJR)6# i8|$¨aXEd}~Tڿۅ1!3{$U'8m3?#mۂ(}ob!ކeRf֓gS/q YR5杴G}tzos&8!Sy!YPw 񷃮 y@bF=g|"o;ܗL!㑚ǩ-͍3/ۧ늪PbO: :W' YIלEݨN-J Dy'f\ȍuT56jOzh(t‰h5l da)ѧ=pz-e,^Ed2Slg晌ط7Խ8pBS%1눸8a8('L{gRV}M`sXҼVӥ5Z8g*6y%jUg?UV  yjIeze4(J}>|H( GS*Vke2X]DZm_:+3]6Grݸ)ͫlv~ɥ[uv[煞8X3RڡC+FCNٖD.a+=zE:=.Ui%.7T4KD/b=87eHgpb0R+qo rپT>juqpJsi,tLgG Q>zAw.b] 蓛yL~ŏ%* c|D[3tizJr|JJ^R= u3<Ocw0:ÖYEr]j٨7~Fy@B'u3dK̥r$*4&ڶ|#*Ls~Mv N{Qq 8֍d|msh) 6EW9Bm&wCw&$=[ Ak wMU 6kݏxbq9[:/>ۦv=$/צ7b,C\] YnlxXw,}Wv:`u\.C _[qho76?_vR PCG"/5tRU*n)íPa+˱w.oXoteg ͜1'kLfg%;D/WL{s|?OQD˩ Evm zR161Ay]}!s:)%ݏW&%!Jh^@ O$Ԟ2\d leרjD(jD?{d~:$\# k5zTjg.T`^9OA4! ]Xeg7;q#,"@A۶4i'("XI^#/'ih9/SD6f\ǂ$pFzN>f]-[0~x8'3йj($)gx^؎Vt*|1*zs~J]m'D2xKw 6KBWDkW#vswyqC0>Б]jH4$_~eċ}x*GDŽTI_1V0N> s%bܼܗsf5m1__Z|qUN3f}6exs/o.&m8ɤ#y M w~KO}JZmY5\ՉV L ^糹5ravK<:SPBJwN{ *S8Ռ 'ug 8Pf5 +6rV3UL)_LsjtکP-wuv6&C7<7 >N.p&HAaVчJD(/؂V̀+2:tSP+wVpql QcHQc-U†[F-wFo~ReVm,eyo\[8ݮ)2}&/9[e.5L/8P7+}J9no{ÇgMnpJ螢"a`M/Wv@. IVe%P _s\WTr1gpsǙ+eSN1T *5]'7[@;ERCr#9;]XiɛBמ]yS-]zMk,[|^:)4%haWh7|,%DԵylJp|e Ce<z=a61OYP\5-*C"=o).Տ_󃣷6_Ti߯`f}A$%,:˅[VLxz%CJŝq߃pH!Oxe_9F`V}BLjÖs iln7NnH? endstream endobj 1490 0 obj << /Length1 1166 /Length2 4839 /Length3 0 /Length 5600 /Filter /FlateDecode >> stream xuSu\[;!@ ɡ[;ga!n!钐i$/z9~|ֳX{F|`#D GPwGo/#6!x :ܽk E e$EUP׼7P %DAkA?H)>CP$ TN8 !^oK |ٿh$214IJJ2@^@`_SCu_`(׸@.WCJ@r{9!(FU`e^$4S"!NC  0C=!*| @P@QA!AIA! srUM~ppPA!?/_?w$  uB!.wk^A@__+ #09?g+JI q$.vuFIQfK?u;@OSj@?ƹϑ| Hko~ۘu(uE]sWK_j0oUxPK_Pg?y4Q0"LP/5E9a?U~}KDA]Nnp] p?J`(hvvF"}Ag;C@ N$ӓ'-'Պ|kC]b&?oðWq:un%"y%ҲU]*pup0ƋI*a p4bdtF v1$=n(5X~XܕS2FІ0X#`d){YAu[i,@`UEAtRџZ*wJ!$}GFq6SW}VvW/8H/?'#$1ϓQaND'aFz$>)|bKr^ ?/Ϟ4 Oa>!]lG~iiz;MK+X5,XL!pYDf]gb"$ d!Ono0rx0Űr^!&.hYʻP҅O֗kCcfڕnırAF?0a?:I?xwsX#KezGry&dYZ )X81/47&Nb5M̻C_<~KϩUPY M|4"Qv^LPU k;fr$_,z='{gW(򃨶ٵT &oWO9F0?4M:PYة-J Bm؍ ^\Wb+, *z+YH)WMR6mMҀ^?o #LofֽYEK&?0؃y-ǟ!}=\h / ֫;<.É4K'@0AڊL:CG1*w;M{+TfR1w0O9-#VE54v 3[z nLi J#cW HsQ%st,m9U#r¶rg!5U!m] s`_mt6,dK\ƃʥ9 V|XeM~RLeco+ @;WK;8, ֝](>e32<. G4XUa-byC2 4]Nٱ/1~ƻoLq i{˛:Xnj}ƾXv`ږ \^m!ݟɔ՝m)k+}R'>Gǀk08v ?(w;z3*O<6&ve"FM|FN_.[J Q.y=:k\t=6?5hcZ]!G=2L+(ʌRٓ|Ȉ4<խj}/[fp6j֧g嘚+j'hd{QlT*UrIwibjqpG|uIn_4 B3lIg Ai-B9^Xhз&0OsX䩨zVIbW[ DI:[bK7sCimM4k"&+gtS׋V"޷t1R)VhbL ׁT@ԧSKn$U q@,F>'cꮹW +ap vXtuW< 0¨׵ʜG-ҝ\gt'y-U?gv3 G]t!+%砊%γ % Un c;de.|BS9/|4UHS<?2{wgAikF-q+}ʂ lS̭!Ce5§;UF0%V]qW^Gbbor٠ۖ?B DJUq1vbG;iq1bE}#J֚)a'@pJ.uּ2ှ`7wIEE=vs~(/{Nu`-@ҝPЭOԐ^thW{(;9w7>Eq Ŕ>U٢nnH,h/1Qan?zkM [R;`3RoC>8ZrtaP%39s1v~*N[[wǺr&Dž]YS.olbۢ馷t0?JF<+Kl{szepPSc~֏Xx%}+6Z8+VQ@$ƊI]_Yi%m5p!`r92ͻN8T 5T+n5<U2 M-̔lQZՒC|En͏S 6j$"*6IP6>ڥ_!M.H/k%&eeg1ljs %|ΝK/"F Ing,W~!R=ͨ(\DU<~ ݏÓŖ \ԛEaiDZ $DeA^OR΅ɷʞ 8CkG.DSԍ'' g+ Ɵo׫Oٖvp1:d M,4؀]e+{zsXt{. VSi-7\!'F.NIyI~̸ҡwb®J5%*^exk}d%FͲe^?Z^75QiaA%(1U hAY8%7]׽!jcg2]{zyiQg{=뫉l@=XLIueK ;{‘jǗI A͞AZR1,|ٲu_NabUۧ ݙ=  *yۜ2{`-JhiFa92%eVHCuP/\Bv{ӝZ8#3)[.ER)k3ި.&2ob`ԸTF *@jaH8l 3` j:8k,hAUKT";:\Jyʻi+*p@8MۧVqެuGDrx& 9U |%%z-x9h6ǟ xgzaġwlg ݸُs-Mwn-˭[1PJ>mf&RMr/9Z۝&R$'<j<>9`_kQ[-pTa5C?&RMSaGQřF8p{Kg?+I$,z/EWۙ?{ 8E:BFcM j+{ lHj9%ƯLc4J_Uްo`90icq=фI~v 1VGRL5z%+u/z CtRxWƒ6c-yeY+qf^<2)+L\ݔ)X]]38F| Zzϙ!AK'OQ|6]UZͅ tPB*I)'sxz3ܗ<_!Od;-q5HSJ)+&O/d۰I LN-Ǹ˻f'2:yOuѸM[mwV`JbR#a =@X&bfu4$ᨷXx()Eccʯ!wG? i_Op~ˎfY?C0+~wçjԷ,am릝F^%q1GE="M&0OD3oc1t2g~6i:PIr̾,gA939P x`tlh0g6l <啣 jU%/ܯ8+I+!̐i S 8-먒]6 % 'Q0T?26_g۝s z8afk. ЄhV'i:v{Qu9rK]j˲=Sgz>ݼ p ,D>|s endstream endobj 1492 0 obj << /Length1 1199 /Length2 1958 /Length3 0 /Length 2701 /Filter /FlateDecode >> stream xmSy<{G -ʥz-l2%Ǯ% cF3`HTDBn֋E"K*)!-,W*n^;s\1fL.r` 'P0]wq1.0hhA0\-x 2 F|tOՑ#N<(80cC"s` BBt\I p̀7Dȃ`@em:-"Ѕ_ !BA67d!Bar@R8s׉E0!xm@+CH8\"6,0N)aZp2 !@0 D. s= ΁ @?I.7}-v aL0"C!Q D~2|Z(<o20@'ΎAҝJyP8};E尅h ܶ\<͹-'@Goz|bD҆ĥ- ȬZ ߁ C >Fx<2Aȏx _v~a)`Z@4*ldqE e~t.-?t?Kf6`KFo L'f,W :qŠ#!0|Q!!)2!? ##J1`CtZ|)$!%`8Ȑ2v̖0:|l֗IbĊ;(s OgZLVPW%)I;‚XIuGŬmŖ9dǥ:' Sҳ_[\8ab.UV(Tx隴p6Cc$:2>P|:f[l=QV+\ +J.= voCrBΖI\jY.Y ~UJJwaH3^l"kc&<(QSKZ={;{MQc.kob^̮OzE*%bl _}{l d@񪦧RFi+ʹlDulr-ԁkަ::$h"M4+D[KdF]YH;6r$.dcGEUN$^qcTtP*nRuVLݰz:B{}y<ĐG^6J$RNzRn"rn᯺_yAyx۹M8p@/& N+Ø&_ QxԽ7gzo ν5$b_;}hϧ1M#S.,.ͻh@31 لa]qGNW{W`7ĚkV7TJ;9pYˆ6轘g"6q-1HݨЁ[CE *n΋ͧR"vH(IW6ď']~R:@I]OLx}ŏ~⁦=qTN$Q"^Qleđ>|:unT'eZwdKpk10a~IZ!멩'|c$UC!cErW5F4/ޛ~U˾w| xHDǹAˎ^μ1{9SElҖo~{(Ͻ}AS>I[AKM~ik. ]VEzL;V 5b䓩3vn)Y41꫷cRqi&p|JLY蔣TXC_NEt!zfis:#WjOnm4:5>Oj}čF&9c7|߼ wmWk~!$ޘnI?\+EcGui U{Zo/@v$#fwqbҸ,uam͠Hޛ͇n=%v\fWoey\/< endstream endobj 1494 0 obj << /Length1 1626 /Length2 15551 /Length3 0 /Length 16387 /Filter /FlateDecode >> stream xڭct&Tl;Ym۶bvRmTbWmŠy_}Xc<559g,rb%UzaSc3 {Wzf&KKN.ltr4Lbf&3777,9@@IMKK_L^Sbeazp7up3w jfp4[ٚD$T I3{3g-@ gebfbF 0wp0q74X. `pڻ~`eobf/ÿ9:;|Y}龂)98[9*I%.V_j?%KK wy `jh _0\- ljk+?:[@GG[y;aru15gefiY7w03[n?ufj?3Ch`o053eTppJ c῏[ov -fkג @ϢqlZhElMS' j-L LZHXy*YX́_\@:5K+`?Q/ʊZ/C!pUr?Jw0_ˆ8x|9l_w 7!1Yl _#?c 7%GmE.W7343]]r0 tcs,kR+) u Ȉ2z chhZXe7ߔygZՇ&X?H2TiH9C<3pA&亜u N .؟n?%$msJNT1 6fD[҄~2:WekWnټdW}pxe3ś%^34nB,DJ[ &P]z$Y ;? 19ߋr{>B:okKU鲾4/%``n%HgLt*;tZ >E(7^W:hhi!IAoԞ p2'xa2`8{b"tA提]!bS/?ݩ P 4 g !|k_:;7GB٩=p^0H_}u?)uUfcXCHvSwo}Sx0ݽAO@B"IO'mJDBQ_>n^wBg4v̥l@`].An^v_t8sN#UQMru䔩ABbw~]ELY&x,ZTk$1[hߐnh#J6:'wf|TEh-a|ICb҈-jh5T9?rrf(!k2~<*¸K_H 1>'oZSv~fs6V:MU ڑ1hSzTE,Nn&E+Ϧ=@LTafVcI|Wdhu@' R_$#+5B n;F8v݊+V՟u PP~4}]@oNE1>(\j(:tZy9MT-T.,X v anMx r ZN\6i3hzHڧ1o}?9z;"< !Խ52L%XݟSx{n .zB򟹘 OZ (ct6 ,LIj]$BcpPMW5-\z((em"K}sUΤ' Ċ07œfsixu  Bػ*g٬7idHQZ2I1|*w׭ɥ;5l7J=*ģxش}pO[H,p8Afjڮ4K$k6@y\2FLj|[N17Zj>JG81Ƌ`_;Kh]vhɓVK JD49@O'g,GNq# %|}ћʖ["A@- 땓kN?G7o1k]SIaXϜ2p}le8|<"uÊ4$XP=GBI(`Sg<_VE%$M1"'`,xqxNWc I溠WCo2+vFz.TSo: &zTYčN@#h CoY>rT E?QغT*dT/a=0:݌%HD6eϿowetEd nM܆:[x-K6j'5O#)#&:W$'3j( 7"%۽2g ǂU]EPfiP ilB5ӃҀETM.Zp&}Oao#\/0qBIEě8Go18,= 'Ws!bLjxB 'K -.e޴W> r?Z"+ =\~mqHEUѾgy@I hY{Ͽuᨶ[=9$FDmq7vk{ Sfx4 Ɵw6%$gMy)ԯc+%bT˛ñE<`@M ( V`t D~D! (1ŝmφZ4B|8ֶD X/  "x;~#+/)S": n.Ar 5S+(5a| ?đ{Zk{-1ؖCַ(PSe(|Awm#Q N Ui},b${i(#TXiB/|Q@ %}X?8 2#u*=]3>!ޕGCذ["` =w0̪@1+S-\eW>[?Xj%^-_EDfh;d2=#83ʍ}c=UjAIgy2(v ߘ;?@3}qF?=ZGпG%tK})^KSʗa:D =#-pܲC4 'b%B !8!)TA15ˆ?1SEa9*,XMZ(X_Ԓu3F}5~>>?}ۗםr_^?T|Ѻ|O~2)31;E!DI$̧83)~\C0jd9x;S,>,t\(Nnů1*XŰNmDUjLȻr0G9y9nGnwI>r.JyIsqf]™;s] DxI1VQur( 0 JQԒӠHG͟G)g./RrMM2a*n `Ҕ^  =ܓCu[|[Fض|Δ|8Kꃪ7#>7mYP}CgE6^)k\7-)ki-noi-ƍn99ˋOBc -03(~f~K60[HOyFg94È0; 7;̐`զ[9F/iG3 GǰkK%*fj MۤwD&C\]Qu vD3d2M!Iԉ.X\76] ˖*=ȈIraɕ(B/L gE?y謫]Im`n,(+p# 5 Rv9VQ%dϬH S`N_ cVdqu^J-@F+az/\8(Z+WfO_?TJ`[)ZJ*dM(귿^y?H0Y* w}v]/.IтG}29bRa?♛R]]AG[\ i-78}ʣ$0B[a"&>V=جqF8 =cAs(kT ݛaSpD[_bQ)T Dvm(I%)уƎP=Rݔ_c g>NՉ>? tọ,0~:.({B>G$FKe@(pTjLyzu) r]Z v}Z^}L1qӄTpe*NŖUv ?ۅ.98&oeLFJ'թ^0y!taLm~@eD&So<ϵG#ȉ' 1˿rF`.fDqÝScńwsg BjRA\]1 {#ғuhE´Xq0c]M{ X!+y҉,vv勈ؓ ;Ҋ!kSNs.;]vXV*;PJ_9 U0\w?TGS{bz}994}kQ_^{sc )e<,pw^ (%Y.EqBK[`!V]YJb1Ȟ M\7/XIeXVdhZ|X a=MuV!o\YN~5-Q7jK iYO2ġ[Bcq=mzq2Z#]rzic+nT)TUWǐ 'c-JM/!*mɏT0-&]2Qqe03Sv4%X!!$uFk7Dq?O82 s=ٚfB%̿uGZ5f ru[2/һ!v(`G[Jߙ!h.Lq)ڤ֗>#|+u Tw 950FP v^w,cs(,f uOǝ9S6Qf!7qUi!rZƊ"YJ]?u1$Tjt޿E"TƅmTp4=+8\ʦ,k*‹]F>K#>oJ9L>l?~K%pVڅ9ӗQ%%8\w|YH|H^A8{B,1%"FL21MpW<4m^E*C*\p1 3e[ʹ}w9^35٣cw _߹gic1~mM6#j:[Άٗ@vt*v" 53kEi[}N4'DJ;Pn~渿ٰo/^(OeM~<+٨*ڧ.)s0*5H8%K'o^B.&D9@szkwܨ%|wT.Ac (m#"^.rD"S_caHL۴ K#e%hz xxj+L[4F{(EUN@-정g$a12hB0C:A,XH_0.W<}iB<ҽ&|hGevIj+MOJ)::"?䈡BOf%ZwgO68~ $tj4`sDӵntYS2U[R6.NRHCCp&!m[d>,>u w8 n Qڈo_0!++ٲ : @L.q'Rn\Y~y Z!$)@^?ʐpJ/(5rn.u DlV5n$%~UDvSMsebU1 "sS#?;Ֆxl(,PnFdG`&UkJ:hCB I6]7YݲL[AC3q}d{5N - mєT(jяṉg'2r)Bhv&) ͅF#5-[2Y}z ~H:b f0{|?NB65^~"ؤ"tN/5m4B4(4.>nr[+t+3c[ưLB0}ߜO34P֕_ '*SDbZK Ha!z'rFHVJN$o{W{i崆Ŀ-2sgހ0)ԙʖAvú=a)u}z|Aq (l8,j֫D.VBErר] /5 0I#+56O "Dx2Edg:238W jA zTp T fl58|P AݨGA"g~y#qvf`#[yyaBd*>ī&6(*M=b]0:,fLu /4il(A=Cr #-޹U6]Nm, cޙ =X6pթ=/Ku]='`;?4t_MA >Aa|эa y[^A0TZ9L W31ZA7t1h v pS8=E,] LjXi͸њv:BNӒax9p\]3{|)6jMthH+pirXV`G*D >0G1jQa{zGjIGP_;!C| KnC`;1Y/~]:Gjs.YĬ=V`͢f{8ozx@#1 E7{)bd tB=X>\JQ.?[/PʻבҒ/V&Qʿ,0MU] 72v/A\C<i<~l=NY0ArwrD.@U| K}'.-uwn1TMцl[ ^5}cz^z34eAr`PFN&+RPlZ!XS/xPoM蔊!F/D8U"e2[MdJ&KC޴ J]X_2Ny)e mnC(? mvJ͋c(kUܹѵ  jA { ,8#)e?'X[;P@_2fFz_(9_]$ҭȘ;5#IZt#D6>!()O Dy2@vͶ\qAJ=={>4mz%V4VHL1 %@hsOZkT"vs&|JiU|^{uL INwz(z' Rxz!㘉>y2P\ !HEafv]n -iYgx`H⇨ԕVeM۔Eb9vle)6teQ[:#PI'K=òшwC|:M=|Mr@^5SԄw8}/;2Kh{onV=0ྛHia۲e`MKPsҴP+f`|m׉͋V]Ȣ/p1 :Ѧ7Ȁ̛Gg8˭v%go@PU2qjw #Q±Q?8zeC_9M,:/ET ^݊5O\H'85˞UүG sح1X@"ĴRc~ ]?x JgNް(]^zuK@k2ޔ}bhYڿRmҁ&$lUXݼPՉC.TwmK0_ s+`KK̈\\>,rV 2v:QxAx:# ͕G0ɨA@@3PL>5cacu`)w?n|ȷi˽C9υZUO0JnGy8N/hoD. h#c,I} CShWexR¢vLUW1wmauYgX䤛rN!~?E({Lkyӻm\u7ro[Xth o N Qyj])bn 7K[(K#s h:Lȩ탏Y"AaX8D-;[/}͌8M2 5FΖ?VXIdzTjx*ynA+}`bz&`6뤪bZsRmp2CP4mxy6<84w"# SpM~[[TwAxxe0ҧgnm`z\wqZ"XT#^:!LZz5p;B+_qtz9"my@R>g}#0k!n;ĮwЖ'A*璱ܫFKR؟f= 2.!\zvkJç ז:bH:Z@K*D>"ؖoP& YC HW5_3{~#3Rk iH,ζ݈Kiڝ6L`TԦWMCDwW$5]%ĻJ11|Qgɜu0{ԪH,"!4ϵ\>74C:g:vr;ߎrzn.<Ģ{>ߓ/ NqGVfJ!\E5ջ>QW[h5(LRZ?a#S6^ν?d†`ܦ;2PU^ cGC@ i)qyhq͉6|o3>1A 'YޖGsٚ{CHq V(_LGܢ!ߚ)>1Mqn6 >|V_8 \iȟ54L^U.n]E_94-v~ ,(MSMjyQ[h.jiHKgbun];p_p%W #Fv V^9B̲Ҡ*x>UJTfD07U.J331$³iJ7A3bu߀,pt`>c1 Xlgo\ 5U] 1y()md,דukqC^!(VS[XQא<2<  i 5@C쭦Mç^cSgh/ 3Ũ}T:͛eLǨ5-w^pzidd?lоo7&7z+5HMw^-x؁% ]h+WJKXE8.h2»=Ti'dqjeKnL)ԆÁ#SÉBӵ`'ĈIS 4F΍dùQ=? Ai|cQuE_ګL?kw㛋G9tK$s}{h—H/'<׈QukC&!ZbGUph~d@yrt;7$-Hy~&9^DD$[V9y1t/Doi:D=J˂oW7?8敁MB/̳u[]Ks80KW1UCcxp |XUREWP+-0zS=cEgpߢ-;qݘt~AkYt&0(v;1bۏinxL[wm@O5?sCP31nGR@ юU1eɆdjX> stream xڬct&vVTl۶m۶mNm۶zӧtkgꚸ="#RP472scgY:+s)YaȄL ],D ]L&Sc ldinTURO?.#t4p3w5s lj p0Yژ4%rqS;S'C1@ٔ `f035gXC0ScSLS'[KgKg,m\M)_98k `ldUADuX`oe bhi p1p')o`N*?+8:ؘ:;tOҽ翢?ktq61adonsK;스=zW:k@ " Ml<&f0?]P߱LG-FyB]#ch{g2/_M]LXR@oW31u3 cd`/6 KckH`vCPDULPs`w\T<?7?0BBo:F6 N&M1,kd7㿺t ?bhgw_uvfuޘ;*#;ӥ3xBDt8ԡY(ξ?#b>es@pÆ'ϗy7;arsm0-6 E%NPT$nEhO~MH-@( g'Oc#C=}4yd܆~gD).N_on59muɪ^Kq;߂ KFWaqL%I|U;$W.2W8,aZ3HJX($M$825բyYqDƪRvJc~@vժd 4+ Z2G=80hZQ7COJnԄtC z~zK?xS䓹Al2x7WM#.;KA=dP'·ذ^Ht\&aI!kj$מu:IfS-]< יq}̷I& d, vg%y&9oՐ0Mh2\Ra<| b/k便ZVKY-9ԔQXrIiqXHᐏ6bLWXw%8A衴4 M'd*$<ϟHyT_Ȑ6YtBmě wJJ~W.G-1C5Nۧd3V?hg6GA+vgx[Vb%߻?|4n2g{y=& v^}mBzmyqzIwgsޝЭ!x%WKGw2ݴ ,+mBe2OP-UI7G3+a?K r_eC mu2QS&Jw{ r\X^L's^]o{\YUb\R:!1nҦrtcC4U`p`iTѹ yF$GuӶ @ z½9 bwyr(riGeŅul[6 $:̨*- w.hO{jssBGb0r :A Y.tlԝںJ3":^G%t"ڭ$iKvEmS:KS!.뵫%q0B7cLɊK8PF&yD.} jekc4T;@n(L}-d f[t׊)˙v䀾$'AٲOS-tTh^#$r[ϞP=gZyRSǍ8ιJQfF/'i}X2cYX06;NŜ\"<8FޞpXBȣV".N"r[ T#8a #޻R\^It28S^mt;oR:(Eѕ99Sc>^d, R\;G;k)7h w)CY oj)O8&hJ+Ѱ3k:Hd" {~dl|hT(ĥگ3>X .Wմ١pL9DO:80YEV͍lNMQ9Xb^=G?A~ eoOxH]4FXfyU[^}N/lHP>v #^ȩYጶzq"*Jh,H){"O~ܡ2\kŎ/?I>#^+JRy}GqK32G4 %AԦ VI+dO4(I"u[qlR*\g7n;Fln95,ͅȫ_[S'MAUk!4EBO1'<0Oyyx&~uL3̏^ DHq>>DFMkAsel0F껒{(>-^I30n,eƥ'Sg6:%hI[/jJ{Tҭ}Q)X)vMf4io`!u|2GePx2|"ԬFVgsH)Hsҥ1zI!"}tZJ32hRhKWR)P1XZ34ia&MjR7#R:?&9GZJg]R.Q0`ʜ/ѓ%Q:4dbd1 XW 9=LRDʦ 5V5G5ª)]4?X#[HW^DtԴ FUKƂD5Υ7x(l0kD11F".+$2d2Sk+O')5\5hBrL*R(_rm}h8xCqzALUX$^ D>=~9Љξp$`6up7W6/x\SmLF;Hq :_H4tLE4sG}2|5cY߫4yNb\Z't(S|Otv1ʮlw 4bIu"~n%O[^WkvVbsG<{$\!duB;l| td!@q:g ;SgE 5%B/inBɍfmbCF*M[dA3Cg}P5⧮2^,׾ H1Eͯen^6%?<9AF+Pm/t V~dkK6jjL.ۧm팯P=1ZmbXš,UQ*rs9Vޱ8/rM# L 20PeuS=zi BU556sZZ]-^BNd5Tp6]u#4leLV@ip* gdGt3ڞC[Q[Ť>g-ld-Ȅsw<@[P' K(cs4(d^BI>LQCA U.St T.˯Ne؀`?*0ŷh An7'JJsf0~dCMk^)O o4T%U&.r!x q򝴷`YOٟW\`FGJ)fy-L)%ɛ/XF|\8|W҅6V\;VkQ H^*УwZ5mH)<:[tFGUκq bO.4SC4 ؊y氵ēSyjBSb OڮqHpdĞQdꪙ$"Aa t3Ù&V}hAlzFu8Whꏀg[W%H(P+ 7ӻYLV( o1 hD' ImSz(^ pb/ӎ n¯dR(4&pRY]%E>kcCו#-1J 3=y v QDL=CN<=xZX:beuJ\nMB' w\5wη֕w Np<]XXC(=i@#>G2Ƴǽr6bq?9Wq*+|ݎ:l|·FF7Wxg|VD|^9[A/.$ض>nUw}o6=Yd  ЬY܍~MePOct3- gJRҰM8+/^Wϱ[}6p4E(u[(FA]{ߗ!핔.165 Md [Mh v!M!ʸʣ3\f ,Ϫ=WΒ-fmZ><.o-W| ;I+XAf.GS*_<{ua"F'8cp˰&Yu@9e[VdbQz:Ew(t2=-W)X9ASn#(nmNCR<;DIWd|G i Y5! `%&2_&\9֝n ${[l5{!ٌj׃%ܤ0 ۹Kc7XLg/76dۀu뢟}7*j.~~ zJyÍĿvc;Fk{2=u v&!-81\-:EBe]U]'9k]wUce^p ˍr5zrNRBZ kf~td5<|C`? pn`{ԯxk]//c"Ub0`-,>\G'MTX)TDjT )HWy!XǢ[o DklqЧqӧO[j!%^9|'V*.n#h,`ܤBG?:¡xBԯ7ӠsoRzg-/ݵ`xD~y3lܢr5_W l%F- <5? J}Ot44TSkN qx7-5[m1-=?M?B*E*T+C(7~|d00iFQQUX}r 4a aGSm$"(咺*ĥ޶cck]o\c_kKs?r5DSc­tb6mBe2MEg KiV+-FA3ľ1*/RK .CréY56^Wzپ!IXl$-cs(Pz`acH ަ ]oK&z"Dň&1?nRw.Btvi̴jiʍ+"4sL TS=ݘZ<2(#,34 M^\u J]S%G7&exJT 4~q8vnO:ZS MCbI5`EԋBԿB+\vB y5oׁevAg˸9_8f?i#F  ȼu y]6f` |P!fE ,$؟5.ZtXɵ͹ {3i7q@kbYN`:h\'ŽKr'Aٯ-BP}7gΛuD *+Ӈ>ǹHiFǨ;W;ߦXnDu>X܈/*MbY!J M[7LXd ij3 = &(Γ^#{k*XG]*bN'5kIc̓[2D;'A\["cy.RŽhF\ M/WU܌|Vė(@/rwmvhT20[LW)y!/!& em#(2-& ٗEn.SJu>5xrZoi$Y pƢ"g e]9%'mգvx$_&XH(WfлvG+,j n&:gqzقAM#t}Z<+Mt  [_V_J~nAk!ȜqӺℋ7WZWe ރbL{^jxF 5]}0%6¢6f;?vD/B*t̃ 2NNlwQ6͠_iՎpV~aQ s1G+p%bs݋j GgF\s踺 i2*y~}bĤ #Do kOt=onpG*On8> F"Epq}SbG#FOoZ1~EB6\α~avpKp f4LĄKn16fȳɒ^ŗK'8Fqӿtemwvۼt{f7alț#Xٹq_P!MAX:&[v?O&&iT(Q;%+GaR=8x@*LC 1/=<>WBP"Kf1tHCbQs{}ֳ~aUU ] ~{H4kCׄ5Jh[ݸ\spF\SK՚NF?Fз ^fw砊EVIt|u~AkjMH-i]Tz ~0<ׄ_X;M?g]]I5X6S/Ez>YY;2M3O3Zm[-hJgCLq)ʇ}zv)-yеԔwo?h(C{qd?fI:ffvmD~c/O4˚hlNjaycP,盧a`9܉n:OL5X䪢,Q>wzڍrf1KRW$"<84(d&qmΜZS6?6ݣ}TOA?'FYu.צjUb* |X]>CMa%`1 K 3AZu֛GzXFW٦* i4Z _!`?Dy59_00vHfmQW3۩cpHw)QI?ʕܭhyA Y<Vqx#z_6'E)H-/vC/imU*EH SuY 1aXs!?hSQ7aY1\v>:%eDKQB uDQ CAdzŒ#BʼOH q/yQ \$䈃] ϲ 7L^_yBMT6+:T*o _V:Vbyp[VJ męGޯ6 Mr}THAqcr3adXtL럿~XוdC6=/Ϊcwk:V!>| ~Τ#y\ɖ>7š3G U8@,$:B)ԅE0/e7:N 2z78Pp|l|?k?avܯA!Y̝p)ܡzH;g2oJۇ]R;R%[ǟ}obѨ Hg֛HT$+;h'Te/UrTQ$ H@N@VL7]%wCdqr-]-ӆm<ť fy|'ȪsjV1@u4DDdQ;\kɤ::e^\0[.i7j%53JRFq(>9Veg9x릏zq@eժeԫj/7nK }50mQ] 'px&x;;h5&wdQw"Iy\\N>w .Q ҄<5mj|p+_"͉n[)#y%k )V@t(L ,Qۄ k(||2ohٷr)+}v^&(؁ [-Eň^xI14RAADDJ/Lmkj{޷Ej/i'!.ޞƀ#ca1Î=:ń".۟h&vIŽWQ)>}4.22$.=SOaɐE)cXA*9(93NoBkQ]l+]f8G|_ZlVg5es+?<]@Ĵ *ˏ@$,{V4#Hu9+*Uya 9&%1Q{N# p@^}FsōK@`( +n; y"u)[LQtIr#V] So6&dME*DY #gZf7BGõl:Dz k *!S=c9%3L.V#G[bE~Q"<1|j [~Tfz}Ȭ qf34=nhqc4a'>j5? ZmXƒ Y5^b%k՟T fWrv-;@`͸KWu1ͭUVum23|s-Pa?M7ww^hr,Duˏ}G뵚_:"tkܽ3#w`DX 2]{w A7OC'aX[/Ze=sMJ8D]a s&M @ ~݅R_?Pק_ʳ^f:R/Z>૝w&j.xb"Y4@sO~3M6CM8>(یg(8Ma댾SD1@uOE#( 2LF]6N,4lPV\J뗌v4jv=L9N >ҷoSD_@]YGcjPI {1ELcPkf0,QmV#.l`F3ϢϺQZnp- 0OS.m$'vMNzP(Ȓ~[Eүlւ1.I9޼"#8S`^*3a L{}]_|=[NP%3Y|h t|ћzЏwp0MMxY$;Oz)Χ:AˇmndR$p\¿q.$aמ`SLZؔ{%[ F3#xn TN\K&&=dZᨨ欁J/]3p=[)0`rqA_wVILrw$+Lv`ߦvӉDoך>9iF Dt'3$i]yw:VթwdFŦcDG]lU'(I˽1f^lcHAu-̛`g InBHe@lhp'EavJI NVeu^2kk\-(#)~dHpYOLnZB||$ԏM]90Éf-UŻ==\"w$a2edDO5b-)ӰTdno5oESڶЊK~kUc@ /MUqa1ll!I 8co)?W >[, TX̯XEѕ`o =q^wi {V^ [K mIOt.ˡ5|VmC`I,eMWdr@f۽&*nrܜIO .S4 .c LBQ¿_;N=n+eҋb Ol<'/oTxdg B2lOLl>G&7N뼙za0Z%={4CPzIsvrC$)|&c)sX'e; 6raЗ,JnEgL]!*8N*hv-؀-BWB]iLi05W5qrZHHk,0\, (H#wEGc^ =a?"1Br ЗXvn-O{@fOuQ J:vj+E/SU;FG9qmA90~57ޙ.QGe;ؘe6 IQW0H/8de-zshc{;'XUnab@>[JlZoɛWgocMh-m9"ЍlgE!m]u1BVʶ-X4*6p[׀@uŻO4`/LAlc8Ѷ~N uӄuMɯ5*%䢅aVB,ដR,ɒJ=eP7tJz摤qI 3oi[/5=hQ@V`M"XD_jGaOޚFH1o iu*Ɣר vg'hIBpՍ31OI4sSB0+k<ʍW]k('NB k`28NNfgtmXbMT梯>#ψJE L9MF $# lP-2mg7E,>˪8+k k[>m_Y=b VbJޱB^ U6zv J4lqPl1[Y"inR~.4[ FU* t Oi1uØE%7$m4rh7ן~ SlbRP5ETrN4tD!^uI})éfL ^ⓕAD aqWj^߷|"uG o\N5g?Xj΂-zr{fn4 FyvPvB~[+aUVxs4Ƿ^XC??,Siw0|Cy3)"s0X=֬&N^3 ak07Ҽ {Dk1-$ƤYKK{LX9$Q蓭1]P,=X< gY;^e xxfG> eK`< '8JH痰^0.n.Nc 3{yQǷYcb<ݟ"Jw\ 7/%BgrN!7狁7<rQ[g WR2fddxwulM~y vјIO?YHJ.'읭5}Q"f'"@ 6Oš"y|6:šc ,s0JH`kSn%B*e,<\ ΣQ {ÉC{C-&nU< YT9K8IxNΦZ>-Na¬,PQ!-L)tXi%lI [icoQW 2 цt0#1*o\o dnډW(oJ!kH o8&NAX2=TZ B4 }nԽ2ͼO,*34^@IA]lnj1V+6ָYc2+O":|lg:L[T w a~p%,zHg~EVx`E6'7gznU{q\f8e_xv|OvK, mVjUֺuhhEIJsP4̶aR IgiҦʶ#BkVۃZDF)U7E9BM n~3R g)TIZvG$v_PL;+zH-# X21eg \ߏ {ԓD+S4!&!K2`K&sEW4xh/mS5 jI~ʂ +,W3w}kZH QN dv#IM=-&|ϒ%:v[t5c6HM#F+a(+":hmUg74 IﶕTFaKɓgPu &f-t%:JcZ8esBK|_ya[=uEN)i #7]f9g8noYJ\WW842ڰ _L RBr,)n_C$Tcٱ=TZ+ L 9SK{=Ͻxky% >T\r2ÛCe5<<ij\vPfr ޷*G*V`'2E,[ l 6_}POm5$ǛfNRS#{+H87™XgByK%7`ڢ<+O/!i0FX޷ƜXX& Oũ螪~&)ڿXjիL5=_Y~JvdLVۈiYedcYf64B:' ҩ!&E\>%zJAo4J-8L~[Zs6ؑ Ro8xH0C ܵXB'D0$"`ln&^}ec"> \zRί\|ЕrRb+(h e6k:~ޢkMnKDqㆭNNz|QX=Jkg|OO5b^,<^Ck.2ޫR1$ N[:J<ܳ`~+&q- { 5UGDg9ccȗ~1`(-,BAf6zkqΔ++c89 r2݊ϮzĨ$\~l:sq yTyjok5fx[ĉ0+먻iz6? Du7D4GFD4= Ub(ߢ9p̓r7ғHH[pR̖ }QmK5֗@z%sI+雷z*(K*wr`uȱض2zp,:߾c NRtq,z$60{)aOi!v3ÃF?2boߪn*`t|lS gdB Ikvkq /qܾ b Y&*dNvNʯrJ$ǑtT$$c*T]Qs"u+MIwW.YI9:J ™ےȹ)J ¿yGj5C$݇FP9XuS pEi* b*XMX])Cb0}YN2!J`T|b!bJܺYǾ›Ntꝵ!%{[$Hg~>N7r1:ٛ6 *)$9+܅ F),v! ʩ~W_#PҟG3-Lﮡ{N:Z]*$׫ 0aq_Rҥ.Jأ Y| Mra+v Ha(KFP8G~}j.Ptkְu153t/D=#j{^RE؁tM-.:aBm: d,ZM=Qѣ(~PX,A۷3zV_4)KQ_֋mi#_#D+ĠF o2I˟:6D endstream endobj 1498 0 obj << /Length1 1647 /Length2 12668 /Length3 0 /Length 13520 /Filter /FlateDecode >> stream xڭwcxnlÊ͎mcb[ctlc۶:۳gϵϙ?sG>^׳*rbezAc[C1[=37@QFΖK^Y ;8YE L&#  lk`afRUR/?OKG 3 llbp27ZX4%Trqg ΆF # 5`hlWi G;#O37# :3``t쁓-hdlWrSۿs԰>)::99X9>*#O'sb;Z|[OMc[#Jt:XN&nN24[8Ytf`wΎ@e@p013p06qttNokۿ3 'GkS8fϘFN,p͋$?1DP&a`l v1:}PXf#W#9/>k1gkk9Ǟ|. sd-k_ 25v][YBh=3?bn& NFS-W8X[M>IFLL[Yb k hmT8ۙ#r%$dgfгp0}^#e ,ZL LL̀~u77@#[Hh9z) 6rvpdmY?_7#[# ˔Tj_c"Z=]vEu*~)[\eU vh);LsIsQ)Z9huSO#=/d6!3m)*BL~ux#u C1JlCA;>H8|"ţ͊%1I<&p[g 艞L$Iybj- Jv[6g5F ~M&6q}s̄A+wW%H5T [@ռGlJi ^^Y#>'sil g3V(Jw;z(Q%;2:#R)#qj.Sark9τFznd9CsceMF;NI Tp;yB/Kztee6,<@;SzV4Xϰnr1pFL)1lX0EDxs`$CXZM8pO1 "o|ܰx8F>Hr'AZkۙó*CIΓZ>{n$)qxu[ABk̀7vSEL uWvx-2_˺"rQM]L5(/jjDēvfNL.sFɿFʦ:!ݳt#jĕ%̝a|n .a$"l& .YtTHcW9)U`sy]d B r7P6eAR}-|#; r[:'4ljY/%f#b@_2j2]磠6d׼w Gtc Ibr,3_"P{oe]|#@aoru `(NVUzNNit↶6bQJ͢5gљˬ"`"$?@u ZfbTXG IvKíNQՉ v {릗d4U(9[A~p,kJxsx.]_f]jpUCpzޔ `m$ U"Yц3 V!|ms+ [r` GҎk=_|$X @ƻshuȲ_e.]EeE>Q755Ps 2o(QʘhAqODElHe id3'KH^Up/"T>!J JB 46:*gq Gk3Ae[vܾل-^U0VcfaU ԱHttɥ,W}>+>XT M}矕N>ZˈXcf\}2G"N @W6}jQm]IŻ,:CTŎ92NsZ44+/\.ela:K2eWӃI)ek7żJEE x~֖7Ddrӌm[8`όYcж$$|!kt,joBW6IC-|why8OGQq)._.LNa?W˗ yUq0)ŻpO8e)U⽋ eqe85¡3ZY3.'wmv,K pAhZZl#ZW[ؓ|#rԉNH9҄NCCO}z|#ǃr1(U;clOoDC<RŝYhx+s58Kd(7˙lIIYo(T q _fDwQ Q?b<سQAj\*m*0"hcne͇kj:pd9OS|ȿ *'p?f Q9Q~7YP缳ZI>|fFEoK%C)pZRRou)[> ) C vGGѰ쑯U/ 5\:±=#h Łb[OH.sOpjnWX#TpHejLɳ1 %xlkb4fX'oCVf61lw]Fp~j3ia"|hxln͈]_Wo 4cXr&ݬc#ͅ0fJsx;6G,FU7725Yt$^oӨ8dEoYqWj9@wơ63$Խy/m׫<ظz۱xJ褳VFvvbȾI_hXC) \cr׊Pjf>.#Z8}^o Ƕ- Lg[5c /qA[rFrcKm6r;NשQ]f醨<#_7g+?PnW?DqwYٷWm!rSׯJQu<˚oIP3jKlc+r0 @g hl4Ģ&{ȹӻQ<-$D@>wX{&S6z:Ze~'qRE)(psqm+N^q*yZΌH2} R0r0UѦ@:@ l=}VM@sE ³WvKGNN< $R[rNdOֆzAFޠUR>טd7bsc8W^;}©{f!"v8N^/, (YVLҐ![3%/(ui)\7B$Ap{[}G1-a* LB#zq7=s=Eng.zʍo[au^R<7.i3_;;c +ַmBYEov;q.9^7Kz.;8)-}b&/lFz.l Ȁs/MޝᤡVa6=X:VDbQ "J{e tUl@@xgE˨h j/&CVkIzg1/LPYx،n[ z{A 0)GVS Jy&9głX9]'Ԓ*w񒖏Rji:R N)Y.H<4QSjz; ]Ԇ+1ֽ򎻦|N>UAGwoCe>a\NBLrZ;JF9 [H7|VSՑp%.&Xp El(x?H*t,Ҹ`0S,·4zK:*6VRX:=074'{^&`2L2QKg$(et?nЄ@W mڣUr=X>ims4!]Z|40y(ԊFW⼙WlZe;G|Qp 9z,5*xd^]`C:4 c)"NIlzPRxT7KD,*Wcx L'!=eJ;}poaVCL;3`/(/j!7ҥ N ̏G!ΰۇwNWMjjC؄s$Te'eɇ7b.P'վpN"ZOYs'D*Q l Dֳ' gyLj*k8WI&`WtђLJ>[T`j'Yyt:܇5 k #Mo A#iBFbhj,$׿q7P |TRGAN!Ђ豤Vhi<7XA3LkUlV%“;-@ZzLi"qy*3tc ޢtðwŲݠAJ9,j Ǹ>y o +_&ǐc e-+ҟ.k"| !CTS̓mTRQ&(5)S-zh]H9^v^DsTR/N^>\¬ !U͖@|ъ$y@~ Z #YDlBӄb3r[fL˲%;ŪP6.rf IiAr X. k-U:Jx)姃vjeZ͕ $2љqA؏'=>x\ [vk V#y6{#/< M5TE?yDh\I}=4*>P2+"G:5nɜߚ~ک.RZַ?vxp)gU X^,jBR|ADL@$ !WU渾=dd! nQXc^BwBŶxN]< 7+yjԧž·.>r5x E;VڛtLp~`Dj}L AgH :J<q{8_7n)W%ZfS,MЛ)x?j19p(Gne4QZ%SʆJf<70ЯI }XHt;A44P=[j 5ֆ&x aSC (-^˨'.)ULs&<+v-Y1 EGe(ti2hmсإT:f."f\LC&هE z IDQ&u; qf:g?O9eY!v`lW9\AӨDNWO*$5IIbt_޲ ZV5bM׭L k,+K{x8_6|%.5kcmue,CApS"fr" o N'FJ(P$ 8+y2̽Ed;ْQ³Zs]jV5ꬒ3l.{D0tii~fcà")_~t[\XO@X'HbFCIHV}4M{X;}?X/H }7z^j4cTJgGL#gq3];)c*{Iy ES9Ƣq} n|%Zs:&EF35k$BXN?9UUԸV;iGzUJݕ2%\M*doFCQSjHѺZO=hs>u,Xq#X)Gp7W@?ub|[>l;P_:uf=w6mJ2SNo5HJ}QMji\LLWdl{X߷|*LfPgW^z?kd ԙ`BR ijԊR-dp]pw԰o2 w8ăK]bJUW0XKx %5ΧkB|J trI"m:B ~kBǫ*VU`M&2i] T?ԎYbF¼Hͽ}N`tjR:3+G fmSY iТ.`OZRs,zg ՔGbT[6"0!o{4SҀ@kdjҲ)[e;C/ +7BL眖02t[Ѡ첿oB4J(L$3l~j D $` }V6%4>G+Ie~it, ٛC2޳;{o>o0`~aNtc'r0BN|%8diRyGʗ{g; E? ! P*:B-9)}5>+:6Sƈpcs18:6_π$۴=J'^]:moYbpAQ/Y&FLK嚕3ZH#E5C"8*mrl=c|~{(O͓ƟDyӷtTv'!`;|`!r9[g̏%vͣq5Oq1|&^m豃Ku6ܔtЀ` ]l[!ۖT؏*=^|>2A?[FhdH'i R83a|I'9;:(Fb.~Ȥ sc E% Jqky^q_o}NwRn rlI貵SNHgZ6t8䡳xb$:œ$BVu i)]čUIʚ1vf(rC :şha$zs<z* d/RRXmx#A^k(Tvُ͕Ug:;$Kɶ"LV/)w1 Y 0_>  (HP|c:(Wi/1vyI]鴧njk]lhG:c_R̖k&qIFnDwҰ(;(J88qo"X݊{kp*y/S0X iGxː/`[8:nbHwW@DLyC/* y_ҡqcFW󫣼##5$F:do4hԤwJzmj];ᤪ@̒Yo x t|=EK`f=ޅ^^n n"IFbBTl:^dyd8IEceHB<9@KQ2kC<2uT]3j/O7Y0yҾ>)Uk VOk %]a*h\ 'c l,W|g8E1eԞwg0G|m)91 I&PįN9*[ r8S+{ }dao 8gY ӛ^|{ qsgN}h`V8Q\|oI(:g7:eaZ\k /P- %}|\ ZuVE"u _.՚^E[EIZ](yY͚ [Fl. ]zgIC£ba: Id`&U|{"YvH4F(k%C%:iHv ] f׶x޳9z5A3nְlYx=b)KOM(^vѡ܃x؍M 1馓Kx^[E:dBD&d6B2FPu Fe,e,V}v}_eb'`IU: qTJ"X$rKF`~ӶTY8ʺtP }K#wZ3P;&"IbE o5qt?Ȼ [5oP=ܨ(RaOxqPǷ nR[}g[SEhUP׳@fFhY ,{{DN F&>#If7n0LFۣQdUUĆT3:i7q'j &LZ +^Ա/d]Z }ito}|@Ug10 aZ9Vp[`d}IiP-I+O>`ǀ Uey Mz ~ kHTW=p.&QEZ8TC 3]!eC 7ݛG9 bSI阌r"|m p D\–|bUowŽ-yW\#'9!"-^(e/!'İ!$ Pëh6$\gڐmGĤ;M*edCW-.<U{zl{h6S'TtVh㏼6SGDGӄUҔvx܍Vnlq+FY7:e*blg:x9"A (ֶ$kٷ[ vܾ\|]?hd&x)+M"4=ØL+$5.O` taEs$;Hk6ڿ=Oώpdb y|7~nUiSng۾zQx0)!BCDa|  3 4̓1hYɋOKuv}DЄlRH%ӻww[cCXzx+I(2uRB0Gj 3$H+=Z's zVnyΊ%]Ciڴ;=2w'f:gkz!\n-v}~ѭBr@{yw]#@:5S}yd@lvY|_ )Eor "z>'nWb1gyw-θP'\љ8jk)&vI7GJŪuͦީxޖ޾NT_JZI3N^h DPm,T,?M (e M>OTtruMYW!ٲ%,64dl}my2W,=x!(~RaC?~ؠ'Q\"ţ(G#H- ɅET wnɔm0P٫:e}Ay>$Z&rgml4!!Z{hs-%_qEȕn5`KNIhnQښl #CtfbF-)DZ,rUqXނ^95*BVD9D`E Z=SVN6vKA}A?B*EMwKCDw2d[wW^Bqj*D9~1KN&] `$ӪZdĢ)B2;Osq/CbѾ?:S4ժ~Ktj//?&(e4ۉi43(mp!aܙ;hèfA!xe$4=I@ kS=.:YI}aduj1 X`a`1Q/혘y+8ewA}z `践=s!uS3Q,֌IR\h5&/D U70\H6;M 3yʌ.Eݦ:ΣNT#$^h'2eM2@w&^V )况b 1N- R$Yt'~v60?xվV/:ęL* 6ai0CS-Uå^9R#Ua H?\fnND 0l^Ĝ'$OE?cOLuuPQ<1R|A4o=a8GRWlY;~Qi^}޻p9.iH%M/ ҵlڄ0)| :uS/>i e|Muj+Mz..H>]UyR&v-/KReĹeoƬ/—zLs'U0/ŝ;Y v'DXS`ߦ̂iArYj b{ck+e{DaRMgo@ ĩlqs'xA2T_~P]DZT~BOcÉYŻ#8QV.B,D|sK>.+JNtSC$#k쇚zofMo(j"D96_pTd[t 0~NCy)8KK(>'9J)y.SoLirS^1k>eTn-Siib<{{ѝ5ћf8i+HmPm OUĞ endstream endobj 1424 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 4683 /Filter /FlateDecode >> stream x\YsF~ׯǙJoU(qby8v`7p8; 4P",90gg Jꠘ`RajXcVjx朤F`>ΑEE#S dhQEMp!LzZ$ 2!LODFtԒLYRD{) A Lz1-}юZi"ZR0A(sHEfA44%- 4t̘F8F xG)<A3QS*f4Gd6(ˬ%;zlT4 K#kJВ (K@bm29b JA2VבJ3yg_{O B%= " }b\#$B(4TB'Ot:J"ɘH h*Ċ'RSҪօn`:I6'/_9kaB6ܼKd1FDC4." Q'ݐ@ "!EH5Cu)%<ϫl:gtx2⭀s?~+QW-na4NBno?c9߮Fea?q`e  u; +n i.$P *,h{h0Ѡ}0, \ T=`]crE$BAБܓ 7 w`MH5$ ]Z%FB7ibRP#Y 垈pvGGQ {P@]LmKT"Rpڈa5/""!=i2 ͝ӈD ]M@Fj?h $)v$NA '@.BQpRA89$XH/i&l52Jv-(GɑlFA>li0B4r HK x'$I~_4$ЊWca {TAC"B#W*ŔB ʣQņFiODAR5SAōBB h6a?9%NT/SEzG|} EFDTQ)249!!rH9qC*SIu6O 'rxPȆT~Re4A Єå>nI Z>qKz{$L>FNFHH2)9Q-/3d ℡¤[,Az=D Jl"6aOy~ LZm zXxt!{+_07,@f]w2x':NhEwuA> wuFCgٌ?{xӊJ;ǘybx9_/Z.MNh%Y TZ)h>-0U$%O+DVZ.7|nȝ *7tn#<#<#<#<#<#<#<#jw NFhG0VdQ8<}%ɬ7)j|إo z i-qYyɌ M2T󐈀GW#4` :IB a??6bځjR,Ӕ}lU ZQ:LSjIoD\ UG ԠQ]4Τ)Q\bd= WFϞe{з?X5@0GDZ6g)GoWLkQ#?ߟLHY δ A' t@ki~~2ݷtݿ=SLMA/%ݟv+ =x:y hMw/}TKjKyk?͉4CO4m9#CcGE/Cp 5H:K/+&}gSԏ^K>Q4teit~ɼ?A4'i4M6gMdC51.bZ5kزV^hMM.v}v'{v}BC\ݯyn.LDo+Ⱦ3BtnDC3~}dnjmv?ߟ[w6䩯Ss[]I,2&51z-Ptch^ MjB[+8.m\'Bf7c智ĶV,Yn}6EJlgYS:;H>Ǜ"zW隒Emf=*=QYAFu^Dzö}4j2uR>jh",Cah>jlqjHou7YpgmYͥ΂e؈~fRn$LsQɎnWY{ni뼵]7^?׶ߔlW⍭`֞hA*אnȩGm6p'mu{ҽVwW^^RAle>V |=~6 t{ƻp՚jוTxm-#}I NS`eʟى &865b~]kWbr/'K|7>_LGKfGZ)L ^rLǣG\}i/Fpv1-q7V+怿2Zbu_З9qi|7񋗯_wq"{RBn8_ƙ;9ez4嗓zś o?ˏ9=;:xѴ͸- o˘-l?/-]z/=̖hҙvdm4J.)t3o2mGWb9b4\MN(c>_^9/~? ?|V+~E/kSzOwz*O/9k'ܒjT^rt|IQg! Wa_"Uq x*O靀O1?rQ.'Yg%W4S 2j:nT5Z'd1^_VdzVM(p9-?H,Vާ_Q|: %/+ʋ|Ε͗%ao> \\%X#|c9&`{$8&@Ӭh|' eUy#~ؑ3e`\MWHV0!tY^N*,?@rWv?.ʲF"j|QftyAu<9}\@N%q;{' \vvNa:`oDj! pxK)8zٓ*ةݾUeߊJ"Tv rۀ;&Zm9o]Uh}S wKYNk2!H_+U)}UHr 3>m~dr~<?8OwHkH B'F7RH)HC ȍV]<:M92@ s~;Ͼ6/ʋ.,!$ՏYjeaeX`8J_qd-\wNoCQ *"=k!D'g\_>7;tY2k݂.7LEvWT|;HR\rbzrI@Wʶ]x'}-mXKڪB-:ڲg--ʆ>LOɭ3[VqiWV_6710c4uʾnN&QE_Ozv`O(ӍW$`s]ek*T#_G-`^myMsRYr?v|goUzʴΰ``:alפV '>*$n*SIfe%W֓M$csRm gQ͚Eݱl˶ܘD7^>[D*,0vA7.m/ƔqgʪeۅW]@ؔ)aj/);~S)]~ !:> stream xڭ[[Ʊ~_, G}a'%YAk,`[ +ӜG`YU_ݫ;=4I0QφNMQSNZ)7q 7xb4_i'6*cox"qz"G)P&K"^ƂP·D<"R<2Š&SdT0@_  qÀ q ddW:7[LEpba#ɝb%wn AmEu1(-^2NZU ^v /{ 6 .D+F,+AY, J`9;-G{+L3`ag`?9#s@y5Dj8[&VxH]O!,4O-ApDw;)/w0Zh2b0S,H!*$"GwIk{W<H$r+]HVdSH%$2J16n7WգQ{գy(գݍL(_gɋku^owo"|5=ww_Nxw?ϟ}ًVFM<׷$*/^~P*52KgLo:T>~T铿=jC5U4:|}TӿhlAN} T_=yZl#T5;TUw_>ɋdlgе>{z?߿{ǟ7?,덣@ 8|8gy\p|{=9? Sp_ܽyv> on/z/Oϟܼ;KH.'-=93Ч/<DL٫n]=*o٫7[&Ʌ) ?b^oW2jBBW&kм1_LFb_8ZkE.1> *X2lO[`)Ld*[f62*Vf~s7nB]}݇vB&$l׸]7M` [tZ&Y(+ŏ750~z%LXXǛxKFCޒ7WaRNJlQ-q+5 Qf/jFlӲ7X=0vpsI]0:Í;lv|f/Ɔ-1q R+si6\=ɤeoE:-z(ؖB/o#lRϛGK~3~X7[;\>wJn7{Duefg6Fx3فzeFzDMGb N"ho1FeXǹF}⇃U髏~A~P~k!QG˫whotzo:s*]VU灮|ot(G['|a>N|C6+^=l@{ViýɃR.b97;F;7@q!{_/LT O(2UߛŇl764^`l't?6U{:vj/xJGHģzlflr`c4Cz׳C iK;6ؓk4NOبvb'=nv (K9н#v-p8փ9j&i?bAf݋~>mwqWhO_rQ͏{z:xCT$ cUFnRZ9bS5,jٛK]A4W[ M#].:p=-_nN@iqRiMGUU Tf-9좚'[S.ZBnf"8 YrM_/c폫㐲7>%OR5)kk"`jU z]OkBͰKmAJ Ce5KלgcciVռT^7Ιj ֝iu)L4$ssZM/Рڵ@R,_S :JLg,)T r^rUh م1ICOǚ7EHU{.mZҨ6J+ ԟp[xj2[q6Z:TKa҉"0c FI6>E/j2x~z)mҸܤ9+t(=̞E5iVgDogzbKC0~^H3CUcX`Tts6jLl?mƢ<L2p}+s08 }C]t BG;k[D2zs63C3zs¤Uv!"R.{t03,#uUGfUF䛜v=)`БDKSRsS0A:;95V8T' 5lDoc2u;z9)4Z Sz%v<+fCP* tlUQGOchY'"ZL#Ǫl}4Y.&RRvc"Efb\:|"8Up-1 FL MڙEsPTUhF!Pqqhgiژ}\Rbta!l1FTb$ 0 ֈ>8^R r1bB&Зv"NfCR5E2f+K 3f#H,C{+ \1˦fO2x3ZZWm@eH}pʾ^RAgɩHNJcE~Ƒ7 F%@>+Z+*t3&b 'v'SbE;t!Z%O endstream endobj 1606 0 obj << /Author(Frank L\374beck ; Max Neunh\366ffer)/Title(GAPDoc)/Subject()/Creator(LaTeX with hyperref package / GAPDoc)/Producer(pdfTeX-1.40.12)/Keywords() /CreationDate (D:20120223160817+01'00') /ModDate (D:20120223160817+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011) kpathsea version 6.0.1) >> endobj 1533 0 obj << /Type /ObjStm /N 73 /First 745 /Length 3678 /Filter /FlateDecode >> stream xڕ[)1c`GW`s[뵍ab$D2[yԗ>ˀ" YdwcBh!*)ڠAD{h?cڤ c1VpLCa !:. -:BVDW?18hsb,Q91Yb:"aneRg4$_m?I%C7R?$&hKP+!G% JhiR, %xBRPJXrCaXy_eaE7a>JPee0303jK-A$|p pVW+pj^*kXgsI`#WR]G/qAZmOuLJ"pt! pgW;(7jz}Ϛj_$҂kMUro;HR)-D|߽i} ӵ\n8x姁/FN7SS_h5(2>!fqx.FN5-ԧ4rOCJ3qws4_ o~ww7Go6w] ̹U'dy$1>?40ύ4YcZs>s|!2ނSq9˘Dj0Xoѓ?zbu-03`6 oW<7t 2^iLZGRŝtIMYFMϴrdzƥ|l<_o6=''Kt\/ZbGtu4OVQ E빺Vi%G_s>4Yό .Yo7GێN>2]oI xճJ[J'z!Ox_=kO3k6>Lg]pqRtZ4~vƞ5nѻϯ9L+L I)N>H= a:f{Bgy,dՅ K$4P3I@7 mBGIP}TlݲNi0p$ZSbukY|k00G D4"[؎Bx'bmW:PÓ<`#XJQs@`꽗mX; B=e&0_P1\쒼i=iǬŎMY$)jtJY؅5`{};f% NYQ E9-FµR{Vp+?j:_M"kjEe.P6dUD'E,$= >fȼ zcGS ,u"g{=s I?3 Px(}2Be';j+k'@<\%r}L{G ^*ZB"֒ށ S$i),Jp- *ħן>z$;x;nle[w>{MkY]_ka}X F!&6UynǢϱ>FB\ZGfZ k-ĵ+XXt>0׵ulõde]k!n93z2LOλ&gL/~==NYR[!_KkiR,zZM^zTR`+چ>٢˚rx|X6c`;Xw_W:vY`0lNaG^(+r<3:V<<:{n TQNM|V%o0n;H"xf!׹(x6 q!mn>{MI JgO^r LېuҠVВTͰS* ,>^^aۅpUZXJF\r;$SU_ ]&c=*xqLqžiMl9Xo>*ڸccMSi9غRll]g1nJMK,M*2l[ >BB3UpwsiV󯣝Ź[Ź0w+i~tҍ.ҍ.=tb<}Y{PHݤ3|sxLQwC#K.ثٽw]~Elp pw{%1鹑n| Ƌ([)_?5Q g~ .}|ޞ_>o~M@w(7Qһ`?~k|_>}~_6~_[A[bm%mʵUUjEmIaR1   ƍƍƍ)5MMMMSNkR7777777777TSfpsfpsfpsfpspKpKpKpKpKp˴Bnninini\%pq \j\%piAu 5.KKR2ܸ .7.ˍr2ܸ .7.ˍwm\Wpq\i\WWpq\i\WWjԲF+SptvZ ] /Length 3798 /Filter /FlateDecode >> stream x%{l]8v'qvby9qljID J趂-Bjh"TUPAB]nAJH+#DBS. h+.?}fl$Gi%[&?Iu*MZ K.CI66Nl -#b(nۚ$vveb;NbWݠvF:nӌĮQ D*Ž`ĮPĦ(.LjVb#t G1b.QNHq'8NMlI0L.)l* πt)siR?OlpUb(ub:L'o^U$v.1N$󞦨"6ALξJl0E%yӭ*戝(An[&n\m;NQb6^(bI}<8`<chIH]s :@ 3 Z3:LW*WbTK9X//+qh4 #cUo(clUVj'`TcJd͒qTc:W,Tcܹ.TT"yYHwUtpH}%y%T+DCb\V ?*0B%VREvݒae2* +lZPݶMarUxUaSSλC K*,6$/YZF i*^S9}@ jZ@+h@3k%_ 4+oÒYU:A v=NA8#(8΂SגX9~0!phRd:d~A;F9Ӗ|8. pY[< iK~堪 `O%_a}m>9SU 9xA9;f{: -rȑ!'3T}9ZhE9ZxA9 sf_Ґ"rI1J[A@Jeɵ.gq(ǡ2b~W'«=j-A/* L#)#0e -f)K3HİngK"4G"W@\6Jl AJ̾55`Xa%U`j r>ūWsIoN2Gz L- 8p( M`. "`IhCqp-ܧU$} 'O/;[5R7Z;lXK1ukΖ ,}CE5K?=b+h` L(v-ұ`=`7>exMGA8 Y:#c` 8 ΀`蕛aK(=x. KWN$[,}v\ 0 n@Uf=a?oQG XL % Va` <%xE{]$L,J m1[upčҏgТDėw^,)E(PbDIw$>˴TߺQQ"C %2P(ѧT"HɂKyL `I%2PhEk-Z\j /_엤$UK+js%2ZBbR>QbD=Kj#JMEZ#J(1DJ(Q$% MU  V958NaՎ~B ?ts`E0buX82.Ym<@f׭v秵 xvd68 =9ʬ xUڇR@Bf(vY;ɑۿHX a1f\)W^zVZZd=c&,ZU W!x0 4+*2XV*xЧr 33V3{roP%c7c7xv3<.N znXKY/82dpޞ d8NV2d,fgL-Ŭt~s`#b|q;Ngӌ2[Lǃ/0 `ʞ3O6 VQ({ V޳E<% sI x͞ulH ;wdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gwdߑ}Gw)V?F1h- }rm#F8p0a#G-Z8ph¡C WF/X}媶S-m=\֒1m-[ikZ{W[6Zznm_ֺm^XamymmZ5[5C_ɸeq[ nϣVCE7 99IТ7 lol ls#G(Q>|D#G(Q>|D#G(Q>|D#G(Q>F"]HE.|d‹("# "zD#GD="zD#GD="zD#GD="zD#RGHZk& endstream endobj startxref 546802 %%EOF GAPDoc-1.5.1/doc/chap4.html0000644000175000017500000002627312026346063013647 0ustar billbill GAP (GAPDoc) - Chapter 4: Distributing a Document into Several Files

4 Distributing a Document into Several Files

In GAPDoc there are facilities to distribute a single document over several files. This is for example interesting, if one wants to store the documentation of some code in the same file as the code itself. Or, if one just wants to store chapters of a document in separate files. There is a set of conventions how this is done and some tools to collect the text for further processing.

The technique can also be used to distribute and collect other types of documents into respectively from several files (e.g., source code, examples).

4.1 The Conventions

In this description we use the string GAPDoc for marking pieces of a document to collect.

Pieces of documentation that shall be incorporated into another document are marked as follows:

##  <#GAPDoc Label="MyPiece">
##  <E>This</E> is the piece.
##  The hash characters are removed.
##  <#/GAPDoc>

This piece is then included into another file by a statement like: <#Include Label="MyPiece"> Here are the exact rules, how pieces are gathered:

  • All lines up to a line containing the character sequence "<#GAPDoc Label="" (exactly one space character) are ignored. The characters on the same line before this sequence are stored as "prefix". The characters after the sequence up to the next double quotes character are stored as "label". All other characters in the line are ignored.

  • The following lines up to a line containing the character sequence "<#/GAPDoc>" are stored under the label. These lines are processed as follows: The longest possible substring from the beginning of the line that equals the corresponding substring of the prefix is removed.

Having stored a list of labels and pieces of text gathered as above this can be used as follows.

  • In GAPDoc documentation files all statements of the form "<#Include Label="Key">" are replaced by the sequence of lines stored under the label Key.

  • Additionally, every occurrence of a statement of the form "<#Include SYSTEM "Filename">" is replaced by the whole file stored under the name Filename in the file system.

  • These substitutions are done recursively (although one should probably avoid to use this extensively).

Here is another example:

# # <#GAPDoc Label="AnotherPiece">  some characters
# # This text is not indented.
#  This text is indented by one blank.
#Not indented.
#<#/GAPDoc>

replaces <#Include Label="AnotherPiece"> by

This text is not indented.
 This text is indented by one blank. 
Not indented.

Since these rules are very simple it is quite easy to write a program in almost any programming language which does this gathering of text pieces and the substitutions. In GAPDoc there is the GAP function ComposedDocument (4.2-1) which does this.

Note that the XML-tag-like markup we have used here is not a legal XML markup, since the hash character is not allowed in element names. The mechanism described here is a preprocessing step which composes a document.

4.2 A Tool for Collecting a Document

4.2-1 ComposedDocument
‣ ComposedDocument( tagname, path, main, source[, info] )( function )
‣ ComposedXMLString( path, main, source[, info] )( function )

Returns: a document as string, or a list with this string and information about the source positions

The argument tagname is the string used for the pseudo elements which mark the pieces of a document to collect. (In 4.1 we used GAPDoc as tagname. The second function ComposedXMLString( ... ) is an abbreviation for ComposedDocument("GAPDoc", ... ).

The argument path must be a path to some directory (as string or directory object), main the name of a file in this directory and source a list of file names, all of these relative to path. The document is constructed via the mechanism described in Section 4.1.

First the files given in source are scanned for chunks of the document marked by <#tagname Label="..."> and </#tagname> pairs. Then the file main is read and all <#Include ... >-tags are substituted recursively by other files or chunks of documentation found in the first step, respectively. If the optional argument info is given and set to true this function returns a list [str, origin], where str is a string containing the composed document and origin is a sorted list of entries of the form [pos, filename, line]. Here pos runs through all character positions of starting lines or text pieces from different files in str. The filename and line describe the origin of this part of the collected document. Without the fourth argument only the string str is returned.

gap> doc := ComposedDocument("GAPDoc", "/my/dir", "manual.xml", 
> ["../lib/func.gd", "../lib/func.gi"], true);;

4.2-2 OriginalPositionDocument
‣ OriginalPositionDocument( srcinfo, pos )( function )

Returns: A pair [filename, linenumber].

Here srcinfo must be a data structure as returned as second entry by ComposedDocument (4.2-1) called with info=true. It returns for a given position pos in the composed document the file name and line number from which that text was collected.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/enter.xml0000644000175000017500000003673412026346063013624 0ustar billbill How To Type a &GAPDoc; Document In this chapter we give a more formal description of what you need to start to type documentation in &GAPDoc; XML format. Many details were already explained by example in Section  of the introduction.

We do not answer the question How to write a &GAPDoc; document? in this chapter. You can (hopefully) find an answer to this question by studying the example in the introduction, see , and learning about more details in the reference Chapter .

The definite source for all details of the official XML standard with useful annotations is:

http://www.xml.com/axml/axml.html

Although this document must be quite technical, it is surprisingly well readable.

General XML Syntax We will now discuss the pieces of text which can occur in a general XML document. We start with those pieces which do not contribute to the actual content of the document. Head of XML Document Each XML document should have a head which states that it is an XML document in some encoding and which XML-defined language is used. In case of a &GAPDoc; document this should always look as in the following example. ]]> See  for a remark on the encoding statement.

(There may be local entity definitions inside the DOCTYPE statement, see Subsection  below.) Comments A comment in XML starts with the character sequence <!-- and ends with the sequence -->. Between these sequences there must not be two adjacent dashes --. Processing Instructions A processing instruction in XML starts with the character sequence <? followed by a name (xml is only allowed at the very beginning of the document to declare it being an XML document, see ). After that any characters may follow, except that the ending sequence ?> must not occur within the processing instruction.  

And now we turn to those parts of the document which contribute to its actual content. Names in XML and Whitespace A name in XML (used for element and attribute identifiers, see below) must start with a letter (in the encoding of the document) or with a colon : or underscore _ character. The following characters may also be digits, dots . or dashes -.

This is a simplified description of the rules in the standard, which are concerned with lots of unicode ranges to specify what a letter is.

Sequences only consisting of the following characters are considered as whitespace: blanks, tabs, carriage return characters and new line characters. Elements The actual content of an XML document consists of elements. An element has some content with a leading start tag () and a trailing end tag (). The content can contain further elements but they must be properly nested. One can define elements whose content is always empty, those elements can also be entered with a single combined tag (). Start Tags A start-tag consists of a less-than-character < directly followed (without whitespace) by an element name (see ), optional attributes, optional whitespace, and a greater-than-character >.

An attribute consists of some whitespace and then its name followed by an equal sign = which is optionally enclosed by whitespace, and the attribute value, which is enclosed either in single or double quotes. The attribute value may not contain the type of quote used as a delimiter or the character <, the character & may only appear to start an entity, see . We describe in  how to enter special characters in attribute values.

Note especially that no whitespace is allowed between the starting < character and the element name. The quotes around an attribute value cannot be omitted. The names of elements and attributes are case sensitive. End Tags An end tag consists of the two characters </ directly followed by the element name, optional whitespace and a greater-than-character >. Combined Tags for Empty Elements Elements which always have empty content can be written with a single tag. This looks like a start tag (see ) except that the trailing greater-than-character > is substituted by the two character sequence />. Entities An entity in XML is a macro for some substitution text. There are two types of entities.

A character entity can be used to specify characters in the encoding of the document (can be useful for entering non-ASCII characters which you cannot manage to type in directly). They are entered with a sequence &#, directly followed by either some decimal digits or an x and some hexadecimal digits, directly followed by a semicolon ;. Using such a character entity is just equivalent to typing the corresponding character directly.

Then there are references to named entities. They are entered with an ampersand character & directly followed by a name which is directly followed by a semicolon ;. Such entities must be declared somewhere by giving a substitution text. This text is included in the document and the document is parsed again afterwards. The exact rules are a bit subtle but you probably want to use this only in simple cases. Predefined entities for &GAPDoc; are described in and .

Special Characters in XML We have seen that the less-than-character < and the ampersand character & start a tag or entity reference in XML. To get these characters into the document text one has to use entity references, namely &lt; to get < and &amp; to get &. Furthermore &gt; must be used to get > when the string ]]> appears in element content (and not as delimiter of a CDATA section explained below).

Another possibility is to use a CDATA statement explained in . Rules for Attribute Values Attribute values can contain entities which are substituted recursively. But except for the entities &lt; or a character entity it is not allowed that a < character is introduced by the substitution (there is no XML parsing for evaluating the attribute value, just entity substitutions). CDATA Pieces of text which contain many characters which can be misinterpreted as markup can be enclosed by the character sequences and ]]>. Everything between these sequences is considered as content of the document and is not further interpreted as XML text. All the rules explained so far in this section do not apply to such a part of the document. The only document content which cannot be entered directly inside a CDATA statement is the sequence ]]>. This can be entered as ]]&gt; outside the CDATA statement.

A nesting of tags like ]]> is not allowed.
Encoding of an XML Document We suggest to use the UTF-8 encoding for writing &GAPDoc; XML documents. But the tools described in Chapter also work with ASCII or the various ISO-8859-X encodings (ISO-8859-1 is also called latin1 and covers most special characters for western European languages). Well Formed and Valid XML Documents We want to mention two further important words which are often used in the context of XML documents. A piece of text becomes a well formed XML document if all the formal rules described in this section are fulfilled.

But this says nothing about the content of the document. To give this content a meaning one needs a declaration of the element and corresponding attribute names as well as of named entities which are allowed. Furthermore there may be restrictions how such elements can be nested. This definition of an XML based markup language is done in a document type definition. An XML document which contains only elements and entities declared in such a document type definition and obeys the rules given there is called valid (with respect to this document type definition).

The main file of the &GAPDoc; package is gapdoc.dtd. This contains such a definition of a markup language. We are not going to explain the formal syntax rules for document type definitions in this section. But in Chapter  we will explain enough about it to understand the file gapdoc.dtd and so the markup language defined there.

Entering &GAPDoc; Documents Here are some additional rules for writing &GAPDoc; XML documents. Other special characters As &GAPDoc; documents are used to produce &LaTeX; and HTML documents, the question arises how to deal with characters with a special meaning for other applications (for example &, #, $, %, ~, \, {, }, _, ^,   (this is a non-breakable space, ~ in &LaTeX;) have a special meaning for &LaTeX; and &, <, > have a special meaning for HTML (and XML). In &GAPDoc; you can usually just type these characters directly, it is the task of the converter programs which translate to some output format to take care of such special characters. The exceptions to this simple rule are: & and < must be entered as &amp; and &lt; as explained in . The content of the &GAPDoc; elements <M>, <Math> and <Display> is &LaTeX; code, see . The content of an <Alt> element with Only attribute contains code for the specified output type, see . Remark: In former versions of &GAPDoc; one had to use particular entities for all the special characters mentioned above (&tamp;, &hash;, &dollar;, &percent;, &tilde;, &bslash;, &obrace;, &cbrace;, &uscore;, &circum;, &tlt;, &tgt;). These are no longer needed, but they are still defined for backwards compatibility with older &GAPDoc; documents. Mathematical Formulae Mathematical formulae in &GAPDoc; are typed as in &LaTeX;. They must be the content of one of three types of &GAPDoc; elements concerned with mathematical formulae: Math, Display, and M (see Sections  and  for more details). The first two correspond to &LaTeX;'s math mode and display math mode. The last one is a special form of the Math element type, that imposes certain restrictions on the content. On the other hand the content of an M element is processed in a well defined way for text terminal or HTML output. The Display element also has an attribute such that its content is processed as in M elements.

Note that the content of these element is &LaTeX; code, but the special characters < and & for XML must be entered via the entities described in  or by using a CDATA statement, see .

More Entities In &GAPDoc; there are some more predefined entities: &GAP; &GAP; &GAPDoc; &GAPDoc; &TeX; &TeX; &LaTeX; &LaTeX; &BibTeX; &BibTeX; &MeatAxe; &MeatAxe; &XGAP; &XGAP; &copyright; ©right; &nbsp;   &ndash;
Predefined Entities in the &GAPDoc; system
Here &nbsp; is a non-breakable space character.

Additional entities are defined for some mathematical symbols, see for more details.

One can define further local entities right inside the head (see ) of a &GAPDoc; XML document as in the following example.

text possibly with markup"> ]>]]> These additional definitions go into the <!DOCTYPE tag in square brackets. Such new entities are used like this: &MyEntity;

GAPDoc-1.5.1/doc/refdtd.xml0000644000175000017500000020374512026346063013755 0ustar billbill The Document Type Definition In this chapter we first explain what a document type definition is and then describe gapdoc.dtd in detail. That file together with the current chapter define how a &GAPDoc; document has to look like. It can be found in the main directory of the &GAPDoc; package and it is reproduced in Appendix .

We do not give many examples in this chapter which is more intended as a formal reference for all &GAPDoc; elements. Instead we provide an extra document with book name GAPDocExample (also accessible from the &GAP; online help). This uses all the constructs introduced in this chapter and you can easily compare the source code and how it looks like in the different output formats. Furthermore recall that many basic things about XML markup were already explained by example in the introductory chapter .

What is a DTD? A document type definition (DTD) is a formal declaration of how an XML document has to be structured. It is itself structured such that programs that handle documents can read it and treat the documents accordingly. There are for example parsers and validity checkers that use the DTD to validate an XML document, see .

The main thing a DTD does is to specify which elements may occur in documents of a certain document type, how they can be nested, and what attributes they can or must have. So, for each element there is a rule.

Note that a DTD can not ensure that a document which is valid also makes sense to the converters! It only says something about the formal structure of the document.

For the remaining part of this chapter we have divided the elements of &GAPDoc; documents into several subsets, each of which will be discussed in one of the next sections.

See the following three subsections to learn by example, how a DTD works. We do not want to be too formal here, but just enable the reader to understand the declarations in gapdoc.dtd. For precise descriptions of the syntax of DTD's see again the official standard in:

  http://www.xml.com/axml/axml.html

Overall Document Structure A &GAPDoc; document contains on its top level exactly one element with name Book. This element is declared in the DTD as follows: <Book> Book ]]> After the keyword ELEMENT and the name Book there is a list in parentheses. This is a comma separated list of names of elements which can occur (in the given order) in the content of a Book element. Each name in such a list can be followed by one of the characters ?, * or +, meaning that the corresponding element can occur zero or one time, an arbitrary number of times, or at least once, respectively. Without such an extra character the corresponding element must occur exactly once. Instead of one name in this list there can also be a list of elements names separated by | characters, this denotes any element with one of the names (i.e., | means or).

So, the Book element must contain first a TitlePage element, then an optional TableOfContents element, then a Body element, then zero or more elements of type Appendix, then an optional Bibliography element, and finally an optional element of type TheIndex.

Note that only these elements are allowed in the content of the Book element. No other elements or text is allowed in between. An exception of this is that there may be whitespace between the end tag of one and the start tag of the next element - this should be ignored when the document is processed to some output format. An element like this is called an element with element content.

The second declaration starts with the keyword ATTLIST and the element name Book. After that there is a triple of whitespace separated parameters (in general an arbitrary number of such triples, one for each allowed attribute name). The first (Name) is the name of an attribute for a Book element. The second (CDATA) is always the same for all of our declarations, it means that the value of the attribute consists of character data. The third parameter #REQUIRED means that this attribute must be specified with any Book element. Later we will also see optional attributes which are declared as #IMPLIED. <TitlePage> TitlePage

]]> Within this element information for the title page is collected. Note that more than one author can be specified. The elements must appear in this order because there is no sensible way to specify in a DTD something like the following elements may occur in any order but each exactly once.

Before going on with the other elements inside the Book element we explain the elements for the title page. <Title> Title

]]> Here is the last construct you need to understand for reading gapdoc.dtd. The expression %Text; is a so-called parameter entity. It is something like a macro within the DTD. It is defined as follows:
<Version> Version ]]> Note that the version can only contain character data and no further markup elements (except for Alt, which is necessary to resolve the entities described in ). The converters will not put the word Version in front of the text in this element. <TitleComment> TitleComment ]]> Sometimes a title and subtitle are not sufficient to give a rough idea about the content of a package. In this case use this optional element to specify an additional text for the front page of the book. This text should be short, use the Abstract element (see ) for longer explanations. <Author> Author ]]> As noted in the comment there may be more than one element of this type. This element should contain the name of an author and probably an Email-address and/or WWW-Homepage element for this author, see  and . You can also specify an individual postal address here, instead of using the Address element described below, see . <Date> Date ]]> Only character data is allowed in this element which gives a date for the document. No automatic formatting is done. <Address> Address ]]> This optional element can be used to specify a postal address of the author or the authors. If there are several authors with different addresses then put the Address elements inside the Author elements.

Use the Br element (see ) to mark the line breaks in the usual formatting of the address on a letter.

Note that often it is not necessary to use this element because a postal address is easy to find via a link to a personal web page. <Abstract> Abstract

]]> This element contains an abstract of the whole book.
<Copyright> Copyright ]]> This element is used for the copyright notice. Note the &copyright; entity as described in section . <Acknowledgements> Acknowledgements ]]> This element contains the acknowledgements. <Colophon> Colophon ]]> The colophon page is used to say something about the history of a document. <TableOfContents> TableOfContents ]]> This element may occur in the Book element after the TitlePage element. If it is present, a table of contents is generated and inserted into the document. Note that because this element is declared to be EMPTY one can use the abbreviation ]]> to denote this empty element. <Bibliography> Bibliography ]]> This element may occur in the Book element after the last Appendix element. If it is present, a bibliography section is generated and inserted into the document. The attribute Databases must be specified, the names of several data files can be specified, separated by commas.

Two kinds of files can be specified in Databases: The first are &BibTeX; files as defined in . Such files must have a name with extension .bib, and in Databases the name must be given without this extension. The second are files in BibXMLext format as defined in Section . These files must have an extension .xml and in Databases the full name must be specified.

We suggest to use the BibXMLext format because it allows to produce potentially nicer bibliography entries in text and HTML documents.

A bibliography style may be specified with the Style attribute. The optional Style attribute (for &LaTeX; output of the document) must also be specified without the .bst extension (the default is alpha). See also section for a description of the Cite element which is used to include bibliography references into the text.

<TheIndex> TheIndex

]]> This element may occur in the Book element after the Bibliography element. If it is present, an index is generated and inserted into the document. There are elements in &GAPDoc; which implicitly generate index entries (e.g., Func ()) and there is an element Index () for explicitly adding index entries.
Sectioning Elements A &GAPDoc; book is divided into chapters, sections, and subsections. The idea is of course, that a chapter consists of sections, which in turn consist of subsections. However for the sake of flexibility, the rules are not too restrictive. Firstly, text is allowed everywhere in the body of the document (and not only within sections). Secondly, the chapter level may be omitted. The exact rules are described below.

Appendices are a flavor of chapters, occurring after all regular chapters. There is a special type of subsection called ManSection. This is a subsection devoted to the description of a function, operation or variable. It is analogous to a manpage in the UNIX environment. Usually each function, operation, method, and so on should have its own ManSection.

Cross referencing is done on the level of Subsections, respectively ManSections. The topics in &GAP;'s online help are also pointing to subsections. So, they should not be too long.

We start our description of the sectioning elements top-down: <Body> Body The Body element marks the main part of the document. It must occur after the TableOfContents element. There is a big difference between inside and outside of this element: Whereas regular text is allowed nearly everywhere in the Body element and its subelements, this is not true for the outside. This has also implications on the handling of whitespace. Outside superfluous whitespace is usually ignored when it occurs between elements. Inside of the Body element whitespace matters because character data is allowed nearly everywhere. Here is the definition in the DTD:

]]> The fact that Chapter and Section elements are allowed here leads to the possibility to omit the chapter level entirely in the document. For a description of %Text; see .

(Remark: The purpose of this element is to make sure that a valid &GAPDoc; document has a correct overall structure, which is only possible when the top element Book has element content.) <Chapter> Chapter

]]> A Chapter element can have a Label attribute, such that this chapter can be referenced later on with a Ref element (see section ). Note that you have to specify a label to reference the chapter as there is no automatic labelling!

Chapter elements can contain text (for a description of %Text; see ), Section elements, and Heading elements.

The following additional rule cannot be stated in the DTD because we want a Chapter element to have mixed content. There must be exactly one Heading element in the Chapter element, containing the heading of the chapter. Here is its definition: <Heading> Heading

]]> This element is used for headings in Chapter, Section, Subsection, and Appendix elements. It may only contain %InnerText; (for a description see ).

Each of the mentioned sectioning elements must contain exactly one direct Heading element (i.e., one which is not contained in another sectioning element). <Appendix> Appendix

]]> The Appendix element behaves exactly like a Chapter element (see ) except for the position within the document and the numbering. While chapters are counted with numbers (1., 2., 3., ...) the appendices are counted with capital letters (A., B., ...).

Again there is an optional Label attribute used for references. <Section> Section

]]> A Section element can have a Label attribute, such that this section can be referenced later on with a Ref element (see section ). Note that you have to specify a label to reference the section as there is no automatic labelling!

Section elements can contain text (for a description of %Text; see ), Heading elements, and subsections.

There must be exactly one direct Heading element in a Section element, containing the heading of the section.

Note that a subsection is either a Subsection element or a ManSection element. <Subsection> Subsection

]]> The Subsection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section ). Note that you have to specify a label to reference the subsection as there is no automatic labelling!

Subsection elements can contain text (for a description of %Text; see ), and Heading elements.

There must be exactly one Heading element in a Subsection element, containing the heading of the subsection.

Another type of subsection is a ManSection, explained now:

ManSection–a special kind of subsection ManSections are intended to describe a function, operation, method, variable, or some other technical instance. It is analogous to a manpage in the UNIX environment. <ManSection> ManSection Description Returns ]]> The ManSection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section ). But this is probably rarely necessary because the elements Func and so on (explained below) generate automatically labels for cross referencing.

The content of a ManSection element is one or more elements describing certain items in &GAP;, each of them optionally followed by a Returns element, followed by a Description element, which contains %Text; (see ) describing it. (Remember to include examples in the description as often as possible, see ). The classes of items &GAPDoc; knows of are: functions (Func), operations (Oper), methods (Meth), filters (Filt), properties (Prop), attributes (Attr), variables (Var), families (Fam), and info classes (InfoClass). One ManSection should only describe several of such items when these are very closely related.

Each element for an item corresponding to a &GAP; function can be followed by a Returns element. In output versions of the document the string Returns: will be put in front of the content text. The text in the Returns element should usually be a short hint about the type of object returned by the function. This is intended to give a good mnemonic for the use of a function (together with a good choice of names for the formal arguments).

ManSections are also sectioning elements which count as subsections. Usually there should be no Heading-element in a ManSection, in that case a heading is generated automatically from the first Func-like element. Sometimes this default behaviour does not look appropriate, for example when there are several Func-like elements. For such cases an optional Heading is allowed. <Func> Func

]]> This element is used within a ManSection element to specify the usage of a function. The Name attribute is required and its value is the name of the function. The value of the Arg attribute (also required) contains the full list of arguments including optional parts, which are denoted by square brackets. The argument names can be separated by whitespace, commas or the square brackets for the optional arguments, like or . If &GAP; options are used, this can be followed by a colon : and one or more assignments, like .

The name of the function is also used as label for cross referencing. When the name of the function appears in the text of the document it should always be written with the Ref element, see . This allows to use a unique typesetting style for function names and automatic cross referencing.

If the optional Label attribute is given, it is appended (with a colon : in between) to the name of the function for cross referencing purposes. The text of the label can also appear in the document text. So, it should be a kind of short explanation.

]]> The optional Comm attribute should be a short description of the function, usually at most one line long (this is currently nowhere used).

This element automatically produces an index entry with the name of the function and, if present, the text of the Label attribute as subentry (see also  and ). <Oper> Oper

]]> This element is used within a ManSection element to specify the usage of an operation. The attributes are used exactly in the same way as in the Func element (see ).

Note that multiple descriptions of the same operation may occur in a document because there may be several declarations in &GAP;. Furthermore there may be several ManSections for methods of this operation (see ) which also use the same name. For reference purposes these must be distinguished by different Label attributes. <Meth> Meth

]]> This element is used within a ManSection element to specify the usage of a method. The attributes are used exactly in the same way as in the Func element (see ).

Frequently, an operation is implemented by several different methods. Therefore it seems to be interesting to document them independently. This is possible by using the same method name in different ManSections. It is however required that these subsections and those describing the corresponding operation are distinguished by different Label attributes. <Filt> Filt

]]> This element is used within a ManSection element to specify the usage of a filter. The first four attributes are used in the same way as in the Func element (see ), except that the Arg attribute is optional.

The Type attribute can be any string, but it is thought to be something like Category or Representation. <Prop> Prop

]]> This element is used within a ManSection element to specify the usage of a property. The attributes are used exactly in the same way as in the Func element (see ).

<Attr> Attr

]]> This element is used within a ManSection element to specify the usage of an attribute (in &GAP;). The attributes are used exactly in the same way as in the Func element (see ).

<Var> Var

]]> This element is used within a ManSection element to document a global variable. The attributes are used exactly in the same way as in the Func element (see ) except that there is no Arg attribute.

<Fam> Fam

]]> This element is used within a ManSection element to document a family. The attributes are used exactly in the same way as in the Func element (see ) except that there is no Arg attribute.

<InfoClass> InfoClass

]]> This element is used within a ManSection element to document an info class. The attributes are used exactly in the same way as in the Func element (see ) except that there is no Arg attribute.

Cross Referencing and Citations Cross referencing in the &GAPDoc; system is somewhat different to the usual &LaTeX; cross referencing in so far, that a reference knows which type of object it is referencing. For example a reference to a function is distinguished from a reference to a chapter. The idea of this is, that the markup must contain this information such that the converters can produce better output. The HTML converter can for example typeset a function reference just as the name of the function with a link to the description of the function, or a chapter reference as a number with a link in the other case.

Referencing is done with the Ref element: <Ref> Ref

]]> The Ref element is defined to be EMPTY. If one of the attributes Func, Oper, Meth, Prop, Attr, Var, Fam, InfoClass, Chap, Sect, Subsect, Appendix is given then there must be exactly one of these, making the reference one to the corresponding object. The Label attribute can be specified in addition to make the reference unique, for example if more than one method with a given name is present. (Note that there is no way to specify in the DTD that exactly one of the first listed attributes must be given, this is an additional rule.)

A reference to a Label element defined below (see ) is done by giving the Label attribute and optionally the Text attribute. If the Text attribute is present its value is typeset in place of the Ref element, if linking is possible (for example in HTML). If this is not possible, the section number is typeset. This type of reference is also used for references to tables (see ).

An external reference into another book can be specified by using the BookName attribute. In this case the Label attribute or, if this is not given, the function or section like attribute, is used to resolve the reference. The generated reference points to the first hit when asking ?book name: label inside &GAP;.

The optional attribute Style can take only the values Text and Number. It can be used with references to sectioning units and it gives a hint to the converter programs, whether an explicit section number is generated or text. Normally all references to sections generate numbers and references to a &GAP; object generate the name of the corresponding object with some additional link or sectioning information, which is the behavior of Style="Text". In case Style="Number" in all cases an explicit section number is generated. So

described in section ]]> produces: described in section . <Label> Label ]]> This element is used to define a label for referencing a certain position in the document, if this is possible. If an exact reference is not possible (like in a printed version of the document) a reference to the corresponding subsection is generated. The value of the Name attribute must be unique under all Label elements. <Cite> Cite ]]> This element is for bibliography citations. It is EMPTY by definition. The attribute Key is the key for a lookup in a &BibTeX; database that has to be specified in the Bibliography element (see ). The value of the Where attribute specifies the position in the document as in the corresponding &LaTeX; syntax \cite[Where value]{Key value}. <Index> Index ]]> This element generates an index entry. The text within the element is typeset in the index entry, which is sorted under the value, that is specified in the Key and Subkey attributes. If they are not specified, the typeset text itself is used as the key.

A subkey can be specified in the simpler version as an attribute, but then no further markup can be used for the subkey. Optionally, the subkey text can be given in a Subkey element, in this case the attribute value is used for sorting but the typeset text is taken from the content of Subkey.

Note that all Func and similar elements automatically generate index entries. If the TheIndex element () is not present in the document all Index elements are ignored. <URL> URL

]]> This element is for references into the internet. It specifies an URL and optionally a text which can be used for a link (like in HTML or PDF versions of the document). This can be specified in two ways: Either the URL is given as element content and the text is given in the optional Text attribute (in this case the text cannot contain further markup), or the element contains the two elements Link and LinkText which in turn contain the URL and the text, respectively. The default value for the text is the URL itself.
<Email> Email ]]> This element type is the special case of an URL specifying an email address. The content of the element should be the email address without any prefix like mailto:. This address is typeset by all converters, also without any prefix. In the case of an output document format like HTML the converter can produce a link with a mailto: prefix. <Homepage> Homepage ]]> This element type is the special case of an URL specifying a WWW-homepage.
Structural Elements like Lists The &GAPDoc; system offers some limited access to structural elements like lists, enumerations, and tables. Although it is possible to use all &LaTeX; constructs one always has to think about other output formats. The elements in this section are guaranteed to produce something reasonable in all output formats. <List> List ]]> This element produces a list. Each item in the list corresponds to an Item element. Every Item element is optionally preceded by a Mark element. The content of this is used as a marker for the item. Note that this marker can be a whole word or even a sentence. It will be typeset in some emphasized fashion and most converters will provide some indentation for the rest of the item.

The Only and Not attributes can be used to specify, that the list is included into the output by only one type of converter (Only) or all but one type of converter (Not). Of course at most one of the two attributes may occur in one element. The following values are allowed as of now: LaTeX, HTML, and Text. See also the Alt element in for more about text alternatives for certain converters. <Mark> Mark

]]> This element is used in the List element to mark items. See for an explanation.
<Item> Item ]]> This element is used in the List, Enum, and Table elements to specify the items. See sections , , and for further information. <Enum> Enum ]]> This element is used like the List element (see ) except that the items must not have marks attached to them. Instead, the items are numbered automatically. The same comments about the Only and Not attributes as above apply. <Table> Table <Caption> <Row> <Align> <HorLine> <Item> in <Table> ]]> A table in &GAPDoc; consists of an optional Caption element followed by a sequence of Row and HorLine elements. A HorLine element produces a horizontal line in the table. A Row element consists of a sequence of Item elements as they also occur in List and Enum elements. The Only and Not attributes have the same functionality as described in the List element in .

The Align attribute is written like a &LaTeX; tabular alignment specifier but only the letters l, r, c, and | are allowed meaning left alignment, right alignment, centered alignment, and a vertical line as delimiter between columns respectively.

If the Label attribute is there, one can reference the table with the Ref element (see ) using its Label attribute.

Usually only simple tables should be used. If you want a complicated table in the &LaTeX; output you should provide alternatives for text and HTML output. Note that in HTML-4.0 there is no possibility to interpret the | column separators and HorLine elements as intended. There are lines between all columns and rows or no lines at all.

Types of Text This section covers the markup of text. Various types of text exist. The following elements are used in the &GAPDoc; system to mark them. They mostly come in pairs, one long name which is easier to remember and a shortcut to make the markup lighter.

Most of the following elements are thought to contain only character data and no further markup elements. It is however necessary to allow Alt elements to resolve the entities described in section . <Emph> and <E> Emph E

]]> This element is used to emphasize some piece of text. It may contain %InnerText; (see ). <Quoted> and <Q> Quoted Q ]]> This element is used to put some piece of text into  -quotes. It may contain %InnerText; (see ). <Keyword> and <K> Keyword K ]]> This element is used to mark something as a keyword. Usually this will be a &GAP; keyword such as if or for. No further markup elements are allowed within this element except for the Alt element, which is necessary. <Arg> and <A> Arg A ]]> This element is used inside Descriptions in ManSections to mark something as an argument (of a function, operation, or such). It is guaranteed that the converters typeset those exactly as in the definition of functions. No further markup elements are allowed within this element. <Code> and <C> Code C ]]> This element is used to mark something as a piece of code like for example a &GAP; expression. It is guaranteed that the converters typeset this exactly as in the Listing element (compare section ). The only further markup elements allowed within this element are <Arg> elements (see ). <File> and <F> File F ]]> This element is used to mark something as a filename or a pathname in the file system. No further markup elements are allowed within this element. <Button> and <B> Button B ]]> This element is used to mark something as a button. It can also be used for other items in a graphical user interface like menus, menu entries, or keys. No further markup elements are allowed within this element. <Package> Package ]]> This element is used to mark something as a name of a package. This is for example used to define the entities &GAP;, &XGAP; or &GAPDoc; (see section ). No further markup elements are allowed within this element. <Listing> Listing ]]> This element is used to embed listings of programs into the document. Only character data and no other elements are allowed in the content. You should not use the character entities described in section but instead type the characters directly. Only the general XML rules from section apply. Note especially the usage of <![CDATA[ sections described there. It is guaranteed that all converters use a fixed width font for typesetting Listing elements. Compare also the usage of the Code and C elements in .

The Type attribute contains a comment about the type of listed code. It may appear in the output. <Log> and <Example> Log Example

]]> These two elements behave exactly like the Listing element (see ). They are thought for protocols of &GAP; sessions. The only difference between the two is that Example sections are intended to be subject to an automatic manual checking mechanism used to ensure the correctness of the &GAP; manual whereas Log is not touched by this (see section for checking tools).

To get a good layout of the examples for display in a standard terminal we suggest to use SizeScreen([72]); (see ) in your &GAP; session before producing the content of Example elements. <Verb> There is one further type of verbatim-like element.

]]> The content of such an element is guaranteed to be put into an output version exactly as it is using some fixed width font. Before the content a new line is started. If the line after the end of the start tag consists of whitespace only then this part of the content is skipped.

This element is intended to be used together with the Alt element to specify pre-formatted ASCII alternatives for complicated Display formulae or Tables.

Elements for Mathematical Formulae <Math> and <Display> Math Display ]]> These elements are used for mathematical formulae. As described in section they correspond to &LaTeX;'s math and display math mode respectively.

The formulae are typed in as in &LaTeX;, except that the standard XML entities, see  (in particular the characters < and &), must be escaped - either by using the corresponding entities or by enclosing the formula between <![CDATA[ and ]]>. (The main reference for &LaTeX; is .)

It is also possible to use some unicode characters for mathematical symbols directly, provided that it can be translated by into "LaTeX" encoding and that with arguments "latin1" and "single" returns something sensible. Currently, we support entities &CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR; for the corresponding black board bold letters &CC;, &ZZ;, &NN;,&PP;, &QQ;, &HH; and &RR;, respectively.

The only element type that is allowed within the formula elements is the Arg or A element (see ), which is used to typeset identifiers that are arguments to &GAP; functions or operations.

If a Display element has an attribute Mode with value "M", then the formula is formatted as in M elements (see ). Otherwise in text and HTML output the formula is shown as &LaTeX; source code.

For simple formulae (and you should try to make all your formulae simple!) attempt to use the M element or the Mode="M" attribute in Display for which there is a well defined translation into text, which can be used for text and HTML output versions of the document. So, if possible try to avoid the Math elements and Display elements without attribute or provide useful text substitutes for complicated formulae via Alt elements (see  and ). <M> M

]]> The M element type is intended for formulae in the running text for which there is a sensible text version. For the &LaTeX; version of a &GAPDoc; document the M and Math elements are equivalent. The remarks in about special characters and the Arg element apply here as well. A document which has all formulae enclosed in M elements can be well readable in text terminal output and printed output versions.

Compared to former versions of &GAPDoc; many more formulae can be put into M elements. Most modern terminal emulations support unicode characters and many mathematical symbols can now be represented by such characters. But even if a terminal can only display ASCII characters, the user will see some not too bad representation of a formula.

As examples, here are some &LaTeX; macros which have a sensible ASCII translation and are guaranteed to be translated accordingly by text (and HTML) converters (for a full list of handled Macros see RecFields(TEXTMTRANSLATIONS)): \ast * \bf \bmod mod \cdot * \colon : \equiv = \geq >= \germ \hookrightarrow -> \iff <=> \langle < \ldots ... \left   \leq <= \leftarrow <- \Leftarrow <= \limits   \longrightarrow --> \Longrightarrow ==> \mapsto -> \mathbb   \mathop   \mid | \pmod mod \prime ' \rangle > \right   \rightarrow -> \Rightarrow => \rm, \sf, \textrm, \text \setminus \ \thinspace \times x \to -> \vert | \! \, \;   \{ { \} }
&LaTeX; macros with special text translation
In all other macros only the backslash is removed (except for some macros describing more exotic symbols). Whitespace is normalized (to one blank) but not removed. Note that whitespace is not added, so you may want to add a few more spaces than you usually do in your &LaTeX; documents.

Braces {} are removed in general, however pairs of double braces are converted to one pair of braces. This can be used to write <M>x^{12}</M> for x^12 and <M>x_{{i+1}}</M> for x_{i+1}.

Everything else <Alt> Alt This element is used to specify alternatives for different output formats within normal text. See also sections , , and for alternatives in lists and tables. ]]> Of course exactly one of the two attributes must occur in one element. The attribute values must be one word or a list of words, separated by spaces or commas. The words which are currently recognized by the converter programs contained in &GAPDoc; are: LaTeX, HTML, and Text. If the Only attribute is specified then only the corresponding converter will include the content of the element into the output document. If the Not attribute is specified the corresponding converter will ignore the content of the element. You can use other words to specify special alternatives for other converters of &GAPDoc; documents.

We fix a rule for handling the content of an Alt element with Only attribute. In their content code for the corresponding output format is included directly. So, in case of HTML the content is HTML code, in case of &LaTeX; the content is &LaTeX; code. The converters don't apply any handling of special characters to this content.

Within the element only %InnerText; (see ) is allowed. This is to ensure that the same set of chapters, sections, and subsections show up in all output formats. <Par> and <P> Par P

]]> This EMPTY element marks the boundary of paragraphs. Note that an empty line in the input does not mark a new paragraph as opposed to the &LaTeX; convention.

(Remark: it would be much easier to parse a document and to understand its sectioning and paragraph structure when there was an element whose content is the text of a paragraph. But in practice many paragraph boundaries are implicitly clear which would make it somewhat painful to enclose each paragraph in extra tags. The introduction of the P or Par elements as above delegates this pain to the writer of a conversion program for &GAPDoc; documents.) <Br> Br

]]> This element can be used to force a line break in the output versions of a &GAPDoc; element, it does not start a new paragraph. Please, do not use this instead of a Par element, this would often lead to ugly output versions of your document.
<Ignore> Ignore ]]> This element can appear anywhere. Its content is ignored by the standard converters. It can be used, for example, to include data which are not part of the actual &GAPDoc; document, like source code, or to make not finished parts of the document invisible.

Of course, one can use special converter programs which extract the contents of Ignore elements. Information on the type of the content can be stored in the optional attribute Remark.

GAPDoc-1.5.1/doc/chapInd_mj.html0000644000175000017500000004775312026346063014712 0ustar billbill GAP (GAPDoc) - Index
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

Index

ManualExamples 5.4
TestManualExamples 5.4
A 3.7-4
Abstract 3.2-10
Acknowledgements 3.2-12
AddHandlerBuildRecBibXMLEntry 7.3-8
AddPageNumbersToSix 5.3-4
AddParagraphNumbersGapDocTree 5.2-9
AddRootParseTree 5.2-5
<Align> 3.6-5
Alt 3.9-1
Appendix 3.3-4
AppendTo1 6.3-1
ApplyToNodesParseTree 5.2-5
Arg 3.7-4
Attr 3.4-7
Author 3.2-7
B 3.7-7
Base64String 6.1-12
Bibliography 3.2-15
Body 3.3-1
Book 3.2-1
BOXCHARS 6.1-1
Br 3.9-3
Button 3.7-7
C 3.7-5
CAPITALLETTERS 6.1-1
<Caption> 3.6-5
Chapter 3.3-2
CheckAndCleanGapDocTree 5.2-8
Cite 3.5-3
Code 3.7-5
Colophon 3.2-13
ComposedDocument 4.2-1
ComposedXMLString 4.2-1
CopyHTMLStyleFiles 5.3-10
Copyright 3.2-11
CSS stylesheets 5.3-9
Date 3.2-8
Address 3.2-9
Description 3.4-1
DIGITS 6.1-1
DigitsNumber 6.1-9
Display 3.8-1
DisplayXMLStructure 5.2-4
E 3.7-1
Email 3.5-6
Emph 3.7-1
Encode 6.2-2
EntitySubstitution 5.2-3
Enum 3.6-4
Example 3.7-10
ExtractExamples 5.4-1
ExtractExamplesXMLTree 5.4-1
F 3.7-6
Fam 3.4-9
File 3.7-6
FileString 6.3-5
Filt 3.4-5
FormatParagraph 6.1-4
Func 3.4-2
<#GAPDoc> 4.1
GAPDoc2HTML 5.3-7
GAPDoc2HTMLPrintHTMLFiles 5.3-8
GAPDoc2LaTeX 5.3-1
GAPDoc2Text 5.3-2
GAPDoc2TextPrintTextFiles 5.3-3
GetTextXMLTree 5.2-6
Heading 3.3-3
HeuristicTranslationsLaTeX2XML.Apply 7.3-2
HeuristicTranslationsLaTeX2XML.ApplyFile 7.3-2
HEXDIGITS 6.1-1
Homepage 3.5-7
<HorLine> 3.6-5
Ignore 3.9-4
<#Include> 4.1
Index 3.5-4
InfoBibTools 7.1-4
InfoClass 3.4-10
InfoGAPDoc 5.3-12
InfoXMLParser 5.2-10
IntListUnicodeString 6.2-1
IsUnicodeCharacter 6.2-1
IsUnicodeString 6.2-1
Item 3.6-3
<Item> in <Table> 3.6-5
K 3.7-3
Keyword 3.7-3
Label 3.5-2
LaTeXUnicodeTable 6.2-2
LETTERS 6.1-1
License .-1
List 3.6-1
Listing 3.7-9
Log 3.7-10
LowercaseUnicodeString 6.2-2
LowercaseUnicodeTable 6.2-2
M 3.8-2
MakeGAPDocDoc 5.1-1
ManSection 3.4-1
Mark 3.6-2
Math 3.8-1
MathJax 5.3-7
MathJax, in MakeGAPDocDoc 5.1-1
Meth 3.4-4
NormalizedNameAndKey 7.1-2
NormalizeNameAndKey 7.1-2
NrCharsUTF8String 6.2-3
NumberDigits 6.1-9
Oper 3.4-3
OriginalPositionDocument 4.2-2
P 3.9-2
Package 3.7-8
Page 6.3-4
PageDisplay 6.3-4
Par 3.9-2
ParseBibFiles 7.1-1
ParseBibStrings 7.1-1
ParseBibXMLextFiles 7.3-4
ParseBibXMLextString 7.3-4
ParseTreeXMLFile 5.2-1
ParseTreeXMLString 5.2-1
PositionMatchingDelimiter 6.1-10
PrintFormattedString 6.3-3
PrintSixFile 5.3-5
PrintTo1 6.3-1
Prop 3.4-6
Q 3.7-2
Quoted 3.7-2
RecBibXMLEntry 7.3-7
Ref 3.5-1
RemoveRootParseTree 5.2-5
RepeatedString 6.1-8
RepeatedUTF8String 6.1-8
Returns 3.4-1
RFC 3986 6.2-1
<Row> 3.6-5
RunExamples 5.4-2
SearchMR 7.4-1
SearchMRBib 7.4-1
Section 3.3-5
SetGAPDocHTMLStyle 5.3-11
SetGapDocLanguage 5.3-13
SetGapDocLaTeXOptions 5.3-1
SetGAPDocTextTheme 5.3-6
SimplifiedUnicodeString 6.2-2
SimplifiedUnicodeTable 6.2-2
SMALLLETTERS 6.1-1
StringBase64 6.1-12
StringBibAsXMLext 7.3-3
StringBibXMLEntry 7.3-9
StringFile 6.3-5
StringPrint 6.3-2
StringView 6.3-2
StringXMLElement 5.2-2
StripBeginEnd 6.1-6
StripEscapeSequences 6.1-7
Subsection 3.3-6
SubstitutionSublist 6.1-5
Subtitle 3.2-4
Table 3.6-5
TableOfContents 3.2-14
TemplateBibXML 7.3-10
TextAttr 6.1-2
TheIndex 3.2-16
Title 3.2-3
TitleComment 3.2-6
TitlePage 3.2-2
UChar 6.2-1
Unicode 6.2-1
UppercaseUnicodeString 6.2-2
URL 3.5-5
URL encoding 6.2-1
UseColorsInTerminal 6.1-2
Using GAPDoc with other languages 5.3-13
Var 3.4-8
Version 3.2-5
WHITESPACE 6.1-1
WidthUTF8String 6.2-3
WordsString 6.1-11
WrapTextAttribute 6.1-3
WriteBibFile 7.1-3
WriteBibXMLextFile 7.3-5
XML 1.1
XMLElements 5.2-7

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chapB_mj.html0000644000175000017500000005114112026346063014343 0ustar billbill GAP (GAPDoc) - Appendix B: The File gapdoc.dtd
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

B The File gapdoc.dtd

For easier reference we repeat here the complete content of the file gapdoc.dtd.

<?xml version="1.0" encoding="UTF-8"?>
<!-- ==================================================================
     gapdoc.dtd - XML Document type definition for GAP documentation
     By Frank Lübeck and Max Neunhöffer
     ================================================================== -->


<!-- Note that this definition goes "bottom-up" because entities can only
     be used after their definition in the file. -->


<!-- ==================================================================
     Some entities:
     ================================================================== -->

<!-- The standard XML entities: -->

<!ENTITY lt     "&#38;#60;"> 
<!ENTITY gt     "&#62;"> 
<!ENTITY amp    "&#38;#38;"> 
<!ENTITY apos   "&#39;"> 
<!ENTITY quot   "&#34;">


<!-- The following were introduced in GAPDoc version < 1.0, it is no longer
     necessary to take care of LaTeX special characters
     (we keep the entities with simplified definitions for compatibility) -->
     
<!ENTITY tamp "&amp;">
<!ENTITY tlt "&lt;">
<!ENTITY tgt "&gt;">
<!ENTITY hash "#">
<!ENTITY dollar "$">
<!ENTITY percent "&#37;">
<!ENTITY tilde "~">
<!ENTITY bslash "\\">
<!ENTITY obrace "{">
<!ENTITY cbrace "}">
<!ENTITY uscore "_">
<!ENTITY circum "^">

<!-- ==================================================================
     Our predefined entities:
     ================================================================== -->

<!ENTITY nbsp "&#160;">
<!ENTITY ndash "&#x2013;">
<!ENTITY GAP    "<Package>GAP</Package>">
<!ENTITY GAPDoc "<Package>GAPDoc</Package>">
<!ENTITY TeX    
  "<Alt Only='LaTeX'>{\TeX}</Alt><Alt Not='LaTeX'>TeX</Alt>">
<!ENTITY LaTeX  
  "<Alt Only='LaTeX'>{\LaTeX}</Alt><Alt Not='LaTeX'>LaTeX</Alt>">
<!ENTITY BibTeX 
  "<Alt Only='LaTeX'>{Bib\TeX}</Alt><Alt Not='LaTeX'>BibTeX</Alt>">
<!ENTITY MeatAxe "<Package>MeatAxe</Package>">
<!ENTITY XGAP   "<Package>XGAP</Package>">
<!ENTITY copyright "&#169;">

<!-- and unicode math symbols -->
<!ENTITY CC "&#x2102;" > <!-- double struck -->
<!ENTITY ZZ "&#x2124;" >
<!ENTITY NN "&#x2115;" >
<!ENTITY PP "&#x2119;" >
<!ENTITY QQ "&#x211a;" >
<!ENTITY HH "&#x210d;" >
<!ENTITY RR "&#x211d;" >


<!-- ==================================================================
     The following describes the "innermost" documentation text which 
     can occur at various places in the document like for example
     section headings. It does neither contain further sectioning 
     elements nor environments like Enums or Lists. 
     ================================================================== -->

<!ENTITY % InnerText "#PCDATA |
                      Alt |
                      Emph | E |
                      Par | P | Br |
                      Keyword | K | Arg | A | Quoted | Q | Code | C | 
                      File | F | Button | B | Package |
                      M | Math | Display | 
                      Example | Listing | Log | Verb |
                      URL | Email | Homepage | Address | Cite | Label | 
                      Ref | Index |
                      Ignore" >


<!ELEMENT Alt (%InnerText;)*>     <!-- This is only to allow "Only" and
                                       "Not" attributes for normal text -->
<!ATTLIST Alt Only CDATA #IMPLIED
              Not  CDATA #IMPLIED>

<!-- The following elements declare a certain block of InnerText to
     have a certain property. They are non-terminal and can contain
     any InnerText recursively. -->

<!ELEMENT Emph (%InnerText;)*>    <!-- Emphasize something -->
<!ELEMENT E    (%InnerText;)*>    <!-- the same as shortcut -->


<!-- The following is an empty element marking a paragraph boundary. -->

<!ELEMENT Par EMPTY>    <!-- this is intentionally empty! -->
<!ELEMENT P EMPTY>      <!-- the same as shortcut  -->

<!-- And here is an element for forcing a line break, not starting
     a new paragraph. -->

<!ELEMENT Br EMPTY>     <!-- a forced line break  -->

<!-- The following elements mark a word or sentence to be of a certain
     kind, such that it can  be typeset differently. They are terminal
     elements that should only contain  character data. But we have to
     allow  Alt elements  for handling  special characters.  For these
     elements we introduce  a long name - which is  easy to remember -
     and a  short name - which  you may prefer because  of the shorter
     markup. -->

<!ELEMENT Keyword (#PCDATA|Alt)*>  <!-- Keyword -->
<!ELEMENT K (#PCDATA|Alt)*>        <!-- Keyword (shortcut) -->

<!ELEMENT Arg (#PCDATA|Alt)*>      <!-- Argument -->
<!ELEMENT A (#PCDATA|Alt)*>        <!-- Argument (shortcut) -->

<!ELEMENT Code (#PCDATA|Alt|A|Arg)*> <!-- GAP code -->
<!ELEMENT C (#PCDATA|Alt|A|Arg)*>    <!-- GAP code (shortcut) -->

<!ELEMENT File (#PCDATA|Alt)*>     <!-- Filename -->
<!ELEMENT F (#PCDATA|Alt)*>        <!-- Filename (shortcut) -->

<!ELEMENT Button (#PCDATA|Alt)*>   <!-- "Button" (also Menu, Key) -->
<!ELEMENT B (#PCDATA|Alt)*>        <!-- "Button" (shortcut) -->

<!ELEMENT Package (#PCDATA|Alt)*>  <!-- A package name -->

<!ELEMENT Quoted (%InnerText;)*>   <!-- Quoted (in quotes) text -->
<!ELEMENT Q (%InnerText;)*>        <!-- Quoted text (shortcut) -->


<!-- The following elements contain mathematical formulae. They are 
     terminal elements that contain character data in TeX notation. -->

<!-- Math with well defined translation to text output -->
<!ELEMENT M (#PCDATA|A|Arg|Alt)*>
<!-- Normal TeX math mode formula -->
<!ELEMENT Math (#PCDATA|A|Arg|Alt)*>   
<!-- TeX displayed math mode formula -->
<!ELEMENT Display (#PCDATA|A|Arg|Alt)*>
<!-- Mode="M" causes <M>-style formatting -->
<!ATTLIST Display Mode CDATA #IMPLIED>  


<!-- The  following  elements  contain  GAP related  text  like  code,
     session  logs or  examples. They  are all  terminal elements  and
     consist of character data which is normally typeset verbatim. The
     different  types  of  the  elements only  control  how  they  are
     treated. -->

<!ELEMENT Example (#PCDATA)>  <!-- This is subject to the automatic 
                                   example checking mechanism -->
<!ELEMENT Log (#PCDATA)>      <!-- This not -->
<!ELEMENT Listing (#PCDATA)>  <!-- This is just for code listings -->
<!ATTLIST Listing Type CDATA #IMPLIED> <!-- a comment about the type of
                                            listed code, may appear in
                                            output -->

<!-- One  further  verbatim element,  this is truely  verbatim without
     any processing and intended  for ASCII substitutes of complicated
     displayed formulae or tables. -->

<!ELEMENT Verb  (#PCDATA)> 

<!-- The following  elements are  for cross-referencing  purposes like
     URLs, citations,  references, and  the index. All  these elements
     are  terminal and  need special  methods  to make  up the  actual
     output during document generation. -->

<!ELEMENT URL (#PCDATA|Alt|Link|LinkText)*>  <!-- Link, LinkText
     variant for case where text needs further markup -->
<!ATTLIST URL Text CDATA #IMPLIED>   <!-- This is for output formats
                                          that have links like HTML -->
<!ELEMENT Link     (%InnerText;)*> <!-- the URL -->
<!ELEMENT LinkText (%InnerText;)*> <!-- text for links, can contain markup -->
<!-- The following two are actually URLs, but the element name determines
     the type. -->
<!ELEMENT Email (#PCDATA|Alt|Link|LinkText)*>
<!ELEMENT Homepage (#PCDATA|Alt|Link|LinkText)*>

<!-- Those who still want to give postal addresses can use the following
     element. Use <Br/> for specifying typical line breaks  -->

<!ELEMENT Address (#PCDATA|Alt|Br)*>

<!ELEMENT Cite EMPTY>
<!ATTLIST Cite Key CDATA #REQUIRED
               Where CDATA #IMPLIED>
               
<!ELEMENT Label EMPTY>
<!ATTLIST Label Name CDATA #REQUIRED>

<!ELEMENT Ref EMPTY>
<!ATTLIST Ref Func      CDATA #IMPLIED
              Oper      CDATA #IMPLIED
              Meth      CDATA #IMPLIED
              Filt      CDATA #IMPLIED
              Prop      CDATA #IMPLIED
              Attr      CDATA #IMPLIED
              Var       CDATA #IMPLIED
              Fam       CDATA #IMPLIED
              InfoClass CDATA #IMPLIED
              Chap      CDATA #IMPLIED
              Sect      CDATA #IMPLIED
              Subsect   CDATA #IMPLIED
              Appendix  CDATA #IMPLIED
              Text      CDATA #IMPLIED

              Label     CDATA #IMPLIED
              BookName  CDATA #IMPLIED
              Style (Text|Number) #IMPLIED>  <!-- normally automatic -->

<!-- Note that  only one attribute  of Ref is used  normally. BookName
     and  Style  can  be  specified in  addition  to  handle  external
     references and the typesetting style of the reference. -->

<!-- For explicit index entries (Func and so on should cause an
     automatically generated index entry). Use the attributes Key,
     Subkey for sorting (simplified, without markup). The Subkey value
     also gets printed. Use the optional Subkey element if the printed
     version needs some markup.                                        -->
<!ELEMENT Index (%InnerText;|Subkey)*>
<!ATTLIST Index Key    CDATA #IMPLIED
                Subkey CDATA #IMPLIED>
<!ELEMENT Subkey (%InnerText;)*>


<!-- ==================================================================
     The following  describes the normal documentation  text which can
     occur  at various  places in  the document.  It does  not contain
     further sectioning elements. In addition to InnerText it can contain 
     environments like enumerations, lists, and such.
     ================================================================== -->

<!ENTITY % Text "%InnerText; | List | Enum | Table">

<!ELEMENT Item ( %Text;)*>
<!ELEMENT Mark ( %InnerText;)*>
<!ELEMENT BigMark ( %InnerText;)*>

<!ELEMENT List ( ((Mark,Item)|(BigMark,Item)|Item)+ )>
<!ATTLIST List Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>
<!ELEMENT Enum ( Item+ )>
<!ATTLIST Enum Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

<!ELEMENT Table ( Caption?, (Row | HorLine)+ )>
<!ATTLIST Table Label   CDATA #IMPLIED
                Only    CDATA #IMPLIED
                Not     CDATA #IMPLIED
                Align   CDATA #REQUIRED>    <!-- A TeX tabular string -->
                <!-- We allow | and l,c,r, nothing else -->
<!ELEMENT Row   ( Item+ )>
<!ELEMENT HorLine EMPTY>
<!ELEMENT Caption ( %InnerText;)*>

<!-- ==================================================================
     We start defining some things within the overall structure:
     ================================================================== -->

<!-- The TitlePage consists of several sub-elements: -->

<!ELEMENT TitlePage (Title, Subtitle?, Version?, TitleComment?, 
                     Author+, Date?, Address?, Abstract?, Copyright?, 
                     Acknowledgements? , Colophon? )>

<!ELEMENT Title (%Text;)*>
<!ELEMENT Subtitle (%Text;)*>
<!ELEMENT Version (%Text;)*>
<!ELEMENT TitleComment (%Text;)*>
<!ELEMENT Author (%Text;)*>    <!-- There may be more than one Author! -->
<!ELEMENT Date (%Text;)*>
<!ELEMENT Abstract (%Text;)*>
<!ELEMENT Copyright (%Text;)*>
<!ELEMENT Acknowledgements (%Text;)*>  
<!ELEMENT Colophon (%Text;)*>


<!-- The following things just specify some information about the
     corresponding parts of the Book: -->

<!ELEMENT TableOfContents EMPTY>
<!ELEMENT Bibliography EMPTY>
<!ATTLIST Bibliography Databases CDATA #REQUIRED
                       Style CDATA #IMPLIED>
<!ELEMENT TheIndex EMPTY>

<!-- ==================================================================
     The Ignore element can be used everywhere to include further
     information in a GAPDoc document which is not intended for the 
     standard converters (e.g., source code, not yet finished stuff,
     and so on. This information can be extracted by special converter 
     routines, more precise information about the content of an Ignore
     element can be given by the "Remark" attribute.
     ================================================================== -->

<!ELEMENT Ignore (%Text;| Chapter | Section | Subsection | ManSection |
                  Heading)*>
<!ATTLIST Ignore Remark CDATA #IMPLIED>
     
<!-- ==================================================================
     Now we go on with the overall structure by defining the sectioning 
     structure, which includes the Synopsis element: 
     ================================================================== -->


<!ELEMENT Subsection (%Text;| Heading)*>
<!ATTLIST Subsection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT ManSection ( Heading?, 
                      ((Func, Returns?) | (Oper, Returns?) | 
                       (Meth, Returns?) | (Filt, Returns?) | 
                       (Prop, Returns?) | (Attr, Returns?) |
                       Var | Fam | InfoClass)+, Description )>
<!ATTLIST ManSection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT Returns (%Text;)*>
<!ELEMENT Description (%Text;)*>


<!-- Note that  the ManSection element  is actually a  subsection with
     respect  to labelling,  referencing, and  counting of  sectioning
     elements. -->

<!ELEMENT Func EMPTY>
<!ATTLIST Func Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!-- Note  that Arg  contains the  full list  of arguments,  including
     optional  parts,  which  are   denoted  by  square  brackets  [].
     Arguments   are  separated   by  whitespace,   commas  count   as
     whitespace. -->

<!-- Note further that although Name and Label are  CDATA (and not ID)
     Label must make up a unique identifier. -->

<!ELEMENT Oper EMPTY>
<!ATTLIST Oper Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>
             
<!ELEMENT Meth EMPTY>
<!ATTLIST Meth Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Filt EMPTY>
<!ATTLIST Filt Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #IMPLIED
               Comm  CDATA #IMPLIED
               Type  CDATA #IMPLIED>  

<!ELEMENT Prop EMPTY>
<!ATTLIST Prop Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Attr EMPTY>
<!ATTLIST Attr Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Var  EMPTY>
<!ATTLIST Var  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

<!ELEMENT Fam  EMPTY>
<!ATTLIST Fam  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

<!ELEMENT InfoClass EMPTY>
<!ATTLIST InfoClass Name  CDATA #REQUIRED
                    Label CDATA #IMPLIED
                    Comm  CDATA #IMPLIED>


<!ELEMENT Heading (%InnerText;)*>

<!ELEMENT Section (%Text;| Heading | Subsection | ManSection)*>
<!ATTLIST Section Label CDATA #IMPLIED>    <!-- For reference purposes -->


<!ELEMENT Chapter (%Text;| Heading | Section)*>
<!ATTLIST Chapter Label CDATA #IMPLIED>    <!-- For reference purposes -->


<!-- Note that  the entity %InnerText; is  documentation that contains
     neither sectioning  elements nor environments  like enumerations,
     but  only  formulae,  labels, references,  citations,  and  other
     terminal elements. -->

<!ELEMENT Appendix (%Text;| Heading | Section)*>
<!ATTLIST Appendix Label CDATA #IMPLIED>   <!-- For reference purposes -->

<!-- Note that  an Appendix  is exactly  the same  as a  Chapter. They
     differ only in the numbering. -->

<!-- ==================================================================
     At last we define the overall structure of a gapdoc Book:
     ================================================================== -->

<!ELEMENT Body  ( %Text;| Chapter | Section )*>

<!ELEMENT Book (TitlePage,
                TableOfContents?,
                Body,
                Appendix*,
                Bibliography?,
                TheIndex?)>
<!ATTLIST Book Name CDATA #REQUIRED>
               
<!-- Note  that  the  entity  %Text; is  documentation  that  contains
     no  further sectioning  elements but  possibly environments  like
     enumerations,  and formulae,  labels, references,  and citations.
     -->

<!-- ============================================================== -->


Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap1_mj.html0000644000175000017500000005070112026346063014323 0ustar billbill GAP (GAPDoc) - Chapter 1: Introduction and Example
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

1 Introduction and Example

The main purpose of the GAPDoc package is to define a file format for documentation of GAP-programs and -packages (see [GAP]). The problem is that such documentation should be readable in several output formats. For example it should be possible to read the documentation inside the terminal in which GAP is running (a text mode) and there should be a printable version in high typesetting quality (produced by some version of TeX). It is also popular to view GAP's online help with a Web-browser via an HTML-version of the documentation. Nowadays one can use LaTeX and standard viewer programs to produce and view on the screen dvi- or pdf-files with full support of internal and external hyperlinks. Certainly there will be other interesting document formats and tools in this direction in the future.

Our aim is to find a format for writing the documentation which allows a relatively easy translation into the output formats just mentioned and which hopefully makes it easy to translate to future output formats as well.

To make documentation written in the GAPDoc format directly usable, we also provide a set of programs, called converters, which produce text-, hyperlinked LaTeX- and HTML-output versions of a GAPDoc document. These programs are developed by the first named author. They run completely inside GAP, i.e., no external programs are needed. You only need latex and pdflatex to process the LaTeX output. These programs are described in Chapter 5.

1.1 XML

The definition of the GAPDoc format uses XML, the "eXtendible Markup Language". This is a standard (defined by the W3C consortium, see http://www.w3c.org) which lays down a syntax for adding markup to a document or to some data. It allows to define document structures via introducing markup elements and certain relations between them. This is done in a document type definition. The file gapdoc.dtd contains such a document type definition and is the central part of the GAPDoc package.

The easiest way for getting a good idea about this is probably to look at an example. The Appendix A contains a short but complete GAPDoc document for a fictitious share package. In the next section we will go through this document, explain basic facts about XML and the GAPDoc document type, and give pointers to more details in later parts of this documentation.

In the last Section 1.3 of this introductory chapter we try to answer some general questions about the decisions which lead to the GAPDoc package.

1.2 A complete example

In this section we recall the lines from the example document in Appendix A and give some explanations.

<?xml version="1.0" encoding="UTF-8"?> 

This line just tells a human reader and computer programs that the file is a document with XML markup and that the text is encoded in the UTF-8 character set (other common encodings are ASCII or ISO-8895-X encodings).

<!--   A complete "fake package" documentation   
-->

Everything in a XML file between "<!--" and "-->" is a comment and not part of the document content.

<!DOCTYPE Book SYSTEM "gapdoc.dtd">

This line says that the document contains markup which is defined in the system file gapdoc.dtd and that the markup obeys certain rules defined in that file (the ending dtd means "document type definition"). It further says that the actual content of the document consists of an element with name "Book". And we can really see that the remaining part of the file is enclosed as follows:

<Book Name="3k+1">
  [...] (content omitted)
</Book>

This demonstrates the basics of the markup in XML. This part of the document is an "element". It consists of the "start tag" <Book Name="3k+1">, the "element content" and the "end tag" </Book> (end tags always start with </). This element also has an "attribute" Name whose "value" is 3k+1.

If you know HTML, this will look familiar to you. But there are some important differences: The element name Book and attribute name Name are case sensitive. The value of an attribute must always be enclosed in quotes. In XML every element has a start and end tag (which can be combined for elements defined as "empty", see for example <TableOfContents/> below).

If you know LaTeX, you are familiar with quite different types of markup, for example: The equivalent of the Book element in LaTeX is \begin{document} ... \end{document}. The sectioning in LaTeX is not done by explicit start and end markup, but implicitly via heading commands like \section. Other markup is done by using braces {} and putting some commands inside. And for mathematical formulae one can use the $ for the start and the end of the markup. In XML all markup looks similar to that of the Book element.

The content of the book starts with a title page.

<TitlePage>
  <Title>The <Package>ThreeKPlusOne</Package> Package</Title>
  <Version>Version 42</Version>
  <Author>Dummy Authör
    <Email>3kplusone@dev.null</Email>
  </Author>

  <Copyright>&copyright; 2000 The Author. <P/>
    You can do with this package what you want.<P/> Really.
  </Copyright>
</TitlePage>

The content of the TitlePage element consists again of elements. In Chapter 3 we describe which elements are allowed within a TitlePage and that their ordering is prescribed in this case. In the (stupid) name of the author you see that a German umlaut is used directly (in ISO-latin1 encoding).

Contrary to LaTeX- or HTML-files this markup does not say anything about the actual layout of the title page in any output version of the document. It just adds information about the meaning of pieces of text.

Within the Copyright element there are two more things to learn about XML markup. The <P/> is a complete element. It is a combined start and end tag. This shortcut is allowed for elements which are defined to be always "empty", i.e., to have no content. You may have already guessed that <P/> is used as a paragraph separator. Note that empty lines do not separate paragraphs (contrary to LaTeX).

The other construct we see here is &copyright;. This is an example of an "entity" in XML and is a macro for some substitution text. Here we use an entity as a shortcut for a complicated expression which makes it possible that the term copyright is printed as some text like (C) in text terminal output and as a copyright character in other output formats. In GAPDoc we predefine some entities. Certain "special characters" must be typed via entities, for example "<", ">" and "&" to avoid a misinterpretation as XML markup. It is possible to define additional entities for your document inside the <!DOCTYPE ...> declaration, see 2.2-3.

Note that elements in XML must always be properly nested, as in this example. A construct like <a><b>...</a></b> is not allowed.

<TableOfContents/>

This is another example of an "empty element". It just means that a table of contents for the whole document should be included into any output version of the document.

After this the main text of the document follows inside certain sectioning elements:

<Body>
  <Chapter> <Heading>The <M>3k+1</M> Problem</Heading>
    <Section Label="sec:theory"> <Heading>Theory</Heading>
      [...] (content omitted)
    </Section>
    <Section> <Heading>Program</Heading>
      [...] (content omitted) 
    </Section>
  </Chapter>
</Body>

These elements are used similarly to "\chapter" and "\section" in LaTeX. But note that the explicit end tags are necessary here.

The sectioning commands allow to assign an optional attribute "Label". This can be used for referring to a section inside the document.

The text of the first section starts as follows. The whitespace in the text is unimportant and the indenting is not necessary.


      Let  <M>k \in  &NN;</M> be  a  natural number.  We consider  the
      sequence <M>n(i, k), i \in &NN;,</M> with <M>n(1, k) = k</M> and
      else 

Here we come to the interesting question how to type mathematical formulae in a GAPDoc document. We did not find any alternative for writing formulae in TeX syntax. (There is MATHML, but even simple formulae contain a lot of markup, become quite unreadable and they are cumbersome to type. Furthermore there seem to be no tools available which translate such formulae in a nice way into TeX and text.) So, formulae are essentially typed as in LaTeX. (Actually, it is also possible to type unicode characters of some mathematical symbols directly, or via an entity like the &NN; above.) There are three types of elements containing formulae: "M", "Math" and "Display". The first two are for in-text formulae and the third is for displayed formulae. Here "M" and "Math" are equivalent, when translating a GAPDoc document into LaTeX. But they are handled differently for terminal text (and HTML) output. For the content of an "M"-element there are defined rules for a translation into well readable terminal text. More complicated formulae are in "Math" or "Display" elements and they are just printed as they are typed in text output. So, to make a section well readable inside a terminal window you should try to put as many formulae as possible into "M"-elements. In our example text we used the notation n(i, k) instead of n_i(k) because it is easier to read in text mode. See Sections 2.2-2 and 3.9 for more details.

A few lines further on we find two non-internal references.

      problem, see <Cite Key="Wi98"/> or
      <URL>http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/</URL>

The first within the "Cite"-element is the citation of a book. In GAPDoc we use the widely used BibTeX database format for reference lists. This does not use XML but has a well documented structure which is easy to parse. And many people have collections of references readily available in this format. The reference list in an output version of the document is produced with the empty element

<Bibliography Databases="3k+1" />

close to the end of our example file. The attribute "Databases" give the name(s) of the database (.bib) files which contain the references.

Putting a Web-address into an "URL"-element allows one to create a hyperlink in output formats which allow this.

The second section of our example contains a special kind of subsection defined in GAPDoc.

      <ManSection> 
        <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/>
        <Description>
          This  function computes  for a  natural number  <A>k</A> the
          beginning of the sequence  <M>n(i, k)</M> defined in section
          <Ref Sect="sec:theory"/>.  The sequence  stops at  the first
          <M>1</M>  or at  <M>n(<A>max</A>, k)</M>,  if <A>max</A>  is
          given.
<Example>
gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
</Example>
        </Description>
      </ManSection>

A "ManSection" contains the description of some function, operation, method, filter and so on. The "Func"-element describes the name of a function (there are also similar elements "Oper", "Meth", "Filt" and so on) and names for its arguments, optional arguments enclosed in square brackets. See Section 3.4 for more details.

In the "Description" we write the argument names as "A"-elements. A good description of a function should usually contain an example of its use. For this there are some verbatim-like elements in GAPDoc, like "Example" above (here, clearly, whitespace matters which causes a slightly strange indenting).

The text contains an internal reference to the first section via the explicitly defined label sec:theory.

The first section also contains a "Ref"-element which refers to the function described here. Note that there is no explicit label for such a reference. The pair <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/> and <Ref Func="ThreeKPlusOneSequence"/> does the cross referencing (and hyperlinking if possible) implicitly via the name of the function.

Here is one further element from our example document which we want to explain.

<TheIndex/>

This is again an empty element which just says that an output version of the document should contain an index. Many entries for the index are generated automatically because the "Func" and similar elements implicitly produce such entries. It is also possible to include explicit additional entries in the index.

1.3 Some questions

Are those XML files too ugly to read and edit?

Just have a look and decide yourself. The markup needs more characters than most TeX or LaTeX markup. But the structure of the document is easier to see. If you configure your favorite editor well, you do not need more key strokes for typing the markup than in LaTeX.

Why do we not use LaTeX alone?

LaTeX is good for writing books. But LaTeX files are generally difficult to parse and to process to other output formats like text for browsing in a terminal window or HTML (or new formats which may become popular in the future). GAPDoc markup is one step more abstract than LaTeX insofar as it describes meaning instead of appearance of text. The inner workings of LaTeX are too complicated to learn without pain, which makes it difficult to overcome problems that occur occasionally.

Why XML and not a newly defined markup language?

XML is a well defined standard that is more and more widely used. Lots of people have thought about it. Years of experience with SGML went into the design. It is easy to explain, easy to parse and lots of tools are available, there will be more in the future.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap7.html0000644000175000017500000016524712026346063013657 0ustar billbill GAP (GAPDoc) - Chapter 7: Utilities for Bibliographies
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

7 Utilities for Bibliographies

A standard for collecting references (in particular to mathematical texts) is BibTeX (http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/). A disadvantage of BibTeX is that the format of the data is specified with the use by LaTeX in mind. The data format is less suited for conversion to other document types like plain text or HTML.

In the first section we describe utilities for using data from BibTeX files in GAP.

In the second section we introduce a new XML based data format BibXMLext for bibliographies which seems better suited for other tasks than using it with LaTeX.

Another section will describe utilities to deal with BibXMLext data in GAP.

7.1 Parsing BibTeX Files

Here are functions for parsing, normalizing and printing reference lists in BibTeX format. The reference describing this format is [Lam85, Appendix B].

7.1-1 ParseBibFiles
‣ ParseBibFiles( bibfile1[, bibfile2[, ...]] )( function )
‣ ParseBibStrings( str1[, str2[, ...]] )( function )

Returns: list [list of bib-records, list of abbrevs, list of expansions]

The first function parses the files bibfile1 and so on (if a file does not exist the extension .bib is appended) in BibTeX format and returns a list as follows: [entries, strings, texts]. Here entries is a list of records, one record for each reference contained in bibfile. Then strings is a list of abbreviations defined by @string-entries in bibfile and texts is a list which contains in the corresponding position the full text for such an abbreviation.

The second function does the same, but the input is given as GAP strings str1 and so on.

The records in entries store key-value pairs of a BibTeX reference in the form rec(key1 = value1, ...). The names of the keys are converted to lower case. The type of the reference (i.e., book, article, ...) and the citation key are stored as components .Type and .Label. The records also have a .From field that says that the data are read from a BibTeX source.

As an example consider the following BibTeX file.

@string{ j  = "Important Journal" }
@article{ AB2000, Author=  "Fritz A. First and Sec, X. Y.", 
TITLE="Short", journal = j, year = 2000 }
gap> bib := ParseBibFiles("doc/test.bib");
[ [ rec( From := rec( BibTeX := true ), Label := "AB2000", 
          Type := "article", author := "Fritz A. First and Sec, X. Y."
            , journal := "Important Journal", title := "Short", 
          year := "2000" ) ], [ "j" ], [ "Important Journal" ] ]

7.1-2 NormalizedNameAndKey
‣ NormalizedNameAndKey( namestr )( function )

Returns: list of strings and names as lists

‣ NormalizeNameAndKey( r )( function )

Returns: nothing

The argument namestr must be a string describing an author or a list of authors as described in the BibTeX documentation in [Lam85, Appendix B 1.2]. The function NormalizedNameAndKey returns a list of the form [ normalized name string, short key, long key, names as lists]. The first entry is a normalized form of the input where names are written as "lastname, first name initials". The second and third entry are the name parts of a short and long key for the bibliography entry, formed from the (initials of) last names. The fourth entry is a list of lists, one for each name, where a name is described by three strings for the last name, the first name initials and the first name(s) as given in the input.

Note that the determination of the initials is limited to names where the first letter is described by a single character (and does not contain some markup, say for accents).

The function NormalizeNameAndKey gets as argument r a record for a bibliography entry as returned by ParseBibFiles (7.1-1). It substitutes .author and .editor fields of r by their normalized form, the original versions are stored in fields .authororig and .editororig.

Furthermore a short and a long citation key is generated and stored in components .printedkey (only if no .key is already bound) and .keylong.

We continue the example from ParseBibFiles (7.1-1).

gap> bib := ParseBibFiles("doc/test.bib");;
gap> NormalizedNameAndKey(bib[1][1].author);
[ "First, F. A. and Sec, X. Y.", "FS", "firstsec", 
  [ [ "First", "F. A.", "Fritz A." ], [ "Sec", "X. Y.", "X. Y." ] ] ]
gap> NormalizeNameAndKey(bib[1][1]);
gap> bib[1][1];
rec( From := rec( BibTeX := true ), Label := "AB2000", 
  Type := "article", author := "First, F. A. and Sec, X. Y.", 
  authororig := "Fritz A. First and Sec, X. Y.", 
  journal := "Important Journal", keylong := "firstsec2000", 
  printedkey := "FS00", title := "Short", year := "2000" )

7.1-3 WriteBibFile
‣ WriteBibFile( bibfile, bib )( function )

Returns: nothing

This is the converse of ParseBibFiles (7.1-1). Here bib either must have a format as list of three lists as it is returned by ParseBibFiles (7.1-1). Or bib can be a record as returned by ParseBibXMLextFiles (7.3-4). A BibTeX file bibfile is written and the entries are formatted in a uniform way. All given abbreviations are used while writing this file.

We continue the example from NormalizeNameAndKey (7.1-2). The command

gap> WriteBibFile("nicer.bib", bib);

produces a file nicer.bib as follows:

@string{j = "Important Journal" }

@article{ AB2000,
  author =           {First, F. A. and Sec, X. Y.},
  title =            {Short},
  journal =          j,
  year =             {2000},
  authororig =       {Fritz A. First and Sec, X. Y.},
  keylong =          {firstsec2000},
  printedkey =       {FS00}
}

7.1-4 InfoBibTools
‣ InfoBibTools( info class )

The default level of this info class is 1. Functions like ParseBibFiles (7.1-1), StringBibAs... are then printing some information. You can suppress it by setting the level of InfoBibTools to 0. With level 2 there may be some more information for debugging purposes.

7.2 The BibXMLext Format

Bibliographical data in BibTeX files have the disadvantage that the actual data are given in LaTeX syntax. This makes it difficult to use the data for anything but for LaTeX, say for representations of the data as plain text or HTML. For example: mathematical formulae are in LaTeX $ environments, non-ASCII characters can be specified in many strange ways, and how to specify URLs for links if the output format allows them?

Here we propose an XML data format for bibliographical data which addresses these problems, it is called BibXMLext. In the next section we describe some tools for generating (an approximation to) this data format from BibTeX data, and for using data given in BibXMLext format for various purposes.

The first motivation for this development was the handling of bibliographical data in GAPDoc, but the format and the tools are certainly useful for other purposes as well.

We started from a DTD bibxml.dtd which is publicly available, say from http://bibtexml.sf.net/. This is essentially a reformulation of the definition of the BibTeX format, including several of some widely used further fields. This has already the advantage that a generic XML parser can check the validity of the data entries, for example for missing compulsary fields in entries. We applied the following changes and extensions to define the DTD for BibXMLext, stored in the file bibxmlext.dtd which can be found in the root directory of this GAPDoc package (and in Appendix C):

names

Lists of names in the author and editor fields in BibTeX are difficult to parse. Here they must be given by a sequence of <name>-elements which each contain an optional <first>- and a <last>-element for the first and last names, respectively.

<M> and <Math>

These elements enclose mathematical formulae, the content is LaTeX code (without the $). These should be handled in the same way as the elements with the same names in GAPDoc, see 3.8-2 and 3.8-1. In particular, simple formulae which have a well defined plain text representation can be given in <M>-elements.

Encoding

Note that in XML files we can use the full range of unicode characters, see http://www.unicode.org/. All non-ASCII characters should be specified as unicode characters. This makes dealing with special characters easy for plain text or HTML, only for use with LaTeX some sort of translation is necessary.

<URL>

These elements are allowed everywhere in the text and should be represented by links in converted formats which allow this. It is used in the same way as the element with the same name in GAPDoc, see 3.5-5.

<Alt Only="..."> and <Alt Not="...">

Sometimes information should be given in different ways, depending on the output format of the data. This is possible with the <Alt>-elements with the same definition as in GAPDoc, see 3.9-1.

<C>

This element should be used to protect text from case changes by converters (the extra {} characters in BibTeX title fields).

<string key="..." value="..."/> and <value key="..."/>

The <string>-element defines key-value pairs which can be used in any field via the <value>-element (not only for whole fields but also parts of the text).

<other type="...">

This is a generic element for fields which are otherwise not supported. An arbitrary number of them is allowed for each entry, so any kind of additional data can be added to entries.

<Wrap Name="...">

This generic element is allowed inside all fields. This markup will be just ignored (but not the element content) by our standard tools. But it can be a useful hook for introducing arbitrary further markup (and our tools can easily be extended to handle it).

Extra entities

The DTD defines the standard XML entities (2.1-10 and the entities &nbsp; (non-breakable space), &ndash; and &copyright;. Use &ndash; in page ranges.

For further details of the DTD we refer to the file bibxmlext.dtd itself which is shown in appendix C. That file also recalls some information from the BibTeX documentation on how the standard fields of entries should be used. Which entry types and which fields are supported (and the ordering of the fields which is fixed by a DTD) can be either read off the DTD, or within GAP one can use the function TemplateBibXML (7.3-10) to get templates for the various entry types.

Here is an example of a BibXMLext document:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE file SYSTEM "bibxmlext.dtd">
<file>
<string key="j" value="Important Journal"/>
<entry id="AB2000"><article>
  <author>
    <name><first>Fritz A.</first><last>First</last></name>
    <name><first>X. Y.</first><last>Sec&#x0151;nd</last></name>
  </author>  
  <title>The <Wrap Name="Package"> <C>F</C>ritz</Wrap> package for the 
         formula <M>x^y - l_{{i+1}} \rightarrow \mathbb{R}</M></title>
  <journal><value key="j"/></journal>
  <year>2000</year>
  <number>13</number>
  <pages>13&ndash;25</pages>
  <note>Online data at <URL Text="Bla Bla Publisher">
                  http://www.publish.com/~ImpJ/123#data</URL></note>
  <other type="mycomment">very useful</other>
</article></entry>
</file>

There is a standard XML header and a DOCTYPE declaration refering to the bibxmlext.dtd DTD mentioned above. Local entities could be defined in the DOCTYPE tag as shown in the example in 2.2-3. The actual content of the document is inside a <file>-element, it consists of <string>- and <entry>-elements. Several of the BibXMLext markup features are shown. We will use this input document for some examples below.

7.3 Utilities for BibXMLext data

7.3-1 Translating BibTeX to BibXMLext

First we describe a tool which can translate bibliography entries from BibTeX data to BibXMLext <entry>-elements. It also does some validation of the data. In some cases it is desirable to improve the result by hand afterwards (editing formulae, adding <URL>-elements, translating non-ASCII characters to unicode, ...).

See WriteBibXMLextFile (7.3-5) below for how to write the results to a BibXMLext file.

7.3-2 HeuristicTranslationsLaTeX2XML.Apply
‣ HeuristicTranslationsLaTeX2XML.Apply( str )( function )

Returns: a string

‣ HeuristicTranslationsLaTeX2XML.ApplyFile( fnam[, outnam] )( function )

Returns: nothing

These utilities translate some LaTeX code into text in UTF-8 encoding. The input is given as a string str, or a file name fnam, respectively. The first function returns the translated string. The second function with one argument overwrites the given file with the translated text. Optionally, the translated file content can be written to another file, if its name is given as second argument outnam.

The record HeuristicTranslationsLaTeX2XML mainly contains translations of LaTeX macros for special characters which were found in hundreds of BibTeX entries from MathSciNet. Just look at this record if you want to know how it works. It is easy to extend, and if you have improvements which may be of general interest, please send them to the GAPDoc author.

gap> s := "\\\"u\\'{e}\\`e{\\ss}";;
gap> Print(s, "\n");               
\"u\'{e}\`e{\ss}
gap> Print(HeuristicTranslationsLaTeX2XML.Apply(s),"\n");
üéèß

7.3-3 StringBibAsXMLext
‣ StringBibAsXMLext( bibentry[, abbrvs, vals][, encoding] )( function )

Returns: a string with XML code, or fail

The argument bibentry is a record representing an entry from a BibTeX file, as returned in the first list of the result of ParseBibFiles (7.1-1). The optional two arguments abbrvs and vals can be lists of abbreviations and substitution strings, as returned as second and third list element in the result of ParseBibFiles (7.1-1). The optional argument encoding specifies the character encoding of the string components of bibentry. If this is not given it is checked if all strings are valid UTF-8 encoded strings, in that case it is assumed that the encoding is UTF-8, otherwise the latin1 encoding is assumed.

The function StringBibAsXMLext creates XML code of an <entry>-element in BibXMLext format. The result is in UTF-8 encoding and contains some heuristic translations, like splitting name lists, finding places for <C>-elements, putting formulae in <M>-elements, substituting some characters. The result should always be checked and maybe improved by hand. Some validity checks are applied to the given data, for example if all non-optional fields are given. If this check fails the function returns fail.

If your BibTeX input contains LaTeX markup for special characters, it can be convenient to translate this input with HeuristicTranslationsLaTeX2XML.Apply (7.3-2) or HeuristicTranslationsLaTeX2XML.ApplyFile (7.3-2) before parsing it as BibTeX.

As an example we consider again the short BibTeX file doc/test.bib shown in the example for ParseBibFiles (7.1-1).

gap> bib := ParseBibFiles("doc/test.bib");;
gap> str := StringBibAsXMLext(bib[1][1], bib[2], bib[3]);;
gap> Print(str, "\n");
<entry id="AB2000"><article>
  <author>
    <name><first>Fritz A.</first><last>First</last></name>
    <name><first>X. Y.</first><last>Sec</last></name>
  </author>  
  <title>Short</title>
  <journal><value key="j"/></journal>
  <year>2000</year>
</article></entry>

The following functions allow parsing of data which are already in BibXMLext format.

7.3-4 ParseBibXMLextString
‣ ParseBibXMLextString( str )( function )
‣ ParseBibXMLextFiles( fname1[, fname2[, ...]] )( function )

Returns: a record with fields .entries, .strings and .entities

The first function gets a string str containing a BibXMLext document or a part of it. It returns a record with the three mentioned fields. Here .entries is a list of partial XML parse trees for the <entry>-elements in str. The field .strings is a list of key-value pairs from the <string>-elements in str. And .strings is a list of name-value pairs of the named entities which were used during the parsing.

The second function ParseBibXMLextFiles uses the first on the content of all files given by filenames fname1 and so on. It collects the results in a single record.

As an example we parse the file testbib.xml shown in 7.2.

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> RecFields(bib);
[ "entries", "strings", "entities" ]
gap> bib.entries;
[ <BibXMLext entry: AB2000> ]
gap> bib.strings;
[ [ "j", "Important Journal" ] ]
gap> bib.entities[1]; 
[ "amp", "&#38;#38;" ]

7.3-5 WriteBibXMLextFile
‣ WriteBibXMLextFile( fname, bib )( function )

Returns: nothing

This function writes a BibXMLext file with name fname.

There are three possibilities to specify the bibliography entries in the argument bib. It can be a list of three lists as returned by ParseBibFiles (7.1-1). Or it can be just the first of such three lists in which case the other two lists are assumed to be empty. To all entries of the (first) list the function StringBibAsXMLext (7.3-3) is applied and the resulting strings are written to the result file.

The third possibility is that bib is a record in the format as returned by ParseBibXMLextString (7.3-4) and ParseBibXMLextFiles (7.3-4). In this case the entries for the BibXMLext file are produced with StringXMLElement (5.2-2), and if bib.entities is bound then it is tried to resubstitute parts of the string by the given entities with EntitySubstitution (5.2-3).

As an example we write back the result of the example shown for ParseBibXMLextFiles (7.3-4) to an equivalent XML file.

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> WriteBibXMLextFile("test.xml", bib);

7.3-6 Bibliography Entries as Records

For working with BibXMLext entries we find it convenient to first translate the parse tree of an entry, as returned by ParseBibXMLextFiles (7.3-4), to a record with the field names of the entry as components whose value is the content of the field as string. These strings are generated with respect to a result type. The records are generated by the following function which can be customized by the user.

7.3-7 RecBibXMLEntry
‣ RecBibXMLEntry( entry[, restype][, strings][, options] )( function )

Returns: a record with fields as strings

This function generates a content string for each field of a bibliography entry and assigns them to record components. This content may depend on the requested result type and possibly some given options.

The arguments are as follows: entry is the parse tree of an <entry> element as returned by ParseBibXMLextString (7.3-4) or ParseBibXMLextFiles (7.3-4). The optional argument restype describes the type of the result. This package supports currently the types "BibTeX", "Text" and "HTML". The default is "BibTeX". The optional argument strings must be a list of key-value pairs as returned in the component .strings in the result of ParseBibXMLextString (7.3-4). The argument options must be a record.

If the entry contains an author field then the result will also contain a component .authorAsList which is a list containing for each author a list with three entries of the form [last name, first name initials, first name] (the third entry means the first name as given in the data). Similarly, an editor field is accompanied by a component .editorAsList.

The following options are currently supported.

If options.fullname is bound and set to true then the full given first names for authors and editors will be used, the default is to use the initials of the first names. Also, if options.namefirstlast is bound and set to true then the names are written in the form "first-name(s) last-name", the default is the form "last-name, first-name(s)".

If options.href is bound and set to false then the "BibTeX" type result will not use \href commands. The default is to produce \href commands from <URL>-elements such that LaTeX with the hyperref package can produce links for them.

The content of an <Alt>-element with Only-attribute is included if restype is given in the attribute and ignored otherwise, and vice versa in case of a Not-attribute. If options.useAlt is bound, it must be a list of strings to which restype is added. Then an <Alt>-element with Only-attribute is evaluated if the intersection of options.useAlt and the types given in the attribute is not empty. In case of a Not-attribute the element is evaluated if this intersection is empty.

If restype is "BibTeX" then the string fields in the result will be recoded with Encode (6.2-2) and target "LaTeX". If options.hasLaTeXmarkup is bound and set to true (for example, because the data are originally read from BibTeX files), then the target "LaTeXleavemarkup" will be used.

We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> e := bib.entries[1];; strs := bib.strings;;
gap> Print(RecBibXMLEntry(e, "BibTeX", strs), "\n");
rec(
  From := rec(
      BibXML := true,
      options := rec(
           ),
      type := "BibTeX" ),
  Label := "AB2000",
  Type := "article",
  author := "First, F. A. and Sec{\\H o}nd, X. Y.",
  authorAsList := 
   [ [ "First", "F. A.", "Fritz A." ], 
      [ "Sec\305\221nd", "X. Y.", "X. Y." ] ],
  journal := "Important Journal",
  mycomment := "very useful",
  note := 
   "Online data at \\href {http://www.publish.com/~ImpJ/123#data} {Bla\
 Bla Publisher}",
  number := "13",
  pages := "13{\\textendash}25",
  printedkey := "FS00",
  title := 
   "The  {F}ritz package for the \n         formula $x^y - l_{{i+1}} \
\\rightarrow \\mathbb{R}$",
  year := "2000" )
gap> Print(RecBibXMLEntry(e, "HTML", strs).note, "\n");
Online data at <a href="http://www.publish.com/~ImpJ/123#data">Bla Bla\
 Publisher</a>

7.3-8 AddHandlerBuildRecBibXMLEntry
‣ AddHandlerBuildRecBibXMLEntry( elementname, restype, handler )( function )

Returns: nothing

The argument elementname must be the name of an entry field supported by the BibXMLext format, the name of one of the special elements "C", "M", "Math", "URL" or of the form "Wrap:myname" or any string "mytype" (which then corresponds to entry fields <other type="mytype">). The string "Finish" has an exceptional meaning, see below.

restype is a string describing the result type for which the handler is installed, see RecBibXMLEntry (7.3-7).

For both arguments, elementname and restype, it is also possible to give lists of the described ones for installing several handler at once.

The argument handler must be a function with five arguments of the form handler(entry, r, restype, strings, options). Here entry is a parse tree of a BibXMLext <entry>-element, r is a node in this tree for an element elementname, and restype, strings and options are as explained in RecBibXMLEntry (7.3-7). The function should return a string representing the content of the node r. If elementname is of the form "Wrap:myname" the handler is used for elements of form <Wrap Name="myname">...</Wrap>.

If elementname is "Finish" the handler should look like above except that now r is the record generated by RecBibXMLEntry (7.3-7) just before it is returned. Here the handler should return nothing. It can be used to manipulate the record r, for example for changing the encoding of the strings or for adding some more components.

The installed handler is called by BuildRecBibXMLEntry(entry, r, restype, strings, options). The string for the whole content of an element can be generated by ContentBuildRecBibXMLEntry(entry, r, restype, strings, options).

We continue the example from RecBibXMLEntry (7.3-7) and install a handler for the <Wrap Name="Package">-element such that LaTeX puts its content in a sans serif font.

gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX",
> function(entry,  r, restype,  strings, options)
>   return Concatenation("\\textsf{", ContentBuildRecBibXMLEntry(
>             entry, r, restype,  strings, options), "}");
> end);
gap> 
gap> Print(RecBibXMLEntry(e, "BibTeX", strs).title, "\n");
The \textsf{ {F}ritz} package for the 
         formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$
gap> Print(RecBibXMLEntry(e, "Text", strs).title, "\n");  
The  Fritz package for the 
         formula x^y - l_{i+1} → R
gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", "Ignore");

7.3-9 StringBibXMLEntry
‣ StringBibXMLEntry( entry[, restype][, strings][, options] )( function )

Returns: a string

The arguments of this function have the same meaning as in RecBibXMLEntry (7.3-7) but the return value is a string representing the bibliography entry in a format specified by restype (default is "BibTeX").

Currently, the following cases for restype are supported:

"BibTeX"

A string with BibTeX source code is generated.

"Text"

A text representation of the text is returned. If options.ansi is bound it must be a record. The components must have names Bib_Label, Bib_author, and so on for all fieldnames. The value of each component is a pair of strings which will enclose the content of the field in the result or the first of these strings in which case the default for the second is TextAttr.reset (see TextAttr (6.1-2)). If you give an empty record here, some default ANSI color markup will be used.

"HTML"

An HTML representation of the bibliography entry is returned. The text from each field is enclosed in markup (mostly <span>-elements) with the class attribute set to the field name. This allows a detailed layout of the code via a style sheet file.

We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).

gap> bib := ParseBibXMLextFiles("doc/testbib.xml");;
gap> e := bib.entries[1];; strs := bib.strings;;
gap> ebib := StringBibXMLEntry(e, "BibTeX", strs);;
gap> PrintFormattedString(ebib);
@article{ AB2000,
  author =           {First, F. A. and Sec{\H o}nd, X. Y.},
  title =            {The  {F}ritz  package  for  the formula $x^y -
                      l_{{i+1}} \rightarrow \mathbb{R}$},
  journal =          {Important Journal},
  number =           {13},
  year =             {2000},
  pages =            {13{\textendash}25},
  note =             {Online          data          at         \href
                      {http://www.publish.com/~ImpJ/123#data}   {Bla
                      Bla Publisher}},
  mycomment =        {very useful},
  printedkey =       {FS00}
}
gap> etxt := StringBibXMLEntry(e, "Text", strs);;      
gap> etxt := SimplifiedUnicodeString(Unicode(etxt), "latin1", "single");;
gap> etxt := Encode(etxt, GAPInfo.TermEncoding);;                        
gap> PrintFormattedString(etxt);
[FS00]  First,  F.  A.  and Second, X. Y., The Fritz package for the
formula  x^y  -  l_{i+1}  ?  R, Important Journal, 13 (2000), 13-25,
(Online        data        at        Bla        Bla        Publisher
(http://www.publish.com/~ImpJ/123#data)).

The following command may be useful to generate completly new bibliography entries in BibXMLext format. It also informs about the supported entry types and field names.

7.3-10 TemplateBibXML
‣ TemplateBibXML( [type] )( function )

Returns: list of types or string

Without an argument this function returns a list of the supported entry types in BibXMLext documents.

With an argument type of one of the supported types the function returns a string which is a template for a corresponding BibXMLext entry. Optional field elements have a * appended. If an element has the word OR appended, then either this element or the next must/can be given, not both. If AND/OR is appended then this and/or the next can/must be given. Elements which can appear several times have a + appended. Places to fill are marked by an X.

gap> TemplateBibXML();
[ "article", "book", "booklet", "conference", "inbook", 
  "incollection", "inproceedings", "manual", "mastersthesis", "misc", 
  "phdthesis", "proceedings", "techreport", "unpublished" ]
gap> Print(TemplateBibXML("inbook"));
<entry id="X"><inbook>
  <author>
    <name><first>X</first><last>X</last></name>+
  </author>OR
  <editor>
    <name><first>X</first><last>X</last></name>+
  </editor>
  <title>X</title>
  <chapter>X</chapter>AND/OR
  <pages>X</pages>
  <publisher>X</publisher>
  <year>X</year>
  <volume>X</volume>*OR
  <number>X</number>*
  <series>X</series>*
  <type>X</type>*
  <address>X</address>*
  <edition>X</edition>*
  <month>X</month>*
  <note>X</note>*
  <key>X</key>*
  <annotate>X</annotate>*
  <crossref>X</crossref>*
  <abstract>X</abstract>*
  <affiliation>X</affiliation>*
  <contents>X</contents>*
  <copyright>X</copyright>*
  <isbn>X</isbn>*OR
  <issn>X</issn>*
  <keywords>X</keywords>*
  <language>X</language>*
  <lccn>X</lccn>*
  <location>X</location>*
  <mrnumber>X</mrnumber>*
  <mrclass>X</mrclass>*
  <mrreviewer>X</mrreviewer>*
  <price>X</price>*
  <size>X</size>*
  <url>X</url>*
  <category>X</category>*
  <other type="X">X</other>*+
</inbook></entry>

7.4 Getting BibTeX entries from MathSciNet

We provide utilities to access the MathSciNet data base from within GAP. One condition for this to work is that the IO-package [Neu07] is available. The other is, of course, that you use these functions from a computer which has access to MathSciNet.

Please note, that the usual license for MathSciNet access does not allow for automated searches in the database. Therefore, only use the SearchMR (7.4-1) function for single queries, as you would do using your webbrowser.

7.4-1 SearchMR
‣ SearchMR( qurec )( function )
‣ SearchMRBib( bib )( function )

Returns: a list of strings, a string or fail

The first function SearchMR provides the same functionality as the Web interface MathSciNet. The query strings must be given as a record, and the following components of this record are recognized: Author, AuthorRelated, Title, ReviewText, Journal, InstitutionCode, Series, MSCPrimSec, MSCPrimary, MRNumber, Anywhere, References and Year.

Furthermore, the component type can be specified. It can be one of "bibtex" (the default if not given), "pdf", "html" and probably others. In the last cases the function returns a string with the correspondig PDF-file or web page from MathSciNet. In the first case the MathSciNet interface returns a web page with BibTeX entries, for convenience this function returns a list of strings, each containing the BibTeX text for a single result entry.

The format of a .Year component can be either a four digit number, optionally preceded by one of the characters '<', '>' or '=', or it can be two four digit numbers separated by a - to specify a year range.

The function SearchMRBib gets a record of a parsed BibTeX entry as input as returned by ParseBibFiles (7.1-1) or ParseBibStrings (7.1-1). It tries to generate some sensible input from this information for SearchMR and calls that function.

gap> ll := SearchMR(rec(Author:="Gauss", Title:="Disquisitiones"));;
gap> ll2 := List(ll, HeuristicTranslationsLaTeX2XML.Apply);;
gap> bib := ParseBibStrings(Concatenation(ll2));;
gap> bibxml := List(bib[1], StringBibAsXMLext);;
gap> bib2 := ParseBibXMLextString(Concatenation(bibxml));;
gap> for b in bib2.entries do 
>          PrintFormattedString(StringBibXMLEntry(b, "Text")); od;     
[Gau95]   Gauss,   C.   F.,  Disquisitiones  arithmeticae,  Academia
Colombiana  de  Ciencias  Exactas  Físicas  y  Naturales,  Colección
Enrique  Pérez  Arbeláez  [Enrique  Pérez  Arbeláez Collection], 10,
Bogotá  (1995),  xliv+495  pages, (Translated from the Latin by Hugo
Barrantes  Campos,  Michael  Josephy  and  Ángel Ruiz Zúñiga, With a
preface by Ruiz Zúñiga).

[Gau86]  Gauss, C. F., Disquisitiones arithmeticae, Springer-Verlag,
New  York  (1986),  xx+472  pages, (Translated and with a preface by
Arthur  A.  Clarke,  Revised  by  William  C.  Waterhouse, Cornelius
Greither and A. W. Grootendorst and with a preface by Waterhouse).

[Gau66]  Gauss,  C. F., Disquisitiones arithmeticae, Yale University
Press, Translated into English by Arthur A. Clarke, S. J, New Haven,
Conn. (1966), xx+472 pages.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap5_mj.html0000644000175000017500000023517112026346063014335 0ustar billbill GAP (GAPDoc) - Chapter 5: The Converters and an XML Parser
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

5 The Converters and an XML Parser

The GAPDoc package contains a set of programs which allow us to convert a GAPDoc book into several output versions and to make them available to GAP's online help.

Currently the following output formats are provided: text for browsing inside a terminal running GAP, LaTeX with hyperref-package for cross references via hyperlinks and HTML for reading with a Web-browser.

5.1 Producing Documentation from Source Files

Here we explain how to use the functions which are described in more detail in the following sections. We assume that we have the main file MyBook.xml of a book "MyBook" in the directory /my/book/path. This contains <#Include ...>-statements as explained in Chapter 4. These refer to some other files as well as pieces of text which are found in the comments of some GAP source files ../lib/a.gd and ../lib/b.gi (relative to the path above). A BibTeX database MyBook.bib for the citations is also in the directory given above. We want to produce a text-, pdf- and HTML-version of the document. (A LaTeX version of the manual is produced, so it is also easy to compile dvi-, and postscript-versions.)

All the commands shown in this Section are collected in the single function MakeGAPDocDoc (5.1-1).

First we construct the complete XML-document as a string with ComposedDocument (4.2-1). This interprets recursively the <#Include ...>-statements.

gap> path := Directory("/my/book/path");;
gap> main := "MyBook.xml";;
gap> files := ["../lib/a.gd", "../lib/b.gi"];;
gap> bookname := "MyBook";;
gap> doc := ComposedDocument("GAPDoc", path, main, files, true);;

Now doc is a list with two entries, the first is a string containing the XML-document, the second gives information from which files and locations which part of the document was collected. This is useful in the next step, if there are any errors in the document.

Next we parse the document and store its structure in a tree-like data structure. The commands for this are ParseTreeXMLString (5.2-1) and CheckAndCleanGapDocTree (5.2-8).

gap> r := ParseTreeXMLString(doc[1], doc[2]);;
gap> CheckAndCleanGapDocTree(r);
true

We start to produce a text version of the manual, which can be read in a terminal (window). The command is GAPDoc2Text (5.3-2). This produces a record with the actual text and some additional information. The text can be written chapter-wise into files with GAPDoc2TextPrintTextFiles (5.3-3). The names of these files are chap0.txt, chap1.txt and so on. The text contains some markup using ANSI escape sequences. This markup is substituted by the GAP help system (user configurable) to show the text with colors and other attributes. For the bibliography we have to tell GAPDoc2Text (5.3-2) the location of the BibTeX database by specifying a path as second argument.

gap> t := GAPDoc2Text(r, path);;
gap> GAPDoc2TextPrintTextFiles(t, path);

This command constructs all parts of the document including table of contents, bibliography and index. The functions FormatParagraph (6.1-4) for formatting text paragraphs and ParseBibFiles (7.1-1) for reading BibTeX files with GAP may be of independent interest.

With the text version we have also produced the information which is used for searching with GAP's online help. Also, labels are produced which can be used by links in the HTML- and pdf-versions of the manual.

Next we produce a LaTeX version of the document. GAPDoc2LaTeX (5.3-1) returns a string containing the LaTeX source. The utility function FileString (6.3-5) writes the content of a string to a file, we choose MyBook.tex.

gap> l := GAPDoc2LaTeX(r);;
gap> FileString(Filename(path, Concatenation(bookname, ".tex")), l);

Assuming that you have a sufficiently good installation of TeX available (see GAPDoc2LaTeX (5.3-1) for details) this can be processed with a series of commands like in the following example.

cd /my/book/path
pdflatex MyBook
bibtex MyBook
pdflatex MyBook
makeindex MyBook
pdflatex MyBook
mv MyBook.pdf manual.pdf

After this we have a pdf-version of the document in the file manual.pdf. It contains hyperlink information which can be used with appropriate browsers for convenient reading of the document on screen (e.g., xpdf is nice because it allows remote calls to display named locations of the document). Of course, we could also use other commands like latex or dvips to process the LaTeX source file. Furthermore we have produced a file MyBook.pnr which is GAP-readable and contains the page number information for each (sub-)section of the document.

We can add this page number information to the indexing information collected by the text converter and then print a manual.six file which is read by GAP when the manual is loaded. This is done with AddPageNumbersToSix (5.3-4) and PrintSixFile (5.3-5).

gap> AddPageNumbersToSix(r, Filename(path, "MyBook.pnr"));
gap> PrintSixFile(Filename(path, "manual.six"), r, bookname);

Finally we produce an HTML-version of the document and write it (chapter-wise) into files chap0.html, chap1.html and so on. They can be read with any Web-browser. The commands are GAPDoc2HTML (5.3-7) and GAPDoc2HTMLPrintHTMLFiles (5.3-8). We also add a link from manual.html to chap0.html. You probably want to copy stylesheet files into the same directory, see 5.3-9 for more details. The argument path of GAPDoc2HTML (5.3-7) specifies the directory containing the BibTeX database files.

gap> h := GAPDoc2HTML(r, path);;
gap> GAPDoc2HTMLPrintHTMLFiles(h, path);

5.1-1 MakeGAPDocDoc
‣ MakeGAPDocDoc( path, main, files, bookname[, gaproot] )( function )

This function collects all the commands for producing a text-, pdf- and HTML-version of a GAPDoc document as described in Section 5.1. It checks the .log file from the call of pdflatex and reports if there are errors, warnings or overfull boxes.

Note: If this function works for you depends on your operating system and installed software. It will probably work on most UNIX systems with a standard LaTeX installation. If the function doesn't work for you look at the source code and adjust it to your system.

Here path must be the directory (as string or directory object) containing the main file main of the document (given with or without the .xml extension. The argument files is a list of (probably source code) files relative to path which contain pieces of documentation which must be included in the document, see Chapter 4. And bookname is the name of the book used by GAP's online help. The optional argument gaproot must be a string which gives the relative path from path to the main GAP root directory. If this is given, the HTML files are produced with relative paths to external books.

MakeGAPDocDoc can be called with additional arguments "MathJax", "Tth" and/or "MathML". If these are given additional variants of the HTML conversion are called, see GAPDoc2HTML (5.3-7) for details.

It is possible to use GAPDoc with other languages than English, see SetGapDocLanguage (5.3-13) for more details.

5.2 Parsing XML Documents

Arbitrary well-formed XML documents can be parsed and browsed by the following functions.

5.2-1 ParseTreeXMLString
‣ ParseTreeXMLString( str[, srcinfo][, entitydict] )( function )
‣ ParseTreeXMLFile( fname[, entitydict] )( function )

Returns: a record which is root of a tree structure

The first function parses an XML-document stored in string str and returns the document in form of a tree.

The optional argument srcinfo must have the same format as in OriginalPositionDocument (4.2-2). If it is given then error messages refer to the original source of the text with the problem.

With the optional argument entitydict named entities can be given to the parser, for example entities which are defined in the .dtd-file (which is not read by this parser). The standard XML-entities do not need to be provided, and for GAPDoc documents the entity definitions from gapdoc.dtd are automatically provided. Entities in the document's <!DOCTYPE declaration are parsed and also need not to be provided here. The argument entitydict must be a record where each component name is an entity name (without the surrounding & and ;) to which is assigned its substitution string.

The second function is just a shortcut for ParseTreeXMLString( StringFile(fname), ... ), see StringFile (6.3-5).

After these functions return the list of named entities which were known during the parsing can be found in the record ENTITYDICT.

A node in the result tree corresponds to an XML element, or to some parsed character data. In the first case it looks as follows:

rec( name := "Book",
     attributes := rec( Name := "EDIM" ),
     content := [ ... list of nodes for content ...],
     start := 312,
     stop := 15610,
     next := 15611     )

This means that str{[312..15610]} looks like <Book Name="EDIM"> ... content ... </Book>.

The leaves of the tree encode parsed character data as in the following example:

rec( name := "PCDATA", 
     content := "text without markup "     )

This function checks whether the XML document is well formed, see 2.1-14 for an explanation. If an error in the XML structure is found, a break loop is entered and the text around the position where the problem starts is shown. With Show(); one can browse the original input in the Pager (Reference: Pager), starting with the line where the error occurred. All entities are resolved when they are either entities defined in the GAPDoc package (in particular the standard XML entities) or if their definition is included in the <!DOCTYPE ..> tag of the document.

Note that ParseTreeXMLString does not parse and interpret the corresponding document type definition (the .dtd-file given in the <!DOCTYPE ..> tag). Hence it also does not check the validity of the document (i.e., it is no validating XML parser).

If you are using this function to parse a GAPDoc document you can use CheckAndCleanGapDocTree (5.2-8) for some validation and additional checking of the document structure.

5.2-2 StringXMLElement
‣ StringXMLElement( tree )( function )

Returns: a list [string, positions]

The argument tree must have a format of a node in the parse tree of an XML document as returned by ParseTreeXMLString (5.2-1) (including the root node representing the full document). This function computes a pair [string, positions] where string contains XML code which is equivalent to the code which was parsed to get tree. And positions is a list of lists of four numbers [eltb, elte, contb, conte]. There is one such list for each XML element occuring in string, where eltb and elte are the begin and end position of this element in string and where contb and conte are begin and end position of the content of this element, or both are 0 if there is no content.

Note that parsing XML code is an irreversible task, we can only expect to get equivalent XML code from this function. But parsing the resulting string again and applying StringXMLElement again gives the same result. See the function EntitySubstitution (5.2-3) for back-substitutions of entities in the result.

5.2-3 EntitySubstitution
‣ EntitySubstitution( xmlstring, entities )( function )

Returns: a string

The argument xmlstring must be a string containing XML code or a pair [string, positions] as returned by StringXMLElement (5.2-2). The argument entities specifies entity names (without the surrounding & and ;) and their substitution strings, either a list of pairs of strings or as a record with the names as components and the substitutions as values.

This function tries to substitute non-intersecting parts of string by the given entities. If the positions information is given then only parts of the document which allow a valid substitution by an entity are considered. Otherwise a simple text substitution without further check is done.

Note that in general the entity resolution in XML documents is a complicated and non-reversible task. But nevertheless this utility may be useful in not too complicated situations.

5.2-4 DisplayXMLStructure
‣ DisplayXMLStructure( tree )( function )

This utility displays the tree structure of an XML document as it is returned by ParseTreeXMLString (5.2-1) (without the PCDATA leaves).

Since this is usually quite long the result is shown using the Pager (Reference: Pager).

5.2-5 ApplyToNodesParseTree
‣ ApplyToNodesParseTree( tree, fun )( function )
‣ AddRootParseTree( tree )( function )
‣ RemoveRootParseTree( tree )( function )

The function ApplyToNodesParseTree applies a function fun to all nodes of the parse tree tree of an XML document returned by ParseTreeXMLString (5.2-1).

The function AddRootParseTree is an application of this. It adds to all nodes a component .root to which the top node tree tree is assigned. These components can be removed afterwards with RemoveRootParseTree.

Here are two more utilities which use ApplyToNodesParseTree.

5.2-6 GetTextXMLTree
‣ GetTextXMLTree( tree )( function )

Returns: a string

The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function collects the content of this and all included elements recursively into a string.

5.2-7 XMLElements
‣ XMLElements( tree, eltnames )( function )

Returns: a list of nodes

The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function returns a list of all subnodes of tree (possibly including tree) of elements with name given in the list of strings eltnames. Use "PCDATA" as name for leave nodes which contain the actual text of the document. As an abbreviation eltnames can also be a string which is then put in a one element list.

And here are utilities for processing GAPDoc XML documents.

5.2-8 CheckAndCleanGapDocTree
‣ CheckAndCleanGapDocTree( tree )( function )

Returns: nothing

The argument tree of this function is a parse tree from ParseTreeXMLString (5.2-1) of some GAPDoc document. This function does an (incomplete) validity check of the document according to the document type declaration in gapdoc.dtd. It also does some additional checks which cannot be described in the DTD (like checking whether chapters and sections have a heading). For elements with element content the whitespace between these elements is removed.

In case of an error the break loop is entered and the position of the error in the original XML document is printed. With Show(); one can browse the original input in the Pager (Reference: Pager).

5.2-9 AddParagraphNumbersGapDocTree
‣ AddParagraphNumbersGapDocTree( tree )( function )

Returns: nothing

The argument tree must be an XML tree returned by ParseTreeXMLString (5.2-1) applied to a GAPDoc document. This function adds to each node of the tree a component .count which is of form [Chapter[, Section[, Subsection, Paragraph] ] ]. Here the first three numbers should be the same as produced by the LaTeX version of the document. Text before the first chapter is counted as chapter 0 and similarly for sections and subsections. Some elements are always considered to start a new paragraph.

5.2-10 InfoXMLParser
‣ InfoXMLParser( info class )

The default level of this info class is 1. Functions like ParseTreeXMLString (5.2-1) are then printing some information, in particular in case of errors. You can suppress it by setting the level of InfoXMLParser to 0. With level 2 there may be some more information for debugging purposes.

5.3 The Converters

Here are more details about the conversion programs for GAPDoc XML documents.

5.3-1 GAPDoc2LaTeX
‣ GAPDoc2LaTeX( tree )( function )

Returns: LaTeX document as string

‣ SetGapDocLaTeXOptions( [...] )( function )

Returns: Nothing

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). The output is a string containing a version of the document which can be written to a file and processed with LaTeX or pdfLaTeX (and probably BibTeX and makeindex).

The output uses the report document class and needs the following LaTeX packages: a4wide, amssymb, inputenc, makeidx, color, fancyvrb, psnfss, pslatex, enumitem and hyperref. These are for example provided by the teTeX-1.0 or texlive distributions of TeX (which in turn are used for most TeX packages of current Linux distributions); see http://www.tug.org/tetex/.

In particular, the resulting pdf-output (and dvi-output) contains (internal and external) hyperlinks which can be very useful for onscreen browsing of the document.

The LaTeX processing also produces a file with extension .pnr which is GAP readable and contains the page numbers for all (sub)sections of the document. This can be used by GAP's online help; see AddPageNumbersToSix (5.3-4). Non-ASCII characters in the GAPDoc document are translated to LaTeX input in ASCII-encoding with the help of Encode (6.2-2) and the option "LaTeX". See the documentation of Encode (6.2-2) for how to proceed if you have a character which is not handled (yet).

This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2LaTeXProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust layout details to your own taste by slight modifications of the program.

Former versions of GAPDoc supported some XML processing instructions to add some extra lines to the preamble of the LaTeX document. Its use is now deprecated, use the much more flexible SetGapDocLaTeXOptions instead: The default layout of the resulting documents can be changed with SetGapDocLaTeXOptions. This changes parts of the header of the LaTeX file produced by GAPDoc. You can see the header with some placeholders by Page(GAPDoc2LaTeXProcs.Head);. The placeholders are filled with components from the record GAPDoc2LaTeXProcs.DefaultOptions. The arguments of SetGapDocLaTeXOptions can be records with the same structure (or parts of it) with different values. As abbreviations there are also three strings supported as arguments. These are "nocolor" for switching all colors to black; then "nopslatex" to use standard LaTeX fonts instead of postscript fonts; and finally "utf8" to choose UTF-8 as input encoding for the LaTeX document.

5.3-2 GAPDoc2Text
‣ GAPDoc2Text( tree[, bibpath][, width] )( function )

Returns: record containing text files as strings and other information

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). This function produces a text version of the document which can be used with GAP's online help (with the "screen" viewer, see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography and index. The bibliography is made from BibXMLext or BibTeX databases, see 7. Their location must be given with the argument bibpath (as string or directory object).

The output is a record with one component for each chapter (with names "0", "1", ..., "Bib" and "Ind"). Each such component is again a record with the following components:

text

the text of the whole chapter as a string

ssnr

list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1)

linenr

corresponding list of line numbers where the subsections start

len

number of lines of this chapter

The result can be written into files with the command GAPDoc2TextPrintTextFiles (5.3-3).

As a side effect this function also produces the manual.six information which is used for searching in GAP's online help. This is stored in tree.six and can be printed into a manual.six file with PrintSixFile (5.3-5) (preferably after producing a LaTeX version of the document as well and adding the page number information to tree.six, see GAPDoc2LaTeX (5.3-1) and AddPageNumbersToSix (5.3-4)).

The text produced by this function contains some markup via ANSI escape sequences. The sequences used here are usually ignored by terminals. But the GAP help system will substitute them by interpreted color and attribute sequences (see TextAttr (6.1-2)) before displaying them. There is a default markup used for this but it can also be configured by the user, see SetGAPDocTextTheme (5.3-6). Furthermore, the text produced is in UTF-8 encoding. The encoding is also translated on the fly, if GAPInfo.TermEncoding is set to some encoding supported by Encode (6.2-2), e.g., "ISO-8859-1" or "latin1".

With the optional argument width a different length of the output text lines can be chosen. The default is 76 and all lines in the resulting text start with two spaces. This looks good on a terminal with a standard width of 80 characters and you probably don't want to use this argument.

5.3-3 GAPDoc2TextPrintTextFiles
‣ GAPDoc2TextPrintTextFiles( t[, path] )( function )

Returns: nothing

The first argument must be a result returned by GAPDoc2Text (5.3-2). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.txt, chap1.txt, ..., chapBib.txt, and chapInd.txt.

If you want to make your document accessible via the GAP online help you must put at least these files for the text version into a directory, together with the file manual.six, see PrintSixFile (5.3-5). Then specify the path to the manual.six file in the packages PackageInfo.g file, see Reference: The PackageInfo.g File.

Optionally you can add the dvi- and pdf-versions of the document which are produced with GAPDoc2LaTeX (5.3-1) to this directory. The files must have the names manual.dvi and manual.pdf, respectively. Also you can add the files of the HTML version produced with GAPDoc2HTML (5.3-7) to this directory, see GAPDoc2HTMLPrintHTMLFiles (5.3-8). The handler functions in GAP for this help format detect automatically which of the optional formats of a book are actually available.

5.3-4 AddPageNumbersToSix
‣ AddPageNumbersToSix( tree, pnrfile )( function )

Returns: nothing

Here tree must be the XML tree of a GAPDoc document, returned by ParseTreeXMLString (5.2-1). Running latex on the result of GAPDoc2LaTeX(tree) produces a file pnrfile (with extension .pnr). The command GAPDoc2Text(tree) creates a component tree.six which contains all information about the document for the GAP online help, except the page numbers in the .dvi, .ps, .pdf versions of the document. This command adds the missing page number information to tree.six.

5.3-5 PrintSixFile
‣ PrintSixFile( tree, bookname, fname )( function )

Returns: nothing

This function prints the .six file fname for a GAPDoc document stored in tree with name bookname. Such a file contains all information about the book which is needed by the GAP online help. This information must first be created by calls of GAPDoc2Text (5.3-2) and AddPageNumbersToSix (5.3-4).

5.3-6 SetGAPDocTextTheme
‣ SetGAPDocTextTheme( [optrec1[, optrec2], ...] )( function )

Returns: nothing

This utility function is for readers of the screen version of GAP manuals which are generated by the GAPDoc package. It allows to configure the color and attribute layout of the displayed text. There is a default which can be reset by calling this function without argument.

As an abbreviation the arguments optrec1 and so on can be strings for the known name of a theme. Information about valid names is shown with SetGAPDocTextTheme("");.

Otherwise, optrec1 and so on must be a record. Its entries overwrite the corresponding entries in the default and in previous arguments. To construct valid markup you can use TextAttr (6.1-2). Entries must be either pairs of strings, which are put before and after the corresponding text, or as an abbreviation it can be a single string. In the latter case, the second string is implied; if the string contains an escape sequence the second string is TextAttr.reset, otherwise the given string is used. The following components are recognized:

flush

"both" for left-right justified paragraphs, and "left" for ragged right ones

Heading

chapter and (sub-)section headings

Func

function, operation, ... names

Arg

argument names in descriptions

Example

example code

Package

package names

Returns

Returns-line in descriptions

URL

URLs

Mark

Marks in description lists

K

GAP keywords

C

code or text to type

F

file names

B

buttons

M

simplified math elements

Math

normal math elements

Display

displayed math elements

Emph

emphasized text

Q

quoted text

Ref

reference text

Prompt

GAP prompt in examples

BrkPrompt

GAP break prompt in examples

GAPInput

GAP input in examples

reset

reset to default, don't change this

BibAuthor

author names in bibliography

BibTitle

titles in bibliography

BibJournal

journal names in bibliography

BibVolume

volume number in bibliography

BibLabel

labels for bibliography entries

BibReset

reset for bibliography, don't change

ListBullet

bullet for simple lists (2 visible characters long)

EnumMarks

one visible character before and after the number in enumerated lists

DefLineMarker

marker before function and variable definitions (2 visible characters long)

FillString

for filling in definitions and example separator lines

gap> # use no colors for GAP examples and 
gap> # change display of headings to bold green
gap> SetGAPDocTextTheme("noColorPrompt", 
>            rec(Heading:=Concatenation(TextAttr.bold, TextAttr.2)));

5.3-7 GAPDoc2HTML
‣ GAPDoc2HTML( tree[, bibpath[, gaproot]][, mtrans] )( function )

Returns: record containing HTML files as strings and other information

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). Without an mtrans argument this function produces an HTML version of the document which can be read with any Web-browser and also be used with GAP's online help (see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography, and index. The bibliography is made from BibTeX databases. Their location must be given with the argument bibpath (as string or directory object, if not given the current directory is used). If the third argument gaproot is given and is a string then this string is interpreted as relative path to GAP's main root directory. Reference-URLs to external HTML-books which begin with the GAP root path are then rewritten to start with the given relative path. This makes the HTML-documentation portable provided a package is installed in some standard location below the GAP root.

The output is a record with one component for each chapter (with names "0", "1", ..., "Bib", and "Ind"). Each such component is again a record with the following components:

text

the text of an HTML file containing the whole chapter (as a string)

ssnr

list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1)

Standard output format without mtrans argument

The HTML code produced with this converter conforms to the W3C specification "XHTML 1.0 strict", see http://www.w3.org/TR/xhtml1. First, this means that the HTML files are valid XML files. Secondly, the extension "strict" says in particular that the code doesn't contain any explicit font or color information.

Mathematical formulae are handled as in the text converter GAPDoc2Text (5.3-2). We don't want to assume that the browser can use symbol fonts. Some GAP users like to browse the online help with lynx, see SetHelpViewer (Reference: SetHelpViewer), which runs inside the same terminal windows as GAP.

To view the generated files in graphical browsers, stylesheet files with layout configuration should be copied into the directory with the generated HTML files, see 5.3-9.

Output format with mtrans argument

Currently, there are three variants of this converter available which handle mathematical formulae differently. They are accessed via the optional last mtrans argument.

If mtrans is set to "MathJax" the formulae are essentially translated as for LaTeX documents (there is no processing of <M> elements as decribed in 3.8-2). Inline formulae are delimited by \( and \) and displayed formulae by \[ and \]. With MathJax webpages can contain nicely formatted scalable and searchable formulae. The resulting files link by default to http://cdn.mathjax.org to get the MathJax script and fonts. This means that they can only be used on computers with internet access. An alternative URL can be set by overwriting GAPDoc2HTMLProcs.MathJaxURL before building the HTML version of a manual. This way a local installation of MathJax could be used. See http://www.mathjax.org/ for more details.

The following possibilities for mtrans are still supported, but since the MathJax approach seems much better, their use is deprecated.

If the argument mtrans is set to "Tth" it is assumed that you have installed the LaTeX to HTML translation program tth. This is used to translate the contents of the M, Math and Display elements into HTML code. Note that the resulting code is not compliant with any standard. Formally it is "XHTML 1.0 Transitional", it contains explicit font specifications and the characters of mathematical symbols are included via their position in a "Symbol" font. Some graphical browsers can be configured to display this in a useful manner, check the Tth homepage for more details.

If the mtrans argument is set to "MathML" it is assumed that you have installed the translation program ttm, see also the Tth homepage). This is used to translate the contents of the M, Math and Display elements to MathML 2.0 markup. The resulting files should conform to the "XHTML 1.1 plus MathML 2.0" standard, see the W3C information for more details. It is expected that the next generation of graphical browsers will be able to render such files (try for example Mozilla, at least 0.9.9). You must copy the .xsl and .css files from GAPDocs mathml directory to the directory containing the output files. The translation with ttm is still experimental. The output of this converter variant is garbage for browsers which don't support MathML.

This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2TextProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust certain details to your own taste by slight modifications of the program.

The result of this converter can be written to files with the command GAPDoc2HTMLPrintHTMLFiles (5.3-8).

There are two user preferences for reading the HTML manuals produced by GAPDoc. A user can choose among several style files which determine the appearance of the manual pages with SetUserPreference("GAPDoc", "HTMLStyle", [...]); where the list in the third argument are arguments for SetGAPDocHTMLStyle (5.3-11). The second preference is set by SetUserPreference("GAPDoc", "UseMathJax", ...); where the third argument is true or false (default). If this is set to true, the GAP help system displays the MathJax version of the HTML manuals.

5.3-8 GAPDoc2HTMLPrintHTMLFiles
‣ GAPDoc2HTMLPrintHTMLFiles( t[, path] )( function )

Returns: nothing

The first argument must be a result returned by GAPDoc2HTML (5.3-7). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.html, chap1.html, ..., chapBib.html, and chapInd.html.

The MathJax versions are written to files chap0_mj.html, ..., chapInd_mj.html.

The experimental versions which are produced with tth or ttm use different names for the files, namely chap0_sym.html, and so on for files which need symbol fonts and chap0_mml.xml for files with MathML translations.

You should also add stylesheet files to the directory with the HTML files, see 5.3-9.

5.3-9 Stylesheet files

For graphical browsers the layout of the generated HTML manuals can be highly configured by cascading stylesheet (CSS) and javascript files. Such files are provided in the styles directory of the GAPDoc package.

We recommend that these files are copied into each manual directory (such that each of them is selfcontained). There is a utility function CopyHTMLStyleFiles (5.3-10) which does this. Of course, these files may be changed or new styles may be added. New styles may also be sent to the GAPDoc authors for possible inclusion in future versions.

The generated HTML files refer to the file manual.css which conforms to the W3C specification CSS 2.0, see http://www.w3.org/TR/REC-CSS2, and the javascript file manual.js (only in browsers which support CSS or javascript, respectively; but the HTML files are also readable without any of them). To add a style mystyle one or both of mystyle.css and mystyle.js must be provided; these can overwrite default settings and add new javascript functions. For more details see the comments in manual.js.

5.3-10 CopyHTMLStyleFiles
‣ CopyHTMLStyleFiles( dir )( function )

Returns: nothing

This utility function copies the *.css and *.js files from the styles directory of the GAPDoc package into the directory dir.

5.3-11 SetGAPDocHTMLStyle
‣ SetGAPDocHTMLStyle( [style1[, style2], ...] )( function )

Returns: nothing

This utility function is for readers of the HTML version of GAP manuals which are generated by the GAPDoc package. It allows to configure the display style of the manuals. This will only have an effect if you are using a browser that supports javascript. There is a default which can be reset by calling this function without argument.

The arguments style1 and so on must be strings. You can find out about the valid strings by following the [Style] link on top of any manual page. (Going back to the original page, its address has a setting for GAPDocStyle which is the list of strings, separated by commas, you want to use here.)

gap> # show/hide subsections in tables on contents only after click,
gap> # and don't use colors in GAP examples
gap> SetGAPDocHTMLStyle("toggless", "nocolorprompt");

5.3-12 InfoGAPDoc
‣ InfoGAPDoc( info class )

The default level of this info class is 1. The converter functions for GAPDoc documents are then printing some information. You can suppress this by setting the level of InfoGAPDoc to 0. With level 2 there may be some more information for debugging purposes.

5.3-13 SetGapDocLanguage
‣ SetGapDocLanguage( [lang] )( function )

Returns: nothing

The GAPDoc converter programs sometimes produce text which is not explicit in the document, e.g., headers like "Abstract", "Appendix", links to "Next Chapter", variable types "function" and so on.

With SetGapDocLanguage the language for these texts can be changed. The argument lang must be a string. Calling without argument or with a language name for which no translations are available is the same as using the default "english".

If your language lang is not yet available, look at the record GAPDocTexts.english and translate all the strings to lang. Then assign this record to GAPDocTexts.(lang) and send it to the GAPDoc authors for inclusion in future versions of GAPDoc. (Currently, there are translations for english, german, russian and ukrainian.)

Further hints: To get strings produced by LaTeX right you will probably use the babel package with option lang, see the information on ExtraPreamble in GAPDoc2LaTeX (5.3-1). If lang cannot be encoded in latin1 encoding you can consider the use of "utf8" with SetGapDocLaTeXOptions (5.3-1).

5.4 Testing Manual Examples

We also provide some tools to check and adjust the examples given in <Example>-elements.

Former versions of GAPDoc provided functions ManualExamples and TestManualExamples. These functions are still available, but no longer documented. Their use is deprecated.

5.4-1 ExtractExamples
‣ ExtractExamples( path, main, files, units )( function )

Returns: a list of lists

‣ ExtractExamplesXMLTree( tree, units )( function )

Returns: a list of lists

The argument tree must be a parse tree of a GAPDoc document, see ParseTreeXMLFile (5.2-1). The function ExtractExamplesXMLTree returns a data structure representing the <Example> elements of the document. The return value can be used with RunExamples (5.4-2) to check and optionally update the examples of the document.

Depending on the argument units several examples are collected in one list. Recognized values for units are "Chapter", "Section", "Subsection" or "Single". The latter means that each example is in a separate list. For all other value of units just one list with all examples is returned.

The arguments path, main and files of ExtractExamples are the same as for ComposedDocument (4.2-1). This function first contructs and parses the GAPDoc document and then applies ExtractExamplesXMLTree.

5.4-2 RunExamples
‣ RunExamples( exmpls[, optrec] )( function )

Returns: nothing

The argument exmpls must be the output of a call to ExtractExamples (5.4-1) or ExtractExamplesXMLTree (5.4-1). The optional argument optrec must be a record, its components can change the default behaviour of this function.

By default this function runs the GAP input of all examples and compares the actual output with the output given in the examples. If differences occur these are displayed together with information on the location of the source code of that example. Before running the examples in each unit (entry of exmpls) the function START_TEST (Reference: START_TEST) is called and the screen width is set to 72 characters.

If the argument optrec is given, the following components are recognized:

showDiffs

The default value is true, if set to something else found differences in the examples are not displayed.

width

The value must be a positive integer which is used as screen width when running the examples. As mentioned above, the default is 72 which is a sensible value for the text version of the GAPDoc document used in a 80 character wide terminal.

changeSources

If this is set to true then the source code of all manual examples which show differences is adjusted to the current outputs. The default is false.
Use this feature with care. Note that sometimes differences can indicate a bug, and in such a case it is more appropriate to fix the bug instead of changing the example output.

compareFunction

The function used to compare the output shown in the example and the current output. See Test (Reference: Test) for more details.

checkWidth

If this option is a positive integer n the function prints warnings if an example contains any line with more than n characters (input and output lines are considered). By default this option is set to false.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap0_mj.html0000644000175000017500000010641312026346063014324 0ustar billbill GAP (GAPDoc) - Contents
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

GAPDoc

( Version 1.5.1 )

February 2012

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De
Homepage: http://www.math.rwth-aachen.de/~Frank.Luebeck

Max Neunhöffer
Email: neunhoef at mcs.st-and.ac.uk
Homepage: http://www-groups.mcs.st-and.ac.uk/~neunhoef/

Copyright

© 2000-2012 by Frank Lübeck and Max Neunhöffer

GAPDoc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Contents

3 The Document Type Definition

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/gapdoc.toc0000644000175000017500000005537012026346063013726 0ustar billbill\contentsline {chapter}{\numberline {1}\leavevmode {\color {Chapter }Introduction and Example}}{5}{chapter.1} \contentsline {section}{\numberline {1.1}\leavevmode {\color {Chapter }XML}}{5}{section.1.1} \contentsline {section}{\numberline {1.2}\leavevmode {\color {Chapter }A complete example}}{6}{section.1.2} \contentsline {section}{\numberline {1.3}\leavevmode {\color {Chapter }Some questions}}{9}{section.1.3} \contentsline {chapter}{\numberline {2}\leavevmode {\color {Chapter }How To Type a \textsf {GAPDoc} Document}}{10}{chapter.2} \contentsline {section}{\numberline {2.1}\leavevmode {\color {Chapter }General XML Syntax}}{10}{section.2.1} \contentsline {subsection}{\numberline {2.1.1}\leavevmode {\color {Chapter }Head of XML Document}}{10}{subsection.2.1.1} \contentsline {subsection}{\numberline {2.1.2}\leavevmode {\color {Chapter }Comments}}{10}{subsection.2.1.2} \contentsline {subsection}{\numberline {2.1.3}\leavevmode {\color {Chapter }Processing Instructions}}{11}{subsection.2.1.3} \contentsline {subsection}{\numberline {2.1.4}\leavevmode {\color {Chapter }Names in XML and Whitespace}}{11}{subsection.2.1.4} \contentsline {subsection}{\numberline {2.1.5}\leavevmode {\color {Chapter }Elements}}{11}{subsection.2.1.5} \contentsline {subsection}{\numberline {2.1.6}\leavevmode {\color {Chapter }Start Tags}}{11}{subsection.2.1.6} \contentsline {subsection}{\numberline {2.1.7}\leavevmode {\color {Chapter }End Tags}}{11}{subsection.2.1.7} \contentsline {subsection}{\numberline {2.1.8}\leavevmode {\color {Chapter }Combined Tags for Empty Elements}}{11}{subsection.2.1.8} \contentsline {subsection}{\numberline {2.1.9}\leavevmode {\color {Chapter }Entities}}{12}{subsection.2.1.9} \contentsline {subsection}{\numberline {2.1.10}\leavevmode {\color {Chapter }Special Characters in XML}}{12}{subsection.2.1.10} \contentsline {subsection}{\numberline {2.1.11}\leavevmode {\color {Chapter }Rules for Attribute Values}}{12}{subsection.2.1.11} \contentsline {subsection}{\numberline {2.1.12}\leavevmode {\color {Chapter }\texttt {CDATA}}}{12}{subsection.2.1.12} \contentsline {subsection}{\numberline {2.1.13}\leavevmode {\color {Chapter }Encoding of an XML Document}}{12}{subsection.2.1.13} \contentsline {subsection}{\numberline {2.1.14}\leavevmode {\color {Chapter }Well Formed and Valid XML Documents}}{13}{subsection.2.1.14} \contentsline {section}{\numberline {2.2}\leavevmode {\color {Chapter }Entering \textsf {GAPDoc} Documents}}{13}{section.2.2} \contentsline {subsection}{\numberline {2.2.1}\leavevmode {\color {Chapter }Other special characters}}{13}{subsection.2.2.1} \contentsline {subsection}{\numberline {2.2.2}\leavevmode {\color {Chapter }Mathematical Formulae}}{13}{subsection.2.2.2} \contentsline {subsection}{\numberline {2.2.3}\leavevmode {\color {Chapter }More Entities}}{14}{subsection.2.2.3} \contentsline {chapter}{\numberline {3}\leavevmode {\color {Chapter }The Document Type Definition}}{15}{chapter.3} \contentsline {section}{\numberline {3.1}\leavevmode {\color {Chapter }What is a DTD?}}{15}{section.3.1} \contentsline {section}{\numberline {3.2}\leavevmode {\color {Chapter }Overall Document Structure}}{15}{section.3.2} \contentsline {subsection}{\numberline {3.2.1}\leavevmode {\color {Chapter }\texttt {{\textless }Book{\textgreater }}}}{16}{subsection.3.2.1} \contentsline {subsection}{\numberline {3.2.2}\leavevmode {\color {Chapter }\texttt {{\textless }TitlePage{\textgreater }}}}{16}{subsection.3.2.2} \contentsline {subsection}{\numberline {3.2.3}\leavevmode {\color {Chapter }\texttt {{\textless }Title{\textgreater }}}}{16}{subsection.3.2.3} \contentsline {subsection}{\numberline {3.2.4}\leavevmode {\color {Chapter }\texttt {{\textless }Subtitle{\textgreater }}}}{17}{subsection.3.2.4} \contentsline {subsection}{\numberline {3.2.5}\leavevmode {\color {Chapter }\texttt {{\textless }Version{\textgreater }}}}{17}{subsection.3.2.5} \contentsline {subsection}{\numberline {3.2.6}\leavevmode {\color {Chapter }\texttt {{\textless }TitleComment{\textgreater }}}}{18}{subsection.3.2.6} \contentsline {subsection}{\numberline {3.2.7}\leavevmode {\color {Chapter }\texttt {{\textless }Author{\textgreater }}}}{18}{subsection.3.2.7} \contentsline {subsection}{\numberline {3.2.8}\leavevmode {\color {Chapter }\texttt {{\textless }Date{\textgreater }}}}{18}{subsection.3.2.8} \contentsline {subsection}{\numberline {3.2.9}\leavevmode {\color {Chapter }\texttt {{\textless }Address{\textgreater }}}}{18}{subsection.3.2.9} \contentsline {subsection}{\numberline {3.2.10}\leavevmode {\color {Chapter }\texttt {{\textless }Abstract{\textgreater }}}}{18}{subsection.3.2.10} \contentsline {subsection}{\numberline {3.2.11}\leavevmode {\color {Chapter }\texttt {{\textless }Copyright{\textgreater }}}}{18}{subsection.3.2.11} \contentsline {subsection}{\numberline {3.2.12}\leavevmode {\color {Chapter }\texttt {{\textless }Acknowledgements{\textgreater }}}}{19}{subsection.3.2.12} \contentsline {subsection}{\numberline {3.2.13}\leavevmode {\color {Chapter }\texttt {{\textless }Colophon{\textgreater }}}}{19}{subsection.3.2.13} \contentsline {subsection}{\numberline {3.2.14}\leavevmode {\color {Chapter }\texttt {{\textless }TableOfContents{\textgreater }}}}{19}{subsection.3.2.14} \contentsline {subsection}{\numberline {3.2.15}\leavevmode {\color {Chapter }\texttt {{\textless }Bibliography{\textgreater }} }}{19}{subsection.3.2.15} \contentsline {subsection}{\numberline {3.2.16}\leavevmode {\color {Chapter }\texttt {{\textless }TheIndex{\textgreater }}}}{20}{subsection.3.2.16} \contentsline {section}{\numberline {3.3}\leavevmode {\color {Chapter }Sectioning Elements}}{20}{section.3.3} \contentsline {subsection}{\numberline {3.3.1}\leavevmode {\color {Chapter }\texttt {{\textless }Body{\textgreater }}}}{20}{subsection.3.3.1} \contentsline {subsection}{\numberline {3.3.2}\leavevmode {\color {Chapter }\texttt {{\textless }Chapter{\textgreater }}}}{20}{subsection.3.3.2} \contentsline {subsection}{\numberline {3.3.3}\leavevmode {\color {Chapter }\texttt {{\textless }Heading{\textgreater }}}}{21}{subsection.3.3.3} \contentsline {subsection}{\numberline {3.3.4}\leavevmode {\color {Chapter }\texttt {{\textless }Appendix{\textgreater }}}}{21}{subsection.3.3.4} \contentsline {subsection}{\numberline {3.3.5}\leavevmode {\color {Chapter }\texttt {{\textless }Section{\textgreater }}}}{21}{subsection.3.3.5} \contentsline {subsection}{\numberline {3.3.6}\leavevmode {\color {Chapter }\texttt {{\textless }Subsection{\textgreater }}}}{21}{subsection.3.3.6} \contentsline {section}{\numberline {3.4}\leavevmode {\color {Chapter }ManSection{\textendash }a special kind of subsection}}{22}{section.3.4} \contentsline {subsection}{\numberline {3.4.1}\leavevmode {\color {Chapter }\texttt {{\textless }ManSection{\textgreater }}}}{22}{subsection.3.4.1} \contentsline {subsection}{\numberline {3.4.2}\leavevmode {\color {Chapter }\texttt {{\textless }Func{\textgreater }}}}{22}{subsection.3.4.2} \contentsline {subsection}{\numberline {3.4.3}\leavevmode {\color {Chapter }\texttt {{\textless }Oper{\textgreater }}}}{23}{subsection.3.4.3} \contentsline {subsection}{\numberline {3.4.4}\leavevmode {\color {Chapter }\texttt {{\textless }Meth{\textgreater }}}}{23}{subsection.3.4.4} \contentsline {subsection}{\numberline {3.4.5}\leavevmode {\color {Chapter }\texttt {{\textless }Filt{\textgreater }}}}{24}{subsection.3.4.5} \contentsline {subsection}{\numberline {3.4.6}\leavevmode {\color {Chapter }\texttt {{\textless }Prop{\textgreater }}}}{24}{subsection.3.4.6} \contentsline {subsection}{\numberline {3.4.7}\leavevmode {\color {Chapter }\texttt {{\textless }Attr{\textgreater }}}}{24}{subsection.3.4.7} \contentsline {subsection}{\numberline {3.4.8}\leavevmode {\color {Chapter }\texttt {{\textless }Var{\textgreater }}}}{24}{subsection.3.4.8} \contentsline {subsection}{\numberline {3.4.9}\leavevmode {\color {Chapter }\texttt {{\textless }Fam{\textgreater }}}}{25}{subsection.3.4.9} \contentsline {subsection}{\numberline {3.4.10}\leavevmode {\color {Chapter }\texttt {{\textless }InfoClass{\textgreater }}}}{25}{subsection.3.4.10} \contentsline {section}{\numberline {3.5}\leavevmode {\color {Chapter }Cross Referencing and Citations}}{25}{section.3.5} \contentsline {subsection}{\numberline {3.5.1}\leavevmode {\color {Chapter }\texttt {{\textless }Ref{\textgreater }}}}{25}{subsection.3.5.1} \contentsline {subsection}{\numberline {3.5.2}\leavevmode {\color {Chapter }\texttt {{\textless }Label{\textgreater }}}}{26}{subsection.3.5.2} \contentsline {subsection}{\numberline {3.5.3}\leavevmode {\color {Chapter }\texttt {{\textless }Cite{\textgreater }}}}{26}{subsection.3.5.3} \contentsline {subsection}{\numberline {3.5.4}\leavevmode {\color {Chapter }\texttt {{\textless }Index{\textgreater }}}}{27}{subsection.3.5.4} \contentsline {subsection}{\numberline {3.5.5}\leavevmode {\color {Chapter }\texttt {{\textless }URL{\textgreater }}}}{27}{subsection.3.5.5} \contentsline {subsection}{\numberline {3.5.6}\leavevmode {\color {Chapter }\texttt {{\textless }Email{\textgreater }}}}{27}{subsection.3.5.6} \contentsline {subsection}{\numberline {3.5.7}\leavevmode {\color {Chapter }\texttt {{\textless }Homepage{\textgreater }}}}{28}{subsection.3.5.7} \contentsline {section}{\numberline {3.6}\leavevmode {\color {Chapter }Structural Elements like Lists}}{28}{section.3.6} \contentsline {subsection}{\numberline {3.6.1}\leavevmode {\color {Chapter }\texttt {{\textless }List{\textgreater }}}}{28}{subsection.3.6.1} \contentsline {subsection}{\numberline {3.6.2}\leavevmode {\color {Chapter }\texttt {{\textless }Mark{\textgreater }}}}{28}{subsection.3.6.2} \contentsline {subsection}{\numberline {3.6.3}\leavevmode {\color {Chapter }\texttt {{\textless }Item{\textgreater }}}}{28}{subsection.3.6.3} \contentsline {subsection}{\numberline {3.6.4}\leavevmode {\color {Chapter }\texttt {{\textless }Enum{\textgreater }}}}{28}{subsection.3.6.4} \contentsline {subsection}{\numberline {3.6.5}\leavevmode {\color {Chapter }\texttt {{\textless }Table{\textgreater }}}}{29}{subsection.3.6.5} \contentsline {section}{\numberline {3.7}\leavevmode {\color {Chapter }Types of Text}}{29}{section.3.7} \contentsline {subsection}{\numberline {3.7.1}\leavevmode {\color {Chapter }\texttt {{\textless }Emph{\textgreater }} and \texttt {{\textless }E{\textgreater }}}}{29}{subsection.3.7.1} \contentsline {subsection}{\numberline {3.7.2}\leavevmode {\color {Chapter }\texttt {{\textless }Quoted{\textgreater }} and \texttt {{\textless }Q{\textgreater }}}}{30}{subsection.3.7.2} \contentsline {subsection}{\numberline {3.7.3}\leavevmode {\color {Chapter }\texttt {{\textless }Keyword{\textgreater }} and \texttt {{\textless }K{\textgreater }}}}{30}{subsection.3.7.3} \contentsline {subsection}{\numberline {3.7.4}\leavevmode {\color {Chapter }\texttt {{\textless }Arg{\textgreater }} and \texttt {{\textless }A{\textgreater }}}}{30}{subsection.3.7.4} \contentsline {subsection}{\numberline {3.7.5}\leavevmode {\color {Chapter }\texttt {{\textless }Code{\textgreater }} and \texttt {{\textless }C{\textgreater }}}}{30}{subsection.3.7.5} \contentsline {subsection}{\numberline {3.7.6}\leavevmode {\color {Chapter }\texttt {{\textless }File{\textgreater }} and \texttt {{\textless }F{\textgreater }}}}{30}{subsection.3.7.6} \contentsline {subsection}{\numberline {3.7.7}\leavevmode {\color {Chapter }\texttt {{\textless }Button{\textgreater }} and \texttt {{\textless }B{\textgreater }}}}{31}{subsection.3.7.7} \contentsline {subsection}{\numberline {3.7.8}\leavevmode {\color {Chapter }\texttt {{\textless }Package{\textgreater }}}}{31}{subsection.3.7.8} \contentsline {subsection}{\numberline {3.7.9}\leavevmode {\color {Chapter }\texttt {{\textless }Listing{\textgreater }}}}{31}{subsection.3.7.9} \contentsline {subsection}{\numberline {3.7.10}\leavevmode {\color {Chapter }\texttt {{\textless }Log{\textgreater }} and \texttt {{\textless }Example{\textgreater }}}}{31}{subsection.3.7.10} \contentsline {subsection}{\numberline {3.7.11}\leavevmode {\color {Chapter }\texttt {{\textless }Verb{\textgreater }}}}{32}{subsection.3.7.11} \contentsline {section}{\numberline {3.8}\leavevmode {\color {Chapter }Elements for Mathematical Formulae}}{32}{section.3.8} \contentsline {subsection}{\numberline {3.8.1}\leavevmode {\color {Chapter }\texttt {{\textless }Math{\textgreater }} and \texttt {{\textless }Display{\textgreater }}}}{32}{subsection.3.8.1} \contentsline {subsection}{\numberline {3.8.2}\leavevmode {\color {Chapter }\texttt {{\textless }M{\textgreater }}}}{32}{subsection.3.8.2} \contentsline {section}{\numberline {3.9}\leavevmode {\color {Chapter }Everything else}}{35}{section.3.9} \contentsline {subsection}{\numberline {3.9.1}\leavevmode {\color {Chapter }\texttt {{\textless }Alt{\textgreater }}}}{35}{subsection.3.9.1} \contentsline {subsection}{\numberline {3.9.2}\leavevmode {\color {Chapter }\texttt {{\textless }Par{\textgreater }} and \texttt {{\textless }P{\textgreater }}}}{35}{subsection.3.9.2} \contentsline {subsection}{\numberline {3.9.3}\leavevmode {\color {Chapter }\texttt {{\textless }Br{\textgreater }}}}{35}{subsection.3.9.3} \contentsline {subsection}{\numberline {3.9.4}\leavevmode {\color {Chapter }\texttt {{\textless }Ignore{\textgreater }}}}{36}{subsection.3.9.4} \contentsline {chapter}{\numberline {4}\leavevmode {\color {Chapter }Distributing a Document into Several Files}}{37}{chapter.4} \contentsline {section}{\numberline {4.1}\leavevmode {\color {Chapter }The Conventions}}{37}{section.4.1} \contentsline {section}{\numberline {4.2}\leavevmode {\color {Chapter }A Tool for Collecting a Document}}{38}{section.4.2} \contentsline {subsection}{\numberline {4.2.1}\leavevmode {\color {Chapter }ComposedDocument}}{38}{subsection.4.2.1} \contentsline {subsection}{\numberline {4.2.2}\leavevmode {\color {Chapter }OriginalPositionDocument}}{39}{subsection.4.2.2} \contentsline {chapter}{\numberline {5}\leavevmode {\color {Chapter }The Converters and an XML Parser}}{40}{chapter.5} \contentsline {section}{\numberline {5.1}\leavevmode {\color {Chapter }Producing Documentation from Source Files}}{40}{section.5.1} \contentsline {subsection}{\numberline {5.1.1}\leavevmode {\color {Chapter }MakeGAPDocDoc}}{42}{subsection.5.1.1} \contentsline {section}{\numberline {5.2}\leavevmode {\color {Chapter }Parsing XML Documents}}{42}{section.5.2} \contentsline {subsection}{\numberline {5.2.1}\leavevmode {\color {Chapter }ParseTreeXMLString}}{42}{subsection.5.2.1} \contentsline {subsection}{\numberline {5.2.2}\leavevmode {\color {Chapter }StringXMLElement}}{43}{subsection.5.2.2} \contentsline {subsection}{\numberline {5.2.3}\leavevmode {\color {Chapter }EntitySubstitution}}{44}{subsection.5.2.3} \contentsline {subsection}{\numberline {5.2.4}\leavevmode {\color {Chapter }DisplayXMLStructure}}{44}{subsection.5.2.4} \contentsline {subsection}{\numberline {5.2.5}\leavevmode {\color {Chapter }ApplyToNodesParseTree}}{44}{subsection.5.2.5} \contentsline {subsection}{\numberline {5.2.6}\leavevmode {\color {Chapter }GetTextXMLTree}}{45}{subsection.5.2.6} \contentsline {subsection}{\numberline {5.2.7}\leavevmode {\color {Chapter }XMLElements}}{45}{subsection.5.2.7} \contentsline {subsection}{\numberline {5.2.8}\leavevmode {\color {Chapter }CheckAndCleanGapDocTree}}{45}{subsection.5.2.8} \contentsline {subsection}{\numberline {5.2.9}\leavevmode {\color {Chapter }AddParagraphNumbersGapDocTree}}{45}{subsection.5.2.9} \contentsline {subsection}{\numberline {5.2.10}\leavevmode {\color {Chapter }InfoXMLParser}}{45}{subsection.5.2.10} \contentsline {section}{\numberline {5.3}\leavevmode {\color {Chapter }The Converters}}{46}{section.5.3} \contentsline {subsection}{\numberline {5.3.1}\leavevmode {\color {Chapter }GAPDoc2LaTeX}}{46}{subsection.5.3.1} \contentsline {subsection}{\numberline {5.3.2}\leavevmode {\color {Chapter }GAPDoc2Text}}{47}{subsection.5.3.2} \contentsline {subsection}{\numberline {5.3.3}\leavevmode {\color {Chapter }GAPDoc2TextPrintTextFiles}}{47}{subsection.5.3.3} \contentsline {subsection}{\numberline {5.3.4}\leavevmode {\color {Chapter }AddPageNumbersToSix}}{48}{subsection.5.3.4} \contentsline {subsection}{\numberline {5.3.5}\leavevmode {\color {Chapter }PrintSixFile}}{48}{subsection.5.3.5} \contentsline {subsection}{\numberline {5.3.6}\leavevmode {\color {Chapter }SetGAPDocTextTheme}}{48}{subsection.5.3.6} \contentsline {subsection}{\numberline {5.3.7}\leavevmode {\color {Chapter }GAPDoc2HTML}}{50}{subsection.5.3.7} \contentsline {subsection}{\numberline {5.3.8}\leavevmode {\color {Chapter }GAPDoc2HTMLPrintHTMLFiles}}{52}{subsection.5.3.8} \contentsline {subsection}{\numberline {5.3.9}\leavevmode {\color {Chapter }Stylesheet files}}{52}{subsection.5.3.9} \contentsline {subsection}{\numberline {5.3.10}\leavevmode {\color {Chapter }CopyHTMLStyleFiles}}{53}{subsection.5.3.10} \contentsline {subsection}{\numberline {5.3.11}\leavevmode {\color {Chapter }SetGAPDocHTMLStyle}}{53}{subsection.5.3.11} \contentsline {subsection}{\numberline {5.3.12}\leavevmode {\color {Chapter }InfoGAPDoc}}{53}{subsection.5.3.12} \contentsline {subsection}{\numberline {5.3.13}\leavevmode {\color {Chapter }SetGapDocLanguage}}{53}{subsection.5.3.13} \contentsline {section}{\numberline {5.4}\leavevmode {\color {Chapter }Testing Manual Examples}}{54}{section.5.4} \contentsline {subsection}{\numberline {5.4.1}\leavevmode {\color {Chapter }ExtractExamples}}{54}{subsection.5.4.1} \contentsline {subsection}{\numberline {5.4.2}\leavevmode {\color {Chapter }RunExamples}}{54}{subsection.5.4.2} \contentsline {chapter}{\numberline {6}\leavevmode {\color {Chapter }String and Text Utilities}}{56}{chapter.6} \contentsline {section}{\numberline {6.1}\leavevmode {\color {Chapter }Text Utilities}}{56}{section.6.1} \contentsline {subsection}{\numberline {6.1.1}\leavevmode {\color {Chapter }WHITESPACE}}{56}{subsection.6.1.1} \contentsline {subsection}{\numberline {6.1.2}\leavevmode {\color {Chapter }TextAttr}}{57}{subsection.6.1.2} \contentsline {subsection}{\numberline {6.1.3}\leavevmode {\color {Chapter }WrapTextAttribute}}{57}{subsection.6.1.3} \contentsline {subsection}{\numberline {6.1.4}\leavevmode {\color {Chapter }FormatParagraph}}{58}{subsection.6.1.4} \contentsline {subsection}{\numberline {6.1.5}\leavevmode {\color {Chapter }SubstitutionSublist}}{58}{subsection.6.1.5} \contentsline {subsection}{\numberline {6.1.6}\leavevmode {\color {Chapter }StripBeginEnd}}{59}{subsection.6.1.6} \contentsline {subsection}{\numberline {6.1.7}\leavevmode {\color {Chapter }StripEscapeSequences}}{59}{subsection.6.1.7} \contentsline {subsection}{\numberline {6.1.8}\leavevmode {\color {Chapter }RepeatedString}}{59}{subsection.6.1.8} \contentsline {subsection}{\numberline {6.1.9}\leavevmode {\color {Chapter }NumberDigits}}{59}{subsection.6.1.9} \contentsline {subsection}{\numberline {6.1.10}\leavevmode {\color {Chapter }PositionMatchingDelimiter}}{60}{subsection.6.1.10} \contentsline {subsection}{\numberline {6.1.11}\leavevmode {\color {Chapter }WordsString}}{60}{subsection.6.1.11} \contentsline {subsection}{\numberline {6.1.12}\leavevmode {\color {Chapter }Base64String}}{60}{subsection.6.1.12} \contentsline {section}{\numberline {6.2}\leavevmode {\color {Chapter }Unicode Strings}}{61}{section.6.2} \contentsline {subsection}{\numberline {6.2.1}\leavevmode {\color {Chapter }Unicode Strings and Characters}}{61}{subsection.6.2.1} \contentsline {subsection}{\numberline {6.2.2}\leavevmode {\color {Chapter }Encode}}{62}{subsection.6.2.2} \contentsline {subsection}{\numberline {6.2.3}\leavevmode {\color {Chapter }Lengths of UTF-8 strings}}{63}{subsection.6.2.3} \contentsline {section}{\numberline {6.3}\leavevmode {\color {Chapter }Print Utilities}}{64}{section.6.3} \contentsline {subsection}{\numberline {6.3.1}\leavevmode {\color {Chapter }PrintTo1}}{64}{subsection.6.3.1} \contentsline {subsection}{\numberline {6.3.2}\leavevmode {\color {Chapter }StringPrint}}{64}{subsection.6.3.2} \contentsline {subsection}{\numberline {6.3.3}\leavevmode {\color {Chapter }PrintFormattedString}}{64}{subsection.6.3.3} \contentsline {subsection}{\numberline {6.3.4}\leavevmode {\color {Chapter }Page}}{64}{subsection.6.3.4} \contentsline {subsection}{\numberline {6.3.5}\leavevmode {\color {Chapter }StringFile}}{65}{subsection.6.3.5} \contentsline {chapter}{\numberline {7}\leavevmode {\color {Chapter }Utilities for Bibliographies}}{66}{chapter.7} \contentsline {section}{\numberline {7.1}\leavevmode {\color {Chapter }Parsing Bib{T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\spacefactor \@m } Files}}{66}{section.7.1} \contentsline {subsection}{\numberline {7.1.1}\leavevmode {\color {Chapter }ParseBibFiles}}{66}{subsection.7.1.1} \contentsline {subsection}{\numberline {7.1.2}\leavevmode {\color {Chapter }NormalizedNameAndKey}}{67}{subsection.7.1.2} \contentsline {subsection}{\numberline {7.1.3}\leavevmode {\color {Chapter }WriteBibFile}}{67}{subsection.7.1.3} \contentsline {subsection}{\numberline {7.1.4}\leavevmode {\color {Chapter }InfoBibTools}}{68}{subsection.7.1.4} \contentsline {section}{\numberline {7.2}\leavevmode {\color {Chapter }The BibXMLext Format}}{68}{section.7.2} \contentsline {section}{\numberline {7.3}\leavevmode {\color {Chapter }Utilities for BibXMLext data}}{70}{section.7.3} \contentsline {subsection}{\numberline {7.3.1}\leavevmode {\color {Chapter }Translating Bib{T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\spacefactor \@m } to BibXMLext}}{70}{subsection.7.3.1} \contentsline {subsection}{\numberline {7.3.2}\leavevmode {\color {Chapter }HeuristicTranslationsLaTeX2XML.Apply}}{70}{subsection.7.3.2} \contentsline {subsection}{\numberline {7.3.3}\leavevmode {\color {Chapter }StringBibAsXMLext}}{71}{subsection.7.3.3} \contentsline {subsection}{\numberline {7.3.4}\leavevmode {\color {Chapter }ParseBibXMLextString}}{72}{subsection.7.3.4} \contentsline {subsection}{\numberline {7.3.5}\leavevmode {\color {Chapter }WriteBibXMLextFile}}{72}{subsection.7.3.5} \contentsline {subsection}{\numberline {7.3.6}\leavevmode {\color {Chapter }Bibliography Entries as Records}}{72}{subsection.7.3.6} \contentsline {subsection}{\numberline {7.3.7}\leavevmode {\color {Chapter }RecBibXMLEntry}}{73}{subsection.7.3.7} \contentsline {subsection}{\numberline {7.3.8}\leavevmode {\color {Chapter }AddHandlerBuildRecBibXMLEntry}}{74}{subsection.7.3.8} \contentsline {subsection}{\numberline {7.3.9}\leavevmode {\color {Chapter }StringBibXMLEntry}}{75}{subsection.7.3.9} \contentsline {subsection}{\numberline {7.3.10}\leavevmode {\color {Chapter }TemplateBibXML}}{76}{subsection.7.3.10} \contentsline {section}{\numberline {7.4}\leavevmode {\color {Chapter }Getting Bib{T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX\spacefactor \@m } entries from \textsf {MathSciNet}}}{77}{section.7.4} \contentsline {subsection}{\numberline {7.4.1}\leavevmode {\color {Chapter }SearchMR}}{77}{subsection.7.4.1} \contentsline {chapter}{\numberline {A}\leavevmode {\color {Chapter }The File \texttt {3k+1.xml}}}{79}{appendix.A} \contentsline {chapter}{\numberline {B}\leavevmode {\color {Chapter }The File \texttt {gapdoc.dtd}}}{81}{appendix.B} \contentsline {chapter}{\numberline {C}\leavevmode {\color {Chapter }The File \texttt {bibxmlext.dtd}}}{90}{appendix.C} \contentsline {chapter}{References}{100}{appendix*.3} \contentsline {chapter}{Index}{101}{section*.4} GAPDoc-1.5.1/doc/chap5.html0000644000175000017500000023406312026346063013646 0ustar billbill GAP (GAPDoc) - Chapter 5: The Converters and an XML Parser
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

5 The Converters and an XML Parser

The GAPDoc package contains a set of programs which allow us to convert a GAPDoc book into several output versions and to make them available to GAP's online help.

Currently the following output formats are provided: text for browsing inside a terminal running GAP, LaTeX with hyperref-package for cross references via hyperlinks and HTML for reading with a Web-browser.

5.1 Producing Documentation from Source Files

Here we explain how to use the functions which are described in more detail in the following sections. We assume that we have the main file MyBook.xml of a book "MyBook" in the directory /my/book/path. This contains <#Include ...>-statements as explained in Chapter 4. These refer to some other files as well as pieces of text which are found in the comments of some GAP source files ../lib/a.gd and ../lib/b.gi (relative to the path above). A BibTeX database MyBook.bib for the citations is also in the directory given above. We want to produce a text-, pdf- and HTML-version of the document. (A LaTeX version of the manual is produced, so it is also easy to compile dvi-, and postscript-versions.)

All the commands shown in this Section are collected in the single function MakeGAPDocDoc (5.1-1).

First we construct the complete XML-document as a string with ComposedDocument (4.2-1). This interprets recursively the <#Include ...>-statements.

gap> path := Directory("/my/book/path");;
gap> main := "MyBook.xml";;
gap> files := ["../lib/a.gd", "../lib/b.gi"];;
gap> bookname := "MyBook";;
gap> doc := ComposedDocument("GAPDoc", path, main, files, true);;

Now doc is a list with two entries, the first is a string containing the XML-document, the second gives information from which files and locations which part of the document was collected. This is useful in the next step, if there are any errors in the document.

Next we parse the document and store its structure in a tree-like data structure. The commands for this are ParseTreeXMLString (5.2-1) and CheckAndCleanGapDocTree (5.2-8).

gap> r := ParseTreeXMLString(doc[1], doc[2]);;
gap> CheckAndCleanGapDocTree(r);
true

We start to produce a text version of the manual, which can be read in a terminal (window). The command is GAPDoc2Text (5.3-2). This produces a record with the actual text and some additional information. The text can be written chapter-wise into files with GAPDoc2TextPrintTextFiles (5.3-3). The names of these files are chap0.txt, chap1.txt and so on. The text contains some markup using ANSI escape sequences. This markup is substituted by the GAP help system (user configurable) to show the text with colors and other attributes. For the bibliography we have to tell GAPDoc2Text (5.3-2) the location of the BibTeX database by specifying a path as second argument.

gap> t := GAPDoc2Text(r, path);;
gap> GAPDoc2TextPrintTextFiles(t, path);

This command constructs all parts of the document including table of contents, bibliography and index. The functions FormatParagraph (6.1-4) for formatting text paragraphs and ParseBibFiles (7.1-1) for reading BibTeX files with GAP may be of independent interest.

With the text version we have also produced the information which is used for searching with GAP's online help. Also, labels are produced which can be used by links in the HTML- and pdf-versions of the manual.

Next we produce a LaTeX version of the document. GAPDoc2LaTeX (5.3-1) returns a string containing the LaTeX source. The utility function FileString (6.3-5) writes the content of a string to a file, we choose MyBook.tex.

gap> l := GAPDoc2LaTeX(r);;
gap> FileString(Filename(path, Concatenation(bookname, ".tex")), l);

Assuming that you have a sufficiently good installation of TeX available (see GAPDoc2LaTeX (5.3-1) for details) this can be processed with a series of commands like in the following example.

cd /my/book/path
pdflatex MyBook
bibtex MyBook
pdflatex MyBook
makeindex MyBook
pdflatex MyBook
mv MyBook.pdf manual.pdf

After this we have a pdf-version of the document in the file manual.pdf. It contains hyperlink information which can be used with appropriate browsers for convenient reading of the document on screen (e.g., xpdf is nice because it allows remote calls to display named locations of the document). Of course, we could also use other commands like latex or dvips to process the LaTeX source file. Furthermore we have produced a file MyBook.pnr which is GAP-readable and contains the page number information for each (sub-)section of the document.

We can add this page number information to the indexing information collected by the text converter and then print a manual.six file which is read by GAP when the manual is loaded. This is done with AddPageNumbersToSix (5.3-4) and PrintSixFile (5.3-5).

gap> AddPageNumbersToSix(r, Filename(path, "MyBook.pnr"));
gap> PrintSixFile(Filename(path, "manual.six"), r, bookname);

Finally we produce an HTML-version of the document and write it (chapter-wise) into files chap0.html, chap1.html and so on. They can be read with any Web-browser. The commands are GAPDoc2HTML (5.3-7) and GAPDoc2HTMLPrintHTMLFiles (5.3-8). We also add a link from manual.html to chap0.html. You probably want to copy stylesheet files into the same directory, see 5.3-9 for more details. The argument path of GAPDoc2HTML (5.3-7) specifies the directory containing the BibTeX database files.

gap> h := GAPDoc2HTML(r, path);;
gap> GAPDoc2HTMLPrintHTMLFiles(h, path);

5.1-1 MakeGAPDocDoc
‣ MakeGAPDocDoc( path, main, files, bookname[, gaproot] )( function )

This function collects all the commands for producing a text-, pdf- and HTML-version of a GAPDoc document as described in Section 5.1. It checks the .log file from the call of pdflatex and reports if there are errors, warnings or overfull boxes.

Note: If this function works for you depends on your operating system and installed software. It will probably work on most UNIX systems with a standard LaTeX installation. If the function doesn't work for you look at the source code and adjust it to your system.

Here path must be the directory (as string or directory object) containing the main file main of the document (given with or without the .xml extension. The argument files is a list of (probably source code) files relative to path which contain pieces of documentation which must be included in the document, see Chapter 4. And bookname is the name of the book used by GAP's online help. The optional argument gaproot must be a string which gives the relative path from path to the main GAP root directory. If this is given, the HTML files are produced with relative paths to external books.

MakeGAPDocDoc can be called with additional arguments "MathJax", "Tth" and/or "MathML". If these are given additional variants of the HTML conversion are called, see GAPDoc2HTML (5.3-7) for details.

It is possible to use GAPDoc with other languages than English, see SetGapDocLanguage (5.3-13) for more details.

5.2 Parsing XML Documents

Arbitrary well-formed XML documents can be parsed and browsed by the following functions.

5.2-1 ParseTreeXMLString
‣ ParseTreeXMLString( str[, srcinfo][, entitydict] )( function )
‣ ParseTreeXMLFile( fname[, entitydict] )( function )

Returns: a record which is root of a tree structure

The first function parses an XML-document stored in string str and returns the document in form of a tree.

The optional argument srcinfo must have the same format as in OriginalPositionDocument (4.2-2). If it is given then error messages refer to the original source of the text with the problem.

With the optional argument entitydict named entities can be given to the parser, for example entities which are defined in the .dtd-file (which is not read by this parser). The standard XML-entities do not need to be provided, and for GAPDoc documents the entity definitions from gapdoc.dtd are automatically provided. Entities in the document's <!DOCTYPE declaration are parsed and also need not to be provided here. The argument entitydict must be a record where each component name is an entity name (without the surrounding & and ;) to which is assigned its substitution string.

The second function is just a shortcut for ParseTreeXMLString( StringFile(fname), ... ), see StringFile (6.3-5).

After these functions return the list of named entities which were known during the parsing can be found in the record ENTITYDICT.

A node in the result tree corresponds to an XML element, or to some parsed character data. In the first case it looks as follows:

rec( name := "Book",
     attributes := rec( Name := "EDIM" ),
     content := [ ... list of nodes for content ...],
     start := 312,
     stop := 15610,
     next := 15611     )

This means that str{[312..15610]} looks like <Book Name="EDIM"> ... content ... </Book>.

The leaves of the tree encode parsed character data as in the following example:

rec( name := "PCDATA", 
     content := "text without markup "     )

This function checks whether the XML document is well formed, see 2.1-14 for an explanation. If an error in the XML structure is found, a break loop is entered and the text around the position where the problem starts is shown. With Show(); one can browse the original input in the Pager (Reference: Pager), starting with the line where the error occurred. All entities are resolved when they are either entities defined in the GAPDoc package (in particular the standard XML entities) or if their definition is included in the <!DOCTYPE ..> tag of the document.

Note that ParseTreeXMLString does not parse and interpret the corresponding document type definition (the .dtd-file given in the <!DOCTYPE ..> tag). Hence it also does not check the validity of the document (i.e., it is no validating XML parser).

If you are using this function to parse a GAPDoc document you can use CheckAndCleanGapDocTree (5.2-8) for some validation and additional checking of the document structure.

5.2-2 StringXMLElement
‣ StringXMLElement( tree )( function )

Returns: a list [string, positions]

The argument tree must have a format of a node in the parse tree of an XML document as returned by ParseTreeXMLString (5.2-1) (including the root node representing the full document). This function computes a pair [string, positions] where string contains XML code which is equivalent to the code which was parsed to get tree. And positions is a list of lists of four numbers [eltb, elte, contb, conte]. There is one such list for each XML element occuring in string, where eltb and elte are the begin and end position of this element in string and where contb and conte are begin and end position of the content of this element, or both are 0 if there is no content.

Note that parsing XML code is an irreversible task, we can only expect to get equivalent XML code from this function. But parsing the resulting string again and applying StringXMLElement again gives the same result. See the function EntitySubstitution (5.2-3) for back-substitutions of entities in the result.

5.2-3 EntitySubstitution
‣ EntitySubstitution( xmlstring, entities )( function )

Returns: a string

The argument xmlstring must be a string containing XML code or a pair [string, positions] as returned by StringXMLElement (5.2-2). The argument entities specifies entity names (without the surrounding & and ;) and their substitution strings, either a list of pairs of strings or as a record with the names as components and the substitutions as values.

This function tries to substitute non-intersecting parts of string by the given entities. If the positions information is given then only parts of the document which allow a valid substitution by an entity are considered. Otherwise a simple text substitution without further check is done.

Note that in general the entity resolution in XML documents is a complicated and non-reversible task. But nevertheless this utility may be useful in not too complicated situations.

5.2-4 DisplayXMLStructure
‣ DisplayXMLStructure( tree )( function )

This utility displays the tree structure of an XML document as it is returned by ParseTreeXMLString (5.2-1) (without the PCDATA leaves).

Since this is usually quite long the result is shown using the Pager (Reference: Pager).

5.2-5 ApplyToNodesParseTree
‣ ApplyToNodesParseTree( tree, fun )( function )
‣ AddRootParseTree( tree )( function )
‣ RemoveRootParseTree( tree )( function )

The function ApplyToNodesParseTree applies a function fun to all nodes of the parse tree tree of an XML document returned by ParseTreeXMLString (5.2-1).

The function AddRootParseTree is an application of this. It adds to all nodes a component .root to which the top node tree tree is assigned. These components can be removed afterwards with RemoveRootParseTree.

Here are two more utilities which use ApplyToNodesParseTree.

5.2-6 GetTextXMLTree
‣ GetTextXMLTree( tree )( function )

Returns: a string

The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function collects the content of this and all included elements recursively into a string.

5.2-7 XMLElements
‣ XMLElements( tree, eltnames )( function )

Returns: a list of nodes

The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function returns a list of all subnodes of tree (possibly including tree) of elements with name given in the list of strings eltnames. Use "PCDATA" as name for leave nodes which contain the actual text of the document. As an abbreviation eltnames can also be a string which is then put in a one element list.

And here are utilities for processing GAPDoc XML documents.

5.2-8 CheckAndCleanGapDocTree
‣ CheckAndCleanGapDocTree( tree )( function )

Returns: nothing

The argument tree of this function is a parse tree from ParseTreeXMLString (5.2-1) of some GAPDoc document. This function does an (incomplete) validity check of the document according to the document type declaration in gapdoc.dtd. It also does some additional checks which cannot be described in the DTD (like checking whether chapters and sections have a heading). For elements with element content the whitespace between these elements is removed.

In case of an error the break loop is entered and the position of the error in the original XML document is printed. With Show(); one can browse the original input in the Pager (Reference: Pager).

5.2-9 AddParagraphNumbersGapDocTree
‣ AddParagraphNumbersGapDocTree( tree )( function )

Returns: nothing

The argument tree must be an XML tree returned by ParseTreeXMLString (5.2-1) applied to a GAPDoc document. This function adds to each node of the tree a component .count which is of form [Chapter[, Section[, Subsection, Paragraph] ] ]. Here the first three numbers should be the same as produced by the LaTeX version of the document. Text before the first chapter is counted as chapter 0 and similarly for sections and subsections. Some elements are always considered to start a new paragraph.

5.2-10 InfoXMLParser
‣ InfoXMLParser( info class )

The default level of this info class is 1. Functions like ParseTreeXMLString (5.2-1) are then printing some information, in particular in case of errors. You can suppress it by setting the level of InfoXMLParser to 0. With level 2 there may be some more information for debugging purposes.

5.3 The Converters

Here are more details about the conversion programs for GAPDoc XML documents.

5.3-1 GAPDoc2LaTeX
‣ GAPDoc2LaTeX( tree )( function )

Returns: LaTeX document as string

‣ SetGapDocLaTeXOptions( [...] )( function )

Returns: Nothing

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). The output is a string containing a version of the document which can be written to a file and processed with LaTeX or pdfLaTeX (and probably BibTeX and makeindex).

The output uses the report document class and needs the following LaTeX packages: a4wide, amssymb, inputenc, makeidx, color, fancyvrb, psnfss, pslatex, enumitem and hyperref. These are for example provided by the teTeX-1.0 or texlive distributions of TeX (which in turn are used for most TeX packages of current Linux distributions); see http://www.tug.org/tetex/.

In particular, the resulting pdf-output (and dvi-output) contains (internal and external) hyperlinks which can be very useful for onscreen browsing of the document.

The LaTeX processing also produces a file with extension .pnr which is GAP readable and contains the page numbers for all (sub)sections of the document. This can be used by GAP's online help; see AddPageNumbersToSix (5.3-4). Non-ASCII characters in the GAPDoc document are translated to LaTeX input in ASCII-encoding with the help of Encode (6.2-2) and the option "LaTeX". See the documentation of Encode (6.2-2) for how to proceed if you have a character which is not handled (yet).

This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2LaTeXProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust layout details to your own taste by slight modifications of the program.

Former versions of GAPDoc supported some XML processing instructions to add some extra lines to the preamble of the LaTeX document. Its use is now deprecated, use the much more flexible SetGapDocLaTeXOptions instead: The default layout of the resulting documents can be changed with SetGapDocLaTeXOptions. This changes parts of the header of the LaTeX file produced by GAPDoc. You can see the header with some placeholders by Page(GAPDoc2LaTeXProcs.Head);. The placeholders are filled with components from the record GAPDoc2LaTeXProcs.DefaultOptions. The arguments of SetGapDocLaTeXOptions can be records with the same structure (or parts of it) with different values. As abbreviations there are also three strings supported as arguments. These are "nocolor" for switching all colors to black; then "nopslatex" to use standard LaTeX fonts instead of postscript fonts; and finally "utf8" to choose UTF-8 as input encoding for the LaTeX document.

5.3-2 GAPDoc2Text
‣ GAPDoc2Text( tree[, bibpath][, width] )( function )

Returns: record containing text files as strings and other information

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). This function produces a text version of the document which can be used with GAP's online help (with the "screen" viewer, see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography and index. The bibliography is made from BibXMLext or BibTeX databases, see 7. Their location must be given with the argument bibpath (as string or directory object).

The output is a record with one component for each chapter (with names "0", "1", ..., "Bib" and "Ind"). Each such component is again a record with the following components:

text

the text of the whole chapter as a string

ssnr

list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1)

linenr

corresponding list of line numbers where the subsections start

len

number of lines of this chapter

The result can be written into files with the command GAPDoc2TextPrintTextFiles (5.3-3).

As a side effect this function also produces the manual.six information which is used for searching in GAP's online help. This is stored in tree.six and can be printed into a manual.six file with PrintSixFile (5.3-5) (preferably after producing a LaTeX version of the document as well and adding the page number information to tree.six, see GAPDoc2LaTeX (5.3-1) and AddPageNumbersToSix (5.3-4)).

The text produced by this function contains some markup via ANSI escape sequences. The sequences used here are usually ignored by terminals. But the GAP help system will substitute them by interpreted color and attribute sequences (see TextAttr (6.1-2)) before displaying them. There is a default markup used for this but it can also be configured by the user, see SetGAPDocTextTheme (5.3-6). Furthermore, the text produced is in UTF-8 encoding. The encoding is also translated on the fly, if GAPInfo.TermEncoding is set to some encoding supported by Encode (6.2-2), e.g., "ISO-8859-1" or "latin1".

With the optional argument width a different length of the output text lines can be chosen. The default is 76 and all lines in the resulting text start with two spaces. This looks good on a terminal with a standard width of 80 characters and you probably don't want to use this argument.

5.3-3 GAPDoc2TextPrintTextFiles
‣ GAPDoc2TextPrintTextFiles( t[, path] )( function )

Returns: nothing

The first argument must be a result returned by GAPDoc2Text (5.3-2). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.txt, chap1.txt, ..., chapBib.txt, and chapInd.txt.

If you want to make your document accessible via the GAP online help you must put at least these files for the text version into a directory, together with the file manual.six, see PrintSixFile (5.3-5). Then specify the path to the manual.six file in the packages PackageInfo.g file, see Reference: The PackageInfo.g File.

Optionally you can add the dvi- and pdf-versions of the document which are produced with GAPDoc2LaTeX (5.3-1) to this directory. The files must have the names manual.dvi and manual.pdf, respectively. Also you can add the files of the HTML version produced with GAPDoc2HTML (5.3-7) to this directory, see GAPDoc2HTMLPrintHTMLFiles (5.3-8). The handler functions in GAP for this help format detect automatically which of the optional formats of a book are actually available.

5.3-4 AddPageNumbersToSix
‣ AddPageNumbersToSix( tree, pnrfile )( function )

Returns: nothing

Here tree must be the XML tree of a GAPDoc document, returned by ParseTreeXMLString (5.2-1). Running latex on the result of GAPDoc2LaTeX(tree) produces a file pnrfile (with extension .pnr). The command GAPDoc2Text(tree) creates a component tree.six which contains all information about the document for the GAP online help, except the page numbers in the .dvi, .ps, .pdf versions of the document. This command adds the missing page number information to tree.six.

5.3-5 PrintSixFile
‣ PrintSixFile( tree, bookname, fname )( function )

Returns: nothing

This function prints the .six file fname for a GAPDoc document stored in tree with name bookname. Such a file contains all information about the book which is needed by the GAP online help. This information must first be created by calls of GAPDoc2Text (5.3-2) and AddPageNumbersToSix (5.3-4).

5.3-6 SetGAPDocTextTheme
‣ SetGAPDocTextTheme( [optrec1[, optrec2], ...] )( function )

Returns: nothing

This utility function is for readers of the screen version of GAP manuals which are generated by the GAPDoc package. It allows to configure the color and attribute layout of the displayed text. There is a default which can be reset by calling this function without argument.

As an abbreviation the arguments optrec1 and so on can be strings for the known name of a theme. Information about valid names is shown with SetGAPDocTextTheme("");.

Otherwise, optrec1 and so on must be a record. Its entries overwrite the corresponding entries in the default and in previous arguments. To construct valid markup you can use TextAttr (6.1-2). Entries must be either pairs of strings, which are put before and after the corresponding text, or as an abbreviation it can be a single string. In the latter case, the second string is implied; if the string contains an escape sequence the second string is TextAttr.reset, otherwise the given string is used. The following components are recognized:

flush

"both" for left-right justified paragraphs, and "left" for ragged right ones

Heading

chapter and (sub-)section headings

Func

function, operation, ... names

Arg

argument names in descriptions

Example

example code

Package

package names

Returns

Returns-line in descriptions

URL

URLs

Mark

Marks in description lists

K

GAP keywords

C

code or text to type

F

file names

B

buttons

M

simplified math elements

Math

normal math elements

Display

displayed math elements

Emph

emphasized text

Q

quoted text

Ref

reference text

Prompt

GAP prompt in examples

BrkPrompt

GAP break prompt in examples

GAPInput

GAP input in examples

reset

reset to default, don't change this

BibAuthor

author names in bibliography

BibTitle

titles in bibliography

BibJournal

journal names in bibliography

BibVolume

volume number in bibliography

BibLabel

labels for bibliography entries

BibReset

reset for bibliography, don't change

ListBullet

bullet for simple lists (2 visible characters long)

EnumMarks

one visible character before and after the number in enumerated lists

DefLineMarker

marker before function and variable definitions (2 visible characters long)

FillString

for filling in definitions and example separator lines

gap> # use no colors for GAP examples and 
gap> # change display of headings to bold green
gap> SetGAPDocTextTheme("noColorPrompt", 
>            rec(Heading:=Concatenation(TextAttr.bold, TextAttr.2)));

5.3-7 GAPDoc2HTML
‣ GAPDoc2HTML( tree[, bibpath[, gaproot]][, mtrans] )( function )

Returns: record containing HTML files as strings and other information

The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). Without an mtrans argument this function produces an HTML version of the document which can be read with any Web-browser and also be used with GAP's online help (see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography, and index. The bibliography is made from BibTeX databases. Their location must be given with the argument bibpath (as string or directory object, if not given the current directory is used). If the third argument gaproot is given and is a string then this string is interpreted as relative path to GAP's main root directory. Reference-URLs to external HTML-books which begin with the GAP root path are then rewritten to start with the given relative path. This makes the HTML-documentation portable provided a package is installed in some standard location below the GAP root.

The output is a record with one component for each chapter (with names "0", "1", ..., "Bib", and "Ind"). Each such component is again a record with the following components:

text

the text of an HTML file containing the whole chapter (as a string)

ssnr

list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1)

Standard output format without mtrans argument

The HTML code produced with this converter conforms to the W3C specification "XHTML 1.0 strict", see http://www.w3.org/TR/xhtml1. First, this means that the HTML files are valid XML files. Secondly, the extension "strict" says in particular that the code doesn't contain any explicit font or color information.

Mathematical formulae are handled as in the text converter GAPDoc2Text (5.3-2). We don't want to assume that the browser can use symbol fonts. Some GAP users like to browse the online help with lynx, see SetHelpViewer (Reference: SetHelpViewer), which runs inside the same terminal windows as GAP.

To view the generated files in graphical browsers, stylesheet files with layout configuration should be copied into the directory with the generated HTML files, see 5.3-9.

Output format with mtrans argument

Currently, there are three variants of this converter available which handle mathematical formulae differently. They are accessed via the optional last mtrans argument.

If mtrans is set to "MathJax" the formulae are essentially translated as for LaTeX documents (there is no processing of <M> elements as decribed in 3.8-2). Inline formulae are delimited by \( and \) and displayed formulae by \[ and \]. With MathJax webpages can contain nicely formatted scalable and searchable formulae. The resulting files link by default to http://cdn.mathjax.org to get the MathJax script and fonts. This means that they can only be used on computers with internet access. An alternative URL can be set by overwriting GAPDoc2HTMLProcs.MathJaxURL before building the HTML version of a manual. This way a local installation of MathJax could be used. See http://www.mathjax.org/ for more details.

The following possibilities for mtrans are still supported, but since the MathJax approach seems much better, their use is deprecated.

If the argument mtrans is set to "Tth" it is assumed that you have installed the LaTeX to HTML translation program tth. This is used to translate the contents of the M, Math and Display elements into HTML code. Note that the resulting code is not compliant with any standard. Formally it is "XHTML 1.0 Transitional", it contains explicit font specifications and the characters of mathematical symbols are included via their position in a "Symbol" font. Some graphical browsers can be configured to display this in a useful manner, check the Tth homepage for more details.

If the mtrans argument is set to "MathML" it is assumed that you have installed the translation program ttm, see also the Tth homepage). This is used to translate the contents of the M, Math and Display elements to MathML 2.0 markup. The resulting files should conform to the "XHTML 1.1 plus MathML 2.0" standard, see the W3C information for more details. It is expected that the next generation of graphical browsers will be able to render such files (try for example Mozilla, at least 0.9.9). You must copy the .xsl and .css files from GAPDocs mathml directory to the directory containing the output files. The translation with ttm is still experimental. The output of this converter variant is garbage for browsers which don't support MathML.

This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2TextProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust certain details to your own taste by slight modifications of the program.

The result of this converter can be written to files with the command GAPDoc2HTMLPrintHTMLFiles (5.3-8).

There are two user preferences for reading the HTML manuals produced by GAPDoc. A user can choose among several style files which determine the appearance of the manual pages with SetUserPreference("GAPDoc", "HTMLStyle", [...]); where the list in the third argument are arguments for SetGAPDocHTMLStyle (5.3-11). The second preference is set by SetUserPreference("GAPDoc", "UseMathJax", ...); where the third argument is true or false (default). If this is set to true, the GAP help system displays the MathJax version of the HTML manuals.

5.3-8 GAPDoc2HTMLPrintHTMLFiles
‣ GAPDoc2HTMLPrintHTMLFiles( t[, path] )( function )

Returns: nothing

The first argument must be a result returned by GAPDoc2HTML (5.3-7). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.html, chap1.html, ..., chapBib.html, and chapInd.html.

The MathJax versions are written to files chap0_mj.html, ..., chapInd_mj.html.

The experimental versions which are produced with tth or ttm use different names for the files, namely chap0_sym.html, and so on for files which need symbol fonts and chap0_mml.xml for files with MathML translations.

You should also add stylesheet files to the directory with the HTML files, see 5.3-9.

5.3-9 Stylesheet files

For graphical browsers the layout of the generated HTML manuals can be highly configured by cascading stylesheet (CSS) and javascript files. Such files are provided in the styles directory of the GAPDoc package.

We recommend that these files are copied into each manual directory (such that each of them is selfcontained). There is a utility function CopyHTMLStyleFiles (5.3-10) which does this. Of course, these files may be changed or new styles may be added. New styles may also be sent to the GAPDoc authors for possible inclusion in future versions.

The generated HTML files refer to the file manual.css which conforms to the W3C specification CSS 2.0, see http://www.w3.org/TR/REC-CSS2, and the javascript file manual.js (only in browsers which support CSS or javascript, respectively; but the HTML files are also readable without any of them). To add a style mystyle one or both of mystyle.css and mystyle.js must be provided; these can overwrite default settings and add new javascript functions. For more details see the comments in manual.js.

5.3-10 CopyHTMLStyleFiles
‣ CopyHTMLStyleFiles( dir )( function )

Returns: nothing

This utility function copies the *.css and *.js files from the styles directory of the GAPDoc package into the directory dir.

5.3-11 SetGAPDocHTMLStyle
‣ SetGAPDocHTMLStyle( [style1[, style2], ...] )( function )

Returns: nothing

This utility function is for readers of the HTML version of GAP manuals which are generated by the GAPDoc package. It allows to configure the display style of the manuals. This will only have an effect if you are using a browser that supports javascript. There is a default which can be reset by calling this function without argument.

The arguments style1 and so on must be strings. You can find out about the valid strings by following the [Style] link on top of any manual page. (Going back to the original page, its address has a setting for GAPDocStyle which is the list of strings, separated by commas, you want to use here.)

gap> # show/hide subsections in tables on contents only after click,
gap> # and don't use colors in GAP examples
gap> SetGAPDocHTMLStyle("toggless", "nocolorprompt");

5.3-12 InfoGAPDoc
‣ InfoGAPDoc( info class )

The default level of this info class is 1. The converter functions for GAPDoc documents are then printing some information. You can suppress this by setting the level of InfoGAPDoc to 0. With level 2 there may be some more information for debugging purposes.

5.3-13 SetGapDocLanguage
‣ SetGapDocLanguage( [lang] )( function )

Returns: nothing

The GAPDoc converter programs sometimes produce text which is not explicit in the document, e.g., headers like "Abstract", "Appendix", links to "Next Chapter", variable types "function" and so on.

With SetGapDocLanguage the language for these texts can be changed. The argument lang must be a string. Calling without argument or with a language name for which no translations are available is the same as using the default "english".

If your language lang is not yet available, look at the record GAPDocTexts.english and translate all the strings to lang. Then assign this record to GAPDocTexts.(lang) and send it to the GAPDoc authors for inclusion in future versions of GAPDoc. (Currently, there are translations for english, german, russian and ukrainian.)

Further hints: To get strings produced by LaTeX right you will probably use the babel package with option lang, see the information on ExtraPreamble in GAPDoc2LaTeX (5.3-1). If lang cannot be encoded in latin1 encoding you can consider the use of "utf8" with SetGapDocLaTeXOptions (5.3-1).

5.4 Testing Manual Examples

We also provide some tools to check and adjust the examples given in <Example>-elements.

Former versions of GAPDoc provided functions ManualExamples and TestManualExamples. These functions are still available, but no longer documented. Their use is deprecated.

5.4-1 ExtractExamples
‣ ExtractExamples( path, main, files, units )( function )

Returns: a list of lists

‣ ExtractExamplesXMLTree( tree, units )( function )

Returns: a list of lists

The argument tree must be a parse tree of a GAPDoc document, see ParseTreeXMLFile (5.2-1). The function ExtractExamplesXMLTree returns a data structure representing the <Example> elements of the document. The return value can be used with RunExamples (5.4-2) to check and optionally update the examples of the document.

Depending on the argument units several examples are collected in one list. Recognized values for units are "Chapter", "Section", "Subsection" or "Single". The latter means that each example is in a separate list. For all other value of units just one list with all examples is returned.

The arguments path, main and files of ExtractExamples are the same as for ComposedDocument (4.2-1). This function first contructs and parses the GAPDoc document and then applies ExtractExamplesXMLTree.

5.4-2 RunExamples
‣ RunExamples( exmpls[, optrec] )( function )

Returns: nothing

The argument exmpls must be the output of a call to ExtractExamples (5.4-1) or ExtractExamplesXMLTree (5.4-1). The optional argument optrec must be a record, its components can change the default behaviour of this function.

By default this function runs the GAP input of all examples and compares the actual output with the output given in the examples. If differences occur these are displayed together with information on the location of the source code of that example. Before running the examples in each unit (entry of exmpls) the function START_TEST (Reference: START_TEST) is called and the screen width is set to 72 characters.

If the argument optrec is given, the following components are recognized:

showDiffs

The default value is true, if set to something else found differences in the examples are not displayed.

width

The value must be a positive integer which is used as screen width when running the examples. As mentioned above, the default is 72 which is a sensible value for the text version of the GAPDoc document used in a 80 character wide terminal.

changeSources

If this is set to true then the source code of all manual examples which show differences is adjusted to the current outputs. The default is false.
Use this feature with care. Note that sometimes differences can indicate a bug, and in such a case it is more appropriate to fix the bug instead of changing the example output.

compareFunction

The function used to compare the output shown in the example and the current output. See Test (Reference: Test) for more details.

checkWidth

If this option is a positive integer n the function prints warnings if an example contains any line with more than n characters (input and output lines are considered). By default this option is set to false.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/gapdoc.xml0000644000175000017500000000516012026346063013731 0ustar billbill &GAPDoc; ( Version <#Include SYSTEM "../version"> ) Frank Lübeck Frank.Luebeck@Math.RWTH-Aachen.De http://www.math.rwth-aachen.de/~Frank.Luebeck Max Neunhöffer neunhoef at mcs.st-and.ac.uk http://www-groups.mcs.st-and.ac.uk/~neunhoef/ February 2012 License ©right; 2000-2012 by Frank Lübeck and Max Neunhöffer

&GAPDoc; is free software; you can redistribute it and/or modify it under the terms of the http://www.fsf.org/licenses/gpl.html as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. gap> SizeScreen([72,40]);; <#Include SYSTEM "intro.xml"> <#Include SYSTEM "enter.xml"> <#Include SYSTEM "refdtd.xml"> <#Include SYSTEM "distr.xml"> <#Include SYSTEM "conv.xml"> <#Include SYSTEM "textutil.xml"> <#Include SYSTEM "bibutil.xml"> The File 3k+1.xml Here is the complete source of the example &GAPDoc; document 3k+1.xml discussed in Section .

]]> The File gapdoc.dtd For easier reference we repeat here the complete content of the file gapdoc.dtd. ]]> The File bibxmlext.dtd For easier reference we repeat here the complete content of the file bibxmlext.dtd which is explained in . ]]>
GAPDoc-1.5.1/doc/distr.xml0000644000175000017500000000737712026346063013635 0ustar billbill Distributing a Document into Several Files In &GAPDoc; there are facilities to distribute a single document over several files. This is for example interesting, if one wants to store the documentation of some code in the same file as the code itself. Or, if one just wants to store chapters of a document in separate files. There is a set of conventions how this is done and some tools to collect the text for further processing.

The technique can also be used to distribute and collect other types of documents into respectively from several files (e.g., source code, examples).

<#Include> <#GAPDoc> The Conventions In this description we use the string GAPDoc for marking pieces of a document to collect.

Pieces of documentation that shall be incorporated into another document are marked as follows:

## This is the piece. ## The hash characters are removed. ## <#/GAPDoc>]]> This piece is then included into another file by a statement like: <#Include Label="MyPiece"> Here are the exact rules, how pieces are gathered: All lines up to a line containing the character sequence <#GAPDoc Label=" (exactly one space character) are ignored. The characters on the same line before this sequence are stored as prefix. The characters after the sequence up to the next double quotes character are stored as label. All other characters in the line are ignored. The following lines up to a line containing the character sequence <#/GAPDoc> are stored under the label. These lines are processed as follows: The longest possible substring from the beginning of the line that equals the corresponding substring of the prefix is removed. Having stored a list of labels and pieces of text gathered as above this can be used as follows. In &GAPDoc; documentation files all statements of the form <#Include Label="Key"> are replaced by the sequence of lines stored under the label Key. Additionally, every occurrence of a statement of the form <#Include SYSTEM "Filename"> is replaced by the whole file stored under the name Filename in the file system. These substitutions are done recursively (although one should probably avoid to use this extensively). Here is another example: some characters # # This text is not indented. # This text is indented by one blank. #Not indented. #<#/GAPDoc>]]> replaces <#Include Label="AnotherPiece"> by Since these rules are very simple it is quite easy to write a program in almost any programming language which does this gathering of text pieces and the substitutions. In &GAPDoc; there is the &GAP; function which does this.

Note that the XML-tag-like markup we have used here is not a legal XML markup, since the hash character is not allowed in element names. The mechanism described here is a preprocessing step which composes a document.

A Tool for Collecting a Document <#Include Label="ComposedDocument"> <#Include Label="OriginalPositionDocument">
GAPDoc-1.5.1/doc/rainbow.js0000644000175000017500000000533612026346063013756 0ustar billbill function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); GAPDoc-1.5.1/doc/chapB.html0000644000175000017500000005057212026346063013664 0ustar billbill GAP (GAPDoc) - Appendix B: The File gapdoc.dtd
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

B The File gapdoc.dtd

For easier reference we repeat here the complete content of the file gapdoc.dtd.

<?xml version="1.0" encoding="UTF-8"?>
<!-- ==================================================================
     gapdoc.dtd - XML Document type definition for GAP documentation
     By Frank Lübeck and Max Neunhöffer
     ================================================================== -->


<!-- Note that this definition goes "bottom-up" because entities can only
     be used after their definition in the file. -->


<!-- ==================================================================
     Some entities:
     ================================================================== -->

<!-- The standard XML entities: -->

<!ENTITY lt     "&#38;#60;"> 
<!ENTITY gt     "&#62;"> 
<!ENTITY amp    "&#38;#38;"> 
<!ENTITY apos   "&#39;"> 
<!ENTITY quot   "&#34;">


<!-- The following were introduced in GAPDoc version < 1.0, it is no longer
     necessary to take care of LaTeX special characters
     (we keep the entities with simplified definitions for compatibility) -->
     
<!ENTITY tamp "&amp;">
<!ENTITY tlt "&lt;">
<!ENTITY tgt "&gt;">
<!ENTITY hash "#">
<!ENTITY dollar "$">
<!ENTITY percent "&#37;">
<!ENTITY tilde "~">
<!ENTITY bslash "\\">
<!ENTITY obrace "{">
<!ENTITY cbrace "}">
<!ENTITY uscore "_">
<!ENTITY circum "^">

<!-- ==================================================================
     Our predefined entities:
     ================================================================== -->

<!ENTITY nbsp "&#160;">
<!ENTITY ndash "&#x2013;">
<!ENTITY GAP    "<Package>GAP</Package>">
<!ENTITY GAPDoc "<Package>GAPDoc</Package>">
<!ENTITY TeX    
  "<Alt Only='LaTeX'>{\TeX}</Alt><Alt Not='LaTeX'>TeX</Alt>">
<!ENTITY LaTeX  
  "<Alt Only='LaTeX'>{\LaTeX}</Alt><Alt Not='LaTeX'>LaTeX</Alt>">
<!ENTITY BibTeX 
  "<Alt Only='LaTeX'>{Bib\TeX}</Alt><Alt Not='LaTeX'>BibTeX</Alt>">
<!ENTITY MeatAxe "<Package>MeatAxe</Package>">
<!ENTITY XGAP   "<Package>XGAP</Package>">
<!ENTITY copyright "&#169;">

<!-- and unicode math symbols -->
<!ENTITY CC "&#x2102;" > <!-- double struck -->
<!ENTITY ZZ "&#x2124;" >
<!ENTITY NN "&#x2115;" >
<!ENTITY PP "&#x2119;" >
<!ENTITY QQ "&#x211a;" >
<!ENTITY HH "&#x210d;" >
<!ENTITY RR "&#x211d;" >


<!-- ==================================================================
     The following describes the "innermost" documentation text which 
     can occur at various places in the document like for example
     section headings. It does neither contain further sectioning 
     elements nor environments like Enums or Lists. 
     ================================================================== -->

<!ENTITY % InnerText "#PCDATA |
                      Alt |
                      Emph | E |
                      Par | P | Br |
                      Keyword | K | Arg | A | Quoted | Q | Code | C | 
                      File | F | Button | B | Package |
                      M | Math | Display | 
                      Example | Listing | Log | Verb |
                      URL | Email | Homepage | Address | Cite | Label | 
                      Ref | Index |
                      Ignore" >


<!ELEMENT Alt (%InnerText;)*>     <!-- This is only to allow "Only" and
                                       "Not" attributes for normal text -->
<!ATTLIST Alt Only CDATA #IMPLIED
              Not  CDATA #IMPLIED>

<!-- The following elements declare a certain block of InnerText to
     have a certain property. They are non-terminal and can contain
     any InnerText recursively. -->

<!ELEMENT Emph (%InnerText;)*>    <!-- Emphasize something -->
<!ELEMENT E    (%InnerText;)*>    <!-- the same as shortcut -->


<!-- The following is an empty element marking a paragraph boundary. -->

<!ELEMENT Par EMPTY>    <!-- this is intentionally empty! -->
<!ELEMENT P EMPTY>      <!-- the same as shortcut  -->

<!-- And here is an element for forcing a line break, not starting
     a new paragraph. -->

<!ELEMENT Br EMPTY>     <!-- a forced line break  -->

<!-- The following elements mark a word or sentence to be of a certain
     kind, such that it can  be typeset differently. They are terminal
     elements that should only contain  character data. But we have to
     allow  Alt elements  for handling  special characters.  For these
     elements we introduce  a long name - which is  easy to remember -
     and a  short name - which  you may prefer because  of the shorter
     markup. -->

<!ELEMENT Keyword (#PCDATA|Alt)*>  <!-- Keyword -->
<!ELEMENT K (#PCDATA|Alt)*>        <!-- Keyword (shortcut) -->

<!ELEMENT Arg (#PCDATA|Alt)*>      <!-- Argument -->
<!ELEMENT A (#PCDATA|Alt)*>        <!-- Argument (shortcut) -->

<!ELEMENT Code (#PCDATA|Alt|A|Arg)*> <!-- GAP code -->
<!ELEMENT C (#PCDATA|Alt|A|Arg)*>    <!-- GAP code (shortcut) -->

<!ELEMENT File (#PCDATA|Alt)*>     <!-- Filename -->
<!ELEMENT F (#PCDATA|Alt)*>        <!-- Filename (shortcut) -->

<!ELEMENT Button (#PCDATA|Alt)*>   <!-- "Button" (also Menu, Key) -->
<!ELEMENT B (#PCDATA|Alt)*>        <!-- "Button" (shortcut) -->

<!ELEMENT Package (#PCDATA|Alt)*>  <!-- A package name -->

<!ELEMENT Quoted (%InnerText;)*>   <!-- Quoted (in quotes) text -->
<!ELEMENT Q (%InnerText;)*>        <!-- Quoted text (shortcut) -->


<!-- The following elements contain mathematical formulae. They are 
     terminal elements that contain character data in TeX notation. -->

<!-- Math with well defined translation to text output -->
<!ELEMENT M (#PCDATA|A|Arg|Alt)*>
<!-- Normal TeX math mode formula -->
<!ELEMENT Math (#PCDATA|A|Arg|Alt)*>   
<!-- TeX displayed math mode formula -->
<!ELEMENT Display (#PCDATA|A|Arg|Alt)*>
<!-- Mode="M" causes <M>-style formatting -->
<!ATTLIST Display Mode CDATA #IMPLIED>  


<!-- The  following  elements  contain  GAP related  text  like  code,
     session  logs or  examples. They  are all  terminal elements  and
     consist of character data which is normally typeset verbatim. The
     different  types  of  the  elements only  control  how  they  are
     treated. -->

<!ELEMENT Example (#PCDATA)>  <!-- This is subject to the automatic 
                                   example checking mechanism -->
<!ELEMENT Log (#PCDATA)>      <!-- This not -->
<!ELEMENT Listing (#PCDATA)>  <!-- This is just for code listings -->
<!ATTLIST Listing Type CDATA #IMPLIED> <!-- a comment about the type of
                                            listed code, may appear in
                                            output -->

<!-- One  further  verbatim element,  this is truely  verbatim without
     any processing and intended  for ASCII substitutes of complicated
     displayed formulae or tables. -->

<!ELEMENT Verb  (#PCDATA)> 

<!-- The following  elements are  for cross-referencing  purposes like
     URLs, citations,  references, and  the index. All  these elements
     are  terminal and  need special  methods  to make  up the  actual
     output during document generation. -->

<!ELEMENT URL (#PCDATA|Alt|Link|LinkText)*>  <!-- Link, LinkText
     variant for case where text needs further markup -->
<!ATTLIST URL Text CDATA #IMPLIED>   <!-- This is for output formats
                                          that have links like HTML -->
<!ELEMENT Link     (%InnerText;)*> <!-- the URL -->
<!ELEMENT LinkText (%InnerText;)*> <!-- text for links, can contain markup -->
<!-- The following two are actually URLs, but the element name determines
     the type. -->
<!ELEMENT Email (#PCDATA|Alt|Link|LinkText)*>
<!ELEMENT Homepage (#PCDATA|Alt|Link|LinkText)*>

<!-- Those who still want to give postal addresses can use the following
     element. Use <Br/> for specifying typical line breaks  -->

<!ELEMENT Address (#PCDATA|Alt|Br)*>

<!ELEMENT Cite EMPTY>
<!ATTLIST Cite Key CDATA #REQUIRED
               Where CDATA #IMPLIED>
               
<!ELEMENT Label EMPTY>
<!ATTLIST Label Name CDATA #REQUIRED>

<!ELEMENT Ref EMPTY>
<!ATTLIST Ref Func      CDATA #IMPLIED
              Oper      CDATA #IMPLIED
              Meth      CDATA #IMPLIED
              Filt      CDATA #IMPLIED
              Prop      CDATA #IMPLIED
              Attr      CDATA #IMPLIED
              Var       CDATA #IMPLIED
              Fam       CDATA #IMPLIED
              InfoClass CDATA #IMPLIED
              Chap      CDATA #IMPLIED
              Sect      CDATA #IMPLIED
              Subsect   CDATA #IMPLIED
              Appendix  CDATA #IMPLIED
              Text      CDATA #IMPLIED

              Label     CDATA #IMPLIED
              BookName  CDATA #IMPLIED
              Style (Text|Number) #IMPLIED>  <!-- normally automatic -->

<!-- Note that  only one attribute  of Ref is used  normally. BookName
     and  Style  can  be  specified in  addition  to  handle  external
     references and the typesetting style of the reference. -->

<!-- For explicit index entries (Func and so on should cause an
     automatically generated index entry). Use the attributes Key,
     Subkey for sorting (simplified, without markup). The Subkey value
     also gets printed. Use the optional Subkey element if the printed
     version needs some markup.                                        -->
<!ELEMENT Index (%InnerText;|Subkey)*>
<!ATTLIST Index Key    CDATA #IMPLIED
                Subkey CDATA #IMPLIED>
<!ELEMENT Subkey (%InnerText;)*>


<!-- ==================================================================
     The following  describes the normal documentation  text which can
     occur  at various  places in  the document.  It does  not contain
     further sectioning elements. In addition to InnerText it can contain 
     environments like enumerations, lists, and such.
     ================================================================== -->

<!ENTITY % Text "%InnerText; | List | Enum | Table">

<!ELEMENT Item ( %Text;)*>
<!ELEMENT Mark ( %InnerText;)*>
<!ELEMENT BigMark ( %InnerText;)*>

<!ELEMENT List ( ((Mark,Item)|(BigMark,Item)|Item)+ )>
<!ATTLIST List Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>
<!ELEMENT Enum ( Item+ )>
<!ATTLIST Enum Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

<!ELEMENT Table ( Caption?, (Row | HorLine)+ )>
<!ATTLIST Table Label   CDATA #IMPLIED
                Only    CDATA #IMPLIED
                Not     CDATA #IMPLIED
                Align   CDATA #REQUIRED>    <!-- A TeX tabular string -->
                <!-- We allow | and l,c,r, nothing else -->
<!ELEMENT Row   ( Item+ )>
<!ELEMENT HorLine EMPTY>
<!ELEMENT Caption ( %InnerText;)*>

<!-- ==================================================================
     We start defining some things within the overall structure:
     ================================================================== -->

<!-- The TitlePage consists of several sub-elements: -->

<!ELEMENT TitlePage (Title, Subtitle?, Version?, TitleComment?, 
                     Author+, Date?, Address?, Abstract?, Copyright?, 
                     Acknowledgements? , Colophon? )>

<!ELEMENT Title (%Text;)*>
<!ELEMENT Subtitle (%Text;)*>
<!ELEMENT Version (%Text;)*>
<!ELEMENT TitleComment (%Text;)*>
<!ELEMENT Author (%Text;)*>    <!-- There may be more than one Author! -->
<!ELEMENT Date (%Text;)*>
<!ELEMENT Abstract (%Text;)*>
<!ELEMENT Copyright (%Text;)*>
<!ELEMENT Acknowledgements (%Text;)*>  
<!ELEMENT Colophon (%Text;)*>


<!-- The following things just specify some information about the
     corresponding parts of the Book: -->

<!ELEMENT TableOfContents EMPTY>
<!ELEMENT Bibliography EMPTY>
<!ATTLIST Bibliography Databases CDATA #REQUIRED
                       Style CDATA #IMPLIED>
<!ELEMENT TheIndex EMPTY>

<!-- ==================================================================
     The Ignore element can be used everywhere to include further
     information in a GAPDoc document which is not intended for the 
     standard converters (e.g., source code, not yet finished stuff,
     and so on. This information can be extracted by special converter 
     routines, more precise information about the content of an Ignore
     element can be given by the "Remark" attribute.
     ================================================================== -->

<!ELEMENT Ignore (%Text;| Chapter | Section | Subsection | ManSection |
                  Heading)*>
<!ATTLIST Ignore Remark CDATA #IMPLIED>
     
<!-- ==================================================================
     Now we go on with the overall structure by defining the sectioning 
     structure, which includes the Synopsis element: 
     ================================================================== -->


<!ELEMENT Subsection (%Text;| Heading)*>
<!ATTLIST Subsection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT ManSection ( Heading?, 
                      ((Func, Returns?) | (Oper, Returns?) | 
                       (Meth, Returns?) | (Filt, Returns?) | 
                       (Prop, Returns?) | (Attr, Returns?) |
                       Var | Fam | InfoClass)+, Description )>
<!ATTLIST ManSection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT Returns (%Text;)*>
<!ELEMENT Description (%Text;)*>


<!-- Note that  the ManSection element  is actually a  subsection with
     respect  to labelling,  referencing, and  counting of  sectioning
     elements. -->

<!ELEMENT Func EMPTY>
<!ATTLIST Func Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!-- Note  that Arg  contains the  full list  of arguments,  including
     optional  parts,  which  are   denoted  by  square  brackets  [].
     Arguments   are  separated   by  whitespace,   commas  count   as
     whitespace. -->

<!-- Note further that although Name and Label are  CDATA (and not ID)
     Label must make up a unique identifier. -->

<!ELEMENT Oper EMPTY>
<!ATTLIST Oper Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>
             
<!ELEMENT Meth EMPTY>
<!ATTLIST Meth Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Filt EMPTY>
<!ATTLIST Filt Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #IMPLIED
               Comm  CDATA #IMPLIED
               Type  CDATA #IMPLIED>  

<!ELEMENT Prop EMPTY>
<!ATTLIST Prop Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Attr EMPTY>
<!ATTLIST Attr Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

<!ELEMENT Var  EMPTY>
<!ATTLIST Var  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

<!ELEMENT Fam  EMPTY>
<!ATTLIST Fam  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

<!ELEMENT InfoClass EMPTY>
<!ATTLIST InfoClass Name  CDATA #REQUIRED
                    Label CDATA #IMPLIED
                    Comm  CDATA #IMPLIED>


<!ELEMENT Heading (%InnerText;)*>

<!ELEMENT Section (%Text;| Heading | Subsection | ManSection)*>
<!ATTLIST Section Label CDATA #IMPLIED>    <!-- For reference purposes -->


<!ELEMENT Chapter (%Text;| Heading | Section)*>
<!ATTLIST Chapter Label CDATA #IMPLIED>    <!-- For reference purposes -->


<!-- Note that  the entity %InnerText; is  documentation that contains
     neither sectioning  elements nor environments  like enumerations,
     but  only  formulae,  labels, references,  citations,  and  other
     terminal elements. -->

<!ELEMENT Appendix (%Text;| Heading | Section)*>
<!ATTLIST Appendix Label CDATA #IMPLIED>   <!-- For reference purposes -->

<!-- Note that  an Appendix  is exactly  the same  as a  Chapter. They
     differ only in the numbering. -->

<!-- ==================================================================
     At last we define the overall structure of a gapdoc Book:
     ================================================================== -->

<!ELEMENT Body  ( %Text;| Chapter | Section )*>

<!ELEMENT Book (TitlePage,
                TableOfContents?,
                Body,
                Appendix*,
                Bibliography?,
                TheIndex?)>
<!ATTLIST Book Name CDATA #REQUIRED>
               
<!-- Note  that  the  entity  %Text; is  documentation  that  contains
     no  further sectioning  elements but  possibly environments  like
     enumerations,  and formulae,  labels, references,  and citations.
     -->

<!-- ============================================================== -->


Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/gapdoc.jpg0000644000175000017500000000411412026346063013707 0ustar billbillJFIFGGCreated with The GIMPC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222")!1"AQaq#23B!!1AQ"2a ?mkyS?#,I{[teLntr\\ &֣qgwqZe^{-2~)9}Űyϧʯ2fr+^Iz Xx@L+ۊE2K~T.c|pƼBs ` -.VmϞ^kKu˖\}9ӘGO.']}ĉͻk/g /5|'/4p\_(njԞ^lt\\o=|}X߅rV|:ۙl&:naN>K?,1UՎ:~L1kB&)-@[-IWY>&Ϭ%,vteFRFw-qZ'6";k nrfOߧ/Bk+ҶI>xXO&frWdqΦ,a<5㍓ g ˥g;-1Օmnyo+DI"|?&wuu#y~[ǎ߳ sveu  str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY"); "XXX\033[32mBLUB\033[0mYYY" gap> str2 := WrapTextAttribute(str, TextAttr.1); "\033[31mXXX\033[32mBLUB\033[0m\033[31m\027YYY\033[0m" gap> str3 := WrapTextAttribute(str, TextAttr.underscore); "\033[4mXXX\033[32mBLUB\033[0m\033[4m\027YYY\033[0m" gap> # use Print(str); and so on to see how it looks like.  6.1-4 FormatParagraph FormatParagraph( str[, len][, flush][, attr][, widthfun] )  function Returns: the formatted paragraph as string This function formats a text given in the string str as a paragraph. The optional arguments have the following meaning: len the length of the lines of the formatted text, default is 78 (counted without a visible length of the strings specified in the attr argument) flush can be "left", "right", "center" or "both", telling that lines should be flushed left, flushed right, centered or left-right justified, respectively, default is "both" attr is a list of two strings; the first is prepended and the second appended to each line of the result (can for example be used for indenting, [" ", ""], or some markup, [TextAttr.bold, TextAttr.reset], default is ["", ""]) widthfun must be a function which returns the display width of text in str. The default is Length assuming that each byte corresponds to a character of width one. If str is given in UTF-8 encoding one can use WidthUTF8String (6.2-3) here. This function tries to handle markup with the escape sequences explained in TextAttr (6.1-2) correctly.  Example  gap> str := "One two three four five six seven eight nine ten eleven.";; gap> Print(FormatParagraph(str, 25, "left", ["/* ", " */"]));  /* One two three four five */ /* six seven eight nine ten */ /* eleven. */  6.1-5 SubstitutionSublist SubstitutionSublist( list, sublist, new[, flag] )  function Returns: the changed list This function looks for (non-overlapping) occurrences of a sublist sublist in a list list (compare PositionSublist (Reference: PositionSublist)) and returns a list where these are substituted with the list new. The optional argument flag can either be "all" (this is the default if not given) or "one". In the second case only the first occurrence of sublist is substituted. If sublist does not occur in list then list itself is returned (and not a ShallowCopy(list)).  Example  gap> SubstitutionSublist("xababx", "ab", "a"); "xaax"  6.1-6 StripBeginEnd StripBeginEnd( list, strip )  function Returns: changed string Here list and strip must be lists. This function returns the sublist of list which does not contain the leading and trailing entries which are entries of strip. If the result is equal to list then list itself is returned.  Example  gap> StripBeginEnd(" ,a, b,c, ", ", "); "a, b,c"  6.1-7 StripEscapeSequences StripEscapeSequences( str )  function Returns: string without escape sequences This function returns the string one gets from the string str by removing all escape sequences which are explained in TextAttr (6.1-2). If str does not contain such a sequence then str itself is returned. 6.1-8 RepeatedString RepeatedString( c, len )  function RepeatedUTF8String( c, len )  function Here c must be either a character or a string and len is a non-negative number. Then RepeatedString returns a string of length len consisting of copies of c. In the variant RepeatedUTF8String the argument c is considered as string in UTF-8 encoding, and it can also be specified as unicode string or character, see Unicode (6.2-1). The result is a string in UTF-8 encoding which has visible width len as explained in WidthUTF8String (6.2-3).  Example  gap> RepeatedString('=',51); "===================================================" gap> RepeatedString("*=",51); "*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*" gap> s := "bäh";; gap> enc := GAPInfo.TermEncoding;; gap> if enc <> "UTF-8" then s := Encode(Unicode(s, enc), "UTF-8"); fi; gap> l := RepeatedUTF8String(s, 8);; gap> u := Unicode(l, "UTF-8");; gap> Print(Encode(u, enc), "\n"); bähbähbä  6.1-9 NumberDigits NumberDigits( str, base )  function Returns: integer DigitsNumber( n, base )  function Returns: string The argument str of NumberDigits must be a string consisting only of an optional leading '-' and characters in 0123456789abcdefABCDEF, describing an integer in base base with 2 ≤ base ≤ 16. This function returns the corresponding integer. The function DigitsNumber does the reverse.  Example  gap> NumberDigits("1A3F",16); 6719 gap> DigitsNumber(6719, 16); "1A3F"  6.1-10 PositionMatchingDelimiter PositionMatchingDelimiter( str, delim, pos )  function Returns: position as integer or fail Here str must be a string and delim a string with two different characters. This function searches the smallest position r of the character delim[2] in str such that the number of occurrences of delim[2] in str between positions pos+1 and r is by one greater than the corresponding number of occurrences of delim[1]. If such an r exists, it is returned. Otherwise fail is returned.  Example  gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0); fail gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1); 2 gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6); 11  6.1-11 WordsString WordsString( str )  function Returns: list of strings containing the words This returns the list of words of a text stored in the string str. All non-letters are considered as word boundaries and are removed.  Example  gap> WordsString("one_two \n three!?"); [ "one", "two", "three" ]  6.1-12 Base64String Base64String( str )  function StringBase64( bstr )  function Returns: a string The first function translates arbitrary binary data given as a GAP string into a base 64 encoded string. This encoded string contains only printable ASCII characters and is used in various data transfer protocols (MIME encoded emails, weak password encryption, ...). We use the specification in RFC 2045 (http://tools.ietf.org/html/rfc2045). The second function has the reverse functionality. Here we also accept the characters -_ instead of +/ as last two characters. Whitespace is ignored.  Example  gap> b := Base64String("This is a secret!"); "VGhpcyBpcyBhIHNlY3JldCEA=" gap> StringBase64(b);  "This is a secret!"  6.2 Unicode Strings The GAPDoc package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings. 6.2-1 Unicode Strings and Characters Unicode( list[, encoding] )  operation UChar( num )  operation IsUnicodeString filter IsUnicodeCharacter filter IntListUnicodeString( ustr )  function Unicode characters are described by their codepoint, an integer in the range from 0 to 2^21-1. For details about unicode, see http://www.unicode.org. The function UChar wraps an integer num into a GAP object lying in the filter IsUnicodeCharacter. Use Int to get the codepoint back. The argument num can also be a GAP character which is then translated to an integer via IntChar (Reference: IntChar). Unicode produces a GAP object in the filter IsUnicodeString. This is a wrapped list of integers for the unicode characters in the string. The function IntListUnicodeString gives access to this list of integers. Basic list functionality is available for IsUnicodeString elements. The entries are in IsUnicodeCharacter. The argument list for Unicode is either a list of integers or a GAP string. In the latter case an encoding can be specified as string, its default is "UTF-8". Currently supported encodings can be found in UNICODE_RECODE.NormalizedEncodings (ASCII, ISO-8859-X, UTF-8 and aliases). The encoding "XML" means an ASCII encoding in which non-ASCII characters are specified by XML character entities. The encoding "URL" is for URL-encoded (also called percent-encoded strings, as specified in RFC 3986 (see here (http://www.ietf.org/rfc/rfc3986.txt)). The listed encodings "LaTeX" and aliases cannot be used with Unicode. See the operation Encode (6.2-2) for mapping a unicode string to a GAP string.  Example  gap> ustr := Unicode("a and \366", "latin1"); Unicode("a and \303\266") gap> ustr = Unicode("a and ö", "XML");  true gap> IntListUnicodeString(ustr); [ 97, 32, 97, 110, 100, 32, 246 ] gap> ustr[7]; 'ö'  6.2-2 Encode Encode( ustr[, encoding] )  operation Returns: a GAP string SimplifiedUnicodeString( ustr[, encoding][, "single"] )  function Returns: a unicode string LowercaseUnicodeString( ustr )  function Returns: a unicode string UppercaseUnicodeString( ustr )  function Returns: a unicode string LaTeXUnicodeTable global variable SimplifiedUnicodeTable global variable LowercaseUnicodeTable global variable The operation Encode translates a unicode string ustr into a GAP string in some specified encoding. The default encoding is "UTF-8". Supported encodings can be found in UNICODE_RECODE.NormalizedEncodings. Except for some cases mentioned below characters which are not available in the target encoding are substituted by '?' characters. If the encoding is "URL" (see Unicode (6.2-1)) then an optional argument encreserved can be given, it must be a list of reserved characters which should be percent encoded; the default is to encode only the % character. The encoding "LaTeX" substitutes non-ASCII characters and LaTeX special characters by LaTeX code as given in an ordered list LaTeXUnicodeTable of pairs [codepoint, string]. If you have a unicode character for which no substitution is contained in that list, you will get a warning and the translation is Unicode(nr). In this case find a substitution and add a corresponding [codepoint, string] pair to LaTeXUnicodeTable using AddSet (Reference: AddSet). Also, please, tell the GAPDoc authors about your addition, such that we can extend the list LaTeXUnicodeTable. (Most of the initial entries were generated from lists in the TeX projects encTeX and ucs.) There are some variants of this encoding: "LaTeXleavemarkup" does the same translations for non-ASCII characters but leaves the LaTeX special characters (e.g., any LaTeX commands) as they are. "LaTeXUTF8" does not give a warning about unicode characters without explicit translation, instead it translates the character to its UTF-8 encoding. Make sure to setup your LaTeX document such that all these characters are understood. "LaTeXUTF8leavemarkup" is a combination of the last two variants. Note that the "LaTeX" encoding can only be used with Encode but not for the opposite translation with Unicode (6.2-1) (which would need far too complicated heuristics). The function SimplifiedUnicodeString can be used to substitute many non-ASCII characters by related ASCII characters or strings (e.g., by a corresponding character without accents). The argument ustr and the result are unicode strings, if encoding is "ASCII" then all non-ASCII characters are translated, otherwise only the non-latin1 characters. If the string "single" in an argument then only substitutions are considered which don't make the result string longer. The translations are stored in a sorted list SimplifiedUnicodeTable. Its entries are of the form [codepoint, trans1, trans2, ...]. Here trans1 and so on is either an integer for the codepoint of a substitution character or it is a list of codepoint integers. If you are missing characters in this list and know a sensible ASCII approximation, then add an entry (with AddSet (Reference: AddSet)) and tell the GAPDoc authors about it. (The initial content of SimplifiedUnicodeTable was mainly generated from the transtab tables by Markus Kuhn.) The function LowercaseUnicodeString gets and returns a unicode string and translates each uppercase character to its corresponding lowercase version. This function uses a list LowercaseUnicodeTable of pairs of codepoint integers. This list was generated using the file UnicodeData.txt from the unicode definition (field 14 in each row). The function UppercaseUnicodeString does the similar translation to uppercase characters.  Example  gap> ustr := Unicode("a and ö", "XML"); Unicode("a and \303\266") gap> SimplifiedUnicodeString(ustr, "ASCII"); Unicode("a and oe") gap> SimplifiedUnicodeString(ustr, "ASCII", "single"); Unicode("a and o") gap> ustr2 := UppercaseUnicodeString(ustr);; gap> Print(Encode(ustr2, GAPInfo.TermEncoding), "\n"); A AND Ö  6.2-3 Lengths of UTF-8 strings WidthUTF8String( str )  function NrCharsUTF8String( str )  function Returns: an integer Let str be a GAP string with text in UTF-8 encoding. There are three lengths of such a string which must be distinguished. The operation Length (Reference: Length) returns the number of bytes and so the memory occupied by str. The function NrCharsUTF8String returns the number of unicode characters in str, that is the length of Unicode(str). In many applications the function WidthUTF8String is more interesting, it returns the number of columns needed by the string if printed to a terminal. This takes into account that some unicode characters are combining characters and that there are wide characters which need two columns (e.g., for Chinese or Japanese). (To be precise: This implementation assumes that there are no control characters in str and uses the character width returned by the wcwidth function in the GNU C-library called with UTF-8 locale.)  Example  gap> # A, German umlaut u, B, zero width space, C, newline gap> str := Encode( Unicode( "AüB​C\n", "XML" ) );; gap> Print(str); AüB​C gap> # umlaut u needs two bytes and the zero width space three gap> Length(str); 9 gap> NrCharsUTF8String(str); 6 gap> # zero width space and newline don't contribute to width gap> WidthUTF8String(str); 4  6.3 Print Utilities The following printing utilities turned out to be useful for interactive work with texts in GAP. But they are more general and so we document them here. 6.3-1 PrintTo1 PrintTo1( filename, fun )  function AppendTo1( filename, fun )  function The argument fun must be a function without arguments. Everything which is printed by a call fun() is printed into the file filename. As with PrintTo (Reference: PrintTo) and AppendTo (Reference: AppendTo) this overwrites or appends to, respectively, a previous content of filename. These functions can be particularly efficient when many small pieces of text shall be written to a file, because no multiple reopening of the file is necessary.  Example  gap> f := function() local i;  >  for i in [1..100000] do Print(i, "\n"); od; end;;  gap> PrintTo1("nonsense", f); # now check the local file `nonsense'  6.3-2 StringPrint StringPrint( obj1[, obj2[, ...]] )  function StringView( obj )  function These functions return a string containing the output of a Print or ViewObj call with the same arguments. This should be considered as a (temporary?) hack. It would be better to have String (Reference: String) methods for all GAP objects and to have a generic Print (Reference: Print)-function which just interprets these strings. 6.3-3 PrintFormattedString PrintFormattedString( str )  function This function prints a string str. The difference to Print(str); is that no additional line breaks are introduced by GAP's standard printing mechanism. This can be used to print lines which are longer than the current screen width. In particular one can print text which contains escape sequences like those explained in TextAttr (6.1-2), where lines may have more characters than visible characters. 6.3-4 Page Page( ... )  function PageDisplay( obj )  function These functions are similar to Print (Reference: Print) and Display (Reference: Display), respectively. The difference is that the output is not sent directly to the screen, but is piped into the current pager; see Pager (Reference: Pager).  Example  gap> Page([1..1421]+0); gap> PageDisplay(CharacterTable("Symmetric", 14));  6.3-5 StringFile StringFile( filename )  function FileString( filename, str[, append] )  function The function StringFile returns the content of file filename as a string. This works efficiently with arbitrary (binary or text) files. If something went wrong, this function returns fail. Conversely the function FileString writes the content of a string str into the file filename. If the optional third argument append is given and equals true then the content of str is appended to the file. Otherwise previous content of the file is deleted. This function returns the number of bytes written or fail if something went wrong. Both functions are quite efficient, even with large files. GAPDoc-1.5.1/doc/testbib.xml0000644000175000017500000000136212026346063014130 0ustar billbill
Fritz A.First X. Y.Secőnd The <Wrap Name="Package"> <C>F</C>ritz</Wrap> package for the formula <M>x^y - l_{{i+1}} \rightarrow \mathbb{R}</M> 2000 13 13–25 Online data at http://www.publish.com/~ImpJ/123#data very useful
GAPDoc-1.5.1/doc/nocolorprompt.css0000644000175000017500000000031312026346063015374 0ustar billbill /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } GAPDoc-1.5.1/doc/chapBib.txt0000644000175000017500000000115012026346063014036 0ustar billbill References [GAP] GAP -- Groups, Algorithms, and Programming, Version 4.4.9, The GAP Group, Aachen, St Andrews (2006), ((http://www.gap-system.org)). [Lam85] Lamport, L., LaTeX: A Document Preparation System, Addison-Wesley (1985). [Neu07] Neunhöffer, M., IO, Bindings for low level C library IO, Version 2.2 (2007), ((GAP package)), http://www-groups.mcs.st-and.ac.uk/~neunhoef/Computer/Software/Gap/io.html.  GAPDoc-1.5.1/doc/chapA.html0000644000175000017500000001272312026346063013657 0ustar billbill GAP (GAPDoc) - Appendix A: The File 3k+1.xml
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

A The File 3k+1.xml

Here is the complete source of the example GAPDoc document 3k+1.xml discussed in Section 1.2.

<?xml version="1.0" encoding="UTF-8"?>

<!--   A complete "fake package" documentation   
-->

<!DOCTYPE Book SYSTEM "gapdoc.dtd">

<Book Name="3k+1">

<TitlePage>
  <Title>The <Package>ThreeKPlusOne</Package> Package</Title>
  <Version>Version 42</Version>
  <Author>Dummy Authör
    <Email>3kplusone@dev.null</Email>
  </Author>

  <Copyright>&copyright; 2000 The Author. <P/>
    You can do with this package what you want.<P/> Really.
  </Copyright>
</TitlePage>

<TableOfContents/>

<Body>
  <Chapter> <Heading>The <M>3k+1</M> Problem</Heading>
    <Section Label="sec:theory"> <Heading>Theory</Heading>
      Let  <M>k \in  &NN;</M> be  a  natural number.  We consider  the
      sequence <M>n(i, k), i \in &NN;,</M> with <M>n(1, k) = k</M> and
      else <M>n(i+1,  k) = n(i, k)  / 2</M> if <M>n(i,  k)</M> is even
      and <M>n(i+1, k) =  3 n(i, k) + 1</M> if  <M>n(i, k)</M> is odd.
      <P/> It  is not known  whether for  any natural number  <M>k \in
      &NN;</M> there is an <M>m \in &NN;</M> with <M>n(m, k) = 1</M>.
      <P/>
      <Package>ThreeKPlusOne</Package>  provides   the  function  <Ref
      Func="ThreeKPlusOneSequence"/>   to  explore   this  for   given
      <M>n</M>.  If  you really  want  to  know something  about  this
      problem, see <Cite Key="Wi98"/> or
      <URL>http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/</URL>
      for more details (and forget this package).
    </Section>

    <Section> <Heading>Program</Heading>
      In this section we describe the main function of this package.
      <ManSection> 
        <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/>
        <Description>
          This  function computes  for a  natural number  <A>k</A> the
          beginning of the sequence  <M>n(i, k)</M> defined in section
          <Ref Sect="sec:theory"/>.  The sequence  stops at  the first
          <M>1</M>  or at  <M>n(<A>max</A>, k)</M>,  if <A>max</A>  is
          given.
<Example>
gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
</Example>
        </Description>
      </ManSection>
    </Section>
  </Chapter>
</Body>

<Bibliography Databases="3k+1" />
<TheIndex/>

</Book>

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/test.bib0000644000175000017500000000021412026346063013402 0ustar billbill@string{ j = "Important Journal" } @article{ AB2000, Author= "Fritz A. First and Sec, X. Y.", TITLE="Short", journal = j, year = 2000 } GAPDoc-1.5.1/doc/chap4_mj.html0000644000175000017500000002667212026346063014340 0ustar billbill GAP (GAPDoc) - Chapter 4: Distributing a Document into Several Files
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

4 Distributing a Document into Several Files

In GAPDoc there are facilities to distribute a single document over several files. This is for example interesting, if one wants to store the documentation of some code in the same file as the code itself. Or, if one just wants to store chapters of a document in separate files. There is a set of conventions how this is done and some tools to collect the text for further processing.

The technique can also be used to distribute and collect other types of documents into respectively from several files (e.g., source code, examples).

4.1 The Conventions

In this description we use the string GAPDoc for marking pieces of a document to collect.

Pieces of documentation that shall be incorporated into another document are marked as follows:

##  <#GAPDoc Label="MyPiece">
##  <E>This</E> is the piece.
##  The hash characters are removed.
##  <#/GAPDoc>

This piece is then included into another file by a statement like: <#Include Label="MyPiece"> Here are the exact rules, how pieces are gathered:

  • All lines up to a line containing the character sequence "<#GAPDoc Label="" (exactly one space character) are ignored. The characters on the same line before this sequence are stored as "prefix". The characters after the sequence up to the next double quotes character are stored as "label". All other characters in the line are ignored.

  • The following lines up to a line containing the character sequence "<#/GAPDoc>" are stored under the label. These lines are processed as follows: The longest possible substring from the beginning of the line that equals the corresponding substring of the prefix is removed.

Having stored a list of labels and pieces of text gathered as above this can be used as follows.

  • In GAPDoc documentation files all statements of the form "<#Include Label="Key">" are replaced by the sequence of lines stored under the label Key.

  • Additionally, every occurrence of a statement of the form "<#Include SYSTEM "Filename">" is replaced by the whole file stored under the name Filename in the file system.

  • These substitutions are done recursively (although one should probably avoid to use this extensively).

Here is another example:

# # <#GAPDoc Label="AnotherPiece">  some characters
# # This text is not indented.
#  This text is indented by one blank.
#Not indented.
#<#/GAPDoc>

replaces <#Include Label="AnotherPiece"> by

This text is not indented.
 This text is indented by one blank. 
Not indented.

Since these rules are very simple it is quite easy to write a program in almost any programming language which does this gathering of text pieces and the substitutions. In GAPDoc there is the GAP function ComposedDocument (4.2-1) which does this.

Note that the XML-tag-like markup we have used here is not a legal XML markup, since the hash character is not allowed in element names. The mechanism described here is a preprocessing step which composes a document.

4.2 A Tool for Collecting a Document

4.2-1 ComposedDocument
‣ ComposedDocument( tagname, path, main, source[, info] )( function )
‣ ComposedXMLString( path, main, source[, info] )( function )

Returns: a document as string, or a list with this string and information about the source positions

The argument tagname is the string used for the pseudo elements which mark the pieces of a document to collect. (In 4.1 we used GAPDoc as tagname. The second function ComposedXMLString( ... ) is an abbreviation for ComposedDocument("GAPDoc", ... ).

The argument path must be a path to some directory (as string or directory object), main the name of a file in this directory and source a list of file names, all of these relative to path. The document is constructed via the mechanism described in Section 4.1.

First the files given in source are scanned for chunks of the document marked by <#tagname Label="..."> and </#tagname> pairs. Then the file main is read and all <#Include ... >-tags are substituted recursively by other files or chunks of documentation found in the first step, respectively. If the optional argument info is given and set to true this function returns a list [str, origin], where str is a string containing the composed document and origin is a sorted list of entries of the form [pos, filename, line]. Here pos runs through all character positions of starting lines or text pieces from different files in str. The filename and line describe the origin of this part of the collected document. Without the fourth argument only the string str is returned.

gap> doc := ComposedDocument("GAPDoc", "/my/dir", "manual.xml", 
> ["../lib/func.gd", "../lib/func.gi"], true);;

4.2-2 OriginalPositionDocument
‣ OriginalPositionDocument( srcinfo, pos )( function )

Returns: A pair [filename, linenumber].

Here srcinfo must be a data structure as returned as second entry by ComposedDocument (4.2-1) called with info=true. It returns for a given position pos in the composed document the file name and line number from which that text was collected.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/manual.js0000644000175000017500000001003412026346063013561 0ustar billbill/* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { document.writeln(''); document.writeln(''); } } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } GAPDoc-1.5.1/doc/chap1.html0000644000175000017500000005026312026346063013640 0ustar billbill GAP (GAPDoc) - Chapter 1: Introduction and Example
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

1 Introduction and Example

The main purpose of the GAPDoc package is to define a file format for documentation of GAP-programs and -packages (see [GAP]). The problem is that such documentation should be readable in several output formats. For example it should be possible to read the documentation inside the terminal in which GAP is running (a text mode) and there should be a printable version in high typesetting quality (produced by some version of TeX). It is also popular to view GAP's online help with a Web-browser via an HTML-version of the documentation. Nowadays one can use LaTeX and standard viewer programs to produce and view on the screen dvi- or pdf-files with full support of internal and external hyperlinks. Certainly there will be other interesting document formats and tools in this direction in the future.

Our aim is to find a format for writing the documentation which allows a relatively easy translation into the output formats just mentioned and which hopefully makes it easy to translate to future output formats as well.

To make documentation written in the GAPDoc format directly usable, we also provide a set of programs, called converters, which produce text-, hyperlinked LaTeX- and HTML-output versions of a GAPDoc document. These programs are developed by the first named author. They run completely inside GAP, i.e., no external programs are needed. You only need latex and pdflatex to process the LaTeX output. These programs are described in Chapter 5.

1.1 XML

The definition of the GAPDoc format uses XML, the "eXtendible Markup Language". This is a standard (defined by the W3C consortium, see http://www.w3c.org) which lays down a syntax for adding markup to a document or to some data. It allows to define document structures via introducing markup elements and certain relations between them. This is done in a document type definition. The file gapdoc.dtd contains such a document type definition and is the central part of the GAPDoc package.

The easiest way for getting a good idea about this is probably to look at an example. The Appendix A contains a short but complete GAPDoc document for a fictitious share package. In the next section we will go through this document, explain basic facts about XML and the GAPDoc document type, and give pointers to more details in later parts of this documentation.

In the last Section 1.3 of this introductory chapter we try to answer some general questions about the decisions which lead to the GAPDoc package.

1.2 A complete example

In this section we recall the lines from the example document in Appendix A and give some explanations.

<?xml version="1.0" encoding="UTF-8"?> 

This line just tells a human reader and computer programs that the file is a document with XML markup and that the text is encoded in the UTF-8 character set (other common encodings are ASCII or ISO-8895-X encodings).

<!--   A complete "fake package" documentation   
-->

Everything in a XML file between "<!--" and "-->" is a comment and not part of the document content.

<!DOCTYPE Book SYSTEM "gapdoc.dtd">

This line says that the document contains markup which is defined in the system file gapdoc.dtd and that the markup obeys certain rules defined in that file (the ending dtd means "document type definition"). It further says that the actual content of the document consists of an element with name "Book". And we can really see that the remaining part of the file is enclosed as follows:

<Book Name="3k+1">
  [...] (content omitted)
</Book>

This demonstrates the basics of the markup in XML. This part of the document is an "element". It consists of the "start tag" <Book Name="3k+1">, the "element content" and the "end tag" </Book> (end tags always start with </). This element also has an "attribute" Name whose "value" is 3k+1.

If you know HTML, this will look familiar to you. But there are some important differences: The element name Book and attribute name Name are case sensitive. The value of an attribute must always be enclosed in quotes. In XML every element has a start and end tag (which can be combined for elements defined as "empty", see for example <TableOfContents/> below).

If you know LaTeX, you are familiar with quite different types of markup, for example: The equivalent of the Book element in LaTeX is \begin{document} ... \end{document}. The sectioning in LaTeX is not done by explicit start and end markup, but implicitly via heading commands like \section. Other markup is done by using braces {} and putting some commands inside. And for mathematical formulae one can use the $ for the start and the end of the markup. In XML all markup looks similar to that of the Book element.

The content of the book starts with a title page.

<TitlePage>
  <Title>The <Package>ThreeKPlusOne</Package> Package</Title>
  <Version>Version 42</Version>
  <Author>Dummy Authör
    <Email>3kplusone@dev.null</Email>
  </Author>

  <Copyright>&copyright; 2000 The Author. <P/>
    You can do with this package what you want.<P/> Really.
  </Copyright>
</TitlePage>

The content of the TitlePage element consists again of elements. In Chapter 3 we describe which elements are allowed within a TitlePage and that their ordering is prescribed in this case. In the (stupid) name of the author you see that a German umlaut is used directly (in ISO-latin1 encoding).

Contrary to LaTeX- or HTML-files this markup does not say anything about the actual layout of the title page in any output version of the document. It just adds information about the meaning of pieces of text.

Within the Copyright element there are two more things to learn about XML markup. The <P/> is a complete element. It is a combined start and end tag. This shortcut is allowed for elements which are defined to be always "empty", i.e., to have no content. You may have already guessed that <P/> is used as a paragraph separator. Note that empty lines do not separate paragraphs (contrary to LaTeX).

The other construct we see here is &copyright;. This is an example of an "entity" in XML and is a macro for some substitution text. Here we use an entity as a shortcut for a complicated expression which makes it possible that the term copyright is printed as some text like (C) in text terminal output and as a copyright character in other output formats. In GAPDoc we predefine some entities. Certain "special characters" must be typed via entities, for example "<", ">" and "&" to avoid a misinterpretation as XML markup. It is possible to define additional entities for your document inside the <!DOCTYPE ...> declaration, see 2.2-3.

Note that elements in XML must always be properly nested, as in this example. A construct like <a><b>...</a></b> is not allowed.

<TableOfContents/>

This is another example of an "empty element". It just means that a table of contents for the whole document should be included into any output version of the document.

After this the main text of the document follows inside certain sectioning elements:

<Body>
  <Chapter> <Heading>The <M>3k+1</M> Problem</Heading>
    <Section Label="sec:theory"> <Heading>Theory</Heading>
      [...] (content omitted)
    </Section>
    <Section> <Heading>Program</Heading>
      [...] (content omitted) 
    </Section>
  </Chapter>
</Body>

These elements are used similarly to "\chapter" and "\section" in LaTeX. But note that the explicit end tags are necessary here.

The sectioning commands allow to assign an optional attribute "Label". This can be used for referring to a section inside the document.

The text of the first section starts as follows. The whitespace in the text is unimportant and the indenting is not necessary.


      Let  <M>k \in  &NN;</M> be  a  natural number.  We consider  the
      sequence <M>n(i, k), i \in &NN;,</M> with <M>n(1, k) = k</M> and
      else 

Here we come to the interesting question how to type mathematical formulae in a GAPDoc document. We did not find any alternative for writing formulae in TeX syntax. (There is MATHML, but even simple formulae contain a lot of markup, become quite unreadable and they are cumbersome to type. Furthermore there seem to be no tools available which translate such formulae in a nice way into TeX and text.) So, formulae are essentially typed as in LaTeX. (Actually, it is also possible to type unicode characters of some mathematical symbols directly, or via an entity like the &NN; above.) There are three types of elements containing formulae: "M", "Math" and "Display". The first two are for in-text formulae and the third is for displayed formulae. Here "M" and "Math" are equivalent, when translating a GAPDoc document into LaTeX. But they are handled differently for terminal text (and HTML) output. For the content of an "M"-element there are defined rules for a translation into well readable terminal text. More complicated formulae are in "Math" or "Display" elements and they are just printed as they are typed in text output. So, to make a section well readable inside a terminal window you should try to put as many formulae as possible into "M"-elements. In our example text we used the notation n(i, k) instead of n_i(k) because it is easier to read in text mode. See Sections 2.2-2 and 3.9 for more details.

A few lines further on we find two non-internal references.

      problem, see <Cite Key="Wi98"/> or
      <URL>http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/</URL>

The first within the "Cite"-element is the citation of a book. In GAPDoc we use the widely used BibTeX database format for reference lists. This does not use XML but has a well documented structure which is easy to parse. And many people have collections of references readily available in this format. The reference list in an output version of the document is produced with the empty element

<Bibliography Databases="3k+1" />

close to the end of our example file. The attribute "Databases" give the name(s) of the database (.bib) files which contain the references.

Putting a Web-address into an "URL"-element allows one to create a hyperlink in output formats which allow this.

The second section of our example contains a special kind of subsection defined in GAPDoc.

      <ManSection> 
        <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/>
        <Description>
          This  function computes  for a  natural number  <A>k</A> the
          beginning of the sequence  <M>n(i, k)</M> defined in section
          <Ref Sect="sec:theory"/>.  The sequence  stops at  the first
          <M>1</M>  or at  <M>n(<A>max</A>, k)</M>,  if <A>max</A>  is
          given.
<Example>
gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
</Example>
        </Description>
      </ManSection>

A "ManSection" contains the description of some function, operation, method, filter and so on. The "Func"-element describes the name of a function (there are also similar elements "Oper", "Meth", "Filt" and so on) and names for its arguments, optional arguments enclosed in square brackets. See Section 3.4 for more details.

In the "Description" we write the argument names as "A"-elements. A good description of a function should usually contain an example of its use. For this there are some verbatim-like elements in GAPDoc, like "Example" above (here, clearly, whitespace matters which causes a slightly strange indenting).

The text contains an internal reference to the first section via the explicitly defined label sec:theory.

The first section also contains a "Ref"-element which refers to the function described here. Note that there is no explicit label for such a reference. The pair <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/> and <Ref Func="ThreeKPlusOneSequence"/> does the cross referencing (and hyperlinking if possible) implicitly via the name of the function.

Here is one further element from our example document which we want to explain.

<TheIndex/>

This is again an empty element which just says that an output version of the document should contain an index. Many entries for the index are generated automatically because the "Func" and similar elements implicitly produce such entries. It is also possible to include explicit additional entries in the index.

1.3 Some questions

Are those XML files too ugly to read and edit?

Just have a look and decide yourself. The markup needs more characters than most TeX or LaTeX markup. But the structure of the document is easier to see. If you configure your favorite editor well, you do not need more key strokes for typing the markup than in LaTeX.

Why do we not use LaTeX alone?

LaTeX is good for writing books. But LaTeX files are generally difficult to parse and to process to other output formats like text for browsing in a terminal window or HTML (or new formats which may become popular in the future). GAPDoc markup is one step more abstract than LaTeX insofar as it describes meaning instead of appearance of text. The inner workings of LaTeX are too complicated to learn without pain, which makes it difficult to overcome problems that occur occasionally.

Why XML and not a newly defined markup language?

XML is a well defined standard that is more and more widely used. Lots of people have thought about it. Years of experience with SGML went into the design. It is easy to explain, easy to parse and lots of tools are available, there will be more in the future.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap3_mj.html0000644000175000017500000027774712026346063014352 0ustar billbill GAP (GAPDoc) - Chapter 3: The Document Type Definition
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

3 The Document Type Definition

3 The Document Type Definition

In this chapter we first explain what a "document type definition" is and then describe gapdoc.dtd in detail. That file together with the current chapter define how a GAPDoc document has to look like. It can be found in the main directory of the GAPDoc package and it is reproduced in Appendix B.

We do not give many examples in this chapter which is more intended as a formal reference for all GAPDoc elements. Instead we provide an extra document with book name GAPDocExample (also accessible from the GAP online help). This uses all the constructs introduced in this chapter and you can easily compare the source code and how it looks like in the different output formats. Furthermore recall that many basic things about XML markup were already explained by example in the introductory chapter 1.

3.1 What is a DTD?

A document type definition (DTD) is a formal declaration of how an XML document has to be structured. It is itself structured such that programs that handle documents can read it and treat the documents accordingly. There are for example parsers and validity checkers that use the DTD to validate an XML document, see 2.1-14.

The main thing a DTD does is to specify which elements may occur in documents of a certain document type, how they can be nested, and what attributes they can or must have. So, for each element there is a rule.

Note that a DTD can not ensure that a document which is "valid" also makes sense to the converters! It only says something about the formal structure of the document.

For the remaining part of this chapter we have divided the elements of GAPDoc documents into several subsets, each of which will be discussed in one of the next sections.

See the following three subsections to learn by example, how a DTD works. We do not want to be too formal here, but just enable the reader to understand the declarations in gapdoc.dtd. For precise descriptions of the syntax of DTD's see again the official standard in:

  http://www.xml.com/axml/axml.html

3.2 Overall Document Structure

A GAPDoc document contains on its top level exactly one element with name Book. This element is declared in the DTD as follows:

3.2-1 <Book>
<!ELEMENT Book (TitlePage,
                TableOfContents?,
                Body,
                Appendix*,
                Bibliography?,
                TheIndex?)>
<!ATTLIST Book Name CDATA #REQUIRED>

After the keyword ELEMENT and the name Book there is a list in parentheses. This is a comma separated list of names of elements which can occur (in the given order) in the content of a Book element. Each name in such a list can be followed by one of the characters "?", "*" or "+", meaning that the corresponding element can occur zero or one time, an arbitrary number of times, or at least once, respectively. Without such an extra character the corresponding element must occur exactly once. Instead of one name in this list there can also be a list of elements names separated by "|" characters, this denotes any element with one of the names (i.e., "|" means "or").

So, the Book element must contain first a TitlePage element, then an optional TableOfContents element, then a Body element, then zero or more elements of type Appendix, then an optional Bibliography element, and finally an optional element of type TheIndex.

Note that only these elements are allowed in the content of the Book element. No other elements or text is allowed in between. An exception of this is that there may be whitespace between the end tag of one and the start tag of the next element - this should be ignored when the document is processed to some output format. An element like this is called an element with "element content".

The second declaration starts with the keyword ATTLIST and the element name Book. After that there is a triple of whitespace separated parameters (in general an arbitrary number of such triples, one for each allowed attribute name). The first (Name) is the name of an attribute for a Book element. The second (CDATA) is always the same for all of our declarations, it means that the value of the attribute consists of "character data". The third parameter #REQUIRED means that this attribute must be specified with any Book element. Later we will also see optional attributes which are declared as #IMPLIED.

3.2-2 <TitlePage>
<!ELEMENT TitlePage (Title, Subtitle?, Version?, TitleComment?, 
                     Author+, Date?, Address?, Abstract?, Copyright?, 
                     Acknowledgements? , Colophon? )>

Within this element information for the title page is collected. Note that more than one author can be specified. The elements must appear in this order because there is no sensible way to specify in a DTD something like "the following elements may occur in any order but each exactly once".

Before going on with the other elements inside the Book element we explain the elements for the title page.

3.2-3 <Title>
<!ELEMENT Title (%Text;)*>

Here is the last construct you need to understand for reading gapdoc.dtd. The expression "%Text;" is a so-called "parameter entity". It is something like a macro within the DTD. It is defined as follows:

<!ENTITY % Text "%InnerText; | List | Enum | Table">

This means, that every occurrence of "%Text;" in the DTD is replaced by the expression

%InnerText; | List | Enum | Table

which is then expanded further because of the following definition:

<!ENTITY % InnerText "#PCDATA |
                      Alt |
                      Emph | E |
                      Par | P | Br |
                      Keyword | K | Arg | A | Quoted | Q | Code | C | 
                      File | F | Button | B | Package |
                      M | Math | Display | 
                      Example | Listing | Log | Verb |
                      URL | Email | Homepage | Address | Cite | Label | 
                      Ref | Index" > 

These are the only two parameter entities we are using. They expand to lists of element names which are explained in the sequel and the keyword #PCDATA (concatenated with the "or" character "|").

So, the element (Title) is of so-called "mixed content": It can contain parsed character data which does not contain further markup (#PCDATA) or any of the other above mentioned elements. Mixed content must always have the asterisk qualifier (like in Title) such that any sequence of elements (of the above list) and character data can be contained in a Title element.

The %Text; parameter entity is used in all places in the DTD, where "normal text" should be allowed, including lists, enumerations, and tables, but no sectioning elements.

The %InnerText; parameter entity is used in all places in the DTD, where "inner text" should be allowed. This means, that no structures like lists, enumerations, and tables are allowed. This is used for example in headings.

3.2-4 <Subtitle>
<!ELEMENT Subtitle (%Text;)*>

Contains the subtitle of the document.

3.2-5 <Version>
<!ELEMENT Version (#PCDATA|Alt)*>

Note that the version can only contain character data and no further markup elements (except for Alt, which is necessary to resolve the entities described in 2.2-3). The converters will not put the word "Version" in front of the text in this element.

3.2-6 <TitleComment>
<!ELEMENT TitleComment (%Text;)*>

Sometimes a title and subtitle are not sufficient to give a rough idea about the content of a package. In this case use this optional element to specify an additional text for the front page of the book. This text should be short, use the Abstract element (see 3.2-10) for longer explanations.

3.2-7 <Author>
<!ELEMENT Author (%Text;)*>    <!-- There may be more than one Author! -->

As noted in the comment there may be more than one element of this type. This element should contain the name of an author and probably an Email-address and/or WWW-Homepage element for this author, see 3.5-6 and 3.5-7. You can also specify an individual postal address here, instead of using the Address element described below, see 3.2-9.

3.2-8 <Date>
<!ELEMENT Date (#PCDATA)>

Only character data is allowed in this element which gives a date for the document. No automatic formatting is done.

3.2-9 <Address>
<!ELEMENT Address (#PCDATA|Alt|Br)*>

This optional element can be used to specify a postal address of the author or the authors. If there are several authors with different addresses then put the Address elements inside the Author elements.

Use the Br element (see 3.9-3) to mark the line breaks in the usual formatting of the address on a letter.

Note that often it is not necessary to use this element because a postal address is easy to find via a link to a personal web page.

3.2-10 <Abstract>
<!ELEMENT Abstract (%Text;)*>

This element contains an abstract of the whole book.

3.2-11 <Copyright>
<!ELEMENT Copyright (%Text;)*>

This element is used for the copyright notice. Note the &copyright; entity as described in section 2.2-3.

3.2-12 <Acknowledgements>
<!ELEMENT Acknowledgements (%Text;)*>

This element contains the acknowledgements.

3.2-13 <Colophon>
<!ELEMENT Colophon (%Text;)*>

The "colophon" page is used to say something about the history of a document.

3.2-14 <TableOfContents>
<!ELEMENT TableOfContents EMPTY>

This element may occur in the Book element after the TitlePage element. If it is present, a table of contents is generated and inserted into the document. Note that because this element is declared to be EMPTY one can use the abbreviation

<TableOfContents/>

to denote this empty element.

3.2-15 <Bibliography>
<!ELEMENT Bibliography EMPTY>
<!ATTLIST Bibliography Databases CDATA #REQUIRED
                       Style CDATA #IMPLIED>

This element may occur in the Book element after the last Appendix element. If it is present, a bibliography section is generated and inserted into the document. The attribute Databases must be specified, the names of several data files can be specified, separated by commas.

Two kinds of files can be specified in Databases: The first are BibTeX files as defined in [Lam85, Appendix B]. Such files must have a name with extension .bib, and in Databases the name must be given without this extension. The second are files in BibXMLext format as defined in Section 7.2. These files must have an extension .xml and in Databases the full name must be specified.

We suggest to use the BibXMLext format because it allows to produce potentially nicer bibliography entries in text and HTML documents.

A bibliography style may be specified with the Style attribute. The optional Style attribute (for LaTeX output of the document) must also be specified without the .bst extension (the default is alpha). See also section 3.5-3 for a description of the Cite element which is used to include bibliography references into the text.

3.2-16 <TheIndex>
<!ELEMENT TheIndex EMPTY>

This element may occur in the Book element after the Bibliography element. If it is present, an index is generated and inserted into the document. There are elements in GAPDoc which implicitly generate index entries (e.g., Func (3.4-2)) and there is an element Index (3.5-4) for explicitly adding index entries.

3.3 Sectioning Elements

A GAPDoc book is divided into chapters, sections, and subsections. The idea is of course, that a chapter consists of sections, which in turn consist of subsections. However for the sake of flexibility, the rules are not too restrictive. Firstly, text is allowed everywhere in the body of the document (and not only within sections). Secondly, the chapter level may be omitted. The exact rules are described below.

Appendices are a flavor of chapters, occurring after all regular chapters. There is a special type of subsection called "ManSection". This is a subsection devoted to the description of a function, operation or variable. It is analogous to a manpage in the UNIX environment. Usually each function, operation, method, and so on should have its own ManSection.

Cross referencing is done on the level of Subsections, respectively ManSections. The topics in GAP's online help are also pointing to subsections. So, they should not be too long.

We start our description of the sectioning elements "top-down":

3.3-1 <Body>

The Body element marks the main part of the document. It must occur after the TableOfContents element. There is a big difference between inside and outside of this element: Whereas regular text is allowed nearly everywhere in the Body element and its subelements, this is not true for the outside. This has also implications on the handling of whitespace. Outside superfluous whitespace is usually ignored when it occurs between elements. Inside of the Body element whitespace matters because character data is allowed nearly everywhere. Here is the definition in the DTD:

<!ELEMENT Body  ( %Text;| Chapter | Section )*>

The fact that Chapter and Section elements are allowed here leads to the possibility to omit the chapter level entirely in the document. For a description of %Text; see here.

(Remark: The purpose of this element is to make sure that a valid GAPDoc document has a correct overall structure, which is only possible when the top element Book has element content.)

3.3-2 <Chapter>
<!ELEMENT Chapter (%Text;| Heading | Section)*>
<!ATTLIST Chapter Label CDATA #IMPLIED>    <!-- For reference purposes -->

A Chapter element can have a Label attribute, such that this chapter can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the chapter as there is no automatic labelling!

Chapter elements can contain text (for a description of %Text; see here), Section elements, and Heading elements.

The following additional rule cannot be stated in the DTD because we want a Chapter element to have mixed content. There must be exactly one Heading element in the Chapter element, containing the heading of the chapter. Here is its definition:

3.3-3 <Heading>
<!ELEMENT Heading (%InnerText;)*>

This element is used for headings in Chapter, Section, Subsection, and Appendix elements. It may only contain %InnerText; (for a description see here).

Each of the mentioned sectioning elements must contain exactly one direct Heading element (i.e., one which is not contained in another sectioning element).

3.3-4 <Appendix>
<!ELEMENT Appendix (%Text;| Heading | Section)*>
<!ATTLIST Appendix Label CDATA #IMPLIED>   <!-- For reference purposes -->

The Appendix element behaves exactly like a Chapter element (see 3.3-2) except for the position within the document and the numbering. While chapters are counted with numbers (1., 2., 3., ...) the appendices are counted with capital letters (A., B., ...).

Again there is an optional Label attribute used for references.

3.3-5 <Section>
<!ELEMENT Section (%Text;| Heading | Subsection | ManSection)*>
<!ATTLIST Section Label CDATA #IMPLIED>    <!-- For reference purposes -->

A Section element can have a Label attribute, such that this section can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the section as there is no automatic labelling!

Section elements can contain text (for a description of %Text; see here), Heading elements, and subsections.

There must be exactly one direct Heading element in a Section element, containing the heading of the section.

Note that a subsection is either a Subsection element or a ManSection element.

3.3-6 <Subsection>
<!ELEMENT Subsection (%Text;| Heading)*>
<!ATTLIST Subsection Label CDATA #IMPLIED> <!-- For reference purposes -->

The Subsection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the subsection as there is no automatic labelling!

Subsection elements can contain text (for a description of %Text; see here), and Heading elements.

There must be exactly one Heading element in a Subsection element, containing the heading of the subsection.

Another type of subsection is a ManSection, explained now:

3.4 ManSection–a special kind of subsection

ManSections are intended to describe a function, operation, method, variable, or some other technical instance. It is analogous to a manpage in the UNIX environment.

3.4-1 <ManSection>
<!ELEMENT ManSection ( Heading?, 
                      ((Func, Returns?) | (Oper, Returns?) | 
                       (Meth, Returns?) | (Filt, Returns?) | 
                       (Prop, Returns?) | (Attr, Returns?) |
                       Var | Fam | InfoClass)+, Description )>
<!ATTLIST ManSection Label CDATA #IMPLIED> <!-- For reference purposes -->

<!ELEMENT Returns (%Text;)*>
<!ELEMENT Description (%Text;)*>

The ManSection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). But this is probably rarely necessary because the elements Func and so on (explained below) generate automatically labels for cross referencing.

The content of a ManSection element is one or more elements describing certain items in GAP, each of them optionally followed by a Returns element, followed by a Description element, which contains %Text; (see here) describing it. (Remember to include examples in the description as often as possible, see 3.7-10). The classes of items GAPDoc knows of are: functions (Func), operations (Oper), methods (Meth), filters (Filt), properties (Prop), attributes (Attr), variables (Var), families (Fam), and info classes (InfoClass). One ManSection should only describe several of such items when these are very closely related.

Each element for an item corresponding to a GAP function can be followed by a Returns element. In output versions of the document the string "Returns: " will be put in front of the content text. The text in the Returns element should usually be a short hint about the type of object returned by the function. This is intended to give a good mnemonic for the use of a function (together with a good choice of names for the formal arguments).

ManSections are also sectioning elements which count as subsections. Usually there should be no Heading-element in a ManSection, in that case a heading is generated automatically from the first Func-like element. Sometimes this default behaviour does not look appropriate, for example when there are several Func-like elements. For such cases an optional Heading is allowed.

3.4-2 <Func>
<!ELEMENT Func EMPTY>
<!ATTLIST Func Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a function. The Name attribute is required and its value is the name of the function. The value of the Arg attribute (also required) contains the full list of arguments including optional parts, which are denoted by square brackets. The argument names can be separated by whitespace, commas or the square brackets for the optional arguments, like "grp[, elm]" or "xx[y[z] ]". If GAP options are used, this can be followed by a colon : and one or more assignments, like "n[, r]: tries := 100".

The name of the function is also used as label for cross referencing. When the name of the function appears in the text of the document it should always be written with the Ref element, see 3.5-1. This allows to use a unique typesetting style for function names and automatic cross referencing.

If the optional Label attribute is given, it is appended (with a colon : in between) to the name of the function for cross referencing purposes. The text of the label can also appear in the document text. So, it should be a kind of short explanation.

<Func Arg="x[, y]" Name="LibFunc" Label="for my objects"/>

The optional Comm attribute should be a short description of the function, usually at most one line long (this is currently nowhere used).

This element automatically produces an index entry with the name of the function and, if present, the text of the Label attribute as subentry (see also 3.2-16 and 3.5-4).

3.4-3 <Oper>
<!ELEMENT Oper EMPTY>
<!ATTLIST Oper Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of an operation. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

Note that multiple descriptions of the same operation may occur in a document because there may be several declarations in GAP. Furthermore there may be several ManSections for methods of this operation (see 3.4-4) which also use the same name. For reference purposes these must be distinguished by different Label attributes.

3.4-4 <Meth>
<!ELEMENT Meth EMPTY>
<!ATTLIST Meth Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a method. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

Frequently, an operation is implemented by several different methods. Therefore it seems to be interesting to document them independently. This is possible by using the same method name in different ManSections. It is however required that these subsections and those describing the corresponding operation are distinguished by different Label attributes.

3.4-5 <Filt>
<!ELEMENT Filt EMPTY>
<!ATTLIST Filt Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #IMPLIED
               Comm  CDATA #IMPLIED
               Type  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a filter. The first four attributes are used in the same way as in the Func element (see 3.4-2), except that the Arg attribute is optional.

The Type attribute can be any string, but it is thought to be something like "Category" or "Representation".

3.4-6 <Prop>
<!ELEMENT Prop EMPTY>
<!ATTLIST Prop Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of a property. The attributes are used exactly in the same way as in the Func element (see 3.4-2).

3.4-7 <Attr>
<!ELEMENT Attr EMPTY>
<!ATTLIST Attr Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Arg   CDATA #REQUIRED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to specify the usage of an attribute (in GAP). The attributes are used exactly in the same way as in the Func element (see 3.4-2).

3.4-8 <Var>
<!ELEMENT Var  EMPTY>
<!ATTLIST Var  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document a global variable. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.4-9 <Fam>
<!ELEMENT Fam  EMPTY>
<!ATTLIST Fam  Name  CDATA #REQUIRED
               Label CDATA #IMPLIED
               Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document a family. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.4-10 <InfoClass>
<!ELEMENT InfoClass EMPTY>
<!ATTLIST InfoClass Name  CDATA #REQUIRED
                    Label CDATA #IMPLIED
                    Comm  CDATA #IMPLIED>

This element is used within a ManSection element to document an info class. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute.

3.5 Cross Referencing and Citations

Cross referencing in the GAPDoc system is somewhat different to the usual LaTeX cross referencing in so far, that a reference knows "which type of object" it is referencing. For example a "reference to a function" is distinguished from a "reference to a chapter". The idea of this is, that the markup must contain this information such that the converters can produce better output. The HTML converter can for example typeset a function reference just as the name of the function with a link to the description of the function, or a chapter reference as a number with a link in the other case.

Referencing is done with the Ref element:

3.5-1 <Ref>
<!ELEMENT Ref EMPTY>
<!ATTLIST Ref Func      CDATA #IMPLIED
              Oper      CDATA #IMPLIED
              Meth      CDATA #IMPLIED
              Filt      CDATA #IMPLIED
              Prop      CDATA #IMPLIED
              Attr      CDATA #IMPLIED
              Var       CDATA #IMPLIED
              Fam       CDATA #IMPLIED
              InfoClass CDATA #IMPLIED
              Chap      CDATA #IMPLIED
              Sect      CDATA #IMPLIED
              Subsect   CDATA #IMPLIED
              Appendix  CDATA #IMPLIED
              Text      CDATA #IMPLIED

              Label     CDATA #IMPLIED
              BookName  CDATA #IMPLIED
              Style (Text | Number) #IMPLIED>  <!-- normally automatic -->

The Ref element is defined to be EMPTY. If one of the attributes Func, Oper, Meth, Prop, Attr, Var, Fam, InfoClass, Chap, Sect, Subsect, Appendix is given then there must be exactly one of these, making the reference one to the corresponding object. The Label attribute can be specified in addition to make the reference unique, for example if more than one method with a given name is present. (Note that there is no way to specify in the DTD that exactly one of the first listed attributes must be given, this is an additional rule.)

A reference to a Label element defined below (see 3.5-2) is done by giving the Label attribute and optionally the Text attribute. If the Text attribute is present its value is typeset in place of the Ref element, if linking is possible (for example in HTML). If this is not possible, the section number is typeset. This type of reference is also used for references to tables (see 3.6-5).

An external reference into another book can be specified by using the BookName attribute. In this case the Label attribute or, if this is not given, the function or section like attribute, is used to resolve the reference. The generated reference points to the first hit when asking "?book name: label" inside GAP.

The optional attribute Style can take only the values Text and Number. It can be used with references to sectioning units and it gives a hint to the converter programs, whether an explicit section number is generated or text. Normally all references to sections generate numbers and references to a GAP object generate the name of the corresponding object with some additional link or sectioning information, which is the behavior of Style="Text". In case Style="Number" in all cases an explicit section number is generated. So

<Ref Subsect="Func" Style="Text"/> described in section 
<Ref Subsect="Func" Style="Number"/>

produces: <Func> described in section 3.4-2.

3.5-2 <Label>
<!ELEMENT Label EMPTY>
<!ATTLIST Label Name CDATA #REQUIRED>

This element is used to define a label for referencing a certain position in the document, if this is possible. If an exact reference is not possible (like in a printed version of the document) a reference to the corresponding subsection is generated. The value of the Name attribute must be unique under all Label elements.

3.5-3 <Cite>
<!ELEMENT Cite EMPTY>
<!ATTLIST Cite Key CDATA #REQUIRED
               Where CDATA #IMPLIED>

This element is for bibliography citations. It is EMPTY by definition. The attribute Key is the key for a lookup in a BibTeX database that has to be specified in the Bibliography element (see 3.2-15). The value of the Where attribute specifies the position in the document as in the corresponding LaTeX syntax \cite[Where value]{Key value}.

3.5-4 <Index>
<!ELEMENT Index (%InnerText;|Subkey)*>
<!ATTLIST Index Key    CDATA #IMPLIED
                Subkey CDATA #IMPLIED>
<!ELEMENT Subkey (%InnerText;)*>

This element generates an index entry. The text within the element is typeset in the index entry, which is sorted under the value, that is specified in the Key and Subkey attributes. If they are not specified, the typeset text itself is used as the key.

A subkey can be specified in the simpler version as an attribute, but then no further markup can be used for the subkey. Optionally, the subkey text can be given in a Subkey element, in this case the attribute value is used for sorting but the typeset text is taken from the content of Subkey.

Note that all Func and similar elements automatically generate index entries. If the TheIndex element (3.2-16) is not present in the document all Index elements are ignored.

3.5-5 <URL>
<!ELEMENT URL (#PCDATA|Alt|Link|LinkText)*>  <!-- Link, LinkText
     variant for case where text needs further markup -->
<!ATTLIST URL Text CDATA #IMPLIED>   <!-- This is for output formats
                                          that have links like HTML -->
<!ELEMENT Link     (%InnerText;)*> <!-- the URL -->
<!ELEMENT LinkText (%InnerText;)*> <!-- text for links, can contain markup -->

This element is for references into the internet. It specifies an URL and optionally a text which can be used for a link (like in HTML or PDF versions of the document). This can be specified in two ways: Either the URL is given as element content and the text is given in the optional Text attribute (in this case the text cannot contain further markup), or the element contains the two elements Link and LinkText which in turn contain the URL and the text, respectively. The default value for the text is the URL itself.

3.5-6 <Email>
<!ELEMENT Email (#PCDATA|Alt|Link|LinkText)*>

This element type is the special case of an URL specifying an email address. The content of the element should be the email address without any prefix like "mailto:". This address is typeset by all converters, also without any prefix. In the case of an output document format like HTML the converter can produce a link with a "mailto:" prefix.

3.5-7 <Homepage>
<!ELEMENT Homepage (#PCDATA|Alt|Link|LinkText)*>

This element type is the special case of an URL specifying a WWW-homepage.

3.6 Structural Elements like Lists

The GAPDoc system offers some limited access to structural elements like lists, enumerations, and tables. Although it is possible to use all LaTeX constructs one always has to think about other output formats. The elements in this section are guaranteed to produce something reasonable in all output formats.

3.6-1 <List>
<!ELEMENT List ( ((Mark,Item)|(BigMark,Item)|Item)+ )>
<!ATTLIST List Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

This element produces a list. Each item in the list corresponds to an Item element. Every Item element is optionally preceded by a Mark element. The content of this is used as a marker for the item. Note that this marker can be a whole word or even a sentence. It will be typeset in some emphasized fashion and most converters will provide some indentation for the rest of the item.

The Only and Not attributes can be used to specify, that the list is included into the output by only one type of converter (Only) or all but one type of converter (Not). Of course at most one of the two attributes may occur in one element. The following values are allowed as of now: "LaTeX", "HTML", and "Text". See also the Alt element in 3.9-1 for more about text alternatives for certain converters.

3.6-2 <Mark>
<!ELEMENT Mark ( %InnerText;)*>

This element is used in the List element to mark items. See 3.6-1 for an explanation.

3.6-3 <Item>
<!ELEMENT Item ( %Text;)*>

This element is used in the List, Enum, and Table elements to specify the items. See sections 3.6-1, 3.6-4, and 3.6-5 for further information.

3.6-4 <Enum>
<!ELEMENT Enum ( Item+ )>
<!ATTLIST Enum Only CDATA #IMPLIED
               Not  CDATA #IMPLIED>

This element is used like the List element (see 3.6-1) except that the items must not have marks attached to them. Instead, the items are numbered automatically. The same comments about the Only and Not attributes as above apply.

3.6-5 <Table>
<!ELEMENT Table ( Caption?, (Row | HorLine)+ )>
<!ATTLIST Table Label   CDATA #IMPLIED
                Only    CDATA #IMPLIED
                Not     CDATA #IMPLIED
                Align   CDATA #REQUIRED>
                <!-- We allow | and l,c,r, nothing else -->
<!ELEMENT Row   ( Item+ )>
<!ELEMENT HorLine EMPTY>
<!ELEMENT Caption ( %InnerText;)*>

A table in GAPDoc consists of an optional Caption element followed by a sequence of Row and HorLine elements. A HorLine element produces a horizontal line in the table. A Row element consists of a sequence of Item elements as they also occur in List and Enum elements. The Only and Not attributes have the same functionality as described in the List element in 3.6-1.

The Align attribute is written like a LaTeX tabular alignment specifier but only the letters "l", "r", "c", and "|" are allowed meaning left alignment, right alignment, centered alignment, and a vertical line as delimiter between columns respectively.

If the Label attribute is there, one can reference the table with the Ref element (see 3.5-1) using its Label attribute.

Usually only simple tables should be used. If you want a complicated table in the LaTeX output you should provide alternatives for text and HTML output. Note that in HTML-4.0 there is no possibility to interpret the "|" column separators and HorLine elements as intended. There are lines between all columns and rows or no lines at all.

3.7 Types of Text

This section covers the markup of text. Various types of "text" exist. The following elements are used in the GAPDoc system to mark them. They mostly come in pairs, one long name which is easier to remember and a shortcut to make the markup "lighter".

Most of the following elements are thought to contain only character data and no further markup elements. It is however necessary to allow Alt elements to resolve the entities described in section 2.2-3.

3.7-1 <Emph> and <E>
<!ELEMENT Emph (%InnerText;)*>    <!-- Emphasize something -->
<!ELEMENT E    (%InnerText;)*>    <!-- the same as shortcut -->

This element is used to emphasize some piece of text. It may contain %InnerText; (see here).

3.7-2 <Quoted> and <Q>
<!ELEMENT Quoted (%InnerText;)*>   <!-- Quoted (in quotes) text -->
<!ELEMENT Q (%InnerText;)*>        <!-- Quoted text (shortcut) -->

This element is used to put some piece of text into " "-quotes. It may contain %InnerText; (see here).

3.7-3 <Keyword> and <K>
<!ELEMENT Keyword (#PCDATA|Alt)*>  <!-- Keyword -->
<!ELEMENT K (#PCDATA|Alt)*>        <!-- Keyword (shortcut) -->

This element is used to mark something as a keyword. Usually this will be a GAP keyword such as "if" or "for". No further markup elements are allowed within this element except for the Alt element, which is necessary.

3.7-4 <Arg> and <A>
<!ELEMENT Arg (#PCDATA|Alt)*>      <!-- Argument -->
<!ELEMENT A (#PCDATA|Alt)*>        <!-- Argument (shortcut) -->

This element is used inside Descriptions in ManSections to mark something as an argument (of a function, operation, or such). It is guaranteed that the converters typeset those exactly as in the definition of functions. No further markup elements are allowed within this element.

3.7-5 <Code> and <C>
<!ELEMENT Code (#PCDATA|Arg|Alt)*>     <!-- GAP code -->
<!ELEMENT C (#PCDATA|Arg|Alt)*>        <!-- GAP code (shortcut) -->

This element is used to mark something as a piece of code like for example a GAP expression. It is guaranteed that the converters typeset this exactly as in the Listing element (compare section 3.7-9). The only further markup elements allowed within this element are <Arg> elements (see 3.7-4).

3.7-6 <File> and <F>
<!ELEMENT File (#PCDATA|Alt)*>     <!-- Filename -->
<!ELEMENT F (#PCDATA|Alt)*>        <!-- Filename (shortcut) -->

This element is used to mark something as a filename or a pathname in the file system. No further markup elements are allowed within this element.

3.7-7 <Button> and <B>
<!ELEMENT Button (#PCDATA|Alt)*>   <!-- "Button" (also Menu, Key, ...) -->
<!ELEMENT B (#PCDATA|Alt)*>        <!-- "Button" (shortcut) -->

This element is used to mark something as a button. It can also be used for other items in a graphical user interface like menus, menu entries, or keys. No further markup elements are allowed within this element.

3.7-8 <Package>
<!ELEMENT Package (#PCDATA|Alt)*>   <!-- A package name -->

This element is used to mark something as a name of a package. This is for example used to define the entities GAP, XGAP or GAPDoc (see section 2.2-3). No further markup elements are allowed within this element.

3.7-9 <Listing>
<!ELEMENT Listing (#PCDATA)>  <!-- This is just for GAP code listings -->
<!ATTLIST Listing Type CDATA #IMPLIED> <!-- a comment about the type of
                                            listed code, may appear in
                                            output -->

This element is used to embed listings of programs into the document. Only character data and no other elements are allowed in the content. You should not use the character entities described in section 2.2-3 but instead type the characters directly. Only the general XML rules from section 2.1 apply. Note especially the usage of <![CDATA[ sections described there. It is guaranteed that all converters use a fixed width font for typesetting Listing elements. Compare also the usage of the Code and C elements in 3.7-5.

The Type attribute contains a comment about the type of listed code. It may appear in the output.

3.7-10 <Log> and <Example>
<!ELEMENT Example (#PCDATA)>  <!-- This is subject to the automatic 
                                   example checking mechanism -->
<!ELEMENT Log (#PCDATA)>      <!-- This not -->

These two elements behave exactly like the Listing element (see 3.7-9). They are thought for protocols of GAP sessions. The only difference between the two is that Example sections are intended to be subject to an automatic manual checking mechanism used to ensure the correctness of the GAP manual whereas Log is not touched by this (see section 5.4 for checking tools).

To get a good layout of the examples for display in a standard terminal we suggest to use SizeScreen([72]); (see SizeScreen (Reference: SizeScreen)) in your GAP session before producing the content of Example elements.

3.7-11 <Verb>

There is one further type of verbatim-like element.

<!ELEMENT Verb  (#PCDATA)> 

The content of such an element is guaranteed to be put into an output version exactly as it is using some fixed width font. Before the content a new line is started. If the line after the end of the start tag consists of whitespace only then this part of the content is skipped.

This element is intended to be used together with the Alt element to specify pre-formatted ASCII alternatives for complicated Display formulae or Tables.

3.8 Elements for Mathematical Formulae

3.8-1 <Math> and <Display>
<!-- Normal TeX math mode formula -->
<!ELEMENT Math (#PCDATA|A|Arg|Alt)*>   
<!-- TeX displayed math mode formula -->
<!ELEMENT Display (#PCDATA|A|Arg|Alt)*>
<!-- Mode="M" causes <M>-style formatting -->
<!ATTLIST Display Mode CDATA #IMPLIED>

These elements are used for mathematical formulae. As described in section 2.2-2 they correspond to LaTeX's math and display math mode respectively.

The formulae are typed in as in LaTeX, except that the standard XML entities, see 2.1-9 (in particular the characters < and &), must be escaped - either by using the corresponding entities or by enclosing the formula between "<![CDATA[" and "]]>". (The main reference for LaTeX is [Lam85].)

It is also possible to use some unicode characters for mathematical symbols directly, provided that it can be translated by Encode (6.2-2) into "LaTeX" encoding and that SimplifiedUnicodeString (6.2-2) with arguments "latin1" and "single" returns something sensible. Currently, we support entities &CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR; for the corresponding black board bold letters ℂ, ℤ, ℕ,ℙ, ℚ, ℍ and ℝ, respectively.

The only element type that is allowed within the formula elements is the Arg or A element (see 3.7-4), which is used to typeset identifiers that are arguments to GAP functions or operations.

If a Display element has an attribute Mode with value "M", then the formula is formatted as in M elements (see 3.8-2). Otherwise in text and HTML output the formula is shown as LaTeX source code.

For simple formulae (and you should try to make all your formulae simple!) attempt to use the M element or the Mode="M" attribute in Display for which there is a well defined translation into text, which can be used for text and HTML output versions of the document. So, if possible try to avoid the Math elements and Display elements without attribute or provide useful text substitutes for complicated formulae via Alt elements (see 3.9-1 and 3.7-11).

3.8-2 <M>
<!-- Math with well defined translation to text output -->
<!ELEMENT M (#PCDATA|A|Arg|Alt)*>

The "M" element type is intended for formulae in the running text for which there is a sensible text version. For the LaTeX version of a GAPDoc document the M and Math elements are equivalent. The remarks in 3.8-1 about special characters and the Arg element apply here as well. A document which has all formulae enclosed in M elements can be well readable in text terminal output and printed output versions.

Compared to former versions of GAPDoc many more formulae can be put into M elements. Most modern terminal emulations support unicode characters and many mathematical symbols can now be represented by such characters. But even if a terminal can only display ASCII characters, the user will see some not too bad representation of a formula.

As examples, here are some LaTeX macros which have a sensible ASCII translation and are guaranteed to be translated accordingly by text (and HTML) converters (for a full list of handled Macros see RecFields(TEXTMTRANSLATIONS)):

Table: LaTeX macros with special text translation
\ast *
\bf
\bmod mod
\cdot *
\colon :
\equiv =
\geq >=
\germ
\hookrightarrow ->
\iff <=>
\langle <
\ldots ...
\left  
\leq <=
\leftarrow <-
\Leftarrow <=
\limits  
\longrightarrow -->
\Longrightarrow ==>
\mapsto ->
\mathbb  
\mathop  
\mid |
\pmod mod
\prime '
\rangle >
\right  
\rightarrow ->
\Rightarrow =>
\rm, \sf, \textrm, \text
\setminus \
\thinspace
\times x
\to ->
\vert |
\!
\,
\;  
\{ {
\} }

 


In all other macros only the backslash is removed (except for some macros describing more exotic symbols). Whitespace is normalized (to one blank) but not removed. Note that whitespace is not added, so you may want to add a few more spaces than you usually do in your LaTeX documents.

Braces {} are removed in general, however pairs of double braces are converted to one pair of braces. This can be used to write <M>x^{12}</M> for x^12 and <M>x_{{i+1}}</M> for x_{i+1}.

3.9 Everything else

3.9-1 <Alt>

This element is used to specify alternatives for different output formats within normal text. See also sections 3.6-1, 3.6-4, and 3.6-5 for alternatives in lists and tables.

<!ELEMENT Alt (%InnerText;)*>  <!-- This is only to allow "Only" and
                                    "Not" attributes for normal text -->
<!ATTLIST Alt Only CDATA #IMPLIED
              Not  CDATA #IMPLIED>

Of course exactly one of the two attributes must occur in one element. The attribute values must be one word or a list of words, separated by spaces or commas. The words which are currently recognized by the converter programs contained in GAPDoc are: "LaTeX", "HTML", and "Text". If the Only attribute is specified then only the corresponding converter will include the content of the element into the output document. If the Not attribute is specified the corresponding converter will ignore the content of the element. You can use other words to specify special alternatives for other converters of GAPDoc documents.

We fix a rule for handling the content of an Alt element with Only attribute. In their content code for the corresponding output format is included directly. So, in case of HTML the content is HTML code, in case of LaTeX the content is LaTeX code. The converters don't apply any handling of special characters to this content.

Within the element only %InnerText; (see here) is allowed. This is to ensure that the same set of chapters, sections, and subsections show up in all output formats.

3.9-2 <Par> and <P>
<!ELEMENT Par EMPTY>    <!-- this is intentionally empty! -->
<!ELEMENT P EMPTY>      <!-- the same as shortcut  -->

This EMPTY element marks the boundary of paragraphs. Note that an empty line in the input does not mark a new paragraph as opposed to the LaTeX convention.

(Remark: it would be much easier to parse a document and to understand its sectioning and paragraph structure when there was an element whose content is the text of a paragraph. But in practice many paragraph boundaries are implicitly clear which would make it somewhat painful to enclose each paragraph in extra tags. The introduction of the P or Par elements as above delegates this pain to the writer of a conversion program for GAPDoc documents.)

3.9-3 <Br>
 
<!ELEMENT Br EMPTY>     <!-- a forced line break  -->

This element can be used to force a line break in the output versions of a GAPDoc element, it does not start a new paragraph. Please, do not use this instead of a Par element, this would often lead to ugly output versions of your document.

3.9-4 <Ignore>
 
<!ELEMENT Ignore (%Text;| Chapter | Section | Subsection | ManSection |
                  Heading)*>
<!ATTLIST Ignore Remark CDATA #IMPLIED>

This element can appear anywhere. Its content is ignored by the standard converters. It can be used, for example, to include data which are not part of the actual GAPDoc document, like source code, or to make not finished parts of the document invisible.

Of course, one can use special converter programs which extract the contents of Ignore elements. Information on the type of the content can be stored in the optional attribute Remark.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap2_mj.html0000644000175000017500000006346112026346063014333 0ustar billbill GAP (GAPDoc) - Chapter 2: How To Type a GAPDoc Document
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

2 How To Type a GAPDoc Document

In this chapter we give a more formal description of what you need to start to type documentation in GAPDoc XML format. Many details were already explained by example in Section 1.2 of the introduction.

We do not answer the question "How to write a GAPDoc document?" in this chapter. You can (hopefully) find an answer to this question by studying the example in the introduction, see 1.2, and learning about more details in the reference Chapter 3.

The definite source for all details of the official XML standard with useful annotations is:

http://www.xml.com/axml/axml.html

Although this document must be quite technical, it is surprisingly well readable.

2.1 General XML Syntax

We will now discuss the pieces of text which can occur in a general XML document. We start with those pieces which do not contribute to the actual content of the document.

2.1-1 Head of XML Document

Each XML document should have a head which states that it is an XML document in some encoding and which XML-defined language is used. In case of a GAPDoc document this should always look as in the following example.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Book SYSTEM "gapdoc.dtd">

See 2.1-13 for a remark on the "encoding" statement.

(There may be local entity definitions inside the DOCTYPE statement, see Subsection 2.2-3 below.)

2.1-2 Comments

A "comment" in XML starts with the character sequence "<!--" and ends with the sequence "-->". Between these sequences there must not be two adjacent dashes "--".

2.1-3 Processing Instructions

A "processing instruction" in XML starts with the character sequence "<?" followed by a name ("xml" is only allowed at the very beginning of the document to declare it being an XML document, see 2.1-1). After that any characters may follow, except that the ending sequence "?>" must not occur within the processing instruction.

 

And now we turn to those parts of the document which contribute to its actual content.

2.1-4 Names in XML and Whitespace

A "name" in XML (used for element and attribute identifiers, see below) must start with a letter (in the encoding of the document) or with a colon ":" or underscore "_" character. The following characters may also be digits, dots "." or dashes "-".

This is a simplified description of the rules in the standard, which are concerned with lots of unicode ranges to specify what a "letter" is.

Sequences only consisting of the following characters are considered as whitespace: blanks, tabs, carriage return characters and new line characters.

2.1-5 Elements

The actual content of an XML document consists of "elements". An element has some "content" with a leading "start tag" (2.1-6) and a trailing "end tag" (2.1-7). The content can contain further elements but they must be properly nested. One can define elements whose content is always empty, those elements can also be entered with a single combined tag (2.1-8).

2.1-6 Start Tags

A "start-tag" consists of a less-than-character "<" directly followed (without whitespace) by an element name (see 2.1-4), optional attributes, optional whitespace, and a greater-than-character ">".

An "attribute" consists of some whitespace and then its name followed by an equal sign "=" which is optionally enclosed by whitespace, and the attribute value, which is enclosed either in single or double quotes. The attribute value may not contain the type of quote used as a delimiter or the character "<", the character "&" may only appear to start an entity, see 2.1-9. We describe in 2.1-11 how to enter special characters in attribute values.

Note especially that no whitespace is allowed between the starting "<" character and the element name. The quotes around an attribute value cannot be omitted. The names of elements and attributes are case sensitive.

2.1-7 End Tags

An "end tag" consists of the two characters "</" directly followed by the element name, optional whitespace and a greater-than-character ">".

2.1-8 Combined Tags for Empty Elements

Elements which always have empty content can be written with a single tag. This looks like a start tag (see 2.1-6) except that the trailing greater-than-character ">" is substituted by the two character sequence "/>".

2.1-9 Entities

An "entity" in XML is a macro for some substitution text. There are two types of entities.

A "character entity" can be used to specify characters in the encoding of the document (can be useful for entering non-ASCII characters which you cannot manage to type in directly). They are entered with a sequence "&#", directly followed by either some decimal digits or an "x" and some hexadecimal digits, directly followed by a semicolon ";". Using such a character entity is just equivalent to typing the corresponding character directly.

Then there are references to "named entities". They are entered with an ampersand character "&" directly followed by a name which is directly followed by a semicolon ";". Such entities must be declared somewhere by giving a substitution text. This text is included in the document and the document is parsed again afterwards. The exact rules are a bit subtle but you probably want to use this only in simple cases. Predefined entities for GAPDoc are described in 2.1-10 and 2.2-3.

2.1-10 Special Characters in XML

We have seen that the less-than-character "<" and the ampersand character "&" start a tag or entity reference in XML. To get these characters into the document text one has to use entity references, namely "&lt;" to get "<" and "&amp;" to get "&". Furthermore "&gt;" must be used to get ">" when the string "]]>" appears in element content (and not as delimiter of a CDATA section explained below).

Another possibility is to use a CDATA statement explained in 2.1-12.

2.1-11 Rules for Attribute Values

Attribute values can contain entities which are substituted recursively. But except for the entities &lt; or a character entity it is not allowed that a < character is introduced by the substitution (there is no XML parsing for evaluating the attribute value, just entity substitutions).

2.1-12 CDATA

Pieces of text which contain many characters which can be misinterpreted as markup can be enclosed by the character sequences "<![CDATA[" and "]]>". Everything between these sequences is considered as content of the document and is not further interpreted as XML text. All the rules explained so far in this section do not apply to such a part of the document. The only document content which cannot be entered directly inside a CDATA statement is the sequence "]]>". This can be entered as "]]&gt;" outside the CDATA statement.

A nesting of tags like <a> <b> </a> </b> is not allowed.

2.1-13 Encoding of an XML Document

We suggest to use the UTF-8 encoding for writing GAPDoc XML documents. But the tools described in Chapter 5 also work with ASCII or the various ISO-8859-X encodings (ISO-8859-1 is also called latin1 and covers most special characters for western European languages).

2.1-14 Well Formed and Valid XML Documents

We want to mention two further important words which are often used in the context of XML documents. A piece of text becomes a "well formed" XML document if all the formal rules described in this section are fulfilled.

But this says nothing about the content of the document. To give this content a meaning one needs a declaration of the element and corresponding attribute names as well as of named entities which are allowed. Furthermore there may be restrictions how such elements can be nested. This definition of an XML based markup language is done in a "document type definition". An XML document which contains only elements and entities declared in such a document type definition and obeys the rules given there is called "valid (with respect to this document type definition)".

The main file of the GAPDoc package is gapdoc.dtd. This contains such a definition of a markup language. We are not going to explain the formal syntax rules for document type definitions in this section. But in Chapter 3 we will explain enough about it to understand the file gapdoc.dtd and so the markup language defined there.

2.2 Entering GAPDoc Documents

Here are some additional rules for writing GAPDoc XML documents.

2.2-1 Other special characters

As GAPDoc documents are used to produce LaTeX and HTML documents, the question arises how to deal with characters with a special meaning for other applications (for example "&", "#", "$", "%", "~", "\", "{", "}", "_", "^", " " (this is a non-breakable space, "~" in LaTeX) have a special meaning for LaTeX and "&", "<", ">" have a special meaning for HTML (and XML). In GAPDoc you can usually just type these characters directly, it is the task of the converter programs which translate to some output format to take care of such special characters. The exceptions to this simple rule are:

  • & and < must be entered as &amp; and &lt; as explained in 2.1-10.

  • The content of the GAPDoc elements <M>, <Math> and <Display> is LaTeX code, see 3.8.

  • The content of an <Alt> element with Only attribute contains code for the specified output type, see 3.9-1.

Remark: In former versions of GAPDoc one had to use particular entities for all the special characters mentioned above (&tamp;, &hash;, &dollar;, &percent;, &tilde;, &bslash;, &obrace;, &cbrace;, &uscore;, &circum;, &tlt;, &tgt;). These are no longer needed, but they are still defined for backwards compatibility with older GAPDoc documents.

2.2-2 Mathematical Formulae

Mathematical formulae in GAPDoc are typed as in LaTeX. They must be the content of one of three types of GAPDoc elements concerned with mathematical formulae: "Math", "Display", and "M" (see Sections 3.8-1 and 3.8-2 for more details). The first two correspond to LaTeX's math mode and display math mode. The last one is a special form of the "Math" element type, that imposes certain restrictions on the content. On the other hand the content of an "M" element is processed in a well defined way for text terminal or HTML output. The "Display" element also has an attribute such that its content is processed as in "M" elements.

Note that the content of these element is LaTeX code, but the special characters "<" and "&" for XML must be entered via the entities described in 2.1-10 or by using a CDATA statement, see 2.1-12.

2.2-3 More Entities

In GAPDoc there are some more predefined entities:

Table: Predefined Entities in the GAPDoc system
&GAP; GAP
&GAPDoc; GAPDoc
&TeX; TeX
&LaTeX; LaTeX
&BibTeX; BibTeX
&MeatAxe; MeatAxe
&XGAP; XGAP
&copyright; ©
&nbsp; " "
&ndash;

 


Here &nbsp; is a non-breakable space character.

Additional entities are defined for some mathematical symbols, see 3.8 for more details.

One can define further local entities right inside the head (see 2.1-1) of a GAPDoc XML document as in the following example.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE Book SYSTEM "gapdoc.dtd"
  [ <!ENTITY MyEntity "some longish <E>text</E> possibly with markup">
  ]>

These additional definitions go into the <!DOCTYPE tag in square brackets. Such new entities are used like this: &MyEntity;

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/toggless.css0000644000175000017500000000167212026346063014317 0ustar billbill/* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } GAPDoc-1.5.1/doc/lefttoc.css0000644000175000017500000000047412026346063014127 0ustar billbill/* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } GAPDoc-1.5.1/doc/chap2.html0000644000175000017500000006270012026346063013640 0ustar billbill GAP (GAPDoc) - Chapter 2: How To Type a GAPDoc Document
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

2 How To Type a GAPDoc Document

In this chapter we give a more formal description of what you need to start to type documentation in GAPDoc XML format. Many details were already explained by example in Section 1.2 of the introduction.

We do not answer the question "How to write a GAPDoc document?" in this chapter. You can (hopefully) find an answer to this question by studying the example in the introduction, see 1.2, and learning about more details in the reference Chapter 3.

The definite source for all details of the official XML standard with useful annotations is:

http://www.xml.com/axml/axml.html

Although this document must be quite technical, it is surprisingly well readable.

2.1 General XML Syntax

We will now discuss the pieces of text which can occur in a general XML document. We start with those pieces which do not contribute to the actual content of the document.

2.1-1 Head of XML Document

Each XML document should have a head which states that it is an XML document in some encoding and which XML-defined language is used. In case of a GAPDoc document this should always look as in the following example.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Book SYSTEM "gapdoc.dtd">

See 2.1-13 for a remark on the "encoding" statement.

(There may be local entity definitions inside the DOCTYPE statement, see Subsection 2.2-3 below.)

2.1-2 Comments

A "comment" in XML starts with the character sequence "<!--" and ends with the sequence "-->". Between these sequences there must not be two adjacent dashes "--".

2.1-3 Processing Instructions

A "processing instruction" in XML starts with the character sequence "<?" followed by a name ("xml" is only allowed at the very beginning of the document to declare it being an XML document, see 2.1-1). After that any characters may follow, except that the ending sequence "?>" must not occur within the processing instruction.

 

And now we turn to those parts of the document which contribute to its actual content.

2.1-4 Names in XML and Whitespace

A "name" in XML (used for element and attribute identifiers, see below) must start with a letter (in the encoding of the document) or with a colon ":" or underscore "_" character. The following characters may also be digits, dots "." or dashes "-".

This is a simplified description of the rules in the standard, which are concerned with lots of unicode ranges to specify what a "letter" is.

Sequences only consisting of the following characters are considered as whitespace: blanks, tabs, carriage return characters and new line characters.

2.1-5 Elements

The actual content of an XML document consists of "elements". An element has some "content" with a leading "start tag" (2.1-6) and a trailing "end tag" (2.1-7). The content can contain further elements but they must be properly nested. One can define elements whose content is always empty, those elements can also be entered with a single combined tag (2.1-8).

2.1-6 Start Tags

A "start-tag" consists of a less-than-character "<" directly followed (without whitespace) by an element name (see 2.1-4), optional attributes, optional whitespace, and a greater-than-character ">".

An "attribute" consists of some whitespace and then its name followed by an equal sign "=" which is optionally enclosed by whitespace, and the attribute value, which is enclosed either in single or double quotes. The attribute value may not contain the type of quote used as a delimiter or the character "<", the character "&" may only appear to start an entity, see 2.1-9. We describe in 2.1-11 how to enter special characters in attribute values.

Note especially that no whitespace is allowed between the starting "<" character and the element name. The quotes around an attribute value cannot be omitted. The names of elements and attributes are case sensitive.

2.1-7 End Tags

An "end tag" consists of the two characters "</" directly followed by the element name, optional whitespace and a greater-than-character ">".

2.1-8 Combined Tags for Empty Elements

Elements which always have empty content can be written with a single tag. This looks like a start tag (see 2.1-6) except that the trailing greater-than-character ">" is substituted by the two character sequence "/>".

2.1-9 Entities

An "entity" in XML is a macro for some substitution text. There are two types of entities.

A "character entity" can be used to specify characters in the encoding of the document (can be useful for entering non-ASCII characters which you cannot manage to type in directly). They are entered with a sequence "&#", directly followed by either some decimal digits or an "x" and some hexadecimal digits, directly followed by a semicolon ";". Using such a character entity is just equivalent to typing the corresponding character directly.

Then there are references to "named entities". They are entered with an ampersand character "&" directly followed by a name which is directly followed by a semicolon ";". Such entities must be declared somewhere by giving a substitution text. This text is included in the document and the document is parsed again afterwards. The exact rules are a bit subtle but you probably want to use this only in simple cases. Predefined entities for GAPDoc are described in 2.1-10 and 2.2-3.

2.1-10 Special Characters in XML

We have seen that the less-than-character "<" and the ampersand character "&" start a tag or entity reference in XML. To get these characters into the document text one has to use entity references, namely "&lt;" to get "<" and "&amp;" to get "&". Furthermore "&gt;" must be used to get ">" when the string "]]>" appears in element content (and not as delimiter of a CDATA section explained below).

Another possibility is to use a CDATA statement explained in 2.1-12.

2.1-11 Rules for Attribute Values

Attribute values can contain entities which are substituted recursively. But except for the entities &lt; or a character entity it is not allowed that a < character is introduced by the substitution (there is no XML parsing for evaluating the attribute value, just entity substitutions).

2.1-12 CDATA

Pieces of text which contain many characters which can be misinterpreted as markup can be enclosed by the character sequences "<![CDATA[" and "]]>". Everything between these sequences is considered as content of the document and is not further interpreted as XML text. All the rules explained so far in this section do not apply to such a part of the document. The only document content which cannot be entered directly inside a CDATA statement is the sequence "]]>". This can be entered as "]]&gt;" outside the CDATA statement.

A nesting of tags like <a> <b> </a> </b> is not allowed.

2.1-13 Encoding of an XML Document

We suggest to use the UTF-8 encoding for writing GAPDoc XML documents. But the tools described in Chapter 5 also work with ASCII or the various ISO-8859-X encodings (ISO-8859-1 is also called latin1 and covers most special characters for western European languages).

2.1-14 Well Formed and Valid XML Documents

We want to mention two further important words which are often used in the context of XML documents. A piece of text becomes a "well formed" XML document if all the formal rules described in this section are fulfilled.

But this says nothing about the content of the document. To give this content a meaning one needs a declaration of the element and corresponding attribute names as well as of named entities which are allowed. Furthermore there may be restrictions how such elements can be nested. This definition of an XML based markup language is done in a "document type definition". An XML document which contains only elements and entities declared in such a document type definition and obeys the rules given there is called "valid (with respect to this document type definition)".

The main file of the GAPDoc package is gapdoc.dtd. This contains such a definition of a markup language. We are not going to explain the formal syntax rules for document type definitions in this section. But in Chapter 3 we will explain enough about it to understand the file gapdoc.dtd and so the markup language defined there.

2.2 Entering GAPDoc Documents

Here are some additional rules for writing GAPDoc XML documents.

2.2-1 Other special characters

As GAPDoc documents are used to produce LaTeX and HTML documents, the question arises how to deal with characters with a special meaning for other applications (for example "&", "#", "$", "%", "~", "\", "{", "}", "_", "^", " " (this is a non-breakable space, "~" in LaTeX) have a special meaning for LaTeX and "&", "<", ">" have a special meaning for HTML (and XML). In GAPDoc you can usually just type these characters directly, it is the task of the converter programs which translate to some output format to take care of such special characters. The exceptions to this simple rule are:

  • & and < must be entered as &amp; and &lt; as explained in 2.1-10.

  • The content of the GAPDoc elements <M>, <Math> and <Display> is LaTeX code, see 3.8.

  • The content of an <Alt> element with Only attribute contains code for the specified output type, see 3.9-1.

Remark: In former versions of GAPDoc one had to use particular entities for all the special characters mentioned above (&tamp;, &hash;, &dollar;, &percent;, &tilde;, &bslash;, &obrace;, &cbrace;, &uscore;, &circum;, &tlt;, &tgt;). These are no longer needed, but they are still defined for backwards compatibility with older GAPDoc documents.

2.2-2 Mathematical Formulae

Mathematical formulae in GAPDoc are typed as in LaTeX. They must be the content of one of three types of GAPDoc elements concerned with mathematical formulae: "Math", "Display", and "M" (see Sections 3.8-1 and 3.8-2 for more details). The first two correspond to LaTeX's math mode and display math mode. The last one is a special form of the "Math" element type, that imposes certain restrictions on the content. On the other hand the content of an "M" element is processed in a well defined way for text terminal or HTML output. The "Display" element also has an attribute such that its content is processed as in "M" elements.

Note that the content of these element is LaTeX code, but the special characters "<" and "&" for XML must be entered via the entities described in 2.1-10 or by using a CDATA statement, see 2.1-12.

2.2-3 More Entities

In GAPDoc there are some more predefined entities:

Table: Predefined Entities in the GAPDoc system
&GAP; GAP
&GAPDoc; GAPDoc
&TeX; TeX
&LaTeX; LaTeX
&BibTeX; BibTeX
&MeatAxe; MeatAxe
&XGAP; XGAP
&copyright; ©
&nbsp; " "
&ndash;

 


Here &nbsp; is a non-breakable space character.

Additional entities are defined for some mathematical symbols, see 3.8 for more details.

One can define further local entities right inside the head (see 2.1-1) of a GAPDoc XML document as in the following example.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE Book SYSTEM "gapdoc.dtd"
  [ <!ENTITY MyEntity "some longish <E>text</E> possibly with markup">
  ]>

These additional definitions go into the <!DOCTYPE tag in square brackets. Such new entities are used like this: &MyEntity;

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chapB.txt0000644000175000017500000005476012026346063013542 0ustar billbill B The File gapdoc.dtd For easier reference we repeat here the complete content of the file gapdoc.dtd.  gapdoc.dtd                                            GAP"> GAPDoc"> {\TeX}TeX"> {\LaTeX}LaTeX"> {Bib\TeX}BibTeX"> MeatAxe"> XGAP">                                                                                                                                                                                                                                                                                              GAPDoc-1.5.1/doc/chapBib_mj.html0000644000175000017500000000742512026346063014664 0ustar billbill GAP (GAPDoc) - References
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

References

[GAP] GAP -- Groups, Algorithms, and Programming, Version 4.4.9, The GAP Group, Aachen, St Andrews (2006)
(http://www.gap-system.org).

[Lam85] Lamport, L., LaTeX: A Document Preparation System, Addison-Wesley (1985).

[Neu07] Neunhöffer, M., IO, Bindings for low level C library IO, Version 2.2 (2007)
(GAP package), http://www-groups.mcs.st-and.ac.uk/~neunhoef/Computer/Software/Gap/io.html.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/intro.xml0000644000175000017500000003745312026346063013641 0ustar billbillIntroduction and Example The main purpose of the &GAPDoc; package is to define a file format for documentation of &GAP;-programs and -packages (see ). The problem is that such documentation should be readable in several output formats. For example it should be possible to read the documentation inside the terminal in which &GAP; is running (a text mode) and there should be a printable version in high typesetting quality (produced by some version of &TeX;). It is also popular to view &GAP;'s online help with a Web-browser via an HTML-version of the documentation. Nowadays one can use &LaTeX; and standard viewer programs to produce and view on the screen dvi- or pdf-files with full support of internal and external hyperlinks. Certainly there will be other interesting document formats and tools in this direction in the future.

Our aim is to find a format for writing the documentation which allows a relatively easy translation into the output formats just mentioned and which hopefully makes it easy to translate to future output formats as well.

To make documentation written in the &GAPDoc; format directly usable, we also provide a set of programs, called converters, which produce text-, hyperlinked &LaTeX;- and HTML-output versions of a &GAPDoc; document. These programs are developed by the first named author. They run completely inside &GAP;, i.e., no external programs are needed. You only need latex and pdflatex to process the &LaTeX; output. These programs are described in Chapter .

XML XML The definition of the &GAPDoc; format uses XML, the eXtendible Markup Language. This is a standard (defined by the W3C consortium, see http://www.w3c.org) which lays down a syntax for adding markup to a document or to some data. It allows to define document structures via introducing markup elements and certain relations between them. This is done in a document type definition. The file gapdoc.dtd contains such a document type definition and is the central part of the &GAPDoc; package.

The easiest way for getting a good idea about this is probably to look at an example. The Appendix  contains a short but complete &GAPDoc; document for a fictitious share package. In the next section we will go through this document, explain basic facts about XML and the &GAPDoc; document type, and give pointers to more details in later parts of this documentation.

In the last Section  of this introductory chapter we try to answer some general questions about the decisions which lead to the &GAPDoc; package.

A complete example In this section we recall the lines from the example document in Appendix  and give some explanations. ]]> This line just tells a human reader and computer programs that the file is a document with XML markup and that the text is encoded in the UTF-8 character set (other common encodings are ASCII or ISO-8895-X encodings). ]]> Everything in a XML file between <!-- and --> is a comment and not part of the document content. ]]> This line says that the document contains markup which is defined in the system file gapdoc.dtd and that the markup obeys certain rules defined in that file (the ending dtd means document type definition). It further says that the actual content of the document consists of an element with name Book. And we can really see that the remaining part of the file is enclosed as follows: [...] (content omitted) ]]> This demonstrates the basics of the markup in XML. This part of the document is an element. It consists of the start tag ]]>, the element content and the end tag ]]> (end tags always start with </). This element also has an attribute Name whose value is 3k+1.

If you know HTML, this will look familiar to you. But there are some important differences: The element name Book and attribute name Name are case sensitive. The value of an attribute must always be enclosed in quotes. In XML every element has a start and end tag (which can be combined for elements defined as empty, see for example <TableOfContents/> below).

If you know &LaTeX;, you are familiar with quite different types of markup, for example: The equivalent of the Book element in &LaTeX; is \begin{document} ... \end{document}. The sectioning in &LaTeX; is not done by explicit start and end markup, but implicitly via heading commands like \section. Other markup is done by using braces {} and putting some commands inside. And for mathematical formulae one can use the $ for the start and the end of the markup. In XML all markup looks similar to that of the Book element.

The content of the book starts with a title page.

The <Package>ThreeKPlusOne</Package> Package Version 42 Dummy Authör 3kplusone@dev.null ©right; 2000 The Author.

You can do with this package what you want.

Really. ]]>

The content of the TitlePage element consists again of elements. In Chapter  we describe which elements are allowed within a TitlePage and that their ordering is prescribed in this case. In the (stupid) name of the author you see that a German umlaut is used directly (in ISO-latin1 encoding).

Contrary to &LaTeX;- or HTML-files this markup does not say anything about the actual layout of the title page in any output version of the document. It just adds information about the meaning of pieces of text.

Within the Copyright element there are two more things to learn about XML markup. The <P/> is a complete element. It is a combined start and end tag. This shortcut is allowed for elements which are defined to be always empty, i.e., to have no content. You may have already guessed that <P/> is used as a paragraph separator. Note that empty lines do not separate paragraphs (contrary to &LaTeX;).

The other construct we see here is &copyright;. This is an example of an entity in XML and is a macro for some substitution text. Here we use an entity as a shortcut for a complicated expression which makes it possible that the term copyright is printed as some text like (C) in text terminal output and as a copyright character in other output formats. In &GAPDoc; we predefine some entities. Certain special characters must be typed via entities, for example <, > and & to avoid a misinterpretation as XML markup. It is possible to define additional entities for your document inside the <!DOCTYPE ...> declaration, see .

Note that elements in XML must always be properly nested, as in this example. A construct like ...]]> is not allowed.

]]> This is another example of an empty element. It just means that a table of contents for the whole document should be included into any output version of the document.

After this the main text of the document follows inside certain sectioning elements:

The 3k+1 Problem
Theory [...] (content omitted)
Program [...] (content omitted)
]]>
These elements are used similarly to \chapter and \section in &LaTeX;. But note that the explicit end tags are necessary here.

The sectioning commands allow to assign an optional attribute Label. This can be used for referring to a section inside the document.

The text of the first section starts as follows. The whitespace in the text is unimportant and the indenting is not necessary.

k \in &NN; be a natural number. We consider the sequence n(i, k), i \in &NN;, with n(1, k) = k and else ]]> Here we come to the interesting question how to type mathematical formulae in a &GAPDoc; document. We did not find any alternative for writing formulae in &TeX; syntax. (There is MATHML, but even simple formulae contain a lot of markup, become quite unreadable and they are cumbersome to type. Furthermore there seem to be no tools available which translate such formulae in a nice way into &TeX; and text.) So, formulae are essentially typed as in &LaTeX;. (Actually, it is also possible to type unicode characters of some mathematical symbols directly, or via an entity like the &NN; above.) There are three types of elements containing formulae: M, Math and Display. The first two are for in-text formulae and the third is for displayed formulae. Here M and Math are equivalent, when translating a &GAPDoc; document into &LaTeX;. But they are handled differently for terminal text (and HTML) output. For the content of an M-element there are defined rules for a translation into well readable terminal text. More complicated formulae are in Math or Display elements and they are just printed as they are typed in text output. So, to make a section well readable inside a terminal window you should try to put as many formulae as possible into M-elements. In our example text we used the notation n(i, k) instead of n_i(k) because it is easier to read in text mode. See Sections  and  for more details.

A few lines further on we find two non-internal references.

or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ ]]> The first within the Cite-element is the citation of a book. In &GAPDoc; we use the widely used &BibTeX; database format for reference lists. This does not use XML but has a well documented structure which is easy to parse. And many people have collections of references readily available in this format. The reference list in an output version of the document is produced with the empty element ]]> close to the end of our example file. The attribute Databases give the name(s) of the database (.bib) files which contain the references.

Putting a Web-address into an URL-element allows one to create a hyperlink in output formats which allow this.

The second section of our example contains a special kind of subsection defined in &GAPDoc;.

This function computes for a natural number k the beginning of the sequence n(i, k) defined in section . The sequence stops at the first 1 or at n(max, k), if max is given. gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package" ]]> A ManSection contains the description of some function, operation, method, filter and so on. The Func-element describes the name of a function (there are also similar elements Oper, Meth, Filt and so on) and names for its arguments, optional arguments enclosed in square brackets. See Section  for more details.

In the Description we write the argument names as A-elements. A good description of a function should usually contain an example of its use. For this there are some verbatim-like elements in &GAPDoc;, like Example above (here, clearly, whitespace matters which causes a slightly strange indenting).

The text contains an internal reference to the first section via the explicitly defined label sec:theory.

The first section also contains a Ref-element which refers to the function described here. Note that there is no explicit label for such a reference. The pair ]]> and ]]> does the cross referencing (and hyperlinking if possible) implicitly via the name of the function.

Here is one further element from our example document which we want to explain.

]]> This is again an empty element which just says that an output version of the document should contain an index. Many entries for the index are generated automatically because the Func and similar elements implicitly produce such entries. It is also possible to include explicit additional entries in the index.
Some questions Are those XML files too ugly to read and edit? Just have a look and decide yourself. The markup needs more characters than most &TeX; or &LaTeX; markup. But the structure of the document is easier to see. If you configure your favorite editor well, you do not need more key strokes for typing the markup than in &LaTeX;. Why do we not use &LaTeX; alone? &LaTeX; is good for writing books. But &LaTeX; files are generally difficult to parse and to process to other output formats like text for browsing in a terminal window or HTML (or new formats which may become popular in the future). &GAPDoc; markup is one step more abstract than &LaTeX; insofar as it describes meaning instead of appearance of text. The inner workings of &LaTeX; are too complicated to learn without pain, which makes it difficult to overcome problems that occur occasionally. Why XML and not a newly defined markup language? XML is a well defined standard that is more and more widely used. Lots of people have thought about it. Years of experience with SGML went into the design. It is easy to explain, easy to parse and lots of tools are available, there will be more in the future.
GAPDoc-1.5.1/doc/gapdoc.out0000644000175000017500000000502112026346063013734 0ustar billbill\BOOKMARK [0][-]{chapter.1}{Introduction and Example}{}% 1 \BOOKMARK [1][-]{section.1.1}{XML}{chapter.1}% 2 \BOOKMARK [1][-]{section.1.2}{A complete example}{chapter.1}% 3 \BOOKMARK [1][-]{section.1.3}{Some questions}{chapter.1}% 4 \BOOKMARK [0][-]{chapter.2}{How To Type a GAPDoc Document}{}% 5 \BOOKMARK [1][-]{section.2.1}{General XML Syntax}{chapter.2}% 6 \BOOKMARK [1][-]{section.2.2}{Entering GAPDoc Documents}{chapter.2}% 7 \BOOKMARK [0][-]{chapter.3}{The Document Type Definition}{}% 8 \BOOKMARK [1][-]{section.3.1}{What is a DTD?}{chapter.3}% 9 \BOOKMARK [1][-]{section.3.2}{Overall Document Structure}{chapter.3}% 10 \BOOKMARK [1][-]{section.3.3}{Sectioning Elements}{chapter.3}% 11 \BOOKMARK [1][-]{section.3.4}{ManSection\205a special kind of subsection}{chapter.3}% 12 \BOOKMARK [1][-]{section.3.5}{Cross Referencing and Citations}{chapter.3}% 13 \BOOKMARK [1][-]{section.3.6}{Structural Elements like Lists}{chapter.3}% 14 \BOOKMARK [1][-]{section.3.7}{Types of Text}{chapter.3}% 15 \BOOKMARK [1][-]{section.3.8}{Elements for Mathematical Formulae}{chapter.3}% 16 \BOOKMARK [1][-]{section.3.9}{Everything else}{chapter.3}% 17 \BOOKMARK [0][-]{chapter.4}{Distributing a Document into Several Files}{}% 18 \BOOKMARK [1][-]{section.4.1}{The Conventions}{chapter.4}% 19 \BOOKMARK [1][-]{section.4.2}{A Tool for Collecting a Document}{chapter.4}% 20 \BOOKMARK [0][-]{chapter.5}{The Converters and an XML Parser}{}% 21 \BOOKMARK [1][-]{section.5.1}{Producing Documentation from Source Files}{chapter.5}% 22 \BOOKMARK [1][-]{section.5.2}{Parsing XML Documents}{chapter.5}% 23 \BOOKMARK [1][-]{section.5.3}{The Converters}{chapter.5}% 24 \BOOKMARK [1][-]{section.5.4}{Testing Manual Examples}{chapter.5}% 25 \BOOKMARK [0][-]{chapter.6}{String and Text Utilities}{}% 26 \BOOKMARK [1][-]{section.6.1}{Text Utilities}{chapter.6}% 27 \BOOKMARK [1][-]{section.6.2}{Unicode Strings}{chapter.6}% 28 \BOOKMARK [1][-]{section.6.3}{Print Utilities}{chapter.6}% 29 \BOOKMARK [0][-]{chapter.7}{Utilities for Bibliographies}{}% 30 \BOOKMARK [1][-]{section.7.1}{Parsing BibTeX Files}{chapter.7}% 31 \BOOKMARK [1][-]{section.7.2}{The BibXMLext Format}{chapter.7}% 32 \BOOKMARK [1][-]{section.7.3}{Utilities for BibXMLext data}{chapter.7}% 33 \BOOKMARK [1][-]{section.7.4}{Getting BibTeX entries from MathSciNet}{chapter.7}% 34 \BOOKMARK [0][-]{appendix.A}{The File 3k+1.xml}{}% 35 \BOOKMARK [0][-]{appendix.B}{The File gapdoc.dtd}{}% 36 \BOOKMARK [0][-]{appendix.C}{The File bibxmlext.dtd}{}% 37 \BOOKMARK [0][-]{appendix*.3}{References}{}% 38 \BOOKMARK [0][-]{section*.4}{Index}{}% 39 GAPDoc-1.5.1/doc/gapdoc.tex0000644000175000017500000111644412026346063013742 0ustar billbill% generated by GAPDoc2LaTeX from XML source (Frank Luebeck) \documentclass[a4paper,11pt]{report} \usepackage{a4wide} \sloppy \pagestyle{myheadings} \usepackage{amssymb} \usepackage[latin1]{inputenc} \usepackage{makeidx} \makeindex \usepackage{color} \definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083} \definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179} \definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894} \definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894} \definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000} \definecolor{Black}{rgb}{0.0,0.0,0.0} \definecolor{linkColor}{rgb}{0.0,0.0,0.554} \definecolor{citeColor}{rgb}{0.0,0.0,0.554} \definecolor{fileColor}{rgb}{0.0,0.0,0.554} \definecolor{urlColor}{rgb}{0.0,0.0,0.554} \definecolor{promptColor}{rgb}{0.0,0.0,0.589} \definecolor{brkpromptColor}{rgb}{0.589,0.0,0.0} \definecolor{gapinputColor}{rgb}{0.589,0.0,0.0} \definecolor{gapoutputColor}{rgb}{0.0,0.0,0.0} %% for a long time these were red and blue by default, %% now black, but keep variables to overwrite \definecolor{FuncColor}{rgb}{0.0,0.0,0.0} %% strange name because of pdflatex bug: \definecolor{Chapter }{rgb}{0.0,0.0,0.0} \definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064} \usepackage{fancyvrb} \usepackage{mathptmx,helvet} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage[ pdftex=true, bookmarks=true, a4paper=true, pdftitle={Written with GAPDoc}, pdfcreator={LaTeX with hyperref package / GAPDoc}, colorlinks=true, backref=page, breaklinks=true, linkcolor=linkColor, citecolor=citeColor, filecolor=fileColor, urlcolor=urlColor, pdfpagemode={UseNone}, ]{hyperref} \newcommand{\maintitlesize}{\fontsize{50}{55}\selectfont} % write page numbers to a .pnr log file for online help \newwrite\pagenrlog \immediate\openout\pagenrlog =\jobname.pnr \immediate\write\pagenrlog{PAGENRS := [} \newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}} %% were never documented, give conflicts with some additional packages \newcommand{\GAP}{\textsf{GAP}} %% nicer description environments, allows long labels \usepackage{enumitem} \setdescription{style=nextline} %% depth of toc \setcounter{tocdepth}{1} %% command for ColorPrompt style examples \newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}} \newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}} \newcommand{\gapinput}[1]{\color{gapinputColor}{#1}} \begin{document} \logpage{[ 0, 0, 0 ]} \begin{titlepage} \mbox{}\vfill \begin{center}{\maintitlesize \textbf{\textsf{GAPDoc}\mbox{}}}\\ \vfill \hypersetup{pdftitle=\textsf{GAPDoc}} \markright{\scriptsize \mbox{}\hfill \textsf{GAPDoc} \hfill\mbox{}} {\Huge ( Version 1.5.1 ) \mbox{}}\\[1cm] {February 2012\mbox{}}\\[1cm] \mbox{}\\[2cm] {\Large \textbf{ Frank L{\"u}beck \mbox{}}}\\ {\Large \textbf{ Max Neunh{\"o}ffer \mbox{}}}\\ \hypersetup{pdfauthor= Frank L{\"u}beck ; Max Neunh{\"o}ffer } \end{center}\vfill \mbox{}\\ {\mbox{}\\ \small \noindent \textbf{ Frank L{\"u}beck } Email: \href{mailto://Frank.Luebeck@Math.RWTH-Aachen.De} {\texttt{Frank.Luebeck@Math.RWTH-Aachen.De}}\\ Homepage: \href{http://www.math.rwth-aachen.de/~Frank.Luebeck} {\texttt{http://www.math.rwth-aachen.de/\texttt{\symbol{126}}Frank.Luebeck}}}\\ {\mbox{}\\ \small \noindent \textbf{ Max Neunh{\"o}ffer } Email: \href{mailto://neunhoef at mcs.st-and.ac.uk} {\texttt{neunhoef at mcs.st-and.ac.uk}}\\ Homepage: \href{http://www-groups.mcs.st-and.ac.uk/~neunhoef/} {\texttt{http://www-groups.mcs.st-and.ac.uk/\texttt{\symbol{126}}neunhoef/}}}\\ \end{titlepage} \newpage\setcounter{page}{2} {\small \section*{Copyright} \logpage{[ 0, 0, 1 ]} \index{License} {\copyright} 2000-2012 by Frank L{\"u}beck and Max Neunh{\"o}ffer \textsf{GAPDoc} is free software; you can redistribute it and/or modify it under the terms of the \href{http://www.fsf.org/licenses/gpl.html} {GNU General Public License} as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. \mbox{}}\\[1cm] \newpage \def\contentsname{Contents\logpage{[ 0, 0, 2 ]}} \tableofcontents \newpage \chapter{\textcolor{Chapter }{Introduction and Example}}\label{ch:intro} \logpage{[ 1, 0, 0 ]} \hyperdef{L}{X7D4EE663818DA109}{} { The main purpose of the \textsf{GAPDoc} package is to define a file format for documentation of \textsf{GAP}-programs and -packages (see \cite{GAP4}). The problem is that such documentation should be readable in several output formats. For example it should be possible to read the documentation inside the terminal in which \textsf{GAP} is running (a text mode) and there should be a printable version in high typesetting quality (produced by some version of {\TeX}). It is also popular to view \textsf{GAP}'s online help with a Web-browser via an HTML-version of the documentation. Nowadays one can use {\LaTeX} and standard viewer programs to produce and view on the screen \texttt{dvi}- or \texttt{pdf}-files with full support of internal and external hyperlinks. Certainly there will be other interesting document formats and tools in this direction in the future. Our aim is to find a \emph{format for writing} the documentation which allows a relatively easy translation into the output formats just mentioned and which hopefully makes it easy to translate to future output formats as well. To make documentation written in the \textsf{GAPDoc} format directly usable, we also provide a set of programs, called converters, which produce text-, hyperlinked {\LaTeX}- and HTML-output versions of a \textsf{GAPDoc} document. These programs are developed by the first named author. They run completely inside \textsf{GAP}, i.e., no external programs are needed. You only need \texttt{latex} and \texttt{pdflatex} to process the {\LaTeX} output. These programs are described in Chapter{\nobreakspace}\ref{ch:conv}. \section{\textcolor{Chapter }{XML}}\label{sec:XML} \logpage{[ 1, 1, 0 ]} \hyperdef{L}{X8590236E858F7E93}{} { \index{XML} The definition of the \textsf{GAPDoc} format uses XML, the ``eXtendible Markup Language''. This is a standard (defined by the W3C consortium, see \href{http://www.w3c.org} {\texttt{http://www.w3c.org}}) which lays down a syntax for adding markup to a document or to some data. It allows to define document structures via introducing markup \emph{elements} and certain relations between them. This is done in a \emph{document type definition}. The file \texttt{gapdoc.dtd} contains such a document type definition and is the central part of the \textsf{GAPDoc} package. The easiest way for getting a good idea about this is probably to look at an example. The Appendix{\nobreakspace}\ref{app:3k+1} contains a short but complete \textsf{GAPDoc} document for a fictitious share package. In the next section we will go through this document, explain basic facts about XML and the \textsf{GAPDoc} document type, and give pointers to more details in later parts of this documentation. In the last Section{\nobreakspace}\ref{sec:faq} of this introductory chapter we try to answer some general questions about the decisions which lead to the \textsf{GAPDoc} package. } \section{\textcolor{Chapter }{A complete example}}\label{sec:3k+1expl} \logpage{[ 1, 2, 0 ]} \hyperdef{L}{X7B47AFA881BFC9DC}{} { In this section we recall the lines from the example document in Appendix{\nobreakspace}\ref{app:3k+1} and give some explanations. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} This line just tells a human reader and computer programs that the file is a document with XML markup and that the text is encoded in the UTF-8 character set (other common encodings are ASCII or ISO-8895-X encodings). \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} Everything in a XML file between ``\texttt{{\textless}!--}'' and ``\texttt{--{\textgreater}}'' is a comment and not part of the document content. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} This line says that the document contains markup which is defined in the system file \texttt{gapdoc.dtd} and that the markup obeys certain rules defined in that file (the ending \texttt{dtd} means ``document type definition''). It further says that the actual content of the document consists of an element with name ``Book''. And we can really see that the remaining part of the file is enclosed as follows: \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] [...] (content omitted) \end{Verbatim} This demonstrates the basics of the markup in XML. This part of the document is an ``element''. It consists of the ``start tag'' \texttt{{\textless}Book Name="3k+1"{\textgreater}}, the ``element content'' and the ``end tag'' \texttt{{\textless}/Book{\textgreater}} (end tags always start with \texttt{{\textless}/}). This element also has an ``attribute'' \texttt{Name} whose ``value'' is \texttt{3k+1}. If you know HTML, this will look familiar to you. But there are some important differences: The element name \texttt{Book} and attribute name \texttt{Name} are \emph{case sensitive}. The value of an attribute must \emph{always} be enclosed in quotes. In XML \emph{every} element has a start and end tag (which can be combined for elements defined as ``empty'', see for example \texttt{{\textless}TableOfContents/{\textgreater}} below). If you know {\LaTeX}, you are familiar with quite different types of markup, for example: The equivalent of the \texttt{Book} element in {\LaTeX} is \texttt{\texttt{\symbol{92}}begin\texttt{\symbol{123}}document\texttt{\symbol{125}} ... \texttt{\symbol{92}}end\texttt{\symbol{123}}document\texttt{\symbol{125}}}. The sectioning in {\LaTeX} is not done by explicit start and end markup, but implicitly via heading commands like \texttt{\texttt{\symbol{92}}section}. Other markup is done by using braces \texttt{\texttt{\symbol{123}}\texttt{\symbol{125}}} and putting some commands inside. And for mathematical formulae one can use the \texttt{\$} for the start \emph{and} the end of the markup. In XML \emph{all} markup looks similar to that of the \texttt{Book} element. The content of the book starts with a title page. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] The <Package>ThreeKPlusOne</Package> Package Version 42 Dummy Authr 3kplusone@dev.null ©right; 2000 The Author.

You can do with this package what you want.

Really. \end{Verbatim} The content of the \texttt{TitlePage} element consists again of elements. In Chapter{\nobreakspace}\ref{DTD} we describe which elements are allowed within a \texttt{TitlePage} and that their ordering is prescribed in this case. In the (stupid) name of the author you see that a German umlaut is used directly (in ISO-latin1 encoding). Contrary to {\LaTeX}- or HTML-files this markup does not say anything about the actual layout of the title page in any output version of the document. It just adds information about the \emph{meaning} of pieces of text. Within the \texttt{Copyright} element there are two more things to learn about XML markup. The \texttt{{\textless}P/{\textgreater}} is a complete element. It is a combined start and end tag. This shortcut is allowed for elements which are defined to be always ``empty'', i.e., to have no content. You may have already guessed that \texttt{{\textless}P/{\textgreater}} is used as a paragraph separator. Note that empty lines do not separate paragraphs (contrary to {\LaTeX}). The other construct we see here is \texttt{\©right;}. This is an example of an ``entity'' in XML and is a macro for some substitution text. Here we use an entity as a shortcut for a complicated expression which makes it possible that the term \emph{copyright} is printed as some text like \texttt{(C)} in text terminal output and as a copyright character in other output formats. In \textsf{GAPDoc} we predefine some entities. Certain ``special characters'' must be typed via entities, for example ``{\textless}'', ``{\textgreater}'' and ``\&'' to avoid a misinterpretation as XML markup. It is possible to define additional entities for your document inside the \texttt{{\textless}!DOCTYPE ...{\textgreater}} declaration, see{\nobreakspace}\ref{GDent}. Note that elements in XML must always be properly nested, as in this example. A construct like \texttt{{\textless}a{\textgreater}{\textless}b{\textgreater}...{\textless}/a{\textgreater}{\textless}/b{\textgreater}} is \emph{not} allowed. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} This is another example of an ``empty element''. It just means that a table of contents for the whole document should be included into any output version of the document. After this the main text of the document follows inside certain sectioning elements: \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] The 3k+1 Problem

Theory [...] (content omitted)
Program [...] (content omitted)
\end{Verbatim} These elements are used similarly to ``\texttt{\symbol{92}}chapter'' and ``\texttt{\symbol{92}}section'' in {\LaTeX}. But note that the explicit end tags are necessary here. The sectioning commands allow to assign an optional attribute ``Label''. This can be used for referring to a section inside the document. The text of the first section starts as follows. The whitespace in the text is unimportant and the indenting is not necessary. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] Let k \in &NN; be a natural number. We consider the sequence n(i, k), i \in &NN;, with n(1, k) = k and else \end{Verbatim} Here we come to the interesting question how to type mathematical formulae in a \textsf{GAPDoc} document. We did not find any alternative for writing formulae in {\TeX} syntax. (There is MATHML, but even simple formulae contain a lot of markup, become quite unreadable and they are cumbersome to type. Furthermore there seem to be no tools available which translate such formulae in a nice way into {\TeX} and text.) So, formulae are essentially typed as in {\LaTeX}. (Actually, it is also possible to type unicode characters of some mathematical symbols directly, or via an entity like the \texttt{\&NN;} above.) There are three types of elements containing formulae: ``M'', ``Math'' and ``Display''. The first two are for in-text formulae and the third is for displayed formulae. Here ``M'' and ``Math'' are equivalent, when translating a \textsf{GAPDoc} document into {\LaTeX}. But they are handled differently for terminal text (and HTML) output. For the content of an ``M''-element there are defined rules for a translation into well readable terminal text. More complicated formulae are in ``Math'' or ``Display'' elements and they are just printed as they are typed in text output. So, to make a section well readable inside a terminal window you should try to put as many formulae as possible into ``M''-elements. In our example text we used the notation \texttt{n(i, k)} instead of \texttt{n{\textunderscore}i(k)} because it is easier to read in text mode. See Sections{\nobreakspace}\ref{GDformulae} and{\nobreakspace}\ref{sec:misc} for more details. A few lines further on we find two non-internal references. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] problem, see or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ \end{Verbatim} The first within the ``Cite''-element is the citation of a book. In \textsf{GAPDoc} we use the widely used Bib{\TeX} database format for reference lists. This does not use XML but has a well documented structure which is easy to parse. And many people have collections of references readily available in this format. The reference list in an output version of the document is produced with the empty element \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} close to the end of our example file. The attribute ``Databases'' give the name(s) of the database (\texttt{.bib}) files which contain the references. Putting a Web-address into an ``URL''-element allows one to create a hyperlink in output formats which allow this. The second section of our example contains a special kind of subsection defined in \textsf{GAPDoc}. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] This function computes for a natural number k the beginning of the sequence n(i, k) defined in section . The sequence stops at the first 1 or at n(max, k), if max is given. gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package" \end{Verbatim} A ``ManSection'' contains the description of some function, operation, method, filter and so on. The ``Func''-element describes the name of a \emph{function} (there are also similar elements ``Oper'', ``Meth'', ``Filt'' and so on) and names for its arguments, optional arguments enclosed in square brackets. See Section{\nobreakspace}\ref{sec:mansect} for more details. In the ``Description'' we write the argument names as ``A''-elements. A good description of a function should usually contain an example of its use. For this there are some verbatim-like elements in \textsf{GAPDoc}, like ``Example'' above (here, clearly, whitespace matters which causes a slightly strange indenting). The text contains an internal reference to the first section via the explicitly defined label \texttt{sec:theory}. The first section also contains a ``Ref''-element which refers to the function described here. Note that there is no explicit label for such a reference. The pair \texttt{{\textless}Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/{\textgreater}} and \texttt{{\textless}Ref Func="ThreeKPlusOneSequence"/{\textgreater}} does the cross referencing (and hyperlinking if possible) implicitly via the name of the function. Here is one further element from our example document which we want to explain. \begin{Verbatim}[fontsize=\small,frame=single,label=from 3k+1.xml] \end{Verbatim} This is again an empty element which just says that an output version of the document should contain an index. Many entries for the index are generated automatically because the ``Func'' and similar elements implicitly produce such entries. It is also possible to include explicit additional entries in the index. } \section{\textcolor{Chapter }{Some questions}}\label{sec:faq} \logpage{[ 1, 3, 0 ]} \hyperdef{L}{X79A97B867F45E5C7}{} { \begin{description} \item[{Are those XML files too ugly to read and edit?}] Just have a look and decide yourself. The markup needs more characters than most {\TeX} or {\LaTeX} markup. But the structure of the document is easier to see. If you configure your favorite editor well, you do not need more key strokes for typing the markup than in {\LaTeX}. \item[{Why do we not use {\LaTeX} alone?}] {\LaTeX} is good for writing books. But {\LaTeX} files are generally difficult to parse and to process to other output formats like text for browsing in a terminal window or HTML (or new formats which may become popular in the future). \textsf{GAPDoc} markup is one step more abstract than {\LaTeX} insofar as it describes meaning instead of appearance of text. The inner workings of {\LaTeX} are too complicated to learn without pain, which makes it difficult to overcome problems that occur occasionally. \item[{Why XML and not a newly defined markup language?}] XML is a well defined standard that is more and more widely used. Lots of people have thought about it. Years of experience with SGML went into the design. It is easy to explain, easy to parse and lots of tools are available, there will be more in the future. \end{description} } } \chapter{\textcolor{Chapter }{How To Type a \textsf{GAPDoc} Document}}\label{HowEnter} \logpage{[ 2, 0, 0 ]} \hyperdef{L}{X820EBE207DCC0655}{} { In this chapter we give a more formal description of what you need to start to type documentation in \textsf{GAPDoc} XML format. Many details were already explained by example in Section{\nobreakspace}\ref{sec:3k+1expl} of the introduction. We do \emph{not} answer the question ``How to \emph{write} a \textsf{GAPDoc} document?'' in this chapter. You can (hopefully) find an answer to this question by studying the example in the introduction, see{\nobreakspace}\ref{sec:3k+1expl}, and learning about more details in the reference Chapter{\nobreakspace}\ref{DTD}. The definite source for all details of the official XML standard with useful annotations is: \href{http://www.xml.com/axml/axml.html} {\texttt{http://www.xml.com/axml/axml.html}} Although this document must be quite technical, it is surprisingly well readable. \section{\textcolor{Chapter }{General XML Syntax}}\label{EnterXML} \logpage{[ 2, 1, 0 ]} \hyperdef{L}{X7B3A544986A1A9EA}{} { We will now discuss the pieces of text which can occur in a general XML document. We start with those pieces which do not contribute to the actual content of the document. \subsection{\textcolor{Chapter }{Head of XML Document}}\label{XMLhead} \logpage{[ 2, 1, 1 ]} \hyperdef{L}{X84E8D39687638CF0}{} { Each XML document should have a head which states that it is an XML document in some encoding and which XML-defined language is used. In case of a \textsf{GAPDoc} document this should always look as in the following example. \begin{Verbatim}[commandchars=@|A,fontsize=\small,frame=single,label=Example] \end{Verbatim} See{\nobreakspace}\ref{XMLenc} for a remark on the ``encoding'' statement. (There may be local entity definitions inside the \texttt{DOCTYPE} statement, see Subsection{\nobreakspace}\ref{GDent} below.) } \subsection{\textcolor{Chapter }{Comments}}\label{XMLcomment} \logpage{[ 2, 1, 2 ]} \hyperdef{L}{X780C79EB85C32138}{} { A ``comment'' in XML starts with the character sequence ``\texttt{{\textless}!--}'' and ends with the sequence ``\texttt{--{\textgreater}}''. Between these sequences there must not be two adjacent dashes ``\texttt{--}''. } \subsection{\textcolor{Chapter }{Processing Instructions}}\label{XMLprocinstr} \logpage{[ 2, 1, 3 ]} \hyperdef{L}{X82DBCCAD8358BB63}{} { A ``processing instruction'' in XML starts with the character sequence ``\texttt{{\textless}?}'' followed by a name (``\texttt{xml}'' is only allowed at the very beginning of the document to declare it being an XML document, see \ref{XMLhead}). After that any characters may follow, except that the ending sequence ``\texttt{?{\textgreater}}'' must not occur within the processing instruction. } {\nobreakspace} And now we turn to those parts of the document which contribute to its actual content. \subsection{\textcolor{Chapter }{Names in XML and Whitespace}}\label{XMLnames} \logpage{[ 2, 1, 4 ]} \hyperdef{L}{X7A0FB16C7FEC0B53}{} { A ``name'' in XML (used for element and attribute identifiers, see below) must start with a letter (in the encoding of the document) or with a colon ``\texttt{:}'' or underscore ``\texttt{{\textunderscore}}'' character. The following characters may also be digits, dots ``\texttt{.}'' or dashes ``\texttt{-}''. This is a simplified description of the rules in the standard, which are concerned with lots of unicode ranges to specify what a ``letter'' is. Sequences only consisting of the following characters are considered as \emph{whitespace}: blanks, tabs, carriage return characters and new line characters. } \subsection{\textcolor{Chapter }{Elements}}\label{XMLel} \logpage{[ 2, 1, 5 ]} \hyperdef{L}{X79B130FC7906FB4C}{} { The actual content of an XML document consists of ``elements''. An element has some ``content'' with a leading ``start tag'' (\ref{XMLstarttag}) and a trailing ``end tag'' (\ref{XMLendtag}). The content can contain further elements but they must be properly nested. One can define elements whose content is always empty, those elements can also be entered with a single combined tag (\ref{XMLcombtag}). } \subsection{\textcolor{Chapter }{Start Tags}}\label{XMLstarttag} \logpage{[ 2, 1, 6 ]} \hyperdef{L}{X7DD1DCB783588BD5}{} { A ``start-tag'' consists of a less-than-character ``\texttt{{\textless}}'' directly followed (without whitespace) by an element name (see{\nobreakspace}\ref{XMLnames}), optional attributes, optional whitespace, and a greater-than-character ``\texttt{{\textgreater}}''. An ``attribute'' consists of some whitespace and then its name followed by an equal sign ``\texttt{=}'' which is optionally enclosed by whitespace, and the attribute value, which is enclosed either in single or double quotes. The attribute value may not contain the type of quote used as a delimiter or the character ``\texttt{{\textless}}'', the character ``\texttt{\&}'' may only appear to start an entity, see{\nobreakspace}\ref{XMLent}. We describe in{\nobreakspace}\ref{AttrValRules} how to enter special characters in attribute values. Note especially that no whitespace is allowed between the starting ``\texttt{{\textless}}'' character and the element name. The quotes around an attribute value cannot be omitted. The names of elements and attributes are \emph{case sensitive}. } \subsection{\textcolor{Chapter }{End Tags}}\label{XMLendtag} \logpage{[ 2, 1, 7 ]} \hyperdef{L}{X7E5A567E83005B62}{} { An ``end tag'' consists of the two characters ``\texttt{{\textless}/}'' directly followed by the element name, optional whitespace and a greater-than-character ``\texttt{{\textgreater}}''. } \subsection{\textcolor{Chapter }{Combined Tags for Empty Elements}}\label{XMLcombtag} \logpage{[ 2, 1, 8 ]} \hyperdef{L}{X843A02A88514D919}{} { Elements which always have empty content can be written with a single tag. This looks like a start tag (see{\nobreakspace}\ref{XMLstarttag}) \emph{except} that the trailing greater-than-character ``\texttt{{\textgreater}}'' is substituted by the two character sequence ``\texttt{/{\textgreater}}''. } \subsection{\textcolor{Chapter }{Entities}}\label{XMLent} \logpage{[ 2, 1, 9 ]} \hyperdef{L}{X78FB56C77B1F391A}{} { An ``entity'' in XML is a macro for some substitution text. There are two types of entities. A ``character entity'' can be used to specify characters in the encoding of the document (can be useful for entering non-ASCII characters which you cannot manage to type in directly). They are entered with a sequence ``\texttt{\&\#}'', directly followed by either some decimal digits or an ``\texttt{x}'' and some hexadecimal digits, directly followed by a semicolon ``\texttt{;}''. Using such a character entity is just equivalent to typing the corresponding character directly. Then there are references to ``named entities''. They are entered with an ampersand character ``\texttt{\&}'' directly followed by a name which is directly followed by a semicolon ``\texttt{;}''. Such entities must be declared somewhere by giving a substitution text. This text is included in the document and the document is parsed again afterwards. The exact rules are a bit subtle but you probably want to use this only in simple cases. Predefined entities for \textsf{GAPDoc} are described in \ref{XMLspchar} and \ref{GDent}. } \subsection{\textcolor{Chapter }{Special Characters in XML}}\label{XMLspchar} \logpage{[ 2, 1, 10 ]} \hyperdef{L}{X84A95A19801EDE76}{} { We have seen that the less-than-character ``\texttt{{\textless}}'' and the ampersand character ``\texttt{\&}'' start a tag or entity reference in XML. To get these characters into the document text one has to use entity references, namely ``\texttt{\<}'' to get ``\texttt{{\textless}}'' and ``\texttt{\&}'' to get ``\texttt{\&}''. Furthermore ``\texttt{\>}'' must be used to get ``\texttt{{\textgreater}}'' when the string ``\texttt{]]{\textgreater}}'' appears in element content (and not as delimiter of a \texttt{CDATA} section explained below). Another possibility is to use a \texttt{CDATA} statement explained in{\nobreakspace}\ref{XMLcdata}. } \subsection{\textcolor{Chapter }{Rules for Attribute Values}}\label{AttrValRules} \logpage{[ 2, 1, 11 ]} \hyperdef{L}{X7F49E7AD785AED22}{} { Attribute values can contain entities which are substituted recursively. But except for the entities \< or a character entity it is not allowed that a {\textless} character is introduced by the substitution (there is no XML parsing for evaluating the attribute value, just entity substitutions). } \subsection{\textcolor{Chapter }{\texttt{CDATA}}}\label{XMLcdata} \logpage{[ 2, 1, 12 ]} \hyperdef{L}{X80D9026B7CB7B32F}{} { Pieces of text which contain many characters which can be misinterpreted as markup can be enclosed by the character sequences ``\texttt{{\textless}![CDATA[}'' and ``\texttt{]]{\textgreater}}''. Everything between these sequences is considered as content of the document and is not further interpreted as XML text. All the rules explained so far in this section do \emph{not apply} to such a part of the document. The only document content which cannot be entered directly inside a \texttt{CDATA} statement is the sequence ``\texttt{]]{\textgreater}}''. This can be entered as ``\texttt{]]\>}'' outside the \texttt{CDATA} statement. \begin{Verbatim}[fontsize=\small,frame=single,label=Example] A nesting of tags like is not allowed. \end{Verbatim} } \subsection{\textcolor{Chapter }{Encoding of an XML Document}}\label{XMLenc} \logpage{[ 2, 1, 13 ]} \hyperdef{L}{X8709BD337DA09ED5}{} { We suggest to use the UTF-8 encoding for writing \textsf{GAPDoc} XML documents. But the tools described in Chapter \ref{ch:conv} also work with ASCII or the various ISO-8859-X encodings (ISO-8859-1 is also called latin1 and covers most special characters for western European languages). } \subsection{\textcolor{Chapter }{Well Formed and Valid XML Documents}}\label{XMLvalid} \logpage{[ 2, 1, 14 ]} \hyperdef{L}{X8561F07A81CABDD6}{} { We want to mention two further important words which are often used in the context of XML documents. A piece of text becomes a ``well formed'' XML document if all the formal rules described in this section are fulfilled. But this says nothing about the content of the document. To give this content a meaning one needs a declaration of the element and corresponding attribute names as well as of named entities which are allowed. Furthermore there may be restrictions how such elements can be nested. This \emph{definition of an XML based markup language} is done in a ``document type definition''. An XML document which contains only elements and entities declared in such a document type definition and obeys the rules given there is called ``valid (with respect to this document type definition)''. The main file of the \textsf{GAPDoc} package is \texttt{gapdoc.dtd}. This contains such a definition of a markup language. We are not going to explain the formal syntax rules for document type definitions in this section. But in Chapter{\nobreakspace}\ref{DTD} we will explain enough about it to understand the file \texttt{gapdoc.dtd} and so the markup language defined there. } } \section{\textcolor{Chapter }{Entering \textsf{GAPDoc} Documents}}\label{EnterGD} \logpage{[ 2, 2, 0 ]} \hyperdef{L}{X7E9C91B77D1D0A4A}{} { Here are some additional rules for writing \textsf{GAPDoc} XML documents. \subsection{\textcolor{Chapter }{Other special characters}}\label{otherspecchar} \logpage{[ 2, 2, 1 ]} \hyperdef{L}{X79171E047B069F94}{} { As \textsf{GAPDoc} documents are used to produce {\LaTeX} and HTML documents, the question arises how to deal with characters with a special meaning for other applications (for example ``\texttt{\&}'', ``\texttt{\#}'', ``\texttt{\$}'', ``\texttt{\%}'', ``\texttt{\texttt{\symbol{126}}}'', ``\texttt{\texttt{\symbol{92}}}'', ``\texttt{\texttt{\symbol{123}}}'', ``\texttt{\texttt{\symbol{125}}}'', ``\texttt{{\textunderscore}}'', ``\texttt{\texttt{\symbol{94}}}'', ``\texttt{{\nobreakspace}}'' (this is a non-breakable space, ``\texttt{\texttt{\symbol{126}}}'' in {\LaTeX}) have a special meaning for {\LaTeX} and ``\texttt{\&}'', ``\texttt{{\textless}}'', ``\texttt{{\textgreater}}'' have a special meaning for HTML (and XML). In \textsf{GAPDoc} you can usually just type these characters directly, it is the task of the converter programs which translate to some output format to take care of such special characters. The exceptions to this simple rule are: \begin{itemize} \item \& and {\textless} must be entered as \texttt{\&} and \texttt{\<} as explained in \ref{XMLspchar}. \item The content of the \textsf{GAPDoc} elements \texttt{{\textless}M{\textgreater}}, \texttt{{\textless}Math{\textgreater}} and \texttt{{\textless}Display{\textgreater}} is {\LaTeX} code, see \ref{MathForm}. \item The content of an \texttt{{\textless}Alt{\textgreater}} element with \texttt{Only} attribute contains code for the specified output type, see \ref{Alt}. \end{itemize} Remark: In former versions of \textsf{GAPDoc} one had to use particular entities for all the special characters mentioned above (\texttt{\&tamp;}, \texttt{\&hash;}, \texttt{\$}, \texttt{\&percent;}, \texttt{\˜}, \texttt{\&bslash;}, \texttt{\&obrace;}, \texttt{\&cbrace;}, \texttt{\&uscore;}, \texttt{\&circum;}, \texttt{\&tlt;}, \texttt{\&tgt;}). These are no longer needed, but they are still defined for backwards compatibility with older \textsf{GAPDoc} documents. } \subsection{\textcolor{Chapter }{Mathematical Formulae}}\label{GDformulae} \logpage{[ 2, 2, 2 ]} \hyperdef{L}{X7EAE0C5A835F126F}{} { Mathematical formulae in \textsf{GAPDoc} are typed as in {\LaTeX}. They must be the content of one of three types of \textsf{GAPDoc} elements concerned with mathematical formulae: ``\texttt{Math}'', ``\texttt{Display}'', and ``\texttt{M}'' (see Sections{\nobreakspace}\ref{Math} and{\nobreakspace}\ref{M} for more details). The first two correspond to {\LaTeX}'s math mode and display math mode. The last one is a special form of the ``\texttt{Math}'' element type, that imposes certain restrictions on the content. On the other hand the content of an ``\texttt{M}'' element is processed in a well defined way for text terminal or HTML output. The ``\texttt{Display}'' element also has an attribute such that its content is processed as in ``\texttt{M}'' elements. Note that the content of these element is {\LaTeX} code, but the special characters ``\texttt{{\textless}}'' and ``\texttt{\&}'' for XML must be entered via the entities described in{\nobreakspace}\ref{XMLspchar} or by using a \texttt{CDATA} statement, see{\nobreakspace}\ref{XMLcdata}. } \subsection{\textcolor{Chapter }{More Entities}}\label{GDent} \logpage{[ 2, 2, 3 ]} \hyperdef{L}{X7BDFF6D37FBED400}{} { In \textsf{GAPDoc} there are some more predefined entities: \begin{center} \begin{tabular}{|l|l|}\hline \texttt{\&GAP;}& \textsf{GAP}\\ \hline \texttt{\&GAPDoc;}& \textsf{GAPDoc}\\ \hline \texttt{\&TeX;}& {\TeX}\\ \hline \texttt{\&LaTeX;}& {\LaTeX}\\ \hline \texttt{\&BibTeX;}& Bib{\TeX}\\ \hline \texttt{\&MeatAxe;}& \textsf{MeatAxe}\\ \hline \texttt{\&XGAP;}& \textsf{XGAP}\\ \hline \texttt{\©right;}& {\copyright}\\ \hline \texttt{\ }& ``{\nobreakspace}''\\ \hline \texttt{\–}& {\textendash}\\ \hline \end{tabular}\\[2mm] \textbf{Table: }Predefined Entities in the \textsf{GAPDoc} system\end{center} Here \texttt{\ } is a non-breakable space character. Additional entities are defined for some mathematical symbols, see \ref{MathForm} for more details. One can define further local entities right inside the head (see{\nobreakspace}\ref{XMLhead}) of a \textsf{GAPDoc} XML document as in the following example. \begin{Verbatim}[fontsize=\small,frame=single,label=Example] text
possibly with markup"> ]> \end{Verbatim} These additional definitions go into the \texttt{{\textless}!DOCTYPE} tag in square brackets. Such new entities are used like this: \texttt{\&MyEntity;} } } } \chapter{\textcolor{Chapter }{The Document Type Definition}}\label{DTD} \logpage{[ 3, 0, 0 ]} \hyperdef{L}{X7859CFF180D52D49}{} { In this chapter we first explain what a ``document type definition'' is and then describe \texttt{gapdoc.dtd} in detail. That file together with the current chapter define how a \textsf{GAPDoc} document has to look like. It can be found in the main directory of the \textsf{GAPDoc} package and it is reproduced in Appendix{\nobreakspace}\ref{GAPDocdtd}. We do not give many examples in this chapter which is more intended as a formal reference for all \textsf{GAPDoc} elements. Instead we provide an extra document with book name \texttt{GAPDocExample} (also accessible from the \textsf{GAP} online help). This uses all the constructs introduced in this chapter and you can easily compare the source code and how it looks like in the different output formats. Furthermore recall that many basic things about XML markup were already explained by example in the introductory chapter{\nobreakspace}\ref{ch:intro}. \section{\textcolor{Chapter }{What is a DTD?}}\logpage{[ 3, 1, 0 ]} \hyperdef{L}{X7B76F6F786521F6B}{} { A document type definition (DTD) is a formal declaration of how an XML document has to be structured. It is itself structured such that programs that handle documents can read it and treat the documents accordingly. There are for example parsers and validity checkers that use the DTD to validate an XML document, see{\nobreakspace}\ref{XMLvalid}. The main thing a DTD does is to specify which elements may occur in documents of a certain document type, how they can be nested, and what attributes they can or must have. So, for each element there is a rule. Note that a DTD can \emph{not} ensure that a document which is ``valid'' also makes sense to the converters! It only says something about the formal structure of the document. For the remaining part of this chapter we have divided the elements of \textsf{GAPDoc} documents into several subsets, each of which will be discussed in one of the next sections. See the following three subsections to learn by example, how a DTD works. We do not want to be too formal here, but just enable the reader to understand the declarations in \texttt{gapdoc.dtd}. For precise descriptions of the syntax of DTD's see again the official standard in: {\nobreakspace}{\nobreakspace}\href{http://www.xml.com/axml/axml.html} {\texttt{http://www.xml.com/axml/axml.html}} } \section{\textcolor{Chapter }{Overall Document Structure}}\logpage{[ 3, 2, 0 ]} \hyperdef{L}{X7DB0F9E57879CC76}{} { A \textsf{GAPDoc} document contains on its top level exactly one element with name \texttt{Book}. This element is declared in the DTD as follows: \subsection{\textcolor{Chapter }{\texttt{{\textless}Book{\textgreater}}}}\logpage{[ 3, 2, 1 ]} \hyperdef{L}{X7D27228D7E68473E}{} { \index{Book@\texttt{Book}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} After the keyword \texttt{ELEMENT} and the name \texttt{Book} there is a list in parentheses. This is a comma separated list of names of elements which can occur (in the given order) in the content of a \texttt{Book} element. Each name in such a list can be followed by one of the characters ``\texttt{?}'', ``\texttt{*}'' or ``\texttt{+}'', meaning that the corresponding element can occur zero or one time, an arbitrary number of times, or at least once, respectively. Without such an extra character the corresponding element must occur exactly once. Instead of one name in this list there can also be a list of elements names separated by ``\texttt{|}'' characters, this denotes any element with one of the names (i.e., ``\texttt{|}'' means ``or''). So, the \texttt{Book} element must contain first a \texttt{TitlePage} element, then an optional \texttt{TableOfContents} element, then a \texttt{Body} element, then zero or more elements of type \texttt{Appendix}, then an optional \texttt{Bibliography} element, and finally an optional element of type \texttt{TheIndex}. Note that \emph{only} these elements are allowed in the content of the \texttt{Book} element. No other elements or text is allowed in between. An exception of this is that there may be whitespace between the end tag of one and the start tag of the next element - this should be ignored when the document is processed to some output format. An element like this is called an element with ``element content''. The second declaration starts with the keyword \texttt{ATTLIST} and the element name \texttt{Book}. After that there is a triple of whitespace separated parameters (in general an arbitrary number of such triples, one for each allowed attribute name). The first (\texttt{Name}) is the name of an attribute for a \texttt{Book} element. The second (\texttt{CDATA}) is always the same for all of our declarations, it means that the value of the attribute consists of ``character data''. The third parameter \texttt{\#REQUIRED} means that this attribute must be specified with any \texttt{Book} element. Later we will also see optional attributes which are declared as \texttt{\#IMPLIED}. } \subsection{\textcolor{Chapter }{\texttt{{\textless}TitlePage{\textgreater}}}}\logpage{[ 3, 2, 2 ]} \hyperdef{L}{X8643EEF587FC8AD4}{} { \index{TitlePage@\texttt{TitlePage}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Within this element information for the title page is collected. Note that more than one author can be specified. The elements must appear in this order because there is no sensible way to specify in a DTD something like ``the following elements may occur in any order but each exactly once''. Before going on with the other elements inside the \texttt{Book} element we explain the elements for the title page. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Title{\textgreater}}}}\label{Title} \logpage{[ 3, 2, 3 ]} \hyperdef{L}{X85C1D07A84F1F736}{} { \index{Title@\texttt{Title}} \label{Text} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Here is the last construct you need to understand for reading \texttt{gapdoc.dtd}. The expression ``\texttt{\%Text;}'' is a so-called ``parameter entity''. It is something like a macro within the DTD. It is defined as follows: \label{InnerText} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This means, that every occurrence of ``\texttt{\%Text;}'' in the DTD is replaced by the expression \label{Innertext} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] %InnerText; | List | Enum | Table \end{Verbatim} which is then expanded further because of the following definition: \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} These are the only two parameter entities we are using. They expand to lists of element names which are explained in the sequel \emph{and} the keyword \texttt{\#PCDATA} (concatenated with the ``or'' character ``\texttt{|}''). So, the element (\texttt{Title}) is of so-called ``mixed content'': It can contain \emph{parsed character data} which does not contain further markup (\texttt{\#PCDATA}) or any of the other above mentioned elements. Mixed content must always have the asterisk qualifier (like in \texttt{Title}) such that any sequence of elements (of the above list) and character data can be contained in a \texttt{Title} element. The \texttt{\%Text;} parameter entity is used in all places in the DTD, where ``normal text'' should be allowed, including lists, enumerations, and tables, but \emph{no} sectioning elements. The \texttt{\%InnerText;} parameter entity is used in all places in the DTD, where ``inner text'' should be allowed. This means, that no structures like lists, enumerations, and tables are allowed. This is used for example in headings. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Subtitle{\textgreater}}}}\logpage{[ 3, 2, 4 ]} \hyperdef{L}{X81B6D8D679A42915}{} { \index{Subtitle@\texttt{Subtitle}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Contains the subtitle of the document. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Version{\textgreater}}}}\label{Version} \logpage{[ 3, 2, 5 ]} \hyperdef{L}{X8064BA177E9D23B8}{} { \index{Version@\texttt{Version}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Note that the version can only contain character data and no further markup elements (except for \texttt{Alt}, which is necessary to resolve the entities described in \ref{GDent}). The converters will \emph{not} put the word ``Version'' in front of the text in this element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}TitleComment{\textgreater}}}}\logpage{[ 3, 2, 6 ]} \hyperdef{L}{X7C2765047A1561EB}{} { \index{TitleComment@\texttt{TitleComment}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Sometimes a title and subtitle are not sufficient to give a rough idea about the content of a package. In this case use this optional element to specify an additional text for the front page of the book. This text should be short, use the \texttt{Abstract} element (see{\nobreakspace}\ref{elAbstract}) for longer explanations. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Author{\textgreater}}}}\logpage{[ 3, 2, 7 ]} \hyperdef{L}{X846067D18467D228}{} { \index{Author@\texttt{Author}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} As noted in the comment there may be more than one element of this type. This element should contain the name of an author and probably an \texttt{Email}-address and/or WWW-\texttt{Homepage} element for this author, see{\nobreakspace}\ref{elEmail} and{\nobreakspace}\ref{elHomepage}. You can also specify an individual postal address here, instead of using the \texttt{Address} element described below, see{\nobreakspace}\ref{elAddress}. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Date{\textgreater}}}}\logpage{[ 3, 2, 8 ]} \hyperdef{L}{X87C47AD378268979}{} { \index{Date@\texttt{Date}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Only character data is allowed in this element which gives a date for the document. No automatic formatting is done. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Address{\textgreater}}}}\label{elAddress} \logpage{[ 3, 2, 9 ]} \hyperdef{L}{X7B84029079583E6E}{} { \index{Date@\texttt{Address}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This optional element can be used to specify a postal address of the author or the authors. If there are several authors with different addresses then put the \texttt{Address} elements inside the \texttt{Author} elements. Use the \texttt{Br} element (see{\nobreakspace}\ref{Br}) to mark the line breaks in the usual formatting of the address on a letter. Note that often it is not necessary to use this element because a postal address is easy to find via a link to a personal web page. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Abstract{\textgreater}}}}\label{elAbstract} \logpage{[ 3, 2, 10 ]} \hyperdef{L}{X7CF09C0F82D16612}{} { \index{Abstract@\texttt{Abstract}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element contains an abstract of the whole book. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Copyright{\textgreater}}}}\logpage{[ 3, 2, 11 ]} \hyperdef{L}{X823232338648B1D7}{} { \index{Copyright@\texttt{Copyright}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used for the copyright notice. Note the \texttt{\©right;} entity as described in section \ref{GDent}. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Acknowledgements{\textgreater}}}}\logpage{[ 3, 2, 12 ]} \hyperdef{L}{X868A17B2849FEB84}{} { \index{Acknowledgements@\texttt{Acknowledgements}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element contains the acknowledgements. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Colophon{\textgreater}}}}\logpage{[ 3, 2, 13 ]} \hyperdef{L}{X87AF74847BEA348D}{} { \index{Colophon@\texttt{Colophon}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The ``colophon'' page is used to say something about the history of a document. } \subsection{\textcolor{Chapter }{\texttt{{\textless}TableOfContents{\textgreater}}}}\logpage{[ 3, 2, 14 ]} \hyperdef{L}{X81F18BDE7B3182F4}{} { \index{TableOfContents@\texttt{TableOfContents}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element may occur in the \texttt{Book} element after the \texttt{TitlePage} element. If it is present, a table of contents is generated and inserted into the document. Note that because this element is declared to be \texttt{EMPTY} one can use the abbreviation \begin{Verbatim}[fontsize=\small,frame=single,label=Example] \end{Verbatim} to denote this empty element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Bibliography{\textgreater}} }}\label{Bibliography} \logpage{[ 3, 2, 15 ]} \hyperdef{L}{X857F84507B5CED2A}{} { \index{Bibliography@\texttt{Bibliography}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element may occur in the \texttt{Book} element after the last \texttt{Appendix} element. If it is present, a bibliography section is generated and inserted into the document. The attribute \texttt{Databases} must be specified, the names of several data files can be specified, separated by commas. Two kinds of files can be specified in \texttt{Databases}: The first are Bib{\TeX} files as defined in{\nobreakspace}\cite[Appendix B]{La85}. Such files must have a name with extension \texttt{.bib}, and in \texttt{Databases} the name must be given \emph{without} this extension. The second are files in BibXMLext format as defined in Section{\nobreakspace}\ref{BibXMLformat}. These files must have an extension \texttt{.xml} and in \texttt{Databases} the \emph{full} name must be specified. We suggest to use the BibXMLext format because it allows to produce potentially nicer bibliography entries in text and HTML documents. A bibliography style may be specified with the \texttt{Style} attribute. The optional \texttt{Style} attribute (for {\LaTeX} output of the document) must also be specified without the \texttt{.bst} extension (the default is \texttt{alpha}). See also section \ref{Cite} for a description of the \texttt{Cite} element which is used to include bibliography references into the text. } \subsection{\textcolor{Chapter }{\texttt{{\textless}TheIndex{\textgreater}}}}\label{TheIndex} \logpage{[ 3, 2, 16 ]} \hyperdef{L}{X80ACB0AA7FC414E4}{} { \index{TheIndex@\texttt{TheIndex}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element may occur in the \texttt{Book} element after the \texttt{Bibliography} element. If it is present, an index is generated and inserted into the document. There are elements in \textsf{GAPDoc} which implicitly generate index entries (e.g., \texttt{Func} (\ref{Func})) and there is an element \texttt{Index} (\ref{Index}) for explicitly adding index entries. } } \section{\textcolor{Chapter }{Sectioning Elements}}\logpage{[ 3, 3, 0 ]} \hyperdef{L}{X80E2AD7481DD69D9}{} { A \textsf{GAPDoc} book is divided into \emph{chapters}, \emph{sections}, and \emph{subsections}. The idea is of course, that a chapter consists of sections, which in turn consist of subsections. However for the sake of flexibility, the rules are not too restrictive. Firstly, text is allowed everywhere in the body of the document (and not only within sections). Secondly, the chapter level may be omitted. The exact rules are described below. \emph{Appendices} are a flavor of chapters, occurring after all regular chapters. There is a special type of subsection called ``\texttt{ManSection}''. This is a subsection devoted to the description of a function, operation or variable. It is analogous to a manpage in the UNIX environment. Usually each function, operation, method, and so on should have its own \texttt{ManSection}. Cross referencing is done on the level of \texttt{Subsection}s, respectively \texttt{ManSection}s. The topics in \textsf{GAP}'s online help are also pointing to subsections. So, they should not be too long. We start our description of the sectioning elements ``top-down'': \subsection{\textcolor{Chapter }{\texttt{{\textless}Body{\textgreater}}}}\logpage{[ 3, 3, 1 ]} \hyperdef{L}{X85FB286D82BA5300}{} { \index{Body@\texttt{Body}} The \texttt{Body} element marks the main part of the document. It must occur after the \texttt{TableOfContents} element. There is a big difference between \emph{inside} and \emph{outside} of this element: Whereas regular text is allowed nearly everywhere in the \texttt{Body} element and its subelements, this is not true for the \emph{outside}. This has also implications on the handling of whitespace. \emph{Outside} superfluous whitespace is usually ignored when it occurs between elements. \emph{Inside} of the \texttt{Body} element whitespace matters because character data is allowed nearly everywhere. Here is the definition in the DTD: \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The fact that \texttt{Chapter} and \texttt{Section} elements are allowed here leads to the possibility to omit the chapter level entirely in the document. For a description of \texttt{\%Text;} see \ref{Text}. (Remark: The purpose of this element is to make sure that a \emph{valid} \textsf{GAPDoc} document has a correct overall structure, which is only possible when the top element \texttt{Book} has element content.) } \subsection{\textcolor{Chapter }{\texttt{{\textless}Chapter{\textgreater}}}}\label{Chapter} \logpage{[ 3, 3, 2 ]} \hyperdef{L}{X81A68C117E39FA60}{} { \index{Chapter@\texttt{Chapter}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} A \texttt{Chapter} element can have a \texttt{Label} attribute, such that this chapter can be referenced later on with a \texttt{Ref} element (see section \ref{Ref}). Note that you have to specify a label to reference the chapter as there is no automatic labelling! \texttt{Chapter} elements can contain text (for a description of \texttt{\%Text;} see \ref{Text}), \texttt{Section} elements, and \texttt{Heading} elements. The following \emph{additional} rule cannot be stated in the DTD because we want a \texttt{Chapter} element to have mixed content. There must be \emph{exactly one} \texttt{Heading} element in the \texttt{Chapter} element, containing the heading of the chapter. Here is its definition: } \subsection{\textcolor{Chapter }{\texttt{{\textless}Heading{\textgreater}}}}\label{Heading} \logpage{[ 3, 3, 3 ]} \hyperdef{L}{X82F09E29814C7A72}{} { \index{Heading@\texttt{Heading}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used for headings in \texttt{Chapter}, \texttt{Section}, \texttt{Subsection}, and \texttt{Appendix} elements. It may only contain \texttt{\%InnerText;} (for a description see \ref{InnerText}). Each of the mentioned sectioning elements must contain exactly one direct \texttt{Heading} element (i.e., one which is not contained in another sectioning element). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Appendix{\textgreater}}}}\logpage{[ 3, 3, 4 ]} \hyperdef{L}{X7951B5C482C59057}{} { \index{Appendix@\texttt{Appendix}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The \texttt{Appendix} element behaves exactly like a \texttt{Chapter} element (see \ref{Chapter}) except for the position within the document and the numbering. While chapters are counted with numbers (1., 2., 3., ...) the appendices are counted with capital letters (A., B., ...). Again there is an optional \texttt{Label} attribute used for references. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Section{\textgreater}}}}\logpage{[ 3, 3, 5 ]} \hyperdef{L}{X795D46507CE20232}{} { \index{Section@\texttt{Section}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} A \texttt{Section} element can have a \texttt{Label} attribute, such that this section can be referenced later on with a \texttt{Ref} element (see section \ref{Ref}). Note that you have to specify a label to reference the section as there is no automatic labelling! \texttt{Section} elements can contain text (for a description of \texttt{\%Text;} see \ref{Text}), \texttt{Heading} elements, and subsections. There must be exactly one direct \texttt{Heading} element in a \texttt{Section} element, containing the heading of the section. Note that a subsection is either a \texttt{Subsection} element or a \texttt{ManSection} element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Subsection{\textgreater}}}}\logpage{[ 3, 3, 6 ]} \hyperdef{L}{X7A9AC7787E8163DC}{} { \index{Subsection@\texttt{Subsection}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The \texttt{Subsection} element can have a \texttt{Label} attribute, such that this subsection can be referenced later on with a \texttt{Ref} element (see section \ref{Ref}). Note that you have to specify a label to reference the subsection as there is no automatic labelling! \texttt{Subsection} elements can contain text (for a description of \texttt{\%Text;} see \ref{Text}), and \texttt{Heading} elements. There must be exactly one \texttt{Heading} element in a \texttt{Subsection} element, containing the heading of the subsection. Another type of subsection is a \texttt{ManSection}, explained now: } } \section{\textcolor{Chapter }{ManSection{\textendash}a special kind of subsection}}\label{sec:mansect} \logpage{[ 3, 4, 0 ]} \hyperdef{L}{X877B8B7C7EDD09E9}{} { \texttt{ManSection}s are intended to describe a function, operation, method, variable, or some other technical instance. It is analogous to a manpage in the UNIX environment. \subsection{\textcolor{Chapter }{\texttt{{\textless}ManSection{\textgreater}}}}\logpage{[ 3, 4, 1 ]} \hyperdef{L}{X7E24999A86DAEB60}{} { \index{ManSection@\texttt{ManSection}} \index{Description@\texttt{Description}} \index{Returns@\texttt{Returns}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The \texttt{ManSection} element can have a \texttt{Label} attribute, such that this subsection can be referenced later on with a \texttt{Ref} element (see section \ref{Ref}). But this is probably rarely necessary because the elements \texttt{Func} and so on (explained below) generate automatically labels for cross referencing. The content of a \texttt{ManSection} element is one or more elements describing certain items in \textsf{GAP}, each of them optionally followed by a \texttt{Returns} element, followed by a \texttt{Description} element, which contains \texttt{\%Text;} (see \ref{Text}) describing it. (Remember to include examples in the description as often as possible, see{\nobreakspace}\ref{Log}). The classes of items \textsf{GAPDoc} knows of are: functions (\texttt{Func}), operations (\texttt{Oper}), methods (\texttt{Meth}), filters (\texttt{Filt}), properties (\texttt{Prop}), attributes (\texttt{Attr}), variables (\texttt{Var}), families (\texttt{Fam}), and info classes (\texttt{InfoClass}). One \texttt{ManSection} should only describe several of such items when these are very closely related. Each element for an item corresponding to a \textsf{GAP} function can be followed by a \texttt{Returns} element. In output versions of the document the string ``Returns: '' will be put in front of the content text. The text in the \texttt{Returns} element should usually be a short hint about the type of object returned by the function. This is intended to give a good mnemonic for the use of a function (together with a good choice of names for the formal arguments). \texttt{ManSection}s are also sectioning elements which count as subsections. Usually there should be no \texttt{Heading}-element in a \texttt{ManSection}, in that case a heading is generated automatically from the first \texttt{Func}-like element. Sometimes this default behaviour does not look appropriate, for example when there are several \texttt{Func}-like elements. For such cases an optional \texttt{Heading} is allowed. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Func{\textgreater}}}}\label{Func} \logpage{[ 3, 4, 2 ]} \hyperdef{L}{X87CA42C681B95BCE}{} { \index{Func@\texttt{Func}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of a function. The \texttt{Name} attribute is required and its value is the name of the function. The value of the \texttt{Arg} attribute (also required) contains the full list of arguments including optional parts, which are denoted by square brackets. The argument names can be separated by whitespace, commas or the square brackets for the optional arguments, like \texttt{"grp[,{\nobreakspace}elm]"} or \texttt{"xx[y[z]{\nobreakspace}]"}. If \textsf{GAP} options are used, this can be followed by a colon \texttt{:} and one or more assignments, like \texttt{"n[,{\nobreakspace}r]: tries := 100"}. The name of the function is also used as label for cross referencing. When the name of the function appears in the text of the document it should \emph{always} be written with the \texttt{Ref} element, see{\nobreakspace}\ref{Ref}. This allows to use a unique typesetting style for function names and automatic cross referencing. If the optional \texttt{Label} attribute is given, it is appended (with a colon \texttt{:} in between) to the name of the function for cross referencing purposes. The text of the label can also appear in the document text. So, it should be a kind of short explanation. \begin{Verbatim}[fontsize=\small,frame=single,label=Example] \end{Verbatim} The optional \texttt{Comm} attribute should be a short description of the function, usually at most one line long (this is currently nowhere used). This element automatically produces an index entry with the name of the function and, if present, the text of the \texttt{Label} attribute as subentry (see also{\nobreakspace}\ref{TheIndex} and{\nobreakspace}\ref{Index}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Oper{\textgreater}}}}\logpage{[ 3, 4, 3 ]} \hyperdef{L}{X82684F9E8461DFC7}{} { \index{Oper@\texttt{Oper}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of an operation. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}). Note that multiple descriptions of the same operation may occur in a document because there may be several declarations in \textsf{GAP}. Furthermore there may be several \texttt{ManSection}s for methods of this operation (see{\nobreakspace}\ref{Meth}) which also use the same name. For reference purposes these must be distinguished by different \texttt{Label} attributes. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Meth{\textgreater}}}}\label{Meth} \logpage{[ 3, 4, 4 ]} \hyperdef{L}{X780247227AC3340B}{} { \index{Meth@\texttt{Meth}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of a method. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}). Frequently, an operation is implemented by several different methods. Therefore it seems to be interesting to document them independently. This is possible by using the same method name in different \texttt{ManSection}s. It is however required that these subsections and those describing the corresponding operation are distinguished by different \texttt{Label} attributes. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Filt{\textgreater}}}}\logpage{[ 3, 4, 5 ]} \hyperdef{L}{X7BFBED2C8766065E}{} { \index{Filt@\texttt{Filt}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of a filter. The first four attributes are used in the same way as in the \texttt{Func} element (see \ref{Func}), except that the \texttt{Arg} attribute is optional. The \texttt{Type} attribute can be any string, but it is thought to be something like ``\texttt{Category}'' or ``\texttt{Representation}''. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Prop{\textgreater}}}}\logpage{[ 3, 4, 6 ]} \hyperdef{L}{X81A6364E79DBE958}{} { \index{Prop@\texttt{Prop}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of a property. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Attr{\textgreater}}}}\logpage{[ 3, 4, 7 ]} \hyperdef{L}{X7B0AA7E98373249D}{} { \index{Attr@\texttt{Attr}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to specify the usage of an attribute (in \textsf{GAP}). The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Var{\textgreater}}}}\logpage{[ 3, 4, 8 ]} \hyperdef{L}{X7D4982A27D773098}{} { \index{Var@\texttt{Var}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to document a global variable. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}) except that there is no \texttt{Arg} attribute. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Fam{\textgreater}}}}\logpage{[ 3, 4, 9 ]} \hyperdef{L}{X7DF346F7795CB5C1}{} { \index{Fam@\texttt{Fam}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to document a family. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}) except that there is no \texttt{Arg} attribute. } \subsection{\textcolor{Chapter }{\texttt{{\textless}InfoClass{\textgreater}}}}\logpage{[ 3, 4, 10 ]} \hyperdef{L}{X84367BDE795E0C56}{} { \index{InfoClass@\texttt{InfoClass}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used within a \texttt{ManSection} element to document an info class. The attributes are used exactly in the same way as in the \texttt{Func} element (see \ref{Func}) except that there is no \texttt{Arg} attribute. } } \section{\textcolor{Chapter }{Cross Referencing and Citations}}\logpage{[ 3, 5, 0 ]} \hyperdef{L}{X78595FB585569617}{} { Cross referencing in the \textsf{GAPDoc} system is somewhat different to the usual {\LaTeX} cross referencing in so far, that a reference knows ``which type of object'' it is referencing. For example a ``reference to a function'' is distinguished from a ``reference to a chapter''. The idea of this is, that the markup must contain this information such that the converters can produce better output. The HTML converter can for example typeset a function reference just as the name of the function with a link to the description of the function, or a chapter reference as a number with a link in the other case. Referencing is done with the \texttt{Ref} element: \subsection{\textcolor{Chapter }{\texttt{{\textless}Ref{\textgreater}}}}\label{Ref} \logpage{[ 3, 5, 1 ]} \hyperdef{L}{X865F20E386B6DA49}{} { \index{Ref@\texttt{Ref}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The \texttt{Ref} element is defined to be \texttt{EMPTY}. If one of the attributes \texttt{Func}, \texttt{Oper}, \texttt{Meth}, \texttt{Prop}, \texttt{Attr}, \texttt{Var}, \texttt{Fam}, \texttt{InfoClass}, \texttt{Chap}, \texttt{Sect}, \texttt{Subsect}, \texttt{Appendix} is given then there must be exactly one of these, making the reference one to the corresponding object. The \texttt{Label} attribute can be specified in addition to make the reference unique, for example if more than one method with a given name is present. (Note that there is no way to specify in the DTD that exactly one of the first listed attributes must be given, this is an additional rule.) A reference to a \texttt{Label} element defined below (see \ref{Label}) is done by giving the \texttt{Label} attribute and optionally the \texttt{Text} attribute. If the \texttt{Text} attribute is present its value is typeset in place of the \texttt{Ref} element, if linking is possible (for example in HTML). If this is not possible, the section number is typeset. This type of reference is also used for references to tables (see \ref{Table}). An external reference into another book can be specified by using the \texttt{BookName} attribute. In this case the \texttt{Label} attribute or, if this is not given, the function or section like attribute, is used to resolve the reference. The generated reference points to the first hit when asking ``?book name: label'' inside \textsf{GAP}. The optional attribute \texttt{Style} can take only the values \texttt{Text} and \texttt{Number}. It can be used with references to sectioning units and it gives a hint to the converter programs, whether an explicit section number is generated or text. Normally all references to sections generate numbers and references to a \textsf{GAP} object generate the name of the corresponding object with some additional link or sectioning information, which is the behavior of \texttt{Style="Text"}. In case \texttt{Style="Number"} in all cases an explicit section number is generated. So \begin{Verbatim}[fontsize=\small,frame=single,label=Example] described in section \end{Verbatim} produces: \hyperref[Func]{`\texttt{{\textless}Func{\textgreater}}'} described in section \ref{Func}. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Label{\textgreater}}}}\label{Label} \logpage{[ 3, 5, 2 ]} \hyperdef{L}{X8653BAF279C7A817}{} { \index{Label@\texttt{Label}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to define a label for referencing a certain position in the document, if this is possible. If an exact reference is not possible (like in a printed version of the document) a reference to the corresponding subsection is generated. The value of the \texttt{Name} attribute must be unique under all \texttt{Label} elements. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Cite{\textgreater}}}}\label{Cite} \logpage{[ 3, 5, 3 ]} \hyperdef{L}{X855B311D7C33A50E}{} { \index{Cite@\texttt{Cite}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is for bibliography citations. It is \texttt{EMPTY} by definition. The attribute \texttt{Key} is the key for a lookup in a Bib{\TeX} database that has to be specified in the \texttt{Bibliography} element (see \ref{Bibliography}). The value of the \texttt{Where} attribute specifies the position in the document as in the corresponding {\LaTeX} syntax \texttt{\texttt{\symbol{92}}cite[Where value]\texttt{\symbol{123}}Key value\texttt{\symbol{125}}}. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Index{\textgreater}}}}\label{Index} \logpage{[ 3, 5, 4 ]} \hyperdef{L}{X7D2B1F278577D2D5}{} { \index{Index@\texttt{Index}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element generates an index entry. The text within the element is typeset in the index entry, which is sorted under the value, that is specified in the \texttt{Key} and \texttt{Subkey} attributes. If they are not specified, the typeset text itself is used as the key. A subkey can be specified in the simpler version as an attribute, but then no further markup can be used for the subkey. Optionally, the subkey text can be given in a \texttt{Subkey} element, in this case the attribute value is used for sorting but the typeset text is taken from the content of \texttt{Subkey}. Note that all \texttt{Func} and similar elements automatically generate index entries. If the \texttt{TheIndex} element (\ref{TheIndex}) is not present in the document all \texttt{Index} elements are ignored. } \subsection{\textcolor{Chapter }{\texttt{{\textless}URL{\textgreater}}}}\label{URL} \logpage{[ 3, 5, 5 ]} \hyperdef{L}{X7C58A957852F867C}{} { \index{URL@\texttt{URL}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is for references into the internet. It specifies an URL and optionally a text which can be used for a link (like in HTML or PDF versions of the document). This can be specified in two ways: Either the URL is given as element content and the text is given in the optional \texttt{Text} attribute (in this case the text cannot contain further markup), or the element contains the two elements \texttt{Link} and \texttt{LinkText} which in turn contain the URL and the text, respectively. The default value for the text is the URL itself. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Email{\textgreater}}}}\label{elEmail} \logpage{[ 3, 5, 6 ]} \hyperdef{L}{X7FEB041D793E781B}{} { \index{Email@\texttt{Email}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element type is the special case of an URL specifying an email address. The content of the element should be the email address without any prefix like ``\texttt{mailto:}''. This address is typeset by all converters, also without any prefix. In the case of an output document format like HTML the converter can produce a link with a ``\texttt{mailto:}'' prefix. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Homepage{\textgreater}}}}\label{elHomepage} \logpage{[ 3, 5, 7 ]} \hyperdef{L}{X81F135A886B732E6}{} { \index{Homepage@\texttt{Homepage}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element type is the special case of an URL specifying a WWW-homepage. } } \section{\textcolor{Chapter }{Structural Elements like Lists}}\logpage{[ 3, 6, 0 ]} \hyperdef{L}{X840099DF83823686}{} { The \textsf{GAPDoc} system offers some limited access to structural elements like lists, enumerations, and tables. Although it is possible to use all {\LaTeX} constructs one always has to think about other output formats. The elements in this section are guaranteed to produce something reasonable in all output formats. \subsection{\textcolor{Chapter }{\texttt{{\textless}List{\textgreater}}}}\label{List} \logpage{[ 3, 6, 1 ]} \hyperdef{L}{X7F97E8DD784F5CAA}{} { \index{List@\texttt{List}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element produces a list. Each item in the list corresponds to an \texttt{Item} element. Every \texttt{Item} element is optionally preceded by a \texttt{Mark} element. The content of this is used as a marker for the item. Note that this marker can be a whole word or even a sentence. It will be typeset in some emphasized fashion and most converters will provide some indentation for the rest of the item. The \texttt{Only} and \texttt{Not} attributes can be used to specify, that the list is included into the output by only one type of converter (\texttt{Only}) or all but one type of converter (\texttt{Not}). Of course at most one of the two attributes may occur in one element. The following values are allowed as of now: ``\texttt{LaTeX}'', ``\texttt{HTML}'', and ``\texttt{Text}''. See also the \texttt{Alt} element in \ref{Alt} for more about text alternatives for certain converters. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Mark{\textgreater}}}}\logpage{[ 3, 6, 2 ]} \hyperdef{L}{X786406A77C9F1CD6}{} { \index{Mark@\texttt{Mark}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used in the \texttt{List} element to mark items. See \ref{List} for an explanation. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Item{\textgreater}}}}\label{Item} \logpage{[ 3, 6, 3 ]} \hyperdef{L}{X7D6BFC907F5FEF37}{} { \index{Item@\texttt{Item}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used in the \texttt{List}, \texttt{Enum}, and \texttt{Table} elements to specify the items. See sections \ref{List}, \ref{Enum}, and \ref{Table} for further information. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Enum{\textgreater}}}}\label{Enum} \logpage{[ 3, 6, 4 ]} \hyperdef{L}{X7D3B2150818E3CD4}{} { \index{Enum@\texttt{Enum}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used like the \texttt{List} element (see \ref{List}) except that the items must not have marks attached to them. Instead, the items are numbered automatically. The same comments about the \texttt{Only} and \texttt{Not} attributes as above apply. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Table{\textgreater}}}}\label{Table} \logpage{[ 3, 6, 5 ]} \hyperdef{L}{X7BA7DA848347E2A9}{} { \index{Table@\texttt{Table}} \index{Caption@\texttt{{\textless}Caption{\textgreater}}} \index{Row@\texttt{{\textless}Row{\textgreater}}} \index{Align@\texttt{{\textless}Align{\textgreater}}} \index{HorLine@\texttt{{\textless}HorLine{\textgreater}}} \index{Item in Table@\texttt{{\textless}Item{\textgreater}} in \texttt{{\textless}Table{\textgreater}}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} A table in \textsf{GAPDoc} consists of an optional \texttt{Caption} element followed by a sequence of \texttt{Row} and \texttt{HorLine} elements. A \texttt{HorLine} element produces a horizontal line in the table. A \texttt{Row} element consists of a sequence of \texttt{Item} elements as they also occur in \texttt{List} and \texttt{Enum} elements. The \texttt{Only} and \texttt{Not} attributes have the same functionality as described in the \texttt{List} element in \ref{List}. The \texttt{Align} attribute is written like a {\LaTeX} tabular alignment specifier but only the letters ``\texttt{l}'', ``\texttt{r}'', ``\texttt{c}'', and ``\texttt{|}'' are allowed meaning left alignment, right alignment, centered alignment, and a vertical line as delimiter between columns respectively. If the \texttt{Label} attribute is there, one can reference the table with the \texttt{Ref} element (see \ref{Ref}) using its \texttt{Label} attribute. Usually only simple tables should be used. If you want a complicated table in the {\LaTeX} output you should provide alternatives for text and HTML output. Note that in HTML-4.0 there is no possibility to interpret the ``\texttt{|}'' column separators and \texttt{HorLine} elements as intended. There are lines between all columns and rows or no lines at all. } } \section{\textcolor{Chapter }{Types of Text}}\logpage{[ 3, 7, 0 ]} \hyperdef{L}{X7CA1E1327AFBA578}{} { This section covers the markup of text. Various types of ``text'' exist. The following elements are used in the \textsf{GAPDoc} system to mark them. They mostly come in pairs, one long name which is easier to remember and a shortcut to make the markup ``lighter''. Most of the following elements are thought to contain only character data and no further markup elements. It is however necessary to allow \texttt{Alt} elements to resolve the entities described in section \ref{GDent}. \subsection{\textcolor{Chapter }{\texttt{{\textless}Emph{\textgreater}} and \texttt{{\textless}E{\textgreater}}}}\logpage{[ 3, 7, 1 ]} \hyperdef{L}{X7E07C12185A25EF7}{} { \index{Emph@\texttt{Emph}} \index{E@\texttt{E}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to emphasize some piece of text. It may contain \texttt{\%InnerText;} (see \ref{InnerText}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Quoted{\textgreater}} and \texttt{{\textless}Q{\textgreater}}}}\logpage{[ 3, 7, 2 ]} \hyperdef{L}{X87FB13F57EF49C93}{} { \index{Quoted@\texttt{Quoted}} \index{Q@\texttt{Q}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to put some piece of text into ``{\nobreakspace}''-quotes. It may contain \texttt{\%InnerText;} (see \ref{InnerText}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}Keyword{\textgreater}} and \texttt{{\textless}K{\textgreater}}}}\logpage{[ 3, 7, 3 ]} \hyperdef{L}{X86A11FA98045FE79}{} { \index{Keyword@\texttt{Keyword}} \index{K@\texttt{K}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to mark something as a \emph{keyword}. Usually this will be a \textsf{GAP} keyword such as ``\texttt{if}'' or ``\texttt{for}''. No further markup elements are allowed within this element except for the \texttt{Alt} element, which is necessary. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Arg{\textgreater}} and \texttt{{\textless}A{\textgreater}}}}\label{Arg} \logpage{[ 3, 7, 4 ]} \hyperdef{L}{X8502FFCF7DC7982B}{} { \index{Arg@\texttt{Arg}} \index{A@\texttt{A}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used inside \texttt{Description}s in \texttt{ManSection}s to mark something as an \emph{argument} (of a function, operation, or such). It is guaranteed that the converters typeset those exactly as in the definition of functions. No further markup elements are allowed within this element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Code{\textgreater}} and \texttt{{\textless}C{\textgreater}}}}\label{Code} \logpage{[ 3, 7, 5 ]} \hyperdef{L}{X79C6755D80AEA4C1}{} { \index{Code@\texttt{Code}} \index{C@\texttt{C}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to mark something as a piece of \emph{code} like for example a \textsf{GAP} expression. It is guaranteed that the converters typeset this exactly as in the \texttt{Listing} element (compare section \ref{Listing}). The only further markup elements allowed within this element are \texttt{{\textless}Arg{\textgreater}} elements (see \ref{Arg}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}File{\textgreater}} and \texttt{{\textless}F{\textgreater}}}}\logpage{[ 3, 7, 6 ]} \hyperdef{L}{X7C30FEC078523528}{} { \index{File@\texttt{File}} \index{F@\texttt{F}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to mark something as a \emph{filename} or a \emph{pathname} in the file system. No further markup elements are allowed within this element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Button{\textgreater}} and \texttt{{\textless}B{\textgreater}}}}\logpage{[ 3, 7, 7 ]} \hyperdef{L}{X79AEA5068489EE6E}{} { \index{Button@\texttt{Button}} \index{B@\texttt{B}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to mark something as a \emph{button}. It can also be used for other items in a graphical user interface like \emph{menus}, \emph{menu entries}, or \emph{keys}. No further markup elements are allowed within this element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Package{\textgreater}}}}\logpage{[ 3, 7, 8 ]} \hyperdef{L}{X7B9BB2D878262083}{} { \index{Package@\texttt{Package}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to mark something as a name of a \emph{package}. This is for example used to define the entities \textsf{GAP}, \textsf{XGAP} or \textsf{GAPDoc} (see section \ref{GDent}). No further markup elements are allowed within this element. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Listing{\textgreater}}}}\label{Listing} \logpage{[ 3, 7, 9 ]} \hyperdef{L}{X799961B67E34193D}{} { \index{Listing@\texttt{Listing}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element is used to embed listings of programs into the document. Only character data and no other elements are allowed in the content. You should \emph{not} use the character entities described in section \ref{GDent} but instead type the characters directly. Only the general XML rules from section \ref{EnterXML} apply. Note especially the usage of \texttt{{\textless}![CDATA[} sections described there. It is guaranteed that all converters use a fixed width font for typesetting \texttt{Listing} elements. Compare also the usage of the \texttt{Code} and \texttt{C} elements in \ref{Code}. The \texttt{Type} attribute contains a comment about the type of listed code. It may appear in the output. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Log{\textgreater}} and \texttt{{\textless}Example{\textgreater}}}}\label{Log} \logpage{[ 3, 7, 10 ]} \hyperdef{L}{X7C926CF778F54591}{} { \index{Log@\texttt{Log}} \index{Example@\texttt{Example}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} These two elements behave exactly like the \texttt{Listing} element (see \ref{Listing}). They are thought for protocols of \textsf{GAP} sessions. The only difference between the two is that \texttt{Example} sections are intended to be subject to an automatic manual checking mechanism used to ensure the correctness of the \textsf{GAP} manual whereas \texttt{Log} is not touched by this (see section \ref{Sec:TestExample} for checking tools). To get a good layout of the examples for display in a standard terminal we suggest to use \texttt{SizeScreen([72]);} (see \texttt{SizeScreen} (\textbf{Reference: SizeScreen})) in your \textsf{GAP} session before producing the content of \texttt{Example} elements. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Verb{\textgreater}}}}\label{Verb} \logpage{[ 3, 7, 11 ]} \hyperdef{L}{X80500AFD86ADECC5}{} { There is one further type of verbatim-like element. \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The content of such an element is guaranteed to be put into an output version exactly as it is using some fixed width font. Before the content a new line is started. If the line after the end of the start tag consists of whitespace only then this part of the content is skipped. This element is intended to be used together with the \texttt{Alt} element to specify pre-formatted ASCII alternatives for complicated \texttt{Display} formulae or \texttt{Table}s. } } \section{\textcolor{Chapter }{Elements for Mathematical Formulae}}\label{MathForm} \logpage{[ 3, 8, 0 ]} \hyperdef{L}{X8145F6B37C04AA0A}{} { \subsection{\textcolor{Chapter }{\texttt{{\textless}Math{\textgreater}} and \texttt{{\textless}Display{\textgreater}}}}\label{Math} \logpage{[ 3, 8, 1 ]} \hyperdef{L}{X7B0254677AA56B5E}{} { \index{Math@\texttt{Math}} \index{Display@\texttt{Display}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} These elements are used for mathematical formulae. As described in section \ref{GDformulae} they correspond to {\LaTeX}'s math and display math mode respectively. The formulae are typed in as in {\LaTeX}, \emph{except} that the standard XML entities, see{\nobreakspace}\ref{XMLent} (in particular the characters \texttt{{\textless}} and \texttt{\&}), must be escaped - either by using the corresponding entities or by enclosing the formula between ``\texttt{{\textless}![CDATA[}'' and ``\texttt{]]{\textgreater}}''. (The main reference for {\LaTeX} is \cite{La85}.) It is also possible to use some unicode characters for mathematical symbols directly, provided that it can be translated by \texttt{Encode} (\ref{Encode}) into \texttt{"LaTeX"} encoding and that \texttt{SimplifiedUnicodeString} (\ref{SimplifiedUnicodeString}) with arguments \texttt{"latin1"} and \texttt{"single"} returns something sensible. Currently, we support entities \texttt{\&CC;}, \texttt{\&ZZ;}, \texttt{\&NN;}, \texttt{\&PP;}, \texttt{\&QQ;}, \texttt{\&HH;}, \texttt{\&RR;} for the corresponding black board bold letters {\ensuremath{\mathbb C}}, {\ensuremath{\mathbb Z}}, {\ensuremath{\mathbb N}},{\ensuremath{\mathbb P}}, {\ensuremath{\mathbb Q}}, {\ensuremath{\mathbb H}} and {\ensuremath{\mathbb R}}, respectively. The only element type that is allowed within the formula elements is the \texttt{Arg} or \texttt{A} element (see \ref{Arg}), which is used to typeset identifiers that are arguments to \textsf{GAP} functions or operations. If a \texttt{Display} element has an attribute \texttt{Mode} with value \texttt{"M"}, then the formula is formatted as in \texttt{M} elements (see{\nobreakspace}\ref{M}). Otherwise in text and HTML output the formula is shown as {\LaTeX} source code. For simple formulae (and you should try to make all your formulae simple!) attempt to use the \texttt{M} element or the \texttt{Mode="M"} attribute in \texttt{Display} for which there is a well defined translation into text, which can be used for text and HTML output versions of the document. So, if possible try to avoid the \texttt{Math} elements and \texttt{Display} elements without attribute or provide useful text substitutes for complicated formulae via \texttt{Alt} elements (see{\nobreakspace}\ref{Alt} and{\nobreakspace}\ref{Verb}). } \subsection{\textcolor{Chapter }{\texttt{{\textless}M{\textgreater}}}}\label{M} \logpage{[ 3, 8, 2 ]} \hyperdef{L}{X8796A7577B29543A}{} { \index{M@\texttt{M}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} The ``\texttt{M}'' element type is intended for formulae in the running text for which there is a sensible text version. For the {\LaTeX} version of a \textsf{GAPDoc} document the \texttt{M} and \texttt{Math} elements are equivalent. The remarks in \ref{Math} about special characters and the \texttt{Arg} element apply here as well. A document which has all formulae enclosed in \texttt{M} elements can be well readable in text terminal output and printed output versions. Compared to former versions of \textsf{GAPDoc} many more formulae can be put into \texttt{M} elements. Most modern terminal emulations support unicode characters and many mathematical symbols can now be represented by such characters. But even if a terminal can only display ASCII characters, the user will see some not too bad representation of a formula. As examples, here are some {\LaTeX} macros which have a sensible ASCII translation and are guaranteed to be translated accordingly by text (and HTML) converters (for a full list of handled Macros see \texttt{RecFields(TEXTMTRANSLATIONS)}): \begin{center} \begin{tabular}{|l|l|}\hline \texttt{\symbol{92}}ast& \texttt{*}\\ \hline \texttt{\symbol{92}}bf& \texttt{}\\ \hline \texttt{\symbol{92}}bmod& \texttt{mod}\\ \hline \texttt{\symbol{92}}cdot& \texttt{*}\\ \hline \texttt{\symbol{92}}colon& \texttt{:}\\ \hline \texttt{\symbol{92}}equiv& \texttt{=}\\ \hline \texttt{\symbol{92}}geq& \texttt{{\textgreater}=}\\ \hline \texttt{\symbol{92}}germ& \texttt{}\\ \hline \texttt{\symbol{92}}hookrightarrow& \texttt{-{\textgreater}}\\ \hline \texttt{\symbol{92}}iff& \texttt{{\textless}={\textgreater}}\\ \hline \texttt{\symbol{92}}langle& \texttt{{\textless}}\\ \hline \texttt{\symbol{92}}ldots& \texttt{...}\\ \hline \texttt{\symbol{92}}left& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}leq& \texttt{{\textless}=}\\ \hline \texttt{\symbol{92}}leftarrow& \texttt{{\textless}-}\\ \hline \texttt{\symbol{92}}Leftarrow& \texttt{{\textless}=}\\ \hline \texttt{\symbol{92}}limits& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}longrightarrow& \texttt{--{\textgreater}}\\ \hline \texttt{\symbol{92}}Longrightarrow& \texttt{=={\textgreater}}\\ \hline \texttt{\symbol{92}}mapsto& \texttt{-{\textgreater}}\\ \hline \texttt{\symbol{92}}mathbb& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}mathop& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}mid& \texttt{|}\\ \hline \texttt{\symbol{92}}pmod& \texttt{mod}\\ \hline \texttt{\symbol{92}}prime& \texttt{'}\\ \hline \texttt{\symbol{92}}rangle& \texttt{{\textgreater}}\\ \hline \texttt{\symbol{92}}right& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}rightarrow& \texttt{-{\textgreater}}\\ \hline \texttt{\symbol{92}}Rightarrow& \texttt{={\textgreater}}\\ \hline \texttt{\symbol{92}}rm, \texttt{\symbol{92}}sf, \texttt{\symbol{92}}textrm, \texttt{\symbol{92}}text& \texttt{}\\ \hline \texttt{\symbol{92}}setminus& \texttt{\texttt{\symbol{92}}}\\ \hline \texttt{\symbol{92}}thinspace& \texttt{ }\\ \hline \texttt{\symbol{92}}times& \texttt{x}\\ \hline \texttt{\symbol{92}}to& \texttt{-{\textgreater}}\\ \hline \texttt{\symbol{92}}vert& \texttt{|}\\ \hline \texttt{\symbol{92}}!& \texttt{}\\ \hline \texttt{\symbol{92}},& \texttt{}\\ \hline \texttt{\symbol{92}};& \texttt{{\nobreakspace}}\\ \hline \texttt{\symbol{92}}\texttt{\symbol{123}}& \texttt{\texttt{\symbol{123}}}\\ \hline \texttt{\symbol{92}}\texttt{\symbol{125}}& \texttt{\texttt{\symbol{125}}}\\ \hline \end{tabular}\\[2mm] \textbf{Table: }{\LaTeX} macros with special text translation\end{center} In all other macros only the backslash is removed (except for some macros describing more exotic symbols). Whitespace is normalized (to one blank) but not removed. Note that whitespace is not added, so you may want to add a few more spaces than you usually do in your {\LaTeX} documents. Braces \texttt{\texttt{\symbol{123}}\texttt{\symbol{125}}} are removed in general, however pairs of double braces are converted to one pair of braces. This can be used to write \texttt{{\textless}M{\textgreater}x\texttt{\symbol{94}}\texttt{\symbol{123}}12\texttt{\symbol{125}}{\textless}/M{\textgreater}} for \texttt{x\texttt{\symbol{94}}12} and \texttt{{\textless}M{\textgreater}x{\textunderscore}\texttt{\symbol{123}}\texttt{\symbol{123}}i+1\texttt{\symbol{125}}\texttt{\symbol{125}}{\textless}/M{\textgreater}} for \texttt{x{\textunderscore}\texttt{\symbol{123}}i+1\texttt{\symbol{125}}}. } } \section{\textcolor{Chapter }{Everything else}}\label{sec:misc} \logpage{[ 3, 9, 0 ]} \hyperdef{L}{X7A0D26B180BEDE37}{} { \subsection{\textcolor{Chapter }{\texttt{{\textless}Alt{\textgreater}}}}\label{Alt} \logpage{[ 3, 9, 1 ]} \hyperdef{L}{X817B08367FF43419}{} { \index{Alt@\texttt{Alt}} This element is used to specify alternatives for different output formats within normal text. See also sections \ref{List}, \ref{Enum}, and \ref{Table} for alternatives in lists and tables. \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} Of course exactly one of the two attributes must occur in one element. The attribute values must be one word or a list of words, separated by spaces or commas. The words which are currently recognized by the converter programs contained in \textsf{GAPDoc} are: ``\texttt{LaTeX}'', ``\texttt{HTML}'', and ``\texttt{Text}''. If the \texttt{Only} attribute is specified then only the corresponding converter will include the content of the element into the output document. If the \texttt{Not} attribute is specified the corresponding converter will ignore the content of the element. You can use other words to specify special alternatives for other converters of \textsf{GAPDoc} documents. We fix a rule for handling the content of an \texttt{Alt} element with \texttt{Only} attribute. In their content code for the corresponding output format is included directly. So, in case of HTML the content is HTML code, in case of {\LaTeX} the content is {\LaTeX} code. The converters don't apply any handling of special characters to this content. Within the element only \texttt{\%InnerText;} (see \ref{InnerText}) is allowed. This is to ensure that the same set of chapters, sections, and subsections show up in all output formats. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Par{\textgreater}} and \texttt{{\textless}P{\textgreater}}}}\label{Par} \logpage{[ 3, 9, 2 ]} \hyperdef{L}{X847CBC4380DBAC63}{} { \index{Par@\texttt{Par}} \index{P@\texttt{P}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This \texttt{EMPTY} element marks the boundary of paragraphs. Note that an empty line in the input does not mark a new paragraph as opposed to the {\LaTeX} convention. (Remark: it would be much easier to parse a document and to understand its sectioning and paragraph structure when there was an element whose \emph{content} is the text of a paragraph. But in practice many paragraph boundaries are implicitly clear which would make it somewhat painful to enclose each paragraph in extra tags. The introduction of the \texttt{P} or \texttt{Par} elements as above delegates this pain to the writer of a conversion program for \textsf{GAPDoc} documents.) } \subsection{\textcolor{Chapter }{\texttt{{\textless}Br{\textgreater}}}}\label{Br} \logpage{[ 3, 9, 3 ]} \hyperdef{L}{X7C910EF07C3FF929}{} { \index{Br@\texttt{Br}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element can be used to force a line break in the output versions of a \textsf{GAPDoc} element, it does not start a new paragraph. Please, do not use this instead of a \texttt{Par} element, this would often lead to ugly output versions of your document. } \subsection{\textcolor{Chapter }{\texttt{{\textless}Ignore{\textgreater}}}}\label{Ignore} \logpage{[ 3, 9, 4 ]} \hyperdef{L}{X84855267801B3077}{} { \index{Ignore@\texttt{Ignore}} \begin{Verbatim}[fontsize=\small,frame=single,label=From gapdoc.dtd] \end{Verbatim} This element can appear anywhere. Its content is ignored by the standard converters. It can be used, for example, to include data which are not part of the actual \textsf{GAPDoc} document, like source code, or to make not finished parts of the document invisible. Of course, one can use special converter programs which extract the contents of \texttt{Ignore} elements. Information on the type of the content can be stored in the optional attribute \texttt{Remark}. } } } \chapter{\textcolor{Chapter }{Distributing a Document into Several Files}}\label{Distributing} \logpage{[ 4, 0, 0 ]} \hyperdef{L}{X7A3355C07F57C280}{} { In \textsf{GAPDoc} there are facilities to distribute a single document over several files. This is for example interesting, if one wants to store the documentation of some code in the same file as the code itself. Or, if one just wants to store chapters of a document in separate files. There is a set of conventions how this is done and some tools to collect the text for further processing. The technique can also be used to distribute and collect other types of documents into respectively from several files (e.g., source code, examples). \section{\textcolor{Chapter }{The Conventions}}\label{DistrConv} \logpage{[ 4, 1, 0 ]} \hyperdef{L}{X7CE078A07E8256DC}{} { \index{Include@\texttt{{\textless}\#Include{\textgreater}}} \index{GAPDoc@\texttt{{\textless}\#GAPDoc{\textgreater}}} In this description we use the string \texttt{GAPDoc} for marking pieces of a document to collect. Pieces of documentation that shall be incorporated into another document are marked as follows: \begin{Verbatim}[fontsize=\small,frame=single,label=Example] ## <#GAPDoc Label="MyPiece"> ## This is the piece. ## The hash characters are removed. ## <#/GAPDoc> \end{Verbatim} This piece is then included into another file by a statement like: \texttt{{\textless}\#Include Label="MyPiece"{\textgreater}} Here are the exact rules, how pieces are gathered: \begin{itemize} \item All lines up to a line containing the character sequence ``\texttt{{\textless}\#GAPDoc{\nobreakspace}Label="}'' (exactly one space character) are ignored. The characters on the same line before this sequence are stored as ``prefix''. The characters after the sequence up to the next double quotes character are stored as ``label''. All other characters in the line are ignored. \item The following lines up to a line containing the character sequence ``\texttt{{\textless}\#/GAPDoc{\textgreater}}'' are stored under the label. These lines are processed as follows: The longest possible substring from the beginning of the line that equals the corresponding substring of the prefix is removed. \end{itemize} Having stored a list of labels and pieces of text gathered as above this can be used as follows. \begin{itemize} \item In \textsf{GAPDoc} documentation files all statements of the form ``\texttt{{\textless}\#Include Label="Key"{\textgreater}}'' are replaced by the sequence of lines stored under the label \texttt{Key}. \item Additionally, every occurrence of a statement of the form ``\texttt{{\textless}\#Include SYSTEM "Filename"{\textgreater}}'' is replaced by the whole file stored under the name \texttt{Filename} in the file system. \item These substitutions are done recursively (although one should probably avoid to use this extensively). \end{itemize} Here is another example: \begin{Verbatim}[fontsize=\small,frame=single,label=Example] # # <#GAPDoc Label="AnotherPiece"> some characters # # This text is not indented. # This text is indented by one blank. #Not indented. #<#/GAPDoc> \end{Verbatim} replaces \texttt{{\textless}\#Include Label="AnotherPiece"{\textgreater}} by \begin{Verbatim}[fontsize=\small,frame=single,label=Example] This text is not indented. This text is indented by one blank. Not indented. \end{Verbatim} Since these rules are very simple it is quite easy to write a program in almost any programming language which does this gathering of text pieces and the substitutions. In \textsf{GAPDoc} there is the \textsf{GAP} function \texttt{ComposedDocument} (\ref{ComposedDocument}) which does this. Note that the XML-tag-like markup we have used here is not a legal XML markup, since the hash character is not allowed in element names. The mechanism described here is a preprocessing step which composes a document. } \section{\textcolor{Chapter }{A Tool for Collecting a Document}}\logpage{[ 4, 2, 0 ]} \hyperdef{L}{X81E07B0F83EBDA5F}{} { \subsection{\textcolor{Chapter }{ComposedDocument}} \logpage{[ 4, 2, 1 ]}\nobreak \hyperdef{L}{X857D77557D12559D}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ComposedDocument({\mdseries\slshape tagname, path, main, source[, info]})\index{ComposedDocument@\texttt{ComposedDocument}} \label{ComposedDocument} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ComposedXMLString({\mdseries\slshape path, main, source[, info]})\index{ComposedXMLString@\texttt{ComposedXMLString}} \label{ComposedXMLString} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a document as string, or a list with this string and information about the source positions The argument \mbox{\texttt{\mdseries\slshape tagname}} is the string used for the pseudo elements which mark the pieces of a document to collect. (In \ref{DistrConv} we used \texttt{GAPDoc} as \mbox{\texttt{\mdseries\slshape tagname}}. The second function \texttt{ComposedXMLString}\texttt{( ... )} is an abbreviation for \texttt{ComposedDocument}\texttt{("GAPDoc", ... )}. The argument \mbox{\texttt{\mdseries\slshape path}} must be a path to some directory (as string or directory object), \mbox{\texttt{\mdseries\slshape main}} the name of a file in this directory and \mbox{\texttt{\mdseries\slshape source}} a list of file names, all of these relative to \mbox{\texttt{\mdseries\slshape path}}. The document is constructed via the mechanism described in Section{\nobreakspace}\ref{DistrConv}. First the files given in \mbox{\texttt{\mdseries\slshape source}} are scanned for chunks of the document marked by \texttt{{\textless}\#\mbox{\texttt{\mdseries\slshape tagname}} Label="..."{\textgreater}} and \texttt{{\textless}/\#\mbox{\texttt{\mdseries\slshape tagname}}{\textgreater}} pairs. Then the file \mbox{\texttt{\mdseries\slshape main}} is read and all \texttt{{\textless}\#Include ... {\textgreater}}-tags are substituted recursively by other files or chunks of documentation found in the first step, respectively. If the optional argument \mbox{\texttt{\mdseries\slshape info}} is given and set to \texttt{true} this function returns a list \texttt{[str, origin]}, where \texttt{str} is a string containing the composed document and \texttt{origin} is a sorted list of entries of the form \texttt{[pos, filename, line]}. Here \texttt{pos} runs through all character positions of starting lines or text pieces from different files in \texttt{str}. The \texttt{filename} and \texttt{line} describe the origin of this part of the collected document. Without the fourth argument only the string \texttt{str} is returned. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@doc := ComposedDocument("GAPDoc", "/my/dir", "manual.xml", | !gapprompt@>| !gapinput@["../lib/func.gd", "../lib/func.gi"], true);;| \end{Verbatim} } \subsection{\textcolor{Chapter }{OriginalPositionDocument}} \logpage{[ 4, 2, 2 ]}\nobreak \hyperdef{L}{X86D1141E7EDCAAC8}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{OriginalPositionDocument({\mdseries\slshape srcinfo, pos})\index{OriginalPositionDocument@\texttt{OriginalPositionDocument}} \label{OriginalPositionDocument} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } A pair \texttt{[filename, linenumber]}. Here \mbox{\texttt{\mdseries\slshape srcinfo}} must be a data structure as returned as second entry by \texttt{ComposedDocument} (\ref{ComposedDocument}) called with \mbox{\texttt{\mdseries\slshape info}}=\texttt{true}. It returns for a given position \mbox{\texttt{\mdseries\slshape pos}} in the composed document the file name and line number from which that text was collected. } } } \chapter{\textcolor{Chapter }{The Converters and an XML Parser}}\label{ch:conv} \logpage{[ 5, 0, 0 ]} \hyperdef{L}{X845E7FDC7C082CC4}{} { The \textsf{GAPDoc} package contains a set of programs which allow us to convert a \textsf{GAPDoc} book into several output versions and to make them available to \textsf{GAP}'s online help. Currently the following output formats are provided: text for browsing inside a terminal running \textsf{GAP}, {\LaTeX} with \texttt{hyperref}-package for cross references via hyperlinks and HTML for reading with a Web-browser. \section{\textcolor{Chapter }{Producing Documentation from Source Files}}\label{MakeDoc} \logpage{[ 5, 1, 0 ]} \hyperdef{L}{X7D1BB5867C13FA14}{} { Here we explain how to use the functions which are described in more detail in the following sections. We assume that we have the main file \texttt{MyBook.xml} of a book \texttt{"MyBook"} in the directory \texttt{/my/book/path}. This contains \texttt{{\textless}\#Include ...{\textgreater}}-statements as explained in Chapter{\nobreakspace}\ref{Distributing}. These refer to some other files as well as pieces of text which are found in the comments of some \textsf{GAP} source files \texttt{../lib/a.gd} and \texttt{../lib/b.gi} (relative to the path above). A Bib{\TeX} database \texttt{MyBook.bib} for the citations is also in the directory given above. We want to produce a text-, \texttt{pdf-} and HTML-version of the document. (A {\LaTeX} version of the manual is produced, so it is also easy to compile \texttt{dvi}-, and postscript-versions.) All the commands shown in this Section are collected in the single function \texttt{MakeGAPDocDoc} (\ref{MakeGAPDocDoc}). First we construct the complete XML-document as a string with \texttt{ComposedDocument} (\ref{ComposedDocument}). This interprets recursively the \texttt{{\textless}\#Include ...{\textgreater}}-statements. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@path := Directory("/my/book/path");;| !gapprompt@gap>| !gapinput@main := "MyBook.xml";;| !gapprompt@gap>| !gapinput@files := ["../lib/a.gd", "../lib/b.gi"];;| !gapprompt@gap>| !gapinput@bookname := "MyBook";;| !gapprompt@gap>| !gapinput@doc := ComposedDocument("GAPDoc", path, main, files, true);;| \end{Verbatim} Now \texttt{doc} is a list with two entries, the first is a string containing the XML-document, the second gives information from which files and locations which part of the document was collected. This is useful in the next step, if there are any errors in the document. Next we parse the document and store its structure in a tree-like data structure. The commands for this are \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) and \texttt{CheckAndCleanGapDocTree} (\ref{CheckAndCleanGapDocTree}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@r := ParseTreeXMLString(doc[1], doc[2]);;| !gapprompt@gap>| !gapinput@CheckAndCleanGapDocTree(r);| true \end{Verbatim} We start to produce a text version of the manual, which can be read in a terminal (window). The command is \texttt{GAPDoc2Text} (\ref{GAPDoc2Text}). This produces a record with the actual text and some additional information. The text can be written chapter-wise into files with \texttt{GAPDoc2TextPrintTextFiles} (\ref{GAPDoc2TextPrintTextFiles}). The names of these files are \texttt{chap0.txt}, \texttt{chap1.txt} and so on. The text contains some markup using ANSI escape sequences. This markup is substituted by the \textsf{GAP} help system (user configurable) to show the text with colors and other attributes. For the bibliography we have to tell \texttt{GAPDoc2Text} (\ref{GAPDoc2Text}) the location of the Bib{\TeX} database by specifying a \texttt{path} as second argument. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@t := GAPDoc2Text(r, path);;| !gapprompt@gap>| !gapinput@GAPDoc2TextPrintTextFiles(t, path);| \end{Verbatim} This command constructs all parts of the document including table of contents, bibliography and index. The functions \texttt{FormatParagraph} (\ref{FormatParagraph}) for formatting text paragraphs and \texttt{ParseBibFiles} (\ref{ParseBibFiles}) for reading Bib{\TeX} files with \textsf{GAP} may be of independent interest. With the text version we have also produced the information which is used for searching with \textsf{GAP}'s online help. Also, labels are produced which can be used by links in the HTML- and \texttt{pdf}-versions of the manual. Next we produce a {\LaTeX} version of the document. \texttt{GAPDoc2LaTeX} (\ref{GAPDoc2LaTeX}) returns a string containing the {\LaTeX} source. The utility function \texttt{FileString} (\ref{FileString}) writes the content of a string to a file, we choose \texttt{MyBook.tex}. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@l := GAPDoc2LaTeX(r);;| !gapprompt@gap>| !gapinput@FileString(Filename(path, Concatenation(bookname, ".tex")), l);| \end{Verbatim} Assuming that you have a sufficiently good installation of {\TeX} available (see \texttt{GAPDoc2LaTeX} (\ref{GAPDoc2LaTeX}) for details) this can be processed with a series of commands like in the following example. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] cd /my/book/path pdflatex MyBook bibtex MyBook pdflatex MyBook makeindex MyBook pdflatex MyBook mv MyBook.pdf manual.pdf \end{Verbatim} After this we have a \texttt{pdf}-version of the document in the file \texttt{manual.pdf}. It contains hyperlink information which can be used with appropriate browsers for convenient reading of the document on screen (e.g., \texttt{xpdf} is nice because it allows remote calls to display named locations of the document). Of course, we could also use other commands like \texttt{latex} or \texttt{dvips} to process the {\LaTeX} source file. Furthermore we have produced a file \texttt{MyBook.pnr} which is \textsf{GAP}-readable and contains the page number information for each (sub-)section of the document. We can add this page number information to the indexing information collected by the text converter and then print a \texttt{manual.six} file which is read by \textsf{GAP} when the manual is loaded. This is done with \texttt{AddPageNumbersToSix} (\ref{AddPageNumbersToSix}) and \texttt{PrintSixFile} (\ref{PrintSixFile}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@AddPageNumbersToSix(r, Filename(path, "MyBook.pnr"));| !gapprompt@gap>| !gapinput@PrintSixFile(Filename(path, "manual.six"), r, bookname);| \end{Verbatim} Finally we produce an HTML-version of the document and write it (chapter-wise) into files \texttt{chap0.html}, \texttt{chap1.html} and so on. They can be read with any Web-browser. The commands are \texttt{GAPDoc2HTML} (\ref{GAPDoc2HTML}) and \texttt{GAPDoc2HTMLPrintHTMLFiles} (\ref{GAPDoc2HTMLPrintHTMLFiles}). We also add a link from \texttt{manual.html} to \texttt{chap0.html}. You probably want to copy stylesheet files into the same directory, see \ref{StyleSheets} for more details. The argument \texttt{path} of \texttt{GAPDoc2HTML} (\ref{GAPDoc2HTML}) specifies the directory containing the Bib{\TeX} database files. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@h := GAPDoc2HTML(r, path);;| !gapprompt@gap>| !gapinput@GAPDoc2HTMLPrintHTMLFiles(h, path);| \end{Verbatim} \subsection{\textcolor{Chapter }{MakeGAPDocDoc}} \logpage{[ 5, 1, 1 ]}\nobreak \hyperdef{L}{X826F530686F4D052}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MakeGAPDocDoc({\mdseries\slshape path, main, files, bookname[, gaproot]})\index{MakeGAPDocDoc@\texttt{MakeGAPDocDoc}} \label{MakeGAPDocDoc} }\hfill{\scriptsize (function)}}\\ This function collects all the commands for producing a text-, \texttt{pdf}- and HTML-version of a \textsf{GAPDoc} document as described in Section{\nobreakspace}\ref{MakeDoc}. It checks the \texttt{.log} file from the call of \texttt{pdflatex} and reports if there are errors, warnings or overfull boxes. \emph{Note:} If this function works for you depends on your operating system and installed software. It will probably work on most \texttt{UNIX} systems with a standard {\LaTeX} installation. If the function doesn't work for you look at the source code and adjust it to your system. Here \mbox{\texttt{\mdseries\slshape path}} must be the directory (as string or directory object) containing the main file \mbox{\texttt{\mdseries\slshape main}} of the document (given with or without the \texttt{.xml} extension. The argument \mbox{\texttt{\mdseries\slshape files}} is a list of (probably source code) files relative to \mbox{\texttt{\mdseries\slshape path}} which contain pieces of documentation which must be included in the document, see Chapter{\nobreakspace}\ref{Distributing}. And \mbox{\texttt{\mdseries\slshape bookname}} is the name of the book used by \textsf{GAP}'s online help. The optional argument \mbox{\texttt{\mdseries\slshape gaproot}} must be a string which gives the relative path from \mbox{\texttt{\mdseries\slshape path}} to the main \textsf{GAP} root directory. If this is given, the HTML files are produced with relative paths to external books. \index{MathJax@\textsf{MathJax}!in \texttt{MakeGAPDocDoc}} \texttt{MakeGAPDocDoc} can be called with additional arguments \texttt{"MathJax"}, \texttt{"Tth"} and/or \texttt{"MathML"}. If these are given additional variants of the HTML conversion are called, see \texttt{GAPDoc2HTML} (\ref{GAPDoc2HTML}) for details. It is possible to use \textsf{GAPDoc} with other languages than English, see \texttt{SetGapDocLanguage} (\ref{SetGapDocLanguage}) for more details. } } \section{\textcolor{Chapter }{Parsing XML Documents}}\label{ParseXML} \logpage{[ 5, 2, 0 ]} \hyperdef{L}{X7FE2AF49838D9034}{} { Arbitrary well-formed XML documents can be parsed and browsed by the following functions. \subsection{\textcolor{Chapter }{ParseTreeXMLString}} \logpage{[ 5, 2, 1 ]}\nobreak \hyperdef{L}{X847EB8498151D443}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseTreeXMLString({\mdseries\slshape str[, srcinfo][, entitydict]})\index{ParseTreeXMLString@\texttt{ParseTreeXMLString}} \label{ParseTreeXMLString} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseTreeXMLFile({\mdseries\slshape fname[, entitydict]})\index{ParseTreeXMLFile@\texttt{ParseTreeXMLFile}} \label{ParseTreeXMLFile} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a record which is root of a tree structure The first function parses an XML-document stored in string \mbox{\texttt{\mdseries\slshape str}} and returns the document in form of a tree. The optional argument \mbox{\texttt{\mdseries\slshape srcinfo}} must have the same format as in \texttt{OriginalPositionDocument} (\ref{OriginalPositionDocument}). If it is given then error messages refer to the original source of the text with the problem. With the optional argument \mbox{\texttt{\mdseries\slshape entitydict}} named entities can be given to the parser, for example entities which are defined in the \texttt{.dtd}-file (which is not read by this parser). The standard XML-entities do not need to be provided, and for \textsf{GAPDoc} documents the entity definitions from \texttt{gapdoc.dtd} are automatically provided. Entities in the document's \texttt{{\textless}!DOCTYPE} declaration are parsed and also need not to be provided here. The argument \mbox{\texttt{\mdseries\slshape entitydict}} must be a record where each component name is an entity name (without the surrounding \& and ;) to which is assigned its substitution string. The second function is just a shortcut for \texttt{ParseTreeXMLString( StringFile(}\mbox{\texttt{\mdseries\slshape fname}}\texttt{), ... )}, see \texttt{StringFile} (\ref{StringFile}). After these functions return the list of named entities which were known during the parsing can be found in the record \texttt{ENTITYDICT}. A node in the result tree corresponds to an XML element, or to some parsed character data. In the first case it looks as follows: \begin{Verbatim}[fontsize=\small,frame=single,label=Example Node] rec( name := "Book", attributes := rec( Name := "EDIM" ), content := [ ... list of nodes for content ...], start := 312, stop := 15610, next := 15611 ) \end{Verbatim} This means that \texttt{\mbox{\texttt{\mdseries\slshape str}}\texttt{\symbol{123}}[312..15610]\texttt{\symbol{125}}} looks like \texttt{{\textless}Book Name="EDIM"{\textgreater} ... content ... {\textless}/Book{\textgreater}}. The leaves of the tree encode parsed character data as in the following example: \begin{Verbatim}[fontsize=\small,frame=single,label=Example Node] rec( name := "PCDATA", content := "text without markup " ) \end{Verbatim} This function checks whether the XML document is \emph{well formed}, see \ref{XMLvalid} for an explanation. If an error in the XML structure is found, a break loop is entered and the text around the position where the problem starts is shown. With \texttt{Show();} one can browse the original input in the \texttt{Pager} (\textbf{Reference: Pager}), starting with the line where the error occurred. All entities are resolved when they are either entities defined in the \textsf{GAPDoc} package (in particular the standard XML entities) or if their definition is included in the \texttt{{\textless}!DOCTYPE ..{\textgreater}} tag of the document. Note that \texttt{ParseTreeXMLString} does not parse and interpret the corresponding document type definition (the \texttt{.dtd}-file given in the \texttt{{\textless}!DOCTYPE ..{\textgreater}} tag). Hence it also does not check the \emph{validity} of the document (i.e., it is no \emph{validating XML parser}). If you are using this function to parse a \textsf{GAPDoc} document you can use \texttt{CheckAndCleanGapDocTree} (\ref{CheckAndCleanGapDocTree}) for some validation and additional checking of the document structure. } \subsection{\textcolor{Chapter }{StringXMLElement}} \logpage{[ 5, 2, 2 ]}\nobreak \hyperdef{L}{X835887057D0B4DA8}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringXMLElement({\mdseries\slshape tree})\index{StringXMLElement@\texttt{StringXMLElement}} \label{StringXMLElement} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a list \texttt{[string, positions]} The argument \mbox{\texttt{\mdseries\slshape tree}} must have a format of a node in the parse tree of an XML document as returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) (including the root node representing the full document). This function computes a pair \texttt{[string, positions]} where \texttt{string} contains XML code which is equivalent to the code which was parsed to get \mbox{\texttt{\mdseries\slshape tree}}. And \texttt{positions} is a list of lists of four numbers \texttt{[eltb, elte, contb, conte]}. There is one such list for each XML element occuring in \texttt{string}, where \texttt{eltb} and \texttt{elte} are the begin and end position of this element in \texttt{string} and where \texttt{contb} and \texttt{conte} are begin and end position of the content of this element, or both are \texttt{0} if there is no content. Note that parsing XML code is an irreversible task, we can only expect to get equivalent XML code from this function. But parsing the resulting \texttt{string} again and applying \texttt{StringXMLElement} again gives the same result. See the function \texttt{EntitySubstitution} (\ref{EntitySubstitution}) for back-substitutions of entities in the result. } \subsection{\textcolor{Chapter }{EntitySubstitution}} \logpage{[ 5, 2, 3 ]}\nobreak \hyperdef{L}{X786827BF793191B3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{EntitySubstitution({\mdseries\slshape xmlstring, entities})\index{EntitySubstitution@\texttt{EntitySubstitution}} \label{EntitySubstitution} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string The argument \mbox{\texttt{\mdseries\slshape xmlstring}} must be a string containing XML code or a pair \texttt{[string, positions]} as returned by \texttt{StringXMLElement} (\ref{StringXMLElement}). The argument \mbox{\texttt{\mdseries\slshape entities}} specifies entity names (without the surrounding \mbox{\texttt{\mdseries\slshape \&}} and \texttt{;}) and their substitution strings, either a list of pairs of strings or as a record with the names as components and the substitutions as values. This function tries to substitute non-intersecting parts of \texttt{string} by the given entities. If the \texttt{positions} information is given then only parts of the document which allow a valid substitution by an entity are considered. Otherwise a simple text substitution without further check is done. Note that in general the entity resolution in XML documents is a complicated and non-reversible task. But nevertheless this utility may be useful in not too complicated situations. } \subsection{\textcolor{Chapter }{DisplayXMLStructure}} \logpage{[ 5, 2, 4 ]}\nobreak \hyperdef{L}{X86589C5C859ACE38}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DisplayXMLStructure({\mdseries\slshape tree})\index{DisplayXMLStructure@\texttt{DisplayXMLStructure}} \label{DisplayXMLStructure} }\hfill{\scriptsize (function)}}\\ This utility displays the tree structure of an XML document as it is returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) (without the \texttt{PCDATA} leaves). Since this is usually quite long the result is shown using the \texttt{Pager} (\textbf{Reference: Pager}). } \subsection{\textcolor{Chapter }{ApplyToNodesParseTree}} \logpage{[ 5, 2, 5 ]}\nobreak \hyperdef{L}{X7A7B223A83E38B40}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ApplyToNodesParseTree({\mdseries\slshape tree, fun})\index{ApplyToNodesParseTree@\texttt{ApplyToNodesParseTree}} \label{ApplyToNodesParseTree} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AddRootParseTree({\mdseries\slshape tree})\index{AddRootParseTree@\texttt{AddRootParseTree}} \label{AddRootParseTree} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RemoveRootParseTree({\mdseries\slshape tree})\index{RemoveRootParseTree@\texttt{RemoveRootParseTree}} \label{RemoveRootParseTree} }\hfill{\scriptsize (function)}}\\ The function \texttt{ApplyToNodesParseTree} applies a function \mbox{\texttt{\mdseries\slshape fun}} to all nodes of the parse tree \mbox{\texttt{\mdseries\slshape tree}} of an XML document returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}). The function \texttt{AddRootParseTree} is an application of this. It adds to all nodes a component \texttt{.root} to which the top node tree \mbox{\texttt{\mdseries\slshape tree}} is assigned. These components can be removed afterwards with \texttt{RemoveRootParseTree}. } Here are two more utilities which use \texttt{ApplyToNodesParseTree} (\ref{ApplyToNodesParseTree}). \subsection{\textcolor{Chapter }{GetTextXMLTree}} \logpage{[ 5, 2, 6 ]}\nobreak \hyperdef{L}{X7F76D4A27C7FB946}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GetTextXMLTree({\mdseries\slshape tree})\index{GetTextXMLTree@\texttt{GetTextXMLTree}} \label{GetTextXMLTree} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string The argument \mbox{\texttt{\mdseries\slshape tree}} must be a node of a parse tree of some XML document, see \texttt{ParseTreeXMLFile} (\ref{ParseTreeXMLFile}). This function collects the content of this and all included elements recursively into a string. } \subsection{\textcolor{Chapter }{XMLElements}} \logpage{[ 5, 2, 7 ]}\nobreak \hyperdef{L}{X8466F74C80442F7D}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{XMLElements({\mdseries\slshape tree, eltnames})\index{XMLElements@\texttt{XMLElements}} \label{XMLElements} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a list of nodes The argument \mbox{\texttt{\mdseries\slshape tree}} must be a node of a parse tree of some XML document, see \texttt{ParseTreeXMLFile} (\ref{ParseTreeXMLFile}). This function returns a list of all subnodes of \mbox{\texttt{\mdseries\slshape tree}} (possibly including \mbox{\texttt{\mdseries\slshape tree}}) of elements with name given in the list of strings \mbox{\texttt{\mdseries\slshape eltnames}}. Use \texttt{"PCDATA"} as name for leave nodes which contain the actual text of the document. As an abbreviation \mbox{\texttt{\mdseries\slshape eltnames}} can also be a string which is then put in a one element list. } And here are utilities for processing \textsf{GAPDoc} XML documents. \subsection{\textcolor{Chapter }{CheckAndCleanGapDocTree}} \logpage{[ 5, 2, 8 ]}\nobreak \hyperdef{L}{X84CFF72484B19C0D}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{CheckAndCleanGapDocTree({\mdseries\slshape tree})\index{CheckAndCleanGapDocTree@\texttt{CheckAndCleanGapDocTree}} \label{CheckAndCleanGapDocTree} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The argument \mbox{\texttt{\mdseries\slshape tree}} of this function is a parse tree from \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) of some \textsf{GAPDoc} document. This function does an (incomplete) validity check of the document according to the document type declaration in \texttt{gapdoc.dtd}. It also does some additional checks which cannot be described in the DTD (like checking whether chapters and sections have a heading). For elements with element content the whitespace between these elements is removed. In case of an error the break loop is entered and the position of the error in the original XML document is printed. With \texttt{Show();} one can browse the original input in the \texttt{Pager} (\textbf{Reference: Pager}). } \subsection{\textcolor{Chapter }{AddParagraphNumbersGapDocTree}} \logpage{[ 5, 2, 9 ]}\nobreak \hyperdef{L}{X84062CD67B286FF0}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AddParagraphNumbersGapDocTree({\mdseries\slshape tree})\index{AddParagraphNumbersGapDocTree@\texttt{AddParagraphNumbersGapDocTree}} \label{AddParagraphNumbersGapDocTree} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The argument \mbox{\texttt{\mdseries\slshape tree}} must be an XML tree returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) applied to a \textsf{GAPDoc} document. This function adds to each node of the tree a component \texttt{.count} which is of form \texttt{[Chapter[, Section[, Subsection, Paragraph] ] ]}. Here the first three numbers should be the same as produced by the {\LaTeX} version of the document. Text before the first chapter is counted as chapter \texttt{0} and similarly for sections and subsections. Some elements are always considered to start a new paragraph. } \subsection{\textcolor{Chapter }{InfoXMLParser}} \logpage{[ 5, 2, 10 ]}\nobreak \hyperdef{L}{X78A22C58841E5D0B}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InfoXMLParser\index{InfoXMLParser@\texttt{InfoXMLParser}} \label{InfoXMLParser} }\hfill{\scriptsize (info class)}}\\ The default level of this info class is 1. Functions like \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) are then printing some information, in particular in case of errors. You can suppress it by setting the level of \texttt{InfoXMLParser} to 0. With level 2 there may be some more information for debugging purposes. } } \section{\textcolor{Chapter }{The Converters}}\label{Converters} \logpage{[ 5, 3, 0 ]} \hyperdef{L}{X8560E1A2845EC2C1}{} { Here are more details about the conversion programs for \textsf{GAPDoc} XML documents. \subsection{\textcolor{Chapter }{GAPDoc2LaTeX}} \logpage{[ 5, 3, 1 ]}\nobreak \hyperdef{L}{X85BE6DF178423EF5}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GAPDoc2LaTeX({\mdseries\slshape tree})\index{GAPDoc2LaTeX@\texttt{GAPDoc2LaTeX}} \label{GAPDoc2LaTeX} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } {\LaTeX} document as string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SetGapDocLaTeXOptions({\mdseries\slshape [...]})\index{SetGapDocLaTeXOptions@\texttt{SetGapDocLaTeXOptions}} \label{SetGapDocLaTeXOptions} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } Nothing The argument \mbox{\texttt{\mdseries\slshape tree}} for this function is a tree describing a \textsf{GAPDoc} XML document as returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) (probably also checked with \texttt{CheckAndCleanGapDocTree} (\ref{CheckAndCleanGapDocTree})). The output is a string containing a version of the document which can be written to a file and processed with {\LaTeX} or pdf{\LaTeX} (and probably Bib{\TeX} and \texttt{makeindex}). The output uses the \texttt{report} document class and needs the following {\LaTeX} packages: \texttt{a4wide}, \texttt{amssymb}, \texttt{inputenc}, \texttt{makeidx}, \texttt{color}, \texttt{fancyvrb}, \texttt{psnfss}, \texttt{pslatex}, \texttt{enumitem} and \texttt{hyperref}. These are for example provided by the \textsf{teTeX-1.0} or \textsf{texlive} distributions of {\TeX} (which in turn are used for most {\TeX} packages of current Linux distributions); see \href{http://www.tug.org/tetex/} {\texttt{http://www.tug.org/tetex/}}. In particular, the resulting \texttt{pdf}-output (and \texttt{dvi}-output) contains (internal and external) hyperlinks which can be very useful for onscreen browsing of the document. The {\LaTeX} processing also produces a file with extension \texttt{.pnr} which is \textsf{GAP} readable and contains the page numbers for all (sub)sections of the document. This can be used by \textsf{GAP}'s online help; see \texttt{AddPageNumbersToSix} (\ref{AddPageNumbersToSix}). Non-ASCII characters in the \textsf{GAPDoc} document are translated to {\LaTeX} input in ASCII-encoding with the help of \texttt{Encode} (\ref{Encode}) and the option \texttt{"LaTeX"}. See the documentation of \texttt{Encode} (\ref{Encode}) for how to proceed if you have a character which is not handled (yet). This function works by running recursively through the document tree and calling a handler function for each \textsf{GAPDoc} XML element. Many of these handler functions (usually in \texttt{GAPDoc2LaTeXProcs.{\textless}ElementName{\textgreater}}) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust layout details to your own taste by slight modifications of the program. Former versions of \textsf{GAPDoc} supported some XML processing instructions to add some extra lines to the preamble of the {\LaTeX} document. Its use is now deprecated, use the much more flexible \texttt{SetGapDocLaTeXOptions} instead: The default layout of the resulting documents can be changed with \texttt{SetGapDocLaTeXOptions}. This changes parts of the header of the {\LaTeX} file produced by \textsf{GAPDoc}. You can see the header with some placeholders by \texttt{Page(GAPDoc2LaTeXProcs.Head);}. The placeholders are filled with components from the record \texttt{GAPDoc2LaTeXProcs.DefaultOptions}. The arguments of \texttt{SetGapDocLaTeXOptions} can be records with the same structure (or parts of it) with different values. As abbreviations there are also three strings supported as arguments. These are \texttt{"nocolor"} for switching all colors to black; then \texttt{"nopslatex"} to use standard {\LaTeX} fonts instead of postscript fonts; and finally \texttt{"utf8"} to choose UTF-8 as input encoding for the {\LaTeX} document. } \subsection{\textcolor{Chapter }{GAPDoc2Text}} \logpage{[ 5, 3, 2 ]}\nobreak \hyperdef{L}{X86CD0B197CD58D2A}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GAPDoc2Text({\mdseries\slshape tree[, bibpath][, width]})\index{GAPDoc2Text@\texttt{GAPDoc2Text}} \label{GAPDoc2Text} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } record containing text files as strings and other information The argument \mbox{\texttt{\mdseries\slshape tree}} for this function is a tree describing a \textsf{GAPDoc} XML document as returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) (probably also checked with \texttt{CheckAndCleanGapDocTree} (\ref{CheckAndCleanGapDocTree})). This function produces a text version of the document which can be used with \textsf{GAP}'s online help (with the \texttt{"screen"} viewer, see \texttt{SetHelpViewer} (\textbf{Reference: SetHelpViewer})). It includes title page, bibliography and index. The bibliography is made from BibXMLext or Bib{\TeX} databases, see \ref{ch:bibutil}. Their location must be given with the argument \mbox{\texttt{\mdseries\slshape bibpath}} (as string or directory object). The output is a record with one component for each chapter (with names \texttt{"0"}, \texttt{"1"}, ..., \texttt{"Bib"} and \texttt{"Ind"}). Each such component is again a record with the following components: \begin{description} \item[{\texttt{text}}] the text of the whole chapter as a string \item[{\texttt{ssnr}}] list of subsection numbers in this chapter (like \texttt{[3, 2, 1]} for chapter{\nobreakspace}3, section{\nobreakspace}2, subsection{\nobreakspace}1) \item[{\texttt{linenr}}] corresponding list of line numbers where the subsections start \item[{\texttt{len}}] number of lines of this chapter \end{description} The result can be written into files with the command \texttt{GAPDoc2TextPrintTextFiles} (\ref{GAPDoc2TextPrintTextFiles}). As a side effect this function also produces the \texttt{manual.six} information which is used for searching in \textsf{GAP}'s online help. This is stored in \texttt{\mbox{\texttt{\mdseries\slshape tree}}.six} and can be printed into a \texttt{manual.six} file with \texttt{PrintSixFile} (\ref{PrintSixFile}) (preferably after producing a {\LaTeX} version of the document as well and adding the page number information to \texttt{\mbox{\texttt{\mdseries\slshape tree}}.six}, see \texttt{GAPDoc2LaTeX} (\ref{GAPDoc2LaTeX}) and \texttt{AddPageNumbersToSix} (\ref{AddPageNumbersToSix})). The text produced by this function contains some markup via ANSI escape sequences. The sequences used here are usually ignored by terminals. But the \textsf{GAP} help system will substitute them by interpreted color and attribute sequences (see \texttt{TextAttr} (\ref{TextAttr})) before displaying them. There is a default markup used for this but it can also be configured by the user, see \texttt{SetGAPDocTextTheme} (\ref{SetGAPDocTextTheme}). Furthermore, the text produced is in UTF-8 encoding. The encoding is also translated on the fly, if \texttt{GAPInfo.TermEncoding} is set to some encoding supported by \texttt{Encode} (\ref{Encode}), e.g., \texttt{"ISO-8859-1"} or \texttt{"latin1"}. With the optional argument \mbox{\texttt{\mdseries\slshape width}} a different length of the output text lines can be chosen. The default is 76 and all lines in the resulting text start with two spaces. This looks good on a terminal with a standard width of 80 characters and you probably don't want to use this argument. } \subsection{\textcolor{Chapter }{GAPDoc2TextPrintTextFiles}} \logpage{[ 5, 3, 3 ]}\nobreak \hyperdef{L}{X7DFCE7357D6032A2}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GAPDoc2TextPrintTextFiles({\mdseries\slshape t[, path]})\index{GAPDoc2TextPrintTextFiles@\texttt{GAPDoc2TextPrintTextFiles}} \label{GAPDoc2TextPrintTextFiles} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The first argument must be a result returned by \texttt{GAPDoc2Text} (\ref{GAPDoc2Text}). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name \texttt{chap0.txt}, \texttt{chap1.txt}, ..., \texttt{chapBib.txt}, and \texttt{chapInd.txt}. If you want to make your document accessible via the \textsf{GAP} online help you must put at least these files for the text version into a directory, together with the file \texttt{manual.six}, see \texttt{PrintSixFile} (\ref{PrintSixFile}). Then specify the path to the \texttt{manual.six} file in the packages \texttt{PackageInfo.g} file, see (\textbf{Reference: The PackageInfo.g File}). Optionally you can add the \texttt{dvi}- and \texttt{pdf}-versions of the document which are produced with \texttt{GAPDoc2LaTeX} (\ref{GAPDoc2LaTeX}) to this directory. The files must have the names \texttt{manual.dvi} and \texttt{manual.pdf}, respectively. Also you can add the files of the HTML version produced with \texttt{GAPDoc2HTML} (\ref{GAPDoc2HTML}) to this directory, see \texttt{GAPDoc2HTMLPrintHTMLFiles} (\ref{GAPDoc2HTMLPrintHTMLFiles}). The handler functions in \textsf{GAP} for this help format detect automatically which of the optional formats of a book are actually available. } \subsection{\textcolor{Chapter }{AddPageNumbersToSix}} \logpage{[ 5, 3, 4 ]}\nobreak \hyperdef{L}{X7EB5E86F87A09F94}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AddPageNumbersToSix({\mdseries\slshape tree, pnrfile})\index{AddPageNumbersToSix@\texttt{AddPageNumbersToSix}} \label{AddPageNumbersToSix} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing Here \mbox{\texttt{\mdseries\slshape tree}} must be the XML tree of a \textsf{GAPDoc} document, returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}). Running \texttt{latex} on the result of \texttt{GAPDoc2LaTeX(\mbox{\texttt{\mdseries\slshape tree}})} produces a file \mbox{\texttt{\mdseries\slshape pnrfile}} (with extension \texttt{.pnr}). The command \texttt{GAPDoc2Text(\mbox{\texttt{\mdseries\slshape tree}})} creates a component \texttt{\mbox{\texttt{\mdseries\slshape tree}}.six} which contains all information about the document for the \textsf{GAP} online help, except the page numbers in the \texttt{.dvi, .ps, .pdf} versions of the document. This command adds the missing page number information to \texttt{\mbox{\texttt{\mdseries\slshape tree}}.six}. } \subsection{\textcolor{Chapter }{PrintSixFile}} \logpage{[ 5, 3, 5 ]}\nobreak \hyperdef{L}{X7D42CFED7885BC00}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PrintSixFile({\mdseries\slshape tree, bookname, fname})\index{PrintSixFile@\texttt{PrintSixFile}} \label{PrintSixFile} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This function prints the \texttt{.six} file \mbox{\texttt{\mdseries\slshape fname}} for a \textsf{GAPDoc} document stored in \mbox{\texttt{\mdseries\slshape tree}} with name \mbox{\texttt{\mdseries\slshape bookname}}. Such a file contains all information about the book which is needed by the \textsf{GAP} online help. This information must first be created by calls of \texttt{GAPDoc2Text} (\ref{GAPDoc2Text}) and \texttt{AddPageNumbersToSix} (\ref{AddPageNumbersToSix}). } \subsection{\textcolor{Chapter }{SetGAPDocTextTheme}} \logpage{[ 5, 3, 6 ]}\nobreak \hyperdef{L}{X7DEB37417BBD8941}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SetGAPDocTextTheme({\mdseries\slshape [optrec1[, optrec2], ...]})\index{SetGAPDocTextTheme@\texttt{SetGAPDocTextTheme}} \label{SetGAPDocTextTheme} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This utility function is for readers of the screen version of \textsf{GAP} manuals which are generated by the \textsf{GAPDoc} package. It allows to configure the color and attribute layout of the displayed text. There is a default which can be reset by calling this function without argument. As an abbreviation the arguments \mbox{\texttt{\mdseries\slshape optrec1}} and so on can be strings for the known name of a theme. Information about valid names is shown with \texttt{SetGAPDocTextTheme("");}. Otherwise, \mbox{\texttt{\mdseries\slshape optrec1}} and so on must be a record. Its entries overwrite the corresponding entries in the default and in previous arguments. To construct valid markup you can use \texttt{TextAttr} (\ref{TextAttr}). Entries must be either pairs of strings, which are put before and after the corresponding text, or as an abbreviation it can be a single string. In the latter case, the second string is implied; if the string contains an escape sequence the second string is \texttt{TextAttr.reset}, otherwise the given string is used. The following components are recognized: \begin{description} \item[{\texttt{flush}}] \texttt{"both"} for left-right justified paragraphs, and \texttt{"left"} for ragged right ones \item[{\texttt{Heading}}] chapter and (sub-)section headings \item[{\texttt{Func}}] function, operation, ... names \item[{\texttt{Arg}}] argument names in descriptions \item[{\texttt{Example}}] example code \item[{\texttt{Package}}] package names \item[{\texttt{Returns}}] Returns-line in descriptions \item[{\texttt{URL}}] URLs \item[{\texttt{Mark}}] Marks in description lists \item[{\texttt{K}}] \textsf{GAP} keywords \item[{\texttt{C}}] code or text to type \item[{\texttt{F}}] file names \item[{\texttt{B}}] buttons \item[{\texttt{M}}] simplified math elements \item[{\texttt{Math}}] normal math elements \item[{\texttt{Display}}] displayed math elements \item[{\texttt{Emph}}] emphasized text \item[{\texttt{Q}}] quoted text \item[{\texttt{Ref}}] reference text \item[{\texttt{Prompt}}] \textsf{GAP} prompt in examples \item[{\texttt{BrkPrompt}}] \textsf{GAP} break prompt in examples \item[{\texttt{GAPInput}}] \textsf{GAP} input in examples \item[{\texttt{reset}}] reset to default, don't change this \item[{\texttt{BibAuthor}}] author names in bibliography \item[{\texttt{BibTitle}}] titles in bibliography \item[{\texttt{BibJournal}}] journal names in bibliography \item[{\texttt{BibVolume}}] volume number in bibliography \item[{\texttt{BibLabel}}] labels for bibliography entries \item[{\texttt{BibReset}}] reset for bibliography, don't change \item[{\texttt{ListBullet}}] bullet for simple lists (2 visible characters long) \item[{\texttt{EnumMarks}}] one visible character before and after the number in enumerated lists \item[{\texttt{DefLineMarker}}] marker before function and variable definitions (2 visible characters long) \item[{\texttt{FillString}}] for filling in definitions and example separator lines \end{description} \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@# use no colors for GAP examples and | !gapprompt@gap>| !gapinput@# change display of headings to bold green| !gapprompt@gap>| !gapinput@SetGAPDocTextTheme("noColorPrompt", | !gapprompt@>| !gapinput@ rec(Heading:=Concatenation(TextAttr.bold, TextAttr.2)));| \end{Verbatim} } \subsection{\textcolor{Chapter }{GAPDoc2HTML}} \logpage{[ 5, 3, 7 ]}\nobreak \hyperdef{L}{X84F22EEB78845CFD}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GAPDoc2HTML({\mdseries\slshape tree[, bibpath[, gaproot]][, mtrans]})\index{GAPDoc2HTML@\texttt{GAPDoc2HTML}} \label{GAPDoc2HTML} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } record containing HTML files as strings and other information \index{MathJax@\textsf{MathJax}} The argument \mbox{\texttt{\mdseries\slshape tree}} for this function is a tree describing a \textsf{GAPDoc} XML document as returned by \texttt{ParseTreeXMLString} (\ref{ParseTreeXMLString}) (probably also checked with \texttt{CheckAndCleanGapDocTree} (\ref{CheckAndCleanGapDocTree})). Without an \mbox{\texttt{\mdseries\slshape mtrans}} argument this function produces an HTML version of the document which can be read with any Web-browser and also be used with \textsf{GAP}'s online help (see \texttt{SetHelpViewer} (\textbf{Reference: SetHelpViewer})). It includes title page, bibliography, and index. The bibliography is made from Bib{\TeX} databases. Their location must be given with the argument \mbox{\texttt{\mdseries\slshape bibpath}} (as string or directory object, if not given the current directory is used). If the third argument \mbox{\texttt{\mdseries\slshape gaproot}} is given and is a string then this string is interpreted as relative path to \textsf{GAP}'s main root directory. Reference-URLs to external HTML-books which begin with the \textsf{GAP} root path are then rewritten to start with the given relative path. This makes the HTML-documentation portable provided a package is installed in some standard location below the \textsf{GAP} root. The output is a record with one component for each chapter (with names \texttt{"0"}, \texttt{"1"}, ..., \texttt{"Bib"}, and \texttt{"Ind"}). Each such component is again a record with the following components: \begin{description} \item[{\texttt{text}}] the text of an HTML file containing the whole chapter (as a string) \item[{\texttt{ssnr}}] list of subsection numbers in this chapter (like \texttt{[3, 2, 1]} for chapter{\nobreakspace}3, section{\nobreakspace}2, subsection{\nobreakspace}1) \end{description} \emph{Standard output format without} \mbox{\texttt{\mdseries\slshape mtrans}} \emph{argument} The HTML code produced with this converter conforms to the W3C specification ``XHTML 1.0 strict'', see \href{http://www.w3.org/TR/xhtml1} {\texttt{http://www.w3.org/TR/xhtml1}}. First, this means that the HTML files are valid XML files. Secondly, the extension ``strict'' says in particular that the code doesn't contain any explicit font or color information. Mathematical formulae are handled as in the text converter \texttt{GAPDoc2Text} (\ref{GAPDoc2Text}). We don't want to assume that the browser can use symbol fonts. Some \textsf{GAP} users like to browse the online help with \texttt{lynx}, see \texttt{SetHelpViewer} (\textbf{Reference: SetHelpViewer}), which runs inside the same terminal windows as \textsf{GAP}. To view the generated files in graphical browsers, stylesheet files with layout configuration should be copied into the directory with the generated HTML files, see \ref{StyleSheets}. \label{mtransarg} \emph{Output format with} \mbox{\texttt{\mdseries\slshape mtrans}} argument Currently, there are three variants of this converter available which handle mathematical formulae differently. They are accessed via the optional last \mbox{\texttt{\mdseries\slshape mtrans}} argument. If \mbox{\texttt{\mdseries\slshape mtrans}} is set to \texttt{"MathJax"} the formulae are essentially translated as for {\LaTeX} documents (there is no processing of \texttt{{\textless}M{\textgreater}} elements as decribed in \ref{M}). Inline formulae are delimited by \texttt{\texttt{\symbol{92}}(} and \texttt{\texttt{\symbol{92}})} and displayed formulae by \texttt{\texttt{\symbol{92}}[} and \texttt{\texttt{\symbol{92}}]}. With \textsf{MathJax} webpages can contain nicely formatted scalable and searchable formulae. The resulting files link by default to \href{http://cdn.mathjax.org} {http://cdn.mathjax.org} to get the \textsf{MathJax} script and fonts. This means that they can only be used on computers with internet access. An alternative URL can be set by overwriting \texttt{GAPDoc2HTMLProcs.MathJaxURL} before building the HTML version of a manual. This way a local installation of \textsf{MathJax} could be used. See \href{http://www.mathjax.org/} {http://www.mathjax.org/} for more details. The following possibilities for \mbox{\texttt{\mdseries\slshape mtrans}} are still supported, but since the \textsf{MathJax} approach seems much better, their use is deprecated. If the argument \mbox{\texttt{\mdseries\slshape mtrans}} is set to \texttt{"Tth"} it is assumed that you have installed the {\LaTeX} to HTML translation program \texttt{tth}. This is used to translate the contents of the \texttt{M}, \texttt{Math} and \texttt{Display} elements into HTML code. Note that the resulting code is not compliant with any standard. Formally it is ``XHTML 1.0 Transitional'', it contains explicit font specifications and the characters of mathematical symbols are included via their position in a ``Symbol'' font. Some graphical browsers can be configured to display this in a useful manner, check \href{http://hutchinson.belmont.ma.us/tth/} {the Tth homepage} for more details. If the \mbox{\texttt{\mdseries\slshape mtrans}} argument is set to \texttt{"MathML"} it is assumed that you have installed the translation program \texttt{ttm}, see also \href{http://hutchinson.belmont.ma.us/tth/} {the Tth homepage}). This is used to translate the contents of the \texttt{M}, \texttt{Math} and \texttt{Display} elements to MathML 2.0 markup. The resulting files should conform to the "XHTML 1.1 plus MathML 2.0" standard, see \href{http://www.w3.org/TR/MathML2/} {the W3C information} for more details. It is expected that the next generation of graphical browsers will be able to render such files (try for example \texttt{Mozilla}, at least 0.9.9). You must copy the \texttt{.xsl} and \texttt{.css} files from \textsf{GAPDoc}s \texttt{mathml} directory to the directory containing the output files. The translation with \texttt{ttm} is still experimental. The output of this converter variant is garbage for browsers which don't support MathML. This function works by running recursively through the document tree and calling a handler function for each \textsf{GAPDoc} XML element. Many of these handler functions (usually in \texttt{GAPDoc2TextProcs.{\textless}ElementName{\textgreater}}) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust certain details to your own taste by slight modifications of the program. The result of this converter can be written to files with the command \texttt{GAPDoc2HTMLPrintHTMLFiles} (\ref{GAPDoc2HTMLPrintHTMLFiles}). There are two user preferences for reading the HTML manuals produced by \textsf{GAPDoc}. A user can choose among several style files which determine the appearance of the manual pages with \texttt{SetUserPreference("GAPDoc", "HTMLStyle", [...]);} where the list in the third argument are arguments for \texttt{SetGAPDocHTMLStyle} (\ref{SetGAPDocHTMLStyle}). The second preference is set by \texttt{SetUserPreference("GAPDoc", "UseMathJax", ...);} where the third argument is \texttt{true} or \texttt{false} (default). If this is set to \texttt{true}, the \textsf{GAP} help system displays the \textsf{MathJax} version of the HTML manuals. } \subsection{\textcolor{Chapter }{GAPDoc2HTMLPrintHTMLFiles}} \logpage{[ 5, 3, 8 ]}\nobreak \hyperdef{L}{X84A7007778073E7A}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{GAPDoc2HTMLPrintHTMLFiles({\mdseries\slshape t[, path]})\index{GAPDoc2HTMLPrintHTMLFiles@\texttt{GAPDoc2HTMLPrintHTMLFiles}} \label{GAPDoc2HTMLPrintHTMLFiles} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The first argument must be a result returned by \texttt{GAPDoc2HTML} (\ref{GAPDoc2HTML}). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name \texttt{chap0.html}, \texttt{chap1.html}, ..., \texttt{chapBib.html}, and \texttt{chapInd.html}. The \textsf{MathJax} versions are written to files \texttt{chap0{\textunderscore}mj.html}, ..., \texttt{chapInd{\textunderscore}mj.html}. The experimental versions which are produced with \texttt{tth} or \texttt{ttm} use different names for the files, namely \texttt{chap0{\textunderscore}sym.html}, and so on for files which need symbol fonts and \texttt{chap0{\textunderscore}mml.xml} for files with MathML translations. You should also add stylesheet files to the directory with the HTML files, see \ref{StyleSheets}. } \subsection{\textcolor{Chapter }{Stylesheet files}}\label{StyleSheets} \logpage{[ 5, 3, 9 ]} \hyperdef{L}{X788AB14383272FDB}{} { \index{CSS stylesheets} For graphical browsers the layout of the generated HTML manuals can be highly configured by cascading stylesheet (CSS) and javascript files. Such files are provided in the \texttt{styles} directory of the \textsf{GAPDoc} package. We recommend that these files are copied into each manual directory (such that each of them is selfcontained). There is a utility function \texttt{CopyHTMLStyleFiles} (\ref{CopyHTMLStyleFiles}) which does this. Of course, these files may be changed or new styles may be added. New styles may also be sent to the \textsf{GAPDoc} authors for possible inclusion in future versions. The generated HTML files refer to the file \texttt{manual.css} which conforms to the W3C specification CSS 2.0, see \href{http://www.w3.org/TR/REC-CSS2} {\texttt{http://www.w3.org/TR/REC-CSS2}}, and the javascript file \texttt{manual.js} (only in browsers which support CSS or javascript, respectively; but the HTML files are also readable without any of them). To add a style \texttt{mystyle} one or both of \texttt{mystyle.css} and \texttt{mystyle.js} must be provided; these can overwrite default settings and add new javascript functions. For more details see the comments in \texttt{manual.js}. } \subsection{\textcolor{Chapter }{CopyHTMLStyleFiles}} \logpage{[ 5, 3, 10 ]}\nobreak \hyperdef{L}{X813599E982DE9B98}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{CopyHTMLStyleFiles({\mdseries\slshape dir})\index{CopyHTMLStyleFiles@\texttt{CopyHTMLStyleFiles}} \label{CopyHTMLStyleFiles} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This utility function copies the \texttt{*.css} and \texttt{*.js} files from the \texttt{styles} directory of the \textsf{GAPDoc} package into the directory \mbox{\texttt{\mdseries\slshape dir}}. } \subsection{\textcolor{Chapter }{SetGAPDocHTMLStyle}} \logpage{[ 5, 3, 11 ]}\nobreak \hyperdef{L}{X85AFD98383174BB5}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SetGAPDocHTMLStyle({\mdseries\slshape [style1[, style2], ...]})\index{SetGAPDocHTMLStyle@\texttt{SetGAPDocHTMLStyle}} \label{SetGAPDocHTMLStyle} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This utility function is for readers of the HTML version of \textsf{GAP} manuals which are generated by the \textsf{GAPDoc} package. It allows to configure the display style of the manuals. This will only have an effect if you are using a browser that supports \textsf{javascript}. There is a default which can be reset by calling this function without argument. The arguments \mbox{\texttt{\mdseries\slshape style1}} and so on must be strings. You can find out about the valid strings by following the \textsc{[Style]} link on top of any manual page. (Going back to the original page, its address has a setting for \texttt{GAPDocStyle} which is the list of strings, separated by commas, you want to use here.) \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@# show/hide subsections in tables on contents only after click,| !gapprompt@gap>| !gapinput@# and don't use colors in GAP examples| !gapprompt@gap>| !gapinput@SetGAPDocHTMLStyle("toggless", "nocolorprompt");| \end{Verbatim} } \subsection{\textcolor{Chapter }{InfoGAPDoc}} \logpage{[ 5, 3, 12 ]}\nobreak \hyperdef{L}{X864A528B81C661A2}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InfoGAPDoc\index{InfoGAPDoc@\texttt{InfoGAPDoc}} \label{InfoGAPDoc} }\hfill{\scriptsize (info class)}}\\ The default level of this info class is 1. The converter functions for \textsf{GAPDoc} documents are then printing some information. You can suppress this by setting the level of \texttt{InfoGAPDoc} to 0. With level 2 there may be some more information for debugging purposes. } \subsection{\textcolor{Chapter }{SetGapDocLanguage}} \logpage{[ 5, 3, 13 ]}\nobreak \hyperdef{L}{X82AB468887ED0DBB}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SetGapDocLanguage({\mdseries\slshape [lang]})\index{SetGapDocLanguage@\texttt{SetGapDocLanguage}} \label{SetGapDocLanguage} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing \index{Using \textsf{GAPDoc} with other languages} The \textsf{GAPDoc} converter programs sometimes produce text which is not explicit in the document, e.g., headers like ``Abstract'', ``Appendix'', links to ``Next Chapter'', variable types ``function'' and so on. With \texttt{SetGapDocLanguage} the language for these texts can be changed. The argument \mbox{\texttt{\mdseries\slshape lang}} must be a string. Calling without argument or with a language name for which no translations are available is the same as using the default \texttt{"english"}. If your language \mbox{\texttt{\mdseries\slshape lang}} is not yet available, look at the record \texttt{GAPDocTexts.english} and translate all the strings to \mbox{\texttt{\mdseries\slshape lang}}. Then assign this record to \texttt{GAPDocTexts.(\mbox{\texttt{\mdseries\slshape lang}})} and send it to the \textsf{GAPDoc} authors for inclusion in future versions of \textsf{GAPDoc}. (Currently, there are translations for \texttt{english}, \texttt{german}, \texttt{russian} and \texttt{ukrainian}.) \emph{Further hints:} To get strings produced by {\LaTeX} right you will probably use the \texttt{babel} package with option \mbox{\texttt{\mdseries\slshape lang}}, see the information on \texttt{ExtraPreamble} in \texttt{GAPDoc2LaTeX} (\ref{GAPDoc2LaTeX}). If \mbox{\texttt{\mdseries\slshape lang}} cannot be encoded in \texttt{latin1} encoding you can consider the use of \texttt{"utf8"} with \texttt{SetGapDocLaTeXOptions} (\ref{SetGapDocLaTeXOptions}). } } \section{\textcolor{Chapter }{Testing Manual Examples}}\label{Sec:TestExample} \logpage{[ 5, 4, 0 ]} \hyperdef{L}{X800299827B88ABBE}{} { \index{\texttt{ManualExamples}} \index{\texttt{TestManualExamples}} We also provide some tools to check and adjust the examples given in \texttt{{\textless}Example{\textgreater}}-elements. Former versions of \textsf{GAPDoc} provided functions \texttt{ManualExamples} and \texttt{TestManualExamples}. These functions are still available, but no longer documented. Their use is deprecated. \subsection{\textcolor{Chapter }{ExtractExamples}} \logpage{[ 5, 4, 1 ]}\nobreak \hyperdef{L}{X8337B2BC79253B3F}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ExtractExamples({\mdseries\slshape path, main, files, units})\index{ExtractExamples@\texttt{ExtractExamples}} \label{ExtractExamples} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a list of lists \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ExtractExamplesXMLTree({\mdseries\slshape tree, units})\index{ExtractExamplesXMLTree@\texttt{ExtractExamplesXMLTree}} \label{ExtractExamplesXMLTree} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a list of lists The argument \mbox{\texttt{\mdseries\slshape tree}} must be a parse tree of a \textsf{GAPDoc} document, see \texttt{ParseTreeXMLFile} (\ref{ParseTreeXMLFile}). The function \texttt{ExtractExamplesXMLTree} returns a data structure representing the \texttt{{\textless}Example{\textgreater}} elements of the document. The return value can be used with \texttt{RunExamples} (\ref{RunExamples}) to check and optionally update the examples of the document. Depending on the argument \mbox{\texttt{\mdseries\slshape units}} several examples are collected in one list. Recognized values for \mbox{\texttt{\mdseries\slshape units}} are \texttt{"Chapter"}, \texttt{"Section"}, \texttt{"Subsection"} or \texttt{"Single"}. The latter means that each example is in a separate list. For all other value of \mbox{\texttt{\mdseries\slshape units}} just one list with all examples is returned. The arguments \mbox{\texttt{\mdseries\slshape path}}, \mbox{\texttt{\mdseries\slshape main}} and \mbox{\texttt{\mdseries\slshape files}} of \texttt{ExtractExamples} are the same as for \texttt{ComposedDocument} (\ref{ComposedDocument}). This function first contructs and parses the \textsf{GAPDoc} document and then applies \texttt{ExtractExamplesXMLTree}. } \subsection{\textcolor{Chapter }{RunExamples}} \logpage{[ 5, 4, 2 ]}\nobreak \hyperdef{L}{X781D56FC7B938DCB}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RunExamples({\mdseries\slshape exmpls[, optrec]})\index{RunExamples@\texttt{RunExamples}} \label{RunExamples} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The argument \mbox{\texttt{\mdseries\slshape exmpls}} must be the output of a call to \texttt{ExtractExamples} (\ref{ExtractExamples}) or \texttt{ExtractExamplesXMLTree} (\ref{ExtractExamplesXMLTree}). The optional argument \mbox{\texttt{\mdseries\slshape optrec}} must be a record, its components can change the default behaviour of this function. By default this function runs the \textsf{GAP} input of all examples and compares the actual output with the output given in the examples. If differences occur these are displayed together with information on the location of the source code of that example. Before running the examples in each unit (entry of \mbox{\texttt{\mdseries\slshape exmpls}}) the function \texttt{START{\textunderscore}TEST} (\textbf{Reference: START{\textunderscore}TEST}) is called and the screen width is set to 72 characters. If the argument \mbox{\texttt{\mdseries\slshape optrec}} is given, the following components are recognized: \begin{description} \item[{\texttt{showDiffs}}] The default value is \texttt{true}, if set to something else found differences in the examples are not displayed. \item[{\texttt{width}}] The value must be a positive integer which is used as screen width when running the examples. As mentioned above, the default is 72 which is a sensible value for the text version of the \textsf{GAPDoc} document used in a 80 character wide terminal. \item[{\texttt{changeSources}}] If this is set to \texttt{true} then the source code of all manual examples which show differences is adjusted to the current outputs. The default is \texttt{false}.\\ Use this feature with care. Note that sometimes differences can indicate a bug, and in such a case it is more appropriate to fix the bug instead of changing the example output. \item[{\texttt{compareFunction}}] The function used to compare the output shown in the example and the current output. See \texttt{Test} (\textbf{Reference: Test}) for more details. \item[{\texttt{checkWidth}}] If this option is a positive integer \texttt{n} the function prints warnings if an example contains any line with more than \texttt{n} characters (input and output lines are considered). By default this option is set to \texttt{false}. \end{description} } } } \chapter{\textcolor{Chapter }{String and Text Utilities}}\label{ch:util} \logpage{[ 6, 0, 0 ]} \hyperdef{L}{X86CEF540862EE042}{} { \section{\textcolor{Chapter }{Text Utilities}}\label{TextUtil} \logpage{[ 6, 1, 0 ]} \hyperdef{L}{X847DA07C7C46B38A}{} { This section describes some utility functions for handling texts within \textsf{GAP}. They are used by the functions in the \textsf{GAPDoc} package but may be useful for other purposes as well. We start with some variables containing useful strings and go on with functions for parsing and reformatting text. \subsection{\textcolor{Chapter }{WHITESPACE}} \logpage{[ 6, 1, 1 ]}\nobreak \hyperdef{L}{X786D477C7AB636AA}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WHITESPACE\index{WHITESPACE@\texttt{WHITESPACE}} \label{WHITESPACE} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{CAPITALLETTERS\index{CAPITALLETTERS@\texttt{CAPITALLETTERS}} \label{CAPITALLETTERS} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SMALLLETTERS\index{SMALLLETTERS@\texttt{SMALLLETTERS}} \label{SMALLLETTERS} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LETTERS\index{LETTERS@\texttt{LETTERS}} \label{LETTERS} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DIGITS\index{DIGITS@\texttt{DIGITS}} \label{DIGITS} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HEXDIGITS\index{HEXDIGITS@\texttt{HEXDIGITS}} \label{HEXDIGITS} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{BOXCHARS\index{BOXCHARS@\texttt{BOXCHARS}} \label{BOXCHARS} }\hfill{\scriptsize (global variable)}}\\ These variables contain sets of characters which are useful for text processing. They are defined as follows. \begin{description} \item[{\texttt{WHITESPACE}}] \texttt{" \texttt{\symbol{92}}n\texttt{\symbol{92}}t\texttt{\symbol{92}}r"} \item[{\texttt{CAPITALLETTERS}}] \texttt{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"} \item[{\texttt{SMALLLETTERS}}] \texttt{"abcdefghijklmnopqrstuvwxyz"} \item[{\texttt{LETTERS}}] concatenation of \texttt{CAPITALLETTERS} and \texttt{SMALLLETTERS} \item[{\texttt{DIGITS}}] \texttt{"0123456789"} \item[{\texttt{HEXDIGITS}}] \texttt{"0123456789ABCDEFabcdef"} \item[{\texttt{BOXCHARS}}] \texttt{Encode(Unicode(9472 + [ 0, 2, 12, 44, 16, 28, 60, 36, 20, 52, 24, 1, 3, 15, 51, 19, 35, 75, 43, 23, 59, 27, 80, 81, 84, 102, 87, 96, 108, 99, 90, 105, 93 ]), "UTF-8")}, these are in UTF-8 encoding, the \texttt{i}-th unicode character is \texttt{BOXCHARS\texttt{\symbol{123}}[3*i-2..3*i]\texttt{\symbol{125}}}. \end{description} } \subsection{\textcolor{Chapter }{TextAttr}} \logpage{[ 6, 1, 2 ]}\nobreak \hyperdef{L}{X785F61E77899580E}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{TextAttr\index{TextAttr@\texttt{TextAttr}} \label{TextAttr} }\hfill{\scriptsize (global variable)}}\\ The record \texttt{TextAttr} contains strings which can be printed to change the terminal attribute for the following characters. This only works with terminals which understand basic ANSI escape sequences. Try the following example to see if this is the case for the terminal you are using. It shows the effect of the foreground and background color attributes and of the \texttt{.bold}, \texttt{.blink}, \texttt{.normal}, \texttt{.reverse} and \texttt{.underscore} which can partly be mixed. \begin{Verbatim}[fontsize=\small,frame=single,label=Example] extra := ["CSI", "reset", "delline", "home"];; for t in Difference(RecNames(TextAttr), extra) do Print(TextAttr.(t), "TextAttr.", t, TextAttr.reset,"\n"); od; \end{Verbatim} The suggested defaults for colors \texttt{0..7} are black, red, green, brown, blue, magenta, cyan, white. But this may be different for your terminal configuration. The escape sequence \texttt{.delline} deletes the content of the current line and \texttt{.home} moves the cursor to the beginning of the current line. \begin{Verbatim}[fontsize=\small,frame=single,label=Example] for i in [1..5] do Print(TextAttr.home, TextAttr.delline, String(i,-6), "\c"); Sleep(1); od; \end{Verbatim} \index{UseColorsInTerminal} Whenever you use this in some printing routines you should make it optional. Use these attributes only when \texttt{UserPreference("UseColorsInTerminal");} returns \texttt{true}. } \subsection{\textcolor{Chapter }{WrapTextAttribute}} \logpage{[ 6, 1, 3 ]}\nobreak \hyperdef{L}{X7B8AD7517E5FD0EA}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WrapTextAttribute({\mdseries\slshape str, attr})\index{WrapTextAttribute@\texttt{WrapTextAttribute}} \label{WrapTextAttribute} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string with markup The argument \mbox{\texttt{\mdseries\slshape str}} must be a text as \textsf{GAP} string, possibly with markup by escape sequences as in \texttt{TextAttr} (\ref{TextAttr}). This function returns a string which is wrapped by the escape sequences \mbox{\texttt{\mdseries\slshape attr}} and \texttt{TextAttr.reset}. It takes care of markup in the given string by appending \mbox{\texttt{\mdseries\slshape attr}} also after each given \texttt{TextAttr.reset} in \mbox{\texttt{\mdseries\slshape str}}. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY");| "XXX\033[32mBLUB\033[0mYYY" !gapprompt@gap>| !gapinput@str2 := WrapTextAttribute(str, TextAttr.1);| "\033[31mXXX\033[32mBLUB\033[0m\033[31m\027YYY\033[0m" !gapprompt@gap>| !gapinput@str3 := WrapTextAttribute(str, TextAttr.underscore);| "\033[4mXXX\033[32mBLUB\033[0m\033[4m\027YYY\033[0m" !gapprompt@gap>| !gapinput@# use Print(str); and so on to see how it looks like.| \end{Verbatim} } \subsection{\textcolor{Chapter }{FormatParagraph}} \logpage{[ 6, 1, 4 ]}\nobreak \hyperdef{L}{X812058CE7C8E9022}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FormatParagraph({\mdseries\slshape str[, len][, flush][, attr][, widthfun]})\index{FormatParagraph@\texttt{FormatParagraph}} \label{FormatParagraph} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } the formatted paragraph as string This function formats a text given in the string \mbox{\texttt{\mdseries\slshape str}} as a paragraph. The optional arguments have the following meaning: \begin{description} \item[{\mbox{\texttt{\mdseries\slshape len}}}] the length of the lines of the formatted text, default is \texttt{78} (counted without a visible length of the strings specified in the \mbox{\texttt{\mdseries\slshape attr}} argument) \item[{\mbox{\texttt{\mdseries\slshape flush}}}] can be \texttt{"left"}, \texttt{"right"}, \texttt{"center"} or \texttt{"both"}, telling that lines should be flushed left, flushed right, centered or left-right justified, respectively, default is \texttt{"both"} \item[{\mbox{\texttt{\mdseries\slshape attr}}}] is a list of two strings; the first is prepended and the second appended to each line of the result (can for example be used for indenting, \texttt{[" ", ""]}, or some markup, \texttt{[TextAttr.bold, TextAttr.reset]}, default is \texttt{["", ""]}) \item[{\mbox{\texttt{\mdseries\slshape widthfun}}}] must be a function which returns the display width of text in \mbox{\texttt{\mdseries\slshape str}}. The default is \texttt{Length} assuming that each byte corresponds to a character of width one. If \mbox{\texttt{\mdseries\slshape str}} is given in \texttt{UTF-8} encoding one can use \texttt{WidthUTF8String} (\ref{WidthUTF8String}) here. \end{description} This function tries to handle markup with the escape sequences explained in \texttt{TextAttr} (\ref{TextAttr}) correctly. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@str := "One two three four five six seven eight nine ten eleven.";;| !gapprompt@gap>| !gapinput@Print(FormatParagraph(str, 25, "left", ["/* ", " */"])); | /* One two three four five */ /* six seven eight nine ten */ /* eleven. */ \end{Verbatim} } \subsection{\textcolor{Chapter }{SubstitutionSublist}} \logpage{[ 6, 1, 5 ]}\nobreak \hyperdef{L}{X82A9121678923445}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SubstitutionSublist({\mdseries\slshape list, sublist, new[, flag]})\index{SubstitutionSublist@\texttt{SubstitutionSublist}} \label{SubstitutionSublist} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } the changed list This function looks for (non-overlapping) occurrences of a sublist \mbox{\texttt{\mdseries\slshape sublist}} in a list \mbox{\texttt{\mdseries\slshape list}} (compare \texttt{PositionSublist} (\textbf{Reference: PositionSublist})) and returns a list where these are substituted with the list \mbox{\texttt{\mdseries\slshape new}}. The optional argument \mbox{\texttt{\mdseries\slshape flag}} can either be \texttt{"all"} (this is the default if not given) or \texttt{"one"}. In the second case only the first occurrence of \mbox{\texttt{\mdseries\slshape sublist}} is substituted. If \mbox{\texttt{\mdseries\slshape sublist}} does not occur in \mbox{\texttt{\mdseries\slshape list}} then \mbox{\texttt{\mdseries\slshape list}} itself is returned (and not a \texttt{ShallowCopy(list)}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@SubstitutionSublist("xababx", "ab", "a");| "xaax" \end{Verbatim} } \subsection{\textcolor{Chapter }{StripBeginEnd}} \logpage{[ 6, 1, 6 ]}\nobreak \hyperdef{L}{X83DE31017B557136}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StripBeginEnd({\mdseries\slshape list, strip})\index{StripBeginEnd@\texttt{StripBeginEnd}} \label{StripBeginEnd} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } changed string Here \mbox{\texttt{\mdseries\slshape list}} and \mbox{\texttt{\mdseries\slshape strip}} must be lists. This function returns the sublist of list which does not contain the leading and trailing entries which are entries of \mbox{\texttt{\mdseries\slshape strip}}. If the result is equal to \mbox{\texttt{\mdseries\slshape list}} then \mbox{\texttt{\mdseries\slshape list}} itself is returned. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@StripBeginEnd(" ,a, b,c, ", ", ");| "a, b,c" \end{Verbatim} } \subsection{\textcolor{Chapter }{StripEscapeSequences}} \logpage{[ 6, 1, 7 ]}\nobreak \hyperdef{L}{X7A5978CF84C3C2D3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StripEscapeSequences({\mdseries\slshape str})\index{StripEscapeSequences@\texttt{StripEscapeSequences}} \label{StripEscapeSequences} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } string without escape sequences This function returns the string one gets from the string \mbox{\texttt{\mdseries\slshape str}} by removing all escape sequences which are explained in \texttt{TextAttr} (\ref{TextAttr}). If \mbox{\texttt{\mdseries\slshape str}} does not contain such a sequence then \mbox{\texttt{\mdseries\slshape str}} itself is returned. } \subsection{\textcolor{Chapter }{RepeatedString}} \logpage{[ 6, 1, 8 ]}\nobreak \hyperdef{L}{X7D71CB837EE969D4}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RepeatedString({\mdseries\slshape c, len})\index{RepeatedString@\texttt{RepeatedString}} \label{RepeatedString} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RepeatedUTF8String({\mdseries\slshape c, len})\index{RepeatedUTF8String@\texttt{RepeatedUTF8String}} \label{RepeatedUTF8String} }\hfill{\scriptsize (function)}}\\ Here \mbox{\texttt{\mdseries\slshape c}} must be either a character or a string and \mbox{\texttt{\mdseries\slshape len}} is a non-negative number. Then \texttt{RepeatedString} returns a string of length \mbox{\texttt{\mdseries\slshape len}} consisting of copies of \mbox{\texttt{\mdseries\slshape c}}. In the variant \texttt{RepeatedUTF8String} the argument \mbox{\texttt{\mdseries\slshape c}} is considered as string in UTF-8 encoding, and it can also be specified as unicode string or character, see \texttt{Unicode} (\ref{Unicode}). The result is a string in UTF-8 encoding which has visible width \mbox{\texttt{\mdseries\slshape len}} as explained in \texttt{WidthUTF8String} (\ref{WidthUTF8String}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@RepeatedString('=',51);| "===================================================" !gapprompt@gap>| !gapinput@RepeatedString("*=",51);| "*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*" !gapprompt@gap>| !gapinput@s := "bh";;| !gapprompt@gap>| !gapinput@enc := GAPInfo.TermEncoding;;| !gapprompt@gap>| !gapinput@if enc <> "UTF-8" then s := Encode(Unicode(s, enc), "UTF-8"); fi;| !gapprompt@gap>| !gapinput@l := RepeatedUTF8String(s, 8);;| !gapprompt@gap>| !gapinput@u := Unicode(l, "UTF-8");;| !gapprompt@gap>| !gapinput@Print(Encode(u, enc), "\n");| bhbhb \end{Verbatim} } \subsection{\textcolor{Chapter }{NumberDigits}} \logpage{[ 6, 1, 9 ]}\nobreak \hyperdef{L}{X7CEEA5B57D7BB38F}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NumberDigits({\mdseries\slshape str, base})\index{NumberDigits@\texttt{NumberDigits}} \label{NumberDigits} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } integer \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{DigitsNumber({\mdseries\slshape n, base})\index{DigitsNumber@\texttt{DigitsNumber}} \label{DigitsNumber} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } string The argument \mbox{\texttt{\mdseries\slshape str}} of \texttt{NumberDigits} must be a string consisting only of an optional leading \texttt{'-'} and characters in \texttt{0123456789abcdefABCDEF}, describing an integer in base \mbox{\texttt{\mdseries\slshape base}} with $2 \leq \mbox{\texttt{\mdseries\slshape base}} \leq 16$. This function returns the corresponding integer. The function \texttt{DigitsNumber} does the reverse. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@NumberDigits("1A3F",16);| 6719 !gapprompt@gap>| !gapinput@DigitsNumber(6719, 16);| "1A3F" \end{Verbatim} } \subsection{\textcolor{Chapter }{PositionMatchingDelimiter}} \logpage{[ 6, 1, 10 ]}\nobreak \hyperdef{L}{X7AF694D9839BF65C}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PositionMatchingDelimiter({\mdseries\slshape str, delim, pos})\index{PositionMatchingDelimiter@\texttt{PositionMatchingDelimiter}} \label{PositionMatchingDelimiter} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } position as integer or \texttt{fail} Here \mbox{\texttt{\mdseries\slshape str}} must be a string and \mbox{\texttt{\mdseries\slshape delim}} a string with two different characters. This function searches the smallest position \texttt{r} of the character \texttt{\mbox{\texttt{\mdseries\slshape delim}}[2]} in \mbox{\texttt{\mdseries\slshape str}} such that the number of occurrences of \texttt{\mbox{\texttt{\mdseries\slshape delim}}[2]} in \mbox{\texttt{\mdseries\slshape str}} between positions \texttt{\mbox{\texttt{\mdseries\slshape pos}}+1} and \texttt{r} is by one greater than the corresponding number of occurrences of \texttt{\mbox{\texttt{\mdseries\slshape delim}}[1]}. If such an \texttt{r} exists, it is returned. Otherwise \texttt{fail} is returned. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0);| fail !gapprompt@gap>| !gapinput@PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1);| 2 !gapprompt@gap>| !gapinput@PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6);| 11 \end{Verbatim} } \subsection{\textcolor{Chapter }{WordsString}} \logpage{[ 6, 1, 11 ]}\nobreak \hyperdef{L}{X832556617F10AAA8}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WordsString({\mdseries\slshape str})\index{WordsString@\texttt{WordsString}} \label{WordsString} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } list of strings containing the words This returns the list of words of a text stored in the string \mbox{\texttt{\mdseries\slshape str}}. All non-letters are considered as word boundaries and are removed. \begin{Verbatim}[commandchars=@|A,fontsize=\small,frame=single,label=Example] @gapprompt|gap>A @gapinput|WordsString("one_two \n three!?");A [ "one", "two", "three" ] \end{Verbatim} } \subsection{\textcolor{Chapter }{Base64String}} \logpage{[ 6, 1, 12 ]}\nobreak \hyperdef{L}{X83F2821783DA9826}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Base64String({\mdseries\slshape str})\index{Base64String@\texttt{Base64String}} \label{Base64String} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringBase64({\mdseries\slshape bstr})\index{StringBase64@\texttt{StringBase64}} \label{StringBase64} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string The first function translates arbitrary binary data given as a GAP string into a \emph{base 64} encoded string. This encoded string contains only printable ASCII characters and is used in various data transfer protocols (\texttt{MIME} encoded emails, weak password encryption, ...). We use the specification in \href{http://tools.ietf.org/html/rfc2045} {RFC 2045}. The second function has the reverse functionality. Here we also accept the characters \texttt{-{\textunderscore}} instead of \texttt{+/} as last two characters. Whitespace is ignored. \begin{Verbatim}[commandchars=@|D,fontsize=\small,frame=single,label=Example] @gapprompt|gap>D @gapinput|b := Base64String("This is a secret!");D "VGhpcyBpcyBhIHNlY3JldCEA=" @gapprompt|gap>D @gapinput|StringBase64(b); D "This is a secret!" \end{Verbatim} } } \section{\textcolor{Chapter }{Unicode Strings}}\label{sec:Unicode} \logpage{[ 6, 2, 0 ]} \hyperdef{L}{X8489C67D80399814}{} { The \textsf{GAPDoc} package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings. \subsection{\textcolor{Chapter }{Unicode Strings and Characters}}\logpage{[ 6, 2, 1 ]} \hyperdef{L}{X8475671278948DDD}{} { \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Unicode({\mdseries\slshape list[, encoding]})\index{Unicode@\texttt{Unicode}} \label{Unicode} }\hfill{\scriptsize (operation)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{UChar({\mdseries\slshape num})\index{UChar@\texttt{UChar}} \label{UChar} }\hfill{\scriptsize (operation)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsUnicodeString\index{IsUnicodeString@\texttt{IsUnicodeString}} \label{IsUnicodeString} }\hfill{\scriptsize (filter)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsUnicodeCharacter\index{IsUnicodeCharacter@\texttt{IsUnicodeCharacter}} \label{IsUnicodeCharacter} }\hfill{\scriptsize (filter)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IntListUnicodeString({\mdseries\slshape ustr})\index{IntListUnicodeString@\texttt{IntListUnicodeString}} \label{IntListUnicodeString} }\hfill{\scriptsize (function)}}\\ Unicode characters are described by their \emph{codepoint}, an integer in the range from $0$ to $2^{21}-1$. For details about unicode, see \href{http://www.unicode.org} {\texttt{http://www.unicode.org}}. The function \texttt{UChar} wraps an integer \mbox{\texttt{\mdseries\slshape num}} into a \textsf{GAP} object lying in the filter \texttt{IsUnicodeCharacter}. Use \texttt{Int} to get the codepoint back. The argument \mbox{\texttt{\mdseries\slshape num}} can also be a \textsf{GAP} character which is then translated to an integer via \texttt{IntChar} (\textbf{Reference: IntChar}). \texttt{Unicode} produces a \textsf{GAP} object in the filter \texttt{IsUnicodeString}. This is a wrapped list of integers for the unicode characters in the string. The function \texttt{IntListUnicodeString} gives access to this list of integers. Basic list functionality is available for \texttt{IsUnicodeString} elements. The entries are in \texttt{IsUnicodeCharacter}. The argument \mbox{\texttt{\mdseries\slshape list}} for \texttt{Unicode} is either a list of integers or a \textsf{GAP} string. In the latter case an \mbox{\texttt{\mdseries\slshape encoding}} can be specified as string, its default is \texttt{"UTF-8"}. \index{URL encoding}\index{RFC 3986} Currently supported encodings can be found in \texttt{UNICODE{\textunderscore}RECODE.NormalizedEncodings} (ASCII, ISO-8859-X, UTF-8 and aliases). The encoding \texttt{"XML"} means an ASCII encoding in which non-ASCII characters are specified by XML character entities. The encoding \texttt{"URL"} is for URL-encoded (also called percent-encoded strings, as specified in RFC 3986 (\href{http://www.ietf.org/rfc/rfc3986.txt} {see here}). The listed encodings \texttt{"LaTeX"} and aliases cannot be used with \texttt{Unicode}. See the operation \texttt{Encode} (\ref{Encode}) for mapping a unicode string to a \textsf{GAP} string. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@ustr := Unicode("a and \366", "latin1");| Unicode("a and \303\266") !gapprompt@gap>| !gapinput@ustr = Unicode("a and ö", "XML"); | true !gapprompt@gap>| !gapinput@IntListUnicodeString(ustr);| [ 97, 32, 97, 110, 100, 32, 246 ] !gapprompt@gap>| !gapinput@ustr[7];| '' \end{Verbatim} } \subsection{\textcolor{Chapter }{Encode}} \logpage{[ 6, 2, 2 ]}\nobreak \hyperdef{L}{X818A31567EB30A39}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Encode({\mdseries\slshape ustr[, encoding]})\index{Encode@\texttt{Encode}} \label{Encode} }\hfill{\scriptsize (operation)}}\\ \textbf{\indent Returns:\ } a \textsf{GAP} string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SimplifiedUnicodeString({\mdseries\slshape ustr[, encoding][, "single"]})\index{SimplifiedUnicodeString@\texttt{SimplifiedUnicodeString}} \label{SimplifiedUnicodeString} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a unicode string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LowercaseUnicodeString({\mdseries\slshape ustr})\index{LowercaseUnicodeString@\texttt{LowercaseUnicodeString}} \label{LowercaseUnicodeString} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a unicode string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{UppercaseUnicodeString({\mdseries\slshape ustr})\index{UppercaseUnicodeString@\texttt{UppercaseUnicodeString}} \label{UppercaseUnicodeString} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a unicode string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LaTeXUnicodeTable\index{LaTeXUnicodeTable@\texttt{LaTeXUnicodeTable}} \label{LaTeXUnicodeTable} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SimplifiedUnicodeTable\index{SimplifiedUnicodeTable@\texttt{SimplifiedUnicodeTable}} \label{SimplifiedUnicodeTable} }\hfill{\scriptsize (global variable)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{LowercaseUnicodeTable\index{LowercaseUnicodeTable@\texttt{LowercaseUnicodeTable}} \label{LowercaseUnicodeTable} }\hfill{\scriptsize (global variable)}}\\ The operation \texttt{Encode} translates a unicode string \mbox{\texttt{\mdseries\slshape ustr}} into a \textsf{GAP} string in some specified \mbox{\texttt{\mdseries\slshape encoding}}. The default encoding is \texttt{"UTF-8"}. Supported encodings can be found in \texttt{UNICODE{\textunderscore}RECODE.NormalizedEncodings}. Except for some cases mentioned below characters which are not available in the target encoding are substituted by '?' characters. If the \mbox{\texttt{\mdseries\slshape encoding}} is \texttt{"URL"} (see \texttt{Unicode} (\ref{Unicode})) then an optional argument \mbox{\texttt{\mdseries\slshape encreserved}} can be given, it must be a list of reserved characters which should be percent encoded; the default is to encode only the \texttt{\%} character. The encoding \texttt{"LaTeX"} substitutes non-ASCII characters and {\LaTeX} special characters by {\LaTeX} code as given in an ordered list \texttt{LaTeXUnicodeTable} of pairs [codepoint, string]. If you have a unicode character for which no substitution is contained in that list, you will get a warning and the translation is \texttt{Unicode(nr)}. In this case find a substitution and add a corresponding [codepoint, string] pair to \texttt{LaTeXUnicodeTable} using \texttt{AddSet} (\textbf{Reference: AddSet}). Also, please, tell the \textsf{GAPDoc} authors about your addition, such that we can extend the list \texttt{LaTeXUnicodeTable}. (Most of the initial entries were generated from lists in the {\TeX} projects enc{\TeX} and \texttt{ucs}.) There are some variants of this encoding: \texttt{"LaTeXleavemarkup"} does the same translations for non-ASCII characters but leaves the {\LaTeX} special characters (e.g., any {\LaTeX} commands) as they are. \texttt{"LaTeXUTF8"} does not give a warning about unicode characters without explicit translation, instead it translates the character to its \texttt{UTF-8} encoding. Make sure to setup your {\LaTeX} document such that all these characters are understood. \texttt{"LaTeXUTF8leavemarkup"} is a combination of the last two variants. Note that the \texttt{"LaTeX"} encoding can only be used with \texttt{Encode} but not for the opposite translation with \texttt{Unicode} (\ref{Unicode}) (which would need far too complicated heuristics). The function \texttt{SimplifiedUnicodeString} can be used to substitute many non-ASCII characters by related ASCII characters or strings (e.g., by a corresponding character without accents). The argument \mbox{\texttt{\mdseries\slshape ustr}} and the result are unicode strings, if \mbox{\texttt{\mdseries\slshape encoding}} is \texttt{"ASCII"} then all non-ASCII characters are translated, otherwise only the non-latin1 characters. If the string \texttt{"single"} in an argument then only substitutions are considered which don't make the result string longer. The translations are stored in a sorted list \texttt{SimplifiedUnicodeTable}. Its entries are of the form \texttt{[codepoint, trans1, trans2, ...]}. Here \texttt{trans1} and so on is either an integer for the codepoint of a substitution character or it is a list of codepoint integers. If you are missing characters in this list and know a sensible ASCII approximation, then add an entry (with \texttt{AddSet} (\textbf{Reference: AddSet})) and tell the \textsf{GAPDoc} authors about it. (The initial content of \texttt{SimplifiedUnicodeTable} was mainly generated from the ``\texttt{transtab}'' tables by Markus Kuhn.) The function \texttt{LowercaseUnicodeString} gets and returns a unicode string and translates each uppercase character to its corresponding lowercase version. This function uses a list \texttt{LowercaseUnicodeTable} of pairs of codepoint integers. This list was generated using the file \texttt{UnicodeData.txt} from the unicode definition (field 14 in each row). The function \texttt{UppercaseUnicodeString} does the similar translation to uppercase characters. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@ustr := Unicode("a and ö", "XML");| Unicode("a and \303\266") !gapprompt@gap>| !gapinput@SimplifiedUnicodeString(ustr, "ASCII");| Unicode("a and oe") !gapprompt@gap>| !gapinput@SimplifiedUnicodeString(ustr, "ASCII", "single");| Unicode("a and o") !gapprompt@gap>| !gapinput@ustr2 := UppercaseUnicodeString(ustr);;| !gapprompt@gap>| !gapinput@Print(Encode(ustr2, GAPInfo.TermEncoding), "\n");| A AND \end{Verbatim} } \subsection{\textcolor{Chapter }{Lengths of UTF-8 strings}}\logpage{[ 6, 2, 3 ]} \hyperdef{L}{X801237207E06A876}{} { \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WidthUTF8String({\mdseries\slshape str})\index{WidthUTF8String@\texttt{WidthUTF8String}} \label{WidthUTF8String} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NrCharsUTF8String({\mdseries\slshape str})\index{NrCharsUTF8String@\texttt{NrCharsUTF8String}} \label{NrCharsUTF8String} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } an integer Let \mbox{\texttt{\mdseries\slshape str}} be a \textsf{GAP} string with text in UTF-8 encoding. There are three ``lengths'' of such a string which must be distinguished. The operation \texttt{Length} (\textbf{Reference: Length}) returns the number of bytes and so the memory occupied by \mbox{\texttt{\mdseries\slshape str}}. The function \texttt{NrCharsUTF8String} returns the number of unicode characters in \mbox{\texttt{\mdseries\slshape str}}, that is the length of \texttt{Unicode(\mbox{\texttt{\mdseries\slshape str}})}. In many applications the function \texttt{WidthUTF8String} is more interesting, it returns the number of columns needed by the string if printed to a terminal. This takes into account that some unicode characters are combining characters and that there are wide characters which need two columns (e.g., for Chinese or Japanese). (To be precise: This implementation assumes that there are no control characters in \mbox{\texttt{\mdseries\slshape str}} and uses the character width returned by the \texttt{wcwidth} function in the GNU C-library called with UTF-8 locale.) \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@# A, German umlaut u, B, zero width space, C, newline| !gapprompt@gap>| !gapinput@str := Encode( Unicode( "AüB​C\n", "XML" ) );;| !gapprompt@gap>| !gapinput@Print(str);| ABC !gapprompt@gap>| !gapinput@# umlaut u needs two bytes and the zero width space three| !gapprompt@gap>| !gapinput@Length(str);| 9 !gapprompt@gap>| !gapinput@NrCharsUTF8String(str);| 6 !gapprompt@gap>| !gapinput@# zero width space and newline don't contribute to width| !gapprompt@gap>| !gapinput@WidthUTF8String(str);| 4 \end{Verbatim} } } \section{\textcolor{Chapter }{Print Utilities}}\label{PrintUtil} \logpage{[ 6, 3, 0 ]} \hyperdef{L}{X860C83047DC4F1BC}{} { The following printing utilities turned out to be useful for interactive work with texts in \textsf{GAP}. But they are more general and so we document them here. \subsection{\textcolor{Chapter }{PrintTo1}} \logpage{[ 6, 3, 1 ]}\nobreak \hyperdef{L}{X8603B90C7C3F0AB1}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PrintTo1({\mdseries\slshape filename, fun})\index{PrintTo1@\texttt{PrintTo1}} \label{PrintTo1} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AppendTo1({\mdseries\slshape filename, fun})\index{AppendTo1@\texttt{AppendTo1}} \label{AppendTo1} }\hfill{\scriptsize (function)}}\\ The argument \mbox{\texttt{\mdseries\slshape fun}} must be a function without arguments. Everything which is printed by a call \mbox{\texttt{\mdseries\slshape fun()}} is printed into the file \mbox{\texttt{\mdseries\slshape filename}}. As with \texttt{PrintTo} (\textbf{Reference: PrintTo}) and \texttt{AppendTo} (\textbf{Reference: AppendTo}) this overwrites or appends to, respectively, a previous content of \mbox{\texttt{\mdseries\slshape filename}}. These functions can be particularly efficient when many small pieces of text shall be written to a file, because no multiple reopening of the file is necessary. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@f := function() local i; | !gapprompt@>| !gapinput@ for i in [1..100000] do Print(i, "\n"); od; end;; | !gapprompt@gap>| !gapinput@PrintTo1("nonsense", f); # now check the local file `nonsense'| \end{Verbatim} } \subsection{\textcolor{Chapter }{StringPrint}} \logpage{[ 6, 3, 2 ]}\nobreak \hyperdef{L}{X829B720C86E57E8B}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringPrint({\mdseries\slshape obj1[, obj2[, ...]]})\index{StringPrint@\texttt{StringPrint}} \label{StringPrint} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringView({\mdseries\slshape obj})\index{StringView@\texttt{StringView}} \label{StringView} }\hfill{\scriptsize (function)}}\\ These functions return a string containing the output of a \texttt{Print} or \texttt{ViewObj} call with the same arguments. This should be considered as a (temporary?) hack. It would be better to have \texttt{String} (\textbf{Reference: String}) methods for all \textsf{GAP} objects and to have a generic \texttt{Print} (\textbf{Reference: Print})-function which just interprets these strings. } \subsection{\textcolor{Chapter }{PrintFormattedString}} \logpage{[ 6, 3, 3 ]}\nobreak \hyperdef{L}{X812A8326844BC910}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PrintFormattedString({\mdseries\slshape str})\index{PrintFormattedString@\texttt{PrintFormattedString}} \label{PrintFormattedString} }\hfill{\scriptsize (function)}}\\ This function prints a string \mbox{\texttt{\mdseries\slshape str}}. The difference to \texttt{Print(str);} is that no additional line breaks are introduced by \textsf{GAP}'s standard printing mechanism. This can be used to print lines which are longer than the current screen width. In particular one can print text which contains escape sequences like those explained in \texttt{TextAttr} (\ref{TextAttr}), where lines may have more characters than \emph{visible characters}. } \subsection{\textcolor{Chapter }{Page}} \logpage{[ 6, 3, 4 ]}\nobreak \hyperdef{L}{X7BB6731F7E3AAA98}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{Page({\mdseries\slshape ...})\index{Page@\texttt{Page}} \label{Page} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{PageDisplay({\mdseries\slshape obj})\index{PageDisplay@\texttt{PageDisplay}} \label{PageDisplay} }\hfill{\scriptsize (function)}}\\ These functions are similar to \texttt{Print} (\textbf{Reference: Print}) and \texttt{Display} (\textbf{Reference: Display}), respectively. The difference is that the output is not sent directly to the screen, but is piped into the current pager; see \texttt{Pager} (\textbf{Reference: Pager}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@Page([1..1421]+0);| !gapprompt@gap>| !gapinput@PageDisplay(CharacterTable("Symmetric", 14));| \end{Verbatim} } \subsection{\textcolor{Chapter }{StringFile}} \logpage{[ 6, 3, 5 ]}\nobreak \hyperdef{L}{X7E14D32181FBC3C3}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringFile({\mdseries\slshape filename})\index{StringFile@\texttt{StringFile}} \label{StringFile} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{FileString({\mdseries\slshape filename, str[, append]})\index{FileString@\texttt{FileString}} \label{FileString} }\hfill{\scriptsize (function)}}\\ The function \texttt{StringFile} returns the content of file \mbox{\texttt{\mdseries\slshape filename}} as a string. This works efficiently with arbitrary (binary or text) files. If something went wrong, this function returns \texttt{fail}. Conversely the function \texttt{FileString} writes the content of a string \mbox{\texttt{\mdseries\slshape str}} into the file \mbox{\texttt{\mdseries\slshape filename}}. If the optional third argument \mbox{\texttt{\mdseries\slshape append}} is given and equals \texttt{true} then the content of \mbox{\texttt{\mdseries\slshape str}} is appended to the file. Otherwise previous content of the file is deleted. This function returns the number of bytes written or \texttt{fail} if something went wrong. Both functions are quite efficient, even with large files. } } } \chapter{\textcolor{Chapter }{Utilities for Bibliographies}}\label{ch:bibutil} \logpage{[ 7, 0, 0 ]} \hyperdef{L}{X7EB94CE97ABF7192}{} { A standard for collecting references (in particular to mathematical texts) is Bib{\TeX} (\href{http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/} {\texttt{http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/}}). A disadvantage of Bib{\TeX} is that the format of the data is specified with the use by {\LaTeX} in mind. The data format is less suited for conversion to other document types like plain text or HTML. In the first section we describe utilities for using data from Bib{\TeX} files in \textsf{GAP}. In the second section we introduce a new XML based data format BibXMLext for bibliographies which seems better suited for other tasks than using it with {\LaTeX}. Another section will describe utilities to deal with BibXMLext data in \textsf{GAP}. \section{\textcolor{Chapter }{Parsing Bib{\TeX} Files}}\label{ParseBib} \logpage{[ 7, 1, 0 ]} \hyperdef{L}{X7A4126EC7BD68F64}{} { Here are functions for parsing, normalizing and printing reference lists in Bib{\TeX} format. The reference describing this format is{\nobreakspace}\cite[Appendix B]{La85}. \subsection{\textcolor{Chapter }{ParseBibFiles}} \logpage{[ 7, 1, 1 ]}\nobreak \hyperdef{L}{X82555C307FDC1817}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseBibFiles({\mdseries\slshape bibfile1[, bibfile2[, ...]]})\index{ParseBibFiles@\texttt{ParseBibFiles}} \label{ParseBibFiles} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseBibStrings({\mdseries\slshape str1[, str2[, ...]]})\index{ParseBibStrings@\texttt{ParseBibStrings}} \label{ParseBibStrings} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } list \texttt{[list of bib-records, list of abbrevs, list of expansions]} The first function parses the files \mbox{\texttt{\mdseries\slshape bibfile1}} and so on (if a file does not exist the extension \texttt{.bib} is appended) in Bib{\TeX} format and returns a list as follows: \texttt{[entries, strings, texts]}. Here \texttt{entries} is a list of records, one record for each reference contained in \mbox{\texttt{\mdseries\slshape bibfile}}. Then \texttt{strings} is a list of abbreviations defined by \texttt{@string}-entries in \mbox{\texttt{\mdseries\slshape bibfile}} and \texttt{texts} is a list which contains in the corresponding position the full text for such an abbreviation. The second function does the same, but the input is given as \textsf{GAP} strings \mbox{\texttt{\mdseries\slshape str1}} and so on. The records in \texttt{entries} store key-value pairs of a Bib{\TeX} reference in the form \texttt{rec(key1 = value1, ...)}. The names of the keys are converted to lower case. The type of the reference (i.e., book, article, ...) and the citation key are stored as components \texttt{.Type} and \texttt{.Label}. The records also have a \texttt{.From} field that says that the data are read from a Bib{\TeX} source. As an example consider the following Bib{\TeX} file. \begin{Verbatim}[fontsize=\small,frame=single,label=doc/test.bib] @string{ j = "Important Journal" } @article{ AB2000, Author= "Fritz A. First and Sec, X. Y.", TITLE="Short", journal = j, year = 2000 } \end{Verbatim} \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibFiles("doc/test.bib");| [ [ rec( From := rec( BibTeX := true ), Label := "AB2000", Type := "article", author := "Fritz A. First and Sec, X. Y." , journal := "Important Journal", title := "Short", year := "2000" ) ], [ "j" ], [ "Important Journal" ] ] \end{Verbatim} } \subsection{\textcolor{Chapter }{NormalizedNameAndKey}} \logpage{[ 7, 1, 2 ]}\nobreak \hyperdef{L}{X7C9F0C337A0A0FF0}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NormalizedNameAndKey({\mdseries\slshape namestr})\index{NormalizedNameAndKey@\texttt{NormalizedNameAndKey}} \label{NormalizedNameAndKey} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } list of strings and names as lists \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NormalizeNameAndKey({\mdseries\slshape r})\index{NormalizeNameAndKey@\texttt{NormalizeNameAndKey}} \label{NormalizeNameAndKey} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The argument \mbox{\texttt{\mdseries\slshape namestr}} must be a string describing an author or a list of authors as described in the Bib{\TeX} documentation in \cite[Appendix B 1.2]{La85}. The function \texttt{NormalizedNameAndKey} returns a list of the form [ normalized name string, short key, long key, names as lists]. The first entry is a normalized form of the input where names are written as ``lastname, first name initials''. The second and third entry are the name parts of a short and long key for the bibliography entry, formed from the (initials of) last names. The fourth entry is a list of lists, one for each name, where a name is described by three strings for the last name, the first name initials and the first name(s) as given in the input. Note that the determination of the initials is limited to names where the first letter is described by a single character (and does not contain some markup, say for accents). The function \texttt{NormalizeNameAndKey} gets as argument \mbox{\texttt{\mdseries\slshape r}} a record for a bibliography entry as returned by \texttt{ParseBibFiles} (\ref{ParseBibFiles}). It substitutes \texttt{.author} and \texttt{.editor} fields of \mbox{\texttt{\mdseries\slshape r}} by their normalized form, the original versions are stored in fields \texttt{.authororig} and \texttt{.editororig}. Furthermore a short and a long citation key is generated and stored in components \texttt{.printedkey} (only if no \texttt{.key} is already bound) and \texttt{.keylong}. We continue the example from \texttt{ParseBibFiles} (\ref{ParseBibFiles}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibFiles("doc/test.bib");;| !gapprompt@gap>| !gapinput@NormalizedNameAndKey(bib[1][1].author);| [ "First, F. A. and Sec, X. Y.", "FS", "firstsec", [ [ "First", "F. A.", "Fritz A." ], [ "Sec", "X. Y.", "X. Y." ] ] ] !gapprompt@gap>| !gapinput@NormalizeNameAndKey(bib[1][1]);| !gapprompt@gap>| !gapinput@bib[1][1];| rec( From := rec( BibTeX := true ), Label := "AB2000", Type := "article", author := "First, F. A. and Sec, X. Y.", authororig := "Fritz A. First and Sec, X. Y.", journal := "Important Journal", keylong := "firstsec2000", printedkey := "FS00", title := "Short", year := "2000" ) \end{Verbatim} } \subsection{\textcolor{Chapter }{WriteBibFile}} \logpage{[ 7, 1, 3 ]}\nobreak \hyperdef{L}{X7C2B2F65851EAA0B}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WriteBibFile({\mdseries\slshape bibfile, bib})\index{WriteBibFile@\texttt{WriteBibFile}} \label{WriteBibFile} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This is the converse of \texttt{ParseBibFiles} (\ref{ParseBibFiles}). Here \mbox{\texttt{\mdseries\slshape bib}} either must have a format as list of three lists as it is returned by \texttt{ParseBibFiles} (\ref{ParseBibFiles}). Or \mbox{\texttt{\mdseries\slshape bib}} can be a record as returned by \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}). A Bib{\TeX} file \mbox{\texttt{\mdseries\slshape bibfile}} is written and the entries are formatted in a uniform way. All given abbreviations are used while writing this file. We continue the example from \texttt{NormalizeNameAndKey} (\ref{NormalizeNameAndKey}). The command \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@WriteBibFile("nicer.bib", bib);| \end{Verbatim} produces a file \texttt{nicer.bib} as follows: \begin{Verbatim}[fontsize=\small,frame=single,label=nicer.bib] @string{j = "Important Journal" } @article{ AB2000, author = {First, F. A. and Sec, X. Y.}, title = {Short}, journal = j, year = {2000}, authororig = {Fritz A. First and Sec, X. Y.}, keylong = {firstsec2000}, printedkey = {FS00} } \end{Verbatim} } \subsection{\textcolor{Chapter }{InfoBibTools}} \logpage{[ 7, 1, 4 ]}\nobreak \hyperdef{L}{X85C1D50F7E37A99A}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InfoBibTools\index{InfoBibTools@\texttt{InfoBibTools}} \label{InfoBibTools} }\hfill{\scriptsize (info class)}}\\ The default level of this info class is 1. Functions like \texttt{ParseBibFiles} (\ref{ParseBibFiles}), \texttt{StringBibAs...} are then printing some information. You can suppress it by setting the level of \texttt{InfoBibTools} to 0. With level 2 there may be some more information for debugging purposes. } } \section{\textcolor{Chapter }{The BibXMLext Format}}\label{BibXMLformat} \logpage{[ 7, 2, 0 ]} \hyperdef{L}{X7FB8F6BD80D859D1}{} { Bibliographical data in Bib{\TeX} files have the disadvantage that the actual data are given in {\LaTeX} syntax. This makes it difficult to use the data for anything but for {\LaTeX}, say for representations of the data as plain text or HTML. For example: mathematical formulae are in {\LaTeX} \texttt{\$} environments, non-ASCII characters can be specified in many strange ways, and how to specify URLs for links if the output format allows them? Here we propose an XML data format for bibliographical data which addresses these problems, it is called BibXMLext. In the next section we describe some tools for generating (an approximation to) this data format from Bib{\TeX} data, and for using data given in BibXMLext format for various purposes. The first motivation for this development was the handling of bibliographical data in \textsf{GAPDoc}, but the format and the tools are certainly useful for other purposes as well. We started from a DTD \texttt{bibxml.dtd} which is publicly available, say from \href{http://bibtexml.sf.net/} {\texttt{http://bibtexml.sf.net/}}. This is essentially a reformulation of the definition of the Bib{\TeX} format, including several of some widely used further fields. This has already the advantage that a generic XML parser can check the validity of the data entries, for example for missing compulsary fields in entries. We applied the following changes and extensions to define the DTD for BibXMLext, stored in the file \texttt{bibxmlext.dtd} which can be found in the root directory of this \textsf{GAPDoc} package (and in Appendix \ref{bibxmlextdtd}): \begin{description} \item[{names}] Lists of names in the \texttt{author} and \texttt{editor} fields in Bib{\TeX} are difficult to parse. Here they must be given by a sequence of \texttt{{\textless}name{\textgreater}}-elements which each contain an optional \texttt{{\textless}first{\textgreater}}- and a \texttt{{\textless}last{\textgreater}}-element for the first and last names, respectively. \item[{\texttt{{\textless}M{\textgreater}} and \texttt{{\textless}Math{\textgreater}}}] These elements enclose mathematical formulae, the content is {\LaTeX} code (without the \texttt{\$}). These should be handled in the same way as the elements with the same names in \textsf{GAPDoc}, see \ref{M} and \ref{Math}. In particular, simple formulae which have a well defined plain text representation can be given in \texttt{{\textless}M{\textgreater}}-elements. \item[{Encoding}] Note that in XML files we can use the full range of unicode characters, see \href{http://www.unicode.org/} {\texttt{http://www.unicode.org/}}. All non-ASCII characters should be specified as unicode characters. This makes dealing with special characters easy for plain text or HTML, only for use with {\LaTeX} some sort of translation is necessary. \item[{\texttt{{\textless}URL{\textgreater}}}] These elements are allowed everywhere in the text and should be represented by links in converted formats which allow this. It is used in the same way as the element with the same name in \textsf{GAPDoc}, see \ref{URL}. \item[{\texttt{{\textless}Alt Only="..."{\textgreater}} and \texttt{{\textless}Alt Not="..."{\textgreater}}}] Sometimes information should be given in different ways, depending on the output format of the data. This is possible with the \texttt{{\textless}Alt{\textgreater}}-elements with the same definition as in \textsf{GAPDoc}, see \ref{Alt}. \item[{\texttt{{\textless}C{\textgreater}}}] This element should be used to protect text from case changes by converters (the extra \texttt{\texttt{\symbol{123}}\texttt{\symbol{125}}} characters in Bib{\TeX} title fields). \item[{\texttt{{\textless}string key="..." value="..."/{\textgreater}} and \texttt{{\textless}value key="..."/{\textgreater}}}] The \texttt{{\textless}string{\textgreater}}-element defines key-value pairs which can be used in any field via the \texttt{{\textless}value{\textgreater}}-element (not only for whole fields but also parts of the text). \item[{\texttt{{\textless}other type="..."{\textgreater}}}] This is a generic element for fields which are otherwise not supported. An arbitrary number of them is allowed for each entry, so any kind of additional data can be added to entries. \item[{\texttt{{\textless}Wrap Name="..."{\textgreater}}}] This generic element is allowed inside all fields. This markup will be just ignored (but not the element content) by our standard tools. But it can be a useful hook for introducing arbitrary further markup (and our tools can easily be extended to handle it). \item[{Extra entities}] The DTD defines the standard XML entities (\ref{XMLspchar} and the entities \texttt{\ } (non-breakable space), \texttt{\–} and \texttt{\©right;}. Use \texttt{\–} in page ranges. \end{description} For further details of the DTD we refer to the file \texttt{bibxmlext.dtd} itself which is shown in appendix \ref{bibxmlextdtd}. That file also recalls some information from the Bib{\TeX} documentation on how the standard fields of entries should be used. Which entry types and which fields are supported (and the ordering of the fields which is fixed by a DTD) can be either read off the DTD, or within \textsf{GAP} one can use the function \texttt{TemplateBibXML} (\ref{TemplateBibXML}) to get templates for the various entry types. Here is an example of a BibXMLext document: \begin{Verbatim}[fontsize=\small,frame=single,label=doc/testbib.xml]
Fritz A.First X. Y.Secőnd The <Wrap Name="Package"> <C>F</C>ritz</Wrap> package for the formula <M>x^y - l_{{i+1}} \rightarrow \mathbb{R}</M> 2000 13 13–25 Online data at http://www.publish.com/~ImpJ/123#data very useful
\end{Verbatim} There is a standard XML header and a \texttt{DOCTYPE} declaration refering to the \texttt{bibxmlext.dtd} DTD mentioned above. Local entities could be defined in the \texttt{DOCTYPE} tag as shown in the example in \ref{GDent}. The actual content of the document is inside a \texttt{{\textless}file{\textgreater}}-element, it consists of \texttt{{\textless}string{\textgreater}}- and \texttt{{\textless}entry{\textgreater}}-elements. Several of the BibXMLext markup features are shown. We will use this input document for some examples below. } \section{\textcolor{Chapter }{Utilities for BibXMLext data}}\label{BibXMLtools} \logpage{[ 7, 3, 0 ]} \hyperdef{L}{X7AC255DE7D2531B6}{} { \subsection{\textcolor{Chapter }{Translating Bib{\TeX} to BibXMLext}}\label{Subsect:IntroXMLBib} \logpage{[ 7, 3, 1 ]} \hyperdef{L}{X7C5548E77ECA29D7}{} { First we describe a tool which can translate bibliography entries from Bib{\TeX} data to BibXMLext \texttt{{\textless}entry{\textgreater}}-elements. It also does some validation of the data. In some cases it is desirable to improve the result by hand afterwards (editing formulae, adding \texttt{{\textless}URL{\textgreater}}-elements, translating non-ASCII characters to unicode, ...). See \texttt{WriteBibXMLextFile} (\ref{WriteBibXMLextFile}) below for how to write the results to a BibXMLext file. } \subsection{\textcolor{Chapter }{HeuristicTranslationsLaTeX2XML.Apply}} \logpage{[ 7, 3, 2 ]}\nobreak \hyperdef{L}{X7A025E0A7A1CD390}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HeuristicTranslationsLaTeX2XML.Apply({\mdseries\slshape str})\index{HeuristicTranslationsLaTeX2XML.Apply@\texttt{Heuristic}\-\texttt{Translations}\-\texttt{La}\-\texttt{Te}\-\texttt{X2}\-\texttt{X}\-\texttt{M}\-\texttt{L.}\-\texttt{Apply}} \label{HeuristicTranslationsLaTeX2XML.Apply} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{HeuristicTranslationsLaTeX2XML.ApplyFile({\mdseries\slshape fnam[, outnam]})\index{HeuristicTranslationsLaTeX2XML.ApplyFile@\texttt{Heuristic}\-\texttt{Translations}\-\texttt{La}\-\texttt{Te}\-\texttt{X2}\-\texttt{X}\-\texttt{M}\-\texttt{L.}\-\texttt{Apply}\-\texttt{File}} \label{HeuristicTranslationsLaTeX2XML.ApplyFile} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing These utilities translate some {\LaTeX} code into text in UTF-8 encoding. The input is given as a string \mbox{\texttt{\mdseries\slshape str}}, or a file name \mbox{\texttt{\mdseries\slshape fnam}}, respectively. The first function returns the translated string. The second function with one argument overwrites the given file with the translated text. Optionally, the translated file content can be written to another file, if its name is given as second argument \mbox{\texttt{\mdseries\slshape outnam}}. The record \texttt{HeuristicTranslationsLaTeX2XML} mainly contains translations of {\LaTeX} macros for special characters which were found in hundreds of Bib{\TeX} entries from \href{http://www.ams.org/mathscinet/} {MathSciNet}. Just look at this record if you want to know how it works. It is easy to extend, and if you have improvements which may be of general interest, please send them to the \textsf{GAPDoc} author. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@s := "\\\"u\\'{e}\\`e{\\ss}";;| !gapprompt@gap>| !gapinput@Print(s, "\n"); | \"u\'{e}\`e{\ss} !gapprompt@gap>| !gapinput@Print(HeuristicTranslationsLaTeX2XML.Apply(s),"\n");| \end{Verbatim} } \subsection{\textcolor{Chapter }{StringBibAsXMLext}} \logpage{[ 7, 3, 3 ]}\nobreak \hyperdef{L}{X85F33C64787A00B7}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringBibAsXMLext({\mdseries\slshape bibentry[, abbrvs, vals][, encoding]})\index{StringBibAsXMLext@\texttt{StringBibAsXMLext}} \label{StringBibAsXMLext} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string with XML code, or \texttt{fail} The argument \mbox{\texttt{\mdseries\slshape bibentry}} is a record representing an entry from a Bib{\TeX} file, as returned in the first list of the result of \texttt{ParseBibFiles} (\ref{ParseBibFiles}). The optional two arguments \mbox{\texttt{\mdseries\slshape abbrvs}} and \mbox{\texttt{\mdseries\slshape vals}} can be lists of abbreviations and substitution strings, as returned as second and third list element in the result of \texttt{ParseBibFiles} (\ref{ParseBibFiles}). The optional argument \mbox{\texttt{\mdseries\slshape encoding}} specifies the character encoding of the string components of \mbox{\texttt{\mdseries\slshape bibentry}}. If this is not given it is checked if all strings are valid UTF-8 encoded strings, in that case it is assumed that the encoding is UTF-8, otherwise the latin1 encoding is assumed. The function \texttt{StringBibAsXMLext} creates XML code of an \texttt{{\textless}entry{\textgreater}}-element in \texttt{BibXMLext} format. The result is in UTF-8 encoding and contains some heuristic translations, like splitting name lists, finding places for \texttt{{\textless}C{\textgreater}}-elements, putting formulae in \texttt{{\textless}M{\textgreater}}-elements, substituting some characters. The result should always be checked and maybe improved by hand. Some validity checks are applied to the given data, for example if all non-optional fields are given. If this check fails the function returns \texttt{fail}. If your Bib{\TeX} input contains {\LaTeX} markup for special characters, it can be convenient to translate this input with \texttt{HeuristicTranslationsLaTeX2XML.Apply} (\ref{HeuristicTranslationsLaTeX2XML.Apply}) or \texttt{HeuristicTranslationsLaTeX2XML.ApplyFile} (\ref{HeuristicTranslationsLaTeX2XML.ApplyFile}) before parsing it as Bib{\TeX}. As an example we consider again the short Bib{\TeX} file \texttt{doc/test.bib} shown in the example for \texttt{ParseBibFiles} (\ref{ParseBibFiles}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibFiles("doc/test.bib");;| !gapprompt@gap>| !gapinput@str := StringBibAsXMLext(bib[1][1], bib[2], bib[3]);;| !gapprompt@gap>| !gapinput@Print(str, "\n");|
Fritz A.First X. Y.Sec Short 2000
\end{Verbatim} } The following functions allow parsing of data which are already in BibXMLext format. \subsection{\textcolor{Chapter }{ParseBibXMLextString}} \logpage{[ 7, 3, 4 ]}\nobreak \hyperdef{L}{X86BD29AE7A453721}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseBibXMLextString({\mdseries\slshape str})\index{ParseBibXMLextString@\texttt{ParseBibXMLextString}} \label{ParseBibXMLextString} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ParseBibXMLextFiles({\mdseries\slshape fname1[, fname2[, ...]]})\index{ParseBibXMLextFiles@\texttt{ParseBibXMLextFiles}} \label{ParseBibXMLextFiles} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a record with fields \texttt{.entries}, \texttt{.strings} and \texttt{.entities} The first function gets a string \mbox{\texttt{\mdseries\slshape str}} containing a \texttt{BibXMLext} document or a part of it. It returns a record with the three mentioned fields. Here \texttt{.entries} is a list of partial XML parse trees for the \texttt{{\textless}entry{\textgreater}}-elements in \mbox{\texttt{\mdseries\slshape str}}. The field \texttt{.strings} is a list of key-value pairs from the \texttt{{\textless}string{\textgreater}}-elements in \mbox{\texttt{\mdseries\slshape str}}. And \texttt{.strings} is a list of name-value pairs of the named entities which were used during the parsing. The second function \texttt{ParseBibXMLextFiles} uses the first on the content of all files given by filenames \mbox{\texttt{\mdseries\slshape fname1}} and so on. It collects the results in a single record. As an example we parse the file \texttt{testbib.xml} shown in \ref{BibXMLformat}. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibXMLextFiles("doc/testbib.xml");;| !gapprompt@gap>| !gapinput@RecFields(bib);| [ "entries", "strings", "entities" ] !gapprompt@gap>| !gapinput@bib.entries;| [ ] !gapprompt@gap>| !gapinput@bib.strings;| [ [ "j", "Important Journal" ] ] !gapprompt@gap>| !gapinput@bib.entities[1]; | [ "amp", "&#38;" ] \end{Verbatim} } \subsection{\textcolor{Chapter }{WriteBibXMLextFile}} \logpage{[ 7, 3, 5 ]}\nobreak \hyperdef{L}{X7811108C7E5B1709}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{WriteBibXMLextFile({\mdseries\slshape fname, bib})\index{WriteBibXMLextFile@\texttt{WriteBibXMLextFile}} \label{WriteBibXMLextFile} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing This function writes a BibXMLext file with name \mbox{\texttt{\mdseries\slshape fname}}. There are three possibilities to specify the bibliography entries in the argument \mbox{\texttt{\mdseries\slshape bib}}. It can be a list of three lists as returned by \texttt{ParseBibFiles} (\ref{ParseBibFiles}). Or it can be just the first of such three lists in which case the other two lists are assumed to be empty. To all entries of the (first) list the function \texttt{StringBibAsXMLext} (\ref{StringBibAsXMLext}) is applied and the resulting strings are written to the result file. The third possibility is that \mbox{\texttt{\mdseries\slshape bib}} is a record in the format as returned by \texttt{ParseBibXMLextString} (\ref{ParseBibXMLextString}) and \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}). In this case the entries for the BibXMLext file are produced with \texttt{StringXMLElement} (\ref{StringXMLElement}), and if \mbox{\texttt{\mdseries\slshape bib}}\texttt{.entities} is bound then it is tried to resubstitute parts of the string by the given entities with \texttt{EntitySubstitution} (\ref{EntitySubstitution}). As an example we write back the result of the example shown for \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}) to an equivalent XML file. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibXMLextFiles("doc/testbib.xml");;| !gapprompt@gap>| !gapinput@WriteBibXMLextFile("test.xml", bib);| \end{Verbatim} } \subsection{\textcolor{Chapter }{Bibliography Entries as Records}}\label{Subsect:RecBib} \logpage{[ 7, 3, 6 ]} \hyperdef{L}{X82167F1280F4310E}{} { For working with BibXMLext entries we find it convenient to first translate the parse tree of an entry, as returned by \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}), to a record with the field names of the entry as components whose value is the content of the field as string. These strings are generated with respect to a result type. The records are generated by the following function which can be customized by the user. } \subsection{\textcolor{Chapter }{RecBibXMLEntry}} \logpage{[ 7, 3, 7 ]}\nobreak \hyperdef{L}{X786C33ED79F425F1}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{RecBibXMLEntry({\mdseries\slshape entry[, restype][, strings][, options]})\index{RecBibXMLEntry@\texttt{RecBibXMLEntry}} \label{RecBibXMLEntry} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a record with fields as strings This function generates a content string for each field of a bibliography entry and assigns them to record components. This content may depend on the requested result type and possibly some given options. The arguments are as follows: \mbox{\texttt{\mdseries\slshape entry}} is the parse tree of an \texttt{{\textless}entry{\textgreater}} element as returned by \texttt{ParseBibXMLextString} (\ref{ParseBibXMLextString}) or \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}). The optional argument \mbox{\texttt{\mdseries\slshape restype}} describes the type of the result. This package supports currently the types \texttt{"BibTeX"}, \texttt{"Text"} and \texttt{"HTML"}. The default is \texttt{"BibTeX"}. The optional argument \mbox{\texttt{\mdseries\slshape strings}} must be a list of key-value pairs as returned in the component \texttt{.strings} in the result of \texttt{ParseBibXMLextString} (\ref{ParseBibXMLextString}). The argument \mbox{\texttt{\mdseries\slshape options}} must be a record. If the entry contains an \texttt{author} field then the result will also contain a component \texttt{.authorAsList} which is a list containing for each author a list with three entries of the form \texttt{[last name, first name initials, first name]} (the third entry means the first name as given in the data). Similarly, an \texttt{editor} field is accompanied by a component \texttt{.editorAsList}. The following \mbox{\texttt{\mdseries\slshape options}} are currently supported. If \texttt{options.fullname} is bound and set to \texttt{true} then the full given first names for authors and editors will be used, the default is to use the initials of the first names. Also, if \texttt{options.namefirstlast} is bound and set to \texttt{true} then the names are written in the form ``first-name(s) last-name'', the default is the form ``last-name, first-name(s)''. If \texttt{options.href} is bound and set to \texttt{false} then the \texttt{"BibTeX"} type result will not use \texttt{\texttt{\symbol{92}}href} commands. The default is to produce \texttt{\texttt{\symbol{92}}href} commands from \texttt{{\textless}URL{\textgreater}}-elements such that {\LaTeX} with the \texttt{hyperref} package can produce links for them. The content of an \texttt{{\textless}Alt{\textgreater}}-element with \texttt{Only}-attribute is included if \mbox{\texttt{\mdseries\slshape restype}} is given in the attribute and ignored otherwise, and vice versa in case of a \texttt{Not}-attribute. If \texttt{options.useAlt} is bound, it must be a list of strings to which \mbox{\texttt{\mdseries\slshape restype}} is added. Then an \texttt{{\textless}Alt{\textgreater}}-element with \texttt{Only}-attribute is evaluated if the intersection of \texttt{options.useAlt} and the types given in the attribute is not empty. In case of a \texttt{Not}-attribute the element is evaluated if this intersection is empty. If \mbox{\texttt{\mdseries\slshape restype}} is \texttt{"BibTeX"} then the string fields in the result will be recoded with \texttt{Encode} (\ref{Encode}) and target \texttt{"LaTeX"}. If \texttt{options.hasLaTeXmarkup} is bound and set to \texttt{true} (for example, because the data are originally read from Bib{\TeX} files), then the target \texttt{"LaTeXleavemarkup"} will be used. We use again the file shown in the example for \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}). \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@bib := ParseBibXMLextFiles("doc/testbib.xml");;| !gapprompt@gap>| !gapinput@e := bib.entries[1];; strs := bib.strings;;| !gapprompt@gap>| !gapinput@Print(RecBibXMLEntry(e, "BibTeX", strs), "\n");| rec( From := rec( BibXML := true, options := rec( ), type := "BibTeX" ), Label := "AB2000", Type := "article", author := "First, F. A. and Sec{\\H o}nd, X. Y.", authorAsList := [ [ "First", "F. A.", "Fritz A." ], [ "Sec\305\221nd", "X. Y.", "X. Y." ] ], journal := "Important Journal", mycomment := "very useful", note := "Online data at \\href {http://www.publish.com/~ImpJ/123#data} {Bla\ Bla Publisher}", number := "13", pages := "13{\\textendash}25", printedkey := "FS00", title := "The {F}ritz package for the \n formula $x^y - l_{{i+1}} \ \\rightarrow \\mathbb{R}$", year := "2000" ) !gapprompt@gap>| !gapinput@Print(RecBibXMLEntry(e, "HTML", strs).note, "\n");| Online data at Bla Bla\ Publisher \end{Verbatim} } \subsection{\textcolor{Chapter }{AddHandlerBuildRecBibXMLEntry}} \logpage{[ 7, 3, 8 ]}\nobreak \hyperdef{L}{X8067261385905A36}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AddHandlerBuildRecBibXMLEntry({\mdseries\slshape elementname, restype, handler})\index{AddHandlerBuildRecBibXMLEntry@\texttt{AddHandlerBuildRecBibXMLEntry}} \label{AddHandlerBuildRecBibXMLEntry} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } nothing The argument \mbox{\texttt{\mdseries\slshape elementname}} must be the name of an entry field supported by the BibXMLext format, the name of one of the special elements \texttt{"C"}, \texttt{"M"}, \texttt{"Math"}, \texttt{"URL"} or of the form \texttt{"Wrap:myname"} or any string \texttt{"mytype"} (which then corresponds to entry fields \texttt{{\textless}other type="mytype"{\textgreater}}). The string \texttt{"Finish"} has an exceptional meaning, see below. \mbox{\texttt{\mdseries\slshape restype}} is a string describing the result type for which the handler is installed, see \texttt{RecBibXMLEntry} (\ref{RecBibXMLEntry}). For both arguments, \mbox{\texttt{\mdseries\slshape elementname}} and \mbox{\texttt{\mdseries\slshape restype}}, it is also possible to give lists of the described ones for installing several handler at once. The argument \mbox{\texttt{\mdseries\slshape handler}} must be a function with five arguments of the form \mbox{\texttt{\mdseries\slshape handler}}\texttt{(entry, r, restype, strings, options)}. Here \mbox{\texttt{\mdseries\slshape entry}} is a parse tree of a BibXMLext \texttt{{\textless}entry{\textgreater}}-element, \mbox{\texttt{\mdseries\slshape r}} is a node in this tree for an element \mbox{\texttt{\mdseries\slshape elementname}}, and \mbox{\texttt{\mdseries\slshape restype}}, \mbox{\texttt{\mdseries\slshape strings}} and \mbox{\texttt{\mdseries\slshape options}} are as explained in \texttt{RecBibXMLEntry} (\ref{RecBibXMLEntry}). The function should return a string representing the content of the node \mbox{\texttt{\mdseries\slshape r}}. If \mbox{\texttt{\mdseries\slshape elementname}} is of the form \texttt{"Wrap:myname"} the handler is used for elements of form \texttt{{\textless}Wrap Name="myname"{\textgreater}...{\textless}/Wrap{\textgreater}}. If \mbox{\texttt{\mdseries\slshape elementname}} is \texttt{"Finish"} the handler should look like above except that now \mbox{\texttt{\mdseries\slshape r}} is the record generated by \texttt{RecBibXMLEntry} (\ref{RecBibXMLEntry}) just before it is returned. Here the handler should return nothing. It can be used to manipulate the record \mbox{\texttt{\mdseries\slshape r}}, for example for changing the encoding of the strings or for adding some more components. The installed handler is called by \texttt{BuildRecBibXMLEntry(}\mbox{\texttt{\mdseries\slshape entry}}, \mbox{\texttt{\mdseries\slshape r}}, \mbox{\texttt{\mdseries\slshape restype}}, \mbox{\texttt{\mdseries\slshape strings}}, \mbox{\texttt{\mdseries\slshape options}}\texttt{)}. The string for the whole content of an element can be generated by \texttt{ContentBuildRecBibXMLEntry(}\mbox{\texttt{\mdseries\slshape entry}}, \mbox{\texttt{\mdseries\slshape r}}, \mbox{\texttt{\mdseries\slshape restype}}, \mbox{\texttt{\mdseries\slshape strings}}, \mbox{\texttt{\mdseries\slshape options}}\texttt{)}. We continue the example from \texttt{RecBibXMLEntry} (\ref{RecBibXMLEntry}) and install a handler for the \texttt{{\textless}Wrap Name="Package"{\textgreater}}-element such that {\LaTeX} puts its content in a sans serif font. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX",| !gapprompt@>| !gapinput@function(entry, r, restype, strings, options)| !gapprompt@>| !gapinput@ return Concatenation("\\textsf{", ContentBuildRecBibXMLEntry(| !gapprompt@>| !gapinput@ entry, r, restype, strings, options), "}");| !gapprompt@>| !gapinput@end);| !gapprompt@gap>| !gapinput@| !gapprompt@gap>| !gapinput@Print(RecBibXMLEntry(e, "BibTeX", strs).title, "\n");| The \textsf{ {F}ritz} package for the formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$ !gapprompt@gap>| !gapinput@Print(RecBibXMLEntry(e, "Text", strs).title, "\n"); | The Fritz package for the formula x^y - l_{i+1} -> R !gapprompt@gap>| !gapinput@AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", "Ignore");| \end{Verbatim} } \subsection{\textcolor{Chapter }{StringBibXMLEntry}} \logpage{[ 7, 3, 9 ]}\nobreak \hyperdef{L}{X790A295680F7CD24}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{StringBibXMLEntry({\mdseries\slshape entry[, restype][, strings][, options]})\index{StringBibXMLEntry@\texttt{StringBibXMLEntry}} \label{StringBibXMLEntry} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a string The arguments of this function have the same meaning as in \texttt{RecBibXMLEntry} (\ref{RecBibXMLEntry}) but the return value is a string representing the bibliography entry in a format specified by \mbox{\texttt{\mdseries\slshape restype}} (default is \texttt{"BibTeX"}). Currently, the following cases for \mbox{\texttt{\mdseries\slshape restype}} are supported: \begin{description} \item[{\texttt{"BibTeX"}}] A string with Bib{\TeX} source code is generated. \item[{\texttt{"Text"}}] A text representation of the text is returned. If \texttt{options.ansi} is bound it must be a record. The components must have names \texttt{Bib{\textunderscore}Label}, \texttt{Bib{\textunderscore}author}, and so on for all fieldnames. The value of each component is a pair of strings which will enclose the content of the field in the result or the first of these strings in which case the default for the second is \texttt{TextAttr.reset} (see \texttt{TextAttr} (\ref{TextAttr})). If you give an empty record here, some default ANSI color markup will be used. \item[{\texttt{"HTML"}}] An HTML representation of the bibliography entry is returned. The text from each field is enclosed in markup (mostly \texttt{{\textless}span{\textgreater}}-elements) with the \texttt{class} attribute set to the field name. This allows a detailed layout of the code via a style sheet file. \end{description} We use again the file shown in the example for \texttt{ParseBibXMLextFiles} (\ref{ParseBibXMLextFiles}). \begin{Verbatim}[commandchars=!|C,fontsize=\small,frame=single,label=Example] !gapprompt|gap>C !gapinput|bib := ParseBibXMLextFiles("doc/testbib.xml");;C !gapprompt|gap>C !gapinput|e := bib.entries[1];; strs := bib.strings;;C !gapprompt|gap>C !gapinput|ebib := StringBibXMLEntry(e, "BibTeX", strs);;C !gapprompt|gap>C !gapinput|PrintFormattedString(ebib);C @article{ AB2000, author = {First, F. A. and Sec{\H o}nd, X. Y.}, title = {The {F}ritz package for the formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$}, journal = {Important Journal}, number = {13}, year = {2000}, pages = {13{\textendash}25}, note = {Online data at \href {http://www.publish.com/~ImpJ/123#data} {Bla Bla Publisher}}, mycomment = {very useful}, printedkey = {FS00} } !gapprompt|gap>C !gapinput|etxt := StringBibXMLEntry(e, "Text", strs);; C !gapprompt|gap>C !gapinput|etxt := SimplifiedUnicodeString(Unicode(etxt), "latin1", "single");;C !gapprompt|gap>C !gapinput|etxt := Encode(etxt, GAPInfo.TermEncoding);; C !gapprompt|gap>C !gapinput|PrintFormattedString(etxt);C [FS00] First, F. A. and Second, X. Y., The Fritz package for the formula x^y - l_{i+1} ? R, Important Journal, 13 (2000), 13-25, (Online data at Bla Bla Publisher (http://www.publish.com/~ImpJ/123#data)). \end{Verbatim} } The following command may be useful to generate completly new bibliography entries in BibXMLext format. It also informs about the supported entry types and field names. \subsection{\textcolor{Chapter }{TemplateBibXML}} \logpage{[ 7, 3, 10 ]}\nobreak \hyperdef{L}{X7C6FF57087016019}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{TemplateBibXML({\mdseries\slshape [type]})\index{TemplateBibXML@\texttt{TemplateBibXML}} \label{TemplateBibXML} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } list of types or string Without an argument this function returns a list of the supported entry types in BibXMLext documents. With an argument \mbox{\texttt{\mdseries\slshape type}} of one of the supported types the function returns a string which is a template for a corresponding BibXMLext entry. Optional field elements have a \texttt{*} appended. If an element has the word \texttt{OR} appended, then either this element or the next must/can be given, not both. If \texttt{AND/OR} is appended then this and/or the next can/must be given. Elements which can appear several times have a \texttt{+} appended. Places to fill are marked by an \texttt{X}. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@TemplateBibXML();| [ "article", "book", "booklet", "conference", "inbook", "incollection", "inproceedings", "manual", "mastersthesis", "misc", "phdthesis", "proceedings", "techreport", "unpublished" ] !gapprompt@gap>| !gapinput@Print(TemplateBibXML("inbook"));| XX+ OR XX+ X XAND/OR X X X X*OR X* X* X*
X
* X* X* X* X* X* X* X* X* X* X* X*OR X* X* X* X* X* X* X* X* X* X* X* X* X*+
\end{Verbatim} } } \section{\textcolor{Chapter }{Getting Bib{\TeX} entries from \textsf{MathSciNet}}}\label{MathSciNet} \logpage{[ 7, 4, 0 ]} \hyperdef{L}{X826901BD844D3F87}{} { We provide utilities to access the \href{http://www.ams.org/mathscinet/} {\textsf{ MathSciNet}} data base from within GAP. One condition for this to work is that the \textsf{IO}-package \cite{IO} is available. The other is, of course, that you use these functions from a computer which has access to \textsf{MathSciNet}. Please note, that the usual license for \textsf{MathSciNet} access does not allow for automated searches in the database. Therefore, only use the \texttt{SearchMR} (\ref{SearchMR}) function for single queries, as you would do using your webbrowser. \subsection{\textcolor{Chapter }{SearchMR}} \logpage{[ 7, 4, 1 ]}\nobreak \hyperdef{L}{X8009F8A17DDFF9AF}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SearchMR({\mdseries\slshape qurec})\index{SearchMR@\texttt{SearchMR}} \label{SearchMR} }\hfill{\scriptsize (function)}}\\ \noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{SearchMRBib({\mdseries\slshape bib})\index{SearchMRBib@\texttt{SearchMRBib}} \label{SearchMRBib} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } a list of strings, a string or \texttt{fail} The first function \texttt{SearchMR} provides the same functionality as the Web interface \href{http://www.ams.org/mathscinet/} {\textsf{ MathSciNet}}. The query strings must be given as a record, and the following components of this record are recognized: \texttt{Author}, \texttt{AuthorRelated}, \texttt{Title}, \texttt{ReviewText}, \texttt{Journal}, \texttt{InstitutionCode}, \texttt{Series}, \texttt{MSCPrimSec}, \texttt{MSCPrimary}, \texttt{MRNumber}, \texttt{Anywhere}, \texttt{References} and \texttt{Year}. Furthermore, the component \texttt{type} can be specified. It can be one of \texttt{"bibtex"} (the default if not given), \texttt{"pdf"}, \texttt{"html"} and probably others. In the last cases the function returns a string with the correspondig PDF-file or web page from \textsf{MathSciNet}. In the first case the \textsf{MathSciNet} interface returns a web page with Bib{\TeX} entries, for convenience this function returns a list of strings, each containing the Bib{\TeX} text for a single result entry. The format of a \texttt{.Year} component can be either a four digit number, optionally preceded by one of the characters \texttt{'{\textless}'}, \texttt{'{\textgreater}'} or \texttt{'='}, or it can be two four digit numbers separated by a \texttt{-} to specify a year range. The function \texttt{SearchMRBib} gets a record of a parsed Bib{\TeX} entry as input as returned by \texttt{ParseBibFiles} (\ref{ParseBibFiles}) or \texttt{ParseBibStrings} (\ref{ParseBibStrings}). It tries to generate some sensible input from this information for \texttt{SearchMR} and calls that function. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@ll := SearchMR(rec(Author:="Gauss", Title:="Disquisitiones"));;| !gapprompt@gap>| !gapinput@ll2 := List(ll, HeuristicTranslationsLaTeX2XML.Apply);;| !gapprompt@gap>| !gapinput@bib := ParseBibStrings(Concatenation(ll2));;| !gapprompt@gap>| !gapinput@bibxml := List(bib[1], StringBibAsXMLext);;| !gapprompt@gap>| !gapinput@bib2 := ParseBibXMLextString(Concatenation(bibxml));;| !gapprompt@gap>| !gapinput@for b in bib2.entries do | !gapprompt@>| !gapinput@ PrintFormattedString(StringBibXMLEntry(b, "Text")); od; | [Gau95] Gauss, C. F., Disquisitiones arithmeticae, Academia Colombiana de Ciencias Exactas Fsicas y Naturales, Coleccin Enrique Prez Arbelez [Enrique Prez Arbelez Collection], 10, Bogot (1995), xliv+495 pages, (Translated from the Latin by Hugo Barrantes Campos, Michael Josephy and ngel Ruiz Ziga, With a preface by Ruiz Ziga). [Gau86] Gauss, C. F., Disquisitiones arithmeticae, Springer-Verlag, New York (1986), xx+472 pages, (Translated and with a preface by Arthur A. Clarke, Revised by William C. Waterhouse, Cornelius Greither and A. W. Grootendorst and with a preface by Waterhouse). [Gau66] Gauss, C. F., Disquisitiones arithmeticae, Yale University Press, Translated into English by Arthur A. Clarke, S. J, New Haven, Conn. (1966), xx+472 pages. \end{Verbatim} } } } \appendix \chapter{\textcolor{Chapter }{The File \texttt{3k+1.xml}}}\label{app:3k+1} \logpage{[ "A", 0, 0 ]} \hyperdef{L}{X7DC4C82B87717D1C}{} { Here is the complete source of the example \textsf{GAPDoc} document \texttt{3k+1.xml} discussed in Section{\nobreakspace}\ref{sec:3k+1expl}. \begin{Verbatim}[fontsize=\small,frame=single,label=3k+1.xml] The <Package>ThreeKPlusOne</Package> Package Version 42 Dummy Authr 3kplusone@dev.null ©right; 2000 The Author.

You can do with this package what you want.

Really. The 3k+1 Problem

Theory Let k \in &NN; be a natural number. We consider the sequence n(i, k), i \in &NN;, with n(1, k) = k and else n(i+1, k) = n(i, k) / 2 if n(i, k) is even and n(i+1, k) = 3 n(i, k) + 1 if n(i, k) is odd.

It is not known whether for any natural number k \in &NN; there is an m \in &NN; with n(m, k) = 1.

ThreeKPlusOne provides the function to explore this for given n. If you really want to know something about this problem, see or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ for more details (and forget this package).

Program In this section we describe the main function of this package. This function computes for a natural number k the beginning of the sequence n(i, k) defined in section . The sequence stops at the first 1 or at n(max, k), if max is given. gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package"
\end{Verbatim} } \chapter{\textcolor{Chapter }{The File \texttt{gapdoc.dtd}}}\label{GAPDocdtd} \logpage{[ "B", 0, 0 ]} \hyperdef{L}{X85274DD38456275D}{} { For easier reference we repeat here the complete content of the file \texttt{gapdoc.dtd}. \begin{Verbatim}[fontsize=\small,frame=single,label=gapdoc.dtd] GAP"> GAPDoc"> {\TeX}TeX"> {\LaTeX}LaTeX"> {Bib\TeX}BibTeX"> MeatAxe"> XGAP"> \end{Verbatim} } \chapter{\textcolor{Chapter }{The File \texttt{bibxmlext.dtd}}}\label{bibxmlextdtd} \logpage{[ "C", 0, 0 ]} \hyperdef{L}{X7B5D840781E99076}{} { For easier reference we repeat here the complete content of the file \texttt{bibxmlext.dtd} which is explained in \ref{BibXMLformat}. \begin{Verbatim}[fontsize=\small,frame=single,label=bibxmlext.dtd] \end{Verbatim} } \def\bibname{References\logpage{[ "Bib", 0, 0 ]} \hyperdef{L}{X7A6F98FD85F02BFE}{} } \bibliographystyle{alpha} \bibliography{gapdocbib.xml} \addcontentsline{toc}{chapter}{References} \def\indexname{Index\logpage{[ "Ind", 0, 0 ]} \hyperdef{L}{X83A0356F839C696F}{} } \cleardoublepage \phantomsection \addcontentsline{toc}{chapter}{Index} \printindex \newpage \immediate\write\pagenrlog{["End"], \arabic{page}];} \immediate\closeout\pagenrlog \end{document} GAPDoc-1.5.1/doc/bibutil.xml0000644000175000017500000002100112026346063014116 0ustar billbill Utilities for Bibliographies A standard for collecting references (in particular to mathematical texts) is &BibTeX; (http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/). A disadvantage of &BibTeX; is that the format of the data is specified with the use by &LaTeX; in mind. The data format is less suited for conversion to other document types like plain text or HTML.

In the first section we describe utilities for using data from &BibTeX; files in &GAP;.

In the second section we introduce a new XML based data format BibXMLext for bibliographies which seems better suited for other tasks than using it with &LaTeX;.

Another section will describe utilities to deal with BibXMLext data in &GAP;.

Parsing &BibTeX; Files Here are functions for parsing, normalizing and printing reference lists in &BibTeX; format. The reference describing this format is . <#Include Label="ParseBibFiles"> <#Include Label="NormalizeNameAndKey"> <#Include Label="WriteBibFile"> <#Include Label="InfoBibTools">
The BibXMLext Format Bibliographical data in &BibTeX; files have the disadvantage that the actual data are given in &LaTeX; syntax. This makes it difficult to use the data for anything but for &LaTeX;, say for representations of the data as plain text or HTML. For example: mathematical formulae are in &LaTeX; $ environments, non-ASCII characters can be specified in many strange ways, and how to specify URLs for links if the output format allows them?

Here we propose an XML data format for bibliographical data which addresses these problems, it is called BibXMLext. In the next section we describe some tools for generating (an approximation to) this data format from &BibTeX; data, and for using data given in BibXMLext format for various purposes.

The first motivation for this development was the handling of bibliographical data in &GAPDoc;, but the format and the tools are certainly useful for other purposes as well.

We started from a DTD bibxml.dtd which is publicly available, say from http://bibtexml.sf.net/. This is essentially a reformulation of the definition of the &BibTeX; format, including several of some widely used further fields. This has already the advantage that a generic XML parser can check the validity of the data entries, for example for missing compulsary fields in entries. We applied the following changes and extensions to define the DTD for BibXMLext, stored in the file bibxmlext.dtd which can be found in the root directory of this &GAPDoc; package (and in Appendix ): names Lists of names in the author and editor fields in &BibTeX; are difficult to parse. Here they must be given by a sequence of <name>-elements which each contain an optional <first>- and a <last>-element for the first and last names, respectively. <M> and <Math> These elements enclose mathematical formulae, the content is &LaTeX; code (without the $). These should be handled in the same way as the elements with the same names in &GAPDoc;, see and . In particular, simple formulae which have a well defined plain text representation can be given in <M>-elements. Encoding Note that in XML files we can use the full range of unicode characters, see http://www.unicode.org/. All non-ASCII characters should be specified as unicode characters. This makes dealing with special characters easy for plain text or HTML, only for use with &LaTeX; some sort of translation is necessary. <URL> These elements are allowed everywhere in the text and should be represented by links in converted formats which allow this. It is used in the same way as the element with the same name in &GAPDoc;, see . <Alt Only="..."> and <Alt Not="..."> Sometimes information should be given in different ways, depending on the output format of the data. This is possible with the <Alt>-elements with the same definition as in &GAPDoc;, see . <C> This element should be used to protect text from case changes by converters (the extra {} characters in &BibTeX; title fields). <string key="..." value="..."/> and <value key="..."/> The <string>-element defines key-value pairs which can be used in any field via the <value>-element (not only for whole fields but also parts of the text). <other type="..."> This is a generic element for fields which are otherwise not supported. An arbitrary number of them is allowed for each entry, so any kind of additional data can be added to entries. <Wrap Name="..."> This generic element is allowed inside all fields. This markup will be just ignored (but not the element content) by our standard tools. But it can be a useful hook for introducing arbitrary further markup (and our tools can easily be extended to handle it). Extra entities The DTD defines the standard XML entities ( and the entities &nbsp; (non-breakable space), &ndash; and &copyright;. Use &ndash; in page ranges. For further details of the DTD we refer to the file bibxmlext.dtd itself which is shown in appendix . That file also recalls some information from the &BibTeX; documentation on how the standard fields of entries should be used. Which entry types and which fields are supported (and the ordering of the fields which is fixed by a DTD) can be either read off the DTD, or within &GAP; one can use the function to get templates for the various entry types.

Here is an example of a BibXMLext document:

]]> There is a standard XML header and a DOCTYPE declaration refering to the bibxmlext.dtd DTD mentioned above. Local entities could be defined in the DOCTYPE tag as shown in the example in . The actual content of the document is inside a <file>-element, it consists of <string>- and <entry>-elements. Several of the BibXMLext markup features are shown. We will use this input document for some examples below.
Utilities for BibXMLext data Translating &BibTeX; to BibXMLext First we describe a tool which can translate bibliography entries from &BibTeX; data to BibXMLext <entry>-elements. It also does some validation of the data. In some cases it is desirable to improve the result by hand afterwards (editing formulae, adding <URL>-elements, translating non-ASCII characters to unicode, ...).

See below for how to write the results to a BibXMLext file. <#Include Label="StringBibAsXMLext"> The following functions allow parsing of data which are already in BibXMLext format. <#Include Label="ParseBibXMLextString"> <#Include Label="WriteBibXMLextFile"> Bibliography Entries as Records For working with BibXMLext entries we find it convenient to first translate the parse tree of an entry, as returned by , to a record with the field names of the entry as components whose value is the content of the field as string. These strings are generated with respect to a result type. The records are generated by the following function which can be customized by the user. <#Include Label="RecBibXMLEntry"> <#Include Label="AddHandlerBuildRecBibXMLEntry"> <#Include Label="StringBibXMLEntry"> The following command may be useful to generate completly new bibliography entries in BibXMLext format. It also informs about the supported entry types and field names. <#Include Label="TemplateBibXML">

<#Include Label="SearchMRSection">
GAPDoc-1.5.1/doc/chapInd.txt0000644000175000017500000001351312026346063014062 0ustar billbill Index A 3.7-4 Abstract 3.2-10 Acknowledgements 3.2-12 AddHandlerBuildRecBibXMLEntry 7.3-8 AddPageNumbersToSix 5.3-4 AddParagraphNumbersGapDocTree 5.2-9 AddRootParseTree 5.2-5  3.6-5 Alt 3.9-1 Appendix 3.3-4 AppendTo1 6.3-1 ApplyToNodesParseTree 5.2-5 Arg 3.7-4 Attr 3.4-7 Author 3.2-7 B 3.7-7 Base64String 6.1-12 Bibliography 3.2-15 Body 3.3-1 Book 3.2-1 BOXCHARS 6.1-1 Br 3.9-3 Button 3.7-7 C 3.7-5 CAPITALLETTERS 6.1-1  3.6-5 Chapter 3.3-2 CheckAndCleanGapDocTree 5.2-8 Cite 3.5-3 Code 3.7-5 Colophon 3.2-13 ComposedDocument 4.2-1 ComposedXMLString 4.2-1 CopyHTMLStyleFiles 5.3-10 Copyright 3.2-11 CSS stylesheets 5.3-9 Date 3.2-8 Address 3.2-9 Description 3.4-1 DIGITS 6.1-1 DigitsNumber 6.1-9 Display 3.8-1 DisplayXMLStructure 5.2-4 E 3.7-1 Email 3.5-6 Emph 3.7-1 Encode 6.2-2 EntitySubstitution 5.2-3 Enum 3.6-4 Example 3.7-10 ExtractExamples 5.4-1 ExtractExamplesXMLTree 5.4-1 F 3.7-6 Fam 3.4-9 File 3.7-6 FileString 6.3-5 Filt 3.4-5 FormatParagraph 6.1-4 Func 3.4-2 <#GAPDoc> 4.1 GAPDoc2HTML 5.3-7 GAPDoc2HTMLPrintHTMLFiles 5.3-8 GAPDoc2LaTeX 5.3-1 GAPDoc2Text 5.3-2 GAPDoc2TextPrintTextFiles 5.3-3 GetTextXMLTree 5.2-6 Heading 3.3-3 HeuristicTranslationsLaTeX2XML.Apply 7.3-2 HeuristicTranslationsLaTeX2XML.ApplyFile 7.3-2 HEXDIGITS 6.1-1 Homepage 3.5-7  3.6-5 Ignore 3.9-4 <#Include> 4.1 Index 3.5-4 InfoBibTools 7.1-4 InfoClass 3.4-10 InfoGAPDoc 5.3-12 InfoXMLParser 5.2-10 IntListUnicodeString 6.2-1 IsUnicodeCharacter 6.2-1 IsUnicodeString 6.2-1 Item 3.6-3  in  3.6-5 K 3.7-3 Keyword 3.7-3 Label 3.5-2 LaTeXUnicodeTable 6.2-2 LETTERS 6.1-1 License .-1 List 3.6-1 Listing 3.7-9 Log 3.7-10 LowercaseUnicodeString 6.2-2 LowercaseUnicodeTable 6.2-2 M 3.8-2 MakeGAPDocDoc 5.1-1 ManSection 3.4-1 ManualExamples 5.4 Mark 3.6-2 Math 3.8-1 MathJax 5.3-7 MathJax, in MakeGAPDocDoc 5.1-1 Meth 3.4-4 NormalizedNameAndKey 7.1-2 NormalizeNameAndKey 7.1-2 NrCharsUTF8String 6.2-3 NumberDigits 6.1-9 Oper 3.4-3 OriginalPositionDocument 4.2-2 P 3.9-2 Package 3.7-8 Page 6.3-4 PageDisplay 6.3-4 Par 3.9-2 ParseBibFiles 7.1-1 ParseBibStrings 7.1-1 ParseBibXMLextFiles 7.3-4 ParseBibXMLextString 7.3-4 ParseTreeXMLFile 5.2-1 ParseTreeXMLString 5.2-1 PositionMatchingDelimiter 6.1-10 PrintFormattedString 6.3-3 PrintSixFile 5.3-5 PrintTo1 6.3-1 Prop 3.4-6 Q 3.7-2 Quoted 3.7-2 RecBibXMLEntry 7.3-7 Ref 3.5-1 RemoveRootParseTree 5.2-5 RepeatedString 6.1-8 RepeatedUTF8String 6.1-8 Returns 3.4-1 RFC 3986 6.2-1  3.6-5 RunExamples 5.4-2 SearchMR 7.4-1 SearchMRBib 7.4-1 Section 3.3-5 SetGAPDocHTMLStyle 5.3-11 SetGapDocLanguage 5.3-13 SetGapDocLaTeXOptions 5.3-1 SetGAPDocTextTheme 5.3-6 SimplifiedUnicodeString 6.2-2 SimplifiedUnicodeTable 6.2-2 SMALLLETTERS 6.1-1 StringBase64 6.1-12 StringBibAsXMLext 7.3-3 StringBibXMLEntry 7.3-9 StringFile 6.3-5 StringPrint 6.3-2 StringView 6.3-2 StringXMLElement 5.2-2 StripBeginEnd 6.1-6 StripEscapeSequences 6.1-7 Subsection 3.3-6 SubstitutionSublist 6.1-5 Subtitle 3.2-4 Table 3.6-5 TableOfContents 3.2-14 TemplateBibXML 7.3-10 TestManualExamples 5.4 TextAttr 6.1-2 TheIndex 3.2-16 Title 3.2-3 TitleComment 3.2-6 TitlePage 3.2-2 UChar 6.2-1 Unicode 6.2-1 UppercaseUnicodeString 6.2-2 URL 3.5-5 URL encoding 6.2-1 UseColorsInTerminal 6.1-2 Using GAPDoc with other languages 5.3-13 Var 3.4-8 Version 3.2-5 WHITESPACE 6.1-1 WidthUTF8String 6.2-3 WordsString 6.1-11 WrapTextAttribute 6.1-3 WriteBibFile 7.1-3 WriteBibXMLextFile 7.3-5 XML 1.1 XMLElements 5.2-7 ------------------------------------------------------- GAPDoc-1.5.1/doc/chap0.txt0000644000175000017500000002160212026346063013505 0ustar billbill GAPDoc ( Version 1.5.1 ) February 2012 Frank Lübeck Max Neunhöffer Frank Lübeck Email: mailto:Frank.Luebeck@Math.RWTH-Aachen.De Homepage: http://www.math.rwth-aachen.de/~Frank.Luebeck Max Neunhöffer Email: mailto:neunhoef at mcs.st-and.ac.uk Homepage: http://www-groups.mcs.st-and.ac.uk/~neunhoef/ ------------------------------------------------------- Copyright © 2000-2012 by Frank Lübeck and Max Neunhöffer GAPDoc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (http://www.fsf.org/licenses/gpl.html) as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ------------------------------------------------------- Contents (GAPDoc) 1 Introduction and Example 1.1 XML 1.2 A complete example 1.3 Some questions 2 How To Type a GAPDoc Document 2.1 General XML Syntax 2.1-1 Head of XML Document 2.1-2 Comments 2.1-3 Processing Instructions 2.1-4 Names in XML and Whitespace 2.1-5 Elements 2.1-6 Start Tags 2.1-7 End Tags 2.1-8 Combined Tags for Empty Elements 2.1-9 Entities 2.1-10 Special Characters in XML 2.1-11 Rules for Attribute Values 2.1-12 CDATA 2.1-13 Encoding of an XML Document 2.1-14 Well Formed and Valid XML Documents 2.2 Entering GAPDoc Documents 2.2-1 Other special characters 2.2-2 Mathematical Formulae 2.2-3 More Entities 3 The Document Type Definition 3.1 What is a DTD? 3.2 Overall Document Structure 3.2-1  3.2-2  3.2-3  3.2-4 <Subtitle> 3.2-5 <Version> 3.2-6 <TitleComment> 3.2-7 <Author> 3.2-8 <Date> 3.2-9 <Address> 3.2-10 <Abstract> 3.2-11 <Copyright> 3.2-12 <Acknowledgements> 3.2-13 <Colophon> 3.2-14 <TableOfContents> 3.2-15 <Bibliography> 3.2-16 <TheIndex> 3.3 Sectioning Elements 3.3-1 <Body> 3.3-2 <Chapter> 3.3-3 <Heading> 3.3-4 <Appendix> 3.3-5 <Section> 3.3-6 <Subsection> 3.4 ManSection–a special kind of subsection 3.4-1 <ManSection> 3.4-2 <Func> 3.4-3 <Oper> 3.4-4 <Meth> 3.4-5 <Filt> 3.4-6 <Prop> 3.4-7 <Attr> 3.4-8 <Var> 3.4-9 <Fam> 3.4-10 <InfoClass> 3.5 Cross Referencing and Citations 3.5-1 <Ref> 3.5-2 <Label> 3.5-3 <Cite> 3.5-4 <Index> 3.5-5 <URL> 3.5-6 <Email> 3.5-7 <Homepage> 3.6 Structural Elements like Lists 3.6-1 <List> 3.6-2 <Mark> 3.6-3 <Item> 3.6-4 <Enum> 3.6-5 <Table> 3.7 Types of Text 3.7-1 <Emph> and <E> 3.7-2 <Quoted> and <Q> 3.7-3 <Keyword> and <K> 3.7-4 <Arg> and <A> 3.7-5 <Code> and <C> 3.7-6 <File> and <F> 3.7-7 <Button> and <B> 3.7-8 <Package> 3.7-9 <Listing> 3.7-10 <Log> and <Example> 3.7-11 <Verb> 3.8 Elements for Mathematical Formulae 3.8-1 <Math> and <Display> 3.8-2 <M> 3.9 Everything else 3.9-1 <Alt> 3.9-2 <Par> and <P> 3.9-3 <Br> 3.9-4 <Ignore> 4 Distributing a Document into Several Files 4.1 The Conventions 4.2 A Tool for Collecting a Document 4.2-1 ComposedDocument 4.2-2 OriginalPositionDocument 5 The Converters and an XML Parser 5.1 Producing Documentation from Source Files 5.1-1 MakeGAPDocDoc 5.2 Parsing XML Documents 5.2-1 ParseTreeXMLString 5.2-2 StringXMLElement 5.2-3 EntitySubstitution 5.2-4 DisplayXMLStructure 5.2-5 ApplyToNodesParseTree 5.2-6 GetTextXMLTree 5.2-7 XMLElements 5.2-8 CheckAndCleanGapDocTree 5.2-9 AddParagraphNumbersGapDocTree 5.2-10 InfoXMLParser 5.3 The Converters 5.3-1 GAPDoc2LaTeX 5.3-2 GAPDoc2Text 5.3-3 GAPDoc2TextPrintTextFiles 5.3-4 AddPageNumbersToSix 5.3-5 PrintSixFile 5.3-6 SetGAPDocTextTheme 5.3-7 GAPDoc2HTML 5.3-8 GAPDoc2HTMLPrintHTMLFiles 5.3-9 Stylesheet files 5.3-10 CopyHTMLStyleFiles 5.3-11 SetGAPDocHTMLStyle 5.3-12 InfoGAPDoc 5.3-13 SetGapDocLanguage 5.4 Testing Manual Examples 5.4-1 ExtractExamples 5.4-2 RunExamples 6 String and Text Utilities 6.1 Text Utilities 6.1-1 WHITESPACE 6.1-2 TextAttr 6.1-3 WrapTextAttribute 6.1-4 FormatParagraph 6.1-5 SubstitutionSublist 6.1-6 StripBeginEnd 6.1-7 StripEscapeSequences 6.1-8 RepeatedString 6.1-9 NumberDigits 6.1-10 PositionMatchingDelimiter 6.1-11 WordsString 6.1-12 Base64String 6.2 Unicode Strings 6.2-1 Unicode Strings and Characters 6.2-2 Encode 6.2-3 Lengths of UTF-8 strings 6.3 Print Utilities 6.3-1 PrintTo1 6.3-2 StringPrint 6.3-3 PrintFormattedString 6.3-4 Page 6.3-5 StringFile 7 Utilities for Bibliographies 7.1 Parsing BibTeX Files 7.1-1 ParseBibFiles 7.1-2 NormalizedNameAndKey 7.1-3 WriteBibFile 7.1-4 InfoBibTools 7.2 The BibXMLext Format 7.3 Utilities for BibXMLext data 7.3-1 Translating BibTeX to BibXMLext 7.3-2 HeuristicTranslationsLaTeX2XML.Apply 7.3-3 StringBibAsXMLext 7.3-4 ParseBibXMLextString 7.3-5 WriteBibXMLextFile 7.3-6 Bibliography Entries as Records 7.3-7 RecBibXMLEntry 7.3-8 AddHandlerBuildRecBibXMLEntry 7.3-9 StringBibXMLEntry 7.3-10 TemplateBibXML 7.4 Getting BibTeX entries from MathSciNet 7.4-1 SearchMR A The File 3k+1.xml B The File gapdoc.dtd C The File bibxmlext.dtd  ������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/doc/conv.xml���������������������������������������������������������������������������0000644�0001750�0001750�00000024107�12026346063�013443� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� <Chapter Label="ch:conv"> <Heading>The Converters and an XML Parser</Heading> The &GAPDoc; package contains a set of programs which allow us to convert a &GAPDoc; book into several output versions and to make them available to &GAP;'s online help.<P/> Currently the following output formats are provided: text for browsing inside a terminal running &GAP;, &LaTeX; with <C>hyperref</C>-package for cross references via hyperlinks and HTML for reading with a Web-browser.<P/> <Section Label="MakeDoc"> <Heading>Producing Documentation from Source Files</Heading> Here we explain how to use the functions which are described in more detail in the following sections. We assume that we have the main file <F>MyBook.xml</F> of a book <C>"MyBook"</C> in the directory <F>/my/book/path</F>. This contains <C><#Include ...></C>-statements as explained in Chapter <Ref Sect="Distributing"/>. These refer to some other files as well as pieces of text which are found in the comments of some &GAP; source files <F>../lib/a.gd</F> and <F>../lib/b.gi</F> (relative to the path above). A &BibTeX; database <F>MyBook.bib</F> for the citations is also in the directory given above. We want to produce a text-, <C>pdf-</C> and HTML-version of the document. (A &LaTeX; version of the manual is produced, so it is also easy to compile <C>dvi</C>-, and postscript-versions.)<P/> All the commands shown in this Section are collected in the single function <Ref Func="MakeGAPDocDoc"/>.<P/> First we construct the complete XML-document as a string with <Ref Func="ComposedDocument"/>. This interprets recursively the <C><#Include ...></C>-statements. <Log> gap> path := Directory("/my/book/path");; gap> main := "MyBook.xml";; gap> files := ["../lib/a.gd", "../lib/b.gi"];; gap> bookname := "MyBook";; gap> doc := ComposedDocument("GAPDoc", path, main, files, true);; </Log> Now <C>doc</C> is a list with two entries, the first is a string containing the XML-document, the second gives information from which files and locations which part of the document was collected. This is useful in the next step, if there are any errors in the document. <P/> Next we parse the document and store its structure in a tree-like data structure. The commands for this are <Ref Func="ParseTreeXMLString"/> and <Ref Func="CheckAndCleanGapDocTree"/>. <Log> gap> r := ParseTreeXMLString(doc[1], doc[2]);; gap> CheckAndCleanGapDocTree(r); true </Log> We start to produce a text version of the manual, which can be read in a terminal (window). The command is <Ref Func="GAPDoc2Text"/>. This produces a record with the actual text and some additional information. The text can be written chapter-wise into files with <Ref Func="GAPDoc2TextPrintTextFiles"/>. The names of these files are <F>chap0.txt</F>, <F>chap1.txt</F> and so on. The text contains some markup using ANSI escape sequences. This markup is substituted by the &GAP; help system (user configurable) to show the text with colors and other attributes. For the bibliography we have to tell <Ref Func="GAPDoc2Text"/> the location of the &BibTeX; database by specifying a <C>path</C> as second argument. <Log> gap> t := GAPDoc2Text(r, path);; gap> GAPDoc2TextPrintTextFiles(t, path); </Log> This command constructs all parts of the document including table of contents, bibliography and index. The functions <Ref Func="FormatParagraph"/> for formatting text paragraphs and <Ref Func="ParseBibFiles"/> for reading &BibTeX; files with &GAP; may be of independent interest.<P/> With the text version we have also produced the information which is used for searching with &GAP;'s online help. Also, labels are produced which can be used by links in the HTML- and <C>pdf</C>-versions of the manual. <P/> Next we produce a &LaTeX; version of the document. <Ref Func="GAPDoc2LaTeX"/> returns a string containing the &LaTeX; source. The utility function <Ref Func="FileString"/> writes the content of a string to a file, we choose <F>MyBook.tex</F>. <Log> gap> l := GAPDoc2LaTeX(r);; gap> FileString(Filename(path, Concatenation(bookname, ".tex")), l); </Log> Assuming that you have a sufficiently good installation of &TeX; available (see <Ref Func="GAPDoc2LaTeX"/> for details) this can be processed with a series of commands like in the following example. <Log> cd /my/book/path pdflatex MyBook bibtex MyBook pdflatex MyBook makeindex MyBook pdflatex MyBook mv MyBook.pdf manual.pdf </Log> After this we have a <C>pdf</C>-version of the document in the file <F>manual.pdf</F>. It contains hyperlink information which can be used with appropriate browsers for convenient reading of the document on screen (e.g., <C>xpdf</C> is nice because it allows remote calls to display named locations of the document). Of course, we could also use other commands like <C>latex</C> or <C>dvips</C> to process the &LaTeX; source file. Furthermore we have produced a file <F>MyBook.pnr</F> which is &GAP;-readable and contains the page number information for each (sub-)section of the document. <P/> We can add this page number information to the indexing information collected by the text converter and then print a <F>manual.six</F> file which is read by &GAP; when the manual is loaded. This is done with <Ref Func="AddPageNumbersToSix"/> and <Ref Func="PrintSixFile"/>. <Log> gap> AddPageNumbersToSix(r, Filename(path, "MyBook.pnr")); gap> PrintSixFile(Filename(path, "manual.six"), r, bookname); </Log> Finally we produce an HTML-version of the document and write it (chapter-wise) into files <F>chap0.html</F>, <F>chap1.html</F> and so on. They can be read with any Web-browser. The commands are <Ref Func="GAPDoc2HTML"/> and <Ref Func="GAPDoc2HTMLPrintHTMLFiles"/>. We also add a link from <F>manual.html</F> to <F>chap0.html</F>. You probably want to copy stylesheet files into the same directory, see <Ref Subsect="StyleSheets"/> for more details. The argument <C>path</C> of <Ref Func="GAPDoc2HTML"/> specifies the directory containing the &BibTeX; database files. <Log> gap> h := GAPDoc2HTML(r, path);; gap> GAPDoc2HTMLPrintHTMLFiles(h, path); </Log> <ManSection > <Func Arg="path, main, files, bookname[, gaproot]" Name="MakeGAPDocDoc" /> <Description> This function collects all the commands for producing a text-, <C>pdf</C>- and HTML-version of a &GAPDoc; document as described in Section <Ref Sect="MakeDoc"/>. It checks the <C>.log</C> file from the call of <C>pdflatex</C> and reports if there are errors, warnings or overfull boxes.<P/> <Emph>Note:</Emph> If this function works for you depends on your operating system and installed software. It will probably work on most <C>UNIX</C> systems with a standard &LaTeX; installation. If the function doesn't work for you look at the source code and adjust it to your system. <P/> Here <A>path</A> must be the directory (as string or directory object) containing the main file <A>main</A> of the document (given with or without the <C>.xml</C> extension. The argument <A>files</A> is a list of (probably source code) files relative to <A>path</A> which contain pieces of documentation which must be included in the document, see Chapter <Ref Chap="Distributing"/>. And <A>bookname</A> is the name of the book used by &GAP;'s online help. The optional argument <A>gaproot</A> must be a string which gives the relative path from <A>path</A> to the main &GAP; root directory. If this is given, the HTML files are produced with relative paths to external books.<P/> <Index Key="MathJax" Subkey="in MakeGAPDocDoc"><Package>MathJax</Package> <Subkey>in <C>MakeGAPDocDoc</C></Subkey></Index> <Ref Func="MakeGAPDocDoc"/> can be called with additional arguments <C>"MathJax"</C>, <C>"Tth"</C> and/or <C>"MathML"</C>. If these are given additional variants of the HTML conversion are called, see <Ref Func="GAPDoc2HTML"/> for details.<P/> It is possible to use &GAPDoc; with other languages than English, see <Ref Func="SetGapDocLanguage"/> for more details.<P/> </Description> </ManSection> </Section> <Section Label="ParseXML"> <Heading>Parsing XML Documents</Heading> Arbitrary well-formed XML documents can be parsed and browsed by the following functions. <#Include Label="ParseTreeXMLString"> <#Include Label="StringXMLElement"> <#Include Label="EntitySubstitution"> <#Include Label="DisplayXMLStructure"> <#Include Label="ApplyToNodesParseTree"> Here are two more utilities which use <Ref Func="ApplyToNodesParseTree"/>. <#Include Label="GetTextXMLTree"> <#Include Label="XMLElements"> And here are utilities for processing &GAPDoc; XML documents. <#Include Label="CheckAndCleanGapDocTree"> <#Include Label="AddParagraphNumbersGapDocTree"> <#Include Label="InfoXMLParser"> </Section> <Section Label="Converters"> <Heading>The Converters</Heading> Here are more details about the conversion programs for &GAPDoc; XML documents. <#Include Label="GAPDoc2LaTeX"> <#Include Label="GAPDoc2Text"> <#Include Label="GAPDoc2TextPrintTextFiles"> <#Include Label="AddPageNumbersToSix"> <#Include Label="PrintSixFile"> <#Include Label="SetGAPDocTextTheme"> <#Include Label="GAPDoc2HTML"> <#Include Label="GAPDoc2HTMLPrintHTMLFiles"> <#Include Label="HTMLStyleSheets"> <#Include Label="SetGAPDocHTMLStyle"> <#Include Label="InfoGAPDoc"> <#Include Label="SetGapDocLanguage"> </Section> <Section Label="Sec:TestExample"> <Index><C>ManualExamples</C></Index> <Index><C>TestManualExamples</C></Index> <Heading>Testing Manual Examples</Heading> We also provide some tools to check and adjust the examples given in <C><Example></C>-elements. <P/> Former versions of &GAPDoc; provided functions <C>ManualExamples</C> and <C>TestManualExamples</C>. These functions are still available, but no longer documented. Their use is deprecated. <#Include Label="ExtractExamples"> <#Include Label="RunExamples"> </Section> </Chapter> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/doc/chapInd.html�����������������������������������������������������������������������0000644�0001750�0001750�00000046342�12026346063�014215� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>GAP (GAPDoc) - Index
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

Index

ManualExamples 5.4
TestManualExamples 5.4
A 3.7-4
Abstract 3.2-10
Acknowledgements 3.2-12
AddHandlerBuildRecBibXMLEntry 7.3-8
AddPageNumbersToSix 5.3-4
AddParagraphNumbersGapDocTree 5.2-9
AddRootParseTree 5.2-5
<Align> 3.6-5
Alt 3.9-1
Appendix 3.3-4
AppendTo1 6.3-1
ApplyToNodesParseTree 5.2-5
Arg 3.7-4
Attr 3.4-7
Author 3.2-7
B 3.7-7
Base64String 6.1-12
Bibliography 3.2-15
Body 3.3-1
Book 3.2-1
BOXCHARS 6.1-1
Br 3.9-3
Button 3.7-7
C 3.7-5
CAPITALLETTERS 6.1-1
<Caption> 3.6-5
Chapter 3.3-2
CheckAndCleanGapDocTree 5.2-8
Cite 3.5-3
Code 3.7-5
Colophon 3.2-13
ComposedDocument 4.2-1
ComposedXMLString 4.2-1
CopyHTMLStyleFiles 5.3-10
Copyright 3.2-11
CSS stylesheets 5.3-9
Date 3.2-8
Address 3.2-9
Description 3.4-1
DIGITS 6.1-1
DigitsNumber 6.1-9
Display 3.8-1
DisplayXMLStructure 5.2-4
E 3.7-1
Email 3.5-6
Emph 3.7-1
Encode 6.2-2
EntitySubstitution 5.2-3
Enum 3.6-4
Example 3.7-10
ExtractExamples 5.4-1
ExtractExamplesXMLTree 5.4-1
F 3.7-6
Fam 3.4-9
File 3.7-6
FileString 6.3-5
Filt 3.4-5
FormatParagraph 6.1-4
Func 3.4-2
<#GAPDoc> 4.1
GAPDoc2HTML 5.3-7
GAPDoc2HTMLPrintHTMLFiles 5.3-8
GAPDoc2LaTeX 5.3-1
GAPDoc2Text 5.3-2
GAPDoc2TextPrintTextFiles 5.3-3
GetTextXMLTree 5.2-6
Heading 3.3-3
HeuristicTranslationsLaTeX2XML.Apply 7.3-2
HeuristicTranslationsLaTeX2XML.ApplyFile 7.3-2
HEXDIGITS 6.1-1
Homepage 3.5-7
<HorLine> 3.6-5
Ignore 3.9-4
<#Include> 4.1
Index 3.5-4
InfoBibTools 7.1-4
InfoClass 3.4-10
InfoGAPDoc 5.3-12
InfoXMLParser 5.2-10
IntListUnicodeString 6.2-1
IsUnicodeCharacter 6.2-1
IsUnicodeString 6.2-1
Item 3.6-3
<Item> in <Table> 3.6-5
K 3.7-3
Keyword 3.7-3
Label 3.5-2
LaTeXUnicodeTable 6.2-2
LETTERS 6.1-1
License .-1
List 3.6-1
Listing 3.7-9
Log 3.7-10
LowercaseUnicodeString 6.2-2
LowercaseUnicodeTable 6.2-2
M 3.8-2
MakeGAPDocDoc 5.1-1
ManSection 3.4-1
Mark 3.6-2
Math 3.8-1
MathJax 5.3-7
MathJax, in MakeGAPDocDoc 5.1-1
Meth 3.4-4
NormalizedNameAndKey 7.1-2
NormalizeNameAndKey 7.1-2
NrCharsUTF8String 6.2-3
NumberDigits 6.1-9
Oper 3.4-3
OriginalPositionDocument 4.2-2
P 3.9-2
Package 3.7-8
Page 6.3-4
PageDisplay 6.3-4
Par 3.9-2
ParseBibFiles 7.1-1
ParseBibStrings 7.1-1
ParseBibXMLextFiles 7.3-4
ParseBibXMLextString 7.3-4
ParseTreeXMLFile 5.2-1
ParseTreeXMLString 5.2-1
PositionMatchingDelimiter 6.1-10
PrintFormattedString 6.3-3
PrintSixFile 5.3-5
PrintTo1 6.3-1
Prop 3.4-6
Q 3.7-2
Quoted 3.7-2
RecBibXMLEntry 7.3-7
Ref 3.5-1
RemoveRootParseTree 5.2-5
RepeatedString 6.1-8
RepeatedUTF8String 6.1-8
Returns 3.4-1
RFC 3986 6.2-1
<Row> 3.6-5
RunExamples 5.4-2
SearchMR 7.4-1
SearchMRBib 7.4-1
Section 3.3-5
SetGAPDocHTMLStyle 5.3-11
SetGapDocLanguage 5.3-13
SetGapDocLaTeXOptions 5.3-1
SetGAPDocTextTheme 5.3-6
SimplifiedUnicodeString 6.2-2
SimplifiedUnicodeTable 6.2-2
SMALLLETTERS 6.1-1
StringBase64 6.1-12
StringBibAsXMLext 7.3-3
StringBibXMLEntry 7.3-9
StringFile 6.3-5
StringPrint 6.3-2
StringView 6.3-2
StringXMLElement 5.2-2
StripBeginEnd 6.1-6
StripEscapeSequences 6.1-7
Subsection 3.3-6
SubstitutionSublist 6.1-5
Subtitle 3.2-4
Table 3.6-5
TableOfContents 3.2-14
TemplateBibXML 7.3-10
TextAttr 6.1-2
TheIndex 3.2-16
Title 3.2-3
TitleComment 3.2-6
TitlePage 3.2-2
UChar 6.2-1
Unicode 6.2-1
UppercaseUnicodeString 6.2-2
URL 3.5-5
URL encoding 6.2-1
UseColorsInTerminal 6.1-2
Using GAPDoc with other languages 5.3-13
Var 3.4-8
Version 3.2-5
WHITESPACE 6.1-1
WidthUTF8String 6.2-3
WordsString 6.1-11
WrapTextAttribute 6.1-3
WriteBibFile 7.1-3
WriteBibXMLextFile 7.3-5
XML 1.1
XMLElements 5.2-7

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chapC_mj.html0000644000175000017500000005746612026346063014364 0ustar billbill GAP (GAPDoc) - Appendix C: The File bibxmlext.dtd
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

C The File bibxmlext.dtd

For easier reference we repeat here the complete content of the file bibxmlext.dtd which is explained in 7.2.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  - (C) Frank Lübeck (http://www.math.rwth-aachen.de/~Frank.Luebeck)
  -
  - The BibXMLext data format.
  - 
  - This DTD expresses XML markup similar to the BibTeX language
  - specified for LaTeX, or actually its content model.
  -
  - It is a variation of a file bibxml.dtd developed by the project
  -   http://bibtexml.sf.net/
  - 
  - For documentation on BibTeX, see
  -   http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/
  -
  - A previous version of the code originally developed by
  - Vidar Bronken Gundersen, http://bibtexml.sf.net/
  - Reuse and repurposing is approved as long as this
  - notification appears with the code.
  -
-->

<!-- ..................................................................... -->
<!-- Main structure -->

<!-- key-value pairs as in BibTeX @string entries are put in empty elements
     (but here they can be used for parts of an entry field as well)       -->
<!ELEMENT string EMPTY>
<!ATTLIST string
   key        CDATA     #REQUIRED 
   value      CDATA     #REQUIRED >
   
<!-- entry may contain one of the bibliographic types. -->
<!ELEMENT entry ( article | book | booklet |
                         manual | techreport |
                         mastersthesis | phdthesis |
                         inbook | incollection |
                         proceedings | inproceedings |
                         conference |
                         unpublished | misc ) >
<!ATTLIST entry
   id         CDATA     #REQUIRED >

<!-- file is the documents top element. -->
<!ELEMENT file  ( string | entry )* >


<!-- ..................................................................... -->
<!-- Parameter entities -->

<!-- these are additional elements often used, but not included in the
     standard BibTeX distribution, these must be added to the
     bibliography styles, otherwise these fields will be omitted by
     the formatter, we allow an arbitrary number of 'other' elements
     to specify any further information   -->

<!ENTITY   %  n.user " abstract?, affiliation?,
                        contents?, copyright?,
                        (isbn | issn)?, 
                        keywords?, language?, lccn?, 
                        location?, mrnumber?, mrclass?, mrreviewer?,
                        price?, size?, url?, category?, other* ">

<!ENTITY   %  n.common "key?, annotate?, crossref?,
                        %n.user;">

<!-- content model used more than once -->

<!ENTITY   %  n.InProceedings "author, title, booktitle,
                    year, editor?, 
                    (volume | number)?,
                    series?, pages?, address?, 
                    month?, organization?, publisher?,
                    note?, %n.common;">

<!ENTITY   %  n.PHDThesis "author, title, school,
                    year, type?, address?, month?,
                    note?, %n.common;">

<!-- ..................................................................... -->
<!-- Entries in the BibTeX database -->

<!-- [article] An article from a journal or magazine.
  -  Required fields: author, title, journal, year.
  -  Optional fields: volume, number, pages, month, note. -->
<!ELEMENT   article    (author, title, journal,
               year, volume?, number?, pages?,
               month?, note?, %n.common;)
>

<!-- [book] A book with an explicit publisher.  
  -  Required fields: author or editor, title, publisher, year.
  -  Optional fields: volume or number, series, address,
  -     edition, month, note. -->
<!ELEMENT   book    ((author | editor), title,
               publisher, year, (volume | number)?,
               series?, address?, edition?, month?,
               note?, %n.common;)
>
	   
<!-- [booklet] A work that is printed and bound, but without a named
  -  publisher or sponsoring institution  
  -  Required field: title.
  -  Optional fields: author, howpublished, address, month, year, note. -->
<!ELEMENT   booklet    (author?, title,
               howpublished?, address?, month?, 
               year?, note?, %n.common;)
>

<!-- [conference] The same as INPROCEEDINGS,
  -  included for Scribe compatibility. -->
<!ELEMENT   conference      (%n.InProceedings;)
>

<!-- [inbook] A part of a book, which may be a chapter (or section or
  -  whatever) and/or a range of pages.  
  -  Required fields: author or editor, title, chapter and/or pages,
  -     publisher, year.
  -  Optional fields: volume or number, series, type, address,
  -     edition, month, note. -->
<!ELEMENT   inbook    ((author | editor), title,
               ((chapter, pages?) | pages),
               publisher, year, (volume |
               number)?, series?, type?,
               address?, edition?, month?, 
               note?, %n.common;)
>

<!--
  - > I want to express that the elements a and/or b are legal that is one
  - > of them or both must be present in the document instance (see the
  - > element content for BibTeX entry `InBook').
  - > How do I specify this in my DTD?
  - 
  - Dave Peterson:
  -  in content model:   ((a , b?) | b)          if order matters
  -                      ((a , b?) | (b , a?))   otherwise
-->

<!-- [incollection] A part of a book having its own title.
  -  Required fields: author, title, booktitle, publisher, year.
  -  Optional fields: editor, volume or number, series, type,
  -     chapter, pages, address, edition, month, note. -->
<!ELEMENT   incollection    (author, title,
               booktitle, publisher, year,
               editor?, (volume | number)?,
               series?, type?, chapter?, 
               pages?, address?, edition?, 
               month?, note?,
               %n.common;)
>

<!-- [inproceedings] An article in a conference proceedings.
  -  Required fields: author, title, booktitle, year.
  -  Optional fields: editor, volume or number, series, pages,
  -     address, month, organization, publisher, note. -->
<!ELEMENT   inproceedings      (%n.InProceedings;)
>

<!-- [manual] Technical documentation  
  -  Required field: title.
  -  Optional fields: author, organization, address,
  -     edition, month, year, note. -->
<!ELEMENT   manual    (author?, title,
               organization?, address?, edition?,
               month?, year?, note?, %n.common;)
>

<!-- [mastersthesis] A Master's thesis.  
  -  Required fields: author, title, school, year.
  -  Optional fields: type, address, month, note. -->
<!ELEMENT   mastersthesis      (%n.PHDThesis;)
>

<!-- [misc] Use this type when nothing else fits.  
  -  Required fields: none.
  -  Optional fields: author, title, howpublished, month, year, note. -->
<!ELEMENT   misc    (author?, title?,
               howpublished?, month?, year?, note?,
               %n.common;)
>

<!-- [phdthesis] A PhD thesis.  
  -  Required fields: author, title, school, year.
  -  Optional fields: type, address, month, note. -->
<!ELEMENT   phdthesis      (%n.PHDThesis;)
>

<!-- [proceedings] The proceedings of a conference.  
  -  Required fields: title, year.
  -  Optional fields: editor, volume or number, series,
  -     address, month, organization, publisher, note. -->
<!ELEMENT   proceedings    (editor?, title, year,
               (volume | number)?, series?, 
               address?, month?, organization?, 
               publisher?, note?, %n.common;)
>

<!-- [techreport] A report published by a school or other institution,
  -  usually numbered within a series.  
  -  Required fields: author, title, institution, year.
  -  Optional fields: type, number, address, month, note. -->
<!ELEMENT   techreport    (author, title,
               institution, year, type?, number?,
               address?, month?, note?, %n.common;)
>

<!-- [unpublished] A document having an author and title, but not
  -  formally published.  
  -  Required fields: author, title, note.
  -  Optional fields: month, year. -->
<!ELEMENT   unpublished    (author, title, note,
               month?, year?, %n.common;)
>

<!-- ..................................................................... -->
<!-- Fields from the standard bibliography styles -->

<!--
  - Below is a description of all fields recognized by the standard
  - bibliography styles.  An entry can also contain other fields, which
  - are ignored by those styles.
  - 
  - [address] Usually the address of the publisher or other type of
  - institution  For major publishing houses, van~Leunen recommends
  - omitting the information entirely.  For small publishers, on the other
  - hand, you can help the reader by giving the complete address.
  - 
  - [annote] An annotation  It is not used by the standard bibliography
  - styles, but may be used by others that produce an annotated
  - bibliography.
  - 
  - [author] The name(s) of the author(s), here *not* in the format 
  - described in the LaTeX book. Contains elements <name> which in turn
  - contains elements <first>, <last> for the first name (or first names,
  - fully written or as initials, and including middle initials) and
  - the last name.
  - 
  - [booktitle] Title of a book, part of which is being cited.  See the
  - LaTeX book for how to type titles.  For book entries, use the title
  - field instead.
  - 
  - [chapter] A chapter (or section or whatever) number.
  - 
  - [crossref] The database key of the entry being cross referenced.
  - 
  - [edition] The edition of a book-for example, ``Second''.  This
  - should be an ordinal, and should have the first letter capitalized, as
  - shown here; the standard styles convert to lower case when necessary.
  - 
  - [editor] Name(s) of editor(s), typed as indicated in the LaTeX book.
  - If there is also an author field, then the editor field gives the
  - editor of the book or collection in which the reference appears.
  - 
  - [howpublished] How something strange has been published.  The first
  - word should be capitalized.
  - 
  - [institution] The sponsoring institution of a technical report.
  - 
  - [journal] A journal name.  Abbreviations are provided for many
  - journals; see the Local Guide.
  - 
  - [key] Used for alphabetizing, cross referencing, and creating a label
  - when the ``author'' information (described in Section [ref: ] is
  - missing. This field should not be confused with the key that appears
  - in the \cite command and at the beginning of the database entry.
  - 
  - [month] The month in which the work was published or, for an
  - unpublished work, in which it was written. You should use the
  - standard three-letter abbreviation, as described in Appendix B.1.3 of
  - the LaTeX book.
  - 
  - [note] Any additional information that can help the reader.  The first
  - word should be capitalized.
  - 
  - [number] The number of a journal, magazine, technical report, or of a
  - work in a series.  An issue of a journal or magazine is usually
  - identified by its volume and number; the organization that issues a
  - technical report usually gives it a number; and sometimes books are
  - given numbers in a named series.
  - 
  - [organization] The organization that sponsors a conference or that
  - publishes a manual.
  - 
  - [pages] One or more page numbers or range of numbers, such as 42-111
  - or 7,41,73-97 or 43+ (the `+' in this last example indicates pages
  - following that don't form a simple range).  To make it easier to
  - maintain Scribe-compatible databases, the standard styles convert a
  - single dash (as in 7-33) to the double dash used in TeX to denote
  - number ranges (as in 7-33). Here, we suggest to use the entity
  - &ndash; for a dash in page ranges.
  - 
  - [publisher] The publisher's name.
  - 
  - [school] The name of the school where a thesis was written.
  - 
  - [series] The name of a series or set of books.  When citing an entire
  - book, the the title field gives its title and an optional series field
  - gives the name of a series or multi-volume set in which the book is
  - published.
  - 
  - [title] The work's title. For mathematical formulae use the <M> or
  - <Math> elements explained below (and LaTeX code in the content, without
  - surrounding '$').
  - 
  - [type] The type of a technical report-for example, ``Research
  - Note''.
  - 
  - [volume] The volume of a journal or multivolume book.
  - 
  - [year] The year of publication or, for an unpublished work, the year
  - it was written.  Generally it should consist of four numerals, such as
  - 1984, although the standard styles can handle any year whose last four
  - nonpunctuation characters are numerals, such as `(about 1984)'.
-->

<!-- Here is the main extension compared to the original BibXML definition
     from which is DTD is derived: We want to allow more markup in some 
     elements such that we can use the bibliography for high quality 
     output in other formats than LaTeX. 
     
     - <M> and <Math>, mathematical formulae: Specify LaTeX code for "simple" 
       formulae as content of <M> elements; "simple" means that they can be
       translated to a fairly readable ASCII representation as explained in
       the GAPDoc documentation on "<M>". 
       More complicated formulae are given as content of <Math> elements.
       (Think about an <Alt> alternative for text or HTML representations.)
     
     - <URL>: use these elements to specify URLs, they can be properly
       converted to links if possible in an output format (in that case 
       the Text attribute is used for the visible text).

     - <value key="..."/>:  substituted by the value-attribute specified
       in a <string key="..." value="..."/> element. Can be used anywhere,
       not only for complete fields as in BibTeX.

     - <C> protect case changes: should be used instead of {}'s which are
       used in BibTeX title fields to protect the case of letters from
       changes. 

     - <Alt Only="...">, <Alt Not="...">, alternatives for different 
       output formats:  Use this to specify alternatives, the GAPDoc
       utilities will do some special handling for "Text", "HTML",
       and "BibTeX" as output type.

     - <Wrap Name="...">, generic wrapper for other markup:
       Use this for any other type of markup you are interested in. The
       GAPDoc utilities will ignore the markup, but provide a hook
       to do install handler functions for them.
-->
<!ELEMENT   M               (#PCDATA | Alt)* > <!-- math with simple text
                                             representation, in LaTeX -->
<!ELEMENT   Math            (#PCDATA | Alt)* > <!-- other math in LaTeX -->
<!ELEMENT   URL             (#PCDATA | Alt | Link | LinkText)* > <!-- an URL -->
<!ATTLIST   URL Text CDATA #IMPLIED>    <!-- text to be printed 
                                             (default is content) -->
<!ELEMENT   value             EMPTY   > <!-- placeholder for value given .. -->
<!ATTLIST   value key CDATA #REQUIRED > <!-- .. by key, defined in a string
                                             element -->
<!ELEMENT   C    (#PCDATA | value | Alt |
                  M | Math | Wrap | URL)* >  <!-- protect from case changes -->
<!ELEMENT   Alt  (#PCDATA | value | C | Alt |    
                  M | Math | Wrap | URL)* > <!-- specify alternatives for 
                                             various types of output -->
<!ATTLIST   Alt  Only CDATA #IMPLIED
                 Not  CDATA #IMPLIED  > <!-- specify output types in comma and 
                  whitespace separated list (use exactly one of Only or Not) -->

<!ENTITY % withMURL "(#PCDATA | value | M | Math | Wrap | URL | C | Alt )*" >

<!ELEMENT   Wrap           %withMURL; > <!-- a generic wrapper  -->
<!ATTLIST   Wrap Name CDATA #REQUIRED > <!-- needs a 'Name' attribute  -->

<!ELEMENT   address         %withMURL; >
<!-- here we don't want the complicated definition from the LaTeX book,
     use markup for first/last name(s): a <name> element for each
     author which contains <first> (optional), <last> elements:  -->
<!ELEMENT   author          (name)* >
<!ELEMENT   name            (first?, last) >
<!ELEMENT   first           (#PCDATA) >
<!ELEMENT   last            (#PCDATA) >

<!ELEMENT   booktitle       %withMURL; >
<!ELEMENT   chapter         %withMURL; >
<!ELEMENT   edition         %withMURL; >
<!-- same as for author field -->
<!ELEMENT   editor          (name)* >
<!ELEMENT   howpublished    %withMURL; >
<!ELEMENT   institution     %withMURL; >
<!ELEMENT   journal         %withMURL; >
<!ELEMENT   month           %withMURL; >
<!ELEMENT   note            %withMURL; >
<!ELEMENT   number          %withMURL; >
<!ELEMENT   organization    %withMURL; >
<!ELEMENT   pages           %withMURL; >
<!ELEMENT   publisher       %withMURL; >
<!ELEMENT   school          %withMURL; >
<!ELEMENT   series          %withMURL; >
<!ELEMENT   title           %withMURL; >
<!ELEMENT   type            %withMURL; >
<!ELEMENT   volume          %withMURL; >
<!ELEMENT   year            (#PCDATA) >

<!-- These were not listed in the documentation for entry content, but
  -  appeared in the list of fields in the BibTeX documentation -->

<!ELEMENT   annotate        %withMURL; >
<!ELEMENT   crossref        %withMURL; >
<!ELEMENT   key             (#PCDATA) >


<!-- ..................................................................... -->
<!-- Other popular fields
  - 
  - From: http://www.ecst.csuchico.edu/~jacobsd/bib/formats/bibtex.html
  - BibTeX is extremely popular, and many people have used it to store
  - information. Here is a list of some of the more common fields:
  - 
  - [affiliation]  The authors affiliation. 
  - [abstract]  An abstract of the work. 
  - [contents]  A Table of Contents 
  - [copyright]  Copyright information. 
  - [ISBN]  The International Standard Book Number. 
  - [ISSN]  The International Standard Serial Number. 
  -         Used to identify a journal. 
  - [keywords]  Key words used for searching or possibly for annotation. 
  - [language]  The language the document is in. 
  - [location]  A location associated with the entry,
  -             such as the city in which a conference took place.
  - [LCCN]  The Library of Congress Call Number.
  -         I've also seen this as lib-congress. 
  - [mrnumber]  The Mathematical Reviews number. 
  - [mrclass]  The Mathematical Reviews class. 
  - [mrreviewer]  The Mathematical Reviews reviewer. 
  - [price]  The price of the document. 
  - [size]  The physical dimensions of a work. 
  - [URL] The WWW Universal Resource Locator that points to the item being
  -       referenced. This often is used for technical reports to point to the
  -       ftp site where the postscript source of the report is located.
  - 
  - When using BibTeX with LaTeX you need
  - BibTeX style files to print these data.
-->

<!ELEMENT   abstract        %withMURL; >
<!ELEMENT   affiliation     %withMURL; >
<!ELEMENT   contents        %withMURL; >
<!ELEMENT   copyright       %withMURL; >
<!ELEMENT   isbn            (#PCDATA) >
<!ELEMENT   issn            (#PCDATA) >
<!ELEMENT   keywords        %withMURL; >
<!ELEMENT   language        %withMURL; >
<!ELEMENT   lccn            (#PCDATA) >
<!ELEMENT   location        %withMURL; >
<!ELEMENT   mrnumber        %withMURL; >
<!ELEMENT   mrclass         %withMURL; >
<!ELEMENT   mrreviewer      %withMURL; >
<!ELEMENT   price           %withMURL; >
<!ELEMENT   size            %withMURL; >
<!ELEMENT   url             %withMURL; >


<!-- Added by Zeger W. Hendrikse
  - [category]  Category of this bibitem
-->
<!ELEMENT   category      %withMURL; >

<!-- A container element [other] for any further information, a description 
   - of the type of data must be given in the attribute 'type' 
-->
<!ELEMENT   other      %withMURL; >
<!ATTLIST   other
    type      CDATA   #REQUIRED >


<!-- ..................................................................... -->
<!-- Predefined/reserved character entities -->

<!ENTITY amp    "&#38;#38;">
<!ENTITY lt     "&#38;#60;">
<!ENTITY gt     "&#62;">
<!ENTITY apos   "&#39;">
<!ENTITY quot   "&#34;">


<!-- Some more generally useful entities -->
<!ENTITY nbsp "&#160;">
<!ENTITY copyright "&#169;">
<!ENTITY ndash "&#x2013;">
 

<!-- ..................................................................... -->
<!-- End of BibXMLext dtd -->

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chapA_mj.html0000644000175000017500000001327512026346063014350 0ustar billbill GAP (GAPDoc) - Appendix A: The File 3k+1.xml
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

A The File 3k+1.xml

Here is the complete source of the example GAPDoc document 3k+1.xml discussed in Section 1.2.

<?xml version="1.0" encoding="UTF-8"?>

<!--   A complete "fake package" documentation   
-->

<!DOCTYPE Book SYSTEM "gapdoc.dtd">

<Book Name="3k+1">

<TitlePage>
  <Title>The <Package>ThreeKPlusOne</Package> Package</Title>
  <Version>Version 42</Version>
  <Author>Dummy Authör
    <Email>3kplusone@dev.null</Email>
  </Author>

  <Copyright>&copyright; 2000 The Author. <P/>
    You can do with this package what you want.<P/> Really.
  </Copyright>
</TitlePage>

<TableOfContents/>

<Body>
  <Chapter> <Heading>The <M>3k+1</M> Problem</Heading>
    <Section Label="sec:theory"> <Heading>Theory</Heading>
      Let  <M>k \in  &NN;</M> be  a  natural number.  We consider  the
      sequence <M>n(i, k), i \in &NN;,</M> with <M>n(1, k) = k</M> and
      else <M>n(i+1,  k) = n(i, k)  / 2</M> if <M>n(i,  k)</M> is even
      and <M>n(i+1, k) =  3 n(i, k) + 1</M> if  <M>n(i, k)</M> is odd.
      <P/> It  is not known  whether for  any natural number  <M>k \in
      &NN;</M> there is an <M>m \in &NN;</M> with <M>n(m, k) = 1</M>.
      <P/>
      <Package>ThreeKPlusOne</Package>  provides   the  function  <Ref
      Func="ThreeKPlusOneSequence"/>   to  explore   this  for   given
      <M>n</M>.  If  you really  want  to  know something  about  this
      problem, see <Cite Key="Wi98"/> or
      <URL>http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/</URL>
      for more details (and forget this package).
    </Section>

    <Section> <Heading>Program</Heading>
      In this section we describe the main function of this package.
      <ManSection> 
        <Func Name="ThreeKPlusOneSequence" Arg="k[, max]"/>
        <Description>
          This  function computes  for a  natural number  <A>k</A> the
          beginning of the sequence  <M>n(i, k)</M> defined in section
          <Ref Sect="sec:theory"/>.  The sequence  stops at  the first
          <M>1</M>  or at  <M>n(<A>max</A>, k)</M>,  if <A>max</A>  is
          given.
<Example>
gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
</Example>
        </Description>
      </ManSection>
    </Section>
  </Chapter>
</Body>

<Bibliography Databases="3k+1" />
<TheIndex/>

</Book>

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chapC.html0000644000175000017500000005711412026346063013664 0ustar billbill GAP (GAPDoc) - Appendix C: The File bibxmlext.dtd
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

C The File bibxmlext.dtd

For easier reference we repeat here the complete content of the file bibxmlext.dtd which is explained in 7.2.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  - (C) Frank Lübeck (http://www.math.rwth-aachen.de/~Frank.Luebeck)
  -
  - The BibXMLext data format.
  - 
  - This DTD expresses XML markup similar to the BibTeX language
  - specified for LaTeX, or actually its content model.
  -
  - It is a variation of a file bibxml.dtd developed by the project
  -   http://bibtexml.sf.net/
  - 
  - For documentation on BibTeX, see
  -   http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/
  -
  - A previous version of the code originally developed by
  - Vidar Bronken Gundersen, http://bibtexml.sf.net/
  - Reuse and repurposing is approved as long as this
  - notification appears with the code.
  -
-->

<!-- ..................................................................... -->
<!-- Main structure -->

<!-- key-value pairs as in BibTeX @string entries are put in empty elements
     (but here they can be used for parts of an entry field as well)       -->
<!ELEMENT string EMPTY>
<!ATTLIST string
   key        CDATA     #REQUIRED 
   value      CDATA     #REQUIRED >
   
<!-- entry may contain one of the bibliographic types. -->
<!ELEMENT entry ( article | book | booklet |
                         manual | techreport |
                         mastersthesis | phdthesis |
                         inbook | incollection |
                         proceedings | inproceedings |
                         conference |
                         unpublished | misc ) >
<!ATTLIST entry
   id         CDATA     #REQUIRED >

<!-- file is the documents top element. -->
<!ELEMENT file  ( string | entry )* >


<!-- ..................................................................... -->
<!-- Parameter entities -->

<!-- these are additional elements often used, but not included in the
     standard BibTeX distribution, these must be added to the
     bibliography styles, otherwise these fields will be omitted by
     the formatter, we allow an arbitrary number of 'other' elements
     to specify any further information   -->

<!ENTITY   %  n.user " abstract?, affiliation?,
                        contents?, copyright?,
                        (isbn | issn)?, 
                        keywords?, language?, lccn?, 
                        location?, mrnumber?, mrclass?, mrreviewer?,
                        price?, size?, url?, category?, other* ">

<!ENTITY   %  n.common "key?, annotate?, crossref?,
                        %n.user;">

<!-- content model used more than once -->

<!ENTITY   %  n.InProceedings "author, title, booktitle,
                    year, editor?, 
                    (volume | number)?,
                    series?, pages?, address?, 
                    month?, organization?, publisher?,
                    note?, %n.common;">

<!ENTITY   %  n.PHDThesis "author, title, school,
                    year, type?, address?, month?,
                    note?, %n.common;">

<!-- ..................................................................... -->
<!-- Entries in the BibTeX database -->

<!-- [article] An article from a journal or magazine.
  -  Required fields: author, title, journal, year.
  -  Optional fields: volume, number, pages, month, note. -->
<!ELEMENT   article    (author, title, journal,
               year, volume?, number?, pages?,
               month?, note?, %n.common;)
>

<!-- [book] A book with an explicit publisher.  
  -  Required fields: author or editor, title, publisher, year.
  -  Optional fields: volume or number, series, address,
  -     edition, month, note. -->
<!ELEMENT   book    ((author | editor), title,
               publisher, year, (volume | number)?,
               series?, address?, edition?, month?,
               note?, %n.common;)
>
	   
<!-- [booklet] A work that is printed and bound, but without a named
  -  publisher or sponsoring institution  
  -  Required field: title.
  -  Optional fields: author, howpublished, address, month, year, note. -->
<!ELEMENT   booklet    (author?, title,
               howpublished?, address?, month?, 
               year?, note?, %n.common;)
>

<!-- [conference] The same as INPROCEEDINGS,
  -  included for Scribe compatibility. -->
<!ELEMENT   conference      (%n.InProceedings;)
>

<!-- [inbook] A part of a book, which may be a chapter (or section or
  -  whatever) and/or a range of pages.  
  -  Required fields: author or editor, title, chapter and/or pages,
  -     publisher, year.
  -  Optional fields: volume or number, series, type, address,
  -     edition, month, note. -->
<!ELEMENT   inbook    ((author | editor), title,
               ((chapter, pages?) | pages),
               publisher, year, (volume |
               number)?, series?, type?,
               address?, edition?, month?, 
               note?, %n.common;)
>

<!--
  - > I want to express that the elements a and/or b are legal that is one
  - > of them or both must be present in the document instance (see the
  - > element content for BibTeX entry `InBook').
  - > How do I specify this in my DTD?
  - 
  - Dave Peterson:
  -  in content model:   ((a , b?) | b)          if order matters
  -                      ((a , b?) | (b , a?))   otherwise
-->

<!-- [incollection] A part of a book having its own title.
  -  Required fields: author, title, booktitle, publisher, year.
  -  Optional fields: editor, volume or number, series, type,
  -     chapter, pages, address, edition, month, note. -->
<!ELEMENT   incollection    (author, title,
               booktitle, publisher, year,
               editor?, (volume | number)?,
               series?, type?, chapter?, 
               pages?, address?, edition?, 
               month?, note?,
               %n.common;)
>

<!-- [inproceedings] An article in a conference proceedings.
  -  Required fields: author, title, booktitle, year.
  -  Optional fields: editor, volume or number, series, pages,
  -     address, month, organization, publisher, note. -->
<!ELEMENT   inproceedings      (%n.InProceedings;)
>

<!-- [manual] Technical documentation  
  -  Required field: title.
  -  Optional fields: author, organization, address,
  -     edition, month, year, note. -->
<!ELEMENT   manual    (author?, title,
               organization?, address?, edition?,
               month?, year?, note?, %n.common;)
>

<!-- [mastersthesis] A Master's thesis.  
  -  Required fields: author, title, school, year.
  -  Optional fields: type, address, month, note. -->
<!ELEMENT   mastersthesis      (%n.PHDThesis;)
>

<!-- [misc] Use this type when nothing else fits.  
  -  Required fields: none.
  -  Optional fields: author, title, howpublished, month, year, note. -->
<!ELEMENT   misc    (author?, title?,
               howpublished?, month?, year?, note?,
               %n.common;)
>

<!-- [phdthesis] A PhD thesis.  
  -  Required fields: author, title, school, year.
  -  Optional fields: type, address, month, note. -->
<!ELEMENT   phdthesis      (%n.PHDThesis;)
>

<!-- [proceedings] The proceedings of a conference.  
  -  Required fields: title, year.
  -  Optional fields: editor, volume or number, series,
  -     address, month, organization, publisher, note. -->
<!ELEMENT   proceedings    (editor?, title, year,
               (volume | number)?, series?, 
               address?, month?, organization?, 
               publisher?, note?, %n.common;)
>

<!-- [techreport] A report published by a school or other institution,
  -  usually numbered within a series.  
  -  Required fields: author, title, institution, year.
  -  Optional fields: type, number, address, month, note. -->
<!ELEMENT   techreport    (author, title,
               institution, year, type?, number?,
               address?, month?, note?, %n.common;)
>

<!-- [unpublished] A document having an author and title, but not
  -  formally published.  
  -  Required fields: author, title, note.
  -  Optional fields: month, year. -->
<!ELEMENT   unpublished    (author, title, note,
               month?, year?, %n.common;)
>

<!-- ..................................................................... -->
<!-- Fields from the standard bibliography styles -->

<!--
  - Below is a description of all fields recognized by the standard
  - bibliography styles.  An entry can also contain other fields, which
  - are ignored by those styles.
  - 
  - [address] Usually the address of the publisher or other type of
  - institution  For major publishing houses, van~Leunen recommends
  - omitting the information entirely.  For small publishers, on the other
  - hand, you can help the reader by giving the complete address.
  - 
  - [annote] An annotation  It is not used by the standard bibliography
  - styles, but may be used by others that produce an annotated
  - bibliography.
  - 
  - [author] The name(s) of the author(s), here *not* in the format 
  - described in the LaTeX book. Contains elements <name> which in turn
  - contains elements <first>, <last> for the first name (or first names,
  - fully written or as initials, and including middle initials) and
  - the last name.
  - 
  - [booktitle] Title of a book, part of which is being cited.  See the
  - LaTeX book for how to type titles.  For book entries, use the title
  - field instead.
  - 
  - [chapter] A chapter (or section or whatever) number.
  - 
  - [crossref] The database key of the entry being cross referenced.
  - 
  - [edition] The edition of a book-for example, ``Second''.  This
  - should be an ordinal, and should have the first letter capitalized, as
  - shown here; the standard styles convert to lower case when necessary.
  - 
  - [editor] Name(s) of editor(s), typed as indicated in the LaTeX book.
  - If there is also an author field, then the editor field gives the
  - editor of the book or collection in which the reference appears.
  - 
  - [howpublished] How something strange has been published.  The first
  - word should be capitalized.
  - 
  - [institution] The sponsoring institution of a technical report.
  - 
  - [journal] A journal name.  Abbreviations are provided for many
  - journals; see the Local Guide.
  - 
  - [key] Used for alphabetizing, cross referencing, and creating a label
  - when the ``author'' information (described in Section [ref: ] is
  - missing. This field should not be confused with the key that appears
  - in the \cite command and at the beginning of the database entry.
  - 
  - [month] The month in which the work was published or, for an
  - unpublished work, in which it was written. You should use the
  - standard three-letter abbreviation, as described in Appendix B.1.3 of
  - the LaTeX book.
  - 
  - [note] Any additional information that can help the reader.  The first
  - word should be capitalized.
  - 
  - [number] The number of a journal, magazine, technical report, or of a
  - work in a series.  An issue of a journal or magazine is usually
  - identified by its volume and number; the organization that issues a
  - technical report usually gives it a number; and sometimes books are
  - given numbers in a named series.
  - 
  - [organization] The organization that sponsors a conference or that
  - publishes a manual.
  - 
  - [pages] One or more page numbers or range of numbers, such as 42-111
  - or 7,41,73-97 or 43+ (the `+' in this last example indicates pages
  - following that don't form a simple range).  To make it easier to
  - maintain Scribe-compatible databases, the standard styles convert a
  - single dash (as in 7-33) to the double dash used in TeX to denote
  - number ranges (as in 7-33). Here, we suggest to use the entity
  - &ndash; for a dash in page ranges.
  - 
  - [publisher] The publisher's name.
  - 
  - [school] The name of the school where a thesis was written.
  - 
  - [series] The name of a series or set of books.  When citing an entire
  - book, the the title field gives its title and an optional series field
  - gives the name of a series or multi-volume set in which the book is
  - published.
  - 
  - [title] The work's title. For mathematical formulae use the <M> or
  - <Math> elements explained below (and LaTeX code in the content, without
  - surrounding '$').
  - 
  - [type] The type of a technical report-for example, ``Research
  - Note''.
  - 
  - [volume] The volume of a journal or multivolume book.
  - 
  - [year] The year of publication or, for an unpublished work, the year
  - it was written.  Generally it should consist of four numerals, such as
  - 1984, although the standard styles can handle any year whose last four
  - nonpunctuation characters are numerals, such as `(about 1984)'.
-->

<!-- Here is the main extension compared to the original BibXML definition
     from which is DTD is derived: We want to allow more markup in some 
     elements such that we can use the bibliography for high quality 
     output in other formats than LaTeX. 
     
     - <M> and <Math>, mathematical formulae: Specify LaTeX code for "simple" 
       formulae as content of <M> elements; "simple" means that they can be
       translated to a fairly readable ASCII representation as explained in
       the GAPDoc documentation on "<M>". 
       More complicated formulae are given as content of <Math> elements.
       (Think about an <Alt> alternative for text or HTML representations.)
     
     - <URL>: use these elements to specify URLs, they can be properly
       converted to links if possible in an output format (in that case 
       the Text attribute is used for the visible text).

     - <value key="..."/>:  substituted by the value-attribute specified
       in a <string key="..." value="..."/> element. Can be used anywhere,
       not only for complete fields as in BibTeX.

     - <C> protect case changes: should be used instead of {}'s which are
       used in BibTeX title fields to protect the case of letters from
       changes. 

     - <Alt Only="...">, <Alt Not="...">, alternatives for different 
       output formats:  Use this to specify alternatives, the GAPDoc
       utilities will do some special handling for "Text", "HTML",
       and "BibTeX" as output type.

     - <Wrap Name="...">, generic wrapper for other markup:
       Use this for any other type of markup you are interested in. The
       GAPDoc utilities will ignore the markup, but provide a hook
       to do install handler functions for them.
-->
<!ELEMENT   M               (#PCDATA | Alt)* > <!-- math with simple text
                                             representation, in LaTeX -->
<!ELEMENT   Math            (#PCDATA | Alt)* > <!-- other math in LaTeX -->
<!ELEMENT   URL             (#PCDATA | Alt | Link | LinkText)* > <!-- an URL -->
<!ATTLIST   URL Text CDATA #IMPLIED>    <!-- text to be printed 
                                             (default is content) -->
<!ELEMENT   value             EMPTY   > <!-- placeholder for value given .. -->
<!ATTLIST   value key CDATA #REQUIRED > <!-- .. by key, defined in a string
                                             element -->
<!ELEMENT   C    (#PCDATA | value | Alt |
                  M | Math | Wrap | URL)* >  <!-- protect from case changes -->
<!ELEMENT   Alt  (#PCDATA | value | C | Alt |    
                  M | Math | Wrap | URL)* > <!-- specify alternatives for 
                                             various types of output -->
<!ATTLIST   Alt  Only CDATA #IMPLIED
                 Not  CDATA #IMPLIED  > <!-- specify output types in comma and 
                  whitespace separated list (use exactly one of Only or Not) -->

<!ENTITY % withMURL "(#PCDATA | value | M | Math | Wrap | URL | C | Alt )*" >

<!ELEMENT   Wrap           %withMURL; > <!-- a generic wrapper  -->
<!ATTLIST   Wrap Name CDATA #REQUIRED > <!-- needs a 'Name' attribute  -->

<!ELEMENT   address         %withMURL; >
<!-- here we don't want the complicated definition from the LaTeX book,
     use markup for first/last name(s): a <name> element for each
     author which contains <first> (optional), <last> elements:  -->
<!ELEMENT   author          (name)* >
<!ELEMENT   name            (first?, last) >
<!ELEMENT   first           (#PCDATA) >
<!ELEMENT   last            (#PCDATA) >

<!ELEMENT   booktitle       %withMURL; >
<!ELEMENT   chapter         %withMURL; >
<!ELEMENT   edition         %withMURL; >
<!-- same as for author field -->
<!ELEMENT   editor          (name)* >
<!ELEMENT   howpublished    %withMURL; >
<!ELEMENT   institution     %withMURL; >
<!ELEMENT   journal         %withMURL; >
<!ELEMENT   month           %withMURL; >
<!ELEMENT   note            %withMURL; >
<!ELEMENT   number          %withMURL; >
<!ELEMENT   organization    %withMURL; >
<!ELEMENT   pages           %withMURL; >
<!ELEMENT   publisher       %withMURL; >
<!ELEMENT   school          %withMURL; >
<!ELEMENT   series          %withMURL; >
<!ELEMENT   title           %withMURL; >
<!ELEMENT   type            %withMURL; >
<!ELEMENT   volume          %withMURL; >
<!ELEMENT   year            (#PCDATA) >

<!-- These were not listed in the documentation for entry content, but
  -  appeared in the list of fields in the BibTeX documentation -->

<!ELEMENT   annotate        %withMURL; >
<!ELEMENT   crossref        %withMURL; >
<!ELEMENT   key             (#PCDATA) >


<!-- ..................................................................... -->
<!-- Other popular fields
  - 
  - From: http://www.ecst.csuchico.edu/~jacobsd/bib/formats/bibtex.html
  - BibTeX is extremely popular, and many people have used it to store
  - information. Here is a list of some of the more common fields:
  - 
  - [affiliation]  The authors affiliation. 
  - [abstract]  An abstract of the work. 
  - [contents]  A Table of Contents 
  - [copyright]  Copyright information. 
  - [ISBN]  The International Standard Book Number. 
  - [ISSN]  The International Standard Serial Number. 
  -         Used to identify a journal. 
  - [keywords]  Key words used for searching or possibly for annotation. 
  - [language]  The language the document is in. 
  - [location]  A location associated with the entry,
  -             such as the city in which a conference took place.
  - [LCCN]  The Library of Congress Call Number.
  -         I've also seen this as lib-congress. 
  - [mrnumber]  The Mathematical Reviews number. 
  - [mrclass]  The Mathematical Reviews class. 
  - [mrreviewer]  The Mathematical Reviews reviewer. 
  - [price]  The price of the document. 
  - [size]  The physical dimensions of a work. 
  - [URL] The WWW Universal Resource Locator that points to the item being
  -       referenced. This often is used for technical reports to point to the
  -       ftp site where the postscript source of the report is located.
  - 
  - When using BibTeX with LaTeX you need
  - BibTeX style files to print these data.
-->

<!ELEMENT   abstract        %withMURL; >
<!ELEMENT   affiliation     %withMURL; >
<!ELEMENT   contents        %withMURL; >
<!ELEMENT   copyright       %withMURL; >
<!ELEMENT   isbn            (#PCDATA) >
<!ELEMENT   issn            (#PCDATA) >
<!ELEMENT   keywords        %withMURL; >
<!ELEMENT   language        %withMURL; >
<!ELEMENT   lccn            (#PCDATA) >
<!ELEMENT   location        %withMURL; >
<!ELEMENT   mrnumber        %withMURL; >
<!ELEMENT   mrclass         %withMURL; >
<!ELEMENT   mrreviewer      %withMURL; >
<!ELEMENT   price           %withMURL; >
<!ELEMENT   size            %withMURL; >
<!ELEMENT   url             %withMURL; >


<!-- Added by Zeger W. Hendrikse
  - [category]  Category of this bibitem
-->
<!ELEMENT   category      %withMURL; >

<!-- A container element [other] for any further information, a description 
   - of the type of data must be given in the attribute 'type' 
-->
<!ELEMENT   other      %withMURL; >
<!ATTLIST   other
    type      CDATA   #REQUIRED >


<!-- ..................................................................... -->
<!-- Predefined/reserved character entities -->

<!ENTITY amp    "&#38;#38;">
<!ENTITY lt     "&#38;#60;">
<!ENTITY gt     "&#62;">
<!ENTITY apos   "&#39;">
<!ENTITY quot   "&#34;">


<!-- Some more generally useful entities -->
<!ENTITY nbsp "&#160;">
<!ENTITY copyright "&#169;">
<!ENTITY ndash "&#x2013;">
 

<!-- ..................................................................... -->
<!-- End of BibXMLext dtd -->

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap7.txt0000644000175000017500000013344212026346063013522 0ustar billbill 7 Utilities for Bibliographies A standard for collecting references (in particular to mathematical texts) is BibTeX (http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/). A disadvantage of BibTeX is that the format of the data is specified with the use by LaTeX in mind. The data format is less suited for conversion to other document types like plain text or HTML. In the first section we describe utilities for using data from BibTeX files in GAP. In the second section we introduce a new XML based data format BibXMLext for bibliographies which seems better suited for other tasks than using it with LaTeX. Another section will describe utilities to deal with BibXMLext data in GAP. 7.1 Parsing BibTeX Files Here are functions for parsing, normalizing and printing reference lists in BibTeX format. The reference describing this format is [Lam85, Appendix B]. 7.1-1 ParseBibFiles ParseBibFiles( bibfile1[, bibfile2[, ...]] )  function ParseBibStrings( str1[, str2[, ...]] )  function Returns: list [list of bib-records, list of abbrevs, list of expansions] The first function parses the files bibfile1 and so on (if a file does not exist the extension .bib is appended) in BibTeX format and returns a list as follows: [entries, strings, texts]. Here entries is a list of records, one record for each reference contained in bibfile. Then strings is a list of abbreviations defined by @string-entries in bibfile and texts is a list which contains in the corresponding position the full text for such an abbreviation. The second function does the same, but the input is given as GAP strings str1 and so on. The records in entries store key-value pairs of a BibTeX reference in the form rec(key1 = value1, ...). The names of the keys are converted to lower case. The type of the reference (i.e., book, article, ...) and the citation key are stored as components .Type and .Label. The records also have a .From field that says that the data are read from a BibTeX source. As an example consider the following BibTeX file.  doc/test.bib  @string{ j = "Important Journal" } @article{ AB2000, Author= "Fritz A. First and Sec, X. Y.",  TITLE="Short", journal = j, year = 2000 }   Example  gap> bib := ParseBibFiles("doc/test.bib"); [ [ rec( From := rec( BibTeX := true ), Label := "AB2000",   Type := "article", author := "Fritz A. First and Sec, X. Y."  , journal := "Important Journal", title := "Short",   year := "2000" ) ], [ "j" ], [ "Important Journal" ] ]  7.1-2 NormalizedNameAndKey NormalizedNameAndKey( namestr )  function Returns: list of strings and names as lists NormalizeNameAndKey( r )  function Returns: nothing The argument namestr must be a string describing an author or a list of authors as described in the BibTeX documentation in [Lam85, Appendix B 1.2]. The function NormalizedNameAndKey returns a list of the form [ normalized name string, short key, long key, names as lists]. The first entry is a normalized form of the input where names are written as lastname, first name initials. The second and third entry are the name parts of a short and long key for the bibliography entry, formed from the (initials of) last names. The fourth entry is a list of lists, one for each name, where a name is described by three strings for the last name, the first name initials and the first name(s) as given in the input. Note that the determination of the initials is limited to names where the first letter is described by a single character (and does not contain some markup, say for accents). The function NormalizeNameAndKey gets as argument r a record for a bibliography entry as returned by ParseBibFiles (7.1-1). It substitutes .author and .editor fields of r by their normalized form, the original versions are stored in fields .authororig and .editororig. Furthermore a short and a long citation key is generated and stored in components .printedkey (only if no .key is already bound) and .keylong. We continue the example from ParseBibFiles (7.1-1).  Example  gap> bib := ParseBibFiles("doc/test.bib");; gap> NormalizedNameAndKey(bib[1][1].author); [ "First, F. A. and Sec, X. Y.", "FS", "firstsec",   [ [ "First", "F. A.", "Fritz A." ], [ "Sec", "X. Y.", "X. Y." ] ] ] gap> NormalizeNameAndKey(bib[1][1]); gap> bib[1][1]; rec( From := rec( BibTeX := true ), Label := "AB2000",   Type := "article", author := "First, F. A. and Sec, X. Y.",   authororig := "Fritz A. First and Sec, X. Y.",   journal := "Important Journal", keylong := "firstsec2000",   printedkey := "FS00", title := "Short", year := "2000" )  7.1-3 WriteBibFile WriteBibFile( bibfile, bib )  function Returns: nothing This is the converse of ParseBibFiles (7.1-1). Here bib either must have a format as list of three lists as it is returned by ParseBibFiles (7.1-1). Or bib can be a record as returned by ParseBibXMLextFiles (7.3-4). A BibTeX file bibfile is written and the entries are formatted in a uniform way. All given abbreviations are used while writing this file. We continue the example from NormalizeNameAndKey (7.1-2). The command  Example  gap> WriteBibFile("nicer.bib", bib);  produces a file nicer.bib as follows:  nicer.bib  @string{j = "Important Journal" }  @article{ AB2000,  author = {First, F. A. and Sec, X. Y.},  title = {Short},  journal = j,  year = {2000},  authororig = {Fritz A. First and Sec, X. Y.},  keylong = {firstsec2000},  printedkey = {FS00} }  7.1-4 InfoBibTools InfoBibTools info class The default level of this info class is 1. Functions like ParseBibFiles (7.1-1), StringBibAs... are then printing some information. You can suppress it by setting the level of InfoBibTools to 0. With level 2 there may be some more information for debugging purposes. 7.2 The BibXMLext Format Bibliographical data in BibTeX files have the disadvantage that the actual data are given in LaTeX syntax. This makes it difficult to use the data for anything but for LaTeX, say for representations of the data as plain text or HTML. For example: mathematical formulae are in LaTeX $ environments, non-ASCII characters can be specified in many strange ways, and how to specify URLs for links if the output format allows them? Here we propose an XML data format for bibliographical data which addresses these problems, it is called BibXMLext. In the next section we describe some tools for generating (an approximation to) this data format from BibTeX data, and for using data given in BibXMLext format for various purposes. The first motivation for this development was the handling of bibliographical data in GAPDoc, but the format and the tools are certainly useful for other purposes as well. We started from a DTD bibxml.dtd which is publicly available, say from http://bibtexml.sf.net/. This is essentially a reformulation of the definition of the BibTeX format, including several of some widely used further fields. This has already the advantage that a generic XML parser can check the validity of the data entries, for example for missing compulsary fields in entries. We applied the following changes and extensions to define the DTD for BibXMLext, stored in the file bibxmlext.dtd which can be found in the root directory of this GAPDoc package (and in Appendix C): names Lists of names in the author and editor fields in BibTeX are difficult to parse. Here they must be given by a sequence of -elements which each contain an optional - and a -element for the first and last names, respectively.  and  These elements enclose mathematical formulae, the content is LaTeX code (without the $). These should be handled in the same way as the elements with the same names in GAPDoc, see 3.8-2 and 3.8-1. In particular, simple formulae which have a well defined plain text representation can be given in -elements. Encoding Note that in XML files we can use the full range of unicode characters, see http://www.unicode.org/. All non-ASCII characters should be specified as unicode characters. This makes dealing with special characters easy for plain text or HTML, only for use with LaTeX some sort of translation is necessary.  These elements are allowed everywhere in the text and should be represented by links in converted formats which allow this. It is used in the same way as the element with the same name in GAPDoc, see 3.5-5.  and  Sometimes information should be given in different ways, depending on the output format of the data. This is possible with the -elements with the same definition as in GAPDoc, see 3.9-1.  This element should be used to protect text from case changes by converters (the extra {} characters in BibTeX title fields).  and  The -element defines key-value pairs which can be used in any field via the -element (not only for whole fields but also parts of the text).  This is a generic element for fields which are otherwise not supported. An arbitrary number of them is allowed for each entry, so any kind of additional data can be added to entries.  This generic element is allowed inside all fields. This markup will be just ignored (but not the element content) by our standard tools. But it can be a useful hook for introducing arbitrary further markup (and our tools can easily be extended to handle it). Extra entities The DTD defines the standard XML entities (2.1-10 and the entities   (non-breakable space), – and ©right;. Use – in page ranges. For further details of the DTD we refer to the file bibxmlext.dtd itself which is shown in appendix C. That file also recalls some information from the BibTeX documentation on how the standard fields of entries should be used. Which entry types and which fields are supported (and the ordering of the fields which is fixed by a DTD) can be either read off the DTD, or within GAP one can use the function TemplateBibXML (7.3-10) to get templates for the various entry types. Here is an example of a BibXMLext document:  doc/testbib.xml      
    Fritz A.First  X. Y.Secőnd    The Fritz package for the   formula x^y - l_{{i+1}} \rightarrow \mathbb{R}    2000  13  13–25  Online data at   http://www.publish.com/~ImpJ/123#data  very useful 
 
   There is a standard XML header and a DOCTYPE declaration refering to the bibxmlext.dtd DTD mentioned above. Local entities could be defined in the DOCTYPE tag as shown in the example in 2.2-3. The actual content of the document is inside a -element, it consists of - and -elements. Several of the BibXMLext markup features are shown. We will use this input document for some examples below. 7.3 Utilities for BibXMLext data 7.3-1 Translating BibTeX to BibXMLext First we describe a tool which can translate bibliography entries from BibTeX data to BibXMLext -elements. It also does some validation of the data. In some cases it is desirable to improve the result by hand afterwards (editing formulae, adding -elements, translating non-ASCII characters to unicode, ...). See WriteBibXMLextFile (7.3-5) below for how to write the results to a BibXMLext file. 7.3-2 HeuristicTranslationsLaTeX2XML.Apply HeuristicTranslationsLaTeX2XML.Apply( str )  function Returns: a string HeuristicTranslationsLaTeX2XML.ApplyFile( fnam[, outnam] )  function Returns: nothing These utilities translate some LaTeX code into text in UTF-8 encoding. The input is given as a string str, or a file name fnam, respectively. The first function returns the translated string. The second function with one argument overwrites the given file with the translated text. Optionally, the translated file content can be written to another file, if its name is given as second argument outnam. The record HeuristicTranslationsLaTeX2XML mainly contains translations of LaTeX macros for special characters which were found in hundreds of BibTeX entries from MathSciNet (http://www.ams.org/mathscinet/). Just look at this record if you want to know how it works. It is easy to extend, and if you have improvements which may be of general interest, please send them to the GAPDoc author.  Example  gap> s := "\\\"u\\'{e}\\`e{\\ss}";; gap> Print(s, "\n");  \"u\'{e}\`e{\ss} gap> Print(HeuristicTranslationsLaTeX2XML.Apply(s),"\n"); üéèß  7.3-3 StringBibAsXMLext StringBibAsXMLext( bibentry[, abbrvs, vals][, encoding] )  function Returns: a string with XML code, or fail The argument bibentry is a record representing an entry from a BibTeX file, as returned in the first list of the result of ParseBibFiles (7.1-1). The optional two arguments abbrvs and vals can be lists of abbreviations and substitution strings, as returned as second and third list element in the result of ParseBibFiles (7.1-1). The optional argument encoding specifies the character encoding of the string components of bibentry. If this is not given it is checked if all strings are valid UTF-8 encoded strings, in that case it is assumed that the encoding is UTF-8, otherwise the latin1 encoding is assumed. The function StringBibAsXMLext creates XML code of an -element in BibXMLext format. The result is in UTF-8 encoding and contains some heuristic translations, like splitting name lists, finding places for -elements, putting formulae in -elements, substituting some characters. The result should always be checked and maybe improved by hand. Some validity checks are applied to the given data, for example if all non-optional fields are given. If this check fails the function returns fail. If your BibTeX input contains LaTeX markup for special characters, it can be convenient to translate this input with HeuristicTranslationsLaTeX2XML.Apply (7.3-2) or HeuristicTranslationsLaTeX2XML.ApplyFile (7.3-2) before parsing it as BibTeX. As an example we consider again the short BibTeX file doc/test.bib shown in the example for ParseBibFiles (7.1-1).  Example  gap> bib := ParseBibFiles("doc/test.bib");; gap> str := StringBibAsXMLext(bib[1][1], bib[2], bib[3]);; gap> Print(str, "\n"); 
    Fritz A.First  X. Y.Sec    Short    2000 
  The following functions allow parsing of data which are already in BibXMLext format. 7.3-4 ParseBibXMLextString ParseBibXMLextString( str )  function ParseBibXMLextFiles( fname1[, fname2[, ...]] )  function Returns: a record with fields .entries, .strings and .entities The first function gets a string str containing a BibXMLext document or a part of it. It returns a record with the three mentioned fields. Here .entries is a list of partial XML parse trees for the -elements in str. The field .strings is a list of key-value pairs from the -elements in str. And .strings is a list of name-value pairs of the named entities which were used during the parsing. The second function ParseBibXMLextFiles uses the first on the content of all files given by filenames fname1 and so on. It collects the results in a single record. As an example we parse the file testbib.xml shown in 7.2.  Example  gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; gap> RecFields(bib); [ "entries", "strings", "entities" ] gap> bib.entries; [ ] gap> bib.strings; [ [ "j", "Important Journal" ] ] gap> bib.entities[1];  [ "amp", "&#38;" ]  7.3-5 WriteBibXMLextFile WriteBibXMLextFile( fname, bib )  function Returns: nothing This function writes a BibXMLext file with name fname. There are three possibilities to specify the bibliography entries in the argument bib. It can be a list of three lists as returned by ParseBibFiles (7.1-1). Or it can be just the first of such three lists in which case the other two lists are assumed to be empty. To all entries of the (first) list the function StringBibAsXMLext (7.3-3) is applied and the resulting strings are written to the result file. The third possibility is that bib is a record in the format as returned by ParseBibXMLextString (7.3-4) and ParseBibXMLextFiles (7.3-4). In this case the entries for the BibXMLext file are produced with StringXMLElement (5.2-2), and if bib.entities is bound then it is tried to resubstitute parts of the string by the given entities with EntitySubstitution (5.2-3). As an example we write back the result of the example shown for ParseBibXMLextFiles (7.3-4) to an equivalent XML file.  Example  gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; gap> WriteBibXMLextFile("test.xml", bib);  7.3-6 Bibliography Entries as Records For working with BibXMLext entries we find it convenient to first translate the parse tree of an entry, as returned by ParseBibXMLextFiles (7.3-4), to a record with the field names of the entry as components whose value is the content of the field as string. These strings are generated with respect to a result type. The records are generated by the following function which can be customized by the user. 7.3-7 RecBibXMLEntry RecBibXMLEntry( entry[, restype][, strings][, options] )  function Returns: a record with fields as strings This function generates a content string for each field of a bibliography entry and assigns them to record components. This content may depend on the requested result type and possibly some given options. The arguments are as follows: entry is the parse tree of an  element as returned by ParseBibXMLextString (7.3-4) or ParseBibXMLextFiles (7.3-4). The optional argument restype describes the type of the result. This package supports currently the types "BibTeX", "Text" and "HTML". The default is "BibTeX". The optional argument strings must be a list of key-value pairs as returned in the component .strings in the result of ParseBibXMLextString (7.3-4). The argument options must be a record. If the entry contains an author field then the result will also contain a component .authorAsList which is a list containing for each author a list with three entries of the form [last name, first name initials, first name] (the third entry means the first name as given in the data). Similarly, an editor field is accompanied by a component .editorAsList. The following options are currently supported. If options.fullname is bound and set to true then the full given first names for authors and editors will be used, the default is to use the initials of the first names. Also, if options.namefirstlast is bound and set to true then the names are written in the form first-name(s) last-name, the default is the form last-name, first-name(s). If options.href is bound and set to false then the "BibTeX" type result will not use \href commands. The default is to produce \href commands from -elements such that LaTeX with the hyperref package can produce links for them. The content of an -element with Only-attribute is included if restype is given in the attribute and ignored otherwise, and vice versa in case of a Not-attribute. If options.useAlt is bound, it must be a list of strings to which restype is added. Then an -element with Only-attribute is evaluated if the intersection of options.useAlt and the types given in the attribute is not empty. In case of a Not-attribute the element is evaluated if this intersection is empty. If restype is "BibTeX" then the string fields in the result will be recoded with Encode (6.2-2) and target "LaTeX". If options.hasLaTeXmarkup is bound and set to true (for example, because the data are originally read from BibTeX files), then the target "LaTeXleavemarkup" will be used. We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).  Example  gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; gap> e := bib.entries[1];; strs := bib.strings;; gap> Print(RecBibXMLEntry(e, "BibTeX", strs), "\n"); rec(  From := rec(  BibXML := true,  options := rec(  ),  type := "BibTeX" ),  Label := "AB2000",  Type := "article",  author := "First, F. A. and Sec{\\H o}nd, X. Y.",  authorAsList :=   [ [ "First", "F. A.", "Fritz A." ],   [ "Sec\305\221nd", "X. Y.", "X. Y." ] ],  journal := "Important Journal",  mycomment := "very useful",  note :=   "Online data at \\href {http://www.publish.com/~ImpJ/123#data} {Bla\  Bla Publisher}",  number := "13",  pages := "13{\\textendash}25",  printedkey := "FS00",  title :=   "The {F}ritz package for the \n formula $x^y - l_{{i+1}} \ \\rightarrow \\mathbb{R}$",  year := "2000" ) gap> Print(RecBibXMLEntry(e, "HTML", strs).note, "\n"); Online data at Bla Bla\  Publisher  7.3-8 AddHandlerBuildRecBibXMLEntry AddHandlerBuildRecBibXMLEntry( elementname, restype, handler )  function Returns: nothing The argument elementname must be the name of an entry field supported by the BibXMLext format, the name of one of the special elements "C", "M", "Math", "URL" or of the form "Wrap:myname" or any string "mytype" (which then corresponds to entry fields ). The string "Finish" has an exceptional meaning, see below. restype is a string describing the result type for which the handler is installed, see RecBibXMLEntry (7.3-7). For both arguments, elementname and restype, it is also possible to give lists of the described ones for installing several handler at once. The argument handler must be a function with five arguments of the form handler(entry, r, restype, strings, options). Here entry is a parse tree of a BibXMLext -element, r is a node in this tree for an element elementname, and restype, strings and options are as explained in RecBibXMLEntry (7.3-7). The function should return a string representing the content of the node r. If elementname is of the form "Wrap:myname" the handler is used for elements of form .... If elementname is "Finish" the handler should look like above except that now r is the record generated by RecBibXMLEntry (7.3-7) just before it is returned. Here the handler should return nothing. It can be used to manipulate the record r, for example for changing the encoding of the strings or for adding some more components. The installed handler is called by BuildRecBibXMLEntry(entry, r, restype, strings, options). The string for the whole content of an element can be generated by ContentBuildRecBibXMLEntry(entry, r, restype, strings, options). We continue the example from RecBibXMLEntry (7.3-7) and install a handler for the -element such that LaTeX puts its content in a sans serif font.  Example  gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", > function(entry, r, restype, strings, options) >  return Concatenation("\\textsf{", ContentBuildRecBibXMLEntry( >  entry, r, restype, strings, options), "}"); > end); gap>  gap> Print(RecBibXMLEntry(e, "BibTeX", strs).title, "\n"); The \textsf{ {F}ritz} package for the   formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$ gap> Print(RecBibXMLEntry(e, "Text", strs).title, "\n");  The Fritz package for the   formula x^y - l_{i+1} → R gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", "Ignore");  7.3-9 StringBibXMLEntry StringBibXMLEntry( entry[, restype][, strings][, options] )  function Returns: a string The arguments of this function have the same meaning as in RecBibXMLEntry (7.3-7) but the return value is a string representing the bibliography entry in a format specified by restype (default is "BibTeX"). Currently, the following cases for restype are supported: "BibTeX" A string with BibTeX source code is generated. "Text" A text representation of the text is returned. If options.ansi is bound it must be a record. The components must have names Bib_Label, Bib_author, and so on for all fieldnames. The value of each component is a pair of strings which will enclose the content of the field in the result or the first of these strings in which case the default for the second is TextAttr.reset (see TextAttr (6.1-2)). If you give an empty record here, some default ANSI color markup will be used. "HTML" An HTML representation of the bibliography entry is returned. The text from each field is enclosed in markup (mostly 
-elements) with the class attribute set to the field name. This allows a detailed layout of the code via a style sheet file. We use again the file shown in the example for ParseBibXMLextFiles (7.3-4).  Example  gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; gap> e := bib.entries[1];; strs := bib.strings;; gap> ebib := StringBibXMLEntry(e, "BibTeX", strs);; gap> PrintFormattedString(ebib); @article{ AB2000,  author = {First, F. A. and Sec{\H o}nd, X. Y.},  title = {The {F}ritz package for the formula $x^y -  l_{{i+1}} \rightarrow \mathbb{R}$},  journal = {Important Journal},  number = {13},  year = {2000},  pages = {13{\textendash}25},  note = {Online data at \href  {http://www.publish.com/~ImpJ/123#data} {Bla  Bla Publisher}},  mycomment = {very useful},  printedkey = {FS00} } gap> etxt := StringBibXMLEntry(e, "Text", strs);;  gap> etxt := SimplifiedUnicodeString(Unicode(etxt), "latin1", "single");; gap> etxt := Encode(etxt, GAPInfo.TermEncoding);;  gap> PrintFormattedString(etxt); [FS00] First, F. A. and Second, X. Y., The Fritz package for the formula x^y - l_{i+1} ? R, Important Journal, 13 (2000), 13-25, (Online data at Bla Bla Publisher (http://www.publish.com/~ImpJ/123#data)).   The following command may be useful to generate completly new bibliography entries in BibXMLext format. It also informs about the supported entry types and field names. 7.3-10 TemplateBibXML TemplateBibXML( [type] )  function Returns: list of types or string Without an argument this function returns a list of the supported entry types in BibXMLext documents. With an argument type of one of the supported types the function returns a string which is a template for a corresponding BibXMLext entry. Optional field elements have a * appended. If an element has the word OR appended, then either this element or the next must/can be given, not both. If AND/OR is appended then this and/or the next can/must be given. Elements which can appear several times have a + appended. Places to fill are marked by an X.  Example  gap> TemplateBibXML(); [ "article", "book", "booklet", "conference", "inbook",   "incollection", "inproceedings", "manual", "mastersthesis", "misc",   "phdthesis", "proceedings", "techreport", "unpublished" ] gap> Print(TemplateBibXML("inbook"));     XX+  OR    XX+    X  XAND/OR  X  X  X  X*OR  X*  X*  X* 
X
*  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*OR  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*  X*+ 
  7.4 Getting BibTeX entries from MathSciNet We provide utilities to access the  MathSciNet (http://www.ams.org/mathscinet/) data base from within GAP. One condition for this to work is that the IO-package [Neu07] is available. The other is, of course, that you use these functions from a computer which has access to MathSciNet. Please note, that the usual license for MathSciNet access does not allow for automated searches in the database. Therefore, only use the SearchMR (7.4-1) function for single queries, as you would do using your webbrowser. 7.4-1 SearchMR SearchMR( qurec )  function SearchMRBib( bib )  function Returns: a list of strings, a string or fail The first function SearchMR provides the same functionality as the Web interface  MathSciNet (http://www.ams.org/mathscinet/). The query strings must be given as a record, and the following components of this record are recognized: Author, AuthorRelated, Title, ReviewText, Journal, InstitutionCode, Series, MSCPrimSec, MSCPrimary, MRNumber, Anywhere, References and Year. Furthermore, the component type can be specified. It can be one of "bibtex" (the default if not given), "pdf", "html" and probably others. In the last cases the function returns a string with the correspondig PDF-file or web page from MathSciNet. In the first case the MathSciNet interface returns a web page with BibTeX entries, for convenience this function returns a list of strings, each containing the BibTeX text for a single result entry. The format of a .Year component can be either a four digit number, optionally preceded by one of the characters '<', '>' or '=', or it can be two four digit numbers separated by a - to specify a year range. The function SearchMRBib gets a record of a parsed BibTeX entry as input as returned by ParseBibFiles (7.1-1) or ParseBibStrings (7.1-1). It tries to generate some sensible input from this information for SearchMR and calls that function.  Example  gap> ll := SearchMR(rec(Author:="Gauss", Title:="Disquisitiones"));; gap> ll2 := List(ll, HeuristicTranslationsLaTeX2XML.Apply);; gap> bib := ParseBibStrings(Concatenation(ll2));; gap> bibxml := List(bib[1], StringBibAsXMLext);; gap> bib2 := ParseBibXMLextString(Concatenation(bibxml));; gap> for b in bib2.entries do  >  PrintFormattedString(StringBibXMLEntry(b, "Text")); od;  [Gau95] Gauss, C. F., Disquisitiones arithmeticae, Academia Colombiana de Ciencias Exactas Físicas y Naturales, Colección Enrique Pérez Arbeláez [Enrique Pérez Arbeláez Collection], 10, Bogotá (1995), xliv+495 pages, (Translated from the Latin by Hugo Barrantes Campos, Michael Josephy and Ángel Ruiz Zúñiga, With a preface by Ruiz Zúñiga).  [Gau86] Gauss, C. F., Disquisitiones arithmeticae, Springer-Verlag, New York (1986), xx+472 pages, (Translated and with a preface by Arthur A. Clarke, Revised by William C. Waterhouse, Cornelius Greither and A. W. Grootendorst and with a preface by Waterhouse).  [Gau66] Gauss, C. F., Disquisitiones arithmeticae, Yale University Press, Translated into English by Arthur A. Clarke, S. J, New Haven, Conn. (1966), xx+472 pages.   GAPDoc-1.5.1/doc/chapC.txt0000644000175000017500000006555512026346063013547 0ustar billbill C The File bibxmlext.dtd For easier reference we repeat here the complete content of the file bibxmlext.dtd which is explained in 7.2.  bibxmlext.dtd                                                                                                                                                                                                         GAPDoc-1.5.1/doc/ragged.css0000644000175000017500000000023112026346063013707 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } GAPDoc-1.5.1/doc/manual.css0000644000175000017500000001575412026346063013753 0ustar billbill/* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } GAPDoc-1.5.1/doc/manual.lab0000644000175000017500000004350312026346063013712 0ustar billbill\GAPDocLabFile{gapdoc} \makelabel{gapdoc:Title page}{}{X7D2C85EC87DD46E5} \makelabel{gapdoc:Copyright}{}{X81488B807F2A1CF1} \makelabel{gapdoc:Table of Contents}{}{X8537FEB07AF2BEC8} \makelabel{gapdoc:Introduction and Example}{1}{X7D4EE663818DA109} \makelabel{gapdoc:XML}{1.1}{X8590236E858F7E93} \makelabel{gapdoc:A complete example}{1.2}{X7B47AFA881BFC9DC} \makelabel{gapdoc:Some questions}{1.3}{X79A97B867F45E5C7} \makelabel{gapdoc:How To Type a GAPDoc Document}{2}{X820EBE207DCC0655} \makelabel{gapdoc:General XML Syntax}{2.1}{X7B3A544986A1A9EA} \makelabel{gapdoc:Head of XML Document}{2.1.1}{X84E8D39687638CF0} \makelabel{gapdoc:Comments}{2.1.2}{X780C79EB85C32138} \makelabel{gapdoc:Processing Instructions}{2.1.3}{X82DBCCAD8358BB63} \makelabel{gapdoc:Names in XML and Whitespace}{2.1.4}{X7A0FB16C7FEC0B53} \makelabel{gapdoc:Elements}{2.1.5}{X79B130FC7906FB4C} \makelabel{gapdoc:Start Tags}{2.1.6}{X7DD1DCB783588BD5} \makelabel{gapdoc:End Tags}{2.1.7}{X7E5A567E83005B62} \makelabel{gapdoc:Combined Tags for Empty Elements}{2.1.8}{X843A02A88514D919} \makelabel{gapdoc:Entities}{2.1.9}{X78FB56C77B1F391A} \makelabel{gapdoc:Special Characters in XML}{2.1.10}{X84A95A19801EDE76} \makelabel{gapdoc:Rules for Attribute Values}{2.1.11}{X7F49E7AD785AED22} \makelabel{gapdoc:CDATA}{2.1.12}{X80D9026B7CB7B32F} \makelabel{gapdoc:Encoding of an XML Document}{2.1.13}{X8709BD337DA09ED5} \makelabel{gapdoc:Well Formed and Valid XML Documents}{2.1.14}{X8561F07A81CABDD6} \makelabel{gapdoc:Entering GAPDoc Documents}{2.2}{X7E9C91B77D1D0A4A} \makelabel{gapdoc:Other special characters}{2.2.1}{X79171E047B069F94} \makelabel{gapdoc:Mathematical Formulae}{2.2.2}{X7EAE0C5A835F126F} \makelabel{gapdoc:More Entities}{2.2.3}{X7BDFF6D37FBED400} \makelabel{gapdoc:The Document Type Definition}{3}{X7859CFF180D52D49} \makelabel{gapdoc:What is a DTD?}{3.1}{X7B76F6F786521F6B} \makelabel{gapdoc:Overall Document Structure}{3.2}{X7DB0F9E57879CC76} \makelabel{gapdoc:}{3.2.1}{X7D27228D7E68473E} \makelabel{gapdoc:}{3.2.2}{X8643EEF587FC8AD4} \makelabel{gapdoc:}{3.2.3}{X85C1D07A84F1F736} \makelabel{gapdoc:<Subtitle>}{3.2.4}{X81B6D8D679A42915} \makelabel{gapdoc:<Version>}{3.2.5}{X8064BA177E9D23B8} \makelabel{gapdoc:<TitleComment>}{3.2.6}{X7C2765047A1561EB} \makelabel{gapdoc:<Author>}{3.2.7}{X846067D18467D228} \makelabel{gapdoc:<Date>}{3.2.8}{X87C47AD378268979} \makelabel{gapdoc:<Address>}{3.2.9}{X7B84029079583E6E} \makelabel{gapdoc:<Abstract>}{3.2.10}{X7CF09C0F82D16612} \makelabel{gapdoc:<Copyright>}{3.2.11}{X823232338648B1D7} \makelabel{gapdoc:<Acknowledgements>}{3.2.12}{X868A17B2849FEB84} \makelabel{gapdoc:<Colophon>}{3.2.13}{X87AF74847BEA348D} \makelabel{gapdoc:<TableOfContents>}{3.2.14}{X81F18BDE7B3182F4} \makelabel{gapdoc:<Bibliography>}{3.2.15}{X857F84507B5CED2A} \makelabel{gapdoc:<TheIndex>}{3.2.16}{X80ACB0AA7FC414E4} \makelabel{gapdoc:Sectioning Elements}{3.3}{X80E2AD7481DD69D9} \makelabel{gapdoc:<Body>}{3.3.1}{X85FB286D82BA5300} \makelabel{gapdoc:<Chapter>}{3.3.2}{X81A68C117E39FA60} \makelabel{gapdoc:<Heading>}{3.3.3}{X82F09E29814C7A72} \makelabel{gapdoc:<Appendix>}{3.3.4}{X7951B5C482C59057} \makelabel{gapdoc:<Section>}{3.3.5}{X795D46507CE20232} \makelabel{gapdoc:<Subsection>}{3.3.6}{X7A9AC7787E8163DC} \makelabel{gapdoc:ManSection–a special kind of subsection}{3.4}{X877B8B7C7EDD09E9} \makelabel{gapdoc:<ManSection>}{3.4.1}{X7E24999A86DAEB60} \makelabel{gapdoc:<Func>}{3.4.2}{X87CA42C681B95BCE} \makelabel{gapdoc:<Oper>}{3.4.3}{X82684F9E8461DFC7} \makelabel{gapdoc:<Meth>}{3.4.4}{X780247227AC3340B} \makelabel{gapdoc:<Filt>}{3.4.5}{X7BFBED2C8766065E} \makelabel{gapdoc:<Prop>}{3.4.6}{X81A6364E79DBE958} \makelabel{gapdoc:<Attr>}{3.4.7}{X7B0AA7E98373249D} \makelabel{gapdoc:<Var>}{3.4.8}{X7D4982A27D773098} \makelabel{gapdoc:<Fam>}{3.4.9}{X7DF346F7795CB5C1} \makelabel{gapdoc:<InfoClass>}{3.4.10}{X84367BDE795E0C56} \makelabel{gapdoc:Cross Referencing and Citations}{3.5}{X78595FB585569617} \makelabel{gapdoc:<Ref>}{3.5.1}{X865F20E386B6DA49} \makelabel{gapdoc:<Label>}{3.5.2}{X8653BAF279C7A817} \makelabel{gapdoc:<Cite>}{3.5.3}{X855B311D7C33A50E} \makelabel{gapdoc:<Index>}{3.5.4}{X7D2B1F278577D2D5} \makelabel{gapdoc:<URL>}{3.5.5}{X7C58A957852F867C} \makelabel{gapdoc:<Email>}{3.5.6}{X7FEB041D793E781B} \makelabel{gapdoc:<Homepage>}{3.5.7}{X81F135A886B732E6} \makelabel{gapdoc:Structural Elements like Lists}{3.6}{X840099DF83823686} \makelabel{gapdoc:<List>}{3.6.1}{X7F97E8DD784F5CAA} \makelabel{gapdoc:<Mark>}{3.6.2}{X786406A77C9F1CD6} \makelabel{gapdoc:<Item>}{3.6.3}{X7D6BFC907F5FEF37} \makelabel{gapdoc:<Enum>}{3.6.4}{X7D3B2150818E3CD4} \makelabel{gapdoc:<Table>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:Types of Text}{3.7}{X7CA1E1327AFBA578} \makelabel{gapdoc:<Emph> and <E>}{3.7.1}{X7E07C12185A25EF7} \makelabel{gapdoc:<Quoted> and <Q>}{3.7.2}{X87FB13F57EF49C93} \makelabel{gapdoc:<Keyword> and <K>}{3.7.3}{X86A11FA98045FE79} \makelabel{gapdoc:<Arg> and <A>}{3.7.4}{X8502FFCF7DC7982B} \makelabel{gapdoc:<Code> and <C>}{3.7.5}{X79C6755D80AEA4C1} \makelabel{gapdoc:<File> and <F>}{3.7.6}{X7C30FEC078523528} \makelabel{gapdoc:<Button> and <B>}{3.7.7}{X79AEA5068489EE6E} \makelabel{gapdoc:<Package>}{3.7.8}{X7B9BB2D878262083} \makelabel{gapdoc:<Listing>}{3.7.9}{X799961B67E34193D} \makelabel{gapdoc:<Log> and <Example>}{3.7.10}{X7C926CF778F54591} \makelabel{gapdoc:<Verb>}{3.7.11}{X80500AFD86ADECC5} \makelabel{gapdoc:Elements for Mathematical Formulae}{3.8}{X8145F6B37C04AA0A} \makelabel{gapdoc:<Math> and <Display>}{3.8.1}{X7B0254677AA56B5E} \makelabel{gapdoc:<M>}{3.8.2}{X8796A7577B29543A} \makelabel{gapdoc:Everything else}{3.9}{X7A0D26B180BEDE37} \makelabel{gapdoc:<Alt>}{3.9.1}{X817B08367FF43419} \makelabel{gapdoc:<Par> and <P>}{3.9.2}{X847CBC4380DBAC63} \makelabel{gapdoc:<Br>}{3.9.3}{X7C910EF07C3FF929} \makelabel{gapdoc:<Ignore>}{3.9.4}{X84855267801B3077} \makelabel{gapdoc:Distributing a Document into Several Files}{4}{X7A3355C07F57C280} \makelabel{gapdoc:The Conventions}{4.1}{X7CE078A07E8256DC} \makelabel{gapdoc:A Tool for Collecting a Document}{4.2}{X81E07B0F83EBDA5F} \makelabel{gapdoc:The Converters and an XML Parser}{5}{X845E7FDC7C082CC4} \makelabel{gapdoc:Producing Documentation from Source Files}{5.1}{X7D1BB5867C13FA14} \makelabel{gapdoc:Parsing XML Documents}{5.2}{X7FE2AF49838D9034} \makelabel{gapdoc:The Converters}{5.3}{X8560E1A2845EC2C1} \makelabel{gapdoc:Stylesheet files}{5.3.9}{X788AB14383272FDB} \makelabel{gapdoc:Testing Manual Examples}{5.4}{X800299827B88ABBE} \makelabel{gapdoc:String and Text Utilities}{6}{X86CEF540862EE042} \makelabel{gapdoc:Text Utilities}{6.1}{X847DA07C7C46B38A} \makelabel{gapdoc:Unicode Strings}{6.2}{X8489C67D80399814} \makelabel{gapdoc:Unicode Strings and Characters}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:Lengths of UTF-8 strings}{6.2.3}{X801237207E06A876} \makelabel{gapdoc:Print Utilities}{6.3}{X860C83047DC4F1BC} \makelabel{gapdoc:Utilities for Bibliographies}{7}{X7EB94CE97ABF7192} \makelabel{gapdoc:Parsing BibTeX Files}{7.1}{X7A4126EC7BD68F64} \makelabel{gapdoc:The BibXMLext Format}{7.2}{X7FB8F6BD80D859D1} \makelabel{gapdoc:Utilities for BibXMLext data}{7.3}{X7AC255DE7D2531B6} \makelabel{gapdoc:Translating BibTeX to BibXMLext}{7.3.1}{X7C5548E77ECA29D7} \makelabel{gapdoc:Bibliography Entries as Records}{7.3.6}{X82167F1280F4310E} \makelabel{gapdoc:Getting BibTeX entries from MathSciNet}{7.4}{X826901BD844D3F87} \makelabel{gapdoc:The File gapdoc.dtd}{B}{X85274DD38456275D} \makelabel{gapdoc:The File bibxmlext.dtd}{C}{X7B5D840781E99076} \makelabel{gapdoc:Bibliography}{Bib}{X7A6F98FD85F02BFE} \makelabel{gapdoc:References}{Bib}{X7A6F98FD85F02BFE} \makelabel{gapdoc:Index}{Ind}{X83A0356F839C696F} \makelabel{gapdoc:License}{}{X81488B807F2A1CF1} \makelabel{gapdoc:XML}{1.1}{X8590236E858F7E93} \makelabel{gapdoc:Book}{3.2.1}{X7D27228D7E68473E} \makelabel{gapdoc:TitlePage}{3.2.2}{X8643EEF587FC8AD4} \makelabel{gapdoc:Title}{3.2.3}{X85C1D07A84F1F736} \makelabel{gapdoc:Subtitle}{3.2.4}{X81B6D8D679A42915} \makelabel{gapdoc:Version}{3.2.5}{X8064BA177E9D23B8} \makelabel{gapdoc:TitleComment}{3.2.6}{X7C2765047A1561EB} \makelabel{gapdoc:Author}{3.2.7}{X846067D18467D228} \makelabel{gapdoc:Date}{3.2.8}{X87C47AD378268979} \makelabel{gapdoc:Address}{3.2.9}{X7B84029079583E6E} \makelabel{gapdoc:Abstract}{3.2.10}{X7CF09C0F82D16612} \makelabel{gapdoc:Copyright}{3.2.11}{X823232338648B1D7} \makelabel{gapdoc:Acknowledgements}{3.2.12}{X868A17B2849FEB84} \makelabel{gapdoc:Colophon}{3.2.13}{X87AF74847BEA348D} \makelabel{gapdoc:TableOfContents}{3.2.14}{X81F18BDE7B3182F4} \makelabel{gapdoc:Bibliography}{3.2.15}{X857F84507B5CED2A} \makelabel{gapdoc:TheIndex}{3.2.16}{X80ACB0AA7FC414E4} \makelabel{gapdoc:Body}{3.3.1}{X85FB286D82BA5300} \makelabel{gapdoc:Chapter}{3.3.2}{X81A68C117E39FA60} \makelabel{gapdoc:Heading}{3.3.3}{X82F09E29814C7A72} \makelabel{gapdoc:Appendix}{3.3.4}{X7951B5C482C59057} \makelabel{gapdoc:Section}{3.3.5}{X795D46507CE20232} \makelabel{gapdoc:Subsection}{3.3.6}{X7A9AC7787E8163DC} \makelabel{gapdoc:ManSection}{3.4.1}{X7E24999A86DAEB60} \makelabel{gapdoc:Description}{3.4.1}{X7E24999A86DAEB60} \makelabel{gapdoc:Returns}{3.4.1}{X7E24999A86DAEB60} \makelabel{gapdoc:Func}{3.4.2}{X87CA42C681B95BCE} \makelabel{gapdoc:Oper}{3.4.3}{X82684F9E8461DFC7} \makelabel{gapdoc:Meth}{3.4.4}{X780247227AC3340B} \makelabel{gapdoc:Filt}{3.4.5}{X7BFBED2C8766065E} \makelabel{gapdoc:Prop}{3.4.6}{X81A6364E79DBE958} \makelabel{gapdoc:Attr}{3.4.7}{X7B0AA7E98373249D} \makelabel{gapdoc:Var}{3.4.8}{X7D4982A27D773098} \makelabel{gapdoc:Fam}{3.4.9}{X7DF346F7795CB5C1} \makelabel{gapdoc:InfoClass}{3.4.10}{X84367BDE795E0C56} \makelabel{gapdoc:Ref}{3.5.1}{X865F20E386B6DA49} \makelabel{gapdoc:Label}{3.5.2}{X8653BAF279C7A817} \makelabel{gapdoc:Cite}{3.5.3}{X855B311D7C33A50E} \makelabel{gapdoc:Index}{3.5.4}{X7D2B1F278577D2D5} \makelabel{gapdoc:URL}{3.5.5}{X7C58A957852F867C} \makelabel{gapdoc:Email}{3.5.6}{X7FEB041D793E781B} \makelabel{gapdoc:Homepage}{3.5.7}{X81F135A886B732E6} \makelabel{gapdoc:List}{3.6.1}{X7F97E8DD784F5CAA} \makelabel{gapdoc:Mark}{3.6.2}{X786406A77C9F1CD6} \makelabel{gapdoc:Item}{3.6.3}{X7D6BFC907F5FEF37} \makelabel{gapdoc:Enum}{3.6.4}{X7D3B2150818E3CD4} \makelabel{gapdoc:Table}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:<Caption>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:<Row>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:<Align>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:<HorLine>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:<Item> in <Table>}{3.6.5}{X7BA7DA848347E2A9} \makelabel{gapdoc:Emph}{3.7.1}{X7E07C12185A25EF7} \makelabel{gapdoc:E}{3.7.1}{X7E07C12185A25EF7} \makelabel{gapdoc:Quoted}{3.7.2}{X87FB13F57EF49C93} \makelabel{gapdoc:Q}{3.7.2}{X87FB13F57EF49C93} \makelabel{gapdoc:Keyword}{3.7.3}{X86A11FA98045FE79} \makelabel{gapdoc:K}{3.7.3}{X86A11FA98045FE79} \makelabel{gapdoc:Arg}{3.7.4}{X8502FFCF7DC7982B} \makelabel{gapdoc:A}{3.7.4}{X8502FFCF7DC7982B} \makelabel{gapdoc:Code}{3.7.5}{X79C6755D80AEA4C1} \makelabel{gapdoc:C}{3.7.5}{X79C6755D80AEA4C1} \makelabel{gapdoc:File}{3.7.6}{X7C30FEC078523528} \makelabel{gapdoc:F}{3.7.6}{X7C30FEC078523528} \makelabel{gapdoc:Button}{3.7.7}{X79AEA5068489EE6E} \makelabel{gapdoc:B}{3.7.7}{X79AEA5068489EE6E} \makelabel{gapdoc:Package}{3.7.8}{X7B9BB2D878262083} \makelabel{gapdoc:Listing}{3.7.9}{X799961B67E34193D} \makelabel{gapdoc:Log}{3.7.10}{X7C926CF778F54591} \makelabel{gapdoc:Example}{3.7.10}{X7C926CF778F54591} \makelabel{gapdoc:Math}{3.8.1}{X7B0254677AA56B5E} \makelabel{gapdoc:Display}{3.8.1}{X7B0254677AA56B5E} \makelabel{gapdoc:M}{3.8.2}{X8796A7577B29543A} \makelabel{gapdoc:Alt}{3.9.1}{X817B08367FF43419} \makelabel{gapdoc:Par}{3.9.2}{X847CBC4380DBAC63} \makelabel{gapdoc:P}{3.9.2}{X847CBC4380DBAC63} \makelabel{gapdoc:Br}{3.9.3}{X7C910EF07C3FF929} \makelabel{gapdoc:Ignore}{3.9.4}{X84855267801B3077} \makelabel{gapdoc:<Include>}{4.1}{X7CE078A07E8256DC} \makelabel{gapdoc:<GAPDoc>}{4.1}{X7CE078A07E8256DC} \makelabel{gapdoc:ComposedDocument}{4.2.1}{X857D77557D12559D} \makelabel{gapdoc:ComposedXMLString}{4.2.1}{X857D77557D12559D} \makelabel{gapdoc:OriginalPositionDocument}{4.2.2}{X86D1141E7EDCAAC8} \makelabel{gapdoc:MakeGAPDocDoc}{5.1.1}{X826F530686F4D052} \makelabel{gapdoc:MathJax in MakeGAPDocDoc}{5.1.1}{X826F530686F4D052} \makelabel{gapdoc:ParseTreeXMLString}{5.2.1}{X847EB8498151D443} \makelabel{gapdoc:ParseTreeXMLFile}{5.2.1}{X847EB8498151D443} \makelabel{gapdoc:StringXMLElement}{5.2.2}{X835887057D0B4DA8} \makelabel{gapdoc:EntitySubstitution}{5.2.3}{X786827BF793191B3} \makelabel{gapdoc:DisplayXMLStructure}{5.2.4}{X86589C5C859ACE38} \makelabel{gapdoc:ApplyToNodesParseTree}{5.2.5}{X7A7B223A83E38B40} \makelabel{gapdoc:AddRootParseTree}{5.2.5}{X7A7B223A83E38B40} \makelabel{gapdoc:RemoveRootParseTree}{5.2.5}{X7A7B223A83E38B40} \makelabel{gapdoc:GetTextXMLTree}{5.2.6}{X7F76D4A27C7FB946} \makelabel{gapdoc:XMLElements}{5.2.7}{X8466F74C80442F7D} \makelabel{gapdoc:CheckAndCleanGapDocTree}{5.2.8}{X84CFF72484B19C0D} \makelabel{gapdoc:AddParagraphNumbersGapDocTree}{5.2.9}{X84062CD67B286FF0} \makelabel{gapdoc:InfoXMLParser}{5.2.10}{X78A22C58841E5D0B} \makelabel{gapdoc:GAPDoc2LaTeX}{5.3.1}{X85BE6DF178423EF5} \makelabel{gapdoc:SetGapDocLaTeXOptions}{5.3.1}{X85BE6DF178423EF5} \makelabel{gapdoc:GAPDoc2Text}{5.3.2}{X86CD0B197CD58D2A} \makelabel{gapdoc:GAPDoc2TextPrintTextFiles}{5.3.3}{X7DFCE7357D6032A2} \makelabel{gapdoc:AddPageNumbersToSix}{5.3.4}{X7EB5E86F87A09F94} \makelabel{gapdoc:PrintSixFile}{5.3.5}{X7D42CFED7885BC00} \makelabel{gapdoc:SetGAPDocTextTheme}{5.3.6}{X7DEB37417BBD8941} \makelabel{gapdoc:GAPDoc2HTML}{5.3.7}{X84F22EEB78845CFD} \makelabel{gapdoc:MathJax}{5.3.7}{X84F22EEB78845CFD} \makelabel{gapdoc:GAPDoc2HTMLPrintHTMLFiles}{5.3.8}{X84A7007778073E7A} \makelabel{gapdoc:CSS stylesheets}{5.3.9}{X788AB14383272FDB} \makelabel{gapdoc:CopyHTMLStyleFiles}{5.3.10}{X813599E982DE9B98} \makelabel{gapdoc:SetGAPDocHTMLStyle}{5.3.11}{X85AFD98383174BB5} \makelabel{gapdoc:InfoGAPDoc}{5.3.12}{X864A528B81C661A2} \makelabel{gapdoc:SetGapDocLanguage}{5.3.13}{X82AB468887ED0DBB} \makelabel{gapdoc:Using GAPDoc with other languages}{5.3.13}{X82AB468887ED0DBB} \makelabel{gapdoc:ManualExamples}{5.4}{X800299827B88ABBE} \makelabel{gapdoc:TestManualExamples}{5.4}{X800299827B88ABBE} \makelabel{gapdoc:ExtractExamples}{5.4.1}{X8337B2BC79253B3F} \makelabel{gapdoc:ExtractExamplesXMLTree}{5.4.1}{X8337B2BC79253B3F} \makelabel{gapdoc:RunExamples}{5.4.2}{X781D56FC7B938DCB} \makelabel{gapdoc:WHITESPACE}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:CAPITALLETTERS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:SMALLLETTERS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:LETTERS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:DIGITS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:HEXDIGITS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:BOXCHARS}{6.1.1}{X786D477C7AB636AA} \makelabel{gapdoc:TextAttr}{6.1.2}{X785F61E77899580E} \makelabel{gapdoc:UseColorsInTerminal}{6.1.2}{X785F61E77899580E} \makelabel{gapdoc:WrapTextAttribute}{6.1.3}{X7B8AD7517E5FD0EA} \makelabel{gapdoc:FormatParagraph}{6.1.4}{X812058CE7C8E9022} \makelabel{gapdoc:SubstitutionSublist}{6.1.5}{X82A9121678923445} \makelabel{gapdoc:StripBeginEnd}{6.1.6}{X83DE31017B557136} \makelabel{gapdoc:StripEscapeSequences}{6.1.7}{X7A5978CF84C3C2D3} \makelabel{gapdoc:RepeatedString}{6.1.8}{X7D71CB837EE969D4} \makelabel{gapdoc:RepeatedUTF8String}{6.1.8}{X7D71CB837EE969D4} \makelabel{gapdoc:NumberDigits}{6.1.9}{X7CEEA5B57D7BB38F} \makelabel{gapdoc:DigitsNumber}{6.1.9}{X7CEEA5B57D7BB38F} \makelabel{gapdoc:PositionMatchingDelimiter}{6.1.10}{X7AF694D9839BF65C} \makelabel{gapdoc:WordsString}{6.1.11}{X832556617F10AAA8} \makelabel{gapdoc:Base64String}{6.1.12}{X83F2821783DA9826} \makelabel{gapdoc:StringBase64}{6.1.12}{X83F2821783DA9826} \makelabel{gapdoc:Unicode}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:UChar}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:IsUnicodeString}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:IsUnicodeCharacter}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:IntListUnicodeString}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:URL encoding}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:RFC 3986}{6.2.1}{X8475671278948DDD} \makelabel{gapdoc:Encode}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:SimplifiedUnicodeString}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:LowercaseUnicodeString}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:UppercaseUnicodeString}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:LaTeXUnicodeTable}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:SimplifiedUnicodeTable}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:LowercaseUnicodeTable}{6.2.2}{X818A31567EB30A39} \makelabel{gapdoc:WidthUTF8String}{6.2.3}{X801237207E06A876} \makelabel{gapdoc:NrCharsUTF8String}{6.2.3}{X801237207E06A876} \makelabel{gapdoc:PrintTo1}{6.3.1}{X8603B90C7C3F0AB1} \makelabel{gapdoc:AppendTo1}{6.3.1}{X8603B90C7C3F0AB1} \makelabel{gapdoc:StringPrint}{6.3.2}{X829B720C86E57E8B} \makelabel{gapdoc:StringView}{6.3.2}{X829B720C86E57E8B} \makelabel{gapdoc:PrintFormattedString}{6.3.3}{X812A8326844BC910} \makelabel{gapdoc:Page}{6.3.4}{X7BB6731F7E3AAA98} \makelabel{gapdoc:PageDisplay}{6.3.4}{X7BB6731F7E3AAA98} \makelabel{gapdoc:StringFile}{6.3.5}{X7E14D32181FBC3C3} \makelabel{gapdoc:FileString}{6.3.5}{X7E14D32181FBC3C3} \makelabel{gapdoc:ParseBibFiles}{7.1.1}{X82555C307FDC1817} \makelabel{gapdoc:ParseBibStrings}{7.1.1}{X82555C307FDC1817} \makelabel{gapdoc:NormalizedNameAndKey}{7.1.2}{X7C9F0C337A0A0FF0} \makelabel{gapdoc:NormalizeNameAndKey}{7.1.2}{X7C9F0C337A0A0FF0} \makelabel{gapdoc:WriteBibFile}{7.1.3}{X7C2B2F65851EAA0B} \makelabel{gapdoc:InfoBibTools}{7.1.4}{X85C1D50F7E37A99A} \makelabel{gapdoc:HeuristicTranslationsLaTeX2XML.Apply}{7.3.2}{X7A025E0A7A1CD390} \makelabel{gapdoc:HeuristicTranslationsLaTeX2XML.ApplyFile}{7.3.2}{X7A025E0A7A1CD390} \makelabel{gapdoc:StringBibAsXMLext}{7.3.3}{X85F33C64787A00B7} \makelabel{gapdoc:ParseBibXMLextString}{7.3.4}{X86BD29AE7A453721} \makelabel{gapdoc:ParseBibXMLextFiles}{7.3.4}{X86BD29AE7A453721} \makelabel{gapdoc:WriteBibXMLextFile}{7.3.5}{X7811108C7E5B1709} \makelabel{gapdoc:RecBibXMLEntry}{7.3.7}{X786C33ED79F425F1} \makelabel{gapdoc:AddHandlerBuildRecBibXMLEntry}{7.3.8}{X8067261385905A36} \makelabel{gapdoc:StringBibXMLEntry}{7.3.9}{X790A295680F7CD24} \makelabel{gapdoc:TemplateBibXML}{7.3.10}{X7C6FF57087016019} \makelabel{gapdoc:SearchMR}{7.4.1}{X8009F8A17DDFF9AF} \makelabel{gapdoc:SearchMRBib}{7.4.1}{X8009F8A17DDFF9AF} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/doc/chapBib.html�����������������������������������������������������������������������0000644�0001750�0001750�00000007061�12026346063�014172� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>GAP (GAPDoc) - References
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

References

[GAP] GAP -- Groups, Algorithms, and Programming, Version 4.4.9, The GAP Group, Aachen, St Andrews (2006)
(http://www.gap-system.org).

[Lam85] Lamport, L., LaTeX: A Document Preparation System, Addison-Wesley (1985).

[Neu07] Neunhöffer, M., IO, Bindings for low level C library IO, Version 2.2 (2007)
(GAP package), http://www-groups.mcs.st-and.ac.uk/~neunhoef/Computer/Software/Gap/io.html.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap4.txt0000644000175000017500000001636612026346063013524 0ustar billbill 4 Distributing a Document into Several Files In GAPDoc there are facilities to distribute a single document over several files. This is for example interesting, if one wants to store the documentation of some code in the same file as the code itself. Or, if one just wants to store chapters of a document in separate files. There is a set of conventions how this is done and some tools to collect the text for further processing. The technique can also be used to distribute and collect other types of documents into respectively from several files (e.g., source code, examples). 4.1 The Conventions In this description we use the string GAPDoc for marking pieces of a document to collect. Pieces of documentation that shall be incorporated into another document are marked as follows:  Example  ## <#GAPDoc Label="MyPiece"> ## This is the piece. ## The hash characters are removed. ## <#/GAPDoc>  This piece is then included into another file by a statement like: <#Include Label="MyPiece"> Here are the exact rules, how pieces are gathered:  All lines up to a line containing the character sequence <#GAPDoc Label=" (exactly one space character) are ignored. The characters on the same line before this sequence are stored as prefix. The characters after the sequence up to the next double quotes character are stored as label. All other characters in the line are ignored.  The following lines up to a line containing the character sequence <#/GAPDoc> are stored under the label. These lines are processed as follows: The longest possible substring from the beginning of the line that equals the corresponding substring of the prefix is removed. Having stored a list of labels and pieces of text gathered as above this can be used as follows.  In GAPDoc documentation files all statements of the form <#Include Label="Key"> are replaced by the sequence of lines stored under the label Key.  Additionally, every occurrence of a statement of the form <#Include SYSTEM "Filename"> is replaced by the whole file stored under the name Filename in the file system.  These substitutions are done recursively (although one should probably avoid to use this extensively). Here is another example:  Example  # # <#GAPDoc Label="AnotherPiece"> some characters # # This text is not indented. # This text is indented by one blank. #Not indented. #<#/GAPDoc>  replaces <#Include Label="AnotherPiece"> by  Example  This text is not indented.  This text is indented by one blank.  Not indented.  Since these rules are very simple it is quite easy to write a program in almost any programming language which does this gathering of text pieces and the substitutions. In GAPDoc there is the GAP function ComposedDocument (4.2-1) which does this. Note that the XML-tag-like markup we have used here is not a legal XML markup, since the hash character is not allowed in element names. The mechanism described here is a preprocessing step which composes a document. 4.2 A Tool for Collecting a Document 4.2-1 ComposedDocument ComposedDocument( tagname, path, main, source[, info] )  function ComposedXMLString( path, main, source[, info] )  function Returns: a document as string, or a list with this string and information about the source positions The argument tagname is the string used for the pseudo elements which mark the pieces of a document to collect. (In 4.1 we used GAPDoc as tagname. The second function ComposedXMLString( ... ) is an abbreviation for ComposedDocument("GAPDoc", ... ). The argument path must be a path to some directory (as string or directory object), main the name of a file in this directory and source a list of file names, all of these relative to path. The document is constructed via the mechanism described in Section 4.1. First the files given in source are scanned for chunks of the document marked by <#tagname Label="..."> and  pairs. Then the file main is read and all <#Include ... >-tags are substituted recursively by other files or chunks of documentation found in the first step, respectively. If the optional argument info is given and set to true this function returns a list [str, origin], where str is a string containing the composed document and origin is a sorted list of entries of the form [pos, filename, line]. Here pos runs through all character positions of starting lines or text pieces from different files in str. The filename and line describe the origin of this part of the collected document. Without the fourth argument only the string str is returned.  Example  gap> doc := ComposedDocument("GAPDoc", "/my/dir", "manual.xml",  > ["../lib/func.gd", "../lib/func.gi"], true);;  4.2-2 OriginalPositionDocument OriginalPositionDocument( srcinfo, pos )  function Returns: A pair [filename, linenumber]. Here srcinfo must be a data structure as returned as second entry by ComposedDocument (4.2-1) called with info=true. It returns for a given position pos in the composed document the file name and line number from which that text was collected. GAPDoc-1.5.1/doc/gapdoc.bib0000644000175000017500000000076512026346063013673 0ustar billbill @book{ La85, author = {Lamport, Leslie}, title = {\LaTeX: A Document Preparation System}, publisher = {Addison-Wesley}, year = {1985}, isbn = {0-201-15790-X} } @manual{GAP4, key = "GAP", organization = "The GAP Group", title = {{GAP} -- {G}roups, {A}lgorithms, and {P}rogramming, Version 4.3}, year = 2002, address = "Aachen, St~Andrews", note = "http://www.gap-system.org", keywords = "groups; *; gap; manual" } GAPDoc-1.5.1/doc/chap0.html0000644000175000017500000010502112026346063013630 0ustar billbill GAP (GAPDoc) - Contents
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

GAPDoc

( Version 1.5.1 )

February 2012

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De
Homepage: http://www.math.rwth-aachen.de/~Frank.Luebeck

Max Neunhöffer
Email: neunhoef at mcs.st-and.ac.uk
Homepage: http://www-groups.mcs.st-and.ac.uk/~neunhoef/

Copyright

© 2000-2012 by Frank Lübeck and Max Neunhöffer

GAPDoc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Contents

3 The Document Type Definition

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/chap3.txt0000644000175000017500000022255712026346063013524 0ustar billbill 3 The Document Type Definition In this chapter we first explain what a document type definition is and then describe gapdoc.dtd in detail. That file together with the current chapter define how a GAPDoc document has to look like. It can be found in the main directory of the GAPDoc package and it is reproduced in Appendix B. We do not give many examples in this chapter which is more intended as a formal reference for all GAPDoc elements. Instead we provide an extra document with book name GAPDocExample (also accessible from the GAP online help). This uses all the constructs introduced in this chapter and you can easily compare the source code and how it looks like in the different output formats. Furthermore recall that many basic things about XML markup were already explained by example in the introductory chapter 1. 3.1 What is a DTD? A document type definition (DTD) is a formal declaration of how an XML document has to be structured. It is itself structured such that programs that handle documents can read it and treat the documents accordingly. There are for example parsers and validity checkers that use the DTD to validate an XML document, see 2.1-14. The main thing a DTD does is to specify which elements may occur in documents of a certain document type, how they can be nested, and what attributes they can or must have. So, for each element there is a rule. Note that a DTD can not ensure that a document which is valid also makes sense to the converters! It only says something about the formal structure of the document. For the remaining part of this chapter we have divided the elements of GAPDoc documents into several subsets, each of which will be discussed in one of the next sections. See the following three subsections to learn by example, how a DTD works. We do not want to be too formal here, but just enable the reader to understand the declarations in gapdoc.dtd. For precise descriptions of the syntax of DTD's see again the official standard in:   http://www.xml.com/axml/axml.html 3.2 Overall Document Structure A GAPDoc document contains on its top level exactly one element with name Book. This element is declared in the DTD as follows: 3.2-1   From gapdoc.dtd     After the keyword ELEMENT and the name Book there is a list in parentheses. This is a comma separated list of names of elements which can occur (in the given order) in the content of a Book element. Each name in such a list can be followed by one of the characters ?, * or +, meaning that the corresponding element can occur zero or one time, an arbitrary number of times, or at least once, respectively. Without such an extra character the corresponding element must occur exactly once. Instead of one name in this list there can also be a list of elements names separated by | characters, this denotes any element with one of the names (i.e., | means or). So, the Book element must contain first a TitlePage element, then an optional TableOfContents element, then a Body element, then zero or more elements of type Appendix, then an optional Bibliography element, and finally an optional element of type TheIndex. Note that only these elements are allowed in the content of the Book element. No other elements or text is allowed in between. An exception of this is that there may be whitespace between the end tag of one and the start tag of the next element - this should be ignored when the document is processed to some output format. An element like this is called an element with element content. The second declaration starts with the keyword ATTLIST and the element name Book. After that there is a triple of whitespace separated parameters (in general an arbitrary number of such triples, one for each allowed attribute name). The first (Name) is the name of an attribute for a Book element. The second (CDATA) is always the same for all of our declarations, it means that the value of the attribute consists of character data. The third parameter #REQUIRED means that this attribute must be specified with any Book element. Later we will also see optional attributes which are declared as #IMPLIED. 3.2-2   From gapdoc.dtd    Within this element information for the title page is collected. Note that more than one author can be specified. The elements must appear in this order because there is no sensible way to specify in a DTD something like the following elements may occur in any order but each exactly once. Before going on with the other elements inside the Book element we explain the elements for the title page. 3.2-3   From gapdoc.dtd  <!ELEMENT Title (%Text;)*>  Here is the last construct you need to understand for reading gapdoc.dtd. The expression %Text; is a so-called parameter entity. It is something like a macro within the DTD. It is defined as follows:  From gapdoc.dtd  <!ENTITY % Text "%InnerText; | List | Enum | Table">  This means, that every occurrence of %Text; in the DTD is replaced by the expression  From gapdoc.dtd  %InnerText; | List | Enum | Table  which is then expanded further because of the following definition:  From gapdoc.dtd  <!ENTITY % InnerText "#PCDATA |  Alt |  Emph | E |  Par | P | Br |  Keyword | K | Arg | A | Quoted | Q | Code | C |   File | F | Button | B | Package |  M | Math | Display |   Example | Listing | Log | Verb |  URL | Email | Homepage | Address | Cite | Label |   Ref | Index" >   These are the only two parameter entities we are using. They expand to lists of element names which are explained in the sequel and the keyword #PCDATA (concatenated with the or character |). So, the element (Title) is of so-called mixed content: It can contain parsed character data which does not contain further markup (#PCDATA) or any of the other above mentioned elements. Mixed content must always have the asterisk qualifier (like in Title) such that any sequence of elements (of the above list) and character data can be contained in a Title element. The %Text; parameter entity is used in all places in the DTD, where normal text should be allowed, including lists, enumerations, and tables, but no sectioning elements. The %InnerText; parameter entity is used in all places in the DTD, where inner text should be allowed. This means, that no structures like lists, enumerations, and tables are allowed. This is used for example in headings. 3.2-4 <Subtitle>  From gapdoc.dtd  <!ELEMENT Subtitle (%Text;)*>  Contains the subtitle of the document. 3.2-5 <Version>  From gapdoc.dtd  <!ELEMENT Version (#PCDATA|Alt)*>  Note that the version can only contain character data and no further markup elements (except for Alt, which is necessary to resolve the entities described in 2.2-3). The converters will not put the word Version in front of the text in this element. 3.2-6 <TitleComment>  From gapdoc.dtd  <!ELEMENT TitleComment (%Text;)*>  Sometimes a title and subtitle are not sufficient to give a rough idea about the content of a package. In this case use this optional element to specify an additional text for the front page of the book. This text should be short, use the Abstract element (see 3.2-10) for longer explanations. 3.2-7 <Author>  From gapdoc.dtd  <!ELEMENT Author (%Text;)*> <!-- There may be more than one Author! -->  As noted in the comment there may be more than one element of this type. This element should contain the name of an author and probably an Email-address and/or WWW-Homepage element for this author, see 3.5-6 and 3.5-7. You can also specify an individual postal address here, instead of using the Address element described below, see 3.2-9. 3.2-8 <Date>  From gapdoc.dtd  <!ELEMENT Date (#PCDATA)>  Only character data is allowed in this element which gives a date for the document. No automatic formatting is done. 3.2-9 <Address>  From gapdoc.dtd  <!ELEMENT Address (#PCDATA|Alt|Br)*>  This optional element can be used to specify a postal address of the author or the authors. If there are several authors with different addresses then put the Address elements inside the Author elements. Use the Br element (see 3.9-3) to mark the line breaks in the usual formatting of the address on a letter. Note that often it is not necessary to use this element because a postal address is easy to find via a link to a personal web page. 3.2-10 <Abstract>  From gapdoc.dtd  <!ELEMENT Abstract (%Text;)*>  This element contains an abstract of the whole book. 3.2-11 <Copyright>  From gapdoc.dtd  <!ELEMENT Copyright (%Text;)*>  This element is used for the copyright notice. Note the ©right; entity as described in section 2.2-3. 3.2-12 <Acknowledgements>  From gapdoc.dtd  <!ELEMENT Acknowledgements (%Text;)*>  This element contains the acknowledgements. 3.2-13 <Colophon>  From gapdoc.dtd  <!ELEMENT Colophon (%Text;)*>  The colophon page is used to say something about the history of a document. 3.2-14 <TableOfContents>  From gapdoc.dtd  <!ELEMENT TableOfContents EMPTY>  This element may occur in the Book element after the TitlePage element. If it is present, a table of contents is generated and inserted into the document. Note that because this element is declared to be EMPTY one can use the abbreviation  Example  <TableOfContents/>  to denote this empty element. 3.2-15 <Bibliography>  From gapdoc.dtd  <!ELEMENT Bibliography EMPTY> <!ATTLIST Bibliography Databases CDATA #REQUIRED  Style CDATA #IMPLIED>  This element may occur in the Book element after the last Appendix element. If it is present, a bibliography section is generated and inserted into the document. The attribute Databases must be specified, the names of several data files can be specified, separated by commas. Two kinds of files can be specified in Databases: The first are BibTeX files as defined in [Lam85, Appendix B]. Such files must have a name with extension .bib, and in Databases the name must be given without this extension. The second are files in BibXMLext format as defined in Section 7.2. These files must have an extension .xml and in Databases the full name must be specified. We suggest to use the BibXMLext format because it allows to produce potentially nicer bibliography entries in text and HTML documents. A bibliography style may be specified with the Style attribute. The optional Style attribute (for LaTeX output of the document) must also be specified without the .bst extension (the default is alpha). See also section 3.5-3 for a description of the Cite element which is used to include bibliography references into the text. 3.2-16 <TheIndex>  From gapdoc.dtd  <!ELEMENT TheIndex EMPTY>  This element may occur in the Book element after the Bibliography element. If it is present, an index is generated and inserted into the document. There are elements in GAPDoc which implicitly generate index entries (e.g., Func (3.4-2)) and there is an element Index (3.5-4) for explicitly adding index entries. 3.3 Sectioning Elements A GAPDoc book is divided into chapters, sections, and subsections. The idea is of course, that a chapter consists of sections, which in turn consist of subsections. However for the sake of flexibility, the rules are not too restrictive. Firstly, text is allowed everywhere in the body of the document (and not only within sections). Secondly, the chapter level may be omitted. The exact rules are described below. Appendices are a flavor of chapters, occurring after all regular chapters. There is a special type of subsection called ManSection. This is a subsection devoted to the description of a function, operation or variable. It is analogous to a manpage in the UNIX environment. Usually each function, operation, method, and so on should have its own ManSection. Cross referencing is done on the level of Subsections, respectively ManSections. The topics in GAP's online help are also pointing to subsections. So, they should not be too long. We start our description of the sectioning elements top-down: 3.3-1 <Body> The Body element marks the main part of the document. It must occur after the TableOfContents element. There is a big difference between inside and outside of this element: Whereas regular text is allowed nearly everywhere in the Body element and its subelements, this is not true for the outside. This has also implications on the handling of whitespace. Outside superfluous whitespace is usually ignored when it occurs between elements. Inside of the Body element whitespace matters because character data is allowed nearly everywhere. Here is the definition in the DTD:  From gapdoc.dtd  <!ELEMENT Body ( %Text;| Chapter | Section )*>  The fact that Chapter and Section elements are allowed here leads to the possibility to omit the chapter level entirely in the document. For a description of %Text; see 3.2-3. (Remark: The purpose of this element is to make sure that a valid GAPDoc document has a correct overall structure, which is only possible when the top element Book has element content.) 3.3-2 <Chapter>  From gapdoc.dtd  <!ELEMENT Chapter (%Text;| Heading | Section)*> <!ATTLIST Chapter Label CDATA #IMPLIED> <!-- For reference purposes -->  A Chapter element can have a Label attribute, such that this chapter can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the chapter as there is no automatic labelling! Chapter elements can contain text (for a description of %Text; see 3.2-3), Section elements, and Heading elements. The following additional rule cannot be stated in the DTD because we want a Chapter element to have mixed content. There must be exactly one Heading element in the Chapter element, containing the heading of the chapter. Here is its definition: 3.3-3 <Heading>  From gapdoc.dtd  <!ELEMENT Heading (%InnerText;)*>  This element is used for headings in Chapter, Section, Subsection, and Appendix elements. It may only contain %InnerText; (for a description see 3.2-3). Each of the mentioned sectioning elements must contain exactly one direct Heading element (i.e., one which is not contained in another sectioning element). 3.3-4 <Appendix>  From gapdoc.dtd  <!ELEMENT Appendix (%Text;| Heading | Section)*> <!ATTLIST Appendix Label CDATA #IMPLIED> <!-- For reference purposes -->  The Appendix element behaves exactly like a Chapter element (see 3.3-2) except for the position within the document and the numbering. While chapters are counted with numbers (1., 2., 3., ...) the appendices are counted with capital letters (A., B., ...). Again there is an optional Label attribute used for references. 3.3-5 <Section>  From gapdoc.dtd  <!ELEMENT Section (%Text;| Heading | Subsection | ManSection)*> <!ATTLIST Section Label CDATA #IMPLIED> <!-- For reference purposes -->  A Section element can have a Label attribute, such that this section can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the section as there is no automatic labelling! Section elements can contain text (for a description of %Text; see 3.2-3), Heading elements, and subsections. There must be exactly one direct Heading element in a Section element, containing the heading of the section. Note that a subsection is either a Subsection element or a ManSection element. 3.3-6 <Subsection>  From gapdoc.dtd  <!ELEMENT Subsection (%Text;| Heading)*> <!ATTLIST Subsection Label CDATA #IMPLIED> <!-- For reference purposes -->  The Subsection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). Note that you have to specify a label to reference the subsection as there is no automatic labelling! Subsection elements can contain text (for a description of %Text; see 3.2-3), and Heading elements. There must be exactly one Heading element in a Subsection element, containing the heading of the subsection. Another type of subsection is a ManSection, explained now: 3.4 ManSection–a special kind of subsection ManSections are intended to describe a function, operation, method, variable, or some other technical instance. It is analogous to a manpage in the UNIX environment. 3.4-1 <ManSection>  From gapdoc.dtd  <!ELEMENT ManSection ( Heading?,   ((Func, Returns?) | (Oper, Returns?) |   (Meth, Returns?) | (Filt, Returns?) |   (Prop, Returns?) | (Attr, Returns?) |  Var | Fam | InfoClass)+, Description )> <!ATTLIST ManSection Label CDATA #IMPLIED> <!-- For reference purposes -->  <!ELEMENT Returns (%Text;)*> <!ELEMENT Description (%Text;)*>  The ManSection element can have a Label attribute, such that this subsection can be referenced later on with a Ref element (see section 3.5-1). But this is probably rarely necessary because the elements Func and so on (explained below) generate automatically labels for cross referencing. The content of a ManSection element is one or more elements describing certain items in GAP, each of them optionally followed by a Returns element, followed by a Description element, which contains %Text; (see 3.2-3) describing it. (Remember to include examples in the description as often as possible, see 3.7-10). The classes of items GAPDoc knows of are: functions (Func), operations (Oper), methods (Meth), filters (Filt), properties (Prop), attributes (Attr), variables (Var), families (Fam), and info classes (InfoClass). One ManSection should only describe several of such items when these are very closely related. Each element for an item corresponding to a GAP function can be followed by a Returns element. In output versions of the document the string Returns:  will be put in front of the content text. The text in the Returns element should usually be a short hint about the type of object returned by the function. This is intended to give a good mnemonic for the use of a function (together with a good choice of names for the formal arguments). ManSections are also sectioning elements which count as subsections. Usually there should be no Heading-element in a ManSection, in that case a heading is generated automatically from the first Func-like element. Sometimes this default behaviour does not look appropriate, for example when there are several Func-like elements. For such cases an optional Heading is allowed. 3.4-2 <Func>  From gapdoc.dtd  <!ELEMENT Func EMPTY> <!ATTLIST Func Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #REQUIRED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of a function. The Name attribute is required and its value is the name of the function. The value of the Arg attribute (also required) contains the full list of arguments including optional parts, which are denoted by square brackets. The argument names can be separated by whitespace, commas or the square brackets for the optional arguments, like "grp[, elm]" or "xx[y[z] ]". If GAP options are used, this can be followed by a colon : and one or more assignments, like "n[, r]: tries := 100". The name of the function is also used as label for cross referencing. When the name of the function appears in the text of the document it should always be written with the Ref element, see 3.5-1. This allows to use a unique typesetting style for function names and automatic cross referencing. If the optional Label attribute is given, it is appended (with a colon : in between) to the name of the function for cross referencing purposes. The text of the label can also appear in the document text. So, it should be a kind of short explanation.  Example  <Func Arg="x[, y]" Name="LibFunc" Label="for my objects"/>  The optional Comm attribute should be a short description of the function, usually at most one line long (this is currently nowhere used). This element automatically produces an index entry with the name of the function and, if present, the text of the Label attribute as subentry (see also 3.2-16 and 3.5-4). 3.4-3 <Oper>  From gapdoc.dtd  <!ELEMENT Oper EMPTY> <!ATTLIST Oper Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #REQUIRED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of an operation. The attributes are used exactly in the same way as in the Func element (see 3.4-2). Note that multiple descriptions of the same operation may occur in a document because there may be several declarations in GAP. Furthermore there may be several ManSections for methods of this operation (see 3.4-4) which also use the same name. For reference purposes these must be distinguished by different Label attributes. 3.4-4 <Meth>  From gapdoc.dtd  <!ELEMENT Meth EMPTY> <!ATTLIST Meth Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #REQUIRED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of a method. The attributes are used exactly in the same way as in the Func element (see 3.4-2). Frequently, an operation is implemented by several different methods. Therefore it seems to be interesting to document them independently. This is possible by using the same method name in different ManSections. It is however required that these subsections and those describing the corresponding operation are distinguished by different Label attributes. 3.4-5 <Filt>  From gapdoc.dtd  <!ELEMENT Filt EMPTY> <!ATTLIST Filt Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #IMPLIED  Comm CDATA #IMPLIED  Type CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of a filter. The first four attributes are used in the same way as in the Func element (see 3.4-2), except that the Arg attribute is optional. The Type attribute can be any string, but it is thought to be something like Category or Representation. 3.4-6 <Prop>  From gapdoc.dtd  <!ELEMENT Prop EMPTY> <!ATTLIST Prop Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #REQUIRED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of a property. The attributes are used exactly in the same way as in the Func element (see 3.4-2). 3.4-7 <Attr>  From gapdoc.dtd  <!ELEMENT Attr EMPTY> <!ATTLIST Attr Name CDATA #REQUIRED  Label CDATA #IMPLIED  Arg CDATA #REQUIRED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to specify the usage of an attribute (in GAP). The attributes are used exactly in the same way as in the Func element (see 3.4-2). 3.4-8 <Var>  From gapdoc.dtd  <!ELEMENT Var EMPTY> <!ATTLIST Var Name CDATA #REQUIRED  Label CDATA #IMPLIED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to document a global variable. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute. 3.4-9 <Fam>  From gapdoc.dtd  <!ELEMENT Fam EMPTY> <!ATTLIST Fam Name CDATA #REQUIRED  Label CDATA #IMPLIED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to document a family. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute. 3.4-10 <InfoClass>  From gapdoc.dtd  <!ELEMENT InfoClass EMPTY> <!ATTLIST InfoClass Name CDATA #REQUIRED  Label CDATA #IMPLIED  Comm CDATA #IMPLIED>  This element is used within a ManSection element to document an info class. The attributes are used exactly in the same way as in the Func element (see 3.4-2) except that there is no Arg attribute. 3.5 Cross Referencing and Citations Cross referencing in the GAPDoc system is somewhat different to the usual LaTeX cross referencing in so far, that a reference knows which type of object it is referencing. For example a reference to a function is distinguished from a reference to a chapter. The idea of this is, that the markup must contain this information such that the converters can produce better output. The HTML converter can for example typeset a function reference just as the name of the function with a link to the description of the function, or a chapter reference as a number with a link in the other case. Referencing is done with the Ref element: 3.5-1 <Ref>  From gapdoc.dtd  <!ELEMENT Ref EMPTY> <!ATTLIST Ref Func CDATA #IMPLIED  Oper CDATA #IMPLIED  Meth CDATA #IMPLIED  Filt CDATA #IMPLIED  Prop CDATA #IMPLIED  Attr CDATA #IMPLIED  Var CDATA #IMPLIED  Fam CDATA #IMPLIED  InfoClass CDATA #IMPLIED  Chap CDATA #IMPLIED  Sect CDATA #IMPLIED  Subsect CDATA #IMPLIED  Appendix CDATA #IMPLIED  Text CDATA #IMPLIED   Label CDATA #IMPLIED  BookName CDATA #IMPLIED  Style (Text | Number) #IMPLIED> <!-- normally automatic -->  The Ref element is defined to be EMPTY. If one of the attributes Func, Oper, Meth, Prop, Attr, Var, Fam, InfoClass, Chap, Sect, Subsect, Appendix is given then there must be exactly one of these, making the reference one to the corresponding object. The Label attribute can be specified in addition to make the reference unique, for example if more than one method with a given name is present. (Note that there is no way to specify in the DTD that exactly one of the first listed attributes must be given, this is an additional rule.) A reference to a Label element defined below (see 3.5-2) is done by giving the Label attribute and optionally the Text attribute. If the Text attribute is present its value is typeset in place of the Ref element, if linking is possible (for example in HTML). If this is not possible, the section number is typeset. This type of reference is also used for references to tables (see 3.6-5). An external reference into another book can be specified by using the BookName attribute. In this case the Label attribute or, if this is not given, the function or section like attribute, is used to resolve the reference. The generated reference points to the first hit when asking ?book name: label inside GAP. The optional attribute Style can take only the values Text and Number. It can be used with references to sectioning units and it gives a hint to the converter programs, whether an explicit section number is generated or text. Normally all references to sections generate numbers and references to a GAP object generate the name of the corresponding object with some additional link or sectioning information, which is the behavior of Style="Text". In case Style="Number" in all cases an explicit section number is generated. So  Example  <Ref Subsect="Func" Style="Text"/> described in section  <Ref Subsect="Func" Style="Number"/>  produces: '<Func>' described in section 3.4-2. 3.5-2 <Label>  From gapdoc.dtd  <!ELEMENT Label EMPTY> <!ATTLIST Label Name CDATA #REQUIRED>  This element is used to define a label for referencing a certain position in the document, if this is possible. If an exact reference is not possible (like in a printed version of the document) a reference to the corresponding subsection is generated. The value of the Name attribute must be unique under all Label elements. 3.5-3 <Cite>  From gapdoc.dtd  <!ELEMENT Cite EMPTY> <!ATTLIST Cite Key CDATA #REQUIRED  Where CDATA #IMPLIED>  This element is for bibliography citations. It is EMPTY by definition. The attribute Key is the key for a lookup in a BibTeX database that has to be specified in the Bibliography element (see 3.2-15). The value of the Where attribute specifies the position in the document as in the corresponding LaTeX syntax \cite[Where value]{Key value}. 3.5-4 <Index>  From gapdoc.dtd  <!ELEMENT Index (%InnerText;|Subkey)*> <!ATTLIST Index Key CDATA #IMPLIED  Subkey CDATA #IMPLIED> <!ELEMENT Subkey (%InnerText;)*>  This element generates an index entry. The text within the element is typeset in the index entry, which is sorted under the value, that is specified in the Key and Subkey attributes. If they are not specified, the typeset text itself is used as the key. A subkey can be specified in the simpler version as an attribute, but then no further markup can be used for the subkey. Optionally, the subkey text can be given in a Subkey element, in this case the attribute value is used for sorting but the typeset text is taken from the content of Subkey. Note that all Func and similar elements automatically generate index entries. If the TheIndex element (3.2-16) is not present in the document all Index elements are ignored. 3.5-5 <URL>  From gapdoc.dtd  <!ELEMENT URL (#PCDATA|Alt|Link|LinkText)*> <!-- Link, LinkText  variant for case where text needs further markup --> <!ATTLIST URL Text CDATA #IMPLIED> <!-- This is for output formats  that have links like HTML --> <!ELEMENT Link (%InnerText;)*> <!-- the URL --> <!ELEMENT LinkText (%InnerText;)*> <!-- text for links, can contain markup -->   This element is for references into the internet. It specifies an URL and optionally a text which can be used for a link (like in HTML or PDF versions of the document). This can be specified in two ways: Either the URL is given as element content and the text is given in the optional Text attribute (in this case the text cannot contain further markup), or the element contains the two elements Link and LinkText which in turn contain the URL and the text, respectively. The default value for the text is the URL itself. 3.5-6 <Email>  From gapdoc.dtd  <!ELEMENT Email (#PCDATA|Alt|Link|LinkText)*>  This element type is the special case of an URL specifying an email address. The content of the element should be the email address without any prefix like mailto:. This address is typeset by all converters, also without any prefix. In the case of an output document format like HTML the converter can produce a link with a mailto: prefix. 3.5-7 <Homepage>  From gapdoc.dtd  <!ELEMENT Homepage (#PCDATA|Alt|Link|LinkText)*>  This element type is the special case of an URL specifying a WWW-homepage. 3.6 Structural Elements like Lists The GAPDoc system offers some limited access to structural elements like lists, enumerations, and tables. Although it is possible to use all LaTeX constructs one always has to think about other output formats. The elements in this section are guaranteed to produce something reasonable in all output formats. 3.6-1 <List>  From gapdoc.dtd  <!ELEMENT List ( ((Mark,Item)|(BigMark,Item)|Item)+ )> <!ATTLIST List Only CDATA #IMPLIED  Not CDATA #IMPLIED>  This element produces a list. Each item in the list corresponds to an Item element. Every Item element is optionally preceded by a Mark element. The content of this is used as a marker for the item. Note that this marker can be a whole word or even a sentence. It will be typeset in some emphasized fashion and most converters will provide some indentation for the rest of the item. The Only and Not attributes can be used to specify, that the list is included into the output by only one type of converter (Only) or all but one type of converter (Not). Of course at most one of the two attributes may occur in one element. The following values are allowed as of now: LaTeX, HTML, and Text. See also the Alt element in 3.9-1 for more about text alternatives for certain converters. 3.6-2 <Mark>  From gapdoc.dtd  <!ELEMENT Mark ( %InnerText;)*>  This element is used in the List element to mark items. See 3.6-1 for an explanation. 3.6-3 <Item>  From gapdoc.dtd  <!ELEMENT Item ( %Text;)*>  This element is used in the List, Enum, and Table elements to specify the items. See sections 3.6-1, 3.6-4, and 3.6-5 for further information. 3.6-4 <Enum>  From gapdoc.dtd  <!ELEMENT Enum ( Item+ )> <!ATTLIST Enum Only CDATA #IMPLIED  Not CDATA #IMPLIED>  This element is used like the List element (see 3.6-1) except that the items must not have marks attached to them. Instead, the items are numbered automatically. The same comments about the Only and Not attributes as above apply. 3.6-5 <Table>  From gapdoc.dtd  <!ELEMENT Table ( Caption?, (Row | HorLine)+ )> <!ATTLIST Table Label CDATA #IMPLIED  Only CDATA #IMPLIED  Not CDATA #IMPLIED  Align CDATA #REQUIRED>  <!-- We allow | and l,c,r, nothing else --> <!ELEMENT Row ( Item+ )> <!ELEMENT HorLine EMPTY> <!ELEMENT Caption ( %InnerText;)*>  A table in GAPDoc consists of an optional Caption element followed by a sequence of Row and HorLine elements. A HorLine element produces a horizontal line in the table. A Row element consists of a sequence of Item elements as they also occur in List and Enum elements. The Only and Not attributes have the same functionality as described in the List element in 3.6-1. The Align attribute is written like a LaTeX tabular alignment specifier but only the letters l, r, c, and | are allowed meaning left alignment, right alignment, centered alignment, and a vertical line as delimiter between columns respectively. If the Label attribute is there, one can reference the table with the Ref element (see 3.5-1) using its Label attribute. Usually only simple tables should be used. If you want a complicated table in the LaTeX output you should provide alternatives for text and HTML output. Note that in HTML-4.0 there is no possibility to interpret the | column separators and HorLine elements as intended. There are lines between all columns and rows or no lines at all. 3.7 Types of Text This section covers the markup of text. Various types of text exist. The following elements are used in the GAPDoc system to mark them. They mostly come in pairs, one long name which is easier to remember and a shortcut to make the markup lighter. Most of the following elements are thought to contain only character data and no further markup elements. It is however necessary to allow Alt elements to resolve the entities described in section 2.2-3. 3.7-1 <Emph> and <E>  From gapdoc.dtd  <!ELEMENT Emph (%InnerText;)*> <!-- Emphasize something --> <!ELEMENT E (%InnerText;)*> <!-- the same as shortcut -->  This element is used to emphasize some piece of text. It may contain %InnerText; (see 3.2-3). 3.7-2 <Quoted> and <Q>  From gapdoc.dtd  <!ELEMENT Quoted (%InnerText;)*> <!-- Quoted (in quotes) text --> <!ELEMENT Q (%InnerText;)*> <!-- Quoted text (shortcut) -->  This element is used to put some piece of text into  -quotes. It may contain %InnerText; (see 3.2-3). 3.7-3 <Keyword> and <K>  From gapdoc.dtd  <!ELEMENT Keyword (#PCDATA|Alt)*> <!-- Keyword --> <!ELEMENT K (#PCDATA|Alt)*> <!-- Keyword (shortcut) -->  This element is used to mark something as a keyword. Usually this will be a GAP keyword such as if or for. No further markup elements are allowed within this element except for the Alt element, which is necessary. 3.7-4 <Arg> and <A>  From gapdoc.dtd  <!ELEMENT Arg (#PCDATA|Alt)*> <!-- Argument --> <!ELEMENT A (#PCDATA|Alt)*> <!-- Argument (shortcut) -->  This element is used inside Descriptions in ManSections to mark something as an argument (of a function, operation, or such). It is guaranteed that the converters typeset those exactly as in the definition of functions. No further markup elements are allowed within this element. 3.7-5 <Code> and <C>  From gapdoc.dtd  <!ELEMENT Code (#PCDATA|Arg|Alt)*> <!-- GAP code --> <!ELEMENT C (#PCDATA|Arg|Alt)*> <!-- GAP code (shortcut) -->  This element is used to mark something as a piece of code like for example a GAP expression. It is guaranteed that the converters typeset this exactly as in the Listing element (compare section 3.7-9). The only further markup elements allowed within this element are <Arg> elements (see 3.7-4). 3.7-6 <File> and <F>  From gapdoc.dtd  <!ELEMENT File (#PCDATA|Alt)*> <!-- Filename --> <!ELEMENT F (#PCDATA|Alt)*> <!-- Filename (shortcut) -->  This element is used to mark something as a filename or a pathname in the file system. No further markup elements are allowed within this element. 3.7-7 <Button> and <B>  From gapdoc.dtd  <!ELEMENT Button (#PCDATA|Alt)*> <!-- "Button" (also Menu, Key, ...) --> <!ELEMENT B (#PCDATA|Alt)*> <!-- "Button" (shortcut) -->  This element is used to mark something as a button. It can also be used for other items in a graphical user interface like menus, menu entries, or keys. No further markup elements are allowed within this element. 3.7-8 <Package>  From gapdoc.dtd  <!ELEMENT Package (#PCDATA|Alt)*> <!-- A package name -->  This element is used to mark something as a name of a package. This is for example used to define the entities GAP, XGAP or GAPDoc (see section 2.2-3). No further markup elements are allowed within this element. 3.7-9 <Listing>  From gapdoc.dtd  <!ELEMENT Listing (#PCDATA)> <!-- This is just for GAP code listings --> <!ATTLIST Listing Type CDATA #IMPLIED> <!-- a comment about the type of  listed code, may appear in  output -->  This element is used to embed listings of programs into the document. Only character data and no other elements are allowed in the content. You should not use the character entities described in section 2.2-3 but instead type the characters directly. Only the general XML rules from section 2.1 apply. Note especially the usage of <![CDATA[ sections described there. It is guaranteed that all converters use a fixed width font for typesetting Listing elements. Compare also the usage of the Code and C elements in 3.7-5. The Type attribute contains a comment about the type of listed code. It may appear in the output. 3.7-10 <Log> and <Example>  From gapdoc.dtd  <!ELEMENT Example (#PCDATA)> <!-- This is subject to the automatic   example checking mechanism --> <!ELEMENT Log (#PCDATA)> <!-- This not -->  These two elements behave exactly like the Listing element (see 3.7-9). They are thought for protocols of GAP sessions. The only difference between the two is that Example sections are intended to be subject to an automatic manual checking mechanism used to ensure the correctness of the GAP manual whereas Log is not touched by this (see section 5.4 for checking tools). To get a good layout of the examples for display in a standard terminal we suggest to use SizeScreen([72]); (see SizeScreen (Reference: SizeScreen)) in your GAP session before producing the content of Example elements. 3.7-11 <Verb> There is one further type of verbatim-like element.  From gapdoc.dtd  <!ELEMENT Verb (#PCDATA)>   The content of such an element is guaranteed to be put into an output version exactly as it is using some fixed width font. Before the content a new line is started. If the line after the end of the start tag consists of whitespace only then this part of the content is skipped. This element is intended to be used together with the Alt element to specify pre-formatted ASCII alternatives for complicated Display formulae or Tables. 3.8 Elements for Mathematical Formulae 3.8-1 <Math> and <Display>  From gapdoc.dtd  <!-- Normal TeX math mode formula --> <!ELEMENT Math (#PCDATA|A|Arg|Alt)*>  <!-- TeX displayed math mode formula --> <!ELEMENT Display (#PCDATA|A|Arg|Alt)*> <!-- Mode="M" causes <M>-style formatting --> <!ATTLIST Display Mode CDATA #IMPLIED>  These elements are used for mathematical formulae. As described in section 2.2-2 they correspond to LaTeX's math and display math mode respectively. The formulae are typed in as in LaTeX, except that the standard XML entities, see 2.1-9 (in particular the characters < and &), must be escaped - either by using the corresponding entities or by enclosing the formula between <![CDATA[ and ]]>. (The main reference for LaTeX is [Lam85].) It is also possible to use some unicode characters for mathematical symbols directly, provided that it can be translated by Encode (6.2-2) into "LaTeX" encoding and that SimplifiedUnicodeString (6.2-2) with arguments "latin1" and "single" returns something sensible. Currently, we support entities &CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR; for the corresponding black board bold letters ℂ, ℤ, ℕ,ℙ, ℚ, ℍ and ℝ, respectively. The only element type that is allowed within the formula elements is the Arg or A element (see 3.7-4), which is used to typeset identifiers that are arguments to GAP functions or operations. If a Display element has an attribute Mode with value "M", then the formula is formatted as in M elements (see 3.8-2). Otherwise in text and HTML output the formula is shown as LaTeX source code. For simple formulae (and you should try to make all your formulae simple!) attempt to use the M element or the Mode="M" attribute in Display for which there is a well defined translation into text, which can be used for text and HTML output versions of the document. So, if possible try to avoid the Math elements and Display elements without attribute or provide useful text substitutes for complicated formulae via Alt elements (see 3.9-1 and 3.7-11). 3.8-2 <M>  From gapdoc.dtd  <!-- Math with well defined translation to text output --> <!ELEMENT M (#PCDATA|A|Arg|Alt)*>  The M element type is intended for formulae in the running text for which there is a sensible text version. For the LaTeX version of a GAPDoc document the M and Math elements are equivalent. The remarks in 3.8-1 about special characters and the Arg element apply here as well. A document which has all formulae enclosed in M elements can be well readable in text terminal output and printed output versions. Compared to former versions of GAPDoc many more formulae can be put into M elements. Most modern terminal emulations support unicode characters and many mathematical symbols can now be represented by such characters. But even if a terminal can only display ASCII characters, the user will see some not too bad representation of a formula. As examples, here are some LaTeX macros which have a sensible ASCII translation and are guaranteed to be translated accordingly by text (and HTML) converters (for a full list of handled Macros see RecFields(TEXTMTRANSLATIONS)): ┌──────────────────────────┬─────┐ │ \ast │ * │ ├──────────────────────────┼─────┤ │ \bf │  │ ├──────────────────────────┼─────┤ │ \bmod │ mod │ ├──────────────────────────┼─────┤ │ \cdot │ * │ ├──────────────────────────┼─────┤ │ \colon │ : │ ├──────────────────────────┼─────┤ │ \equiv │ = │ ├──────────────────────────┼─────┤ │ \geq │ >= │ ├──────────────────────────┼─────┤ │ \germ │  │ ├──────────────────────────┼─────┤ │ \hookrightarrow │ -> │ ├──────────────────────────┼─────┤ │ \iff │ <=> │ ├──────────────────────────┼─────┤ │ \langle │ < │ ├──────────────────────────┼─────┤ │ \ldots │ ... │ ├──────────────────────────┼─────┤ │ \left │   │ ├──────────────────────────┼─────┤ │ \leq │ <= │ ├──────────────────────────┼─────┤ │ \leftarrow │ <- │ ├──────────────────────────┼─────┤ │ \Leftarrow │ <= │ ├──────────────────────────┼─────┤ │ \limits │   │ ├──────────────────────────┼─────┤ │ \longrightarrow │ --> │ ├──────────────────────────┼─────┤ │ \Longrightarrow │ ==> │ ├──────────────────────────┼─────┤ │ \mapsto │ -> │ ├──────────────────────────┼─────┤ │ \mathbb │   │ ├──────────────────────────┼─────┤ │ \mathop │   │ ├──────────────────────────┼─────┤ │ \mid │ | │ ├──────────────────────────┼─────┤ │ \pmod │ mod │ ├──────────────────────────┼─────┤ │ \prime │ ' │ ├──────────────────────────┼─────┤ │ \rangle │ > │ ├──────────────────────────┼─────┤ │ \right │   │ ├──────────────────────────┼─────┤ │ \rightarrow │ -> │ ├──────────────────────────┼─────┤ │ \Rightarrow │ => │ ├──────────────────────────┼─────┤ │ \rm, \sf, \textrm, \text │  │ ├──────────────────────────┼─────┤ │ \setminus │ \ │ ├──────────────────────────┼─────┤ │ \thinspace │   │ ├──────────────────────────┼─────┤ │ \times │ x │ ├──────────────────────────┼─────┤ │ \to │ -> │ ├──────────────────────────┼─────┤ │ \vert │ | │ ├──────────────────────────┼─────┤ │ \! │  │ ├──────────────────────────┼─────┤ │ \, │  │ ├──────────────────────────┼─────┤ │ \; │   │ ├──────────────────────────┼─────┤ │ \{ │ { │ ├──────────────────────────┼─────┤ │ \} │ } │ └──────────────────────────┴─────┘ Table: LaTeX macros with special text translation In all other macros only the backslash is removed (except for some macros describing more exotic symbols). Whitespace is normalized (to one blank) but not removed. Note that whitespace is not added, so you may want to add a few more spaces than you usually do in your LaTeX documents. Braces {} are removed in general, however pairs of double braces are converted to one pair of braces. This can be used to write <M>x^{12}</M> for x^12 and <M>x_{{i+1}}</M> for x_{i+1}. 3.9 Everything else 3.9-1 <Alt> This element is used to specify alternatives for different output formats within normal text. See also sections 3.6-1, 3.6-4, and 3.6-5 for alternatives in lists and tables.  From gapdoc.dtd  <!ELEMENT Alt (%InnerText;)*> <!-- This is only to allow "Only" and  "Not" attributes for normal text --> <!ATTLIST Alt Only CDATA #IMPLIED  Not CDATA #IMPLIED>  Of course exactly one of the two attributes must occur in one element. The attribute values must be one word or a list of words, separated by spaces or commas. The words which are currently recognized by the converter programs contained in GAPDoc are: LaTeX, HTML, and Text. If the Only attribute is specified then only the corresponding converter will include the content of the element into the output document. If the Not attribute is specified the corresponding converter will ignore the content of the element. You can use other words to specify special alternatives for other converters of GAPDoc documents. We fix a rule for handling the content of an Alt element with Only attribute. In their content code for the corresponding output format is included directly. So, in case of HTML the content is HTML code, in case of LaTeX the content is LaTeX code. The converters don't apply any handling of special characters to this content. Within the element only %InnerText; (see 3.2-3) is allowed. This is to ensure that the same set of chapters, sections, and subsections show up in all output formats. 3.9-2 <Par> and <P>  From gapdoc.dtd  <!ELEMENT Par EMPTY> <!-- this is intentionally empty! --> <!ELEMENT P EMPTY> <!-- the same as shortcut -->  This EMPTY element marks the boundary of paragraphs. Note that an empty line in the input does not mark a new paragraph as opposed to the LaTeX convention. (Remark: it would be much easier to parse a document and to understand its sectioning and paragraph structure when there was an element whose content is the text of a paragraph. But in practice many paragraph boundaries are implicitly clear which would make it somewhat painful to enclose each paragraph in extra tags. The introduction of the P or Par elements as above delegates this pain to the writer of a conversion program for GAPDoc documents.) 3.9-3 <Br>  From gapdoc.dtd  <!ELEMENT Br EMPTY> <!-- a forced line break -->  This element can be used to force a line break in the output versions of a GAPDoc element, it does not start a new paragraph. Please, do not use this instead of a Par element, this would often lead to ugly output versions of your document. 3.9-4 <Ignore>  From gapdoc.dtd  <!ELEMENT Ignore (%Text;| Chapter | Section | Subsection | ManSection |  Heading)*> <!ATTLIST Ignore Remark CDATA #IMPLIED>  This element can appear anywhere. Its content is ignored by the standard converters. It can be used, for example, to include data which are not part of the actual GAPDoc document, like source code, or to make not finished parts of the document invisible. Of course, one can use special converter programs which extract the contents of Ignore elements. Information on the type of the content can be stored in the optional attribute Remark. �������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/doc/chap5.txt��������������������������������������������������������������������������0000644�0001750�0001750�00000155716�12026346063�013530� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 5 The Converters and an XML Parser The GAPDoc package contains a set of programs which allow us to convert a GAPDoc book into several output versions and to make them available to GAP's online help. Currently the following output formats are provided: text for browsing inside a terminal running GAP, LaTeX with hyperref-package for cross references via hyperlinks and HTML for reading with a Web-browser. 5.1 Producing Documentation from Source Files Here we explain how to use the functions which are described in more detail in the following sections. We assume that we have the main file MyBook.xml of a book "MyBook" in the directory /my/book/path. This contains <#Include ...>-statements as explained in Chapter 4. These refer to some other files as well as pieces of text which are found in the comments of some GAP source files ../lib/a.gd and ../lib/b.gi (relative to the path above). A BibTeX database MyBook.bib for the citations is also in the directory given above. We want to produce a text-, pdf- and HTML-version of the document. (A LaTeX version of the manual is produced, so it is also easy to compile dvi-, and postscript-versions.) All the commands shown in this Section are collected in the single function MakeGAPDocDoc (5.1-1). First we construct the complete XML-document as a string with ComposedDocument (4.2-1). This interprets recursively the <#Include ...>-statements.  Example  gap> path := Directory("/my/book/path");; gap> main := "MyBook.xml";; gap> files := ["../lib/a.gd", "../lib/b.gi"];; gap> bookname := "MyBook";; gap> doc := ComposedDocument("GAPDoc", path, main, files, true);;  Now doc is a list with two entries, the first is a string containing the XML-document, the second gives information from which files and locations which part of the document was collected. This is useful in the next step, if there are any errors in the document. Next we parse the document and store its structure in a tree-like data structure. The commands for this are ParseTreeXMLString (5.2-1) and CheckAndCleanGapDocTree (5.2-8).  Example  gap> r := ParseTreeXMLString(doc[1], doc[2]);; gap> CheckAndCleanGapDocTree(r); true  We start to produce a text version of the manual, which can be read in a terminal (window). The command is GAPDoc2Text (5.3-2). This produces a record with the actual text and some additional information. The text can be written chapter-wise into files with GAPDoc2TextPrintTextFiles (5.3-3). The names of these files are chap0.txt, chap1.txt and so on. The text contains some markup using ANSI escape sequences. This markup is substituted by the GAP help system (user configurable) to show the text with colors and other attributes. For the bibliography we have to tell GAPDoc2Text (5.3-2) the location of the BibTeX database by specifying a path as second argument.  Example  gap> t := GAPDoc2Text(r, path);; gap> GAPDoc2TextPrintTextFiles(t, path);  This command constructs all parts of the document including table of contents, bibliography and index. The functions FormatParagraph (6.1-4) for formatting text paragraphs and ParseBibFiles (7.1-1) for reading BibTeX files with GAP may be of independent interest. With the text version we have also produced the information which is used for searching with GAP's online help. Also, labels are produced which can be used by links in the HTML- and pdf-versions of the manual. Next we produce a LaTeX version of the document. GAPDoc2LaTeX (5.3-1) returns a string containing the LaTeX source. The utility function FileString (6.3-5) writes the content of a string to a file, we choose MyBook.tex.  Example  gap> l := GAPDoc2LaTeX(r);; gap> FileString(Filename(path, Concatenation(bookname, ".tex")), l);  Assuming that you have a sufficiently good installation of TeX available (see GAPDoc2LaTeX (5.3-1) for details) this can be processed with a series of commands like in the following example.  Example  cd /my/book/path pdflatex MyBook bibtex MyBook pdflatex MyBook makeindex MyBook pdflatex MyBook mv MyBook.pdf manual.pdf  After this we have a pdf-version of the document in the file manual.pdf. It contains hyperlink information which can be used with appropriate browsers for convenient reading of the document on screen (e.g., xpdf is nice because it allows remote calls to display named locations of the document). Of course, we could also use other commands like latex or dvips to process the LaTeX source file. Furthermore we have produced a file MyBook.pnr which is GAP-readable and contains the page number information for each (sub-)section of the document. We can add this page number information to the indexing information collected by the text converter and then print a manual.six file which is read by GAP when the manual is loaded. This is done with AddPageNumbersToSix (5.3-4) and PrintSixFile (5.3-5).  Example  gap> AddPageNumbersToSix(r, Filename(path, "MyBook.pnr")); gap> PrintSixFile(Filename(path, "manual.six"), r, bookname);  Finally we produce an HTML-version of the document and write it (chapter-wise) into files chap0.html, chap1.html and so on. They can be read with any Web-browser. The commands are GAPDoc2HTML (5.3-7) and GAPDoc2HTMLPrintHTMLFiles (5.3-8). We also add a link from manual.html to chap0.html. You probably want to copy stylesheet files into the same directory, see 5.3-9 for more details. The argument path of GAPDoc2HTML (5.3-7) specifies the directory containing the BibTeX database files.  Example  gap> h := GAPDoc2HTML(r, path);; gap> GAPDoc2HTMLPrintHTMLFiles(h, path);  5.1-1 MakeGAPDocDoc MakeGAPDocDoc( path, main, files, bookname[, gaproot] )  function This function collects all the commands for producing a text-, pdf- and HTML-version of a GAPDoc document as described in Section 5.1. It checks the .log file from the call of pdflatex and reports if there are errors, warnings or overfull boxes. Note: If this function works for you depends on your operating system and installed software. It will probably work on most UNIX systems with a standard LaTeX installation. If the function doesn't work for you look at the source code and adjust it to your system. Here path must be the directory (as string or directory object) containing the main file main of the document (given with or without the .xml extension. The argument files is a list of (probably source code) files relative to path which contain pieces of documentation which must be included in the document, see Chapter 4. And bookname is the name of the book used by GAP's online help. The optional argument gaproot must be a string which gives the relative path from path to the main GAP root directory. If this is given, the HTML files are produced with relative paths to external books. MakeGAPDocDoc can be called with additional arguments "MathJax", "Tth" and/or "MathML". If these are given additional variants of the HTML conversion are called, see GAPDoc2HTML (5.3-7) for details. It is possible to use GAPDoc with other languages than English, see SetGapDocLanguage (5.3-13) for more details. 5.2 Parsing XML Documents Arbitrary well-formed XML documents can be parsed and browsed by the following functions. 5.2-1 ParseTreeXMLString ParseTreeXMLString( str[, srcinfo][, entitydict] )  function ParseTreeXMLFile( fname[, entitydict] )  function Returns: a record which is root of a tree structure The first function parses an XML-document stored in string str and returns the document in form of a tree. The optional argument srcinfo must have the same format as in OriginalPositionDocument (4.2-2). If it is given then error messages refer to the original source of the text with the problem. With the optional argument entitydict named entities can be given to the parser, for example entities which are defined in the .dtd-file (which is not read by this parser). The standard XML-entities do not need to be provided, and for GAPDoc documents the entity definitions from gapdoc.dtd are automatically provided. Entities in the document's <!DOCTYPE declaration are parsed and also need not to be provided here. The argument entitydict must be a record where each component name is an entity name (without the surrounding & and ;) to which is assigned its substitution string. The second function is just a shortcut for ParseTreeXMLString( StringFile(fname), ... ), see StringFile (6.3-5). After these functions return the list of named entities which were known during the parsing can be found in the record ENTITYDICT. A node in the result tree corresponds to an XML element, or to some parsed character data. In the first case it looks as follows:  Example Node  rec( name := "Book",  attributes := rec( Name := "EDIM" ),  content := [ ... list of nodes for content ...],  start := 312,  stop := 15610,  next := 15611 )  This means that str{[312..15610]} looks like <Book Name="EDIM"> ... content ... </Book>. The leaves of the tree encode parsed character data as in the following example:  Example Node  rec( name := "PCDATA",   content := "text without markup " )  This function checks whether the XML document is well formed, see 2.1-14 for an explanation. If an error in the XML structure is found, a break loop is entered and the text around the position where the problem starts is shown. With Show(); one can browse the original input in the Pager (Reference: Pager), starting with the line where the error occurred. All entities are resolved when they are either entities defined in the GAPDoc package (in particular the standard XML entities) or if their definition is included in the <!DOCTYPE ..> tag of the document. Note that ParseTreeXMLString does not parse and interpret the corresponding document type definition (the .dtd-file given in the <!DOCTYPE ..> tag). Hence it also does not check the validity of the document (i.e., it is no validating XML parser). If you are using this function to parse a GAPDoc document you can use CheckAndCleanGapDocTree (5.2-8) for some validation and additional checking of the document structure. 5.2-2 StringXMLElement StringXMLElement( tree )  function Returns: a list [string, positions] The argument tree must have a format of a node in the parse tree of an XML document as returned by ParseTreeXMLString (5.2-1) (including the root node representing the full document). This function computes a pair [string, positions] where string contains XML code which is equivalent to the code which was parsed to get tree. And positions is a list of lists of four numbers [eltb, elte, contb, conte]. There is one such list for each XML element occuring in string, where eltb and elte are the begin and end position of this element in string and where contb and conte are begin and end position of the content of this element, or both are 0 if there is no content. Note that parsing XML code is an irreversible task, we can only expect to get equivalent XML code from this function. But parsing the resulting string again and applying StringXMLElement again gives the same result. See the function EntitySubstitution (5.2-3) for back-substitutions of entities in the result. 5.2-3 EntitySubstitution EntitySubstitution( xmlstring, entities )  function Returns: a string The argument xmlstring must be a string containing XML code or a pair [string, positions] as returned by StringXMLElement (5.2-2). The argument entities specifies entity names (without the surrounding & and ;) and their substitution strings, either a list of pairs of strings or as a record with the names as components and the substitutions as values. This function tries to substitute non-intersecting parts of string by the given entities. If the positions information is given then only parts of the document which allow a valid substitution by an entity are considered. Otherwise a simple text substitution without further check is done. Note that in general the entity resolution in XML documents is a complicated and non-reversible task. But nevertheless this utility may be useful in not too complicated situations. 5.2-4 DisplayXMLStructure DisplayXMLStructure( tree )  function This utility displays the tree structure of an XML document as it is returned by ParseTreeXMLString (5.2-1) (without the PCDATA leaves). Since this is usually quite long the result is shown using the Pager (Reference: Pager). 5.2-5 ApplyToNodesParseTree ApplyToNodesParseTree( tree, fun )  function AddRootParseTree( tree )  function RemoveRootParseTree( tree )  function The function ApplyToNodesParseTree applies a function fun to all nodes of the parse tree tree of an XML document returned by ParseTreeXMLString (5.2-1). The function AddRootParseTree is an application of this. It adds to all nodes a component .root to which the top node tree tree is assigned. These components can be removed afterwards with RemoveRootParseTree. Here are two more utilities which use ApplyToNodesParseTree. 5.2-6 GetTextXMLTree GetTextXMLTree( tree )  function Returns: a string The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function collects the content of this and all included elements recursively into a string. 5.2-7 XMLElements XMLElements( tree, eltnames )  function Returns: a list of nodes The argument tree must be a node of a parse tree of some XML document, see ParseTreeXMLFile (5.2-1). This function returns a list of all subnodes of tree (possibly including tree) of elements with name given in the list of strings eltnames. Use "PCDATA" as name for leave nodes which contain the actual text of the document. As an abbreviation eltnames can also be a string which is then put in a one element list. And here are utilities for processing GAPDoc XML documents. 5.2-8 CheckAndCleanGapDocTree CheckAndCleanGapDocTree( tree )  function Returns: nothing The argument tree of this function is a parse tree from ParseTreeXMLString (5.2-1) of some GAPDoc document. This function does an (incomplete) validity check of the document according to the document type declaration in gapdoc.dtd. It also does some additional checks which cannot be described in the DTD (like checking whether chapters and sections have a heading). For elements with element content the whitespace between these elements is removed. In case of an error the break loop is entered and the position of the error in the original XML document is printed. With Show(); one can browse the original input in the Pager (Reference: Pager). 5.2-9 AddParagraphNumbersGapDocTree AddParagraphNumbersGapDocTree( tree )  function Returns: nothing The argument tree must be an XML tree returned by ParseTreeXMLString (5.2-1) applied to a GAPDoc document. This function adds to each node of the tree a component .count which is of form [Chapter[, Section[, Subsection, Paragraph] ] ]. Here the first three numbers should be the same as produced by the LaTeX version of the document. Text before the first chapter is counted as chapter 0 and similarly for sections and subsections. Some elements are always considered to start a new paragraph. 5.2-10 InfoXMLParser InfoXMLParser info class The default level of this info class is 1. Functions like ParseTreeXMLString (5.2-1) are then printing some information, in particular in case of errors. You can suppress it by setting the level of InfoXMLParser to 0. With level 2 there may be some more information for debugging purposes. 5.3 The Converters Here are more details about the conversion programs for GAPDoc XML documents. 5.3-1 GAPDoc2LaTeX GAPDoc2LaTeX( tree )  function Returns: LaTeX document as string SetGapDocLaTeXOptions( [...] )  function Returns: Nothing The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). The output is a string containing a version of the document which can be written to a file and processed with LaTeX or pdfLaTeX (and probably BibTeX and makeindex). The output uses the report document class and needs the following LaTeX packages: a4wide, amssymb, inputenc, makeidx, color, fancyvrb, psnfss, pslatex, enumitem and hyperref. These are for example provided by the teTeX-1.0 or texlive distributions of TeX (which in turn are used for most TeX packages of current Linux distributions); see http://www.tug.org/tetex/. In particular, the resulting pdf-output (and dvi-output) contains (internal and external) hyperlinks which can be very useful for onscreen browsing of the document. The LaTeX processing also produces a file with extension .pnr which is GAP readable and contains the page numbers for all (sub)sections of the document. This can be used by GAP's online help; see AddPageNumbersToSix (5.3-4). Non-ASCII characters in the GAPDoc document are translated to LaTeX input in ASCII-encoding with the help of Encode (6.2-2) and the option "LaTeX". See the documentation of Encode (6.2-2) for how to proceed if you have a character which is not handled (yet). This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2LaTeXProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust layout details to your own taste by slight modifications of the program. Former versions of GAPDoc supported some XML processing instructions to add some extra lines to the preamble of the LaTeX document. Its use is now deprecated, use the much more flexible SetGapDocLaTeXOptions instead: The default layout of the resulting documents can be changed with SetGapDocLaTeXOptions. This changes parts of the header of the LaTeX file produced by GAPDoc. You can see the header with some placeholders by Page(GAPDoc2LaTeXProcs.Head);. The placeholders are filled with components from the record GAPDoc2LaTeXProcs.DefaultOptions. The arguments of SetGapDocLaTeXOptions can be records with the same structure (or parts of it) with different values. As abbreviations there are also three strings supported as arguments. These are "nocolor" for switching all colors to black; then "nopslatex" to use standard LaTeX fonts instead of postscript fonts; and finally "utf8" to choose UTF-8 as input encoding for the LaTeX document. 5.3-2 GAPDoc2Text GAPDoc2Text( tree[, bibpath][, width] )  function Returns: record containing text files as strings and other information The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). This function produces a text version of the document which can be used with GAP's online help (with the "screen" viewer, see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography and index. The bibliography is made from BibXMLext or BibTeX databases, see 7. Their location must be given with the argument bibpath (as string or directory object). The output is a record with one component for each chapter (with names "0", "1", ..., "Bib" and "Ind"). Each such component is again a record with the following components: text the text of the whole chapter as a string ssnr list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1) linenr corresponding list of line numbers where the subsections start len number of lines of this chapter The result can be written into files with the command GAPDoc2TextPrintTextFiles (5.3-3). As a side effect this function also produces the manual.six information which is used for searching in GAP's online help. This is stored in tree.six and can be printed into a manual.six file with PrintSixFile (5.3-5) (preferably after producing a LaTeX version of the document as well and adding the page number information to tree.six, see GAPDoc2LaTeX (5.3-1) and AddPageNumbersToSix (5.3-4)). The text produced by this function contains some markup via ANSI escape sequences. The sequences used here are usually ignored by terminals. But the GAP help system will substitute them by interpreted color and attribute sequences (see TextAttr (6.1-2)) before displaying them. There is a default markup used for this but it can also be configured by the user, see SetGAPDocTextTheme (5.3-6). Furthermore, the text produced is in UTF-8 encoding. The encoding is also translated on the fly, if GAPInfo.TermEncoding is set to some encoding supported by Encode (6.2-2), e.g., "ISO-8859-1" or "latin1". With the optional argument width a different length of the output text lines can be chosen. The default is 76 and all lines in the resulting text start with two spaces. This looks good on a terminal with a standard width of 80 characters and you probably don't want to use this argument. 5.3-3 GAPDoc2TextPrintTextFiles GAPDoc2TextPrintTextFiles( t[, path] )  function Returns: nothing The first argument must be a result returned by GAPDoc2Text (5.3-2). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.txt, chap1.txt, ..., chapBib.txt, and chapInd.txt. If you want to make your document accessible via the GAP online help you must put at least these files for the text version into a directory, together with the file manual.six, see PrintSixFile (5.3-5). Then specify the path to the manual.six file in the packages PackageInfo.g file, see 'Reference: The PackageInfo.g File'. Optionally you can add the dvi- and pdf-versions of the document which are produced with GAPDoc2LaTeX (5.3-1) to this directory. The files must have the names manual.dvi and manual.pdf, respectively. Also you can add the files of the HTML version produced with GAPDoc2HTML (5.3-7) to this directory, see GAPDoc2HTMLPrintHTMLFiles (5.3-8). The handler functions in GAP for this help format detect automatically which of the optional formats of a book are actually available. 5.3-4 AddPageNumbersToSix AddPageNumbersToSix( tree, pnrfile )  function Returns: nothing Here tree must be the XML tree of a GAPDoc document, returned by ParseTreeXMLString (5.2-1). Running latex on the result of GAPDoc2LaTeX(tree) produces a file pnrfile (with extension .pnr). The command GAPDoc2Text(tree) creates a component tree.six which contains all information about the document for the GAP online help, except the page numbers in the .dvi, .ps, .pdf versions of the document. This command adds the missing page number information to tree.six. 5.3-5 PrintSixFile PrintSixFile( tree, bookname, fname )  function Returns: nothing This function prints the .six file fname for a GAPDoc document stored in tree with name bookname. Such a file contains all information about the book which is needed by the GAP online help. This information must first be created by calls of GAPDoc2Text (5.3-2) and AddPageNumbersToSix (5.3-4). 5.3-6 SetGAPDocTextTheme SetGAPDocTextTheme( [optrec1[, optrec2], ...] )  function Returns: nothing This utility function is for readers of the screen version of GAP manuals which are generated by the GAPDoc package. It allows to configure the color and attribute layout of the displayed text. There is a default which can be reset by calling this function without argument. As an abbreviation the arguments optrec1 and so on can be strings for the known name of a theme. Information about valid names is shown with SetGAPDocTextTheme("");. Otherwise, optrec1 and so on must be a record. Its entries overwrite the corresponding entries in the default and in previous arguments. To construct valid markup you can use TextAttr (6.1-2). Entries must be either pairs of strings, which are put before and after the corresponding text, or as an abbreviation it can be a single string. In the latter case, the second string is implied; if the string contains an escape sequence the second string is TextAttr.reset, otherwise the given string is used. The following components are recognized: flush "both" for left-right justified paragraphs, and "left" for ragged right ones Heading chapter and (sub-)section headings Func function, operation, ... names Arg argument names in descriptions Example example code Package package names Returns Returns-line in descriptions URL URLs Mark Marks in description lists K GAP keywords C code or text to type F file names B buttons M simplified math elements Math normal math elements Display displayed math elements Emph emphasized text Q quoted text Ref reference text Prompt GAP prompt in examples BrkPrompt GAP break prompt in examples GAPInput GAP input in examples reset reset to default, don't change this BibAuthor author names in bibliography BibTitle titles in bibliography BibJournal journal names in bibliography BibVolume volume number in bibliography BibLabel labels for bibliography entries BibReset reset for bibliography, don't change ListBullet bullet for simple lists (2 visible characters long) EnumMarks one visible character before and after the number in enumerated lists DefLineMarker marker before function and variable definitions (2 visible characters long) FillString for filling in definitions and example separator lines  Example  gap> # use no colors for GAP examples and  gap> # change display of headings to bold green gap> SetGAPDocTextTheme("noColorPrompt",  >  rec(Heading:=Concatenation(TextAttr.bold, TextAttr.2)));  5.3-7 GAPDoc2HTML GAPDoc2HTML( tree[, bibpath[, gaproot]][, mtrans] )  function Returns: record containing HTML files as strings and other information The argument tree for this function is a tree describing a GAPDoc XML document as returned by ParseTreeXMLString (5.2-1) (probably also checked with CheckAndCleanGapDocTree (5.2-8)). Without an mtrans argument this function produces an HTML version of the document which can be read with any Web-browser and also be used with GAP's online help (see SetHelpViewer (Reference: SetHelpViewer)). It includes title page, bibliography, and index. The bibliography is made from BibTeX databases. Their location must be given with the argument bibpath (as string or directory object, if not given the current directory is used). If the third argument gaproot is given and is a string then this string is interpreted as relative path to GAP's main root directory. Reference-URLs to external HTML-books which begin with the GAP root path are then rewritten to start with the given relative path. This makes the HTML-documentation portable provided a package is installed in some standard location below the GAP root. The output is a record with one component for each chapter (with names "0", "1", ..., "Bib", and "Ind"). Each such component is again a record with the following components: text the text of an HTML file containing the whole chapter (as a string) ssnr list of subsection numbers in this chapter (like [3, 2, 1] for chapter 3, section 2, subsection 1) Standard output format without mtrans argument The HTML code produced with this converter conforms to the W3C specification XHTML 1.0 strict, see http://www.w3.org/TR/xhtml1. First, this means that the HTML files are valid XML files. Secondly, the extension strict says in particular that the code doesn't contain any explicit font or color information. Mathematical formulae are handled as in the text converter GAPDoc2Text (5.3-2). We don't want to assume that the browser can use symbol fonts. Some GAP users like to browse the online help with lynx, see SetHelpViewer (Reference: SetHelpViewer), which runs inside the same terminal windows as GAP. To view the generated files in graphical browsers, stylesheet files with layout configuration should be copied into the directory with the generated HTML files, see 5.3-9. Output format with mtrans argument Currently, there are three variants of this converter available which handle mathematical formulae differently. They are accessed via the optional last mtrans argument. If mtrans is set to "MathJax" the formulae are essentially translated as for LaTeX documents (there is no processing of <M> elements as decribed in 3.8-2). Inline formulae are delimited by \( and \) and displayed formulae by \[ and \]. With MathJax webpages can contain nicely formatted scalable and searchable formulae. The resulting files link by default to http://cdn.mathjax.org to get the MathJax script and fonts. This means that they can only be used on computers with internet access. An alternative URL can be set by overwriting GAPDoc2HTMLProcs.MathJaxURL before building the HTML version of a manual. This way a local installation of MathJax could be used. See http://www.mathjax.org/ for more details. The following possibilities for mtrans are still supported, but since the MathJax approach seems much better, their use is deprecated. If the argument mtrans is set to "Tth" it is assumed that you have installed the LaTeX to HTML translation program tth. This is used to translate the contents of the M, Math and Display elements into HTML code. Note that the resulting code is not compliant with any standard. Formally it is XHTML 1.0 Transitional, it contains explicit font specifications and the characters of mathematical symbols are included via their position in a Symbol font. Some graphical browsers can be configured to display this in a useful manner, check the Tth homepage (http://hutchinson.belmont.ma.us/tth/) for more details. If the mtrans argument is set to "MathML" it is assumed that you have installed the translation program ttm, see also the Tth homepage (http://hutchinson.belmont.ma.us/tth/)). This is used to translate the contents of the M, Math and Display elements to MathML 2.0 markup. The resulting files should conform to the "XHTML 1.1 plus MathML 2.0" standard, see the W3C information (http://www.w3.org/TR/MathML2/) for more details. It is expected that the next generation of graphical browsers will be able to render such files (try for example Mozilla, at least 0.9.9). You must copy the .xsl and .css files from GAPDocs mathml directory to the directory containing the output files. The translation with ttm is still experimental. The output of this converter variant is garbage for browsers which don't support MathML. This function works by running recursively through the document tree and calling a handler function for each GAPDoc XML element. Many of these handler functions (usually in GAPDoc2TextProcs.<ElementName>) are not difficult to understand (the greatest complications are some commands for index entries, labels or the output of page number information). So it should be easy to adjust certain details to your own taste by slight modifications of the program. The result of this converter can be written to files with the command GAPDoc2HTMLPrintHTMLFiles (5.3-8). There are two user preferences for reading the HTML manuals produced by GAPDoc. A user can choose among several style files which determine the appearance of the manual pages with SetUserPreference("GAPDoc", "HTMLStyle", [...]); where the list in the third argument are arguments for SetGAPDocHTMLStyle (5.3-11). The second preference is set by SetUserPreference("GAPDoc", "UseMathJax", ...); where the third argument is true or false (default). If this is set to true, the GAP help system displays the MathJax version of the HTML manuals. 5.3-8 GAPDoc2HTMLPrintHTMLFiles GAPDoc2HTMLPrintHTMLFiles( t[, path] )  function Returns: nothing The first argument must be a result returned by GAPDoc2HTML (5.3-7). The second argument is a path for the files to write, it can be given as string or directory object. The text of each chapter is written into a separate file with name chap0.html, chap1.html, ..., chapBib.html, and chapInd.html. The MathJax versions are written to files chap0_mj.html, ..., chapInd_mj.html. The experimental versions which are produced with tth or ttm use different names for the files, namely chap0_sym.html, and so on for files which need symbol fonts and chap0_mml.xml for files with MathML translations. You should also add stylesheet files to the directory with the HTML files, see 5.3-9. 5.3-9 Stylesheet files For graphical browsers the layout of the generated HTML manuals can be highly configured by cascading stylesheet (CSS) and javascript files. Such files are provided in the styles directory of the GAPDoc package. We recommend that these files are copied into each manual directory (such that each of them is selfcontained). There is a utility function CopyHTMLStyleFiles (5.3-10) which does this. Of course, these files may be changed or new styles may be added. New styles may also be sent to the GAPDoc authors for possible inclusion in future versions. The generated HTML files refer to the file manual.css which conforms to the W3C specification CSS 2.0, see http://www.w3.org/TR/REC-CSS2, and the javascript file manual.js (only in browsers which support CSS or javascript, respectively; but the HTML files are also readable without any of them). To add a style mystyle one or both of mystyle.css and mystyle.js must be provided; these can overwrite default settings and add new javascript functions. For more details see the comments in manual.js. 5.3-10 CopyHTMLStyleFiles CopyHTMLStyleFiles( dir )  function Returns: nothing This utility function copies the *.css and *.js files from the styles directory of the GAPDoc package into the directory dir. 5.3-11 SetGAPDocHTMLStyle SetGAPDocHTMLStyle( [style1[, style2], ...] )  function Returns: nothing This utility function is for readers of the HTML version of GAP manuals which are generated by the GAPDoc package. It allows to configure the display style of the manuals. This will only have an effect if you are using a browser that supports javascript. There is a default which can be reset by calling this function without argument. The arguments style1 and so on must be strings. You can find out about the valid strings by following the [Style] link on top of any manual page. (Going back to the original page, its address has a setting for GAPDocStyle which is the list of strings, separated by commas, you want to use here.)  Example  gap> # show/hide subsections in tables on contents only after click, gap> # and don't use colors in GAP examples gap> SetGAPDocHTMLStyle("toggless", "nocolorprompt");  5.3-12 InfoGAPDoc InfoGAPDoc info class The default level of this info class is 1. The converter functions for GAPDoc documents are then printing some information. You can suppress this by setting the level of InfoGAPDoc to 0. With level 2 there may be some more information for debugging purposes. 5.3-13 SetGapDocLanguage SetGapDocLanguage( [lang] )  function Returns: nothing The GAPDoc converter programs sometimes produce text which is not explicit in the document, e.g., headers like Abstract, Appendix, links to Next Chapter, variable types function and so on. With SetGapDocLanguage the language for these texts can be changed. The argument lang must be a string. Calling without argument or with a language name for which no translations are available is the same as using the default "english". If your language lang is not yet available, look at the record GAPDocTexts.english and translate all the strings to lang. Then assign this record to GAPDocTexts.(lang) and send it to the GAPDoc authors for inclusion in future versions of GAPDoc. (Currently, there are translations for english, german, russian and ukrainian.) Further hints: To get strings produced by LaTeX right you will probably use the babel package with option lang, see the information on ExtraPreamble in GAPDoc2LaTeX (5.3-1). If lang cannot be encoded in latin1 encoding you can consider the use of "utf8" with SetGapDocLaTeXOptions (5.3-1). 5.4 Testing Manual Examples We also provide some tools to check and adjust the examples given in <Example>-elements. Former versions of GAPDoc provided functions ManualExamples and TestManualExamples. These functions are still available, but no longer documented. Their use is deprecated. 5.4-1 ExtractExamples ExtractExamples( path, main, files, units )  function Returns: a list of lists ExtractExamplesXMLTree( tree, units )  function Returns: a list of lists The argument tree must be a parse tree of a GAPDoc document, see ParseTreeXMLFile (5.2-1). The function ExtractExamplesXMLTree returns a data structure representing the <Example> elements of the document. The return value can be used with RunExamples (5.4-2) to check and optionally update the examples of the document. Depending on the argument units several examples are collected in one list. Recognized values for units are "Chapter", "Section", "Subsection" or "Single". The latter means that each example is in a separate list. For all other value of units just one list with all examples is returned. The arguments path, main and files of ExtractExamples are the same as for ComposedDocument (4.2-1). This function first contructs and parses the GAPDoc document and then applies ExtractExamplesXMLTree. 5.4-2 RunExamples RunExamples( exmpls[, optrec] )  function Returns: nothing The argument exmpls must be the output of a call to ExtractExamples (5.4-1) or ExtractExamplesXMLTree (5.4-1). The optional argument optrec must be a record, its components can change the default behaviour of this function. By default this function runs the GAP input of all examples and compares the actual output with the output given in the examples. If differences occur these are displayed together with information on the location of the source code of that example. Before running the examples in each unit (entry of exmpls) the function START_TEST (Reference: START_TEST) is called and the screen width is set to 72 characters. If the argument optrec is given, the following components are recognized: showDiffs The default value is true, if set to something else found differences in the examples are not displayed. width The value must be a positive integer which is used as screen width when running the examples. As mentioned above, the default is 72 which is a sensible value for the text version of the GAPDoc document used in a 80 character wide terminal. changeSources If this is set to true then the source code of all manual examples which show differences is adjusted to the current outputs. The default is false. Use this feature with care. Note that sometimes differences can indicate a bug, and in such a case it is more appropriate to fix the bug instead of changing the example output. compareFunction The function used to compare the output shown in the example and the current output. See Test (Reference: Test) for more details. checkWidth If this option is a positive integer n the function prints warnings if an example contains any line with more than n characters (input and output lines are considered). By default this option is set to false. ��������������������������������������������������GAPDoc-1.5.1/doc/chap1.txt��������������������������������������������������������������������������0000644�0001750�0001750�00000042754�12026346063�013521� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 1 Introduction and Example The main purpose of the GAPDoc package is to define a file format for documentation of GAP-programs and -packages (see [GAP]). The problem is that such documentation should be readable in several output formats. For example it should be possible to read the documentation inside the terminal in which GAP is running (a text mode) and there should be a printable version in high typesetting quality (produced by some version of TeX). It is also popular to view GAP's online help with a Web-browser via an HTML-version of the documentation. Nowadays one can use LaTeX and standard viewer programs to produce and view on the screen dvi- or pdf-files with full support of internal and external hyperlinks. Certainly there will be other interesting document formats and tools in this direction in the future. Our aim is to find a format for writing the documentation which allows a relatively easy translation into the output formats just mentioned and which hopefully makes it easy to translate to future output formats as well. To make documentation written in the GAPDoc format directly usable, we also provide a set of programs, called converters, which produce text-, hyperlinked LaTeX- and HTML-output versions of a GAPDoc document. These programs are developed by the first named author. They run completely inside GAP, i.e., no external programs are needed. You only need latex and pdflatex to process the LaTeX output. These programs are described in Chapter 5. 1.1 XML The definition of the GAPDoc format uses XML, the eXtendible Markup Language. This is a standard (defined by the W3C consortium, see http://www.w3c.org) which lays down a syntax for adding markup to a document or to some data. It allows to define document structures via introducing markup elements and certain relations between them. This is done in a document type definition. The file gapdoc.dtd contains such a document type definition and is the central part of the GAPDoc package. The easiest way for getting a good idea about this is probably to look at an example. The Appendix A contains a short but complete GAPDoc document for a fictitious share package. In the next section we will go through this document, explain basic facts about XML and the GAPDoc document type, and give pointers to more details in later parts of this documentation. In the last Section 1.3 of this introductory chapter we try to answer some general questions about the decisions which lead to the GAPDoc package. 1.2 A complete example In this section we recall the lines from the example document in Appendix A and give some explanations.  from 3k+1.xml  <?xml version="1.0" encoding="UTF-8"?>   This line just tells a human reader and computer programs that the file is a document with XML markup and that the text is encoded in the UTF-8 character set (other common encodings are ASCII or ISO-8895-X encodings).  from 3k+1.xml  <!-- A complete "fake package" documentation  -->  Everything in a XML file between <!-- and --> is a comment and not part of the document content.  from 3k+1.xml  <!DOCTYPE Book SYSTEM "gapdoc.dtd">  This line says that the document contains markup which is defined in the system file gapdoc.dtd and that the markup obeys certain rules defined in that file (the ending dtd means document type definition). It further says that the actual content of the document consists of an element with name Book. And we can really see that the remaining part of the file is enclosed as follows:  from 3k+1.xml  <Book Name="3k+1">  [...] (content omitted) </Book>  This demonstrates the basics of the markup in XML. This part of the document is an element. It consists of the start tag <Book Name="3k+1">, the element content and the end tag </Book> (end tags always start with </). This element also has an attribute Name whose value is 3k+1. If you know HTML, this will look familiar to you. But there are some important differences: The element name Book and attribute name Name are case sensitive. The value of an attribute must always be enclosed in quotes. In XML every element has a start and end tag (which can be combined for elements defined as empty, see for example <TableOfContents/> below). If you know LaTeX, you are familiar with quite different types of markup, for example: The equivalent of the Book element in LaTeX is \begin{document} ... \end{document}. The sectioning in LaTeX is not done by explicit start and end markup, but implicitly via heading commands like \section. Other markup is done by using braces {} and putting some commands inside. And for mathematical formulae one can use the $ for the start and the end of the markup. In XML all markup looks similar to that of the Book element. The content of the book starts with a title page.  from 3k+1.xml  <TitlePage>  <Title>The <Package>ThreeKPlusOne</Package> Package  Version 42  Dummy Authör  3kplusone@dev.null     ©right; 2000 The Author.

  You can do with this package what you want.

Really.     The content of the TitlePage element consists again of elements. In Chapter 3 we describe which elements are allowed within a TitlePage and that their ordering is prescribed in this case. In the (stupid) name of the author you see that a German umlaut is used directly (in ISO-latin1 encoding). Contrary to LaTeX- or HTML-files this markup does not say anything about the actual layout of the title page in any output version of the document. It just adds information about the meaning of pieces of text. Within the Copyright element there are two more things to learn about XML markup. The 

 is a complete element. It is a combined start and end tag. This shortcut is allowed for elements which are defined to be always empty, i.e., to have no content. You may have already guessed that 

 is used as a paragraph separator. Note that empty lines do not separate paragraphs (contrary to LaTeX). The other construct we see here is ©right;. This is an example of an entity in XML and is a macro for some substitution text. Here we use an entity as a shortcut for a complicated expression which makes it possible that the term copyright is printed as some text like (C) in text terminal output and as a copyright character in other output formats. In GAPDoc we predefine some entities. Certain special characters must be typed via entities, for example <, > and & to avoid a misinterpretation as XML markup. It is possible to define additional entities for your document inside the  declaration, see 2.2-3. Note that elements in XML must always be properly nested, as in this example. A construct like ... is not allowed.  from 3k+1.xml    This is another example of an empty element. It just means that a table of contents for the whole document should be included into any output version of the document. After this the main text of the document follows inside certain sectioning elements:  from 3k+1.xml    The 3k+1 Problem 

Theory  [...] (content omitted) 
 
Program  [...] (content omitted)  
     These elements are used similarly to \chapter and \section in LaTeX. But note that the explicit end tags are necessary here. The sectioning commands allow to assign an optional attribute Label. This can be used for referring to a section inside the document. The text of the first section starts as follows. The whitespace in the text is unimportant and the indenting is not necessary.  from 3k+1.xml    Let k \in &NN; be a natural number. We consider the  sequence n(i, k), i \in &NN;, with n(1, k) = k and  else   Here we come to the interesting question how to type mathematical formulae in a GAPDoc document. We did not find any alternative for writing formulae in TeX syntax. (There is MATHML, but even simple formulae contain a lot of markup, become quite unreadable and they are cumbersome to type. Furthermore there seem to be no tools available which translate such formulae in a nice way into TeX and text.) So, formulae are essentially typed as in LaTeX. (Actually, it is also possible to type unicode characters of some mathematical symbols directly, or via an entity like the &NN; above.) There are three types of elements containing formulae: M, Math and Display. The first two are for in-text formulae and the third is for displayed formulae. Here M and Math are equivalent, when translating a GAPDoc document into LaTeX. But they are handled differently for terminal text (and HTML) output. For the content of an M-element there are defined rules for a translation into well readable terminal text. More complicated formulae are in Math or Display elements and they are just printed as they are typed in text output. So, to make a section well readable inside a terminal window you should try to put as many formulae as possible into M-elements. In our example text we used the notation n(i, k) instead of n_i(k) because it is easier to read in text mode. See Sections 2.2-2 and 3.9 for more details. A few lines further on we find two non-internal references.  from 3k+1.xml   problem, see or  http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/  The first within the Cite-element is the citation of a book. In GAPDoc we use the widely used BibTeX database format for reference lists. This does not use XML but has a well documented structure which is easy to parse. And many people have collections of references readily available in this format. The reference list in an output version of the document is produced with the empty element  from 3k+1.xml    close to the end of our example file. The attribute Databases give the name(s) of the database (.bib) files which contain the references. Putting a Web-address into an URL-element allows one to create a hyperlink in output formats which allow this. The second section of our example contains a special kind of subsection defined in GAPDoc.  from 3k+1.xml         This function computes for a natural number k the  beginning of the sequence n(i, k) defined in section  . The sequence stops at the first  1 or at n(max, k), if max is  given.  gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package"       A ManSection contains the description of some function, operation, method, filter and so on. The Func-element describes the name of a function (there are also similar elements Oper, Meth, Filt and so on) and names for its arguments, optional arguments enclosed in square brackets. See Section 3.4 for more details. In the Description we write the argument names as A-elements. A good description of a function should usually contain an example of its use. For this there are some verbatim-like elements in GAPDoc, like Example above (here, clearly, whitespace matters which causes a slightly strange indenting). The text contains an internal reference to the first section via the explicitly defined label sec:theory. The first section also contains a Ref-element which refers to the function described here. Note that there is no explicit label for such a reference. The pair  and  does the cross referencing (and hyperlinking if possible) implicitly via the name of the function. Here is one further element from our example document which we want to explain.  from 3k+1.xml    This is again an empty element which just says that an output version of the document should contain an index. Many entries for the index are generated automatically because the Func and similar elements implicitly produce such entries. It is also possible to include explicit additional entries in the index. 1.3 Some questions Are those XML files too ugly to read and edit? Just have a look and decide yourself. The markup needs more characters than most TeX or LaTeX markup. But the structure of the document is easier to see. If you configure your favorite editor well, you do not need more key strokes for typing the markup than in LaTeX. Why do we not use LaTeX alone? LaTeX is good for writing books. But LaTeX files are generally difficult to parse and to process to other output formats like text for browsing in a terminal window or HTML (or new formats which may become popular in the future). GAPDoc markup is one step more abstract than LaTeX insofar as it describes meaning instead of appearance of text. The inner workings of LaTeX are too complicated to learn without pain, which makes it difficult to overcome problems that occur occasionally. Why XML and not a newly defined markup language? XML is a well defined standard that is more and more widely used. Lots of people have thought about it. Years of experience with SGML went into the design. It is easy to explain, easy to parse and lots of tools are available, there will be more in the future. GAPDoc-1.5.1/doc/times.css0000644000175000017500000000026112026346063013602 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } GAPDoc-1.5.1/doc/chap6.html0000644000175000017500000013521412026346063013645 0ustar billbill GAP (GAPDoc) - Chapter 6: String and Text Utilities
Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

6 String and Text Utilities

6.1 Text Utilities

This section describes some utility functions for handling texts within GAP. They are used by the functions in the GAPDoc package but may be useful for other purposes as well. We start with some variables containing useful strings and go on with functions for parsing and reformatting text.

6.1-1 WHITESPACE
‣ WHITESPACE( global variable )
‣ CAPITALLETTERS( global variable )
‣ SMALLLETTERS( global variable )
‣ LETTERS( global variable )
‣ DIGITS( global variable )
‣ HEXDIGITS( global variable )
‣ BOXCHARS( global variable )

These variables contain sets of characters which are useful for text processing. They are defined as follows.

WHITESPACE

" \n\t\r"

CAPITALLETTERS

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

SMALLLETTERS

"abcdefghijklmnopqrstuvwxyz"

LETTERS

concatenation of CAPITALLETTERS and SMALLLETTERS

DIGITS

"0123456789"

HEXDIGITS

"0123456789ABCDEFabcdef"

BOXCHARS

"─│┌┬┐├┼┤└┴┘━┃┏┳┓┣╋┫┗┻┛═║╔╦╗╠╬╣╚╩╝" , these are in UTF-8 encoding, the i-th unicode character is BOXCHARS{[3*i-2..3*i]}.

6.1-2 TextAttr
‣ TextAttr( global variable )

The record TextAttr contains strings which can be printed to change the terminal attribute for the following characters. This only works with terminals which understand basic ANSI escape sequences. Try the following example to see if this is the case for the terminal you are using. It shows the effect of the foreground and background color attributes and of the .bold, .blink, .normal, .reverse and .underscore which can partly be mixed.

extra := ["CSI", "reset", "delline", "home"];;
for t in Difference(RecNames(TextAttr), extra) do
  Print(TextAttr.(t), "TextAttr.", t, TextAttr.reset,"\n");
od;

The suggested defaults for colors 0..7 are black, red, green, brown, blue, magenta, cyan, white. But this may be different for your terminal configuration.

The escape sequence .delline deletes the content of the current line and .home moves the cursor to the beginning of the current line.

for i in [1..5] do 
  Print(TextAttr.home, TextAttr.delline, String(i,-6), "\c"); 
  Sleep(1); 
od;

Whenever you use this in some printing routines you should make it optional. Use these attributes only when UserPreference("UseColorsInTerminal"); returns true.

6.1-3 WrapTextAttribute
‣ WrapTextAttribute( str, attr )( function )

Returns: a string with markup

The argument str must be a text as GAP string, possibly with markup by escape sequences as in TextAttr (6.1-2). This function returns a string which is wrapped by the escape sequences attr and TextAttr.reset. It takes care of markup in the given string by appending attr also after each given TextAttr.reset in str.

gap> str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY");
"XXX\033[32mBLUB\033[0mYYY"
gap> str2 := WrapTextAttribute(str, TextAttr.1);
"\033[31mXXX\033[32mBLUB\033[0m\033[31m\027YYY\033[0m"
gap> str3 := WrapTextAttribute(str, TextAttr.underscore);
"\033[4mXXX\033[32mBLUB\033[0m\033[4m\027YYY\033[0m"
gap> # use Print(str); and so on to see how it looks like.

6.1-4 FormatParagraph
‣ FormatParagraph( str[, len][, flush][, attr][, widthfun] )( function )

Returns: the formatted paragraph as string

This function formats a text given in the string str as a paragraph. The optional arguments have the following meaning:

len

the length of the lines of the formatted text, default is 78 (counted without a visible length of the strings specified in the attr argument)

flush

can be "left", "right", "center" or "both", telling that lines should be flushed left, flushed right, centered or left-right justified, respectively, default is "both"

attr

is a list of two strings; the first is prepended and the second appended to each line of the result (can for example be used for indenting, [" ", ""], or some markup, [TextAttr.bold, TextAttr.reset], default is ["", ""])

widthfun

must be a function which returns the display width of text in str. The default is Length assuming that each byte corresponds to a character of width one. If str is given in UTF-8 encoding one can use WidthUTF8String (6.2-3) here.

This function tries to handle markup with the escape sequences explained in TextAttr (6.1-2) correctly.

gap> str := "One two three four five six seven eight nine ten eleven.";;
gap> Print(FormatParagraph(str, 25, "left", ["/* ", " */"]));           
/* One two three four five */
/* six seven eight nine ten */
/* eleven. */

6.1-5 SubstitutionSublist
‣ SubstitutionSublist( list, sublist, new[, flag] )( function )

Returns: the changed list

This function looks for (non-overlapping) occurrences of a sublist sublist in a list list (compare PositionSublist (Reference: PositionSublist)) and returns a list where these are substituted with the list new.

The optional argument flag can either be "all" (this is the default if not given) or "one". In the second case only the first occurrence of sublist is substituted.

If sublist does not occur in list then list itself is returned (and not a ShallowCopy(list)).

gap> SubstitutionSublist("xababx", "ab", "a");
"xaax"

6.1-6 StripBeginEnd
‣ StripBeginEnd( list, strip )( function )

Returns: changed string

Here list and strip must be lists. This function returns the sublist of list which does not contain the leading and trailing entries which are entries of strip. If the result is equal to list then list itself is returned.

gap> StripBeginEnd(" ,a, b,c,   ", ", ");
"a, b,c"

6.1-7 StripEscapeSequences
‣ StripEscapeSequences( str )( function )

Returns: string without escape sequences

This function returns the string one gets from the string str by removing all escape sequences which are explained in TextAttr (6.1-2). If str does not contain such a sequence then str itself is returned.

6.1-8 RepeatedString
‣ RepeatedString( c, len )( function )
‣ RepeatedUTF8String( c, len )( function )

Here c must be either a character or a string and len is a non-negative number. Then RepeatedString returns a string of length len consisting of copies of c.

In the variant RepeatedUTF8String the argument c is considered as string in UTF-8 encoding, and it can also be specified as unicode string or character, see Unicode (6.2-1). The result is a string in UTF-8 encoding which has visible width len as explained in WidthUTF8String (6.2-3).

gap> RepeatedString('=',51);
"==================================================="
gap> RepeatedString("*=",51);
"*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"
gap> s := "bäh";;
gap> enc := GAPInfo.TermEncoding;;
gap> if enc <> "UTF-8" then s := Encode(Unicode(s, enc), "UTF-8"); fi;
gap> l := RepeatedUTF8String(s, 8);;
gap> u := Unicode(l, "UTF-8");;
gap> Print(Encode(u, enc), "\n");
bähbähbä

6.1-9 NumberDigits
‣ NumberDigits( str, base )( function )

Returns: integer

‣ DigitsNumber( n, base )( function )

Returns: string

The argument str of NumberDigits must be a string consisting only of an optional leading '-' and characters in 0123456789abcdefABCDEF, describing an integer in base base with 2 ≤ base ≤ 16. This function returns the corresponding integer.

The function DigitsNumber does the reverse.

gap> NumberDigits("1A3F",16);
6719
gap> DigitsNumber(6719, 16);
"1A3F"

6.1-10 PositionMatchingDelimiter
‣ PositionMatchingDelimiter( str, delim, pos )( function )

Returns: position as integer or fail

Here str must be a string and delim a string with two different characters. This function searches the smallest position r of the character delim[2] in str such that the number of occurrences of delim[2] in str between positions pos+1 and r is by one greater than the corresponding number of occurrences of delim[1].

If such an r exists, it is returned. Otherwise fail is returned.

gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0);
fail
gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1);
2
gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6);
11

6.1-11 WordsString
‣ WordsString( str )( function )

Returns: list of strings containing the words

This returns the list of words of a text stored in the string str. All non-letters are considered as word boundaries and are removed.

gap> WordsString("one_two \n    three!?");
[ "one", "two", "three" ]

6.1-12 Base64String
‣ Base64String( str )( function )
‣ StringBase64( bstr )( function )

Returns: a string

The first function translates arbitrary binary data given as a GAP string into a base 64 encoded string. This encoded string contains only printable ASCII characters and is used in various data transfer protocols (MIME encoded emails, weak password encryption, ...). We use the specification in RFC 2045.

The second function has the reverse functionality. Here we also accept the characters -_ instead of +/ as last two characters. Whitespace is ignored.

gap> b := Base64String("This is a secret!");
"VGhpcyBpcyBhIHNlY3JldCEA="
gap> StringBase64(b);                       
"This is a secret!"

6.2 Unicode Strings

The GAPDoc package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings.

6.2-1 Unicode Strings and Characters
‣ Unicode( list[, encoding] )( operation )
‣ UChar( num )( operation )
‣ IsUnicodeString( filter )
‣ IsUnicodeCharacter( filter )
‣ IntListUnicodeString( ustr )( function )

Unicode characters are described by their codepoint, an integer in the range from 0 to 2^21-1. For details about unicode, see http://www.unicode.org.

The function UChar wraps an integer num into a GAP object lying in the filter IsUnicodeCharacter. Use Int to get the codepoint back. The argument num can also be a GAP character which is then translated to an integer via IntChar (Reference: IntChar).

Unicode produces a GAP object in the filter IsUnicodeString. This is a wrapped list of integers for the unicode characters in the string. The function IntListUnicodeString gives access to this list of integers. Basic list functionality is available for IsUnicodeString elements. The entries are in IsUnicodeCharacter. The argument list for Unicode is either a list of integers or a GAP string. In the latter case an encoding can be specified as string, its default is "UTF-8".

Currently supported encodings can be found in UNICODE_RECODE.NormalizedEncodings (ASCII, ISO-8859-X, UTF-8 and aliases). The encoding "XML" means an ASCII encoding in which non-ASCII characters are specified by XML character entities. The encoding "URL" is for URL-encoded (also called percent-encoded strings, as specified in RFC 3986 (see here). The listed encodings "LaTeX" and aliases cannot be used with Unicode. See the operation Encode (6.2-2) for mapping a unicode string to a GAP string.

gap> ustr := Unicode("a and \366", "latin1");
Unicode("a and \303\266")
gap> ustr = Unicode("a and &#246;", "XML");  
true
gap> IntListUnicodeString(ustr);
[ 97, 32, 97, 110, 100, 32, 246 ]
gap> ustr[7];
'ö'

6.2-2 Encode
‣ Encode( ustr[, encoding] )( operation )

Returns: a GAP string

‣ SimplifiedUnicodeString( ustr[, encoding][, "single"] )( function )

Returns: a unicode string

‣ LowercaseUnicodeString( ustr )( function )

Returns: a unicode string

‣ UppercaseUnicodeString( ustr )( function )

Returns: a unicode string

‣ LaTeXUnicodeTable( global variable )
‣ SimplifiedUnicodeTable( global variable )
‣ LowercaseUnicodeTable( global variable )

The operation Encode translates a unicode string ustr into a GAP string in some specified encoding. The default encoding is "UTF-8".

Supported encodings can be found in UNICODE_RECODE.NormalizedEncodings. Except for some cases mentioned below characters which are not available in the target encoding are substituted by '?' characters.

If the encoding is "URL" (see Unicode (6.2-1)) then an optional argument encreserved can be given, it must be a list of reserved characters which should be percent encoded; the default is to encode only the % character.

The encoding "LaTeX" substitutes non-ASCII characters and LaTeX special characters by LaTeX code as given in an ordered list LaTeXUnicodeTable of pairs [codepoint, string]. If you have a unicode character for which no substitution is contained in that list, you will get a warning and the translation is Unicode(nr). In this case find a substitution and add a corresponding [codepoint, string] pair to LaTeXUnicodeTable using AddSet (Reference: AddSet). Also, please, tell the GAPDoc authors about your addition, such that we can extend the list LaTeXUnicodeTable. (Most of the initial entries were generated from lists in the TeX projects encTeX and ucs.) There are some variants of this encoding:

"LaTeXleavemarkup" does the same translations for non-ASCII characters but leaves the LaTeX special characters (e.g., any LaTeX commands) as they are.

"LaTeXUTF8" does not give a warning about unicode characters without explicit translation, instead it translates the character to its UTF-8 encoding. Make sure to setup your LaTeX document such that all these characters are understood.

"LaTeXUTF8leavemarkup" is a combination of the last two variants.

Note that the "LaTeX" encoding can only be used with Encode but not for the opposite translation with Unicode (6.2-1) (which would need far too complicated heuristics).

The function SimplifiedUnicodeString can be used to substitute many non-ASCII characters by related ASCII characters or strings (e.g., by a corresponding character without accents). The argument ustr and the result are unicode strings, if encoding is "ASCII" then all non-ASCII characters are translated, otherwise only the non-latin1 characters. If the string "single" in an argument then only substitutions are considered which don't make the result string longer. The translations are stored in a sorted list SimplifiedUnicodeTable. Its entries are of the form [codepoint, trans1, trans2, ...]. Here trans1 and so on is either an integer for the codepoint of a substitution character or it is a list of codepoint integers. If you are missing characters in this list and know a sensible ASCII approximation, then add an entry (with AddSet (Reference: AddSet)) and tell the GAPDoc authors about it. (The initial content of SimplifiedUnicodeTable was mainly generated from the "transtab" tables by Markus Kuhn.)

The function LowercaseUnicodeString gets and returns a unicode string and translates each uppercase character to its corresponding lowercase version. This function uses a list LowercaseUnicodeTable of pairs of codepoint integers. This list was generated using the file UnicodeData.txt from the unicode definition (field 14 in each row).

The function UppercaseUnicodeString does the similar translation to uppercase characters.

gap> ustr := Unicode("a and &#246;", "XML");
Unicode("a and \303\266")
gap> SimplifiedUnicodeString(ustr, "ASCII");
Unicode("a and oe")
gap> SimplifiedUnicodeString(ustr, "ASCII", "single");
Unicode("a and o")
gap> ustr2 := UppercaseUnicodeString(ustr);;
gap> Print(Encode(ustr2, GAPInfo.TermEncoding), "\n");
A AND Ö

6.2-3 Lengths of UTF-8 strings
‣ WidthUTF8String( str )( function )
‣ NrCharsUTF8String( str )( function )

Returns: an integer

Let str be a GAP string with text in UTF-8 encoding. There are three "lengths" of such a string which must be distinguished. The operation Length (Reference: Length) returns the number of bytes and so the memory occupied by str. The function NrCharsUTF8String returns the number of unicode characters in str, that is the length of Unicode(str).

In many applications the function WidthUTF8String is more interesting, it returns the number of columns needed by the string if printed to a terminal. This takes into account that some unicode characters are combining characters and that there are wide characters which need two columns (e.g., for Chinese or Japanese). (To be precise: This implementation assumes that there are no control characters in str and uses the character width returned by the wcwidth function in the GNU C-library called with UTF-8 locale.)

gap> # A, German umlaut u, B, zero width space, C, newline
gap> str := Encode( Unicode( "A&#xFC;B&#x200B;C\n", "XML" ) );;
gap> Print(str);
AüB​C
gap> # umlaut u needs two bytes and the zero width space three
gap> Length(str);
9
gap> NrCharsUTF8String(str);
6
gap> # zero width space and newline don't contribute to width
gap> WidthUTF8String(str);
4

6.3 Print Utilities

The following printing utilities turned out to be useful for interactive work with texts in GAP. But they are more general and so we document them here.

6.3-1 PrintTo1
‣ PrintTo1( filename, fun )( function )
‣ AppendTo1( filename, fun )( function )

The argument fun must be a function without arguments. Everything which is printed by a call fun() is printed into the file filename. As with PrintTo (Reference: PrintTo) and AppendTo (Reference: AppendTo) this overwrites or appends to, respectively, a previous content of filename.

These functions can be particularly efficient when many small pieces of text shall be written to a file, because no multiple reopening of the file is necessary.

gap> f := function() local i; 
>   for i in [1..100000] do Print(i, "\n"); od; end;; 
gap> PrintTo1("nonsense", f); # now check the local file `nonsense'

6.3-2 StringPrint
‣ StringPrint( obj1[, obj2[, ...]] )( function )
‣ StringView( obj )( function )

These functions return a string containing the output of a Print or ViewObj call with the same arguments.

This should be considered as a (temporary?) hack. It would be better to have String (Reference: String) methods for all GAP objects and to have a generic Print (Reference: Print)-function which just interprets these strings.

6.3-3 PrintFormattedString
‣ PrintFormattedString( str )( function )

This function prints a string str. The difference to Print(str); is that no additional line breaks are introduced by GAP's standard printing mechanism. This can be used to print lines which are longer than the current screen width. In particular one can print text which contains escape sequences like those explained in TextAttr (6.1-2), where lines may have more characters than visible characters.

6.3-4 Page
‣ Page( ... )( function )
‣ PageDisplay( obj )( function )

These functions are similar to Print (Reference: Print) and Display (Reference: Display), respectively. The difference is that the output is not sent directly to the screen, but is piped into the current pager; see Pager (Reference: Pager).

gap> Page([1..1421]+0);
gap> PageDisplay(CharacterTable("Symmetric", 14));

6.3-5 StringFile
‣ StringFile( filename )( function )
‣ FileString( filename, str[, append] )( function )

The function StringFile returns the content of file filename as a string. This works efficiently with arbitrary (binary or text) files. If something went wrong, this function returns fail.

Conversely the function FileString writes the content of a string str into the file filename. If the optional third argument append is given and equals true then the content of str is appended to the file. Otherwise previous content of the file is deleted. This function returns the number of bytes written or fail if something went wrong.

Both functions are quite efficient, even with large files.

Goto Chapter: Top 1 2 3 4 5 6 7 A B C Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/doc/toggless.js0000644000175000017500000000420512026346063014136 0ustar billbill/* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); GAPDoc-1.5.1/doc/manual.six0000644000175000017500000012604712026346063013764 0ustar billbill#SIXFORMAT GapDocGAP HELPBOOKINFOSIXTMP := rec( encoding := "UTF-8", bookname := "GAPDoc", entries := [ [ "Title page", ".", [ 0, 0, 0 ], 1, 1, "title page", "X7D2C85EC87DD46E5" ], [ "Copyright", ".-1", [ 0, 0, 1 ], 26, 2, "copyright", "X81488B807F2A1CF1" ] , [ "Table of Contents", ".-2", [ 0, 0, 2 ], 37, 3, "table of contents", "X8537FEB07AF2BEC8" ], [ "\033[1X\033[33X\033[0;-2YIntroduction and Example\033[133X\033[101X", "1", [ 1, 0, 0 ], 1, 5, "introduction and example", "X7D4EE663818DA109" ], [ "\033[1X\033[33X\033[0;-2YXML\033[133X\033[101X", "1.1", [ 1, 1, 0 ], 27, 5, "xml", "X8590236E858F7E93" ], [ "\033[1X\033[33X\033[0;-2YA complete example\033[133X\033[101X", "1.2", [ 1, 2, 0 ], 47, 6, "a complete example", "X7B47AFA881BFC9DC" ], [ "\033[1X\033[33X\033[0;-2YSome questions\033[133X\033[101X", "1.3", [ 1, 3, 0 ], 289, 9, "some questions", "X79A97B867F45E5C7" ], [ "\033[1X\033[33X\033[0;-2YHow To Type a \033[5XGAPDoc\033[105X\033[101X\\ 027\033[1X\027 Document\033[133X\033[101X", "2", [ 2, 0, 0 ], 1, 10, "how to type a gapdoc\027\027 document", "X820EBE207DCC0655" ], [ "\033[1X\033[33X\033[0;-2YGeneral XML Syntax\033[133X\033[101X", "2.1", [ 2, 1, 0 ], 21, 10, "general xml syntax", "X7B3A544986A1A9EA" ], [ "\033[1X\033[33X\033[0;-2YHead of XML Document\033[133X\033[101X", "2.1-1", [ 2, 1, 1 ], 28, 10, "head of xml document", "X84E8D39687638CF0" ], [ "\033[1X\033[33X\033[0;-2YComments\033[133X\033[101X", "2.1-2", [ 2, 1, 2 ], 45, 10, "comments", "X780C79EB85C32138" ], [ "\033[1X\033[33X\033[0;-2YProcessing Instructions\033[133X\033[101X", "2.1-3", [ 2, 1, 3 ], 52, 11, "processing instructions", "X82DBCCAD8358BB63" ], [ "\033[1X\033[33X\033[0;-2YNames in XML and Whitespace\033[133X\033[101X", "2.1-4", [ 2, 1, 4 ], 66, 11, "names in xml and whitespace", "X7A0FB16C7FEC0B53" ], [ "\033[1X\033[33X\033[0;-2YElements\033[133X\033[101X", "2.1-5", [ 2, 1, 5 ], 81, 11, "elements", "X79B130FC7906FB4C" ], [ "\033[1X\033[33X\033[0;-2YStart Tags\033[133X\033[101X", "2.1-6", [ 2, 1, 6 ], 90, 11, "start tags", "X7DD1DCB783588BD5" ], [ "\033[1X\033[33X\033[0;-2YEnd Tags\033[133X\033[101X", "2.1-7", [ 2, 1, 7 ], 108, 11, "end tags", "X7E5A567E83005B62" ], [ "\033[1X\033[33X\033[0;-2YCombined Tags for Empty Elements\033[133X\033[101\ X", "2.1-8", [ 2, 1, 8 ], 114, 11, "combined tags for empty elements", "X843A02A88514D919" ], [ "\033[1X\033[33X\033[0;-2YEntities\033[133X\033[101X", "2.1-9", [ 2, 1, 9 ], 121, 12, "entities", "X78FB56C77B1F391A" ], [ "\033[1X\033[33X\033[0;-2YSpecial Characters in XML\033[133X\033[101X", "2.1-10", [ 2, 1, 10 ], 142, 12, "special characters in xml", "X84A95A19801EDE76" ], [ "\033[1X\033[33X\033[0;-2YRules for Attribute Values\033[133X\033[101X", "2.1-11", [ 2, 1, 11 ], 154, 12, "rules for attribute values", "X7F49E7AD785AED22" ], [ "\033[1X\033[33X\033[0;-2Y\033[10XCDATA\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "2.1-12", [ 2, 1, 12 ], 162, 12, "cdata\027\027", "X80D9026B7CB7B32F" ], [ "\033[1X\033[33X\033[0;-2YEncoding of an XML Document\033[133X\033[101X", "2.1-13", [ 2, 1, 13 ], 178, 12, "encoding of an xml document", "X8709BD337DA09ED5" ], [ "\033[1X\033[33X\033[0;-2YWell Formed and Valid XML Documents\033[133X\033[\ 101X", "2.1-14", [ 2, 1, 14 ], 186, 13, "well formed and valid xml documents", "X8561F07A81CABDD6" ], [ "\033[1X\033[33X\033[0;-2YEntering \033[5XGAPDoc\033[105X\033[101X\027\033[\ 1X\027 Documents\033[133X\033[101X", "2.2", [ 2, 2, 0 ], 208, 13, "entering gapdoc\027\027 documents", "X7E9C91B77D1D0A4A" ], [ "\033[1X\033[33X\033[0;-2YOther special characters\033[133X\033[101X", "2.2-1", [ 2, 2, 1 ], 213, 13, "other special characters", "X79171E047B069F94" ], [ "\033[1X\033[33X\033[0;-2YMathematical Formulae\033[133X\033[101X", "2.2-2", [ 2, 2, 2 ], 239, 13, "mathematical formulae", "X7EAE0C5A835F126F" ], [ "\033[1X\033[33X\033[0;-2YMore Entities\033[133X\033[101X", "2.2-3", [ 2, 2, 3 ], 256, 14, "more entities", "X7BDFF6D37FBED400" ], [ "\033[1X\033[33X\033[0;-2YThe Document Type Definition\033[133X\033[101X", "3", [ 3, 0, 0 ], 1, 15, "the document type definition", "X7859CFF180D52D49" ], [ "\033[1X\033[33X\033[0;-2YWhat is a DTD?\033[133X\033[101X", "3.1", [ 3, 1, 0 ], 17, 15, "what is a dtd?", "X7B76F6F786521F6B" ], [ "\033[1X\033[33X\033[0;-2YOverall Document Structure\033[133X\033[101X", "3.2", [ 3, 2, 0 ], 45, 15, "overall document structure", "X7DB0F9E57879CC76" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.2-1", [ 3, 2, 1 ], 51, 16, "\027\027", "X7D27228D7E68473E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-2", [ 3, 2, 2 ], 95, 16, "\027\027", "X8643EEF587FC8AD4" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.2-3", [ 3, 2, 3 ], 112, 16, "<title>\027\027", "X85C1D07A84F1F736" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Subtitle>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-4", [ 3, 2, 4 ], 167, 17, "<subtitle>\027\027", "X81B6D8D679A42915" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Version>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-5", [ 3, 2, 5 ], 176, 17, "<version>\027\027", "X8064BA177E9D23B8" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<TitleComment>\033[110X\033[101X\027\033[\ 1X\027\033[133X\033[101X", "3.2-6", [ 3, 2, 6 ], 188, 18, "<titlecomment>\027\027", "X7C2765047A1561EB" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Author>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-7", [ 3, 2, 7 ], 200, 18, "<author>\027\027", "X846067D18467D228" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Date>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.2-8", [ 3, 2, 8 ], 213, 18, "<date>\027\027", "X87C47AD378268979" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Address>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-9", [ 3, 2, 9 ], 223, 18, "<address>\027\027", "X7B84029079583E6E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Abstract>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-10", [ 3, 2, 10 ], 240, 18, "<abstract>\027\027", "X7CF09C0F82D16612" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Copyright>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-11", [ 3, 2, 11 ], 249, 18, "<copyright>\027\027", "X823232338648B1D7" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Acknowledgements>\033[110X\033[101X\027\\ 033[1X\027\033[133X\033[101X", "3.2-12", [ 3, 2, 12 ], 259, 19, "<acknowledgements>\027\027", "X868A17B2849FEB84" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Colophon>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-13", [ 3, 2, 13 ], 268, 19, "<colophon>\027\027", "X87AF74847BEA348D" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<TableOfContents>\033[110X\033[101X\027\\ 033[1X\027\033[133X\033[101X", "3.2-14", [ 3, 2, 14 ], 277, 19, "<tableofcontents>\027\027", "X81F18BDE7B3182F4" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Bibliography>\033[110X\033[101X\027\033[\ 1X\027\033[133X\033[101X", "3.2-15", [ 3, 2, 15 ], 295, 19, "<bibliography>\027\027", "X857F84507B5CED2A" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<TheIndex>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.2-16", [ 3, 2, 16 ], 325, 20, "<theindex>\027\027", "X80ACB0AA7FC414E4" ], [ "\033[1X\033[33X\033[0;-2YSectioning Elements\033[133X\033[101X", "3.3", [ 3, 3, 0 ], 338, 20, "sectioning elements", "X80E2AD7481DD69D9" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Body>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.3-1", [ 3, 3, 1 ], 360, 20, "<body>\027\027", "X85FB286D82BA5300" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Chapter>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.3-2", [ 3, 3, 2 ], 384, 20, "<chapter>\027\027", "X81A68C117E39FA60" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Heading>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.3-3", [ 3, 3, 3 ], 405, 21, "<heading>\027\027", "X82F09E29814C7A72" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Appendix>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.3-4", [ 3, 3, 4 ], 420, 21, "<appendix>\027\027", "X7951B5C482C59057" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Section>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.3-5", [ 3, 3, 5 ], 435, 21, "<section>\027\027", "X795D46507CE20232" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Subsection>\033[110X\033[101X\027\033[1X\ \027\033[133X\033[101X", "3.3-6", [ 3, 3, 6 ], 457, 21, "<subsection>\027\027", "X7A9AC7787E8163DC" ], [ "\033[1X\033[33X\033[0;-2YManSection\342\200\223a special kind of subsectio\ n\033[133X\033[101X", "3.4", [ 3, 4, 0 ], 478, 22, "mansectiona\200\223a special kind of subsection", "X877B8B7C7EDD09E9" ] , [ "\033[1X\033[33X\033[0;-2Y\033[10X<ManSection>\033[110X\033[101X\027\033[1X\ \027\033[133X\033[101X", "3.4-1", [ 3, 4, 1 ], 485, 22, "<mansection>\027\027", "X7E24999A86DAEB60" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Func>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-2", [ 3, 4, 2 ], 528, 22, "<func>\027\027", "X87CA42C681B95BCE" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Oper>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-3", [ 3, 4, 3 ], 569, 23, "<oper>\027\027", "X82684F9E8461DFC7" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Meth>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-4", [ 3, 4, 4 ], 590, 23, "<meth>\027\027", "X780247227AC3340B" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Filt>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-5", [ 3, 4, 5 ], 611, 24, "<filt>\027\027", "X7BFBED2C8766065E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Prop>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-6", [ 3, 4, 6 ], 630, 24, "<prop>\027\027", "X81A6364E79DBE958" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Attr>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-7", [ 3, 4, 7 ], 645, 24, "<attr>\027\027", "X7B0AA7E98373249D" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Var>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-8", [ 3, 4, 8 ], 660, 24, "<var>\027\027", "X7D4982A27D773098" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Fam>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.4-9", [ 3, 4, 9 ], 674, 25, "<fam>\027\027", "X7DF346F7795CB5C1" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<InfoClass>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.4-10", [ 3, 4, 10 ], 688, 25, "<infoclass>\027\027", "X84367BDE795E0C56" ], [ "\033[1X\033[33X\033[0;-2YCross Referencing and Citations\033[133X\033[101X\ ", "3.5", [ 3, 5, 0 ], 702, 25, "cross referencing and citations", "X78595FB585569617" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Ref>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-1", [ 3, 5, 1 ], 717, 25, "<ref>\027\027", "X865F20E386B6DA49" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Label>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-2", [ 3, 5, 2 ], 779, 26, "<label>\027\027", "X8653BAF279C7A817" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Cite>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-3", [ 3, 5, 3 ], 793, 26, "<cite>\027\027", "X855B311D7C33A50E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Index>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-4", [ 3, 5, 4 ], 808, 27, "<index>\027\027", "X7D2B1F278577D2D5" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<URL>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-5", [ 3, 5, 5 ], 832, 27, "<url>\027\027", "X7C58A957852F867C" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Email>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.5-6", [ 3, 5, 6 ], 853, 27, "<email>\027\027", "X7FEB041D793E781B" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Homepage>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.5-7", [ 3, 5, 7 ], 866, 28, "<homepage>\027\027", "X81F135A886B732E6" ], [ "\033[1X\033[33X\033[0;-2YStructural Elements like Lists\033[133X\033[101X" , "3.6", [ 3, 6, 0 ], 875, 28, "structural elements like lists", "X840099DF83823686" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<List>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.6-1", [ 3, 6, 1 ], 884, 28, "<list>\027\027", "X7F97E8DD784F5CAA" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Mark>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.6-2", [ 3, 6, 2 ], 907, 28, "<mark>\027\027", "X786406A77C9F1CD6" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Item>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.6-3", [ 3, 6, 3 ], 917, 28, "<item>\027\027", "X7D6BFC907F5FEF37" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Enum>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.6-4", [ 3, 6, 4 ], 927, 28, "<enum>\027\027", "X7D3B2150818E3CD4" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Table>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<table>\027\027", "X7BA7DA848347E2A9" ], [ "\033[1X\033[33X\033[0;-2YTypes of Text\033[133X\033[101X", "3.7", [ 3, 7, 0 ], 977, 29, "types of text", "X7CA1E1327AFBA578" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Emph>\033[110X\033[101X\027\033[1X\027 a\ nd \033[10X<E>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-1", [ 3, 7, 1 ], 989, 29, "<emph>\027\027 and <e>\027\027", "X7E07C12185A25EF7" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Quoted>\033[110X\033[101X\027\033[1X\\ 027 and \033[10X<Q>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-2", [ 3, 7, 2 ], 1000, 30, "<quoted>\027\027 and <q>\027\027", "X87FB13F57EF49C93" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Keyword>\033[110X\033[101X\027\033[1X\\ 027 and \033[10X<K>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-3", [ 3, 7, 3 ], 1011, 30, "<keyword>\027\027 and <k>\027\027", "X86A11FA98045FE79" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Arg>\033[110X\033[101X\027\033[1X\027 an\ d \033[10X<A>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-4", [ 3, 7, 4 ], 1023, 30, "<arg>\027\027 and <a>\027\027", "X8502FFCF7DC7982B" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Code>\033[110X\033[101X\027\033[1X\027 a\ nd \033[10X<C>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-5", [ 3, 7, 5 ], 1036, 30, "<code>\027\027 and <c>\027\027", "X79C6755D80AEA4C1" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<File>\033[110X\033[101X\027\033[1X\027 a\ nd \033[10X<F>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-6", [ 3, 7, 6 ], 1049, 30, "<file>\027\027 and <f>\027\027", "X7C30FEC078523528" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Button>\033[110X\033[101X\027\033[1X\\ 027 and \033[10X<B>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-7", [ 3, 7, 7 ], 1060, 31, "<button>\027\027 and <b>\027\027", "X79AEA5068489EE6E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Package>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.7-8", [ 3, 7, 8 ], 1072, 31, "<package>\027\027", "X7B9BB2D878262083" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Listing>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.7-9", [ 3, 7, 9 ], 1083, 31, "<listing>\027\027", "X799961B67E34193D" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Log>\033[110X\033[101X\027\033[1X\027 an\ d \033[10X<Example>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.7-10", [ 3, 7, 10 ], 1105, 31, "<log>\027\027 and <example>\027\027", "X7C926CF778F54591" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Verb>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.7-11", [ 3, 7, 11 ], 1124, 32, "<verb>\027\027", "X80500AFD86ADECC5" ], [ "\033[1X\033[33X\033[0;-2YElements for Mathematical Formulae\033[133X\033[1\ 01X", "3.8", [ 3, 8, 0 ], 1141, 32, "elements for mathematical formulae", "X8145F6B37C04AA0A" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Math>\033[110X\033[101X\027\033[1X\027 a\ nd \033[10X<Display>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.8-1", [ 3, 8, 1 ], 1144, 32, "<math>\027\027 and <display>\027\027", "X7B0254677AA56B5E" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<M>\033[110X\033[101X\027\033[1X\027\033[\ 133X\033[101X", "3.8-2", [ 3, 8, 2 ], 1187, 32, "<m>\027\027", "X8796A7577B29543A" ], [ "\033[1X\033[33X\033[0;-2YEverything else\033[133X\033[101X", "3.9", [ 3, 9, 0 ], 1307, 35, "everything else", "X7A0D26B180BEDE37" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Alt>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.9-1", [ 3, 9, 1 ], 1310, 35, "<alt>\027\027", "X817B08367FF43419" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Par>\033[110X\033[101X\027\033[1X\027 an\ d \033[10X<P>\033[110X\033[101X\027\033[1X\027\033[133X\033[101X", "3.9-2", [ 3, 9, 2 ], 1344, 35, "<par>\027\027 and <p>\027\027", "X847CBC4380DBAC63" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Br>\033[110X\033[101X\027\033[1X\027\\ 033[133X\033[101X", "3.9-3", [ 3, 9, 3 ], 1364, 35, "<br>\027\027", "X7C910EF07C3FF929" ], [ "\033[1X\033[33X\033[0;-2Y\033[10X<Ignore>\033[110X\033[101X\027\033[1X\\ 027\033[133X\033[101X", "3.9-4", [ 3, 9, 4 ], 1376, 36, "<ignore>\027\027", "X84855267801B3077" ], [ "\033[1X\033[33X\033[0;-2YDistributing a Document into Several Files\033[13\ 3X\033[101X", "4", [ 4, 0, 0 ], 1, 37, "distributing a document into several files", "X7A3355C07F57C280" ], [ "\033[1X\033[33X\033[0;-2YThe Conventions\033[133X\033[101X", "4.1", [ 4, 1, 0 ], 15, 37, "the conventions", "X7CE078A07E8256DC" ], [ "\033[1X\033[33X\033[0;-2YA Tool for Collecting a Document\033[133X\033[101\ X", "4.2", [ 4, 2, 0 ], 87, 38, "a tool for collecting a document", "X81E07B0F83EBDA5F" ], [ "\033[1X\033[33X\033[0;-2YThe Converters and an XML Parser\033[133X\033[101\ X", "5", [ 5, 0, 0 ], 1, 40, "the converters and an xml parser", "X845E7FDC7C082CC4" ], [ "\033[1X\033[33X\033[0;-2YProducing Documentation from Source Files\033[133\ X\033[101X", "5.1", [ 5, 1, 0 ], 12, 40, "producing documentation from source files", "X7D1BB5867C13FA14" ], [ "\033[1X\033[33X\033[0;-2YParsing XML Documents\033[133X\033[101X", "5.2", [ 5, 2, 0 ], 167, 42, "parsing xml documents", "X7FE2AF49838D9034" ], [ "\033[1X\033[33X\033[0;-2YThe Converters\033[133X\033[101X", "5.3", [ 5, 3, 0 ], 372, 46, "the converters", "X8560E1A2845EC2C1" ], [ "\033[1X\033[33X\033[0;-2YStylesheet files\033[133X\033[101X", "5.3-9", [ 5, 3, 9 ], 799, 52, "stylesheet files", "X788AB14383272FDB" ], [ "\033[1X\033[33X\033[0;-2YTesting Manual Examples\033[133X\033[101X", "5.4", [ 5, 4, 0 ], 884, 54, "testing manual examples", "X800299827B88ABBE" ], [ "\033[1X\033[33X\033[0;-2YString and Text Utilities\033[133X\033[101X", "6", [ 6, 0, 0 ], 1, 56, "string and text utilities", "X86CEF540862EE042" ], [ "\033[1X\033[33X\033[0;-2YText Utilities\033[133X\033[101X", "6.1", [ 6, 1, 0 ], 4, 56, "text utilities", "X847DA07C7C46B38A" ], [ "\033[1X\033[33X\033[0;-2YUnicode Strings\033[133X\033[101X", "6.2", [ 6, 2, 0 ], 296, 61, "unicode strings", "X8489C67D80399814" ], [ "\033[1X\033[33X\033[0;-2YUnicode Strings and Characters\033[133X\033[101X" , "6.2-1", [ 6, 2, 1 ], 303, 61, "unicode strings and characters", "X8475671278948DDD" ], [ "\033[1X\033[33X\033[0;-2YLengths of UTF-8 strings\033[133X\033[101X", "6.2-3", [ 6, 2, 3 ], 438, 63, "lengths of utf-8 strings", "X801237207E06A876" ], [ "\033[1X\033[33X\033[0;-2YPrint Utilities\033[133X\033[101X", "6.3", [ 6, 3, 0 ], 474, 64, "print utilities", "X860C83047DC4F1BC" ], [ "\033[1X\033[33X\033[0;-2YUtilities for Bibliographies\033[133X\033[101X", "7", [ 7, 0, 0 ], 1, 66, "utilities for bibliographies", "X7EB94CE97ABF7192" ], [ "\033[1X\033[33X\033[0;-2YParsing BibTeX Files\033[133X\033[101X", "7.1", [ 7, 1, 0 ], 19, 66, "parsing bibtex files", "X7A4126EC7BD68F64" ], [ "\033[1X\033[33X\033[0;-2YThe BibXMLext Format\033[133X\033[101X", "7.2", [ 7, 2, 0 ], 153, 68, "the bibxmlext format", "X7FB8F6BD80D859D1" ], [ "\033[1X\033[33X\033[0;-2YUtilities for BibXMLext data\033[133X\033[101X", "7.3", [ 7, 3, 0 ], 279, 70, "utilities for bibxmlext data", "X7AC255DE7D2531B6" ], [ "\033[1X\033[33X\033[0;-2YTranslating BibTeX to BibXMLext\033[133X\033[101X\ ", "7.3-1", [ 7, 3, 1 ], 282, 70, "translating bibtex to bibxmlext", "X7C5548E77ECA29D7" ], [ "\033[1X\033[33X\033[0;-2YBibliography Entries as Records\033[133X\033[101X\ ", "7.3-6", [ 7, 3, 6 ], 433, 72, "bibliography entries as records", "X82167F1280F4310E" ], [ "\033[1X\033[33X\033[0;-2YGetting BibTeX entries from \033[5XMathSciNet\\ 033[105X\033[101X\027\033[1X\027\033[133X\033[101X", "7.4", [ 7, 4, 0 ], 713, 77, "getting bibtex entries from mathscinet\027\027", "X826901BD844D3F87" ], [ "\033[1X\033[33X\033[0;-2YThe File \033[11X3k+1.xml\033[111X\033[101X\027\\ 033[1X\027\033[133X\033[101X", "a", [ "A", 0, 0 ], 1, 79, "the file 3k+1.xml\027\027", "X7DC4C82B87717D1C" ], [ "\033[1X\033[33X\033[0;-2YThe File \033[11Xgapdoc.dtd\033[111X\033[101X\\ 027\033[1X\027\033[133X\033[101X", "b", [ "B", 0, 0 ], 1, 81, "the file gapdoc.dtd\027\027", "X85274DD38456275D" ], [ "\033[1X\033[33X\033[0;-2YThe File \033[11Xbibxmlext.dtd\033[111X\033[101X\\ 027\033[1X\027\033[133X\033[101X", "c", [ "C", 0, 0 ], 1, 90, "the file bibxmlext.dtd\027\027", "X7B5D840781E99076" ], [ "Bibliography", "bib", [ "Bib", 0, 0 ], 1, 100, "bibliography", "X7A6F98FD85F02BFE" ], [ "References", "bib", [ "Bib", 0, 0 ], 1, 100, "references", "X7A6F98FD85F02BFE" ], [ "Index", "ind", [ "Ind", 0, 0 ], 1, 101, "index", "X83A0356F839C696F" ], [ "License", ".-1", [ 0, 0, 1 ], 26, 2, "license", "X81488B807F2A1CF1" ], [ "XML", "1.1", [ 1, 1, 0 ], 27, 5, "xml", "X8590236E858F7E93" ], [ "\033[10XBook\033[110X", "3.2-1", [ 3, 2, 1 ], 51, 16, "book", "X7D27228D7E68473E" ], [ "\033[10XTitlePage\033[110X", "3.2-2", [ 3, 2, 2 ], 95, 16, "titlepage", "X8643EEF587FC8AD4" ], [ "\033[10XTitle\033[110X", "3.2-3", [ 3, 2, 3 ], 112, 16, "title", "X85C1D07A84F1F736" ], [ "\033[10XSubtitle\033[110X", "3.2-4", [ 3, 2, 4 ], 167, 17, "subtitle", "X81B6D8D679A42915" ], [ "\033[10XVersion\033[110X", "3.2-5", [ 3, 2, 5 ], 176, 17, "version", "X8064BA177E9D23B8" ], [ "\033[10XTitleComment\033[110X", "3.2-6", [ 3, 2, 6 ], 188, 18, "titlecomment", "X7C2765047A1561EB" ], [ "\033[10XAuthor\033[110X", "3.2-7", [ 3, 2, 7 ], 200, 18, "author", "X846067D18467D228" ], [ "\033[10XDate\033[110X", "3.2-8", [ 3, 2, 8 ], 213, 18, "date", "X87C47AD378268979" ], [ "\033[10XAddress\033[110X", "3.2-9", [ 3, 2, 9 ], 223, 18, "address", "X7B84029079583E6E" ], [ "\033[10XAbstract\033[110X", "3.2-10", [ 3, 2, 10 ], 240, 18, "abstract", "X7CF09C0F82D16612" ], [ "\033[10XCopyright\033[110X", "3.2-11", [ 3, 2, 11 ], 249, 18, "copyright", "X823232338648B1D7" ], [ "\033[10XAcknowledgements\033[110X", "3.2-12", [ 3, 2, 12 ], 259, 19, "acknowledgements", "X868A17B2849FEB84" ], [ "\033[10XColophon\033[110X", "3.2-13", [ 3, 2, 13 ], 268, 19, "colophon", "X87AF74847BEA348D" ], [ "\033[10XTableOfContents\033[110X", "3.2-14", [ 3, 2, 14 ], 277, 19, "tableofcontents", "X81F18BDE7B3182F4" ], [ "\033[10XBibliography\033[110X", "3.2-15", [ 3, 2, 15 ], 295, 19, "bibliography", "X857F84507B5CED2A" ], [ "\033[10XTheIndex\033[110X", "3.2-16", [ 3, 2, 16 ], 325, 20, "theindex", "X80ACB0AA7FC414E4" ], [ "\033[10XBody\033[110X", "3.3-1", [ 3, 3, 1 ], 360, 20, "body", "X85FB286D82BA5300" ], [ "\033[10XChapter\033[110X", "3.3-2", [ 3, 3, 2 ], 384, 20, "chapter", "X81A68C117E39FA60" ], [ "\033[10XHeading\033[110X", "3.3-3", [ 3, 3, 3 ], 405, 21, "heading", "X82F09E29814C7A72" ], [ "\033[10XAppendix\033[110X", "3.3-4", [ 3, 3, 4 ], 420, 21, "appendix", "X7951B5C482C59057" ], [ "\033[10XSection\033[110X", "3.3-5", [ 3, 3, 5 ], 435, 21, "section", "X795D46507CE20232" ], [ "\033[10XSubsection\033[110X", "3.3-6", [ 3, 3, 6 ], 457, 21, "subsection", "X7A9AC7787E8163DC" ], [ "\033[10XManSection\033[110X", "3.4-1", [ 3, 4, 1 ], 485, 22, "mansection", "X7E24999A86DAEB60" ], [ "\033[10XDescription\033[110X", "3.4-1", [ 3, 4, 1 ], 485, 22, "description", "X7E24999A86DAEB60" ], [ "\033[10XReturns\033[110X", "3.4-1", [ 3, 4, 1 ], 485, 22, "returns", "X7E24999A86DAEB60" ], [ "\033[10XFunc\033[110X", "3.4-2", [ 3, 4, 2 ], 528, 22, "func", "X87CA42C681B95BCE" ], [ "\033[10XOper\033[110X", "3.4-3", [ 3, 4, 3 ], 569, 23, "oper", "X82684F9E8461DFC7" ], [ "\033[10XMeth\033[110X", "3.4-4", [ 3, 4, 4 ], 590, 23, "meth", "X780247227AC3340B" ], [ "\033[10XFilt\033[110X", "3.4-5", [ 3, 4, 5 ], 611, 24, "filt", "X7BFBED2C8766065E" ], [ "\033[10XProp\033[110X", "3.4-6", [ 3, 4, 6 ], 630, 24, "prop", "X81A6364E79DBE958" ], [ "\033[10XAttr\033[110X", "3.4-7", [ 3, 4, 7 ], 645, 24, "attr", "X7B0AA7E98373249D" ], [ "\033[10XVar\033[110X", "3.4-8", [ 3, 4, 8 ], 660, 24, "var", "X7D4982A27D773098" ], [ "\033[10XFam\033[110X", "3.4-9", [ 3, 4, 9 ], 674, 25, "fam", "X7DF346F7795CB5C1" ], [ "\033[10XInfoClass\033[110X", "3.4-10", [ 3, 4, 10 ], 688, 25, "infoclass", "X84367BDE795E0C56" ], [ "\033[10XRef\033[110X", "3.5-1", [ 3, 5, 1 ], 717, 25, "ref", "X865F20E386B6DA49" ], [ "\033[10XLabel\033[110X", "3.5-2", [ 3, 5, 2 ], 779, 26, "label", "X8653BAF279C7A817" ], [ "\033[10XCite\033[110X", "3.5-3", [ 3, 5, 3 ], 793, 26, "cite", "X855B311D7C33A50E" ], [ "\033[10XIndex\033[110X", "3.5-4", [ 3, 5, 4 ], 808, 27, "index", "X7D2B1F278577D2D5" ], [ "\033[10XURL\033[110X", "3.5-5", [ 3, 5, 5 ], 832, 27, "url", "X7C58A957852F867C" ], [ "\033[10XEmail\033[110X", "3.5-6", [ 3, 5, 6 ], 853, 27, "email", "X7FEB041D793E781B" ], [ "\033[10XHomepage\033[110X", "3.5-7", [ 3, 5, 7 ], 866, 28, "homepage", "X81F135A886B732E6" ], [ "\033[10XList\033[110X", "3.6-1", [ 3, 6, 1 ], 884, 28, "list", "X7F97E8DD784F5CAA" ], [ "\033[10XMark\033[110X", "3.6-2", [ 3, 6, 2 ], 907, 28, "mark", "X786406A77C9F1CD6" ], [ "\033[10XItem\033[110X", "3.6-3", [ 3, 6, 3 ], 917, 28, "item", "X7D6BFC907F5FEF37" ], [ "\033[10XEnum\033[110X", "3.6-4", [ 3, 6, 4 ], 927, 28, "enum", "X7D3B2150818E3CD4" ], [ "\033[10XTable\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "table", "X7BA7DA848347E2A9" ], [ "\033[10X<Caption>\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<caption>", "X7BA7DA848347E2A9" ], [ "\033[10X<Row>\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<row>", "X7BA7DA848347E2A9" ], [ "\033[10X<Align>\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<align>", "X7BA7DA848347E2A9" ], [ "\033[10X<HorLine>\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<horline>", "X7BA7DA848347E2A9" ], [ "\033[10X<Item>\033[110X in \033[10X<Table>\033[110X", "3.6-5", [ 3, 6, 5 ], 941, 29, "<item> in <table>", "X7BA7DA848347E2A9" ], [ "\033[10XEmph\033[110X", "3.7-1", [ 3, 7, 1 ], 989, 29, "emph", "X7E07C12185A25EF7" ], [ "\033[10XE\033[110X", "3.7-1", [ 3, 7, 1 ], 989, 29, "e", "X7E07C12185A25EF7" ], [ "\033[10XQuoted\033[110X", "3.7-2", [ 3, 7, 2 ], 1000, 30, "quoted", "X87FB13F57EF49C93" ], [ "\033[10XQ\033[110X", "3.7-2", [ 3, 7, 2 ], 1000, 30, "q", "X87FB13F57EF49C93" ], [ "\033[10XKeyword\033[110X", "3.7-3", [ 3, 7, 3 ], 1011, 30, "keyword", "X86A11FA98045FE79" ], [ "\033[10XK\033[110X", "3.7-3", [ 3, 7, 3 ], 1011, 30, "k", "X86A11FA98045FE79" ], [ "\033[10XArg\033[110X", "3.7-4", [ 3, 7, 4 ], 1023, 30, "arg", "X8502FFCF7DC7982B" ], [ "\033[10XA\033[110X", "3.7-4", [ 3, 7, 4 ], 1023, 30, "a", "X8502FFCF7DC7982B" ], [ "\033[10XCode\033[110X", "3.7-5", [ 3, 7, 5 ], 1036, 30, "code", "X79C6755D80AEA4C1" ], [ "\033[10XC\033[110X", "3.7-5", [ 3, 7, 5 ], 1036, 30, "c", "X79C6755D80AEA4C1" ], [ "\033[10XFile\033[110X", "3.7-6", [ 3, 7, 6 ], 1049, 30, "file", "X7C30FEC078523528" ], [ "\033[10XF\033[110X", "3.7-6", [ 3, 7, 6 ], 1049, 30, "f", "X7C30FEC078523528" ], [ "\033[10XButton\033[110X", "3.7-7", [ 3, 7, 7 ], 1060, 31, "button", "X79AEA5068489EE6E" ], [ "\033[10XB\033[110X", "3.7-7", [ 3, 7, 7 ], 1060, 31, "b", "X79AEA5068489EE6E" ], [ "\033[10XPackage\033[110X", "3.7-8", [ 3, 7, 8 ], 1072, 31, "package", "X7B9BB2D878262083" ], [ "\033[10XListing\033[110X", "3.7-9", [ 3, 7, 9 ], 1083, 31, "listing", "X799961B67E34193D" ], [ "\033[10XLog\033[110X", "3.7-10", [ 3, 7, 10 ], 1105, 31, "log", "X7C926CF778F54591" ], [ "\033[10XExample\033[110X", "3.7-10", [ 3, 7, 10 ], 1105, 31, "example", "X7C926CF778F54591" ], [ "\033[10XMath\033[110X", "3.8-1", [ 3, 8, 1 ], 1144, 32, "math", "X7B0254677AA56B5E" ], [ "\033[10XDisplay\033[110X", "3.8-1", [ 3, 8, 1 ], 1144, 32, "display", "X7B0254677AA56B5E" ], [ "\033[10XM\033[110X", "3.8-2", [ 3, 8, 2 ], 1187, 32, "m", "X8796A7577B29543A" ], [ "\033[10XAlt\033[110X", "3.9-1", [ 3, 9, 1 ], 1310, 35, "alt", "X817B08367FF43419" ], [ "\033[10XPar\033[110X", "3.9-2", [ 3, 9, 2 ], 1344, 35, "par", "X847CBC4380DBAC63" ], [ "\033[10XP\033[110X", "3.9-2", [ 3, 9, 2 ], 1344, 35, "p", "X847CBC4380DBAC63" ], [ "\033[10XBr\033[110X", "3.9-3", [ 3, 9, 3 ], 1364, 35, "br", "X7C910EF07C3FF929" ], [ "\033[10XIgnore\033[110X", "3.9-4", [ 3, 9, 4 ], 1376, 36, "ignore", "X84855267801B3077" ], [ "\033[10X<#Include>\033[110X", "4.1", [ 4, 1, 0 ], 15, 37, "< include>", "X7CE078A07E8256DC" ], [ "\033[10X<#GAPDoc>\033[110X", "4.1", [ 4, 1, 0 ], 15, 37, "< gapdoc>", "X7CE078A07E8256DC" ], [ "\033[2XComposedDocument\033[102X", "4.2-1", [ 4, 2, 1 ], 90, 38, "composeddocument", "X857D77557D12559D" ], [ "\033[2XComposedXMLString\033[102X", "4.2-1", [ 4, 2, 1 ], 90, 38, "composedxmlstring", "X857D77557D12559D" ], [ "\033[2XOriginalPositionDocument\033[102X", "4.2-2", [ 4, 2, 2 ], 124, 39, "originalpositiondocument", "X86D1141E7EDCAAC8" ], [ "\033[2XMakeGAPDocDoc\033[102X", "5.1-1", [ 5, 1, 1 ], 136, 42, "makegapdocdoc", "X826F530686F4D052" ], [ "\033[5XMathJax\033[105X in MakeGAPDocDoc", "5.1-1", [ 5, 1, 1 ], 136, 42, "mathjax in makegapdocdoc", "X826F530686F4D052" ], [ "\033[2XParseTreeXMLString\033[102X", "5.2-1", [ 5, 2, 1 ], 173, 42, "parsetreexmlstring", "X847EB8498151D443" ], [ "\033[2XParseTreeXMLFile\033[102X", "5.2-1", [ 5, 2, 1 ], 173, 42, "parsetreexmlfile", "X847EB8498151D443" ], [ "\033[2XStringXMLElement\033[102X", "5.2-2", [ 5, 2, 2 ], 242, 43, "stringxmlelement", "X835887057D0B4DA8" ], [ "\033[2XEntitySubstitution\033[102X", "5.2-3", [ 5, 2, 3 ], 264, 44, "entitysubstitution", "X786827BF793191B3" ], [ "\033[2XDisplayXMLStructure\033[102X", "5.2-4", [ 5, 2, 4 ], 284, 44, "displayxmlstructure", "X86589C5C859ACE38" ], [ "\033[2XApplyToNodesParseTree\033[102X", "5.2-5", [ 5, 2, 5 ], 294, 44, "applytonodesparsetree", "X7A7B223A83E38B40" ], [ "\033[2XAddRootParseTree\033[102X", "5.2-5", [ 5, 2, 5 ], 294, 44, "addrootparsetree", "X7A7B223A83E38B40" ], [ "\033[2XRemoveRootParseTree\033[102X", "5.2-5", [ 5, 2, 5 ], 294, 44, "removerootparsetree", "X7A7B223A83E38B40" ], [ "\033[2XGetTextXMLTree\033[102X", "5.2-6", [ 5, 2, 6 ], 310, 45, "gettextxmltree", "X7F76D4A27C7FB946" ], [ "\033[2XXMLElements\033[102X", "5.2-7", [ 5, 2, 7 ], 319, 45, "xmlelements", "X8466F74C80442F7D" ], [ "\033[2XCheckAndCleanGapDocTree\033[102X", "5.2-8", [ 5, 2, 8 ], 333, 45, "checkandcleangapdoctree", "X84CFF72484B19C0D" ], [ "\033[2XAddParagraphNumbersGapDocTree\033[102X", "5.2-9", [ 5, 2, 9 ], 350, 45, "addparagraphnumbersgapdoctree", "X84062CD67B286FF0" ], [ "\033[2XInfoXMLParser\033[102X", "5.2-10", [ 5, 2, 10 ], 363, 45, "infoxmlparser", "X78A22C58841E5D0B" ], [ "\033[2XGAPDoc2LaTeX\033[102X", "5.3-1", [ 5, 3, 1 ], 378, 46, "gapdoc2latex", "X85BE6DF178423EF5" ], [ "\033[2XSetGapDocLaTeXOptions\033[102X", "5.3-1", [ 5, 3, 1 ], 378, 46, "setgapdoclatexoptions", "X85BE6DF178423EF5" ], [ "\033[2XGAPDoc2Text\033[102X", "5.3-2", [ 5, 3, 2 ], 433, 47, "gapdoc2text", "X86CD0B197CD58D2A" ], [ "\033[2XGAPDoc2TextPrintTextFiles\033[102X", "5.3-3", [ 5, 3, 3 ], 489, 47, "gapdoc2textprinttextfiles", "X7DFCE7357D6032A2" ], [ "\033[2XAddPageNumbersToSix\033[102X", "5.3-4", [ 5, 3, 4 ], 513, 48, "addpagenumberstosix", "X7EB5E86F87A09F94" ], [ "\033[2XPrintSixFile\033[102X", "5.3-5", [ 5, 3, 5 ], 526, 48, "printsixfile", "X7D42CFED7885BC00" ], [ "\033[2XSetGAPDocTextTheme\033[102X", "5.3-6", [ 5, 3, 6 ], 536, 48, "setgapdoctexttheme", "X7DEB37417BBD8941" ], [ "\033[2XGAPDoc2HTML\033[102X", "5.3-7", [ 5, 3, 7 ], 667, 50, "gapdoc2html", "X84F22EEB78845CFD" ], [ "\033[5XMathJax\033[105X", "5.3-7", [ 5, 3, 7 ], 667, 50, "mathjax", "X84F22EEB78845CFD" ], [ "\033[2XGAPDoc2HTMLPrintHTMLFiles\033[102X", "5.3-8", [ 5, 3, 8 ], 779, 52, "gapdoc2htmlprinthtmlfiles", "X84A7007778073E7A" ], [ "CSS stylesheets", "5.3-9", [ 5, 3, 9 ], 799, 52, "css stylesheets", "X788AB14383272FDB" ], [ "\033[2XCopyHTMLStyleFiles\033[102X", "5.3-10", [ 5, 3, 10 ], 820, 53, "copyhtmlstylefiles", "X813599E982DE9B98" ], [ "\033[2XSetGAPDocHTMLStyle\033[102X", "5.3-11", [ 5, 3, 11 ], 828, 53, "setgapdochtmlstyle", "X85AFD98383174BB5" ], [ "\033[2XInfoGAPDoc\033[102X", "5.3-12", [ 5, 3, 12 ], 850, 53, "infogapdoc", "X864A528B81C661A2" ], [ "\033[2XSetGapDocLanguage\033[102X", "5.3-13", [ 5, 3, 13 ], 859, 53, "setgapdoclanguage", "X82AB468887ED0DBB" ], [ "Using \033[5XGAPDoc\033[105X with other languages", "5.3-13", [ 5, 3, 13 ], 859, 53, "using gapdoc with other languages", "X82AB468887ED0DBB" ], [ "\033[10XManualExamples\033[110X", "5.4", [ 5, 4, 0 ], 884, 54, "manualexamples", "X800299827B88ABBE" ], [ "\033[10XTestManualExamples\033[110X", "5.4", [ 5, 4, 0 ], 884, 54, "testmanualexamples", "X800299827B88ABBE" ], [ "\033[2XExtractExamples\033[102X", "5.4-1", [ 5, 4, 1 ], 894, 54, "extractexamples", "X8337B2BC79253B3F" ], [ "\033[2XExtractExamplesXMLTree\033[102X", "5.4-1", [ 5, 4, 1 ], 894, 54, "extractexamplesxmltree", "X8337B2BC79253B3F" ], [ "\033[2XRunExamples\033[102X", "5.4-2", [ 5, 4, 2 ], 917, 54, "runexamples", "X781D56FC7B938DCB" ], [ "\033[2XWHITESPACE\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "whitespace", "X786D477C7AB636AA" ], [ "\033[2XCAPITALLETTERS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "capitalletters", "X786D477C7AB636AA" ], [ "\033[2XSMALLLETTERS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "smallletters", "X786D477C7AB636AA" ], [ "\033[2XLETTERS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "letters", "X786D477C7AB636AA" ], [ "\033[2XDIGITS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "digits", "X786D477C7AB636AA" ], [ "\033[2XHEXDIGITS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "hexdigits", "X786D477C7AB636AA" ], [ "\033[2XBOXCHARS\033[102X", "6.1-1", [ 6, 1, 1 ], 12, 56, "boxchars", "X786D477C7AB636AA" ], [ "\033[2XTextAttr\033[102X", "6.1-2", [ 6, 1, 2 ], 47, 57, "textattr", "X785F61E77899580E" ], [ "UseColorsInTerminal", "6.1-2", [ 6, 1, 2 ], 47, 57, "usecolorsinterminal", "X785F61E77899580E" ], [ "\033[2XWrapTextAttribute\033[102X", "6.1-3", [ 6, 1, 3 ], 83, 57, "wraptextattribute", "X7B8AD7517E5FD0EA" ], [ "\033[2XFormatParagraph\033[102X", "6.1-4", [ 6, 1, 4 ], 104, 58, "formatparagraph", "X812058CE7C8E9022" ], [ "\033[2XSubstitutionSublist\033[102X", "6.1-5", [ 6, 1, 5 ], 145, 58, "substitutionsublist", "X82A9121678923445" ], [ "\033[2XStripBeginEnd\033[102X", "6.1-6", [ 6, 1, 6 ], 166, 59, "stripbeginend", "X83DE31017B557136" ], [ "\033[2XStripEscapeSequences\033[102X", "6.1-7", [ 6, 1, 7 ], 180, 59, "stripescapesequences", "X7A5978CF84C3C2D3" ], [ "\033[2XRepeatedString\033[102X", "6.1-8", [ 6, 1, 8 ], 189, 59, "repeatedstring", "X7D71CB837EE969D4" ], [ "\033[2XRepeatedUTF8String\033[102X", "6.1-8", [ 6, 1, 8 ], 189, 59, "repeatedutf8string", "X7D71CB837EE969D4" ], [ "\033[2XNumberDigits\033[102X", "6.1-9", [ 6, 1, 9 ], 217, 59, "numberdigits", "X7CEEA5B57D7BB38F" ], [ "\033[2XDigitsNumber\033[102X", "6.1-9", [ 6, 1, 9 ], 217, 59, "digitsnumber", "X7CEEA5B57D7BB38F" ], [ "\033[2XPositionMatchingDelimiter\033[102X", "6.1-10", [ 6, 1, 10 ], 239, 60, "positionmatchingdelimiter", "X7AF694D9839BF65C" ], [ "\033[2XWordsString\033[102X", "6.1-11", [ 6, 1, 11 ], 261, 60, "wordsstring", "X832556617F10AAA8" ], [ "\033[2XBase64String\033[102X", "6.1-12", [ 6, 1, 12 ], 274, 60, "base64string", "X83F2821783DA9826" ], [ "\033[2XStringBase64\033[102X", "6.1-12", [ 6, 1, 12 ], 274, 60, "stringbase64", "X83F2821783DA9826" ], [ "\033[2XUnicode\033[102X", "6.2-1", [ 6, 2, 1 ], 303, 61, "unicode", "X8475671278948DDD" ], [ "\033[2XUChar\033[102X", "6.2-1", [ 6, 2, 1 ], 303, 61, "uchar", "X8475671278948DDD" ], [ "\033[2XIsUnicodeString\033[102X", "6.2-1", [ 6, 2, 1 ], 303, 61, "isunicodestring", "X8475671278948DDD" ], [ "\033[2XIsUnicodeCharacter\033[102X", "6.2-1", [ 6, 2, 1 ], 303, 61, "isunicodecharacter", "X8475671278948DDD" ], [ "\033[2XIntListUnicodeString\033[102X", "6.2-1", [ 6, 2, 1 ], 303, 61, "intlistunicodestring", "X8475671278948DDD" ], [ "URL encoding", "6.2-1", [ 6, 2, 1 ], 303, 61, "url encoding", "X8475671278948DDD" ], [ "RFC 3986", "6.2-1", [ 6, 2, 1 ], 303, 61, "rfc 3986", "X8475671278948DDD" ], [ "\033[2XEncode\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "encode", "X818A31567EB30A39" ], [ "\033[2XSimplifiedUnicodeString\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "simplifiedunicodestring", "X818A31567EB30A39" ], [ "\033[2XLowercaseUnicodeString\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "lowercaseunicodestring", "X818A31567EB30A39" ], [ "\033[2XUppercaseUnicodeString\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "uppercaseunicodestring", "X818A31567EB30A39" ], [ "\033[2XLaTeXUnicodeTable\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "latexunicodetable", "X818A31567EB30A39" ], [ "\033[2XSimplifiedUnicodeTable\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "simplifiedunicodetable", "X818A31567EB30A39" ], [ "\033[2XLowercaseUnicodeTable\033[102X", "6.2-2", [ 6, 2, 2 ], 348, 62, "lowercaseunicodetable", "X818A31567EB30A39" ], [ "\033[2XWidthUTF8String\033[102X", "6.2-3", [ 6, 2, 3 ], 438, 63, "widthutf8string", "X801237207E06A876" ], [ "\033[2XNrCharsUTF8String\033[102X", "6.2-3", [ 6, 2, 3 ], 438, 63, "nrcharsutf8string", "X801237207E06A876" ], [ "\033[2XPrintTo1\033[102X", "6.3-1", [ 6, 3, 1 ], 481, 64, "printto1", "X8603B90C7C3F0AB1" ], [ "\033[2XAppendTo1\033[102X", "6.3-1", [ 6, 3, 1 ], 481, 64, "appendto1", "X8603B90C7C3F0AB1" ], [ "\033[2XStringPrint\033[102X", "6.3-2", [ 6, 3, 2 ], 501, 64, "stringprint", "X829B720C86E57E8B" ], [ "\033[2XStringView\033[102X", "6.3-2", [ 6, 3, 2 ], 501, 64, "stringview", "X829B720C86E57E8B" ], [ "\033[2XPrintFormattedString\033[102X", "6.3-3", [ 6, 3, 3 ], 513, 64, "printformattedstring", "X812A8326844BC910" ], [ "\033[2XPage\033[102X", "6.3-4", [ 6, 3, 4 ], 524, 64, "page", "X7BB6731F7E3AAA98" ], [ "\033[2XPageDisplay\033[102X", "6.3-4", [ 6, 3, 4 ], 524, 64, "pagedisplay", "X7BB6731F7E3AAA98" ], [ "\033[2XStringFile\033[102X", "6.3-5", [ 6, 3, 5 ], 539, 65, "stringfile", "X7E14D32181FBC3C3" ], [ "\033[2XFileString\033[102X", "6.3-5", [ 6, 3, 5 ], 539, 65, "filestring", "X7E14D32181FBC3C3" ], [ "\033[2XParseBibFiles\033[102X", "7.1-1", [ 7, 1, 1 ], 25, 66, "parsebibfiles", "X82555C307FDC1817" ], [ "\033[2XParseBibStrings\033[102X", "7.1-1", [ 7, 1, 1 ], 25, 66, "parsebibstrings", "X82555C307FDC1817" ], [ "\033[2XNormalizedNameAndKey\033[102X", "7.1-2", [ 7, 1, 2 ], 64, 67, "normalizednameandkey", "X7C9F0C337A0A0FF0" ], [ "\033[2XNormalizeNameAndKey\033[102X", "7.1-2", [ 7, 1, 2 ], 64, 67, "normalizenameandkey", "X7C9F0C337A0A0FF0" ], [ "\033[2XWriteBibFile\033[102X", "7.1-3", [ 7, 1, 3 ], 111, 67, "writebibfile", "X7C2B2F65851EAA0B" ], [ "\033[2XInfoBibTools\033[102X", "7.1-4", [ 7, 1, 4 ], 144, 68, "infobibtools", "X85C1D50F7E37A99A" ], [ "\033[2XHeuristicTranslationsLaTeX2XML.Apply\033[102X", "7.3-2", [ 7, 3, 2 ], 294, 70, "heuristictranslationslatex2xml.apply", "X7A025E0A7A1CD390" ], [ "\033[2XHeuristicTranslationsLaTeX2XML.ApplyFile\033[102X", "7.3-2", [ 7, 3, 2 ], 294, 70, "heuristictranslationslatex2xml.applyfile", "X7A025E0A7A1CD390" ], [ "\033[2XStringBibAsXMLext\033[102X", "7.3-3", [ 7, 3, 3 ], 324, 71, "stringbibasxmlext", "X85F33C64787A00B7" ], [ "\033[2XParseBibXMLextString\033[102X", "7.3-4", [ 7, 3, 4 ], 374, 72, "parsebibxmlextstring", "X86BD29AE7A453721" ], [ "\033[2XParseBibXMLextFiles\033[102X", "7.3-4", [ 7, 3, 4 ], 374, 72, "parsebibxmlextfiles", "X86BD29AE7A453721" ], [ "\033[2XWriteBibXMLextFile\033[102X", "7.3-5", [ 7, 3, 5 ], 405, 72, "writebibxmlextfile", "X7811108C7E5B1709" ], [ "\033[2XRecBibXMLEntry\033[102X", "7.3-7", [ 7, 3, 7 ], 443, 73, "recbibxmlentry", "X786C33ED79F425F1" ], [ "\033[2XAddHandlerBuildRecBibXMLEntry\033[102X", "7.3-8", [ 7, 3, 8 ], 527, 74, "addhandlerbuildrecbibxmlentry", "X8067261385905A36" ], [ "\033[2XStringBibXMLEntry\033[102X", "7.3-9", [ 7, 3, 9 ], 583, 75, "stringbibxmlentry", "X790A295680F7CD24" ], [ "\033[2XTemplateBibXML\033[102X", "7.3-10", [ 7, 3, 10 ], 648, 76, "templatebibxml", "X7C6FF57087016019" ], [ "\033[2XSearchMR\033[102X", "7.4-1", [ 7, 4, 1 ], 726, 77, "searchmr", "X8009F8A17DDFF9AF" ], [ "\033[2XSearchMRBib\033[102X", "7.4-1", [ 7, 4, 1 ], 726, 77, "searchmrbib", "X8009F8A17DDFF9AF" ] ] ); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/GPL������������������������������������������������������������������������������������0000644�0001750�0001750�00000043110�12026346064�011550� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/bibxmlext.dtd��������������������������������������������������������������������������0000644�0001750�0001750�00000047464�12026346063�013715� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!-- - (C) Frank Lübeck (http://www.math.rwth-aachen.de/~Frank.Luebeck) - - The BibXMLext data format. - - This DTD expresses XML markup similar to the BibTeX language - specified for LaTeX, or actually its content model. - - It is a variation of a file bibxml.dtd developed by the project - http://bibtexml.sf.net/ - - For documentation on BibTeX, see - http://www.ctan.org/tex-archive/biblio/bibtex/distribs/doc/ - - A previous version of the code originally developed by - Vidar Bronken Gundersen, http://bibtexml.sf.net/ - Reuse and repurposing is approved as long as this - notification appears with the code. - --> <!-- ..................................................................... --> <!-- Main structure --> <!-- key-value pairs as in BibTeX @string entries are put in empty elements (but here they can be used for parts of an entry field as well) --> <!ELEMENT string EMPTY> <!ATTLIST string key CDATA #REQUIRED value CDATA #REQUIRED > <!-- entry may contain one of the bibliographic types. --> <!ELEMENT entry ( article | book | booklet | manual | techreport | mastersthesis | phdthesis | inbook | incollection | proceedings | inproceedings | conference | unpublished | misc ) > <!ATTLIST entry id CDATA #REQUIRED > <!-- file is the documents top element. --> <!ELEMENT file ( string | entry )* > <!-- ..................................................................... --> <!-- Parameter entities --> <!-- these are additional elements often used, but not included in the standard BibTeX distribution, these must be added to the bibliography styles, otherwise these fields will be omitted by the formatter, we allow an arbitrary number of 'other' elements to specify any further information --> <!ENTITY % n.user " abstract?, affiliation?, contents?, copyright?, (isbn | issn)?, keywords?, language?, lccn?, location?, mrnumber?, mrclass?, mrreviewer?, price?, size?, url?, category?, other* "> <!ENTITY % n.common "key?, annotate?, crossref?, %n.user;"> <!-- content model used more than once --> <!ENTITY % n.InProceedings "author, title, booktitle, year, editor?, (volume | number)?, series?, pages?, address?, month?, organization?, publisher?, note?, %n.common;"> <!ENTITY % n.PHDThesis "author, title, school, year, type?, address?, month?, note?, %n.common;"> <!-- ..................................................................... --> <!-- Entries in the BibTeX database --> <!-- [article] An article from a journal or magazine. - Required fields: author, title, journal, year. - Optional fields: volume, number, pages, month, note. --> <!ELEMENT article (author, title, journal, year, volume?, number?, pages?, month?, note?, %n.common;) > <!-- [book] A book with an explicit publisher. - Required fields: author or editor, title, publisher, year. - Optional fields: volume or number, series, address, - edition, month, note. --> <!ELEMENT book ((author | editor), title, publisher, year, (volume | number)?, series?, address?, edition?, month?, note?, %n.common;) > <!-- [booklet] A work that is printed and bound, but without a named - publisher or sponsoring institution - Required field: title. - Optional fields: author, howpublished, address, month, year, note. --> <!ELEMENT booklet (author?, title, howpublished?, address?, month?, year?, note?, %n.common;) > <!-- [conference] The same as INPROCEEDINGS, - included for Scribe compatibility. --> <!ELEMENT conference (%n.InProceedings;) > <!-- [inbook] A part of a book, which may be a chapter (or section or - whatever) and/or a range of pages. - Required fields: author or editor, title, chapter and/or pages, - publisher, year. - Optional fields: volume or number, series, type, address, - edition, month, note. --> <!ELEMENT inbook ((author | editor), title, ((chapter, pages?) | pages), publisher, year, (volume | number)?, series?, type?, address?, edition?, month?, note?, %n.common;) > <!-- - > I want to express that the elements a and/or b are legal that is one - > of them or both must be present in the document instance (see the - > element content for BibTeX entry `InBook'). - > How do I specify this in my DTD? - - Dave Peterson: - in content model: ((a , b?) | b) if order matters - ((a , b?) | (b , a?)) otherwise --> <!-- [incollection] A part of a book having its own title. - Required fields: author, title, booktitle, publisher, year. - Optional fields: editor, volume or number, series, type, - chapter, pages, address, edition, month, note. --> <!ELEMENT incollection (author, title, booktitle, publisher, year, editor?, (volume | number)?, series?, type?, chapter?, pages?, address?, edition?, month?, note?, %n.common;) > <!-- [inproceedings] An article in a conference proceedings. - Required fields: author, title, booktitle, year. - Optional fields: editor, volume or number, series, pages, - address, month, organization, publisher, note. --> <!ELEMENT inproceedings (%n.InProceedings;) > <!-- [manual] Technical documentation - Required field: title. - Optional fields: author, organization, address, - edition, month, year, note. --> <!ELEMENT manual (author?, title, organization?, address?, edition?, month?, year?, note?, %n.common;) > <!-- [mastersthesis] A Master's thesis. - Required fields: author, title, school, year. - Optional fields: type, address, month, note. --> <!ELEMENT mastersthesis (%n.PHDThesis;) > <!-- [misc] Use this type when nothing else fits. - Required fields: none. - Optional fields: author, title, howpublished, month, year, note. --> <!ELEMENT misc (author?, title?, howpublished?, month?, year?, note?, %n.common;) > <!-- [phdthesis] A PhD thesis. - Required fields: author, title, school, year. - Optional fields: type, address, month, note. --> <!ELEMENT phdthesis (%n.PHDThesis;) > <!-- [proceedings] The proceedings of a conference. - Required fields: title, year. - Optional fields: editor, volume or number, series, - address, month, organization, publisher, note. --> <!ELEMENT proceedings (editor?, title, year, (volume | number)?, series?, address?, month?, organization?, publisher?, note?, %n.common;) > <!-- [techreport] A report published by a school or other institution, - usually numbered within a series. - Required fields: author, title, institution, year. - Optional fields: type, number, address, month, note. --> <!ELEMENT techreport (author, title, institution, year, type?, number?, address?, month?, note?, %n.common;) > <!-- [unpublished] A document having an author and title, but not - formally published. - Required fields: author, title, note. - Optional fields: month, year. --> <!ELEMENT unpublished (author, title, note, month?, year?, %n.common;) > <!-- ..................................................................... --> <!-- Fields from the standard bibliography styles --> <!-- - Below is a description of all fields recognized by the standard - bibliography styles. An entry can also contain other fields, which - are ignored by those styles. - - [address] Usually the address of the publisher or other type of - institution For major publishing houses, van~Leunen recommends - omitting the information entirely. For small publishers, on the other - hand, you can help the reader by giving the complete address. - - [annote] An annotation It is not used by the standard bibliography - styles, but may be used by others that produce an annotated - bibliography. - - [author] The name(s) of the author(s), here *not* in the format - described in the LaTeX book. Contains elements <name> which in turn - contains elements <first>, <last> for the first name (or first names, - fully written or as initials, and including middle initials) and - the last name. - - [booktitle] Title of a book, part of which is being cited. See the - LaTeX book for how to type titles. For book entries, use the title - field instead. - - [chapter] A chapter (or section or whatever) number. - - [crossref] The database key of the entry being cross referenced. - - [edition] The edition of a book-for example, ``Second''. This - should be an ordinal, and should have the first letter capitalized, as - shown here; the standard styles convert to lower case when necessary. - - [editor] Name(s) of editor(s), typed as indicated in the LaTeX book. - If there is also an author field, then the editor field gives the - editor of the book or collection in which the reference appears. - - [howpublished] How something strange has been published. The first - word should be capitalized. - - [institution] The sponsoring institution of a technical report. - - [journal] A journal name. Abbreviations are provided for many - journals; see the Local Guide. - - [key] Used for alphabetizing, cross referencing, and creating a label - when the ``author'' information (described in Section [ref: ] is - missing. This field should not be confused with the key that appears - in the \cite command and at the beginning of the database entry. - - [month] The month in which the work was published or, for an - unpublished work, in which it was written. You should use the - standard three-letter abbreviation, as described in Appendix B.1.3 of - the LaTeX book. - - [note] Any additional information that can help the reader. The first - word should be capitalized. - - [number] The number of a journal, magazine, technical report, or of a - work in a series. An issue of a journal or magazine is usually - identified by its volume and number; the organization that issues a - technical report usually gives it a number; and sometimes books are - given numbers in a named series. - - [organization] The organization that sponsors a conference or that - publishes a manual. - - [pages] One or more page numbers or range of numbers, such as 42-111 - or 7,41,73-97 or 43+ (the `+' in this last example indicates pages - following that don't form a simple range). To make it easier to - maintain Scribe-compatible databases, the standard styles convert a - single dash (as in 7-33) to the double dash used in TeX to denote - number ranges (as in 7-33). Here, we suggest to use the entity - – for a dash in page ranges. - - [publisher] The publisher's name. - - [school] The name of the school where a thesis was written. - - [series] The name of a series or set of books. When citing an entire - book, the the title field gives its title and an optional series field - gives the name of a series or multi-volume set in which the book is - published. - - [title] The work's title. For mathematical formulae use the <M> or - <Math> elements explained below (and LaTeX code in the content, without - surrounding '$'). - - [type] The type of a technical report-for example, ``Research - Note''. - - [volume] The volume of a journal or multivolume book. - - [year] The year of publication or, for an unpublished work, the year - it was written. Generally it should consist of four numerals, such as - 1984, although the standard styles can handle any year whose last four - nonpunctuation characters are numerals, such as `(about 1984)'. --> <!-- Here is the main extension compared to the original BibXML definition from which is DTD is derived: We want to allow more markup in some elements such that we can use the bibliography for high quality output in other formats than LaTeX. - <M> and <Math>, mathematical formulae: Specify LaTeX code for "simple" formulae as content of <M> elements; "simple" means that they can be translated to a fairly readable ASCII representation as explained in the GAPDoc documentation on "<M>". More complicated formulae are given as content of <Math> elements. (Think about an <Alt> alternative for text or HTML representations.) - <URL>: use these elements to specify URLs, they can be properly converted to links if possible in an output format (in that case the Text attribute is used for the visible text). - <value key="..."/>: substituted by the value-attribute specified in a <string key="..." value="..."/> element. Can be used anywhere, not only for complete fields as in BibTeX. - <C> protect case changes: should be used instead of {}'s which are used in BibTeX title fields to protect the case of letters from changes. - <Alt Only="...">, <Alt Not="...">, alternatives for different output formats: Use this to specify alternatives, the GAPDoc utilities will do some special handling for "Text", "HTML", and "BibTeX" as output type. - <Wrap Name="...">, generic wrapper for other markup: Use this for any other type of markup you are interested in. The GAPDoc utilities will ignore the markup, but provide a hook to do install handler functions for them. --> <!ELEMENT M (#PCDATA | Alt)* > <!-- math with simple text representation, in LaTeX --> <!ELEMENT Math (#PCDATA | Alt)* > <!-- other math in LaTeX --> <!ELEMENT URL (#PCDATA | Alt | Link | LinkText)* > <!-- an URL --> <!ATTLIST URL Text CDATA #IMPLIED> <!-- text to be printed (default is content) --> <!ELEMENT value EMPTY > <!-- placeholder for value given .. --> <!ATTLIST value key CDATA #REQUIRED > <!-- .. by key, defined in a string element --> <!ELEMENT C (#PCDATA | value | Alt | M | Math | Wrap | URL)* > <!-- protect from case changes --> <!ELEMENT Alt (#PCDATA | value | C | Alt | M | Math | Wrap | URL)* > <!-- specify alternatives for various types of output --> <!ATTLIST Alt Only CDATA #IMPLIED Not CDATA #IMPLIED > <!-- specify output types in comma and whitespace separated list (use exactly one of Only or Not) --> <!ENTITY % withMURL "(#PCDATA | value | M | Math | Wrap | URL | C | Alt )*" > <!ELEMENT Wrap %withMURL; > <!-- a generic wrapper --> <!ATTLIST Wrap Name CDATA #REQUIRED > <!-- needs a 'Name' attribute --> <!ELEMENT address %withMURL; > <!-- here we don't want the complicated definition from the LaTeX book, use markup for first/last name(s): a <name> element for each author which contains <first> (optional), <last> elements: --> <!ELEMENT author (name)* > <!ELEMENT name (first?, last) > <!ELEMENT first (#PCDATA) > <!ELEMENT last (#PCDATA) > <!ELEMENT booktitle %withMURL; > <!ELEMENT chapter %withMURL; > <!ELEMENT edition %withMURL; > <!-- same as for author field --> <!ELEMENT editor (name)* > <!ELEMENT howpublished %withMURL; > <!ELEMENT institution %withMURL; > <!ELEMENT journal %withMURL; > <!ELEMENT month %withMURL; > <!ELEMENT note %withMURL; > <!ELEMENT number %withMURL; > <!ELEMENT organization %withMURL; > <!ELEMENT pages %withMURL; > <!ELEMENT publisher %withMURL; > <!ELEMENT school %withMURL; > <!ELEMENT series %withMURL; > <!ELEMENT title %withMURL; > <!ELEMENT type %withMURL; > <!ELEMENT volume %withMURL; > <!ELEMENT year (#PCDATA) > <!-- These were not listed in the documentation for entry content, but - appeared in the list of fields in the BibTeX documentation --> <!ELEMENT annotate %withMURL; > <!ELEMENT crossref %withMURL; > <!ELEMENT key (#PCDATA) > <!-- ..................................................................... --> <!-- Other popular fields - - From: http://www.ecst.csuchico.edu/~jacobsd/bib/formats/bibtex.html - BibTeX is extremely popular, and many people have used it to store - information. Here is a list of some of the more common fields: - - [affiliation] The authors affiliation. - [abstract] An abstract of the work. - [contents] A Table of Contents - [copyright] Copyright information. - [ISBN] The International Standard Book Number. - [ISSN] The International Standard Serial Number. - Used to identify a journal. - [keywords] Key words used for searching or possibly for annotation. - [language] The language the document is in. - [location] A location associated with the entry, - such as the city in which a conference took place. - [LCCN] The Library of Congress Call Number. - I've also seen this as lib-congress. - [mrnumber] The Mathematical Reviews number. - [mrclass] The Mathematical Reviews class. - [mrreviewer] The Mathematical Reviews reviewer. - [price] The price of the document. - [size] The physical dimensions of a work. - [URL] The WWW Universal Resource Locator that points to the item being - referenced. This often is used for technical reports to point to the - ftp site where the postscript source of the report is located. - - When using BibTeX with LaTeX you need - BibTeX style files to print these data. --> <!ELEMENT abstract %withMURL; > <!ELEMENT affiliation %withMURL; > <!ELEMENT contents %withMURL; > <!ELEMENT copyright %withMURL; > <!ELEMENT isbn (#PCDATA) > <!ELEMENT issn (#PCDATA) > <!ELEMENT keywords %withMURL; > <!ELEMENT language %withMURL; > <!ELEMENT lccn (#PCDATA) > <!ELEMENT location %withMURL; > <!ELEMENT mrnumber %withMURL; > <!ELEMENT mrclass %withMURL; > <!ELEMENT mrreviewer %withMURL; > <!ELEMENT price %withMURL; > <!ELEMENT size %withMURL; > <!ELEMENT url %withMURL; > <!-- Added by Zeger W. Hendrikse - [category] Category of this bibitem --> <!ELEMENT category %withMURL; > <!-- A container element [other] for any further information, a description - of the type of data must be given in the attribute 'type' --> <!ELEMENT other %withMURL; > <!ATTLIST other type CDATA #REQUIRED > <!-- ..................................................................... --> <!-- Predefined/reserved character entities --> <!ENTITY amp "&#38;"> <!ENTITY lt "&#60;"> <!ENTITY gt ">"> <!ENTITY apos "'"> <!ENTITY quot """> <!-- Some more generally useful entities --> <!ENTITY nbsp " "> <!ENTITY copyright "©"> <!ENTITY ndash "–"> <!-- ..................................................................... --> <!-- End of BibXMLext dtd --> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/init.g���������������������������������������������������������������������������������0000644�0001750�0001750�00000005211�12026346063�012315� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################# ## #A init.g GAPDoc Frank Lübeck / Max Neunhöffer ## ## #Y Copyright (C) 2000, Frank Lübeck and Max Neunhöffer, #Y Lehrstuhl D für Mathematik, RWTH Aachen ## # An alternative Info handler which does not print implicit "#I " and "\n" BindGlobal("PlainInfoHandler", function ( infoclass, level, list ) local cl, out, s; cl := InfoData.LastClass![1]; if IsBound(InfoData.Output[cl]) then out := InfoData.Output[cl]; else out := DefaultInfoOutput; fi; if out = "*Print*" then for s in list do Print(s); od; Print("\c"); else for s in list do AppendTo( out, s ); od; AppendTo( out, "\c" ); fi; end); ReadPackage("GAPDoc", "lib/UnicodeTools.gd"); ReadPackage("GAPDoc", "lib/PrintUtil.gd"); ReadPackage("GAPDoc", "lib/Text.gd"); ReadPackage("GAPDoc", "lib/ComposeXML.gd"); ReadPackage("GAPDoc", "lib/XMLParser.gd"); ReadPackage("GAPDoc", "lib/GAPDoc.gd"); ReadPackage("GAPDoc", "lib/BibTeX.gd"); ReadPackage("GAPDoc", "lib/BibXMLextTools.gd"); ReadPackage("GAPDoc", "lib/GAPDoc2LaTeX.gd"); ReadPackage("GAPDoc", "lib/GAPDoc2Text.gd"); ReadPackage("GAPDoc", "lib/GAPDoc2HTML.gd"); ReadPackage("GAPDoc", "lib/Make.g"); ReadPackage("GAPDoc", "lib/Examples.gd"); # try to find terminal encoding GAPInfo.tmpfunc := function() local env, pos, enc, a; # we leave the GAPInfo.TermEncodingOverwrite for .gaprc # for a moment, but don't document it - doesn't work with # loaded workspaces if not IsBound(GAPInfo.TermEncodingOverwrite) then if IsList(GAPInfo.SystemEnvironment) then # for compatibility with GAP 4.4. env := rec(); for a in GAPInfo.SystemEnvironment do pos := Position(a, '='); env.(a{[1..pos-1]}) := a{[pos+1..Length(a)]}; od; else env := GAPInfo.SystemEnvironment; fi; enc := fail; if IsBound(env.LC_CTYPE) then enc := env.LC_CTYPE; fi; if enc = fail and IsBound(env.LC_ALL) then enc := env.LC_ALL; fi; if enc = fail and IsBound(env.LANG) then enc := env.LANG; fi; if enc <> fail and (PositionSublist(enc, ".UTF-8") <> fail or PositionSublist(enc, ".utf8") <> fail) then GAPInfo.TermEncoding := "UTF-8"; fi; if not IsBound(GAPInfo.TermEncoding) then # default is latin1 GAPInfo.TermEncoding := "ISO-8859-1"; fi; else GAPInfo.TermEncoding := GAPInfo.TermEncodingOverwrite; fi; end; GAPInfo.tmpfunc(); Add(GAPInfo.PostRestoreFuncs, GAPInfo.tmpfunc); Unbind(GAPInfo.tmpfunc); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/read.g���������������������������������������������������������������������������������0000644�0001750�0001750�00000002017�12026346064�012267� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################# ## #A read.g GAPDoc Frank Lübeck / Max Neunhöffer ## ## #Y Copyright (C) 2000, Frank Lübeck and Max Neunhöffer, #Y Lehrstuhl D für Mathematik, RWTH Aachen ## ReadPackage("GAPDoc", "lib/UnicodeTools.gi"); ReadPackage("GAPDoc", "lib/PrintUtil.gi"); ReadPackage("GAPDoc", "lib/Text.gi"); ReadPackage("GAPDoc", "lib/ComposeXML.gi"); ReadPackage("GAPDoc", "lib/XMLParser.gi"); ReadPackage("GAPDoc", "lib/gapdocdtdinfo.g"); ReadPackage("GAPDoc", "lib/GAPDoc.gi"); ReadPackage("GAPDoc", "lib/BibTeX.gi"); ReadPackage("GAPDoc", "lib/bibxmlextinfo.g"); ReadPackage("GAPDoc", "lib/BibXMLextTools.gi"); ReadPackage("GAPDoc", "lib/GAPDoc2LaTeX.gi"); ReadPackage("GAPDoc", "lib/GAPDoc2Text.gi"); ReadPackage("GAPDoc", "lib/TextThemes.g"); ReadPackage("GAPDoc", "lib/GAPDoc2HTML.gi"); ReadPackage("GAPDoc", "lib/Examples.gi"); # Finally the handler functions for GAP's help system: ReadPackage("GAPDoc", "lib/HelpBookHandler.g"); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/PackageInfo.g��������������������������������������������������������������������������0000644�0001750�0001750�00000005503�12026346064�013526� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������############################################################################# ## ## PackageInfo.g for the package `GAPDoc' Frank Lübeck ## With a new release of the package at least the entries .Version, .Date and ## .ArchiveURL must be updated. SetPackageInfo( rec( PackageName := "GAPDoc", Subtitle := "A Meta Package for GAP Documentation", Version := "1.5.1", ## DD/MM/YYYY format: Date := "23/02/2012", ArchiveURL := "http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/GAPDoc-1.5.1", ArchiveFormats := ".tar.bz2", Persons := [ rec( LastName := "Lübeck", FirstNames := "Frank", IsAuthor := true, IsMaintainer := true, Email := "Frank.Luebeck@Math.RWTH-Aachen.De", WWWHome := "http://www.math.rwth-aachen.de:8001/~Frank.Luebeck", Place := "Aachen", Institution := "Lehrstuhl D für Mathematik, RWTH Aachen", PostalAddress := "Dr. Frank Lübeck\nLehrstuhl D für Mathematik\nRWTH Aachen\nTemplergraben 64\n52062 Aachen\nGERMANY\n" ), rec( LastName := "Neunhöffer", FirstNames := "Max", IsAuthor := true, IsMaintainer := true, Email := "neunhoef at mcs.st-and.ac.uk", WWWHome := "http://www-groups.mcs.st-and.ac.uk/~neunhoef/", Place := "St Andrews", Institution := "School of Mathematics and Statistics, St Andrews", ) ], Status := "accepted", CommunicatedBy := "Steve Linton (St Andrews)", AcceptDate := "10/2006", README_URL := "http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/README.txt", PackageInfoURL := "http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/PackageInfo.g", AbstractHTML := "This package contains a definition of a structure for <span class='pkgname'>GAP</span> (package) documentation, based on XML. It also contains conversion programs for producing text-, PDF- or HTML-versions of such documents, with hyperlinks if possible.", PackageWWWHome := "http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc", PackageDoc := [rec( BookName := "GAPDoc", ArchiveURLSubset := ["doc", "example"], HTMLStart := "doc/chap0.html", PDFFile := "doc/manual.pdf", SixFile := "doc/manual.six", LongTitle := "a meta package for GAP documentation", Autoload := true ), rec( BookName := "GAPDoc Example", ArchiveURLSubset := ["example", "doc"], HTMLStart := "example/chap0.html", PDFFile := "example/manual.pdf", SixFile := "example/manual.six", LongTitle := "example help book for GAPDoc", Autoload := false )], Dependencies := rec( GAP := "4.5.3", NeededOtherPackages := [], SuggestedOtherPackages := [["IO", ">= 2.3"]], ExternalConditions := [["(La)TeX installation for converting documents to PDF", "http://www.latex-project.org"]] ), AvailabilityTest := ReturnTrue, Keywords := ["GAP documentation", "help system", "XML", "pdf", "hyperlink", "unicode", "BibTeX", "BibXMLext"] )); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/3k+1/����������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12174444011�011650� 5����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/3k+1/clean�����������������������������������������������������������������������������0000755�0001750�0001750�00000000153�12026346063�012663� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/bash rm -f *.{aux,log,dvi,ps,pdf,bbl,ilg,ind,idx,out,html,tex,pnr,txt,blg,toc,six,brf,js,css,lab} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������GAPDoc-1.5.1/3k+1/chooser.html����������������������������������������������������������������������0000644�0001750�0001750�00000007456�12026346063�014220� 0����������������������������������������������������������������������������������������������������ustar �bill����������������������������bill�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>GAPDoc Style Chooser

Setting preferences for GAPDoc manuals

Unfold subsections in menus only by mouse clicks: no (default)     yes

Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

Display side of table of contents within chapters: right (default)     left

Main document font: Helvetica/sans serif (default)     Times/serif

Paragraph formatting: left-right justified (default)     ragged right

Apply settings to last page.

GAPDoc-1.5.1/3k+1/3k+1.out0000644000175000017500000000036312026346063013060 0ustar billbill\BOOKMARK [0][-]{chapter.1}{The 3k+1 Problem}{}% 1 \BOOKMARK [1][-]{section.1.1}{Theory}{chapter.1}% 2 \BOOKMARK [1][-]{section.1.2}{Program}{chapter.1}% 3 \BOOKMARK [0][-]{chapter*.3}{References}{}% 4 \BOOKMARK [0][-]{section*.4}{Index}{}% 5 GAPDoc-1.5.1/3k+1/manual.pdf0000644000175000017500000051677012026346063013644 0ustar billbill%PDF-1.5 % 22 0 obj << /Length 281 /Filter /FlateDecode >> stream xڍ;OP sfDCDCZ5IQJ4MCΑm%G{EWlAyt$O`;m v5E=jSR%{HEq[O?7#vjѫY$$c#Zg') 1fQ\ͮIR"V|J#RCD6H}W׿t^Icf` =ZehBV/?ql]e@іp^x1'h+x7 e{ endstream endobj 32 0 obj << /Length 279 /Filter /FlateDecode >> stream xMN0<:-ը.F=]D-[if $erPp[2[NP+-]~WT(=3ۮO}od2;&(U҂@n%\=\\+-W8S9qRF8mt[nkB&%$X& S!'_> stream xTN0+ yY?֏+*q*<"&u'8Dxw; ]/Z9Pw9x (C^rV7!A0h00wt0Ph5)tl򀆆$DTVOqNϨ*gqK;Ha4!$٘8였!P\9]]`CT(9°CNOWUv; endstream endobj 54 0 obj << /Length 1782 /Filter /FlateDecode >> stream xYKs6Wpr'A4I2I_iiKKBR @(Jf2ӃF\~p0pj磳T("8bD\"Up> ._ɺxB#4bt^9XPLwІ P.)H5$SPoHn,  GqILH@kMŠȫڈ?̨z! y4M{"L*c 5lf}Z/Ap>C_}6 fBJ:%{P"!ӮTh*[Qӈ:^G~QmSVy="4&"ԙ15 ǩh,ɣDIRt{dxD K `: +#rq&o] .4tonX΋&ߘ:Y.혘V(Tcw|&v\պ՛`P3?O$v~sH_ZVy@^}"EU<;[%4e l&:.*Ufw˫g о/sz .YzPfurWr8PJ:)0%(ȾE#42$9RXt ^ `8,>a> stream xmRn@+8hCgޏkMh7,c${> cP8yPU=]Ԅ QX"Xg9)qbi)vdK_>w4*tG< gZJ[mZ>$5c]2.R jU&07%xUBb<5UyLkׇSgЋevyMEZĭ$$hPZM\GXO: $x`|6Īoq`,w)Cgr$4$7]x i0S_/m&- r1 㶉i]⻞ʾծ%17qP8qihe}j>ࡉA0>hkx7W8αD[ _ i@(FGzYl7Ř endstream endobj 77 0 obj << /Length 174 /Filter /FlateDecode >> stream xu 0<ō-.MflQE' +؊;j?t,dR,JcB?ӓ|E;\ :x.]lKTcbH ̣xq4\jLTt׿kEt\Ye"v @5 endstream endobj 97 0 obj << /Length1 1463 /Length2 6128 /Length3 0 /Length 7112 /Filter /FlateDecode >> stream xڍwT}?J 5Q) 0b$FH7JwItK))"JJ#!t(C繟=;g]}}n:p-'  u $!S#pT|p B:t%`i9 9 4 >g@cQh G#@&Pc0`aO B@ Cb/ $(Ep,wCAQ3  O Bn#:L`#;v9X t!!0 A#'`e É HsG'E@(W B@AqX1,#< 5(//8:O3\$@:pZ ޷|*\8H憄 ܀_F𹚀!(B\0A8* p4S"TNP]~˄c~[~`'{ÜQHO1XW\_CP~Q qIn_'7_ڛğ#.8/qp|#C ?{#g #po_ ܻԼ ,s6KrjrB&/LqOҴݷP{#OMgGW]T_~ zF5yLl?Z+R~`iíyD[M0048C,>T'loNS~MCrʏ>9PmMuFnۛ\i7ܜ\GtF,LQjtA4'IRֲ'|GvH}х3um_G(V.jHq"n&nYS)Op#%3f_ rJV&˭\|F6-ĚNB" y~^xSʻ:H_ )he&} PeAO^R_M@8 ntE$2r?^$Nr&0*z|N$ASpI0B7Iݼ*o9*=PGMAR[q*hDd`@p1S2,b$kôec QiMS%. ײN|^J!&S殄+<+g3ojla/ɛ9/7>_lnia#Jŷ[}>QF1g~KC-VUk.05O$Щ-3_--?=[5 CW*,7b~;ASѱ IdґSo4YbwLT 3ӭbͲÂwsբc%^߻Q$MJ~)F@J?s?r @٪N|8{K4Nؖ\s{`\0PzyiE;)IApȲ:7q5;K|Y:aƿJnPMVj2>ۧJu[Gi#o$+l6)|sqwףsq׋מ6[vI7h3GYoބ2\gD}[55nw!I@&Lw7ՐuPy%P9rT-*6el;3f&/-W"qSm7Bq .Ai5Q2Lǭ+aӍh/ݳo\PHUV?TBͯF*9 pcT#w(7uKA8ی:,t5*S/!$BZU''{HFWv~aU,bchyؿ47b RR/e"~KB9uPF{4|xe!pr"CBgmF}ɝ3-W>nBt?ehnY"!"#$LZM!4 f='(Dx~8諣e amSϯJ)s ulk/w0,krB&P|uҖ|e#}'dGٻ3gBNc&j(?ɿ 1lR?Q'k S1;i?"vJ:ߠ0`44#M?M{L:,;FA5˵0&#2aAVHd-~f%6>󝋮Ь "!=ĸ _UޏHDoq%plPaLMK3C J#RM|Oo0IaK'RldpS9q`蚑zժ[SJW_Ĭ\Z.!ΝǪ'_cCf-w{d3!USޙT[2d"5n^*cBL'I挲IӚeVƮShjtѫW :dvҟicpym1)+@|R&yzbT^pm]g[ >Eh$&⒡գ}O 6'uߓ#ʈ̤qFYМ86"MQvG[;pZ+fe0ϯUP}R~T3*gcJ0*!6,̛F$>z=0{C{bc1E ǎCQʟ͟W;2VaHi6xQ>ɵ1&hoKNT)9mLֿhZПQ{T+~VeαTwݷƻ)DxM^$O/U}&IU)㥊)sj9EB4j>JI"6W*AZ7]Az<~g˅Ȯr}l0K/{mEP@ǓUĒ(h6rnu^b4isY~tPR+F ޡ^Ls#/^ӚaS$""ny؋'pObZ뉪<#WjNZ&v<ȊGU8i>.eܟIr}28sE fB( 4%襇Y^7b,udGޫSamM 5ᑀ*V%x,A*<GUugQW"SQO͡g~tu*=-SIzқQw|1aUd4-qL}\R%|ml|w#E7.NXhPRA‡=FTl;8`I++8ELϯsnvN Ҝf^A juRg>]-{tDY3/UǛW*r:Uuʞ] u0FSe\p Q{u@2T!*=u p%`l}4 ;RqU?2m>XHfrȟyaf!R\R @qT"25(yd/ݹp^Q8!tVhm\>>LkZ YVxCnk V9#5EY=̼B{ǃn=pJNx+!cV}bڧ ͬJ9rSY&iOh'џ\K.O`Ž*/o:ޗ3o .|~QYB3]7MŁ1e)yJw嶯a'_rgYx.E_>賥ɤzӿ4c$F8UhWTD`͉"ˎ>uWO#P-FvjGyĜhn$;߃MZG[,g]@j\(P}R'0sј'EQoBv%okeRlj(׻5]927͟6Fi22Oh{]VZbZ ,&i)c1lW5_- TYq!1k U:fggʚG;%;^qJ^w @ID'GᤍBNEU'2}$!4eͲ}OPΰir %VuT5Sć k-y\_L(HGku2iS {*{uc 8}{f-h5DG)5*6VCѦòQ4H k ~ʤWvi)e+L"SléY=ۏ)'v́[ЍeJ>O.(qSHR߮iv{UY)r {cуgp7EŬ8PZlW"+cHژ`ˌ-ܟ_ӟ~K8fY*)Qs9h>M$Jf믑˪ܑ'9uZy҃@!Q1|s4Ġ Ja@2H pn:uΞ0Ѝ-׎& `qHkiR V+c ~Ԋy>1hf ieOVD4Xrx3kio?߰?F4zR(L{U$9DSz @&yzh8x<&;,je*7iwQg h/F6_+#;c58uc쉶j q]-Bá7߉N[L.yM魯Y[{tEI1*KKŸmI~dr`2LLuR" Q1RBNʯL +./􄜾v]v'FuJi+K[nPxS6u73$e@5ty_uKPDot诩t2Ј3K[='}YƥInʴ ]b/*ݭ70m 6I'ܬB=vRBs1~V]0U^TFYk<ũF3' #$fMhkx _Tv6?lu⇷XU!{웲k#ei~{.@ɠf\[dp5oM1÷'WկCB4!7 MX*.lC#psFRWg?̥qz$Ahy3LP_Xm6 ĪHDVu(Gj` &geEI[$y؈ۜBO)_Qk>#7^e;h]H *o{PT܎,1xjF9$qu#}-+hM5~&tpf4,1[2̦Y c&XԠG]B}TXخ}5z׳u {CRro`fz' Eri$c4E?[ h{MkfWy>oI:gnx5+Z^!%mBmkm]/^P PCE尀~#t*_l7(X^ړȟ`cMf?u> endstream endobj 99 0 obj << /Length1 1451 /Length2 6269 /Length3 0 /Length 7242 /Filter /FlateDecode >> stream xڍtT[>!HHĀt)!3034H " C %)!)H#)HJ|c{k}ߚ~sγggN6cA%g#B"2]#@DDLHDDA$f$ Fc1U0맋`()H@TPg@ H8U~H{_K/(--%+ABp.qǞNP_)xhaa!;Jt@n# 8~! pLܠ߸1FBXuQ/3 0{@࿝u~;ODP` ].PB`OG0 ƃP`HC億zQB(('EiUV; !p4TH~¿;{ٸ@.?I8{y¡^M?.XHHI &~_FO (pA] ?@# Ai8CG+NOv, q6 X` +5ߌ)+#|"AQ Ȥ.5.o,x /'!Zx?fߤy`<qJ  ]v8j=ʺg[5`x(]aA}!Po lz1@? ae=샂 wB8g0LfRsQ L>@>57)4t/^9DgߔO y""V Zq{%=*kPچ]I]:~x&ɓ0{6PR5ޝ/R-cI\/޺ bHG1.15>JLi!s=Wo]mrS_&e]P(cd1mx`LϾن1 K2ѧlc$:8t֙yDX< rZ%YOfDe .(SNM11t]L`BEG j "L,'j6:д121r3i?V:hՇ$4q4G`e(Po9)wr,@@Ku.٬7o7hI{550AkLJ Bj{~@Si+5%CA~,X8m% ӈ; UW'W6jiGN|W۲撄]Z3` j2,fJ:+rm *JRQL4S)ϭq 80(NqD"Es ϒ.Ev BԞjt9ӓ2%ݵKɐr#0:HQ-˭E'r]ݱvk|ZG`BbJ椈EKreL9\)hՌ7ʴqA {'t%m m~C(`!֠se0+z{> h Yed&aY'$nDI0d[iMGF#h Ɯ{П^VE@>RGeY.GHl 8PvLv<7z:e~ $v3jkI4L/'W}]aQ:L^`?ݗ$Aԕew@=d4|מ\/ܟUTMR fO^3Ys䓔!CxJ qVuTpg^pܬ!ܦIP)!#W_/[~l&8㫏*b;U8JZJ=LE!l=m00hh[ $4HIoZšpKX6'2zO7;QCOY ]®1DpPIW8Ew*|f">nK;^.zIk~ydXNYMfjB-nNpliiVV[*(etviyNe /g{4nepkhwH;i\wE햃NY-84}{Y4ŽtJxw `*6u=>_Jݝ£n."Q1() klyջ:8鼣G+3aYpLJ+50kU^;jK~WžBٿ;ewQz"BcQ\ #y$SQ>lWIAĖ~ƶEK)9!G׋Y3DN֪c@O\;.T[G?p96шȢ zRvJe%w/6CEք侔-' ciV~J;+B_Chy҅۽IPV#i[IjSwR^hCwݖCX6#e;f#e0Æ[1 eWVwbR=+!\Cn^|D6[Ь U.sNҨ{B׫=hͼz Kop"d "FE<9,}Ĕ+ubLڏq,o fw%!mY˞Ԑ?]}0xX<.*O8N152K+ZwR SQ2{\ r 7K^h 0ɢ XP1S> XTH+Yw;PK-pYCOB[ :5> H.z?T&gm{!)`Sͯ8'løDÖC/9לj6Y~QѴbL<pcmㆱ\~pyX ȲH_cR8HgC(837HrD45KUnT΍E t2ɊPhYYv祓6Y[ro .K 4jEM'Ec dK+o8m &ErX>Dϯ~Q?u[.A~݋ч_]6>XdW/L(YvE ^f07=:;l# ѸqI]ZTE^ӷH8&bȧUB%Rϙ>iTBA . NQ v\!q+uy 8կoM9 -N9Kj5aYl˕gC-ݛOs^ّmwȨN[8>Vro<̋%ɳ_>H%,^V~DO=D?tdx9@H+_6&.[XfD gx ـ'8?=wbwK-6ݩic .aj6νC:܅({[Tz&`~gRI9,FUޖWٽ+SWOz\5|-hb>gad^a9mCU>ȃ*|ZЎk{0nDaOFݕ%MR҃9K WqHR^gJKufՃCIgF3$%4ŵ AL5B-U/m=x^Z;!DlڕN?z7gGXM7$t^c4X8.P$Y7[絧?U' M7;poҌNGU~-7M,ƺ/fM0k+=p8e7]?rcڃ}Wv\MYG]^S*ߏ}M+_z{CPg3Zr,HZ *ȘN&Jk.x/rİk{bU}ttjx~d7̈O*BjLkXҰ|wXﭚǬb=2[S5h'W廳/әf- o.l eK oXfdoqpSA cl 54{6)l)vV.I[4ψֹ͛6VO 53&d F[ը ~/;"$3"T !y7޺"OoomXHn:zCRԆ5%|uPL^+i>M ڡ*q1Iߺ@.=ysݼj ѷ槟R|w{+}4MUzLb"6T"{I@ t` xۦ3RiL/qݢ$?kL*vɨ[3t鷴,%L{N!g'䁄ЍwӔV14M =Z-ڬ{fI^WZOʙ6[0]y099_NW7l,!y7:ږud~fαмpȇx&Qb?_.?\VYS妃pth]'yyL8#_o ،yAloF;m f2-%. PO]]rϼ{{yo#7u5BϏfNI{-^h;} _BEk#}ئi񊪻f^q>0P>7nzO'+rD2~?HjII8Mpgrcp 9 $EtNyw;_qVM-ŽZbH-]3zĤm+ZF5F7G9MQ3H&g59E/^xLP;*9QY%NT' HX=|Ȁbv}odlh ɒ42De *)7Zy]BRj 3UeB]$g˵nPǨm+ F#&e:xQ\S^q)3<45뼤mOcstW7n^ 3fI;ۀ<>(d*y!h302|ՙBI^GIt7ҸOg.^'uٵ"pO6f󝘑&a"MKeH_\5Bկ] Bi;uK{FHxr*O.9n1/t;pVi>_f&YG=̳olפF8 (Z@X"gad`fe۱.pd<=L2O)ݘJ*<%W>h]?L endstream endobj 101 0 obj << /Length1 1404 /Length2 5970 /Length3 0 /Length 6926 /Filter /FlateDecode >> stream xڍx4ֶ 5 zމ(c Ø3z%z.$:A JFo$ZtA&ysk}ߚy}z ({: Tt-E P\#2cп\fP74TA,PwGD2R2@ @ r<0> Es\lo`>p ! #[ BQ`81WOOOa Z 'cFP4  @P&89Q0' p0Ɔ#!P7:XK E s8Qa+;\\AHo8#}uaFBB~A4  {,Au%C?4 A _E~rq"1h_SAs\g$ GB`h@]ELGP-?6( @^`G_L]X(W KA_ľhqs+bQQp$cP_kl^+ V~Ͽ XDMLSU9Q^_!1i$ *** 3ϿNo GF-$ &GƆ z(!P^DC;_YW~޿GxA`Ά. ;!Ch](^- ;#JH΅De^PvKK7[GB Ph6 /vg ۲.(vYW FA~$&*bg-q00b@_cA`w77 ^v( &FeÜ^(1y }&XZnN쉒p=S4@/ ؝o {`KAo4kGqN'Zemwo%Ғ8yOiƯ&՞Au%%Lnא}(=;Ƒ`&N^`B9cwR&\)hy|S&Ak_(jWov~nh/"FdѮD>N"q;bCr"x_jz1_i-ui|X܏o {JuQѩφX3gƓp~Om?!VhLhQKmj i=n"r5':jѠ*g6\Z|J7[$,P]*RXC4RHPО+ܶ|CYwY~(DD,%y+:jw׭16DYY*9h,L*0P׹[kY\L%`hug{"=;97cc1RK=,lN=`S{Ck(U=j_ Arf (.Z% cMB`rtwO `(*@/.k%aZ7c_N~O[̤lfAF"r P Mӧ9~߾?"ڏzW2>$k+vVֱϛ-$Ui 5C=YhY&S+7A^0w!Gƴ,qF*iE9 dy}t9mTtq0ĺ֙ ny]\u1D_Ǚ|*#5?񀩁VW{lN;lYZ#m¨UAY&.LЈ{< .z$M rs8*m+,OIy-W5S%K싧E| k0zG6ՓV&Lp y~l9fCZofrִ޹<G{qƶ Ek0ݔZ$#P/״.8P6$~@~4@=^>L<;W#QClf8_q~>:HKX{n {+b×n;Dz\;7VLfQ vncM$q),GP\4Y%Lm?-! W̟Lx̜'vY"V'?Mꕅ9ropgӅ}4_ eYo(L c )IWQ%FCu҉<vCoN$O[=H]ev&񦌧kLveTY81YW~̶PQ ~,dߨM,22Y=_[ٍ"Oe&Fwb8"L=xȹ$.. u95hp+cu4޷h8>jF(O`fl3(?1P쥝b!ʌ8gv c\ւ724Yϼ͎ eM纅.%QY. W8#?P仯ew ?VxR${Q $>gNUkǿ9ۻ=#RuB ǻЄfEozshH%%ϳn-PO|*^ûl6uQZ ц1,)3a (ՕV#qgBA_s5;Bߗj;1ϛ#+-36)6m kG4/ pL#,OвbXq;|-3MQ>)8GX^'egp}E*hno_G<$+.̥˓eG%C* IGI{oZI\$Je1PВԓq¿D:mtJqʩtG˩E 𙀽h.lΞs'nbꋺb/)#u \Y!C2KmYx.8+._[y䴝uqjk\ LVx +^f+m;na5bld=o멐G |Tw¯#IY|[sx?\-~Z9:\$MP\i>~DƔH y꫖L;P3xa9Rlyݑsi}g k*8xox8xC<+°ih|RZףk GOMRŷ9D܁ܦ6|OxU#{o# p .54JW쀇E5!TB _(츹z'my6j׼o9E {!k| [Wr{gwf3|yRSLDQGa-^ΘN5<ůŘY'yq͵F2_# fh𜮨:imT:IV4ʯ |6 2p LVm7wBPgه/:cJBWȃlC![IQ.d±oYӏe9B'dUz썬?~C\4,4V$ց2ќgKka]cjvEAzye]9~3)՘J\3|J$Uҵ/UD |au\E(+Ƨbpܤakj)~v=$?Mv{!P'NqKa1)wao[&go#g^x$=W%-^Ptj2e:(zZÊ2;cEտoڐ+{T[fnABs٤i|8I5l)N|hW;ޞpEDQkIފ_zMω~RҔV*Cs{%_W,|F$)_hs_z9##}w]~A>ԋ[|SBk(J;ɽmlE{*;%^_)Gd6fhyO=Tvp+խY"b'S D@4K7K߆Qܛr[b jd3tɃCF"o _2#zN > 8A+\>h b/VOԶWfbr(j>>Oe&MƛEfޥpw< տ6t_G0 Za}avv:ܶUw[J%4eRkZ^IK`\:jQA΄udžSCG=/Lbn6Mmi3r朹 "T񂹑;]RV3e1+a7U;xR8;g9ə1u7WynAPL˕v_tSK X$)v9T ھ=wyF>uij9dPG/p.; S7%{pƿM!P@V:uH =dhM9}fG'v+Z|^"S) |gOOHOҽQw0[U`~8SI`5w<s9`kKc(}ģ >v_2J6?.mH endstream endobj 103 0 obj << /Length1 1328 /Length2 1591 /Length3 0 /Length 2446 /Filter /FlateDecode >> stream xڍS 8TONAWuNGO)yQ#Jq1{1"x8$Jo:!upC8 Q*!=u{=Zo-6bA0Cq3jܼhT@2T*ddBdH  !9B `Lh @-RJ$V#\F10Rq+9&fit,؉` P|XDT@BqW~˜qP(ȐHJ$+ML 9*$#Go+ \Xu-8x8L4ȴO&Ut,p0B xd<7U!#!9 0t`8Oʑ b\J"BG* f'뀉D0KI9"C]IhA< LLE8!L϶`L*frUsTfCDA@x0G BrF\ 8AIf7~'/ABf*!?~N¸*T~iON{{,1̜Na!<:B&^EFW$}$"Pژ+ca`YT&C|h7OElP87!B8I&%l "2߽8Dl,>DFBa'sN|r0jyL I$D%B'F# P(!@,#T#YPU&Wi92ؙ5?CaƱz!`|ًwq};͕r`eo+^ѳFP?> O|^Pix,Wҵ2zۚ762PnW(lM7 yѐZ|% vڒ]d5tW`hM.K/η?oWum$}v{t柷昪!|-^ӗrejGż5y~㨾ёA*o7!ot,k i jэ[nn3g%#^ļiڣ;&4}[u\+s`qX4Y@+ J;{u"{tjp24ry'.0s;ho?E/>;odt0[ЗC +FT/ͲoXĬb\tIH=tm/#e2)#-ʢL]3<խzvskqjGZʎ]- Ry]smtp{.]ɪ`DuJFnb?hsM/@_䓿d߷˭Iѯnx+N>Jl6_tXt)^5*#>3i'f<ҋ{j~[<Ͷ7Vڗ_<+sv)ʺMg]R2sp,u%syϻ|uRF}P ˉ>43uuLof⭜{6zwSVF+0ţ$lݦ̆3lSfcRĶ]:}O䋙/.zʖ:QoR:3|^IOG5:'+sUѷXTYe=IqlA5dKOikDtnwSV ڮh]yaUdmѮce2X|kwTk)ikI|,0 aCmf;b:g3c-zV&yEķz:4#,5{8y괡gՏ[tݔcIg)Lݗ7],6>1 uzmL֠=?m ۣӨad.mF e%.'ʖQo14PnxX:NI_tnwÊ' ~)z |ܶFj<"›i9:mūHߘo5 endstream endobj 105 0 obj << /Length1 737 /Length2 18714 /Length3 0 /Length 19238 /Filter /FlateDecode >> stream xlctf.Xwl۶mmVN:Fc۶m}o?Us^5k&9#*`b`#'uZ9؋y@3*`abb#:8z9[YXL-hYY94lܭL-|B.n n 8WK UTҖVPI*$@gc[)@h;8lLͬ ÿw:@^\MXBQA .ʨ& 07In5_\5_:{bcfYLVpM T`H 0cfk`lP:9f@g{pDLXH?0s3qGl"a 4Sr{Wg7Ědԣ6*;vݟ45(](dI9|vyd]օ|ƸGW4h*f 70IbڢS殜O\pmET2\9!DOaGNd*X@F, ,毁S{ܝ.{?)%GDX|S9 WPi+ҢLN.,3P(h,t,~0*KgvT'z}/aoN5)MO&ׅ_'j{axX=DFuOCl_sWxpfǯe 6|KQ׸_hoxR[7IMA{`k=0kZ0 p!Ќ?rdOU>:E҇B2VR歎9|qX 0M}%I/%m8 lZ v⿼})7$̒-R^nŇjΚږVyΝO GT>˔B8ivyEx>+XCkHAPJ<~~fr("zi 7ˁݕu u<v*D"Tqf9VKCmKmY_|T0{Xd2Մ^oϒ0~JHJFub ^[Nqץq5=&-fcҁsB䉅*`}[XiMM %fz=^"ҷ``ap<8,vH%E0.'V Do@$4WN[*]a=҄qx1Y;7wbSll% D יHT3 -לvƛH>68re{:`S}-X/)ɻ^Z5.]E},Dov.?:/P?bapGy`G{H//Bp0(?Vlida.zymlMO$ Z0[a-Jų"Ų(*yg" Q03ؖv![c"lǫm6zB#ࡇ(] Bc]Lv}Yu#y._ՑE͈#ljN z.t?y+S׾]y];E[h󅖁 2zB p|[:!vj 4|_B^Su _fhQ+3;{=+i湔SGosW/"ݑ~_= DмZOKBM;Eqty -2_Iz@|cZ7~u d|2_oʉ 㮺b,(BP7ijȮR9DF. j$hЭ@DX|X* 84d~7B 0ryZNjdY9'" L[K]R֘g&*ߧ"?pՒ>{^"~,Rt=:iqgr +yi&'7TELIgUr  plw57i-Sy(Qs>. u%4eAҸW㎅5*"Akt %s1v2pY 0o,j"n*WɿܪK 7h g"֤[[~%ӫ쨆yGa֋ͤȄ%{6ld?\]]_c7p.{(מCm~ȋr%cM_`#g+V}kOl=lͫF4bW;ۮnx!o+~!Jg>XB!NL\U@d~_1֘D@؝tp0 *Q=Q"IuƾG ZfP%`#U9YEބ]gs)q:=1B.yS0&z6z󈗬!"6 :pmY#xRu:\Ecƞ{TJ&wN);}\US8SGیo:EN*`?fvLG(0-XYښ6M!XwDګ~S-}k{SFR͍߯+|Cg9Ox>u=).T=j7uLzWt>^ʶhH(3yZj/lSTuodG$he[%Aٲ" ]^<AnG a~ lT3 PR0<5BCzHЕb+% oe1$dÓ&Emo+SD!9BCOA ۄ'Czaֳט"yG2s'@9gb'ލhJܚtc+"Zg#lϞ ,{- :eׯn[i;G{;"ިwz[i-J4*O< +xQ=נwH+SgO`3Dm):U4q ~S|OpJ^E5~w>IĢj:.c5-P [X5~69PL:bɇnI˹X F9&,M{nk}Z99aJ;ܺ ѳv'i"y'N~8jow4Y}?T#@U]LuUzރwF,OpV<׆%TpJzgwy}sޏ+YG7?{7^ :߅p6`-bu9S p*esj @v u3فDz"Ew<4'6=|rW"sÓ- ~5J? o͈X֫i2ſw0U雋#W8U- l9l+(]Н(-=8cW-dE`әC+,x}1~t˟&12zd s/Lb(gFp$2:Otxk)(o6بTcXg^RS&k$\@KE-cW}KyJݫ"NBPގ>샔פQ3A_^qļ0pmTp[FNu/ASo [ TT|(9G]ML. ojZigW|(@&iQގwi>*Z Kwyl冈P:U A^R>/:(ٱ@YQv3'4sW'VspD}CP <1famФWc _.ڴd\?h+64"x,!!#-^ZI3f@ ^B_ɬt/\YAr7bVW>r@ƞ?{-)R^170&vR_UӘZ޳M"!T"C/.r8t lT3EU7%+ &3hۂݹ#sSGӢ #Ksix"DXӐ !+F8%VfлwJ6_O<'Gv[ "^m(?A3h^.³l~736`@t\oOr;TQgq):œ5%~Mdd?p,~$NQ,S(?=:i*:QzgvH0WPШYiϏܫsdiVz>I E 6uzY4 HYi8᧮RlaH Zנ'~ D#Y@^m]#0%g02mT(^KS> ^s u<P_Ň`AԺqQDVj4t&l]{ c|# #<' .~ =|ߗzT뒩 zaP$yv2?ݴ= p'1C )>#\&Y$|MF9`Zfqſ#G` M5XYyXF rq^Bp(EYt8;R!P Ff $ r#K)r|$M%MY7z-nZ0bD! #0b7_z}8Z_EM,V/ &+w灥nb>dOJPz$5/pp,"-YD`x CUUf 6$^&ȯRRj6e#U:l~IgXI%.E_NVcx8v Zp_mY"+ȉkAL*QY 2aWGqjG˄I[ 24W0➰4ㅿ6[Zܵ;}^Dd7485&* Ese`>qROh"g!/LSyN[y țHgH"2E܊۾0xG%@(O aJ P".],>@W![TYC GZ<(`5Db#q6P垈fB\ӏ_^-S䯘\[s +cγXޭ\̩\x "!I s|8t$YnXoؠ {2d.xQ^Zi||옍bJD/+KUSQ\$>ܜL`PnlTU7I^1,O̠;k ˋ}دj4x:kpM|U?xu3չƸ7ElBk?z E0䱕H>o8;Tr M1i$r_z{sCq{p06֟7YDldӞǸ~fȓ|ם'jiMnJAOB~vō8qxƽߐ7Z*Q.I~;^  zygCb+03l gbʌ%NR?wXJh*v. . An59^WV*M =P&N~3Nڤ]UZ_xݳ:g!zao ʐEsQ"Ȏ{u'm2AlE!D[g/o[)u1e.<hE%Z~ [%!Ci''-/zp1tVd)׭f/rlteo%b{y{F,hmKSȹ<+@[%Y#?~v~MgL姑 Fw :1gl|Ig局qB#6ջo b`+uSRnHs"1MEcܷbh{ Pso#@r!5hǎ*)[i/yi|j*ú2t4a[ebnƄFW:OϗCBN^c(TؚoWX"U vUs]*$_hҠU?y~ĔgkȘ@Ϻ"rTzܧ$3e e6!(fkz:]/C(RaH?^k%;Qcy[k n} "E԰zF6I0Ği!6ˊ q$Cp]Y#;+R *pF(>L4%w?6ȌIg4#. ]@\fdRf#ZLhs+ں3Åe~D8# w96d ݋zZu|A =ǚ%^́V;I.%= 9e͉},`y`6:Ÿl`erO+U[<6(>;TviCc2ʩgud h;C5l3lb4CRnɁfp9\t"[H7X˸ݞ EjSQy 4aY]Qԝ ~C D]fDG L%-n* 3I%c8fP*hDZ@ ffB"ܾkҒ{ñU &>L}B"Mב1t~AI>ܢ;=6 dEWӎN~|dǢ.̑Dq|w/Pi;CS~6珦r~BG= IdQƚQ\((^VJ! 롉ږ [e ^-@% (EJ&}&d ArQ("8InH?qa̼9$f+. yz,y1IPeWvpaJ &m"vss;%󷔶]WJ9p{IC;uaOpb&W]>j"q $UD錂?㿛Zd.":Inܷ) /N94vϧ:nk,L 0~e˙qח$D`FUF~ U:C2FM3~rF0 m :/Stec"^g黝]*wBgv(N}?.#'3'W%zՓ%OIc'$+p(,GA>l[ S2O*6WM8+?OAsrhNʋq-.X/ /.43To<H%񂯰z0.ɥtWMp?U{`-{ nC#ɜ5N%e ; n;s>ԏkh0m'~z*|[肘1%Zm,X㉁U=N}Hmt1UoV$| NcМ *#1+9U\1gJ1r2 / ԑllOsw98sD,Uyf ud|N/GI^z+!#_&>an &P2vJaY=5;/sLڠ;_M(Y $jD?YX4Jt;|2 IjA*Wt%Q;9YLr(2d.]V4be"&`byP+@==TEcE=]L?6|TVSrlntٖ'K0&l#3,aKү]0ߥdL]XRb2¸<{dیt:CK;q]G{opGUK( 'B8Z+:*?B /abgeX2쉥".=,+NTihF 44bZUd2%qx{5S'=jev*UC8h^G%:"C޷ł7ݬeL|i,귨{F v}G27|CN"LZey[pIG!ES/J,]sjI+_Þ]lt3\͎߽\2ƩIlCdccRJ5h›?:X_edo ԕ܃$ c',]~7C?.9B^R žJ܌?1'`lmP|%2Cd pMlrM@; \}nv< (9 `'^.,l-2y$ L4аk"GF˱-#J4Ub{҈`C#:T &TW| |q°t>f;Q:TY d70kLK>`\]׍,@@ϣzzBM#t}HU e>xC9"]]9% Z[5z q߮A)xũ}rl xI{j1 L EKS:p7ٌڤ7YAT( ǧMvꍈZ>6{"6t#$;aEjQm䉬>Ϊs8.q>Ν6Î\m;=b#P сG=t 9 2d ,ɖbjٕȺӝ!Mȼ$|!aRZֻ _xt OD RZD"^wzi"8INU@Q %ggGۘ5>C,n6lPL2r2yZ4a=n*EP ׇP ˜o6bLnd+>(+{ `5wffZfV,]& ]x4>T\st {"KIRS*o8Ѝ,$c[H甛.#v `O6qynd]D1“済L-,ā͡s>gqEzfu"S HqG@&#( eNzBFj9>s7ƪs37#n"6N)jA!];@&v܅˅=R# IZA׸?8&ft>Lpݍ8S0UCdlxQf[up VP/jRloNtx<)., ѕ SAu %{A3By2騏.LFd߆z0|R,Keh)$(}_()-0XEu2.~iuShx}e)}gYߍm ƪ]H zZn%\!6 u0sC y~٫ٷI M]y5S/%b=ݟƇ7~ބx-s͵iܖ'8i'%SVṀ(+\v{6ZT1 2۴e{yYBsݒL\cY5 ބ 9௕izfJr|cwvW|v;Qh1ز떠Te̕s$2So y2kZ^ç:̠۽ BzQ8'dU@:w ]і!bufҘ[)֜GFjgNmqAO|*9Tv3bTsZ aC&C,2M^om>(*+2e:xD@ۤ7X`4ؕR[%C=S&EgזJ=Q~vѤ9h~x"*ier7F^2=u[#O脷#M쳳x[@Ś:jQb4j1 ec<>k4[>W!#2|gr3 W+P˨%x.I>ZÙ'١ed]ccqCoeݸH~n@]J7h"ZO z6qT;EmSIީׯE, ᷍_BYώiҐ VGwhc5@fA-!D]pXmIGz[Ť3f_OBEC_ - m(E#ʶKZ pXA\8te}Y4KYS{FZ&{6==QLTz"T})[/4D|gveZIQb>Q[R{g$Ev0(#:Sa$0H^=ݻH8: M;zƿtBbRG^ԽL s:t MGScW4N᭦DDjݶYVCLʮRG 7Fh{=#`X-ϡnkV8RԾVuw KcDqn8"#TEIJ*|gȴM?x9APnvCP_;>]P;_˙ŇK`09RU'N|Zr endstream endobj 107 0 obj << /Length1 725 /Length2 30914 /Length3 0 /Length 31418 /Filter /FlateDecode >> stream xlc=-m۶mm۶n۶m۶mof̩Su^^J%'bv*&t \b**  tPŽ&v"&\j&&LL PvfFv60p$cgmjadN*BGO'egsS kay I9q q9Uq[GkCk # #['JS;G4l-ɉl]M!fhgC +"(&/B *L"L``kL #Ow[g'&Fʎ,Y:Ǣbd$00r&041nvlq7!P!%?hkk9 a;{gGY;cG[ihP k_AH:#?1e$fnb`Ύ.&qgndM-\lMUc;[k3?{XʑsXd-֎?,xҗt%jd3/KEOެ6C ΎԂ(T ר>WΆæn\QeT[dy&.R:%[-Ȧqn)Y(Y[T"L9>Y.m9ɌA4ggA ߦA/AV~U RK5DKyX󊣑d\׌?idyCI܂k*wR%.7)1Ջl@!1p54,- MظDXf]HiGG+iOv=RL&.vcž5R'lp|n ʢ% 2ߴF~aWHܢ {\K4o.:ޟ8cNo_j 7w4?]0Znv&{Ol_T,F"f5M`i]uT8%yt0&* V(Vo<ѣ`FtT?'liTi:06Jii"jxxӏp;r@[ȳXOm_[;Mmv`jZN//aLPZ{]cV)}&:;_6Q7ⶖ:\\ Q+RKQB9vD. 8j8c ^t%kJ8P^FDez3@9/6Ir!P]\ :Î#g34)ba>jR=Ooꄙ~$0#>'[A>vu;* 7(8y(ɷHije.xFx֣ #:13(xX?\ 9er^ "ꢇfYu!uejo D֠L8f *IǨMf&hʽ:Low I'Ƥ <7#jʵ MLyoI* XlC;;AxjL 9;='~CU.r:$㤿fy^6'Ǩ>U}z+A緛&qF>O ˃EK}:d $Gۺmp^_mwMCzOo±ޏ!3%TQDe YA2TP[>U}LWKIƜH]y[rη=@U_ Qm+L1Ź o_LTt h5qa-+ek0=qOP6Y߶D>ҍqq?{m44J [s>4-~ k4äz\!tYtJ#i-\{l}](m&F M]DcOmRYKY ۼ 5rEC''wV'wd,SuJ4TX]!-wRԠ~m1Ԟ@xj$Z̲[(imhœ#$་ -4~1_G66;<)0dӲ|ʏvF3L_[c5H,HG hU_C_ y zL >7.69JLu]stbR0X1uI0]eRm<#ϫh"`M2`]HFӐ#|ufIu A^[ ~/ڦwl [,3Z[1TXHʘmth@W?pnZ鄌bPMß^"԰ZpH^do+e'+PE@bIn_6Znw̻-7tVol&:wp$HDᨠ=]9N nҎIA b, @u!L~"_-I_X@Wl6vl;˚z~#19S:4m-@z/x%X];}W}S*\am鄤 H-Q|>F&tt-*$}^j+IŊޖ~ɀB"%@?UdoQ6񉯏,s s#['@9[8e0vM%bF=_?@3}'ل2 Rl)Ё\^׸&v^}W-j~d'2K%Fr%1*i8}c`D4>^T5jP@N]9D ,#[v'13J`4xqV>숪?9:dހ =:?K\+ kyj7agdL . "YΏ8﹗`x`4' M"ʰeXa*l\>DFX~V1_^ecfT) ˉ;rUSy,7[Hp}=VHaV6!w*JE4!돃.j 8SyT|gg^yb1زq>,9qR2xl)NGrxs>ʸ|֯X*oҖL>lۃ]~hcv?PT֔"a%ɿ;q/Ь?1qD1 'B_) mTsB2U u_ I0S 1=dA6Dy?F[Cׂ^l J=%TġeRi8k )c/m{ /Ů43zMfQo^#!UՁ|<A)ir t Wʹ$ί@.=x.K58͈ult!Db4 aȿk{Jh^OPoniƀ)%,Z⟒08<)w&P8|S*uyMV4bdoﲍϿĵCV6 [We Kɒh>%,l\1(<:,җ_XqDAUi8`إApdyidu4;6DUc-w9VY80dJ3G9vhac>֪bO42i^*˘[lhF0 :am yw-7fUꔠ|]Uu cX*2K)*΋j)fFsgsQ z!={uI_TEeq֦2/7s/[=J%{{rR@/j55ҁb9tcH)+Ey̐b]RQ5%y'"sM>[t[S ^:1,)C0^mt[h2SRf2CbT?H/؎BHۄ:}Y0Xv1.9OvW Ax=б3JcA>nMY 1MܺA e':o_sGJQ^*&O>zsn0Q?Qмc`Tn<6"UeL 2Y Oh~7|" o\a<6Dy5˕YvZGDjC>"$;(+ Qij=`Kb50禝E# cL`~0TA1/W>V+ab:j6Q7;&*#Wk!ݥ |kBZj ڎؖm6-=.QlL;fuUaW<|`k8 e'z{RȨ&s<2?i+>ǂ ֟15:$|ra>4^YyU ?>)'7T/RNOmvY0+_UD*sI١b Dl.?[*^Td_J4!!7-)n[ǘ t-KIXzP**ꁾFH/^Vh&k^@uoN7JN*aV3m_)Ōf^Yq_(䇬ӼoE SUڣVj`0v'yT¤MWxư+0>hg ((T}ݵ^k@d ^`[v3<'؃]M! J@-=N4xߵOG:i:n\nN`| ;>2!kXveK.L QCdK:zYFCu?G;JC,%O2@ grf4P>6Yc NN_N@*C5>S{/L#N? ^ĕ'/ [T* H> 2Cv 8֓lWGNpl?m.I'85O 35~ȆldIrHid/:/\ZY͗wgwՖ:B& cXaNP(4B]|6X|}hvi' (Fooڋdadv|1>d &䚈"NBdxC6IƏܢWЁM>?AW9@[&˨ꑟw6h_0.1`0O^>C(76R0h=VܵK{![lY'o@º*WVbAM0W#$.{Ra4'la^#RLtC+ݹg1oo$r~-ۗ uku3 mk q뱼ς}Y+<* mtzB]h"_~Vsb1ۂ݁P;+[h-/$ꔄ] Ea~ dG@slEezi R|yas7u" ƃ è! 3U\D@ڰxI3G"R*8kS$w"3ؓq\\ .ght2"oq.H.p@ש l p֗yP_/=P0\Y)v([(JreI(y5,N2ZU3cZ,wEjLIi7~nfԄ #Ne, ~K{pR_yGEnĞ*:)bY+c wx:ps$B:7_;}#qgX 9Ib?IM2̆x=֚0:.T!evz˲Cjˉ$;[`bԝ$jwGڰ1j;7 ԝ-HN-}^1 {[=#8^aO]bVkQ1~BhZ ")`T;MiÓ^vrdű^]|lbB+S{])K;!l^e՚3U$ؕ4?[s5/i B[ pbX>~<Ǭ_>{˧Bc[Ψ! ;_ )Vzr^JCg76aa 'o9`I#e{9K`F-JɄw:bAIe)} 1s-\b|*XBҝ0fȶz:SL_´ 5RRJ~]2rE_ҰUT+Ye~MS([[}9+Cj!:IUƻ4޲#:Ƅcڧa3kyBx$sS۸(aYPD{Шp?]`;|I\:>8N g+j7<'a@C,aH{L/O'*~}džk\(F [lBS[BLT^$}`U #Z;9cvuxW*f\VpcR°+IMOiQ':9icC,a6 U#$*A?]h -,ekt)ېj BwZ6!=e]Fg|/׀_NE-險7s㖒ZdK ~}o\ 7ΨDXG[T/_ZҙnHU67q~?;Vtx]4*,. ZDձɤOHQz<[0ԠHgn "<}LQLi- ۇ-sr鵪v[أDA=u"h:B  _r NnSeOW6]iчΙ*f,J?ևv|Un [z3567ʖݞf=&Dah@[3wvۗ1y ߺD|6{gi,^y{7pIٲz4N?< 7Sa) cT.hicӎW:I.{K>N7CpFn>N#@ f0qMPkӤmD'N(M.0Zo&2_ :_~zld 뎶^h1GSqOW L}d<i!8-TTKfZ£ov`g,,<)/T םԡ?DMQWw6M9[@º؆E/s7!1HN(TOڡC'~nV}#y30<bUuLCPK DzCPXDPIm5sP0`wg8ulZ"-LHE7jԿg|er>7xxq*EXCpƌD8A skz젠؎ˬV/( OK4cZ}r4F/(Uqfͣߍpb!Ϗ݄e<O y\EmΦFd9y0Zd4W";pijHN+X>!ryN[6!vJ(62(6DQ%յ_/H1@8ևߣ.\A@0jZB̦R6h)ހr-/b2LVF{eGQ1Ql,&OZzW(B$b{6]4ŕُ m Q0VGF1b!eʯ nrD;%9NldqR4Áɘb9tIv`{tGy$qF/hEH[߻`>PZwy̺'oG*̪,r g1q$^$z(- HgROp ּꁋ, Qg :Mr-_yyI;gqp"6/*UmucЏpd*%_b#,c9( /DehR/\'GM\n x};fCtbb MkԂ6قw)wv( Ŗ?$`G`F%xu+_{qNl JpsOvH!yLB&RO/ RN@vU P$ֹ)"妰,}TymqELOY%3d16R_ 5mtX,hU%V s~(3tkׯh≽Ed1ʒ nW{T?3#@hIW-'HU%7 ϙTE~KzݧuTBv@4fCvL;IjCL/b1e}\#=f k6 u~O{r}1!Vg#eTfyʮ(^ O!*WpnX^>M7XS;;R:{AYNHiĐ} -|N#O#;&gpyx% КEvyV+p4EB QQAp4WT,ρn*`ѹT!&ʳ̫Hꑜ^^~`l$WM8Z>DPyt(;о HbKb޷H.\8u R8ַlRzʑaʊAz%MDև9`eWEt^Û"~AEȎXG&v˂l^ȟsVݤRmbK{h#ö>QAA9@pɰka6*3t7z^3qCNh|# MKxF٦*ꔄgRkD/t茣unނer8% SBx%5|;"1L`5ېLשlI4Ɔ'^Oo3SÐ6..6Z0 mR^D͢H R|kt;Uke/VR'E4e*HO[=QCkqV9;D<Z2} c d$#ǯF^ox">GkpЩiẊzꀻpCqա5EY, .IO;PpU6,tDOدV;E _ -yFrpd0~T~nB!83xasip`eH Npй,%~19ԨxF8#Wjp[R# CGf_(a\7 Tw:UJm4S2nD-[Ɠ~AN:0` a)f!$msF"ˌjWH m@"J} nz^{ sD`Cy7Ƀ.o,n6픱U1𯩽Xh]):HҙX_Ii65O`RL>n'\^5)ӝDڅ*p!n)del(! !Q`}{G{A:/VR&AìĦd~Н{ n =-Hk<7ĿUŨk;;6d!X< 'qJ ߒNyh`7mD5)}绔J#FmN&]]H_v`L^[/4̉QLs ]d?ǝ.@!G ]rO=^ؾ|Gf7p}f-| ==I>eFύ9!ojFQc#UHjIG!NhÔgk˹츙ꬾzƃJ -i%v͡d% 9iWmNi}[|r=̳r{PMvЕj֣\=.6q_L5ﲇy\$Zj?B$!*ʰvHXVJCT H `~x,KI-Sqݝ#V;lf08^AoҀKI$ pQs{ôA1_G],1@e6Zj iuXvh̓8rA|GsC%*QRyoF>,? ١bwB8ܷzsܸXWgіV(귔2I&M@<[#Zŷk\_C_sG3Sؤ6[ʥ _w6{0pZ`dj߅G(3s 4bg4]>}[#߉ vD.H.̜ϢY,<0")Jl[r#ڈdTľ\4 p s}JC`f챷T6PFg:ҞTk/Ҵ{;\n"./H"-[EL} aXygM>Y'ڴJgohNKi3ߴӵ?aȠ qGyv;XĭRx>"db*MCQu4de^~rP4"?L5(dYH#,Qg$~oR K|/E8=L%ʿQ} .P?]dt! ybQH|0ϛ]JȢA$Lf(q?|^i[G=4F,S`\ l(gD{w?r;1CĽL3Tncp[ K !'p3O fe8X{H,ZY:u%.5@X0gVFQg]2neǑ9 ('=?Sƌ0D$E("^rKV G`MlC_n^P"JL>öftf͠ol qzWtPB}h7ᛜTG\#ćkȧz4Q$3:T(: K)Lƒ mTFq >B[Fʋ94Aq7+e3 "g)QEctst,ѮJm?RMm$9ˁ]%*J0/d.c=a[͌ AT/lLbi ;bJY%v]˘rg2Ķ(QwCwO=VvX Di㛾Kj\ y9d̒'ޜ+F\shkeWN{ek9;#ev䏦|yGuؓY%Iu$eBV(*@(Я5 iW07l8*;rXoa d&ΖH ,;ҍ=q YmBwϵZ;̷7Y^ҙfZxU&ZN{c(E~ݷ7c ügv= .S*vCDva=}T gS> XN |V@VC֊U+`qwb]&uP *F.-Dż3( FwBa9zrܣii6_K7 gbGo<I`L4C xN#dY d xxdpL <:mH:rěLv[慸.XN5ʢh)4&NI1 rhz9{9}WY>`u 54g= , ٖI]G\j.0PT9/4 m>I Y,P8C7433aP3K\n䍒F. )tq΅* GB/QcDɡfY@i.Fm S1*,4*qp]$'Gbr˸Ӂ.eo@- k.JEka0lv2x9g3m(nzv֍U\|^+V?z.e#0[>d]V$\$(L|NzP!lS`4gM!7=4l/䣐>]e"1%Q/IP7vd2t9oOS͎RTsvAjY%^ 4E2 •oI]1{m96`1m۶mwm۶m۶m۶m;ekg~ĽIat슯Ae!A3z'uiЅ}N]!U6Hpu 3X ]JVHȃl__ \k/$9]oD@w@y12ZloFN%}RQkF$YgkM7O K_D<{7̡z.%b#x<= nqlJܑҔ)ꑐ橑JmPD=zϽ;8{>1&2C"h{l#2cS"uH6Ŝ'Ǫs`-q6IXQBΉs+{NݵχǗܫ<}Cx} FgEeg/ϑ[+9"qvFYl(N Lc8K2+tx> K& cjKn$3ъ%^R4teOЎyCj|D\r O'}`2Gf@m.?yUO,.iGRޯHY X1sP& PXP/i$˥B/At'F:}G"Xw+k e;uƇr(ܰ޷wRy^$(t ԟiH&D`9 uff,@Q-4$G(Ϫ0Bށ)VnVH)5F^DVq5@5'jD-gQt+U,"ͪ94 s?CIBs{.Ym:Sͷ1#\h&aXo*r6|ivl߄?dx]h4'!5ȪczC;= kk_׸?o[45D vYtl{6`NNm Z>1`?6<.52 |bwsf[yh3A9i }+_~4" FL"B†t:t׃j;nTǰW[R [yh?N-X6qLW\[ѦI>X;b?8&$mIo+E),k[FʅIҜqHqC@v]^U5aSlV2V?ғ J&,\P8_o4=<1TG|棎nw\&fi_O.\c%]eDŽsRPdoo!l<^ Tk.W;\6+d-@O/-@GCYSĮ4V0ïv{e9)Eo ^ lCK6P&µh+h~ވbRf:Utg/u2Uey)賈UQ!iV+F{Ԙ3_BoV?cO@2>ky2dɆz~Υ͉T ="D4$\Ëx% t:!DDgf퐺Rdfρ#4nŽaDDoz59o*R+l겲"P{x9Jy@Ōe,|\2jfXM*F9'BybÞO ֛YWq>b((EzJ;m،j<]/4MOigʕ4YtD',ok 1onet~٣{OqklrC4uHBCM-\GV]^<ʤGl?pNMVA*O%yNM ^T7D2Tc_nP51}J[7#:z2+ET]%c | ]5Hg+/jm #a=`˔B?$>}"~MOR8xl6"b2pIoMW3Y 3Tש+=j%f!ZinωCJ"h;Mn_[&$^NMс:H9`lZ{&D!!OvsghvߨJh!|MoI oFۙ>86֋Їfr 蚩 q@Mh!ކ;3SKmaģ ޝJ ^DUw{:X}>*t ־\]Ox* ʖջZb6fPaS Ibz1[|*z&2s!b$.eípQFPt+\tU'N#I62gU3X x,tʜvfP|>iZƌ˗9>f~Uޢx@ؕ2,Lt ΁Ҁ թˉE1cu3!ZVg 23Y,?L( 5S;JгbMQ1%pIC bKf08,qǔH&QOsFqÜf+; }{|NV=75Oʗ/UHvЁ*o#ytR#lKd)⦭[9ǴEgO!&<)Li&UZ]QÜc!8?*UZP.R4;>2ܪy^'9=8Kb}6s 6$sGB}X ^hD5G54|atKCGM,g6-̈@Ġf`v-=(6$[\C`/vF&ZwxgxV$=wfRK. vm㣍+L5B-,NyżIlHKĠX` ,|LAq^&;(G3)څ;c-,4ιI}S чŧ!>﨟?RN)a?O$b>!zܩ{UKs<>Dߛ M{t{Aj?~)Drzsz!kȠAg%.>mbŚCIdZwCl`x)@S X]y=u [+әs/Xad(Po2IELjlq-F9ϱNhpBNv..trVZVa*0=I9LH(-: ]:W Ε7MN54$$ _'WΜjA1  35@?W[!\-($ru_7ICx͡y!yLNWе0xc+x_'k7]&;ߥ ?cc3\7' fOJVvhHnFLl3(WZ03}cΩFaߛ6 U/kC l&ƺ+}ӽSYVBB}v?yj4TbMc|e;QN ڝGlXFC_l&yW2Ot3k?r6i&MiA+V_ڸcL-=zRWxxp7e~ ;$ȝo;Zd#kU"I$h)H>3膳x׳1a IGl=͙G=KUyaPk8C] fCG1#j(|0=`L\1V@W~PsLu p/ ˓B+.e0 x-4-^AMp#z2HiEd'Xb~%1P%;^ԑI:C4'_ R+DX+1r\8mU )9l#.{ODz>g) 3&>E(EƓ〻) X7@(P:͕D EgxQлџ{mBUJSsP%O7bEWDGBti? X.GO20Ԗ{pEfEP#O,> ׈9>&]DQLιT<:Fk PݖBxTNƮ}5 vJATv'w_$38`ڼen?`{^DT.wPv3&^K(Qso+mMT-ү=RsyR>Gs06[6 $~ċPgK=MOGgwX0$Y3TX"B=c-UqMvWr HCہ<3VK,|"NqjG켽;bUP^3䙼[g%NLr)СFѰ6( SWdҜ0R'2^]]IdJƞ{݆];bxeib(DCpyՕZ R+0ӓ\Wz6 ˵z\j5FWk,bhxgyO Ї؀cOj+Y{ c.}S`֎t; ԱDA8"g.g9wrgCj.*h>{(E㶒57jbjq&jo]󦐒y-oGصZDl(.}pBPj=E,,h4W\=hbP_Z̸dQ1Iѳ]3 |!afl o@le6&tN8m\JRמ0s@ DD~5 Y/Q|-%;ݐDd!Vp?'jա,lXي`}G9Κ?շZ`$0;hPpl~l(h%+ZZ21f]|3pdq(0 @:\$C@/uA^)#jf* F,Uf-PJ1b1bws|_< JE-s%_}>4:gGL=47uRxvGɁ/LC'i Guao_8sLd : `ۣA89ldw^j4h Z0x<ػKpxJx{)4ȩmyĸ Շܐdt͸WV,/ʵu]? i-^'iq%<;yRGpս:.Rq 5 `[{*}ާH\ Yp0t4v(ROXVbwMj}ephrp7R珹v1&LڂF*e醗!\7DF|;O%j^K>ؒ9N#\}+c&tB'GsЧA#?١>v>mf@6{f:|u|Ok76M$[AAa½N¢rCuI0'ϫY H@I*!ùǒuy?CZL0\8a9EZ:*^av-a.u3;mGu'}ŐN' Udk[w&pee_2ڿ^\D,M00<_{{O>~Xp< 4Y\-8a]r0pq$xnXX+qY7 5ЀȷlD*KTdJ3{:hl4ۛF袒 v^}d'y.2AbppoP 8(ȟb"~R4xsS`6r".mWfq!I׏GgUzIu:զ\ϰ&,~iD>YQ9oo֜I/"ѾѬeJ<|pEkazk,d vSXw oZ|JVrVWkpߞ&'!zi3i[MV5NOP$s{Bp0'vy3V%?cKE,S rKEOn%;_Y{aM:>9t€oܥUI&_Ҹ\,}Yix(*qVnⶾp?Sm(RnZ: ڲjOY$T;%Ѻ"}s_a0VP4LϿ[zrS0la YBiNS2TߣYILH,@mohO|Xtw#2AxXswn-p=w|q?LxO_)T*/H&2Ķ2 %]tKJ'HFf⳶9-HO߸=^EjLj1u3m'>hYM@EboR,2T9fSȵuP'_pW:Qg&RX㞣d-c䪽oEX'ij?%⧓}qH-^F訧\|Kf@(vIQȁߠ,"{ 0Š%t91̖8ӆl#hZqh/]%@^KO-aH"Sɭ0eNbsL G8YsD2u ͯ$,;oQVx=ro"ȵ#*Ք`!Xȩ(d6OP*enO zN i҄LprE!TL@խdaā8; ~&,\ )hp=nVD|,BLx:3a41|N$#㜹M`k|/ Ҩ-Ý;Մ7 .Se$J,vWíS>]D͈: GGa ž5WS,Yj{XL(m=]L_"JAYcRZ3; {NT#Nis}>PGENUZIP֐^.~P .pO\Y8Ԁ2 ҳBM .r:>ˮ3vXЕ}6zɬ5uhMCR=ysD|X!`od e7O"ջl^:N@[ܵ4Vc[5U[jyjX`- ٗTh?MCdNR{u|{k&F5qX/#鲭sZۯ%Gta7< c_FvGL :F}9b~Zlv埬jl7J.=^E3GaV~zE7WHAm|妤܉wl)DPv(GrY-ik#b;ĐNMqӳxem}WruU~ɜnG8w%uo%B +pԿ̔#]`Qe-ߠ&˟7G0_pƼ%s7o~NRc^XH}0 ABpU7y2!TMU7Ѵǎ/$F?x%Bk6:8J/kN]m[g\V äardcMl#V\y2ld|ׇpU<p"zz= h4"m*p*BsM 1Q(.GRxțDԽ.,>.H!"Zб3 :d'<,R8Miޚ2 Z:d.~b u/؟ƒ3ƟYD`bgY<"霬1-׃q+K{='꼓޻,H7ۃ9EB>:53 aMڎm3>~͐&W{!ɫH-F猑)%'LW/!S 3J8DսH/) ;Zf Q=QvyLk+F"M'Z+H]JRrL/ٓ7,~U:MqД<t BH<+8ԞC8etۜC|uJrkLT_m3{8`}+W95wv50' I@#8Tc n_C&}pEz<-L3Bq-{RjϗF&sMC*;Š |Bpa֦1W"M hc3õK#P+C-+3hAAQjce {srXlJ ikBNl7aSh]O0R)7oM>3g 4&]r nȗhG.b0䐅YB_/Oxp^8[̇.ԃx_9Ӭuw!Ss"B rVTXF!&8duyb}lz_^E't%9z[Vћ8D'Vu 搩 L.zCj ךm Wen2FU=CQ|% H֔lZh#%,V&wLnUv|&3L $Q}k-ƅ<~j=!PjP2Dss(#?Ƕ6#({9xFX"‡ljb>O}l_QŊ4W'[\ l,rw)R= af0_vog8DW@|dAWU̽!BȖw='2,@/N55?n2XKD)2ѥhWfK SCLɦHgLofsmbu颶8WC/L>[MmOLM؇c-ź~IG0RoJ_^'aSQ[8?Ay EGpާ^&d<`"7VԧpćDϖ.vpf<ٿq hhxꛌXҸF(ӣQ38[6'@ Ȟ=6ۭgÁJ4WR8Wk߁>{r - YRjږy(q[ euȧ䗶nmǖq+b>6I%GSHÛpJ龳ּb ,OMydDmDļpҳ|јKKL L?>}Ù&8=H$OWDe} PSqf<ωv]4DO|X:ҋ"_KU۔2HIL(aE3fԩai֋Kk'X>,&W"]i#NȶJj['G# <{p*|;7tMBpN\0-Sʭ6|eP%C)51Nt2.LRe芑+p*\-vI`y8`7aޕl\#ߥuC s2l.u>ٯ )23מ1D2OQ !>spg|1K edzs)#wm]q: y7wK5 y煇JsLY7}.:r)kA&}L`QH8Vʶ˳,:eΞ Q%B+Խ5R7O%bZ93瓩KwbSSRi_u ',"mԏ"yvV o*F qy.aЄ=ﱤu~0uv CTy',AZsVW([flWJ7bۆFP}j(團PAV)^ώ9DZ+"yMFB%\ "@,oXD:8*x[M>cR'xȢA$B]M$/G>?>^W~03;DRPQ,.Zqq3k _ä0 פM0է⫉ щ#W㛫7nRS;7X@ fn8}_PRn'[Ķmӏ}5nmhvuyD6xNe|~o-*ʭ>CdV]Y2_;3WQʸ|^K9cdؘ>Y]mӆEl>Y^V, V\YÄkH|D\dNUY.%h1Th{֛#8&*6]r%v)؎HCu;?R,YFf쀘 k`ӵOaioWmED ^P|FYaS+[ڙDQ‚0.$Fo{e0ڧG/Jӊp8}}`yx8MӅύ+5 =q\2a&Y8 +hq f0@R}w7XאBdaSؘ3Nա8g-w %)/ut= =/Ix#4wtBRd rȊgܝL@)6+:A67QF\1vHS4]J(?E[ڤ(m+ 2+uMV7nw]3g 9ZhZQ/s<(<  ʗsR]YzY oQ$L({dRuN"+B~3ReWI8'|8DRe'lI8`ç$d|&,4(Ob”,Hfl ȧQs'Kfvd_7VpK~O&H$X^ulY625*,J纂7am pfnX lTX乨irDVub~+;I8SE]QM&†\Ґ]ϐ\% ˀ.pϒeoh+% {h[aHP+t-:F9WidTsNH0vѳra3uV^,mK6RIN K8|L  endstream endobj 109 0 obj << /Length1 725 /Length2 28490 /Length3 0 /Length 29034 /Filter /FlateDecode >> stream xlzSnͲm۶k۶m۶ڶm۶ZնscGܘ/#FʇUEF$`hDD PWUebb0ҳ8Z9؋q4L*f&f3## @@iBonkdjeg Pwup2𺻻 ;3H ji05((jIK(%ffFE7c[+```oj/N.&`n1sg;*@LAU`do g ?f&Zko?= `lfae/ݤM'!(ѐ `jfOR `jlV jdgeMRF!do|\ĭť:v& 蚸9;ٻ[jdfif`bV'V<_N3?kF:wl5bijpxsS?h̷{W꾕( t Q k)I_R[c5:M-Ҽehѵ:HxA. eQeava㕵I|ll0 +=-Cݧ"^9|[nȜOj^'>֪n9Y ] Y 1b vACq= eWYMA)5 jJD- 莨k糢wl>ۿdE`'p"aIp,@ A7f1\ݭ.l"V,Y-q>BlBɫM`d tkȒ 4igUc5)|LRM/ld5U}^2脾a ߧB\]w߽/B`+J69!cw&ʕU `\gz/7bBĈݗ*s;I'Mi=>,qGb`EV4c=PoJ9(%8r={r-P}duɣQ.T~[ ǖCQ`_ ~F,р@V(kZy'Isdzs9PsOgo-WrmyeaEm> }{/Aur~PL6: xs۝nY;ݭ7ғLkQVw߳C9>N92zf2PM\"̊|5&jw|&!vʐ?KGŷ@̇IX7%H@.C2`Wg٩Y0U.R {d su|‘-M7m#lAA k6.q^QRe^iӗA>ddHn*I*v6`dZv {xdSaK̖L{Դhq`8}# j#*sq Ng OǺi#AUP$Uw(laK&g,4hr%J? mAp0p*sa$CW5^Wnn nX1DuX5)6[|Y["2c֢ $•nZ_{cEDSNTMPd0ba@QrPĕv=Ơ'{d7ӊ)2e8R$Xpt5Ƞ'S}7-AY#$\zs?Yӏs ξ=>OgsWhsabm):~KIn/ͅ:M8?γ9~K9{a1u@S8|o5ʄ5µs<|.|tTj3'G5")#vbPsQ"d? :#H.5ZaKBǂ NnV[]P0r W =AsnΡ% @Z;M u'ff$o2XX5õde_8E=QՁ&SB{z\\ ݟtP'h3|ژ4u\b.+"2kI)J2׈/YT%ÊBKĚF̀lH@@7n$W9ň4EjMHE%w GѕYoMރER)ևx|GW@3%UsULYV %QȂٓB5?˥iۀ)b*Vhr! OpD$;~ 4~lFWi=>/"eWZz.fu}t]CyTTձZ! )sI6NI?0X8z"  l^ |xMzLPJ?ÞY`dZд{e$i=P(baf?QvMoVuNLk,~c:?}X=KICp@]wdkA8NkHrԾHsH|LI Y YLvAfAK]nIB`C;o%`By{iC!Q.n!7'D27)DCd<M`~݊> +ߟ)*nGj܅V*rZyw1L#hc tnU6& 1GXQJ V->z&7Yep>$VwJBuyf?:ne ome,'UBTB*/u` B(U`a$]{4+~ĒC#KnE`U??Z6>Rȧ8h/{ZttTQ ‚9\8u{gxa넓]OmvTw԰qަ QTi+d M\ |J71!#Au%M:[ 4 YYq'D K^N9r *jmo|bg2XwӇ/45RML]kuρUk&Nҥ¶6A~P 젌 (61IϤGyWRrدE&Vsf N%Iz÷l^r6o1bC>`64[IZZ`Ctێy窸;[+(xKݾ)8ke8 n sk3!]FrYcb4dw& ja4FS9M۴؆ SSv YZpSB(蘪ZXX}C(;~5W2P#+a9>E`j$ѴY eIs,s۴N26/tXދa`S$A#ro3\cDzQ!ҪCÂ|RjK)C c//ߜdsZ`./{ B|@t뻡Σ[gQ@vȁZڰp-Vqt@A} 1d~ "˄9͇ e@M>;OFR}5΢L}ɂI>vVH5Q׭[/ ZⲘK+r<:)SC\jaO9ck\nᝆ"xWKMasC=A>Z$<ȄSEGAP=#% qEN#qm޺moh0CoMkѮp'b(N[u%J>{"~aKp/- ހeVq݌4󶼇Vܖ(d UשGExH U9Ąv!8% ~F9HE`(jʮhT0 obfЂ[Y 1C=$Wиk"a^Úr)K+:S$ŭOA[4^Ibn p)GÆ1;Ĥ߰gXV&L>H^ ΊOTU1yoՐ}Oͱ!-Z-SՈgVhƀss<1ڋ:o֒qS`=|hGڪ7G!YZ&UT)=[^E*>' BGV@.eҦUI1_y'I牭x gA>vilQRf#sDNC}l2ִ 6ӵ}MaYa~ϦZQwedv OWW6I*%Gk\tީV m{r/JP^^^v̇;d[(\_L%[F&r;Q 36+1h"2=Hydէ֨g; wRXC<.H\}lyaKNhЖ1lׁm زj*]A7zsv& ~s*}ܨ}) S]uyvV"0vr0`T_+\=zi}W7ՠу[T`MWrO0Ǐu'ѯ=^愹k/bOؠ0Q¤$R$qXmksxfc00X8+ ڼGe ;4K(đ4huP@.۞qf@ |<O_K-oK-nPtqˆzq+*mXؠ^AWGl L- 'ۈ"`g&HHP{Fn~% rxVҽcy%´&DPX!۞bfFBKggg \{xp)C:v+CvI2=MݑOǺkDn\X!z_]Y>Qz1 dy Y>=Zl-p1Nvp[<|5U3|DZOA0Z5)X$L>)jJCa,O,/KĒBioŞ҃W=)YU @ֿy A>5cq~Zc5JLN"з!s=0êvueIc93׌zLo!PK\B:<7L=`k,?U ܹ*e2Q ik{_fuEg";m}Tb4wGɵVv eC~ͬgw {U=S^ZJݙY:@|5l#q$QXm4\3K0uN'>\5:arw䪌^ȸ>szW.>*ڬZR] &1ZYv~zTrZw)J͇ 0OPpОnV4fqE6 W ;@P.KTԉBXEUaN+bg]V@Z$MBe& טQ!]?T[ ؅ā%u'QL@[j#"KXYTMjpȠ`^e#@͚:ۑP`se$oJNAWS\yzjGSdDt?wo9QH&JDHi[ϚvoU?qqb+j~'dz{TR4b 5( { s/B}xpZފ|dL/:KF?Xϸ 3b FG`u>F ѷc p&RvM*IQ8lDR @_an|C"y{>(':$Wq3ҦCc>8gu0&< !MTieO =;)K7v՞F֚ @!;`H$"7=NzcjJ^-4p]2-z "1YJD 7~K=z8vD /w5>̯gp.s;&,y#@׃0_%OC1z3f7o|@>T!1fJ8EOSK.%X`^3L2zՉ'FQ)yh az_0nBށn6e Z햵ey: jD1p]_[g -+hП;+/Iݓ(Pa/id; ۘ_h&*"$L q A^ ShV1E!h[ZU%/HۭKR,Χev"XEZ Fai$/%Q5eJ^ZtB iY'Xc#']IH,$;MBe`ݞ2er[;k: N{Q_ @W F+Ȗe< Jfuw26n7uěF (:^ny_ QU bc6ʮXǒn@fq^LA.*_7LԂ#_.yIfqb`+ -в̈@y++FF΂&H?V{|_`OCͯKap,s k~+Sd<ΦR.? m5G1ӽq<^>$3_Jv ,Pp9]!տ|]SMI|;+{<)9afEq՝g|KstRK丼fkcm|A^ pMXcS=XiBPLW4BoZQm-}']r=CbN3,~ hяр[Noz|cYOE*ؠRQ̞@dѯ dDɽJd%e2aaRޖЄ揅hΣ (AZiUlr`LG>5+iq QF; ^+k3&@QɁ+έsg/ltWx?6&ȭD7s쇾W/[Qa>(Rt)ŴZO9Q,Vy_,4}﵇;z&sf3iKϤ!Tz?jF ZkRFuQ0۴\B F*.Py.Kt#mzw (t˼7Jќ[JT<j[NyCP'oI5wc2@k>~b``fV[syV~e o6M3NEnzk܄: Ғ #k'MPyp}^E."x=ɀBcROT>Y{]f @[D7"1qKs٭#;4mvj˽͛vށ !G63%0OqPigvNe~`^/u b!8َ@e)ՀrXf~BͭvnkG?o痌'υFZuBʗyq0)Xn,pLWq!ff^qV6sx=y74"lzYsr:5vU'kp9&{~4v1 S}J\9&tؚ%46KJ|I^[Y `\WRhElr$t 5#+ŋ)&щ=ݭ`/"5{tc\r8v%؏(.5قvUCܘ KvBU Yb%t N lF/U-3#J_R5+Ÿw r,iLE4;7]06dq3| 7J*0<'w}89m# EFMix㎶8CLIM\#tI?^KyѪ~JK=EW~WS||)?@i}aόMT|X&=\mo%^~c>M1B9/XyϠC5ULvW˩&L|Fd-Ѷz4Ԛ䡽eJ+`a{2ghpX)%7d,Ϗ֝P]BOdN~2V7 cjH w;NuL=T,zW^sZ$EzA12kZ/U+`k yŹBn Ɛ[56Y8r-4IW5mo5f2G#,s]|#:vw=oT91 {p@ޯp&M?foC/ Vٗ3ZG}2`niT оiHtdɹ25d󻸮e&8*VY=)T7eM~Ee>NHEw<-]o 4S9H &tQ 1Wn@,T#C~{t+9Λңc>6͔"{­37'EdU':^%9c8|5\//JA.d^KxƦ3B3ڞMy%8"jўWLH%MJNGBhU&TH΅$;'视+T3Jʩn(TRlJ Qc@P-LQ,^874&jB] gC;x#Mk2ϩ4 "6Br/ <2\Oڸ%r;Qu YA?{gs5n@]Et[Nu)XȒ .CAIr_NϷNirЏh E}Pli>yK f{wWu\7?iq%k^C_ P #ߚl.r- ;yelɃy`JfX bkWuFR E]N%XBYc*oZkB`EԦDb1xQ,a ᮹6u)"pH?sM2QJtajE*?jOgo[͙P_ƫ?Rc)"  JhE,%k큓XLԥ7T ܈ 𕂘RdHxCW}<]J;Vq[#+]ئܫȷ0x >#\-65E1o>B[ٸhA҂[Wp〈W|P$M]n&R }MeF?1i\V(\D06$f="f~EkTX{bSpJ] ðwmYWX>vB4~2ײ4' !͆[}RW GmiѨei>҃K]HnH> KSmfKjK(,ÐFQ1UN0]q>0u t)F֑lTbQ| IV udDkcӣDnĔ|3KrůU䤸JA 9jus?ifHH@XY 0s 'hlp;3'ڎ+ǥ=/|f,Nles1䄝ӟ n l(ֲmMR \q84 bn6ln c9T1Ѕ'6P6W޹(6TVƛڋ(I7/  .lmn|wAgEmG]5z\8c[Ww@ʷ+"BCi4b _]",& եGU$JL{HɂI9~XŒg`42 /)Q `T6t"E? >A۔E9g@[EMmUTԼ-r.2ʝ'gٱy.\F=VabTI'j^ɶnxlϊ$;ӌ:q\&`E9ɮ\b#YC}ǛE# B<5Ї/|,N-0 jnI/׏EhePLeYj.U0P2BңŚ V@sLjcZq,m]CNL~ٗh>/Yz)͸jiYXpUA13/iNd)+bMCXƛK wI3\>ZngZ@o=)BBwV4]oO0Dwd00 kFqpѓ.ʵW-}5;T@tc\:U%Dmv%-3Wo7EX/Rҟ0u(@A@l u­@QAcuwB' /;&1Pa9MC2L/ {zO w6{h8!wl)6YqRk0 YxYNgm$.Vs!ϥ-ya`{$̆$Z8^*u Z;2MX @̈́OcP@ϞFXc3z_eZe7+dq~fVW^l1+0Nmf9PNyӯ= J]<$31D_Ð$Ai!G<otߠ1,[N^ /~kUʔɑѽ dr9CO8T+6izܘ{ ]PČɹj!MѺQmUl2?цa\Ke-{H_l2C$zXEFiSwkiSLQĉ=S8;|Sټ+ w^?cX+ 2*9CN.D:@ٗdž\{u>l4&Uש^4m>}ri/ãՈ8Y*QDiLQ j"pXnL)1WU'yƭRac Hu .P1UH)'ԶIi6mIc{#t'_K!Ё%O |dBҔF„]tv#1EVŨEH@v9ZX6sQUI>o\ -B5 7(;=/3U;l1s>mNgFĭ6YD/)%@[y|qz+ل8D{`"p&X4ﶿr&^+N8?Ŀ99O84!}~\ҷkHm(^G ؕw h:Qjj=9ȍH6Aw%Zǥ%́ J8~5a0xVK}~E`Њr/OjÉ+>f\gD^_p71ΎP,(֔9mѴb2{5L0~0+dK(1$ j]. cfL&u^Mj$1%|0H0.NJ=eeˌzhAI0;=ňymu++U`[sІ0V5-̌I+o5eKd$(z̔2aa$[[[!~w h7(rreS]flgdO/58qmTzU-v!AQɭ }OB`*Iz9Bzt׵ɁI#{0B$HW{׮a~bɹ:{3^t-k%r>yW&dJ!bKGov 5XJtDW(Tp_i>r!=kMgKfܛ`/j\& e4y-o|Zȹr8 1Qm:6+!TfGai&~ fw(13e< Ԃ\oQ ~ݪ;ideꜿDe ^0)G(ck^/ə1o-qAeOՂ!nN٢1!zoaA:RCkVӠ&OpkG7K^wT{}R/d%h'n/s|iB,y]) \HtjN5>-JA{f fx{*S?sGG3 "p2ʴgT:lCdL|H H6φ*acfqNQ]\4+] Ʈ>\QJ0l1T'pV$=bd,cQ@u;n;Ќܜ{# uiG'b͆Xlńw,grz#s)Piܷzj{@WфiBTXa[! U38d ]1,v"'g"o~e[2pUϡ䖾hH`4ld 5n;% Χ?a ǰ$Sx@$IcYb@yc83t('ua 8A|Z %{^Fp8|Sj%`p߹= 4`o8 ,uv_[_B >Z3WzGtE?IjfŒA*vc19{ʽ} 8ksܑLq~ONetąb^uF%AO8/=@P.m=WJ+" Q1esgO3Kyޠrf´ε7PV) ^ܗ"YSr 5Rb/_tO[.QLOx^" aC 1X5B\b4qHn.P*N;;\'5Q)Ӗl;:ӫ[q8"Gyʩ^qI(ش 򒴵a_iQZH,Gq.6quu)`9s,]p46f30& rfs~˗Ek/}D0Z{~+ZQ@gE,]G(f2q1+>Z,B$<ڭ 'i+V6>C!& 63/KQ^J/>@ۮoh~Bƒ9Zd֐?(dGy[k)~6 ʢ܍wO(F쪘#g N ymgQ!1$@Z ˤb՛ʫ$3怫K_mbiko[AJ@)ݸ`x4M9޼ Z4kЪgA% /Q6?+(K|,vn]. :Hfz&7o T6aʹTzh=L)ҒygPW{n y|Otz8&p)^e=Y\Sò kֻ4S0ep̌4 pJuVt{RqxN )Dوd^n1r$m5Ӹs筸Ooqȭc*EP! !DX{2~O/Y|K%C OVj(8 &0oQHAٕ||%7TmWSe(*G%g YwMB=*2s:®wQV7}{ZFJIWVrb& a[%GƩwxNIZ0>3Ifq*\A1jSwk۫"BBuэp~l8K!?=w拠 S؆1SgYeǢQϽ<[Ik$5:B%OtwdIAM)x*%XVq3a#Kah+&;%9rxɵWR|*6o=,WCG # ow~j 1H&W?g6$BzwzɴߝVZd+'YѾ%yD`q̝]5 r}?ށ +[f]/P7X{;.n]*2:P14yL/0kxʫ+S;{]q.hr8 ؆I,k33bwHPZnr 3'D•Vb֘cGnL#fr ;!h|I?!9$yc W~-(gkTv^vVh^y7[\vv*i\fiI&V"yJCq27` 4$X5[rяKs5ak'ȈOϐ!H%ɲ=͆ TpQ>i5V6'M3˄uQPjUh'ݻoPHbEMd"LYpMGhfKGg4 iSY俸S8 bWRz?|՞SL857$j,)2mC‘b#Dw~ls/-@el2E'9ڰ+hxe~ާрV:^'֯Kk}NHI#+9HȣfSWjG%ùfN\A}I(ָwy?*}eRָ%r:&&eE*gːk)XS5 Eْ`iOc"V!Rx#z*cp2p%d$W<"F9Ӹm]sЮ:0G| ӂ6iKFMNǟI}QԵ[Mt#Q؎\1/xpAH {ձkm&k\}|R(S玖um^rԥd=8W4gIĮnۈ!|[ڱ7 O>&I]s!e0\ONѺx9i£mS^%0f_~͛>~-Uo+_.^ɒ5IIi顪2UbYj$TޚVIDᘤ4m çX,fHeTcB&G25V#/)@]l0ُꤓ*҅n,\nK-^%F%˾%Klqy횉Jau)uZ3*,~ ۓSWe`vKzW2IE32ȧ pOV= ] طR11iqhsU8ņ81;K56X+4ggSy<W"qjt# B+x]z2NBJ}E0C]R1<{DEo>PZ׌Fq\%hhaEeUhF݁qRF#J)?k( dyӷ5s~b*@S+!]).`P*n*7Zj 3>O*$ŸJLJklK5ߊ%VK_b9)|]'8N :Ӑк;Ј[ 1Ӟ4e&>Eei(=u=AuFV˘oaǙZl3#@gx0=f鮮5FDgp.T R_j(޷OU"h`=>aͷRL lUWr  RVZB)%32 =5I %sP8?% GО!J? iw^i@|uq/sЂgFNn_Xm/:y}41|٢wDtoC =AfsNpu#JີW' t̿}*q)!z :t~?w*2F JZoȦOYGXI1lZk2/O#w앃?}7㹚8 8aM~{aRC7<:>-X!f x{}X֬Y9$I5fϪǡ"rZ_9 zJ2NAŠ JmkDXG5y1.c= 9 gL@Tg!D-Soۚj$>a` Kp1IN-70˨"4S`#hcXb>-c0u}R1',ϢtSУ6iFLf~1s ]a+Դe^}Oz>}!WvB;^1L*Bݲs΢9ʦNLZVA" BVKQRfĦb@?w+=pRs𧱖 ԥC_q_8rQ: eb2U\O;|ք aӡlU\%Rx3tTD2nj,5j4nܤ bŧ Q sL1T8( }dj5(߿8皥1xS+I2dr@ɢTgD%q O]QiF m#(LC>( sx%`9bZ;?t\d+̝;jvz-tj|'q(cܟ{֑$kCIvq"mlZ\+=-o`|vg&$g>1,lC^Ӝ.8ᮉFi @ z$t {ZТKlc ΄8Hm}1 |8澻*gD[q8#!Tq 78^ k7WY=bBP59pm7B?<"' c%HLiaH]LnIYLqNP/TBS6v2omJkV3[Z?ggkxl ckaT(.!T#4Ճ3ÿ_"!6&^+e@!~]Io`R`z tر67G_An!3C,46]9G50GuʀY g0)L:p"@2\pr|JkKtnm^8!ˑb>GM! !XA*pLh,&c0fS޳f\̒*>!y, z_a\2О1 Zv#<70{ʧ&48ޟn4<{ژN Em,gATH粟$6WFylH'gBqî>ENJFa 5(h-R9>;܇Z|e5?قϥըh Y&oOzK>]B0a2 ){qrcE;yJ]ױk̛~{:<嫏CZRO *m/zYS;v&7 qLѝR-Y?z=8IdaϚک瓁Lp&i yС?/ٺ`FFל%քm+2c$[sogRBcPudNsoSoJz)䱢S#a=MH?ir?/w0 CH6ѽ)a4tsRqJϳdesjTAsU]% wi=<ʞk7H`]8|Ȏ#3i.j+H:uklI}ߘ NRSޱ9!>‡IR?sLvPf7sOU}8P4pQeyDgȝFеx*cv2~ޟp8~ׅKH%5=NUZ|Wl%aΙ#mwhX)9GF㪚E2FA9O/02*ssߏ$H/q h|;lmo|sV@NTJVgV,\b>eɧ?2N_/` V6:9=)rڸLo)2\K\^Th]kLyk\AbH^asXV<1h h=KЗoԸ- P~ צI#y'PV;raFzK7x{VXWoֵ޼?HԿ mУo~- NWK8z@6ӑ$ .@ΗC鏟Y&YsG).{"Ew8p XEʗ?( )9]klgबߵF2̴&oZw}IŅ&!6(\)l}J *kg m@6R[3"8f\O :q(hapϻcb!GG!U'!Yb iA-t)mso o1#MHijeldNNOaK]08R| )PIA愌vK9HtT͏3#CWHs9_AM\"鏓]RX}Lb~}e?c9k+šuYW'ƶ({SĠ{<<ࡈ yF̋tOV_)GBH#W 1y>ѾXgp4\ pLkcG̡\t7AY3rp >oH?\g %>ؑo:4:O[ĉju(ߠDz}}[+ZdG?v@`00 \fHҗBW%VGev.vz6l2iy*_"87ჺkn}Y2-  dO`YTG3OX2GEcϤڍ2ִe4u">eOH -c,F0AOiq|| # dami. endstream endobj 111 0 obj << /Length1 1608 /Length2 4616 /Length3 0 /Length 5418 /Filter /FlateDecode >> stream xڭTg8&z%h(;QF wa F3D !HBآ$j !j}w~u^^a`,A8@5pss@BWsJss War9C8 &++K !>(3552s8DÜ@A} 0P Xjk&E\WЅp4pD? C`筡q\*hP0 w "!A Eh?CN(`Wy8# $ pa82`H jgg<7#.{thp( s @`h+GD.@NU N FhpOߺ!>QAC]q9\n'\|Q@LO?OApWu$G`p)NeOAEEM5Kߩ5<\]Anp/ ߘ r͡VH1 TN8)DEt0o(; W܌.p CqZ^ 3qχ.-{A+sQ{zQ81&>H\aCqΡnIBpMT .@5-*v?,hc@pn8(NыێkŒCP0,撞)ez5n"F|]a\hJ,[d6\rHgr kI4\Nּ˳< CDX7ۚН'5[^04ꄘuAEI~RH[GWbm'ye͎m%fD2nyS`G [%T",9|C,|pYYm| z&pBU!2[Gaz+{Ej/ckEC"!8(U:"*5;U!.sN(1I@ Ε O2'SMk'~6[nzX)3Nлߡ ,;+hk Xl'cjX;$  X5'ԉӇ¤.IY;==X9QIDlJACkg 5}C(JLJ&Lkxr(^EUTAN}cG\ծT79/%/M0I1Bd+Q>"%ei3g `\pc_V=Beg_;h ?qW*Rw<qq[-!T*j=͢*q]5{HIiQJaQ;-;eϮN H>~EP|yGfE5!E}Ak 1q=4Zh1{o.)\Fj;c/ E]o&j&vrXbD4VPsٲM3#12)LC[woEFԄ6o(׈k]w{}'n )> A}utbV#,8^PvicRIb,ۀ{shCӍ_c/Lu(:sG%r7v '~c R x2nKR7fiT{FYYCW!&¥VźwRȮ.!2w H:0LI]{@"t[Y YI `r| V5}M F-էW)7S\wd \\$/~4Ի${{%ݤ|b+NS)z9gΰ^fɘ=S;/}\V퍇nBUr0X`'+6By??ntRϛYThlaCڄԞiS[ 4&cm|f/$PRI?Fܾ`ZBƆfTKƄʇvEyɃ2w`&*ˍoU~ A|]\0'Ȃ/\e7#B[*oAaf >>!exniq70$?9J"nl.ouQ1v%[ϵ_֖ltK* F xR\41GvRyNrpG3T ^,='K|]`69NlC"F2agaRIKx<'*^ ᲝaױrmG|H C2&j@ O׍xK72%jmbmeL?~D ֆC&Fw5OP$W - .]ew}>_BGe:)ݺʾ#SwÛ 5U^jqXlJ=$a0V½q{㐼n3vγ$W+bЫG~x*_O؅L!f7 ͓A$ Aߕ _?i/?X JhJ}ax+ I4CC.E [w%VHh1+ɒl+k.U!M 9@&<䒯I߾Wp1&=?[.l8#~S̓dRi]!s =8(qGfNjVN=BXCT+~u#R#UE%P1@[Kbmz^6:5'lqGSh=J2}r.rῘ&;!mXbvVxsit&vG_4KzJF,B-̭5̅IkIB20'-q蛢|E;ކ?Qf8)98n~]p6HK<\{ 8˸c˪g?ut8Edy*ϙYӹ?oJuRC*F_ť7 {9QTXQߡ͗[eJ함SB]_κcgq¿9~hrW2_;/[(A= ;Vs|jI_zu_ ~)ȼ#:G%,?4n"(vئ3Bv7EN^wv"u}܅@?eRSE5S ?O~`t+fw+nT'ݒ XRdYlB,E ֹh*6_WRg:q7Mkכ+™[TXrSUd6 uڥ9,'{J|z3Jb2Pϡ +[(NO.KcbsL} a_:1߽ұUA$?gTD~>]9[=r< N6ʇHsݫ}i+n6$b*rmL<<0/mV%^~u3cg^:roJQ+<)J4ݽCd>/=r#m"$r!Vr+uw˜O]` ;*=2ZV#H:p 1?@an:^:-4gR|!\bIbnk"XnF^T'Әf7qYan߯Te.PteծR.qj'ejSSנ,K Ӫޱu6dz8'"IS!Es >P`ޥ1-\»!NfD)Caf-/_-uIGe)4{kqyVϩ:m4u`}[c(x;~[H9K1u5bʼ! a{KbL@t|[_ΰS{ G"E^&J;̅KuCE#X冦aG"o5VŢlurK=vtγ gM2^Ehz:OQ?ݵDmă#쵦 a'L3Ϲ*dܯ'u 6Ly-,d,, ~0F;|6܁9MA34QTL0S K)C߬ypKjͰMAnGi hi H;`RWhbWHh2U?P7흳Xx< &{@DVn3h{<6zlWzV\gP/“jd%S2C5e a:U걻Yb1Sp"oUIGi9Gн+^ς!J*2U|)ORK%ѕ[fH3rQY^?YYD!#+M&"}n7Zxҭwz%ַDL[%&S~S<̣n)hͲ‡{W2,ܬdUur~tv欌-nC9v[g)R-Iz*7U,/=F<kz(VB[zl-Q@tź]!]\;#>l7VӤ(ΆF41k*wy!n!MJb dxwfO Z=/x_Z0'S0е 4}x^IZbçjD_!(eі:#ı&;@[tc>Zf5`1'RzS 2byD+g_GmfyEêO>:u*u*"ձOi| endstream endobj 113 0 obj << /Length1 1166 /Length2 3181 /Length3 0 /Length 3929 /Filter /FlateDecode >> stream xuSy<[&BPu;3}#س0? cY0\Yʞ-e͚J%B](!;ov;y<9"pk=$0b2Y:s'3+"Jz &8A@a1&8<UՕ 5Xg P~ 84 C D?C&Q c8$wϪ ? &m%!555;'2(/ HXJF=g( qo_]N1Y, I=A`53DP$u`0=Q䏑D9[ *@ La^A@;,iC~CAcA4Cy}(8"w /5N? r˂kBP$& !%(dUN!gTSR=_Z G'WJ( Rs?G px7A?l,{~@⿬ V]CARX0"?TSY< tG8&ˁ?@ 4CK& (v2;X<%d J8o/w0Jx`(Ț@v% 8=8YD>s"7P?COJ= ϕmєGZ`܊wf۽˝̩(c\W Uoecf;b5'@θD'޵ ~Εx3ɢ@麃A'u d8L 7_i~1~ SQ & 4 >QLuo:2<`/k`sogR 1'T/s;7v6o{7mlw5WlzUak^FDQFfNwJf~Ctܙ}y Ue0n+ qh?}Y!>0\rvD}mV]{/-g':((,y±QZG_Z>P6SQӻXƎ o,ON;zyѣ2e51;&0L}3Tp y ڽ#ZlP^nǬ;.;J4^oY]EJ ukԃX2|bw>}܉0ܦo { cnE2~vK2>E$J+nyظ6̓gU*k:`TvbUI{6/K2ZGbt %骟z(uD9]kXӌq" [ՁolʙoВGԵGs%#}^]XiN=bJEt:IAu`TQBjB|,OkM\~6}if6RTO13M>8x:/.D٧b&IS`4ƃs_]]/b잔!Y._y-N=VCA%ӸTTpCB7ߝ V6d㗺lYt4eo8 їskbjf%Xo ;PosS` N{R>lAn+E6 ѩo}^PGxB2m|SCS.ɦd=ħs4{.ɠ20Y&`Sy673IBe)k49]KJExyZN+/29"w9L}9bw`67oͱ6!-t/A8!NW#"J-Kh6bLg<=C n-[- ]ijǦyQ20gȨ@uԓe>(GF)ެhXW*ML<^;aQPֳA6}#ԣai $$Pb J@.5vE/#Bjp2 uCdD*D\Lp)0Gb:Ak ;ߴhQG S=n2D&PY5k1Bmp8q<3&t){EṼ?)մa-j0m-5@jgwTx9͝o_vw<| @a~t7T %SDRm咠tȊy8-Z,܉( 2MΞ!F>ժPпRbdg4-#ěGPf,Js>Pڷ'Yp:du$6.r%.]=oexez(|x}+M] ʧE#)ecPB`G, K^L}fb-ŝ|]Ija@-E`/.~0_= ~w =_Pwl'jJ,sέ 0ʬiP_mtk߀>T$sFU;h%bx(DqA1P0f01>7pj$6Kh߅by:Ts${0{ӦUsϫ 4ֳvAFYL^;)1Ue;'xӄ~f1Է,(<۲ DV./`Z= 5 {Ԕ{z>9LlpWSsVXؗrNo$YbF[2@OAS[&˓k _ lTp%K_lY~.(\[.>C{1|.fvfuz~֧ݑ?bnۏ YF|>հ{:wA*MH]8^9+<@sƮ&ݺo]ggR]zy7|Pd0I(ZT? [0p -!8,mЬաۧͲ[W_1}$eE % v$~P/,*(dOY3R$9(}$Ŗ% 6| fN(:G{.=Xr F,y%*yܥZK93="ERd0 endstream endobj 115 0 obj << /Length1 1199 /Length2 3066 /Length3 0 /Length 3818 /Filter /FlateDecode >> stream xmSy99QR7Ñ0~ ;?FAAo*0m4J- 'h*ɇآɀ& `z{a3L#l8$:RA2OdB(Z@A FƂY3P2ۇ (;;QQUUeП)xo"<RV6&Hq[^hK6ChhxA JA XK"΂E@'XfcЏH &q4@xO Rm&LJ~[f4@  ?0 :dxpR |_L3n!; qq$"!4A:QSzp]=@]So/3_=~jS+ S˟md sVߎDcA@iØ8^8dO#+C 8lB`.Ζ2xB c!nF&:\Oُqx*}AAmoG)|@"D, 'z(*sDdܿ-K#:})fϻY"X^0ڷ2J$X}KIyy&7: e{l'W[ycrӝݖ52Y7O߼%,#f/5cdg?ǭ|$$7eʰU`b)%8%61h )-,籟Uޚpi:waUA7/"_6 hzkK@\Kt :j~H(!_ibQom۞C$$Ej7rC.\߭ƯקnF<>,^//A;evJMf}$EcIѭq/H;3rk=eAu`}.7~ʁR+=}}.x!QjgLR!F 8IKu8_`ZӇdU5٬gETJ!֜Uy=IKذFr<.^m cR%"4aru9ZZx*}vUӝ'Y8lLsVB#0)V=/,-Dt@Nzpufn)@g  3%af0O#9ʏ da\vc2Y;G+}5o숷L~^VkAm7(•~DT-z 0=Q@ɦ/ȯX "y̎·k9^9_"VM 5qྛ~I 3c6i龖bOV"I˧;R6U;FЋI48~uB^pkZCIo6n*TFVlofG]v@™vˡc_U9dV3/nùjw{?<[(q&C̞wmN8oyY0tQ|Y"w,_N!߷H$0Wl6j^х7:X5շ3To(n,[d$>B(c̊<}Y@du!™WZk䯓LseDwefrtk; o53hL8MxDۻ4^D@ILK`M8̽\| qUJ.>L}GZ\2^硸-iG%t2vMk>;_bn{exrFGֳ3Fy:F>z T )dfL䑙ĕW_" :LXegr^cben5oۭYM*pj&ίlF1)J1MJR5"f}RW[dvuPͽy$= P0)<{mTtbKZ rS|\] y0HgSˀZ#LUҪ,tX7}p\(^t>R,LDK\F ^?Tͱi +PxVr,~h+S# Ld`TC0nXJ#Q ]э.VLHК3$ʩ+w"M^n̗쩚Ym/do,k\G$n+h3]d{Eշ/[jj:9i5-/Pˣeمxsx jZFK%nhH<^q_1})9D^]G)R%і18rWop_Lsh^C" mrIky4^$Įk#Uw dw8cQ耴%eH \<:S{i^Ff+z4ޣLՔypbbkL.rHIv3>#tބ4i1b3oQ Ztp|$ݰ}lmI'4[fܑ7{-GFrxt$)8YVI+2Sr6 "$<ln-H>ڡ-E~p#Gܷ[)p3Q+A|¥({&t D˥mdH9I-9ͫ.ST>{R4Z>?rA@ D#9u5lyݔsd{Ҁ]ʺh9TAcI.Nʻ\dt &w,[O qL_bښh{Xb|\ĂvUOfKm*7c7! ]A/޴μ9C ֎b_rCTy[JOU>]gU7g&f*aFeMf] \wgOQMʧc,x9 g,g)2&k z5/..d=63Ey$&ZmZ/| 5O\& P;$]2t©5H;(VQG|q }0ne?[h,gD6oڧzߑ8sT{61to.λ'U!Hm B}sTlH `4XA-5~13CNϖ.K%3xgR\c$<"KU#bo*k&jm-UBnH܍O8C1|;Lv)m_n0(=U?Tt endstream endobj 117 0 obj << /Length1 1626 /Length2 11210 /Length3 0 /Length 12051 /Filter /FlateDecode >> stream xڭveTۖ-w)%{p NSNp A{Cpwq~5Ʒ5ךkQb@i{3; @dg`Ȭ4` `/i IϏL pp, :M5mzFFZ z-diyp:8!oDu ,@@ NFY Ml. 3" h X88A% 08;@oi@w3_.&#lrv~`{ _r;EؽT!f`#VUUR9H-daca, r fV ۷ym״7mA7])_|V 3 hoߤ<2 7nъwpx19!~6@<+@ w[lw FQ؛mro}ߺ;͐S3 9ݝ0!u~eOU!,/?=fwv;mi;OH|(ViZxwY ~kGy(in~R3,z'o#SR8bCaW;Mxp{C;4q׵1;ZЄ7< a 3{{purqԓ_`7ohNWXe`aaٜSJ 4)Ru0U#;K UN^ y ڻAef,AŲ!w!Ϗɿ jL}Mw#mW]' K:߅/>DKշ̻f (/yҝ bË^ 'Tl  P|{Z`8XF@&-}չ,g^}u>edpRË4#Q#wO# }>DDC'& .UlMͷܓC.S]6"JONH 5V2`Nm_k=|wS%O3G@^Bs (8r]s]%S`5~[?ڰ.A!PY_Q::[#>*Z{?#bTWhYť/}ZV}S?=cQ(DlE=0 ep'lFdIH}ň'Ta_Q) ]=dLd&qSd;9=!dӡȶuH@o|Ƽү*}30AUlVyd&]J򯍹OGUCC2$W.!{xiXm GT^VxyCHL4 nS9Ty;*|~i2-4:+ zZEukvg ;'|j@5A>83I&A$|rM"uljoUFY>)~Y>G1 v>`W ?8t{-q)ɂ~n owG '<(_4.pcc o/gq}Y.&/ ~ U(lU!623Cd1,ϭPjϞǀp p8w|倎&WZ\KqӻVݘjD+L0ax TTjJvmeξ?s9׈@|INf+Hky{nell2uv' "|28~]of7pmr__p&ܻQ`} }xQpf}Nmi*F͖Gvc5VbTN{C4 89q+>MB[Jdz $ˤhZ!0&\K %/NE˦JPCa\·jkV,}u 2JI(^o3NlBn\e^.̤dwp O;a_,bOwsя*5o&Wb_丧[̒<k0Pr, 8Լ.ˏ + Tk|k Uj2╯F|iiG,TkX(~,q6u ͛a1d_q.5=t0ݒqG’dɊ6OkG ~@fH!rsp7)QKQ ȼi^aNGYOBxZy2[Hy޿6|2ԬdN0~SGePӌ2(^zo[Di%՜\,ɼcއн2ԟy?$C-;  C>޻Hq9 B6o4췏Q^=*tTG->C15KSHa\wik I!r_=%Åߥzjr*4 YRFL׬0N ЬIz/,ܣαUzq̅JrNF\E0 `r3VD5ptv]pvs:co`EE W;^dM\nɄL^l,az'iղsz /D\ ~7@tM$H%Elcoqc +&d0¹DPVOVW`}Yj2nN|jK)g|sG=80l֫M%M\hZ-7}#ϋfZ5)D9Io[́<'Z__;2 wɖAݪ~>1,ǹ}"p~(߮w +JuB~k\)VgLk`gL_s>a2s wGt;8n<)̎w sD[P? …Ѹ(~O.*yUlD(j{0@0A=D0儩Cn}C .k'g3Ѳne' Ɣ75)qIZ t4\Vt0{rb^NƘX-Fmg>Ps"nxz0jѠGPm̈?$*sQCT#Gea$Ϭur+M)n p5ANhvE5Y޲ff 73=Sv# „,rŶ0`+v'6l1r8 `{@y[J-x Hз5CYuXMZ@oi)ۆA(ٵD4][Ka4>zd:?ߒE(v7u[|?P1:jbڗyZy lߪ/9 TFD˓6fkf;sw,j¯}j2z~Ҋ]gKISb8AjS7S\y4pRD)O^ Qb#:CxY 3Orj^z>;ɮ6=FP%hE8Vn}r֛@ j,~Y էZt,s|LCU.ΞM%(D }>([ f 1c,KѺPEIL0׹{Cz5[.RdDධ!-jpD40}R'aoQNfzJ&"h(ImESޝ ]033cWE>g3 ƒ"u#,sfj2*ƵZ1K p\K;fPnP,sMNܫS 'WhrPrI!|%,;ClB\vVE9h_[ʹ;4ȟ{,=>D6|"+.3-|BWmsDEMDZ6SR;yn``g1| ?y?*yupL] mlYko+V;RD$ں5}O *lےp܆.i<0o~x?c E&hmd_PH%y{!d:" Сn_ŝ}Uvѩ'0'rW8\yd6sЉ~"/ϝ 楽p o8bi 'mW^%5ֿ&&&[z[eTrcmP]A╧fOcXˊ~%c~߲•䒊0vA=;nJ,ZZNpD;UB )<0DV!x4&4i0]rkUZf-lTɖF}o l;]a 8[[km)j|"3 QP!5Cx5b|'yD-<*2Wd!*pO~DͯD[^-&/ YMn^;V('-z'ܜUUW~N2'<ٗI>ٮz F e>6^~EgZѿ@M5@/v~e]H9~m$E(0j1JfyJH~ q3 P@V('D2Om/E7ea&.X ;x``CeU#g'*F0~)ZAQƧwim3큹{]qf$Ӓ dذh*/N0˥wI u<8'>\|mhZyq ֧[#?)89_kFݰSn˛RBETXY܄7k_Z]v|q_$=eGwr2 RЍᵗCg~(I1wM ӭ:o*آAW$u pTe+T†*41DpViq3x(.i}mϨaW Y QJ܃Pd#uexD zp"JND^/{P_N `(lK$𚩖3DjL×m&MCa&76CL5=a\f^L_GܜEukjx?84=LH?5H'h'#oҟ/z=:$[Qo#ƒ|Fcnvt49_f[s,nj0؜È@.wȷ1`ffc/IRs Q3et8|i]J݂ gR_`s_uQw?dH0U~d^&I̔)lMd'J_g{QgOJ%gvW . tZK<9\ L& <P5L$ڥi 3=]&:׈e~iS(Bap)!gEqAaE9GL i6Zzb Cq$$5;\WFx""ߪ̸P1)v $~,2n4{] 3?50pBlG?g_X1.y ]ew* >t 8 *ePuޭ hqf+op4vi3b@fK뗿+KS>0{XƼU|v7CQK$m8vK{;VA ه\VSuswS4lPIH@ni kt5LvMUڨ">#,tqn, J rmmZ@X M`s4l 5{ht&[pzwu\%A\4Mﳶ_0=l.?Wa3H`B&ct>35Y#gaEO:j ?ڮKɣ^+ 3H[JBդ'36ܰ(Bb z4=nK-6/ 8tp\ܽ/{нǖ΁)݁#.ku#,{PE~ mrLΐEPj#5į=;?rD0o`χM f^{*~7fE=BNgh]ۻv wMOiL5([ U餩2#894e!BPV|Aщv9S?+p ǚ q2=O˪y^#4B&nGUQ67X+ r sGKT=NH_&7pLQ6G%4ڥ&I&|f[5ѳ >CŬ&bDSP4 -w`AQɵoh`O QƇ8k<:uR L#^k^?\AŵBX{ey l-lx&Ms\*ЮhiDTrIQ~eBĂ\#y0p0sYlˏ3!-s"ɫNQzU=${Yϥ.0n>~GRŽp'2 x} YOu +(2+Ӄ`O8L#G >˼=)X[1at^p-X} '~5JdpҢ]) P,z֘PI :y˃Y,(ITH[62A9;xn*jFrs!1^4g+go+?^o$?c^T)dX5CE^R״hB#">Rh [#ĴT=ބEV]{쀄@2'^M;E;  VqI e>k#=eX#eٯ6"%k\{F㛯ZZh9{p?I=H ?)&d{"<_-ɕ7IŴX2j UbjkpYߎL":EjЃĐ)70ϝBOwsPl|p9jJcu>g'Cmvz(9B×D"!;>27Η_.%k8iuba4m=Az~G} I52W PGm*UIGz-̃kWB56aF^n+:_x[7Xnݲƫ퓝ȁ3 aT VtV%>Rl9)j]-O|㼼 B32h gth=3 \ WL+rq $qy$15_D]>WsAߩ+):uMɕInMz.;/xW/HoX(d痬lţ@Mzy0DԵ޳#}ؐTY<]wgCWum\//5.E&`Y`gm~$-/MsakZ=x&{?'1DJ 4l|Jb;}{,x%ko G 8ѹab@)FPV2I|o!B=2_$+8]y&b 0G\|ddC^RN4ǙX܍ *%=_l==V.,T%,玶'9faXNg[CLQI~Q{ 3!碇!ܺUl.6˳(;IXOjz;~i3M6FY,cUC:jj[铢R 0W2YwJSDPOV (=i)C$Ume3)a>F1 W"jQf*L@ڳЍ\4 nS@ݜ[ӿIZ^=Eufv ;I:ZVL?LðʙKRvIe)QXOքUH `_\PŢY~; luU8?(]$aݵ^* ߢaz;UDh_PI3^tf=@TB#c;]0n ݳ j ,6،駠-y\B {#(G6U,HӐYMFߟDrX%#dik4ȶJ7U+S#Zv-;>:e&BЭ&xʒ.컘,y#؊Byi :s=/4$`O{(NZ7d#pd'TwWaDor2!: endstream endobj 119 0 obj << /Length1 1630 /Length2 15084 /Length3 0 /Length 15924 /Filter /FlateDecode >> stream xڭct]%b;c۶mVlݱmTlv۶T*W|Ϗkk/̅XI^hl&wgf`(X:r*froNfF.V@{1#3)@`F:x:YYXU4iiS ?4=,lvf.!U.fs+[3$JRA ifodd Pr52Y;Q́N&@{SJsf% 08;Xu301sGEp0srvrX8ٻ `eobjO%kaWL ldUILyX4ki 4qպY;\<\el0rv5/տpu NfFNfabӝTo`/o࿬gV.f ߘY4q?"mo03[n:735ꟙ)`jfQ7$e>(o!7r+G%ZV{.#{=hl>FvV'jit`.F"lo& %=R ;ģ͍%5K9'Nv4td \ݦYJDƜqJh% z$l'~R(@G4.:&е,}ʱ~(nkw,NZ̾A%$5`*ą?ր+H..-T0V'TKR>АsD?oN|ǑIHH:#J[>.XV3Hu$`zKl7J9+N8Ԗ]3<{_=A 3'Ͳ{0MR=W 岰 ~l):uCtѧzUx"Y8y 7lnaQ6 C2cLg2ZNhl](q;8=Mh70 *vh rX7 ҃n¥P,= 7xbcQZTP4)n <75Gl ^Y_5UZCR%r9b5vva ȏnJ JV?ZbHWŚ5$hQV*!BP` ~?k^Y =0~{۰賦T.6Bf[+S{&wH8~Ej΢B;(Bfof%/7̔lSvaf[?xK샵^|*d7GC=6'[I3 lH/ևĨADdL6~I>kz8>UTâ[x!.yB0J̊y( 6iO7:[Nnf =h0..rS`046<;Ak;Drz`:YPכFa w'OhA^k_DY+QpPqYxn$JӴx/#Jڿ+Y_;N=P08mJQ`yd{1=X!4Jxck9V3KQ/\qf`:^uݬ3|/]]Tk78MHZeGlRS" C[ P*f ~!ĥď_uL;&9cqH[lt(zu1T?i?R7j5:67'tے @U5 ۈ,8< ^aq6!.vL7jӸA3R ]}s :O8g tm ΰdذʸfȌT_-Ԃ|3!QAJl5VZ D'&fO?ËKÅT{8wzӶDZʦ!dJε|`l!$ [ȉomy~[gqjq46S0_8Cȃ+pXHEFnZk ;QBZf1gSDXS(skey$Oi'!%V+/zu1WH%Wn6gU] G`H 7C@}C,KR{6w?P0wfa;[IKA$XJ͖1_) Ylt}-R3iXvs 0-붑'wl>mc>>[agRZ5 OƄ+-ET#oƮRzgr'M5ſ˳!ӗ8>1Nr @6?EZӤ5-֤~ {BBnH!WS@Y43Wh!bg:rQc;,'Afr7_\H*6޿ S7Pw:r@3k -4ZʨhlHkw-)L~fCSI^$Kxogt"+Ϡw:mPIzVYKftr*rHQWNY ;LL/3$e 3쌘m@m(v*sbaO1Wj@1%:62@O_b^`h`%HF&鵭Z¸&ZtY/fZ!~ҍniJc˺露Nz|[d Z^CJ:q.ZthfH!A-Ha,kG!+HG& (,Pa^A܈ࢅIL RB'zǐzIfNU$Wb=$%ZDb+c} kwFS=P{9H>fC?`ܮwO5ɟϥlcb64HUm3vNG'9%VlYƺ8$ڈ0d2'}<1骎mZYnamHj_`|{؁?gՆm[\L!' Wgz*\`0pYvϤ[Ю>o"N+3x.z@+!o]ÝPVx^ݳ08e/nȡ~8c:Chbqz4Va#nIJ`̧7R(dh;?V`eH{E@f"~N@LIC'ܞ!Cîi׆YPfĕ< * bw$ʼ&Z艬]&{-!@p`߃pQ++&~{94ǔ7!0A6vbɷRUH7߾C8:1Lut;fgG̓{) /Ȕ~! bHT7`Q?%)+CIia\5NApe"(IQ̙2q =DCu/Х*”S h(g5:rd;M^'{7myj$A?^UEI FNg!dH`9yxGo9A긍&wZպ{:}a'~<!hi' "A⅑Ki)7·u2I'K'=n UvQ}KP"hi i*&ŬLwf(F,?_ɉO(-ZN5Z[6ȧhII92s7HT3RK@= &Ԗ''z%cYO74Z]N>[?S*X*S5n] nE1T(Nf#5BO׆%8YOR!LKcDll!3aل;ݱ:%.]0DJ 0֌ tW.'[xl2.%Ks kzXvsp~x".ߙ.R'|Wr}ziO>fz` TꃺF ELپ.²wzHq>_2 Oӷ.zKK,LEr=Z{zPS\Y4h )[N7wA~ҹؾm',JPorf)EOь¤0J;>J)okVxTJT]) rX䚟!g.Iؽ,z4  I8(Þ]rpS( VF5-sm|3,.2'99C١Huwm*7 >R?RjOq٭Jlbs*PΌ6{d`=jQY5Ƕ$O aT{u0R}%"J>$9X[%[x7LK`ʗC[7{^%Ha5*k^,Bm*~'\⺳ˁlu?3'FaR(P%juCsZ/ sxgu4ytˉŠaf0#g;tge}p-4֭k"rk 5Kem+!(! :Ng;AU˕A}\&|[(chS=J) rى8YܺT%K$ b23cEhWbJRDXM6hxF~`ehT*K 3?~ޱcϴYLzћdk7"!jg}S,\fB嶺5H9䕮H ^>yl#6.K-?Wh]S'Jߖj< {|cG ;Tz=A*M2S@aR>Q&ߎx@F:Bju OpӦ'bG6~VGMπ4=5 HfrL+kVXB/z; .1rg'C.fj$ A*1,̎Y ;)*oa{M!>5zQ}LR̖Å_m)"4I wD4|׆Kx"{|񴨤 FUM N^/2;ak#C|-*K@9k}@e?kdٯV3;עd{}{D ]M>'/⢛S %{;#QW_'c$@#xhcDhmB "Q밤C|`vHPxWyZR\z]D6-eyzK[jD2&!Z7w|@u v#*PblZQρjgtcs tzbMmG>ӗ}]ӫP,33DQ ܧ71R8BgJVb =Ww1,x66AuI0$M}i(Y~8xUz`/W-_Gs/{dM:< {ic*k*&ln~W`ݚHɩaRK/s +&Vˁtbr\f3.[t^^$L%Xa?s g|vTGP&vxސ'䝝xJH ^:}#Sf3m>ė8UoaEA=7>u8Ji/}-DYgr%[C8՞CRQ™\Cs&"|2 |tkAFX9u}P'HP(-"WVIǏ&E`Q yl0w;Fo8Th31AScbHPe.$.Yot+,GdFdžGFRt}T /UZV̊b֗qkfD5 if7*52ڽ:{bE|ñbM5 %ˍ*p40Lb0/YO/ﴏ`S1Mzi!1n[տ=+ю(6vc?t ҆$lwDDE].w?C,ڠ^zD7[ XdOM9*UZ !r &bØ5P[s {⸪*a1l*`MHDM䊉 鏼 $ ɥQx '=mMʵBZtVogWNZ#i&nwcn[ rgCŁPi&~7Iubw5bCHl2PjQ3GS[NkMLo륊=,$yqQMqVr26oo]H1Ӣ{V/D2O' Ls:H{=ϪVlO` n&7KeALՓp0:.l>DjCMo*)P9 J 2kS?[=W¾(vѴ?/"$%ͷ$~$Ʈ>ȫm=-yH*z9AlN}MVm~=b7}:j dB<.[΀=zA`[ $aRu1X=]償&M^% 5J ,gbML&jdMykb<ѕJh܇Nh;tù(1'S&FmgZbȦh>Gr6NJt V&dkЌFNC+df픅aVw*ݳXr$2GqrYw9eNwFp!%!2ST濹N'C (l6,C`/} e1!gHN\?#&[@ *Zk# yWFTf#yV*h_It5X}Ѳ0ZO͂TlR} v`8AbY#L1>u>{@D@V O:Fe}WPyM)RIglE+O NAasBxF@/+A"[[_gNҹ>ڪzliߣ8NAPs JSek9]ZZe()^L{Ѕ},؈SaMU<^rNtm i KzCu3`;obV4؝{:Z!b{:7 +\SRRi(Yx a /[ }`ߙB$ og@LKvI?Tщp~ċg_9WaB:$R^Y;{G?o\N[,hmUfF~$ `j\_phHZ8~u.[tp50Z&Y?P:" ;~GT){B lU c*f0KHddZ@K?*BP-Ƒ!(mp1o֮;d5 _IdИ TݛAL1!Ee'"G<:VEHV-]$H8R6 ix2b^f} {WHQ 9@*K|b.{nf"86v9l;[ֶg5k VE˺]9v 1IKW_ٖ"qeYW{mHc_DSCh\'yu֧ԁt%X%]ٶa?5I:gV=$8A|8SDVJ7\w^Kt|\Fګi?DeT^AkN-f)7--V;`ރB| 0{+>f`V*p͗=j#R*9m˰k-j%ĆW4٧LZ=ЏRXhhO;#_X`;3Eσ7Z/r6:[b[jOBxWfA. S7]P9Uܨh:z-5OPR eߴ#31f ŴL]^0CnSˌA/4 CT4\Ҹu%PzBu g.(k,pl3Fм#e3M /d%F7D %+3LHhk( -QXXFfla@u8ƐFhm-ղd~,QyI L/Y#U]_ %ؿۥtmҋ%JzܤE`Ņ`)Xv.4+jUsQrgoTTOS V(bɸy2ͼ:#vP6]±`_64W$Ǩup[e$A4DĀN笈GQ0jﮠ%2n=p ːW)AɔO`3ϵ@zD[3XRLB9#Yk>P(M1!=h\+>KARK}ʯ3nHx DެR}CvUMWKC>^ z2' fwbC$ "Dt(I:WtJt0tбmj?Pa7ttz7;nA21q5P6; HsH{>98$_oFEX#]lYdV Vq.lɎ/XxØMr:͘qjdz+h} o X73;?1"'(8^D{Z(&Ҕ[_h[H dǖ?i,p Cif!A *I['b똙PGy);Ci)WcM·u|`fyqȰ-"zϔ!̦ěڥMe4_^]oyC/a r%? <7!; :0u@U\fb>^;y bcU 7vOF'gJ/=X|,=ڿ{L^xa:uS'Qf0? +,KOӞo'eKEɇ9w42璍5CNˑPi*`)px\GW./exM_x .U:MτBXnJxX5#S~T5QƮ NƏu/p qiЍ)fqU`i:P`jzxzCYk! \@E֩ z|Pe@";]^flRz;Du}E}Lk˪Lbypc„ OY2?GTTEH[B +;Ĥ}0)6LѡR\z>zB` j]~J2 ϒS5\O\\VƹRI%6DΈBfF]?JSO)*S_F*u4Zy˴Y+Ϥ0nm?):(nBlj-1bd\Bϟ:~QH+ߗ K1C'@ԄTfpFKvUz"Įv@%W5kMS3 `1^Rhp>,O vnHcZ!ny7tXYϡ 4dHǜS (Ώ۾-AՕx 6Ϳ*pN:Ȫnt?VB2lVp Y∉bA) ɨw"WeوTK׍F0b}FD< =V<)f~1(qi02IF?tl'W,shǢ~B+O8 q@[7Cy8H2nɳpf{hNLV*`9#{J@O@^;yN)uUDE }?) D 1q@)"螻nT9#ŕ~Tw,Ai|l߫t6>\|ltPTr(~-nyKohf-o!RIεܺ#gP9=FB0/3&2HtfioOwI̞r/ ;Xþ`M:@(u`K(tx5 2C 2'l>XNx ZaĞ^2$<mI*,nX7$[8baoP2YY*ɴ&`7TMP} )-Je&ETp28ڵY)*}gT'~qa" 1%Gyu6яh9rD9`XdP4\l]c 7k*lp:չl  (}nprhU=*3F9EJ07퇺Uu}ЂT,MžvjI2>$wX .3(pdW٣Q9Q G'_K6^] ,5ԂU^/\y+$EQi)w% vLǪBﺈnF!4GOe6?~rnHk] rFǨ3-+ҌeX㥨ݵ8ue<[p8 7,il6;?^Z ft-D+'p1C6?{2,JoY>Hgelkt..1r XXIΥcHC!57dCo6m /ˣ١Nz:eDzMU79DE7ߛM!^ye\ C=" úJn7g{82lO!|C+ԄV#aa05KO9*FnYZ+%KeQ_9l~ڶ?`-Yyh]HzVw\Sh.vӇ_#\-!K( w+A(LUU"{O]{;LМ9 3ӁuWs6!P -SЕ 'ɹ$q{ߥe1B씸**Jo->a9rI`ਿ;kw!RxV+~'XcOZ)^FnE^,mK$G>{ |kE`o@I/2Fs$, *7?vC`A ӏZn/6i]!eߢy~K6" ϛ0@IFgױtSJ(l,*8#d |LN1n.4]DG>(R|H٧Pv4,SU}FtTa _B79n hQ|&n~k2mIL12j/}'G&uaMF:K"(G oy1RcU4!9U\~. Ae3 /1{+c#WcNIzG 9%BּUPY#zio' `_-mE7Ẍ%,U:,r{5_ߓsaԄ\wK .n3Mjgs:ps)Ci ZaV9e*"}K Mе YE0Ǜ\eݛ B.5Xnb4ZNp[˿6^t^Od.koH$1@wz{Xs9p#MTۢϒyk`ڵP) ?io]-Aia fa xNX6Fh=ԟ؂p$] ω:a3Ô&.}2y-I_ڊ%-\=-ZSChtRԾ[)T!4q$ Cw`KUS;UՎF#e^ 2\Q5g~*GhuTgxeFT@UOOa&G3Ƨ|7Fn4+kz$م/5V&-rҪ424Vwê ۅ F*S;3윾T $\B0L&lT Ьh_.;Lc%)^0fx'+#ꉔbB[!FὓO4Ǝc$ۊX7% qIEpڅ\o|+za^W%fE!P~$ |uȯMDv9Y)0V$Ŋk3\ im 2b+0upȞ:hPpuZ+\+D"rӽ_EUhxqރT<=ԓI`]>Q k-xY)bIG+8 6ǎ@keKCaY|G ٚWgvM-nPww"5RtZ6͢4ӡ})N»,7) -M iZ1$}· 3zǽyNHBRQ:"/i.ܶM@<&SQ ىKsf endstream endobj 121 0 obj << /Length1 1644 /Length2 6470 /Length3 0 /Length 7308 /Filter /FlateDecode >> stream xڭWgTݖҥHJH.$@ $! QW"U:"ERTA ;뛙?3W޳]}Zcl& A:A0PDL`p˜"=¦P/.Eͭ0$B, eeeɸHYZ sAxpP8E`qgG3(uap(@6O E@ 8  ``(8#_~qb pnP_0h04`w83OB(4wȌ,\Tc ĺcc`8t݄ ^Khp(C`X/w,'(à ?\l pWB4 ;_Pp?? EȀ⸘`,. A&{VtHP/;  3ÏKA"~ԙLŅTo"E<{;n _;[2 gߋB7 y%t2],U NaYɻb0 1ag׷?v PZ  3w " 'ٟD54T %+l PZ/cX`PPƳ4DByMqd_gC ؊q~`7M =HfX~`/4'u? ɦ'`ptl%cNWmG1ƼeH58lś"r~[__1y[Sy8_4~ }PDm}`񚍴&^] 6KIpz uz~^G2k'icowWg>QVq Ƈ)[w~%љ l<&ǟ|6%:`˕*ʄSXD%}CzMnOI|VKsϜFMhqH-\S8iѹ/v:~␌d2UJeHoIJãfl;{rU]0BϳCO1kgŒ+ , j%ne+Ŷм]8c~B3Q{[.Z7 ACm4MPQeǡZW$~5]:w^*>LE5V6jn5I-5J<[&$ E^je3wJZ^.bM +j|MsI3M8` K}rQQ<ܨU@oܜrz_^mu)#vtܐ7qljk{2>RIko‘A'$Ԁ2Z^?P\YjS]hQ.A(c*}#o0MϗxƀzC+j;'tD$`S&+&*\޾9J'[~eW!q@$U~ͺ( *}3)Q]-i"ʉX{_l<;`}Ucɏ✩1F~uьzvwEJe לUݎy_[;jG۲@h.bz2`d*zyWĪOpH`ύh&A2ł @iRPFZ\/3:|~6=pvn+ 703Tp<)4H0$Z*ȗ&?ԃf#E YP#Ҽ 0դÓQrWR+v{ĚKthRnL<mOW$ٶR!N{}ʤR#F+_3-}Cg~d^b\.ҩËnl0N~@88z;\g3-C^af'<.S -[-g]F="=Dꎦ0<|G>bIV2voַ.MC 5y+zS|%,O<$__d7*ӣ9t%dzq;>{w?kNS쇔>鄟⡹{Nv{5d`Q񥗅-`ࣉ䓼$щ-`~&mf@n/Wb1h*i:oۤTtg F'dDZX{ { HՓ+ﻛ\ 3ڮK~x7H^A+TOM~#w (EѾ"Kb: q'l?][1 СW^,`[Q42mk@~ܳsnY/"m=UJBZFĬD<̅x$RfBϗ:k2,.}^#~pNf[8|pIC_\Y3K~~$8.3KvQUpoWSpcg-G~A91**WIǘTtY([`ឞUƝ3Wsj=|Aܨ؉m@(i"2>|!}mMǴ~ 渡$~x|A+u5a͉F+Cv^|d<`,}+urɹڥnFi=-yl(J\h5X!_Y @vJ16-+Wj) kהMyH*B >ߢl@l37.D+T3M(T'w8I0Cv$A֎ez>%7_7 es|ݕ)}uĵ"bȲQn|<ӾBRZ{o0 >uyȟ~;X7)c*u?c.:$z59by.lK|ɵ`lzۉxنWe l TUjAR*3|Rhjej $ػWЄ׼&p`lbqmMIMH>VoewZ'[ǂ6nDM4jr΋%Wڥd)9Znu^lg`.uĆZfMg Q;n.-o uB'A eM"ߥnq9>~s~5˻,(R#~T ihl|gkL4R0zks_ C ҏ^ŋK)ݖ=GV5$|,rg̔$9sw'5x{ohg-AF,s61 ^T[j,&]?kG1ڹ(N<rm x@#֚ɬTQdZ C2r7 /@ 9#.`;pN@f )(ݗU%E_>a+z둪GY7%)##zhZ+۰ߗ՘*47w^Qm; ᡡ/f=DN|Mls,Id(A6XDQЈgoA&m`c:[OUABw ʼnHR@Y!H7s&R3G͇񛧒 = &Kw ~+tUe.L8N| 1 Qj72e(%eД.Gx%3zIۼ<2<>er<vq?usY : KVeXZ)Nn6!kJKݐolEU4em(nIu= -`-~=caѳ8SApOZ߅-ޤj ڌ?xxdFطo`ܻ.xrSQ=OFt./IUˋ=ZuLLY|^WʍOKG錆c rR㴭;?lڧcf)^([:Xڳ yKMgBIV]MoQ&\pxA¶%Y%u%.hoRmf'yr;\r?WG[5``>حL~ޮPzffJ%|0OƌݦFJt%M^h>U­2u:>(*x W &|WQCzqZ=|V޵A_MyMۓMK0~#.aʿG.~.np- ~4Oq2c[@2zx &Ov$֧jqY]PX`KOn #Ǚj## )LNǚ &zYAS4xc"-TI٦1ԋ*7 $QF@^),wg"F E)^]LuT!lU!nR%9=OV/Ř%ߑ(qӤ/k*׏Rs|' 2.3ګSNɸޞ. SDW:i]:KB?+S'#|-4:# к܇R., oʞ^#e[<<(C] ;+wzQ1FĨW _ f'8ݎR'?0TIZk0}CC6W+Z{Y1lq~2HB t : ”ETq [,,v`͎&n޺д%No69D02)!0/Fh ;/JD["mŤ9xn ݡ79eBiqPi"`[Og~VeV|b@ l>1۝E#)M)XS՝S:9e͟ 9P;q@b ~ȓkv5ɨ%^:etQx| 0 gt0^ ) u\M{Ἱ8702!A]9(=Q5nlpK'{\Ӳwў -~\K J4.iUlD8ċ}=e=mJJ %O^%l}~'-D(N$WeôJƘ )>?ƛ`U[!4,?&,DG%崘^YYl_X=.|^Zi{@Kʉw82>KARvi&?wigJU6A%[Fxs&&DOiYymi܁xy+x󉗥lʑ N" `OoH~\I@ k#ӳ!+>9`1}H ham y~ zNj& c[,&jaW0hDÅYˊG@r{c4]w~pMS]n Pf 5F\x2<ql٭KVch)DmۗEgkvկդ@Fޱ/5v1d|,,PgUSB븡FӋDjk]3E|6}kit_>;k܌`M$6!8k^OּumW[n$ϫ4駱t-xRydsB7Rt*uV*ZZ$oA^pԣ2iVzIv5i#T{RnA8Y>4FHSf]PnDϯr>W+Lah"1lumub:ukZsuA/ 5 fa?:@9gƏxٿzkEv0Ts--_i~#^Ioq#UBʣᓙ!~]lk-`j-$ז$;XfKwMBm۪OnF\}p8D|R+ sw(-:W֯1{> stream xڭWeT-V(RHB!$CqZJ/n@aiv<3>9ae㑳YaP/@hׅ9jyt.*{* " 0 `@P .. 9y8Cl]CNnvXyyCl`#x?`q䵴U4J%0ЄPP8`s8u`Pk\rpw a`w7vv8E<@A.ֿ x {p|ȴap qBj+(U'y0OkwK@;` ;9=r?99C@mUc3lhοNNaY;>!rB8|Ejevq vsAg5 i)7y}"$o'5/N t| a]P^6@gP# !_)䠶 <}W!pyPk ~> ӷ^A/ {OEYXYٶg&C ?=xD<9 i D8C|u2s(f{@8;?(g|GٙG"ʽg^0hZ} Dy-h3?k?)˥/(.&[%{@_o zWXlVI o>[y=U ߋ$ s)&_9SП,hx]Q߹3 66];@9rzLK?m*AzE|2"PwS`!H"]3]?j҄wYsw uj7 yknE#XBDoX=s.;?ӭҳޯ]/*_:U%m'yG2cޣRw^*OcG~4{Qd:jz ^Kk1`WzTҸlV,?f.u%!+8ʾēk \S%ƨ?kU - XС% X K(/tP(QX x;w8aIXM|'=l)^ԹZpS\'ZߊFn۳O;wG/dK&*TLuqhy4PL]+b%WRH-3 zr/FJ,V`'nE|C/ a:0Le׸ݓ E{ٍKe̶r},gKk_Cª7aFɔ//ZUK"$f $}=Lџ|I@.LiZ =M^z\yTnrp[ U'3RGk>f@ի}C3k4帟,kaEa=Q>X 4kI*ڦ"ώJӀ)n}{yJVPBWavwKn,͌k%5 wƅuCvno6EGYzJMdܵ$`#Ve%1f͌q9SڦqUU5 Iy3W` G 8Dd6;˛j,=`|X ipvđF2Q#;K٪}ëCX&Dt1r᫧ocDt3$F'*OoH0Qn04bŲ.D#߂=fSs[Cqzк&\Nuyt 'S;ŤW$>q7ZH[fsgJ-~D+ǏdhnBxX.$/cg#.Dћf=<-ѐ}T=y !Tߡp{C}p};lXuSƁ^O"{;f꽼vzcs*3xxQpܒW&W^= Z{Z vP2C{@^MTH QJcɫ4هךy_*[/QM=8̳yJ(y!Kم7DNw$?P/qd^L=ʓ `px0^]S})vO'EaQU/M}$&i|zֆC,|O"44d\̙>bs"jlhCm}_o㶼N \H}HG); up j[y%8ʓoV,;X)qV{Pv?Cf^'RH$ג>ƇŶ) WO+BO+ Tf4NVtɆ_!4.nb0䬻Fֺb!v(Bo^h lu%̭1uޱVn*gljTa[errCިhx/.xyeM~!·{02T8YbfZeB2pᚷsFrf?ݚ@X1{xxhͪ2 &뻂{An'v~"/I!40k|;vRfξdkT*6r+kW~k(9#wō| n|$13[)uʁLI]~Fpe܅GAFjkZ\Gʟs;R[PXecn' C6Vy"s4ʥ)L) 7b~}3ѽ^*:fdd4 K=g$yt̻Xe-7XvWI4-pg0[*h+GO̴B_H n$ S2$W:.+u%x!rh`ڥ`J݄1AVjF 9qCH~btaƕ%eZ0}Zk>L-1WVJ9Ɣ|K[nӤWZ4仼Bt*z$8_W-QPZ)j(g/*"`m2e0j &}L\<*(@,L)E`=L3y0u0~gۦ4)Ǿ'Gp*pG:j?oKZi{l/^Dm(NgUyk7>?vI&10vATGJ>J7KiHD  ww D% OPV%Z, }e`iE|n@<)ydKߜ<d_߳)83 k7|R^-&7t3Nz)jwtnsEd]cY3B`4Š97[踸~Zř6׃52z,Xb*@O˥BP_ʒgjXAD{ &e/'o% ϑoyQF*;]h3驧x (8ӫ&裾 O ƼDz B|܉tM}XЄ()l/S.+zJ 1J{ELĨۊ@NT5-k"Ug }p& X{ޫbֻ(fA I~o?T'/asɲgx``P4'ZЄ1.`۹ l2)N.T4FWF%Wz1Us$L=ƽ%6[jWT) t>epN.C*ԇܸ|?:#w7L&̓?3:Z/Zf?IQ͊;A /P'!:SRkدmvwb`w>vZ꡷r xD+@Rdћ&>SW"r|hA,}Z"v!k3= YTsP)L2mxAaB81n0{湲|IMTCRFbAa 7cYg/3r-"3vӝO_Z?C"yڜK+o-]6vpǝSR4E2'Y*XlΎ ]A9`ǟйn˜J0G7=C޷qr7("YHu ՟DF$^qzI0zY{'C׸ }Bwǁ`p5J49GB>E 9?&SX&tp^; W؇%zA77Ni%#p~We~32T!%e&0c)ͺ/+Z_Z"eŁh״Gرq~̇:4 0r4 Ek>/ƳLnY,"ݑIq/7f_-]Б $bophٹ"X8,J0iܮ -Ҳ㸖 ;+j={AIM)UQN-fO k0¬ڸOzR{]H_0'3`mKeA:|>)fl0nS% [,7EHNDU]0?Q=Wdo 7+Ke3^Ӓ b-BłӌF/j-|V*:PN5}:-Uf:!=+T ε"/-\G?򪪏WZ']תl21_)y߈n7ӿXdkS38{O.npc QV@xysu‘u~UZPx8$e%E]x ACdx1<#Sf)ܽYkH ]m{Y_U~RnU-U*pUeW(DI =sRWq?&N){8iU̖O1y-yĚ yyeׯ)",+czȣև?vk_\C#|s$OUsX9c 1U*b+33R5W|Gjק_0aG43BJFR³,^ǥ#uk};^ٙɄҜGdHJv9.EBGCyl_*)k0Er:D UW>wn̒ޱ7Xʠ`gf(|V8%4%A*r+jU[ 35x.WVB00FWoOmN"qj8`ВP*f5@XCY ŨYR Wy*GnMbm2 hv_Rnx0v-ZƼf1Q$2ϔyL;i7)7S1/}p9eb+)6 V/\"iua7e 8uR9懞h|H4w491ƫ^UԪK'v_33 W7eR"벷Tl}SH3'[%f =XnrSkZW􀆷ESō N!Dn|UT&V}WΒp9u>BkEϮHlRi RΐFkEܗ8 ?'iXrdKsee_#q}? u ֕B X<8Y*<;L9nNvceA+ZxA65s:7/U!'60ڰQ}cYe7¢BM\6|.ޞ_t$h2$FҮɒ+} @lm׭Jcx9\> p߯_͠x)X A \$Ģ75.ZO8 e` jr\ܰi2΃usS 㧥  /y~3rYK*H旇O̍[Vbܿ ʂ'U7?T"oJJwe5Ֆs+F ` ZTp&:cbܽ8$AqJ+>FL!k yb}4!=]{XY=N;lQzSCPd89'_ʹ?MLnmg?yz5N;4 Q$W+vFTZ}ZsDwFVN_Z`.~C$y\~IV$wuve5)fٜf%}Bv&euȈz0.$f-j!;a!A~BV_vM\m|rxBsֵ~.^Danj~d@ߵq,&݃gAģ(#,k]JU+B3lJeU݁ 1OFgtIf \u;=|JUĞe߃X"5xR +V)'i ",ƛd_^ѥX82ñO9ObUtQ@.:| f&,'})mR*\m0ޞ٘gv[ԽT+Ê>,j c7Kڊu9M^WQP$N knw> stream x[mSH_1KyR[ $YLMRԕ blb~=-dI]V"4zf~{FL IXbɤ``R3-<wb S"(rLifb͔aVId⤙Ǹ1{&FX"SXT1 MeCLmˌ1 Ts^1I IF3L %M)4fwh|9..s"ⱌ6)9^#a"RA;aH~~ϟDoOxr9_oh2 Sh! H|DH }`T8Rgh'Dvhj;/)쇃^3~<<<7QUhH #" dYa1Ҿz (-$8 t]EJr1e~Q<&P$*sD4v R%iT&됥P5Q D,֢6HGв&=(lA5%r(V.Iy'FM J-VQL4Yӎ&M#S-MF(XBGb#/dFљjXMo"PБq@Mb4zOZ_:{ёVkzβ[Λ^v=N$Y]`_n ?\\WBPJ9]~#1/xz lH- y1 \VC)#,{İBPL'o&#u\|P )ZIB 6\D4xM^-vF:| # /V )P68!ıs7>Q>f>W(p2rf ;lP@:w+y&%[Xj$9*iؑ9n}E㯟aG7zGIBơd3]SIj'}|,Y:Ud6dr9<3_ {G|8XO8&R :#zK?e]Ӏx8%8x׹/1:_)9n6G}Y_A:[J֥ftfeSWK*\x:ޥ52Ġ~~!_6* MG^GQzVdĒ\bulਘy+/˂dT陨YsYwt: T,}b|yoݥuL17qK!!3u|!&$8X.u*jyG&彂"JE~_05W(UzH);fK2p%'`gAAu)_vՁE=KKED\Y^!T)P lzt9UZ֪k'Ь|漦җ Y-W]lhzUc=0-ڽ^4YOdg9}TrUU@AThՊo =I xKz"\h\xջׇgG/힜JՄBb'粥"001!G/;&%ݾLW׸u4lKì7_l)F7Ko=2Zbޘ^9< zk=:&R} /H`l<]f"LcL.Yj`mi5HdE+ӯf&똹ۻevm%E}⽝ J#[:Hoпnr>~x{줻s$kٖAPڠk.$auk^5k1p=yIŖЗD[: lBw_jy')ͱ 爺9=yܻf9 Ca_ Ѵٮcvl>;tX=}g?f{oxw= `%Oyދ_F1W㴗c~@c<|GÔ._d%ƿMGYzy|'Mb4 yƳq)_xDx==: /cX T(rxt H^N @3ǰ9r4![+G{d٫oKk ';D{bZ$pf3_4rժ]A3t dӆryxtqniz5]f)8bKJuKeRٴT/45C^еr뻓oJZ-36&cCGn`nsJ/O'Wx~CZG >ץ%-j}i,t9V$KIܨw ~> 93?k{ZfVVtҟțșMJݷZ.I25|@6t+ v\|Uʏ+V}q\^C-jgqQ-r 1sGU _!O/qrE/v_/pVwf7[M7Ek`^~y #9,땧lꚦemY?lCe4cA~p.vڊW /+R~5>)pԃBs%t$eօxȹ S>?`^!xlE2c*Ŏ YIFTb:-oX!d9 a&L&6 `զZnX3+kV2LTzSJ9%7* >lY!^]lׅ|>kM}7I&^4b#d?d"~ T/ ,pܭͩss%s'~О\'颜<~snvS^A2"3̶#n*4F7ޯ(36PUMV*L]'_k2Zol^K7amzś=S[7:frݵivwUtU6;v-\:hffݳjlk77,[ *\ƍ &jS+(IߛN)-;9|,TuJƲnx=XBN~, J2du7` endstream endobj 134 0 obj << /Author(Dummy Auth\366r)/Title(The ThreeKPlusOne Package)/Subject()/Creator(LaTeX with hyperref package / GAPDoc)/Producer(pdfTeX-1.40.12)/Keywords() /CreationDate (D:20120223160825+01'00') /ModDate (D:20120223160825+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011) kpathsea version 6.0.1) >> endobj 126 0 obj << /Type /ObjStm /N 11 /First 81 /Length 557 /Filter /FlateDecode >> stream x}Tˎ@+hVZ3dYl.qMDZzG_28J>̀Y NNtwUW4T@0@TYh`Ӏ0@9C)Xk#1IMk^P/09;Cb9/sY[&a yJSX+=ɶ}5LsQ6eVar ]W:7_\/'?t$ ёMUw*&t'ӈM M.UjMU)2GRy,EjdOI}^ޥUEੱ릛٩t ؄ K7[5bl z8⼣f!;g,:g|amxxz-Xjs֐ tu?6['^U+wm0$~>X]m\mj[v ~sr&YjxKBUYҭ||w­4\]+A <4CE1002F4940229A5C2F7779895CF47A>] /Length 333 /Filter /FlateDecode >> stream x%ҷJDQc^uלs9k9`gou ;[ ++;7W0c3sq"NԝUA)8(afeP>hcf@,āU$`{ G ~=8]HTHtȀlHQqv-V!  rT"Z!C)lB9T@%C@#TĿأPM*v] = }0C0 #0⿷|Yg*.ɀUHjRo5zi5ta5U}{S[WZPw!c GAP (3k+1) - Index
Goto Chapter: Top 1 Bib Ind

Index

ThreeKPlusOneSequence 1.2-1

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/chap1_mj.html0000644000175000017500000001225712026346063014233 0ustar billbill GAP (3k+1) - Chapter 1: The \(3k+1\) Problem
Goto Chapter: Top 1 Bib Ind

1 The \(3k+1\) Problem

1.1 Theory

Let \(k \in ℕ\) be a natural number. We consider the sequence \(n(i, k), i \in ℕ,\) with \(n(1, k) = k\) and else \(n(i+1, k) = n(i, k) / 2\) if \(n(i, k)\) is even and \(n(i+1, k) = 3 n(i, k) + 1\) if \(n(i, k)\) is odd.

It is not known whether for any natural number \(k \in ℕ\) there is an \(m \in ℕ\) with \(n(m, k) = 1\).

ThreeKPlusOne provides the function ThreeKPlusOneSequence (1.2-1) to explore this for given \(n\). If you really want to know something about this problem, see [Wir98] or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ for more details (and forget this package).

1.2 Program

In this section we describe the main function of this package.

1.2-1 ThreeKPlusOneSequence
‣ ThreeKPlusOneSequence( k[, max] )( function )

This function computes for a natural number k the beginning of the sequence \(n(i, k)\) defined in section 1.1. The sequence stops at the first \(1\) or at \(n(\textit{max}, k)\), if max is given.

gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/chap0_mj.html0000644000175000017500000000635712026346063014236 0ustar billbill GAP (3k+1) - Contents
Goto Chapter: Top 1 Bib Ind

The ThreeKPlusOne Package

Version 42

Dummy Authör
Email: 3kplusone@dev.null

Copyright

© 2000 The Author.

You can do with this package what you want.

Really.

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/3k+1.bib0000644000175000017500000000052612026346063013006 0ustar billbill% 3k+1 bibliography @book {Wi98, author = {Wirsching, Günther J.}, title = {The dynamical system generated by the $3n+1$ function}, publisher = {Springer-Verlag}, series = {Lecture Notes in Mathematics}, volume = {1681}, address = {Berlin}, year = {1998}, pages = {viii+158}, isbn = {3-540-63970-5} } GAPDoc-1.5.1/3k+1/3k+1.xml0000644000175000017500000000423412026346063013052 0ustar billbill The <Package>ThreeKPlusOne</Package> Package Version 42 Dummy Authör 3kplusone@dev.null ©right; 2000 The Author.

You can do with this package what you want.

Really. The 3k+1 Problem

Theory Let k \in &NN; be a natural number. We consider the sequence n(i, k), i \in &NN;, with n(1, k) = k and else n(i+1, k) = n(i, k) / 2 if n(i, k) is even and n(i+1, k) = 3 n(i, k) + 1 if n(i, k) is odd.

It is not known whether for any natural number k \in &NN; there is an m \in &NN; with n(m, k) = 1.

ThreeKPlusOne provides the function to explore this for given n. If you really want to know something about this problem, see or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ for more details (and forget this package).

Program In this section we describe the main function of this package. This function computes for a natural number k the beginning of the sequence n(i, k) defined in section . The sequence stops at the first 1 or at n(max, k), if max is given. gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package"
GAPDoc-1.5.1/3k+1/rainbow.js0000644000175000017500000000533612026346063013662 0ustar billbill function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); GAPDoc-1.5.1/3k+1/nocolorprompt.css0000644000175000017500000000031312026346063015300 0ustar billbill /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } GAPDoc-1.5.1/3k+1/chapBib.txt0000644000175000017500000000042512026346063013746 0ustar billbill References [Wir98] Wirsching, G. J., The dynamical system generated by the 3n+1 function, Springer-Verlag, Lecture Notes in Mathematics, 1681, Berlin (1998), viii+158 pages.  GAPDoc-1.5.1/3k+1/manual.js0000644000175000017500000001003412026346063013465 0ustar billbill/* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { document.writeln(''); document.writeln(''); } } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } GAPDoc-1.5.1/3k+1/chap1.html0000644000175000017500000001166612026346063013550 0ustar billbill GAP (3k+1) - Chapter 1: The 3k+1 Problem
Goto Chapter: Top 1 Bib Ind

1 The 3k+1 Problem

1.1 Theory

Let k ∈ ℕ be a natural number. We consider the sequence n(i, k), i ∈ ℕ, with n(1, k) = k and else n(i+1, k) = n(i, k) / 2 if n(i, k) is even and n(i+1, k) = 3 n(i, k) + 1 if n(i, k) is odd.

It is not known whether for any natural number k ∈ ℕ there is an m ∈ ℕ with n(m, k) = 1.

ThreeKPlusOne provides the function ThreeKPlusOneSequence (1.2-1) to explore this for given n. If you really want to know something about this problem, see [Wir98] or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ for more details (and forget this package).

1.2 Program

In this section we describe the main function of this package.

1.2-1 ThreeKPlusOneSequence
‣ ThreeKPlusOneSequence( k[, max] )( function )

This function computes for a natural number k the beginning of the sequence n(i, k) defined in section 1.1. The sequence stops at the first 1 or at n(max, k), if max is given.

gap> ThreeKPlusOneSequence(101);
"Sorry, not yet implemented. Wait for Version 84 of the package"
Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/toggless.css0000644000175000017500000000167212026346063014223 0ustar billbill/* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } GAPDoc-1.5.1/3k+1/lefttoc.css0000644000175000017500000000047412026346063014033 0ustar billbill/* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } GAPDoc-1.5.1/3k+1/chapBib_mj.html0000644000175000017500000000471212026346063014564 0ustar billbill GAP (3k+1) - References
Goto Chapter: Top 1 Bib Ind

References

[Wir98] Wirsching, G. J., The dynamical system generated by the 3n+1 function, Springer-Verlag, Lecture Notes in Mathematics, 1681, Berlin (1998), viii+158 pages.

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/chapInd.txt0000644000175000017500000000020412026346063013757 0ustar billbill Index ThreeKPlusOneSequence 1.2-1 ------------------------------------------------------- GAPDoc-1.5.1/3k+1/3k+1.toc0000644000175000017500000000100312026346063013026 0ustar billbill\contentsline {chapter}{\numberline {1}\leavevmode {\color {Chapter }The $3k+1$ Problem}}{4}{chapter.1} \contentsline {section}{\numberline {1.1}\leavevmode {\color {Chapter }Theory}}{4}{section.1.1} \contentsline {section}{\numberline {1.2}\leavevmode {\color {Chapter }Program}}{4}{section.1.2} \contentsline {subsection}{\numberline {1.2.1}\leavevmode {\color {Chapter }ThreeKPlusOneSequence}}{4}{subsection.1.2.1} \contentsline {chapter}{References}{5}{chapter*.3} \contentsline {chapter}{Index}{6}{section*.4} GAPDoc-1.5.1/3k+1/chap0.txt0000644000175000017500000000134712026346063013415 0ustar billbill The ThreeKPlusOne Package Version 42 Dummy Authör Dummy Authör Email: mailto:3kplusone@dev.null ------------------------------------------------------- Copyright © 2000 The Author. You can do with this package what you want. Really. ------------------------------------------------------- Contents (3k+1) 1 The 3k+1 Problem 1.1 Theory 1.2 Program 1.2-1 ThreeKPlusOneSequence  GAPDoc-1.5.1/3k+1/chapInd.html0000644000175000017500000000346312026346063014116 0ustar billbill GAP (3k+1) - Index
Goto Chapter: Top 1 Bib Ind

Index

ThreeKPlusOneSequence 1.2-1

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/ragged.css0000644000175000017500000000023112026346063013613 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } GAPDoc-1.5.1/3k+1/manual.css0000644000175000017500000001575412026346063013657 0ustar billbill/* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } GAPDoc-1.5.1/3k+1/chapBib.html0000644000175000017500000000443412026346063014077 0ustar billbill GAP (3k+1) - References
Goto Chapter: Top 1 Bib Ind

References

[Wir98] Wirsching, G. J., The dynamical system generated by the 3n+1 function, Springer-Verlag, Lecture Notes in Mathematics, 1681, Berlin (1998), viii+158 pages.

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/3k+1.tex0000644000175000017500000001352012026346063013050 0ustar billbill% generated by GAPDoc2LaTeX from XML source (Frank Luebeck) \documentclass[a4paper,11pt]{report} \usepackage{a4wide} \sloppy \pagestyle{myheadings} \usepackage{amssymb} \usepackage[latin1]{inputenc} \usepackage{makeidx} \makeindex \usepackage{color} \definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083} \definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179} \definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894} \definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894} \definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000} \definecolor{Black}{rgb}{0.0,0.0,0.0} \definecolor{linkColor}{rgb}{0.0,0.0,0.554} \definecolor{citeColor}{rgb}{0.0,0.0,0.554} \definecolor{fileColor}{rgb}{0.0,0.0,0.554} \definecolor{urlColor}{rgb}{0.0,0.0,0.554} \definecolor{promptColor}{rgb}{0.0,0.0,0.589} \definecolor{brkpromptColor}{rgb}{0.589,0.0,0.0} \definecolor{gapinputColor}{rgb}{0.589,0.0,0.0} \definecolor{gapoutputColor}{rgb}{0.0,0.0,0.0} %% for a long time these were red and blue by default, %% now black, but keep variables to overwrite \definecolor{FuncColor}{rgb}{0.0,0.0,0.0} %% strange name because of pdflatex bug: \definecolor{Chapter }{rgb}{0.0,0.0,0.0} \definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064} \usepackage{fancyvrb} \usepackage{mathptmx,helvet} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage[ pdftex=true, bookmarks=true, a4paper=true, pdftitle={Written with GAPDoc}, pdfcreator={LaTeX with hyperref package / GAPDoc}, colorlinks=true, backref=page, breaklinks=true, linkcolor=linkColor, citecolor=citeColor, filecolor=fileColor, urlcolor=urlColor, pdfpagemode={UseNone}, ]{hyperref} \newcommand{\maintitlesize}{\fontsize{50}{55}\selectfont} % write page numbers to a .pnr log file for online help \newwrite\pagenrlog \immediate\openout\pagenrlog =\jobname.pnr \immediate\write\pagenrlog{PAGENRS := [} \newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}} %% were never documented, give conflicts with some additional packages \newcommand{\GAP}{\textsf{GAP}} %% nicer description environments, allows long labels \usepackage{enumitem} \setdescription{style=nextline} %% depth of toc \setcounter{tocdepth}{1} %% command for ColorPrompt style examples \newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}} \newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}} \newcommand{\gapinput}[1]{\color{gapinputColor}{#1}} \begin{document} \logpage{[ 0, 0, 0 ]} \begin{titlepage} \mbox{}\vfill \begin{center}{\maintitlesize \textbf{The \textsf{ThreeKPlusOne} Package\mbox{}}}\\ \vfill \hypersetup{pdftitle=The \textsf{ThreeKPlusOne} Package} \markright{\scriptsize \mbox{}\hfill The \textsf{ThreeKPlusOne} Package \hfill\mbox{}} {\Huge Version 42\mbox{}}\\[1cm] \mbox{}\\[2cm] {\Large \textbf{Dummy Auth{\"o}r \mbox{}}}\\ \hypersetup{pdfauthor=Dummy Auth{\"o}r } \end{center}\vfill \mbox{}\\ {\mbox{}\\ \small \noindent \textbf{Dummy Auth{\"o}r } Email: \href{mailto://3kplusone@dev.null} {\texttt{3kplusone@dev.null}}}\\ \end{titlepage} \newpage\setcounter{page}{2} {\small \section*{Copyright} \logpage{[ 0, 0, 1 ]} {\copyright} 2000 The Author. You can do with this package what you want. Really. \mbox{}}\\[1cm] \newpage \def\contentsname{Contents\logpage{[ 0, 0, 2 ]}} \tableofcontents \newpage \chapter{\textcolor{Chapter }{The $3k+1$ Problem}}\logpage{[ 1, 0, 0 ]} \hyperdef{L}{X866DB48D7A6CEF85}{} { \section{\textcolor{Chapter }{Theory}}\label{sec:theory} \logpage{[ 1, 1, 0 ]} \hyperdef{L}{X8729B87B848E3F89}{} { Let $k \in {\ensuremath{\mathbb N}}$ be a natural number. We consider the sequence $n(i, k), i \in {\ensuremath{\mathbb N}},$ with $n(1, k) = k$ and else $n(i+1, k) = n(i, k) / 2$ if $n(i, k)$ is even and $n(i+1, k) = 3 n(i, k) + 1$ if $n(i, k)$ is odd. It is not known whether for any natural number $k \in {\ensuremath{\mathbb N}}$ there is an $m \in {\ensuremath{\mathbb N}}$ with $n(m, k) = 1$. \textsf{ThreeKPlusOne} provides the function \texttt{ThreeKPlusOneSequence} (\ref{ThreeKPlusOneSequence}) to explore this for given $n$. If you really want to know something about this problem, see \cite{Wi98} or \href{http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/} {\texttt{http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/}} for more details (and forget this package). } \section{\textcolor{Chapter }{Program}}\logpage{[ 1, 2, 0 ]} \hyperdef{L}{X7A4605C07A94C9F6}{} { In this section we describe the main function of this package. \subsection{\textcolor{Chapter }{ThreeKPlusOneSequence}} \logpage{[ 1, 2, 1 ]}\nobreak \hyperdef{L}{X7B1A31B8870EA092}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{ThreeKPlusOneSequence({\mdseries\slshape k[, max]})\index{ThreeKPlusOneSequence@\texttt{ThreeKPlusOneSequence}} \label{ThreeKPlusOneSequence} }\hfill{\scriptsize (function)}}\\ This function computes for a natural number \mbox{\texttt{\mdseries\slshape k}} the beginning of the sequence $n(i, k)$ defined in section \ref{sec:theory}. The sequence stops at the first $1$ or at $n(\mbox{\texttt{\mdseries\slshape max}}, k)$, if \mbox{\texttt{\mdseries\slshape max}} is given. \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@ThreeKPlusOneSequence(101);| "Sorry, not yet implemented. Wait for Version 84 of the package" \end{Verbatim} } } } \def\bibname{References\logpage{[ "Bib", 0, 0 ]} \hyperdef{L}{X7A6F98FD85F02BFE}{} } \bibliographystyle{alpha} \bibliography{3k+1} \addcontentsline{toc}{chapter}{References} \def\indexname{Index\logpage{[ "Ind", 0, 0 ]} \hyperdef{L}{X83A0356F839C696F}{} } \cleardoublepage \phantomsection \addcontentsline{toc}{chapter}{Index} \printindex \newpage \immediate\write\pagenrlog{["End"], \arabic{page}];} \immediate\closeout\pagenrlog \end{document} GAPDoc-1.5.1/3k+1/chap0.html0000644000175000017500000000606112026346063013540 0ustar billbill GAP (3k+1) - Contents
Goto Chapter: Top 1 Bib Ind

The ThreeKPlusOne Package

Version 42

Dummy Authör
Email: 3kplusone@dev.null

Copyright

© 2000 The Author.

You can do with this package what you want.

Really.

Goto Chapter: Top 1 Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/3k+1/chap1.txt0000644000175000017500000000322712026346063013415 0ustar billbill 1 The 3k+1 Problem 1.1 Theory Let k ∈ ℕ be a natural number. We consider the sequence n(i, k), i ∈ ℕ, with n(1, k) = k and else n(i+1, k) = n(i, k) / 2 if n(i, k) is even and n(i+1, k) = 3 n(i, k) + 1 if n(i, k) is odd. It is not known whether for any natural number k ∈ ℕ there is an m ∈ ℕ with n(m, k) = 1. ThreeKPlusOne provides the function ThreeKPlusOneSequence (1.2-1) to explore this for given n. If you really want to know something about this problem, see [Wir98] or http://mathsrv.ku-eichstaett.de/MGF/homes/wirsching/ for more details (and forget this package). 1.2 Program In this section we describe the main function of this package. 1.2-1 ThreeKPlusOneSequence ThreeKPlusOneSequence( k[, max] )  function This function computes for a natural number k the beginning of the sequence n(i, k) defined in section 1.1. The sequence stops at the first 1 or at n(max, k), if max is given.  Example  gap> ThreeKPlusOneSequence(101); "Sorry, not yet implemented. Wait for Version 84 of the package"  GAPDoc-1.5.1/3k+1/times.css0000644000175000017500000000026112026346063013506 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } GAPDoc-1.5.1/3k+1/toggless.js0000644000175000017500000000420512026346063014042 0ustar billbill/* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); GAPDoc-1.5.1/3k+1/manual.six0000644000175000017500000000231212026346063013654 0ustar billbill#SIXFORMAT GapDocGAP HELPBOOKINFOSIXTMP := rec( encoding := "UTF-8", bookname := "ThreeKPlusOne", entries := [ [ "Title page", ".", [ 0, 0, 0 ], 1, 1, "title page", "X7D2C85EC87DD46E5" ], [ "Copyright", ".-1", [ 0, 0, 1 ], 17, 2, "copyright", "X81488B807F2A1CF1" ] , [ "Table of Contents", ".-2", [ 0, 0, 2 ], 26, 3, "table of contents", "X8537FEB07AF2BEC8" ], [ "\033[1X\033[33X\033[0;-2YThe \033[22X3k+1\033[122X\033[101X\027\033[1X\\ 027 Problem\033[133X\033[101X", "1", [ 1, 0, 0 ], 1, 4, "the 3k+1\027\027 problem", "X866DB48D7A6CEF85" ], [ "\033[1X\033[33X\033[0;-2YTheory\033[133X\033[101X", "1.1", [ 1, 1, 0 ], 4, 4, "theory", "X8729B87B848E3F89" ], [ "\033[1X\033[33X\033[0;-2YProgram\033[133X\033[101X", "1.2", [ 1, 2, 0 ], 19, 4, "program", "X7A4605C07A94C9F6" ], [ "Bibliography", "bib", [ "Bib", 0, 0 ], 1, 5, "bibliography", "X7A6F98FD85F02BFE" ], [ "References", "bib", [ "Bib", 0, 0 ], 1, 5, "references", "X7A6F98FD85F02BFE" ], [ "Index", "ind", [ "Ind", 0, 0 ], 1, 6, "index", "X83A0356F839C696F" ], [ "\033[2XThreeKPlusOneSequence\033[102X", "1.2-1", [ 1, 2, 1 ], 24, 4, "threekplusonesequence", "X7B1A31B8870EA092" ] ] ); GAPDoc-1.5.1/version0000644000175000017500000000000612026346063012607 0ustar billbill1.5.1 GAPDoc-1.5.1/README0000644000175000017500000000606312026346064012071 0ustar billbill GAPDoc --- A GAP 4 package for preparing documentation of GAP programs Frank Lübeck Max Neunhöffer (Lehrstuhl D für Mathematik, RWTH Aachen) This package provides: - Utilities to use the documentation (of GAP packages and in the future the GAP manuals as well) which is written in GAPDoc format with the GAP help system. If you don't want to write your own (package) documentation you can skip the remaining points. - The description of a markup language for GAP documentation (which is defined using the XML standard). - Three example documents using this language: The GAPDoc documentation itself, a short example which demonstrates all constructs defined in the GAPDoc language, and a very short example explained in the introduction of the main documentation. - A mechanism for distributing documentation among several files, including source code files. - GAP programs (written by the first named author) which produce from documentation written in the GAPDoc language several document formats: □ text format with color markup for onscreen browsing. □ LaTeX format and from this PDF- (and DVI)-versions with hyperlinks. □ HTML (XHTML 1.0 strict) format for reading with a Web-browser (and many hooks for CSS layout). - Utility GAP programs which are used for the above but can be of independent interest as well: * unicode strings with translations to and from other encodings * further utilities for manipulating strings * tools for dealing with BibTeX data * another data format BibXMLext for bibliographical data including tools to manipulate/translate them * a tool ComposedDocument for composing documents which are distributed in many files For further information see: http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/ INSTALLATION Just unpack one of the archives in the "pkg" subdirectory of your GAP installation. The archive is available in several formats: GAPDoc-XXX.zoo (use the "unzoo" or "unzoo.exe" from the GAP homepage) GAPDoc-XXX.tar.gz (GNU tar archive, gzip'ed) GAPDoc-XXX.tar.bz2 (GNU tar archive, bzip2'ed) GAPDoc-XXX-win.zip (with DOS/Windows style line breaks in text files) Unpacking generates a subdirectory "gapdoc". That's it! (Maybe you want to read the help section "?SetHelpViewer" in the GAP reference manual.) Installation *outside the GAP main directory*: When you don't have access to the directory of your main GAP installation you can also install the package by unpacking inside a directory "MYGAPDIR/pkg". (Don't forget to call "gap" with the '-l ";MYGAPDIR"' option.) The only drawback with this installation is that in the HTML version of the package documentation the links to the main GAP manuals don't work. You can correct this by recompiling the GAPDoc documentation: Say 'cd GAPDoc*; gap makedocrel.g'. For questions, suggestions, ... write to Frank.Luebeck@Math.RWTH-Aachen.De Frank Lübeck GAPDoc-1.5.1/example/0000755000175000017500000000000012174444011012632 5ustar billbillGAPDoc-1.5.1/example/clean0000755000175000017500000000017612026346064013653 0ustar billbill#!/bin/bash rm -f *.{aux,log,dvi,ps,pdf,bbl,ilg,ind,idx,out,html,tex,pnr,txt,blg,toc,six,brf,js,css,lab} examplebib.xml.bib GAPDoc-1.5.1/example/chooser.html0000644000175000017500000000745612026346064015203 0ustar billbill GAPDoc Style Chooser

Setting preferences for GAPDoc manuals

Unfold subsections in menus only by mouse clicks: no (default)     yes

Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

Display side of table of contents within chapters: right (default)     left

Main document font: Helvetica/sans serif (default)     Times/serif

Paragraph formatting: left-right justified (default)     ragged right

Apply settings to last page.

GAPDoc-1.5.1/example/chapA.txt0000644000175000017500000000021012026346064014405 0ustar billbill A An Appendix [→ B.11] This is an appendix. GAPDoc-1.5.1/example/example.xml0000644000175000017500000007223312026346064015023 0ustar billbill $\to$'> ]> A Complete Example (&see; <Ref Sect="One"/>) Every element shows up Version <#Include SYSTEM "../version"> If the subtitle ist not sufficient, this <TitleComment> element can be used for a slightly longer text on the front page. Frank Lübeck Frank.Luebeck@Math.RWTH-Aachen.De Max Neunhöffer neunhoef at mcs.st-and.ac.uk February 2012
Lehrstuhl D für Mathematik
Templergraben 64
52062 Aachen
(Germany)
This document tries to use all elements that exist in &GAPDoc;. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn &GAPDoc; quickly. ©right; 2000-2012 by Frank Lübeck and Max Neunhöffer We thank Lehrstuhl D für Mathematik. This is the Colophon page.
Text before chapter . (&see; ) Sectioning Elements Text before the section . (&see; ) Other Markup
Various types of text [&see; ]

In this section we present examples for all the various types of text that are possible in &GAPDoc;: This is emphasized. Keywords are typeset like this and that. Arguments of functions have an element. They look like this: x and y. Code can be written with the Code element: if x = y then Print("Equal"); fi; or while true do Print("Hello"); od;. Filenames have their own element: /usr/local/ca/gap4r2 or pkg/xgap/doc. Buttons, menus, menu entries, and such things are also supported: OK or . Packages are typeset like this: Small Groups Library Quoted text: This is a text in quotes. Paragraphs are separated by the empty Par or P element. Alternatives for different output formats: This is &LaTeX; output. This is other than &LaTeX; output, namely: HTML]]> Text output.

The first is a Listing:

Here is a Log of a &GAP; session using this function: gap> Sieve(100); [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ] gap> Length(last); 25 Here is a &GAP; Example session that is automatically tested: gap> s := Size(CharacterTable("M")); 808017424794512875886459904961710757005754368000000000 gap> s < 10^53; false gap> s < 10^54; true
Formulae
Crossreferencing
Lists and Tables
Entities and Special Characters
An Appendix
GAPDoc-1.5.1/example/chap2.txt0000644000175000017500000002663112026346064014405 0ustar billbill 2 Other Markup 2.1 Various types of text [→ B.5] In this section we present examples for all the various types of text that are possible in GAPDoc:  This is emphasized.  Keywords are typeset like this and that.  Arguments of functions have an element. They look like this: x and y.  Code can be written with the Code element: if x = y then Print("Equal"); fi; or while true do Print("Hello"); od;.  Filenames have their own element: /usr/local/ca/gap4r2 or pkg/xgap/doc.  Buttons, menus, menu entries, and such things are also supported: OK or Cancel.  Packages are typeset like this: Small Groups Library  Quoted text: This is a text in quotes. Paragraphs are separated by the empty Par or P element. Alternatives for different output formats: This is other than LaTeX output, namely: Text output. There are also three elements to typeset verbatim-like text. (→ B.6) The first is a Listing:  GAP code  Sieve := function(n)  # Returns the primes less than n  local l,p,i;  l := [1..n]; Unbind(l[1]);  p := 2;  while p^2 <= n do  if IsBound(l[p]) then  i := 2 * p;  while i <= n do Unbind(l[i]); i := i + p; od;  fi;  p := p + 1;  od;  return Compacted(l); end;  Here is a Log of a GAP session using this function:  Example  gap> Sieve(100); [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,  67, 71, 73, 79, 83, 89, 97 ] gap> Length(last); 25  Here is a GAP Example session that is automatically tested:  Example  gap> s := Size(CharacterTable("M")); 808017424794512875886459904961710757005754368000000000 gap> s < 10^53;  false gap> s < 10^54; true  2.2 Formulae [→ B.7] There are three types of formulae. The first is the normal math mode of LaTeX: b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k. Then there are displayed formulae: \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k  If possible, use the Alt element to specify a better readable text version of such a formula as in the following example: d d d ----- ----- ----- ----- \ \ \ \ ==> ( ) x_i b_i )( ) y_j b_j ) = ) ( ) x_i y_j h_ijk ) b_k / / / / ----- ----- ----- ----- i = 1 j = 1 k = 1 i,j For small formulae without difficult parts use the M element: b_i, x^2, x^2 + 2x + 1 = (x + 1)^2. Note that here whitespace matters for text (or HTML) output. Here are two formulae containing less than characters which are special characters for XML: a < b < c < d and e < f. Using the Mode attribute of a Display element formulae like a ⟶ a mod m' can also be displayed nicely in text and HTML output. 2.3 Crossreferencing [→ B.8] In this section we demonstrate various references to parts of this document. Here is a reference to this section: 2.3. Here is a reference to chapter 1, to appendix A, and to subsection 1.1-1. We distinguish among others references to functions (see f (1.2-1)), to methods with tricky name (see \^\{\}\[\]\<\& (1.2-2)), to operations (see MyOperation (1.2-3)), to methods (see MyOperation (1.2-4) or MyOperation (1.2-5)), to filters (see IsBla (1.2-6)), to properties (see IsBlubb (1.2-7)), to attributes (see NumberBlobbs (1.2-8)), to variables (AllBlibbs (1.2-9)), to families (see BlibbsFamily (1.2-10)), and to info classes (see InfoBlibbs (1.2-11)). There are also references to labels: see 2.3, to other books: see 'GAPDoc: What is a DTD?' or IsSubgroup (Reference: IsSubgroup) in the GAP reference manual. References to sections come in two styles: 1 or 'Sectioning Elements'. Another type of cross referencing is bibliography. Here is a citation: [CR81, (5.22)] is an interesting lemma. There are also URLs: http://www.math.rwth-aachen.de/ Email addresses have a special element: mailto:Frank.Luebeck@Math.RWTH-Aachen.De and Homepages another one: http://www-groups.mcs.st-and.ac.uk/~neunhoef/ And here is a link to the EDIM archives (http://www.math.rwth-aachen.de/~Frank.Luebeck/gap/EDIM/index.html#ARCHS). One can generate index entries as follows (look up the words TeX-UserGroup, RWTH, Aachen, Hauptbahnhof, and GAP, GAPDoc). 2.4 Lists and Tables [→ B.9] There are  lists  enumerations, and  tables or: 1 lists 2 enumerations, and 3 tables or with marks: lists: not numbered enumerations: numbered tables: two-dimensional Lists can also be nested: 1 1 first item of inner enumeration 2 second item of inner enumeration 2  first item of inner list  second item of inner list Here is a table: ┌────────┬───────┬───────────┐ │ Object │ Price │ available │ ├────────┼───────┼───────────┤ ├────────┼───────┼───────────┤ │ Shoe │ $1,00 │ there │ ├────────┼───────┼───────────┤ │ Hat │ $2,00 │ not there │ └────────┴───────┴───────────┘ Table: Prices 2.5 Entities and Special Characters [→ B.10] Here is a table of special characters, the first two are special for XML and must be typed in by entities in GAPDoc documents. The other characters are special for LaTeX but in GAPDoc they can be typed directly. ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ & │ < │ > │ # │ $ │ % │ ~ │ \ │ { │ } │ _ │ ^ │   │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ Table: Special characters in character data And here are the predefined entities in GAPDoc: ┌─────────────┬─────────┐ │ &GAP; │ GAP │ ├─────────────┼─────────┤ │ &GAPDoc; │ GAPDoc │ ├─────────────┼─────────┤ │ &TeX; │ TeX │ ├─────────────┼─────────┤ │ &LaTeX; │ LaTeX │ ├─────────────┼─────────┤ │ &BibTeX; │ BibTeX │ ├─────────────┼─────────┤ │ &MeatAxe; │ MeatAxe │ ├─────────────┼─────────┤ │ &XGAP; │ XGAP │ ├─────────────┼─────────┤ │ ©right; │ © │ └─────────────┴─────────┘ Table: Predefined Entities in the GAPDoc system And some more for mathematical symbols: ℂ, ℤ, ℕ, ℙ, ℚ, ℍ, ℝ. GAPDoc-1.5.1/example/manual.pdf0000644000175000017500000077247612026346064014636 0ustar billbill%PDF-1.5 % 100 0 obj << /Length 697 /Filter /FlateDecode >> stream xڭUMo@W,7[~xw !ZPYpd[q{f봡!73oޛ %kBՌ,Ԋ)$Lp1\%%(lIa% >4&}&T'Q,! 6ąQIm(OKp W6fF2&^=TqJOY΀<a}+cЉfq.@ \`S?CF>MeKW4_{]ք?* ŮƜ_CʦvP(4BA/ͼ#N߳a1XcD#1L$fq;d; uq'ZL{M,OH}~Z!Zˠ/Z0>dAʮw!uarQ(qЯ8ᘢ\,2(ʠ0kW`nЙ{Z5#+Z뢯h^#dO9jj^NJkcg$).#B78GR$<}?SP22z0/P}NEaj87'Thi"<)#Lj[1>V{] >% 6ϙXNiy.mȒtɱEqxMvPTn +Vho+;rrs̕Yʱ7Xts㝧cɩ.w,޿W⒠ٿE6 E} endstream endobj 111 0 obj << /Length 688 /Filter /FlateDecode >> stream xڍK0 qܷZUUE!N@!6Iu|31#;fzd%"i&$Kܐu ɂ[{h4jG5dǫ,;4bMnލ FOʄt;r/rts-1x.g`t1|R\Ҕ (%$y׽TN'tԮ=qqŘ0A<>Gkg*q6A%FWH_(%Pa1H"P` T[Wﴭ6OPrPwo:H7Jw: >H47_A!> stream xo0W`cRuZn4uR"H?;@[u@)C!w dGӐ @D$;)r-s]BP@-Aye0ADCze@k\B]ɹΊ<˗~NWa%<_" DBF?Ξ-C(77eXG^Dg.4l?lv!۰;HOd4i e5\Pc;ļHf`QOX\Sq#TeŦ<ѿײ-##=7{;՚3U*a  J,\H%hF_Pj!8u%+u]RI|aݬdrvɏ:ә|j-YӮܥ*k@{ }D6ƏzW>fz-OMY BN( o|Sbz!=΀ᘷgֵxez%ێ%]־4eKsK w]d`)um;-̙\&xR?n棡d퉍5HwjFO>:8hw/契2 Ǻ`z3 i>cc\1Ju!Xe>8L3x03'Kl~~rCZ6JxpyT4!6{(DXF ә6 (q5 *b֢=g߁7$<Uv:pHCIO?# endstream endobj 152 0 obj << /Length 239 /Filter /FlateDecode >> stream xڕPn1+6ݹeo!;HÐ"tsBJ ޑgvfv@0ƱMG q R{ V3SheuL]*> stream xVMo@WKY\*Z=$9%F!XMUwv򦱫|yx3f yps}Bbzrv Q"4u"pD?3s?Jqd>tB u̯|p70 a$*+,h /r#j ή"%1 I L'!uT5 l6Fs cV0jg$H`#QN_^ 'Ѻ́O aH0~Lhx>'6?V sJ(7Z[h^8f6fTFËxǼ;RĜkRBbD[R ;`IWٶyߜAf](e$~bݖ4=QzD4uv2^ȵeJRK;nuѢ-y"[QյŽe F-H=q40åh)etUlM nF`H )Iu rzNJ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 802 /Length 2003 /Filter /FlateDecode >> stream xYn9}ﯨdI c0v2 ޹9~h+`[2=բ_ՊݳX [lxXuX!MXS o)Srd4y2 :!&Ɂ!kSe-Y/d1Ϣ?1("b& O3䲫%s 2y#^P;(D&)OR02O Bl(al5FS(/bGZB鐪dd JmLLЏ.2d>ʰ8 5> L" d(h+JLVk!Y$`!Wu,+[X/V("F" D({Va鱰 ԃ={-=M`bkA9 3 UrΡp> Y`(] =VfŨpe0`0Ȥу}A @&~@` M@20daO)A[&Cd2}G1̩~G&M.yM}W:n't>v-_?\Rf3usEyyu]O̎UhY\nm7x~ijIn%?S~+b6C..6ŭ.%5OtҜ_mSznMv2^4f<"ig_ZKז'-Wlt|2ڟ?[j=mӊEKŲwP4vdCjGhM7~s5l{B8?掳4qv~;6z'*n6FGeS"MGTN3WbaUv>JdU}.is0B2g$z&gTgazl6Sv&YuE?W]tvYŧv/귧!&r*D?uWF0nc@[qו$A<;?HHVf"}Lzo_$U7{].٥zjBzfrԻ&UD* Bzbt;kWyvR-78-PBF5FSFsg!0JJƅ}Vʏ>P>Jf D?/JR{t(($w{ѩq̃F=,vP `ðJ#ILVҼeulT,z`&Qƿ4= ߗ˃ukJkK˥u M-"<."<."yΌI$Bmr^ Eh ǝݤ9,!'r @_@e=䘿 REYVy*86uA+mVkx0@QZ؅ڰU\NLK8ׇK("GC~4LJA>W Y(r@G(wG%l1*?Qq:EP.9\<^;* T/:9v[3ppN;?;w6)סn'1⭅29"I~GL!i\5r1eKoȡ5KC88,JJBah;YqqvXqtNc} X/ pǑP8Gs!00P"wQQ[*9r{4* Cm5* S3Č\, Q*D(iz"-usS!zgط]*[yTRr/bpz|4ȇ69"ˇYMgTqz7(VOFoIϥfxxs_zse/\BU?*U < XZW2r-䑟GoHV:W  $7Q|5ja٩hy9<:6r]Pa66 endstream endobj 187 0 obj << /Length 1133 /Filter /FlateDecode >> stream xWK6Po2P3|:8H@&($/U![$P 6h&g|3ǻݒ`)(Lƣ\@rO c[=zlNߧCb Vv/-HS )"@W){#칟˶^㯏g6`,qb7('N(Ayhs^ߔ{`As&›ètw }5{daoÃ)Z9a ^G`}^9_<'@[R!U}ۨd$kۂ(A,S8 tGfδFR0xB8Nꩊ3$CұwĀHoqM^ُzHPZ:@*A A8QḄ /m8Sg8ˋ3A7vxJo#e^A^q0Y6(nXԱ5{뮠 tZ73*4KO(<: m> >.RP(Tpİx}tntDߍAn7#\~0)ڦT$2,,,/ s lKIj{^3R{Խ3<:l0$Y$񏁵ݯ||}Aa܂"f\ > stream x}Rn@  8*c-4O)-$R5TH==BpU4/RIAms f[XIyw Z|-Bi~ zxWGsvD9g>)"=Q MK\\" 90's408:H9Y&3 5*u ESOIśf6i Ռ5(..\n,N{I,ZN/ov.fNӣ&B.D ]_m%z8Vˀe-Kt~pz>./ endstream endobj 216 0 obj << /Length 1938 /Filter /FlateDecode >> stream xڭY[wF~ j^Yp$MKڤs\,ac$8 XQ/O>Q@1"*U 1EpXUՓ)8O'V G2D '(&{._fSV!2p|DB(2E 4Χc1Ihyí]eyeeہ1 F N&Fs[zW}Ճs9)ϑi.ԃ`æ]ǵ-&yifZY[sM?p*WҢp웟&TֽUZ˦/ {! =KqF^?{}97;u:j 9fR14dWh8SL  $nSi-|ZvJB"'LnL /2.P}ufY7ǀy?D";ϥW8+ l4r$N@FrT<ެ q6KH:dڬuY(7&Sf-uY[]9= 춱٧p"*={8ky'}Q.2ϡN2$g$6vik*S -V@$씃_`Q}y.kzW/,𣗓) ?nܒ'W"Rth1G7j2W7v(EIkG?ބJbGrѫ !(NW?$n8sڹ-T*KLN,Q,:wn(iq:WJOӊk"?C48mnO?S z X8ܛA"AGGqM* 4{K"0ٓ/d=nPlZ\f3_vLn}FZ4XUef3W(o!1T)"\_t@,Em)|6F4U~IRxM V_%ѣR$s7 ׺8!JQuf F182_jM~Y+i)W5S™f6eop6]zfj-f]쮩-|T'5h"GJqYVK+#5Y֩o/M:4ru\_`H6=rbĢ.ٻk*@ǃas=ԠfTh(WYM8妭6m7۬Ҷ9smL(QL,〠(R (!@]/sUCi]}(1/}@{ؑܘeeZ膵ғ*MY/ثcٽ$ͩ$|/z7}ƁLMLCXdӺiy-LJɛꉗId0m|P(-@91nGLW"pΒFږ122y P %ͨ$q&0?*@= UC N 9%%?온 ci!>eƐgOUi¤{Boa`lʠYޢz\=6:a)ya[<'/{O|PZ 3ycФ`)º8X1 #J]设[,w=u/0Gwjct| m z`> stream x[YoG~ׯ5;}N `,/0"G"p>s6)X?,d@5Uu~]3M'?\|`(d&uBFFD Dr1M>^wyVf/tXӏ|F7Ő"dUlb)N0‰'{ہN486~ p '\ӄ`d#9Os?]~B'$cE4%ۓq2~}Eyk 2B$y_΂;e% @aiJxGiXRcUQ,HwrZ ߹u`]p$=h]Bs4"#[lsR#$)EFFYh4|Ӝ[ٺcHd៳OyᎩK:BI9N)>Ζni0u^/L2-1)YYQ̗ u]7׋I $/`Q@03]+vB "1i V^( ~P"(`Lj5`p-xߤw>T 7R5h>Me{\hCM6d @Ɛd@\Q/ܑ|5!$P'ii-<1'b~$c^l);dhUhXtL jIOe`łMtXwrǏ[ECG&}tA3ϲM9`FZǝ-00(X>peFԆ6Xh4tjs Hhȴ̀=RZ-HE,-{mZ'i?x(is `!y"C00yP!ޖR bȾ5p5+[gVU^[Vw7 Q ʤƠ+Z %8 l$=UBa,Ljm);:\-Qv_)@o=Hv CKfR8qQ7i^d[b`g͹aHSǍ~ CKQӣqAZo ݥW郶saPLGK! Fỷh/&p7"BPޜB0-W<:>DɘZf HF>M,LU2\m1\p?ͺ1 'lӇC0+GO<`T.1t c9ˢS| gl9P͑!3=곚!rh(~õ j.ZG*p("̯vK^F iȫrlE3Xjۢc q]m2! H+:=n,:V;Ծ5k ʑ^͞Ud:~+o]p~}b мOj{ԯMe1cfvǂu*)(ZXG`s"^Mp(6 CUԽA]C !(|7hgOѦMfFtCߜ5l !|Hw5C eIzPFwˢ_ hľw[kq_e.,QIg٢|G]6_?werVY:4Ax؋lpBӖz2p{p3uK b@tw<_ }&)Qe``'^Eڠկ-[o}Yt endstream endobj 259 0 obj << /Length 1944 /Filter /FlateDecode >> stream xYYoF~ϯ`_Z {2 v)p@+ieHE;{"iJ>A$ovvv\88zE0vB8ӥCy( Ї>;Ӆ=xOjZW;Waء24oԌa|;︺'S5DN1d,0C0qב ؕC8bƃ%_T :F  lf1@J?De)]M(v7l%]YdyNk5%Ĉ<ǒ4ie]$0b9t#Ifl6*`3)>PL`!%ʹ5-ӡxkd*v 3$p,/IeUeDJ> stream xڽZnF}WhH@%- 8 p\`4I Zfb"(o,wI%%=gfpZ8çH!0#%LEJ*z7:O'"kl?*URVn F8rST_xO #qf| āk 6Mo/N8XxtRif]ċt.}$͒Gu!d4 SGP홭[\_+&7*oUt夦[ `={fa Hfh"iI a`0!G >dHk$tC@PS5dn=ݧ?yk6Pi]?%Um99qfLeo%irѕÀb vnGcO+C= fW>2fYPSOyð[HB']V{dKu8Lx $6E#z> stream xZKoϯ `6Y* aيcklÇ434Rhz jXv₋J.2bJ(H] KlRedkqq:1YN,ScF'e+J.XŐLZ()${P⁜jh 6F'1^Fݜ&b#MKSǖ`VF چdH,e3, !F.JlG-਒݁eo @<{y,. ^+l7Q{7ĐTTehk Z9@sm3O(amS:N L/4QDž Eh4$8I9"T&DI{p*f LB5$LɌԾ=922ESLIVd&d"lAd2처8q8),g .4(L"pB^6( Zr l$DۀKۀK1ӂ<`x5HL\;/òdi<[bx߼l^5bzTOt3 vΎk\ۅkOb'_~?CEs4dfJ>@}t0p/p>:ًcH1$7f`-}t|/&k\R<.0*-nґ@`NFb1_v0kxaN@ "e+9]]!^+jWx[lqx0k ׼}[+ +o{384j6_#d{||qqv8[zvt2}Z/D. ,9^ny YZ[[Wǹq+ Zn`h)ǁ.\i 22tyt9;u[_<czz:|#6@q|P/78P$6AO" *,qH?",У-l; F4":TK4qL͘+ (pm:Y5E+4TA6A3b(.0X͈㼈J`3%\=~H7򲥇^EhʘNk4WFh꘣U ( 5" yP c()xA 11ZE f—%N#+_d__+bV Tp_d: $k6RڲA8PùX}'˙?Z[V vW_=Crov[Kh쿲ӟׯtyϾ.Ndz?5O>i;0d%"̰p_' `|q6^>?˧+{-􅜡@! dˠ畍9<˧Ox16…%Pg·&3hcMiW?^~/ܨ%n4j{z{|"edam:$KDŽ"{Z03s?OG e},yc ءM;m' I4_= 6ao endstream endobj 283 0 obj << /Length 215 /Filter /FlateDecode >> stream xe? 1 q;Ƥ;*(AP[ŏo-PB/mCb8 Zi ^3XP v9ܿBJ1Bmjtqг*{Ej x L(~Pٚ&CU*>ODc4dc8Sly*i, TiH~SoUlSL!]r:ֱy`e endstream endobj 288 0 obj << /Length 1743 /Filter /FlateDecode >> stream xڭZ[o6~ϯ(B)hf,nEu>}e:"K.KwdR&Z$S;74aS]y E""T2 E˲NvZԼ#f^t&Ț\}:!؏0QK(rp/}<Rx7AhԽ{GET>K NE2"{I!- $0y^ ѸB܈ЁwҟI(ҟ`%fǠV ONr wOv7]JԷgպbJ__Uyg3-qM"BDe4ITs]6;FF^M/l?YYoUiBETbn5`YrRIrɨ߬4ܶ#iD$bpc11X&(¡kMjjG 9uCdI쳪]$пldq޼|U!V!qX%`;E$M-EZպEl,gWiRŕ2uk,uUSma}B#&sk ZNHD kIY($(_8o視.dDlPY 2g&AMhղ>M>Y~z'*u6cꮥ 4hn Qnf7̶!tیO|/nj̺^C!yZ62X"9Mq(|EؔMR9^?!\մ'\BĠ?9ՇeJibPoF/նQ^O1eF6&XG$%@9]rZUǴwVViʹɅJi\g.tQ "6q]fz,T*:Txg-Trh$)p߅8^~{Um ZwUm"@Oj L3dP<7T'O- a9q*NPʤ7M)rh ryC~P0?3 OoH6gGKQ ͼ x 2VYgElRͶ3ںmnŗ4%A ݰ{dMzψuVS0dJd*5bg\ih 1 0eAMU55 6:y0X,M жW#&rgнO={"ϙ6)lsU/BP{*Wqum90nILh:9V4P`urX'qD& sg͏} 6fbO۔>S_ pFT6R &D ^[i60@OA<.ʛ\t?3UݡvhAZua`9sD}޷g-l 7OYاn^nӲ8hrMW?Ihi,b"i6< pNsDDt_@?Co393? AHb+!a$߅2 endstream endobj 298 0 obj << /Length 1639 /Filter /FlateDecode >> stream xڽZnF}Wz(d ^4N4)qZlH4wܵ.L)CD^Ξ93;sv&8y;D!0I&r(Spdr\N7}Ycj?`&JmYS )avD#6ٽ]AF2o ڌn䤞\ӄ`d# xܓ<PeB8b\R;3@O3~:bqry ,Q1X8juKlbP fއ'xo'=_qBMR%E '7p=LόNF-J>'߷gX"EM˦68ʴ EFA ҘĘp HPndp&\WJ&*Hs$"h^o7ˢ̊r=W1ىw"B 9/Lia"+ m/7 #0@`O>gêXS_~-[Y:Gc4sس]l4Hnh Կ)[OW><گ9QI3Hy݌nQ^Rt(A/@ `M8K$_gBS ͋(B)RZ4ɛBwpφ[WǼ|]]k׵66 (8*H+?b;=m`#onڈz=I4 endstream endobj 306 0 obj << /Length 1780 /Filter /FlateDecode >> stream xڭZRG}Wl$f* +7Ǖ`Jt!6,k;jo}gOeӌegsXf[ƳL(Bj&uvq}~]-nyg/f%XV5/,Vz_:Ƀ72 r8;q=8py_] p2OzY@9]. EwٷE4u6> ChU0U@KY!_>-\gl<3`c̀' tU.nfZ"/nVWo5 ׮WxYWz\­O͊>izv]{9^2(0+V$ɭ=|^r{&iLX30/??@C (n#X(FI6#@:|t _{*>a}t==~oN2,v>gͪ$r:<J z&ҁtt1,N$̍ ̝?jt1o&^|Ő@G8N⦃iq.Qje%D4 /ya40cX/5 $ցadF,If6 fxϏxO&x9la7Y 4_%)^]uC1$Q&J` U -XȎNQ4O'M#PJ: J D"TtbmIU@IΧ!G츜5*CAPUL1փi"iP |XT*|V'L,0C)dYq>/LW/5'֠OR-BPkE,6VLITr,pR![HZ$HI \釥(}y=kjVhuOO#(JePc6|٫[~ov&Ne':]Dbyicv>73Cwo9䗨j׼caEtIQ={KGPFh&M.M[½$[Et8qDCfś ּc!A4$-MRO~hMEu}NVbp6'8d%9?& endstream endobj 312 0 obj << /Length 1917 /Filter /FlateDecode >> stream xڭZKs6W>tC@A4fbNwO.iD[PBR_%AЖBC"`w}8p( G iItyQ.e*RƘ.чTYY}5/`O>^_(h7Ő"du|8Gh~Nn檝M"*wGtbGR6o]6or=/(A /5K$_[ jأWCjA:ADX$_kAB$j1 ,1O*{u(NOȤȯc2mƼEOf0_g̏nqo\|FR0((Oz|~yos| ǺX j*jfL\sn*%轴,E?)5Gxu]m T%TBf}To\GJ0%%̫wM#dT U<$$qżjx'f$L:/Oo-,fewCC]NH2gC94*qr?(i3 `?'za=CFQ=n>T,՘pUx&!Ȗn%`+&ϖɪ,]aD&=->m7~vk)Pq1{X5Rkƀڎ~!I[Bcr@~Ү@b) =T c \t,lSeuO9з/Zg/zGvdVsXL{DTuCm3Y$Ph"`yI5 UAU(L6jނ]ETRm6Y{Os9:=e0f4~ZoU]k>S#`WwƑ ,AߖբT說*tX ~x/Ah:v⬭5}mHb*aϡk%ۅQ 'J_D'@?) uu](,{]w/&KfL̊]20EY~ڍeD.0aUDۨ Mw>e[9<8T&~JSgVBu&p1D|V.2b2ym7Mfj,w'{jy_z"Y*Jȥbk,S<^{u6/?o\4sӸ۫'> stream xڭZks6_zg2n "Q4cipIvhSTI*^ $.c9^Uw'wH!0fwQ"%`hnFgTUi?vhg?Sh7Ő"mM#?!xT0i%s\"b` 'F#9D}~B+HԮ:R$FoͧX f FjCR^1"*5R+KGl7eդWV,_~/fXVn),.WIHsXM_pFPb$QXg`xƑr,F,fϼR!XŜ sDԇm ](0`a韍s3Af>Kfv<.y0%+\C >/ HiOab1E~M}K:{=p0@!Ab$: 0UͧBLng-fx{B=]Ec'Wn,y iY:JdA%%]SEޤU4}Ni9.Ŷl5 }$p t=pwzRoNY)(/v?>Vw`>{0wa?ϲSz rW6)VDEN. ?ʇ1 (RcpOOۋvNNƷ|ښ@qT1C4փP3Vi3HK뱵wR Q@r{>{8J#8PK'p wZ#3Ik},Gu 6V3}-1TvnDDwxVTęb|x4CBZ V.5 ~MyhkwJ|divۗwii8?_D|c:HN`KsS>pȂTnmޜUuspWtCݖyYj $OSpxi0gr]"66b v黋F܋rvYQ0(t21)kc~-Ţʢ >f<0RRʇyZX̪oկiиrgSei]?}˨]ǰ4j6/m/7/41x4(crT+^~lbtC*=[͊ek F3r[Yum]414F.&ǧ,wԆ!PwL` g'bUO%Q4",lf?ԗYfgu.J;E8,Hz F[ed1#I1)0XgFzN$NKTL`%Pnt(lU b̴U"B>n'0Xn)?9R u:P<#c$ibhlp~> stream xZmo8_/.һ8Jn8k+7IZVa (j<388f8{u``)d&*\"T1'c*,=G+K6)V-/vF8srmU #Y"NC8qk 6wDD_~? p3ٙdh5.z浝M"+wp*THe#E(EXcAŀ+WQ_@gBMAWϥ5AZɜ˗eU,EYjZϠTt❅3I,DT{pjPQnE>LO_W@cc4 7c:aNk֏wƳM5;2O?Wz&[=l3C2?C>3 k i\mU,J({ sbdɇ4hY>.L'DL]daKsI7 |T+arm.?N&npv'W|qi4$Ӊ5"! AFa{&DfWe~_LÅmd1cc!C㯎QKK_:F&Z b`vs-ntV3.PY\v2n|c;}q[n=Y 3m_S4cMAE GS ZS>6:wNZ'#SPd/Q 7bh 8Dǯ[!_j ~=)bjCM }ˆn.2 WhQ>S]V8:ڏݪBCYY}U~a=r~u{8YU]B`ǁ/-*z=.! e0"rS, suw lg[|?ǷEY.>C9ZEOFotzGR$q/ #J% -7p\Ͽ-Gcp7GߑT㊩Am ,#=4=) SD5?czN |hlE2XKCIK Pv3EvFK9ȂZ`ocXR5l }^g /f' $Pf`Mo-#Zַ%Ê0h;VJS;9 D(٬Cؘ̥͹;s K7ӹY/(\p#4N[de < z7zzI~b 6y endstream endobj 333 0 obj << /Length 2284 /Filter /FlateDecode >> stream xڭZmo8_mh"E $ME6AX[Y% EoDp8|2J3?'aOyoO! @D1KBI̓${ۓ8T0IO7{?_~(Dz\&(K/BJiP'1E)A}4sIYy~J$S$pQ=!5-&g@^~;J`_k@B 8p3oj4 GQ( 7ذn2CIMUQϣ4էl5INX_xLY.te8IdN~P]ee*raNJ9_˪ eK$h"8xk\GLk hPmo\@4ΐsx7C%?nRNQ^wm+d& Bw+Pe4+ egHA+ ҄<*xofCL<[ן5lDZ F*UP{X%#͒W XlgCLq Ȟ6Ķl-(Y$N< <,ZEBg{Y7_$J+6T-]VqXxJe߯?=;."ley ?].2LC`dZTg1L--tJ;NNmd.9#JB nqd SqD B/ LH4X~1,3F҈buޯ; 5n1Ɩj7ٺ>m)(Q5ڙWpЕ"Pw^jE GTli>C] ḧ  PI40ayc2Dfȧh,aCM F+<*pt{t|v 47k$ذnr;@ąf_rnh4۩R]qߌ6([!P؏ +$2ԁYsѬx-bZ*Fy٠"ǝR2Z:>d\Q@V!bFNZ(zu-sFlg2 [~L%VTN{UZ>F&⃺m'!11 e d`K<\%9fh䩂\0ۉ#̷d;Ơg0ec(߮Dl7v0}:աSÌc(Z ?0S]C8jLilĆu#ZN) wj9S+g~*r}_]!BE  f&y1]/YaRy+5Lav(^W_2pdƑWi6_}v#[~ïh["MF gKDOyW|ѠTNO}} }]]vlv*d15ivUoҽT]! @k/"*\R ZVb:nPBMlX7dk=shϭQgջyR[m2'5,k˭cVK,Bk|rV(hʲo9{kwMoϋ"zQ~l*YK ,3O1*N]]|o֣zi`k8l=/wۨiɥT _,QZXǰ]UYuǪ&6#*52~7{ns+;vWN<%G}]ENCId-|MMtW9( endstream endobj 341 0 obj << /Length 1847 /Filter /FlateDecode >> stream xڭZr7}WL @Yq_k2S*F$DDp9å߾ #BD <9ݍF8f8{{l`I%&6@x!U#Ae9eQ`xxf~-.c0E9I_eY532S3^Wun֬M9Sb{7żrAFW h"d0D ]Zzgɼ@mࣝ@=PCR.;.c0&ID)(X2 涰eB^'] xoY6(&n2< !vK4 !]K*^.DObg4ЙB߹GAs).IMl >qLyC u,q=y)Chr*&4 )HyjDCG_d2/U7!R!&ECMR =E?4Λ[HGd l!gF#,ƉMBuΑ> stream xڭZnF}WF@U $7p4CL;j%ѕ%wuƔ܇$CΜ9;3;3+f8{{= 3$dKDʔgLd SEU4w' |x9z?xԆ4Ő"tbo0YO-n 2y!i8('rM3hq_OFz.qF21"qͲwqk}ߜٷ 2BddžA K$Q5UT֤q4XɲZ *|\eixh̋eU\PEhx ESX(FD~v4x!tM$a5Dv3*ZG++F;,({8.4R#$aL˪ 7!Q޸'yh. 0Xդt4<$Y |2i`ӬMw >qLL#vn__ms&y2#1n73foWc{Z]AɼTbvh/$"Wb>6?/DDž?^Q?>K8}#2tKh5wOhE ƒ`P 1c "oؒvz+7t`GR8TI&|Diť??ɯ go`T_`*PhP!vua ^q騽x,ll\<,Gc cj,waP laٜcB]Pi~3K6rѲz6A$hHo~={f U_ H~dq6Y n( /޽s9vn]g5GҶ$-E[,i S6  gظw,֏tE  endstream endobj 355 0 obj << /Length 1655 /Filter /FlateDecode >> stream xڭZioF_hVȊs! G-hD 1w$15k<.wf(]E$z::(! _"&0#-p}l=fjIvt-f$>_ui}k4ASvh Q'W& VbS093i#TM@)&Z&ttzZFФ8ʈPYy&^w;Ʒ j"l#o8.#|k0x#7fiF#%h9C$T#h6L`\7 ҆ P_jⰑ*YH@vͯuCqbum$ߴlFK ajRPPO||t,R(y(?xCqH܆7X*[/ RF0PjaN@u˟xqPb ]&3v=k,UC.R5<.%$X]ӹX~-,FJn:X:REPֲBή@-pmM(`()]j 1/0Iyg;N3u2N` &tNMfVO+fBJ (`i\=zwc}xT/|8)M>\{q ٭g}Q>rÔo7ҭᆂZL8Ƹk=ѠD!ь-V  juR6>J8_޹U N/Q[ WߵpU3 𱺵{w]D_K%a$* wuY|Y,8$ttͯ٦M%ml?ǃoyÇr 7ymE'?W3[k2FC*PЛ=}8o.x!0b`gt rLALUۅr `1U(be*ގ]{w> stream xڭMoA +=Dڄ*6`KGVϯmQVμ~g@0NdpD1zbȾ2Ĵlި*K1WY1&_R nS=Uʼ+V$g%Fk$*yPb# OS郍 jT:5Z(dg-t @I*$N)bǙϧ>GŸ@0}-X}[=W=یY3dn]h2oR(ZϠm#' |%<_"TY#if ~( endstream endobj 366 0 obj << /Length 360 /Filter /FlateDecode >> stream xUQ]o }Wܧ\ j2A,)fL[R}hpq1M3 Bd @%۝)b6tU@r_2uLJe8'F9 ~r۪ Ym_s[p;(1bi!foDZiFlc]n+bXQZ_m92usP NcƒTKQs^ Z\HH0eJ1ҐȊOa145SB endstream endobj 386 0 obj << /Length 502 /Filter /FlateDecode >> stream xڵ]k0+t5O-v:`N V$Q64i.|dd=h0 8PID9(_e'HJ )ݡp^ޥG7ѧ!!  -y_&1 nLyd3ЧJ$ \V# <,*/;{^"{j6@vصtv)&*-B'e]oxU ~:ϕoR"OejW4eNya%HՋ[PXLm1&ߞ-cu8GR,'IIbsˬz$0EQ7"vP/TDmXX\x^:_iot^0 mp+{u9Mwbk'EYtl>Nݤ37)wS 1.O]ըm26G/y S3ޤ8&wRIz ־ endstream endobj 279 0 obj << /Type /ObjStm /N 100 /First 870 /Length 1591 /Filter /FlateDecode >> stream xYk#7~_E+hFAB .mCҜiC;$>fwbo)5igG>~ivL'qVf8TĥlԴ:Q!%BgrU BDY $"bPl!,k*M"웊W쪙!Xj/LUf(XP'494U!ՠ`nj5,FׂE+Gz:PUūbA"ɤOadB`mgNt ͊<FMZm٥`&lf&J&"i :O.2[6SFK29ꀿ@^% ~B'rsq Zj5i لxp8M3ה`Wh5U6,VWj-9Dn8 :yTXH~VP]+: Y!\y`C(:;:5\]vXfͧWgͻYP ͏Ofʝ6_y%O<{YcuGGK|p˫¿{ [vHxJG@j\h̏Б55;bP.~rOc\/?Ube> WoT/D/6HȎ}r"ydڈa"Y wzH#S^b{K[@ñkNV|5'g{x8_nZ[ƍכm۪_柯.-MHf"MN.n`Woxm0_vc:c||EܧuM <Q=JԞk x,C(EPֶ3kӢ'F+oD+W#n|$tĶ׭`%[ujo&b;>5P^u?p|ɐr@ⱘ<i3iN5z!{SG$z)!Q=,1wQ=5_uN|jn9B9G(߈,|gX*iD Q[lv)3V*)S>[u5<|M2kl-lM:\ޑrR.Èn>L|ga"e:x> stream xڍuTk6 J 1twww C0Hw44JI (HJ* HH (R;Yk׵{} 3 !B=5K@HHD@HHm'0 |pb $ڦ Bzp@ťBBa!!p4@u 0/ ;uuC sRR|J^ @H7:# 0dпBpɺ!҂ /_8UE!?K2@#M` 0 @m!0_Lt_dݿ|? W (3 {y`AP+  | GAPO{ VG/F B=i}j0g%?U(F{z0+( g?oA36 AĄ%$&+i77eFkAyý.h "B!$WD@  F P#!tB yĂFzƆ$*+(~aQ(*& ;?GVCWH-  Okpn3 pmĄv5(yzƹ"8 nh?$z87DA~^j!A!QzsP_uh G }?PH0؁=/Z!zR ;?a1q^P@:C7@PG]hy!8WME qA*C]]!"5WvM@^ @hqvQN;M\n~"'~wCAGęR֛~u5S,W ΋6;&i&M_7n($3,J#yعMqidۈRYz6<$?q୙ӳw7,yBSD*P֫©˵¾ w陰O)NC)ogkͣ*Vϰxh(؜F = 8h H c6oBco29UsgĎgkeb%zSXJ)b3XH"YdV~6|S<6 5 < K?GH+cޛK5]̜ow*ƨnwg31zNca SkG\?k.]6}?pRV^nq+ɓ٪͝j׌yt7.΢`SH>95`[ݷOx*SnHqc㧪NϘBHy2M?o-WH~rNB ?ܾFM~)]Gt=S*{=wFwP%Kr9oO*øuX.Wt:CWSeE{hrZ":ˮ~ ;g1iY?(k|.Ε>z&ҮQÊ7$ ,rnV_X>,ums#ę4=pJ)(wtj`񚶘=^x͚H+XOg9-ahٴG s$qLȺJQ^J<ٍ'}]!0~G0S+; `jϔ\u~h7 ƬPf6v{"YUS+_lt7kΎ9Qɗo[BKBvL)*9w+ DOg("JZFtr4|s S&& ˼0:\'|`&ZKOz:=b\.#jB+{-4*h,IR2Ċ?IO%$C &>{)!yS.0"LSbh(/Ye"%Um@yJfphv*Y ٠\,u K6iQ-R؜o h͎_uS kny![enzBPM5gكGgq&xN{cީ1MuuHJ V&dUu۲~brl:e>iK }H.P$^h`po&?5[$6z*6'9 x;){d#}6(b^std٥Ы^knݺ 6܄ϿA|i0uEOܦa*=g<?a^?S16Kߐ./J:t .6ҋgˉdy4_E(ݮTBG4PMi@i\zT`44knf2h=>}L\*:n+>~#Ȅ5mvY8B{h%yNpI {O1(iR}s~7X+7TӰKcТFZ$P}=&=",+qZ%HYR_ &=-i:,pd/4S鞣Vi,{B[3 >ʶ  js\u֓b}i 1`5Ht͎rG -9ə"G -A̹1 pYn0m!Ј;Be aYA([H[Ohj=†2Ws;tw;έl{ikb" mD8S T'b-B[{dOIwhZ% 1mwOr #8J(;G0X(&龱ҞRlPfn_NB1x :o2%0iJVw')0<&$2htRӠ@Q`bBF̮JY:"r%Lx7.3C9˟{2 4!Jkq8'D-⭷6z'-; -t?̧O vgo>n()dCYaX[!p._7LHv;Y}:gKOYΗo',p *Z&]iR4f-μ.~]BJ\|5;Mr[ vNy5iv+ N)`ok;d",B4b;CT:ɚ) [-FOId}D'o7:_!8>zAxGo;Z,Zjt;iMN󅶆 BZIwCygi7Gq1I[S6rXciʴ"2Z59NeHi>j1'+gHb.Vɯ rfr>[M:O>+ڹWhmHXur ޸xhW3 S_ 䘮{tЖk[Llʀԗg`r2QAĥY'܃n_o]ϑEO[-/qjj[O!tTle[%b©Fϡ $A]bQ6h0d?唧K!>^d۶e}p6ne1PLd?.-qqvGjyf}V9*S3<͔}|ӯ̨cTwшM6=y[-6)olO!RǪ,jsM em}}znIyD%8r[.5e:;r:D/1+SWT f݋~=8SaO"is/lO}B8"7ߨ\͢kRUYo)*X(z9Irog"3( 7|̩NYyA}5tX=%!10kK2!vN5S2PS8[A#=T,f@Ow;&XtHā*2#ƈ^ݞ`l'l q"ؿR~Td:}UkRח5o` Xs*׽]+k$Tr1+Ud4zӓ}wN̐d{>pTsw\#^#".)='\;9Iw֪}jdVɋ zh唀3 )NoB[sKv$ϼȰeAz9ѫ(cym|u=8r@0kq~ +c%VOLR^ ZXz< CU6d;$xܕ6:⭾r$$# }T0'Fgev&z@bRkf@Adj%.)0GQ-b͚$[bD^)SP&ifRn\[ҥGtdId &8dy8O@|iX (rcmo`'QU'wudx}aE0,@V=d(٧{4kX'1zf26M2KS*JٷW`wi"nY$J5{XY7ѷ$0wlB0U0ԁEo@]-8du0s3B due}3ĕ'ӡPߚIݺcsiDžqAi]8HZ>6A(Sr_jvKVWvGa@D]2}Xʜ}N]Ϻ>IݟWNEKŌ:q1[QAj{Sp Z,j7x(1%PAIf(&r3! 1(ztqasx\AhqKFVf:k:szďSvn߯}D~5w%xE&fu7f .kU Qο2[OW+I:g(=8t3, (~ډW|=.{},z%Gl]h%\GjX\#u ,.϶RIi JDI]*əeML=h[_˔Y7 (m,[~02bS!G/?$_3B e_vz%Aaz-!} +nq QɮNf{%w=)[.*jj|$v*!?Eh:Ly^PLx){ łn>^uyI֥pp?tTڞ=/dJ5=>k{ϥ| I"ntCgiè^mËAiXfӢϘ oѰn< Ѕf0&~jY{{hR;6#}N}\jSl[ո;e*6pZ-GՑ5’H[[:n%d~Wb+ S$aZPSs?yGvVV%ARRȡyPl^o[#:Kji1VcZdt A8MPGmXO&$Oe8M-wRڅe`܌ ERr>U^ +Λĭ#q4 1%#ʹg\ҧng1P^T$4 endstream endobj 411 0 obj << /Length1 1462 /Length2 6150 /Length3 0 /Length 7133 /Filter /FlateDecode >> stream xڍwT}?J4FIwHncmlF.%UA%DERBB<9>yDXk8aH @ 1Hs1cR?M`a.am,^KrwDlp=vI&9O5>u5l]: T<f>l-q sh8q@&.'rMP5!$o n!j%fP2%tFL'"ki垟vIXdj֥ W{(({`۵monǝۆ:SzA;`+Do>a`wtȂ4&/I"|/]+0P2waVA1nr޴c?ꇱWؼ E${6eEݺ{󵀰Hǡ\0,(zꎚ] ZF{50 4txJ<-.Q% i\ H |" ag^0<T3p0媒{C+iΚ-ޞ/5| jFPl]ߵU\WE=1̝ٺsel{H5|%_eq+odT ᫼V|OK113Zv*IiF ,f.;M'ƻ*y$v-;lxpl婜Tǰ &sqŷ%xڠ79EX!B(M(7}io wI{G.!GIo6rZ--`ghkrՉe]KtZD> y+!:L$,+ߩ!nj VL bcŇ~9̐Uo[=&*?m{m%,ECL%1(wSJ=B`LWf] Ma=I >"i'?5A<ouSTƵyK^oks]Ji"忖?tm%6YUwƣ7+7)IL%+J+~s١@k13d$=۶~IUZPݳ]ԝʳ}.2@JwIXnTYOLX[Ǎ&r]… "fE:ON/̊{7+.)_TH73jK~x•LrGU,koO_ê#@ J&㮝exnRJUϭ4IC+ޝLq9nx vNV<\YK*og܆ 3JN(W$UtzВqEPE^{g:#w@dQ3j3^.2x-hԢG!p_ 1?LNP4^l,FTǘ?8\,zթuVǙbbƣ=Y]WK oSϑu;yvV -*IL:9-:Tyjq̳+tI{>-fsD 7hgo;"/0÷;3AN g@-f9N:>#&SZHQvt`{-%"e|kcg-.Q^ at F`u4taGSjJ:ߺlKu@'CQ,=cz7&}1^Z[UتǮTOcFӶs<*Dm;2 ,+):ohpOJkiosN+.dg nGbEɹ>'b_,{7`O)+ͤzzP hë{nP%qb2/)ZmDCا+uMCo>bKE˴{ 0h)ʻwWKu7_7ޘIZM &t.I֪Ŵ Ok| S|e!y#X2Coty.gM4t;@Li GՆr7txѭw ~MVj k8~1rt?kmtNI%eQO3E59 Ӣ7ʿ̬jyLLДeʽ7K% gn긙/o/KLHJ7,:xB"=LoD%.+5}o`мѮoJ2b!AQng@gR^EJԀߎz[Hő{N^Xb#L}*^5j(0ȚrǖJH.33;gIEL.H)+}]R#~Oj`G-SE$h,<ߋF~ Cz/EtrM\bJ>J/3| v{q#̔ޔۻC 70=A->Hw=JzPjc<*>M)#uD-}@e_XN[a~OwYr '0^i6G&<>񅖪E)ÅxAre뺅/9ꒋlnH9;fӨ2<؎|(\ͧI/\ ӣSoz&o`? a9sĭ M*q51kdCIޏL1:Jz#Gmϋfg㦒\ϡK 8!h2ִQ]+gEPM!P)t+]s!}_DhԳ:r"j]!IzK뵈(꧅/Lث^!7*b(SѸڦj}覸7wW43:IjqOv|K,B72}$m[u:N&L/{}}4-owLm%XXte&59(EGf_U:{o@FQ!_NWKfgǍ<#Ǔɫ }IϞxw,3qgtkR6%cn:GLWy. ) }rn[hvD'FF}|'u3a!U(62 M{7eW纂9-so]ܧWx$P߱z9L{/"c2C*y >FzL [- gЊXζ =% yc3ĩvϭYp}?kqƯ;&i dpê4tP)b &cB 6޼o)fy=#>J릺ПF>tat>dڐn;9ʌ^mo_ܞcĭxPR?"_^{ڻݨ[ԉnD,MȚ~vM2".Bok&[Q }4I,#Wa|, _NN1ۡ+y)%Ww6 3jԥ:zb{r3Jf^y4=XGY<&M|x+tt $P:*u>,$˹%}{A6* -Kt\m";|ubnEc"ܯ_ƨ>qdQz}ӑ endstream endobj 413 0 obj << /Length1 1451 /Length2 6269 /Length3 0 /Length 7242 /Filter /FlateDecode >> stream xڍtT[>!HHĀt)!3034H " C %)!)H#)HJ|c{k}ߚ~sγggN6cA%g#B"2]#@DDLHDDA$f$ Fc1U0맋`()H@TPg@ H8U~H{_K/(--%+ABp.qǞNP_)xhaa!;Jt@n# 8~! pLܠ߸1FBXuQ/3 0{@࿝u~;ODP` ].PB`OG0 ƃP`HC億zQB(('EiUV; !p4TH~¿;{ٸ@.?I8{y¡^M?.XHHI &~_FO (pA] ?@# Ai8CG+NOv, q6 X` +5ߌ)+#|"AQ Ȥ.5.o,x /'!Zx?fߤy`<qJ  ]v8j=ʺg[5`x(]aA}!Po lz1@? ae=샂 wB8g0LfRsQ L>@>57)4t/^9DgߔO y""V Zq{%=*kPچ]I]:~x&ɓ0{6PR5ޝ/R-cI\/޺ bHG1.15>JLi!s=Wo]mrS_&e]P(cd1mx`LϾن1 K2ѧlc$:8t֙yDX< rZ%YOfDe .(SNM11t]L`BEG j "L,'j6:д121r3i?V:hՇ$4q4G`e(Po9)wr,@@Ku.٬7o7hI{550AkLJ Bj{~@Si+5%CA~,X8m% ӈ; UW'W6jiGN|W۲撄]Z3` j2,fJ:+rm *JRQL4S)ϭq 80(NqD"Es ϒ.Ev BԞjt9ӓ2%ݵKɐr#0:HQ-˭E'r]ݱvk|ZG`BbJ椈EKreL9\)hՌ7ʴqA {'t%m m~C(`!֠se0+z{> h Yed&aY'$nDI0d[iMGF#h Ɯ{П^VE@>RGeY.GHl 8PvLv<7z:e~ $v3jkI4L/'W}]aQ:L^`?ݗ$Aԕew@=d4|מ\/ܟUTMR fO^3Ys䓔!CxJ qVuTpg^pܬ!ܦIP)!#W_/[~l&8㫏*b;U8JZJ=LE!l=m00hh[ $4HIoZšpKX6'2zO7;QCOY ]®1DpPIW8Ew*|f">nK;^.zIk~ydXNYMfjB-nNpliiVV[*(etviyNe /g{4nepkhwH;i\wE햃NY-84}{Y4ŽtJxw `*6u=>_Jݝ£n."Q1() klyջ:8鼣G+3aYpLJ+50kU^;jK~WžBٿ;ewQz"BcQ\ #y$SQ>lWIAĖ~ƶEK)9!G׋Y3DN֪c@O\;.T[G?p96шȢ zRvJe%w/6CEք侔-' ciV~J;+B_Chy҅۽IPV#i[IjSwR^hCwݖCX6#e;f#e0Æ[1 eWVwbR=+!\Cn^|D6[Ь U.sNҨ{B׫=hͼz Kop"d "FE<9,}Ĕ+ubLڏq,o fw%!mY˞Ԑ?]}0xX<.*O8N152K+ZwR SQ2{\ r 7K^h 0ɢ XP1S> XTH+Yw;PK-pYCOB[ :5> H.z?T&gm{!)`Sͯ8'løDÖC/9לj6Y~QѴbL<pcmㆱ\~pyX ȲH_cR8HgC(837HrD45KUnT΍E t2ɊPhYYv祓6Y[ro .K 4jEM'Ec dK+o8m &ErX>Dϯ~Q?u[.A~݋ч_]6>XdW/L(YvE ^f07=:;l# ѸqI]ZTE^ӷH8&bȧUB%Rϙ>iTBA . NQ v\!q+uy 8կoM9 -N9Kj5aYl˕gC-ݛOs^ّmwȨN[8>Vro<̋%ɳ_>H%,^V~DO=D?tdx9@H+_6&.[XfD gx ـ'8?=wbwK-6ݩic .aj6νC:܅({[Tz&`~gRI9,FUޖWٽ+SWOz\5|-hb>gad^a9mCU>ȃ*|ZЎk{0nDaOFݕ%MR҃9K WqHR^gJKufՃCIgF3$%4ŵ AL5B-U/m=x^Z;!DlڕN?z7gGXM7$t^c4X8.P$Y7[絧?U' M7;poҌNGU~-7M,ƺ/fM0k+=p8e7]?rcڃ}Wv\MYG]^S*ߏ}M+_z{CPg3Zr,HZ *ȘN&Jk.x/rİk{bU}ttjx~d7̈O*BjLkXҰ|wXﭚǬb=2[S5h'W廳/әf- o.l eK oXfdoqpSA cl 54{6)l)vV.I[4ψֹ͛6VO 53&d F[ը ~/;"$3"T !y7޺"OoomXHn:zCRԆ5%|uPL^+i>M ڡ*q1Iߺ@.=ysݼj ѷ槟R|w{+}4MUzLb"6T"{I@ t` xۦ3RiL/qݢ$?kL*vɨ[3t鷴,%L{N!g'䁄ЍwӔV14M =Z-ڬ{fI^WZOʙ6[0]y099_NW7l,!y7:ږud~fαмpȇx&Qb?_.?\VYS妃pth]'yyL8#_o ،yAloF;m f2-%. PO]]rϼ{{yo#7u5BϏfNI{-^h;} _BEk#}ئi񊪻f^q>0P>7nzO'+rD2~?HjII8Mpgrcp 9 $EtNyw;_qVM-ŽZbH-]3zĤm+ZF5F7G9MQ3H&g59E/^xLP;*9QY%NT' HX=|Ȁbv}odlh ɒ42De *)7Zy]BRj 3UeB]$g˵nPǨm+ F#&e:xQ\S^q)3<45뼤mOcstW7n^ 3fI;ۀ<>(d*y!h302|ՙBI^GIt7ҸOg.^'uٵ"pO6f󝘑&a"MKeH_\5Bկ] Bi;uK{FHxr*O.9n1/t;pVi>_f&YG=̳olפF8 (Z@X"gad`fe۱.pd<=L2O)ݘJ*<%W>h]?L endstream endobj 415 0 obj << /Length1 1494 /Length2 6380 /Length3 0 /Length 7384 /Filter /FlateDecode >> stream xڍxT۶5"wkBJMj At Az"*H/zh(Ams"@ QQ; *` 69#h@#P@P0 `qm8FdV /PQI H &&g[v5_$Ч7?36\VA p["@0 !?w 9rp;7(ZϞ(lh#oWS_ qz7Cψ s>0?P/; 8AQ`翴w35`P8DwQ@a$e!zYWF8AAQ/>ZUo:pDxj0 Bx; AiܠpO v"MGCPc`Oo}9}@ >0 ,*Vޛocgy3:Ѽ/J>Y 7Km򑢭C53򈉙zQosBQ*}k|￝u09 ĞE%3Zb[r\?zYtӉܲJIQO:0c͙YWPI<,3<4n0cq|,3=:) {7<@K5]Q\<--} VlTa[ҀgR]Mlo4μXj03j`=TL΅SҲ s-̏MqÄ7i.mf%d`_(܇M?^K4t]V<}4?n~>y`=d I4Mz!rԄ[EU9JK 2kTgI0".0"5йc.D!x*22i ǷHwmhq, gil[%mKV4 9YWadC^a_,`ѩ]Ak6/;,2ތtpm7^cI*DZ)-Ϛ<ξ,/CܭuܿWaX$ocx0*U'鳀;_DW-+Gʡ-8Q˥ͤ Åfz*Z7k6-w[i jIZ]ힴm+S{Y*'%- SgS2`TR= "4pdRͳRR= #T/ts3x9N#xhr^KQ,AUVn$'5ƽz}ԔTfOy(Rs־~P-au`WMMʺW?, Tj3A?[jOO'S'3I7!K左, ^Jis9DS6yTC9dTOa[ z֘Y%\9Ba>bއi;k ״{M,h>ԬŦ[ B&BW4o?kqYJ;L,̂F"_,b},mQ// k o MmN=FPtlq?rܚTәzfbL՛<#ҩj˩V`&:8#0[Q®2?*ge`z%MWDbx,?2_\۞zh e}qzbE*KKXla+j͕llGxRu8?^BaR via r)(CP_4ZëLkgy2qQNn%35^>*'! Jtl70yڿP<ș b82SDQeq}t ˮ"t@ouuώ\;Um;pTlt4}DM6⚮PH|Sib*&[KC槳Ӧz#;yXԛj+YoVj5Z1԰sŢ&HPOxg*PN|U˹b2e9F &HoJos ]şBx(LPEӓVqD'ioR"<%ZS0ʁ{S UJd^TڹfԖ(XgݨM%QrT^4ws<ıc$ ӥ:K ,t(8#DEFw%U,(iHOGNJIIGsoZnIn0RZ E=nMˈ]`>x&16[p1><'q)hË3rcyG#uo%rѤGtpHw,@ADqb!q*"9D~)Bħ[)UȲR<ъ1u%jĉxBSn59Q(LLTh^Iw?/)`vVl,%m6/_Cߜ3 "1E|&G^r}d(4*8(9wiVVǸ,UÁ~j/W=~gWn>EU˜Y]aJ{~te"0*BkT+˾-exyN9wH'%¸k$vngIr,i1:bT,4AQzM9 2z-CtAJk &? 7H/9d}A$An5=dP>N"cc VDX+9@vbbCz\}JGƎ-Ynča,J?spwư/_l6sRˤŷ^ ?> PcO^;X2zw8uNՑTpm]VR M[Gf[:*qqz [9c=:n_Ț1sK|Qd4QR߾J=t[2GǓ.wP|E쪠aE}IdX<}H'3a:q ,AJs}h_ѳN Z<`&ǾnHL wfNR_9JtVngaqj >(W>ѹ|rN9,˼8vl2_Kj%'@iZ7aj˥UQ0A}"sdXyڕLR~VJ-g:Tι++^ %1رઆM 4]dP3{0)+eO3: H*҉v1ظz2w^d~A[ pW%#?A28.VsaWsȱEZU7r]xW[>Q{SFH? :V{×[]^`NKhDOey'D\XəvujrrŕxKi}PvrkSaO]suF{PJjw؀D-/sVղ'&tr'Z(TeB#q 44X6ck F+Q-M:ٺ#=wrVy~jhp8cò`UAWBS1 ݆ݮ S%!ل'V$Mi(H%>!ɸm*u;\^R3~ )|f(H}sca2f1?$4 FDp+au>&@+x8.JҮOo=<ϠV.Bc{Ii: V+עy Bաz*UobꍑY/g}6{SpDx]{1(S[g#V!z+c3a\bޘQSʝEǠ#x?U y04sGۗ=[AR 2 Qjt%,\7 OX_gP:+3oEÛl XTK]Cov=\ ^wC<Jˀ F /6{C .T6zg@E.yzk'txu-_3>oG鿢;;5iph1HWk=ԡ( ߺ^R]NhS#ȹ(BL>IN N4˾E;Ka!7m}{u"I[{+?Zi~innZ-Q2NaXY9 wkODe2hS;QCަKKv3ox e>^v27\EQ+tXL Z>wYtI]KV L^ag=D*|Ŕ{SOVoӺ؀|b> stream xڍwTS[6UP A]B )"M%zv *M "]TAIQ VΞgfg3kA9phr*f0(ʀP8y EE Aa(T&$=o7&aHE(C IdE@Cp b y NEJ0A:rǑ X 0Pq7%(*!Lx(B `DvR| g#}ʀE 8L0#)2:XыMtđpG 6 ~5a/D $cXO :x86S(ĸy @Q&?/,A{9BP۬Et /i8,_J$#~ĜHjP],|N8 a!an*@8% (do\pm`#KpN"˟T7Ӧ?@ʖ0G!( =_I~@8# TFVP.]wa5~?*${ _c# {#U8@/BP,?ONpvÑ`9Ɔ8GGu)dNnGBp x8L;W%9!`d? 8a)s$ 5xeJDcu`!D%@~[Pbǂ?5@EZX:*֛L<aYFIXHȺ(A3=pYոu&-~9p 5T PKyGzUv>zx?76Zx?W>]W\ZVdgF%0]OB<1yy6zTV}z)j`AWkUg9EjS$MKL\\d_ZTMoзfZ}K_ p6SY8l{hg sacVzxˎ0Y^vI)zIEYqm>/h"5`O3d:$JkbJ#KhenQ- _oǽ Qcv W'-k5)K/GR$}8W {ߴu۠-5)C1@ä|lKJ]DOgR.۷e+%e8@J;\'uj[]ڳFǚPove<αA?mq<-w)0xr?NX†"'c΍B5 \|#H%p (iGw(]dTo kөXڕ~UMSw +B,W)ب$rغ_Z9;3!՛ߺTЙ\uq*??P g􏫐 et5RLl^}Qjs olNy^bye7e|՝fѐC\"1A=53xEXĹG;eD=y4s. Lexobq*raዼ6g'|(Blpo&Xe kBvl`Lwq/ :-Q>B4jw8%י+›l4g$:ad.m69\2}d*վnOyԓ5|Gs飢ܯY_Ǣ{Y| q2ۦG/g'4}SG`-hk^%/[,c*;_ ׾amDB2'{iRm*Tgdd|Z%P!0Нi3w幰ȴ 9J&#)3 dI (_vvuftx`ǯ| _!5?~0M㮑]+'NJ|^}AN+G;TA_Va*b2a;;Gh4^C/?Ƹ0}4~^/u4R~L c[STI8b4>'am)f\Qz4cv(hS+=8g'1.Uɽ΃)QN6O'S, ܳo9_xZVݥ֣D^$4FdxH9}"PIP_wGlK$2>4&D>MTWMŪQnSPO,ޗſI_HoxLx;uK)n,5#P!Eh rb&D~saEP!kH)v6PZ]O vu^oDccE2:͈-3pl=aqo.)fgiq4EA\;>RU'xUw2;̱n[#KeO"x-ԾrY41E('ȻzB\Z"z_no8F7_FG 2\Ѷ.B:+<<&"\aD,rtEjcM6%KHǰGܲ6Q!Jig'oŶ$[&;[zd!t ؝'2G k"ʐ.Y(%ېXZ*^xp._ڢ/9^b)h{#;^$qsÄ=N.V$ 55XIAtRB%_9-gJ:!3:;aǰӚrEQC z]Tb sLϵo8ُ` }|Nګ*##MN8K7FWH+lGV%E@\a$وpPѹkηDyh!12%{e(˵ڝw0cUvՉO R\ a9qEDp %.޴12嘋MY5b|vaENAYmw΃'5܅خ2l|j?+4P#yi99î%Y#fqm`2ld5DM0zoVQg\nޤ.0csX%ӛgU~ܓRVsJ(=Μ^.` c=Ѩ?ƽ'\#+҂Oꬹ£[ݱ_P휑c_˻|G+W:N_:NI#]LϢɳmp(Qh]] endstream endobj 419 0 obj << /Length1 737 /Length2 20188 /Length3 0 /Length 20782 /Filter /FlateDecode >> stream xlspf>vضmN&mNfb۶|9ު?Ww}]wm IG7uo'  #3/@MRMGA!4qvt7q5GstvrPhڙ[[4=ͬ.7+ SR֑QPK)j@;@ X8̭+p=@AB]DRIQ !Ƥ.0q0K7_+ٙW2_$F8hi/d,ݝOBC9ow;;E{ Z Pp48Ž5;*{k;ߠ!f)"U hln.Z?K6wtSֿdVRWoC,`hn` Ps[6+XܿuL\žj=#/ 'fc?隹}? -;dWHVCNk-LuZZ^ݩz"0ؽܑk%5I"OLƒD,㽔U[o6E^Chڛ)BDݺe+N:WJWDN\]xp1BBաZ_ 쭁E"PYWp:-jQc-]w+NQ?,rwŶ)|X4<] yï$@:wC_#:aQ?pw9`ZKK9:m`[v^.Sw~7]nMyCwgclU x6h&#:eWnBT5m\bü i8iGl2B1e!3CP ps?Օc?JjT̚-%~WCH$es\ݢŸaUB *=p!@葥QKYWX='N>Vi9lbw)ⱈOܯۯ?ϓ"B˳*6÷fǪU%` |5hz XlEYwVåO ÔFLC O}9n8gRB36E]2{Y~6mRf=mmI^3(2ܶ3XH!qrJxtCg&9lin5Oj!*ZjQzWhkȉzANZg &IL'y'A$LʙB~Ѳ)M5<\*g(J2&u'$` {&p7p?>۾t+{A^]~R'C^ V˳#Gܰ>q GL9sӚ@`,'{(Bu$+s웅&bF69X7Lvۓl[n[3_6$3) ef7& k maM }\}8VXlDo"^Y=yw+KF.ʑ7QqGpoZcٽY} :T毙֑qh˭IeF /#QJ['ZrqsG"+dbjp;9¤;9-a?R tRrg4q~ySz&%=F ЬɎ $x[52n`EIaIq9w_\Vz]8̒z- DHnJx'YHY.ł!R=z6sqnYŋp"fv].]n9;Pa:2]D%ޮ4ZKPEȪ $@h7`? <L89*Fӎx8¥,!LsϾ͓ܨёEc*p[hF a 1g|=gя1d;`pF,;/B)m!|nA~$anу$ݩf8@ƻa?|VqM!{ƇV+3~ĥMMw]zS*0BR9\9^D!ġ6'3oNOHO}?G=+*Wg8GJ._J&0!xu_G>xSuCD/z9 ˈ.o1//nJAJPDBwkBhzܶc&iN_w%b%4jŖm(hS c3fN5,ǺHz\JI*K=tsLX`ٸf]bJ$3<.O{xacla̽f!֭ɤ<nuTF԰܌oQѣL;&r}g} faN[8RKI)mo,L- 9nh~TPn7= [ozsy( śàmí*+, F2~95UAI0/n)7$냤t2OΚR3B.)0,gҘkA7K"26>7ũP2[Og`K4SSسăB56E06UĮO,h:EŷsX/$KoF)zuW}3;\(B(*?(?y:6Mj ᑢt`\7ҵDd>evOF@+? XNκ^֍aī|vrJWq 'hzyѓp`O+KuG3Q҄ Aqfe4$&ĽCV9<6޵ |Uyނ:R/~thmcGPQe1CZ]W!ߎ_1=/27XlsqE2YzR݆n{|Im-{mz~CvQZi;&}:%:+7jLƐ)86v33}M=>GIQ64I=ANU¬mg8!'+VGa~f?$G?e䅝"L]7uPLk7P#8l+N.0R.+ yc_}y4lf5n@QVmZ[j//K쾖~J|pL9_+S݊z/f"3$wRNj3Z0.t;ւC ,'[3-^[O#Ɖ~uOA @i_b b'٫(D-Nj\"?d_ se7’ێx;4hv o LM;,Eٜb)OJ\0x[W(z&{P7Xg%(7>#`#YL.f*s|_kCQ1@@c(y*xRh{B;:;{F$Rs,eE=f3Ȧ8`#(׬1Aq9̍=[y>M+sVj F`48OՖӕEX40pSBT2K88M:o: {cxr-HK8^qOp궆tN^j,]gm*9.ɟ9-PBN!"wH:q%hϮAPe}ͺH6Y7 qYLpg[c1[ݥ(ө@!g*i$CE?h&y%/Z_Gb3obF}.3ص-{z86-9R=YlM*޽T:4;g5S'm*;LU] 4;SĚWBvda/blq U\N`ޕG%g=>Q)^K&T4,zI~Xiktfi BZb*o+Z׀w3% hE _Gޢ,|R5xҍtuɲ"ޛ !et?_I0* *3&ke=>+T`ya$%NĵEkҡ9WWS?5D9.+$Re8O+bEg d hJl* =ŲWaf Xp3zjHYɯP]el`R9_Oǔ?ݢ&U@97@6VHP-00094T*SawSUs=&!3#i7.']Ԩ!g&UXWj^bt(fLlG%Ug_$.6P9~gfd]l>0Ls Fdʬ] ۟O8w"Cj{KݼƭL>CӴuy.b1&qwePnHJV؀m+(~Զw~CX@@-PC~jTZK @c87NU~@w2Qn,|˵[)| }7}̈I%Q&h=)FKմoԭ\<رmN3E9Kto&C-1ya 4LSw`ϰJ4=ffY$y1쎄}6g KkZ9br_Roj>ŀ,EjV*Pxy݉_7-G}\ *ѝ"6b(QA8Eq[Uo &ϭ~Ρ_ݫW4ydq&ZW~X>/7ɴ7 Y-oT4z;G?ƿit$XTfE\ 1CVkZI5o1=4UWؼX5q/F6 K(d(y{wf˥FPê+]=.7W5^I)HxC.>oNqJxg1yp53a%c dH"ğJ}'#nXR2$x\\[4{ )/PN͟*>ˍɿ?]H]Vn͜vS6MNz%U @~U Q!_:2݋*(~;LjD F}aI Vb"_}eU {`@PaR9 ?;3؅P<g_ԥ> yP9lvI4wP3{ݦ9̟[G1C*$蠸 PJj(hY\j;n*Y*X3 KwOД/׮<_aJX0󈗉ZB>kv1mL!U#!o׌,&MsIy&H*et?[r\3L7"dqSeKw 4L[isL Ԑx+cض/ b彩rB,۶#*1T;V[t}=B9Lg5Y-]q"-K,k kޭS4Æ =mmw$eI T?\=b۸eEE,DHԀF.C08I|Z.P/,egίjf+G]qm+" V b-CV^+^BZ߄mdjRwA@'&)Pg (9ek,`Jͩ SZAl O点/zE Vz[v0nN,E(%7iۍe)oM*$~F_Y~3~ 2Ix(8#L+['oH8qʖ"#oF&.IϷMRk㑡?³Èܶ镑+já,o`zҮcc2s"*U4J2:h4JKg"=XArp06}WZ/,˴Q-P#Ov^Ku "vp'p5XMcY ` Py΁+k BcbF2b1<4EX{7x;EP/#MU07krx`"6&t5DގŕfGzoQw@ㆊ.Q5W.~1L|=PݳzWl^u9aYn aAF$mǬ0zXZS'/r8xLF}8zҕYj(o2(~kq͢=qnkWzơ?}dlH<{-*q䡯 G$.>k݈Gͪ#KßdGӥ x<:4;\sI]-Atkr'-,@֕( VDWJ22R=+:ٝbi-Pj꺢ygz`!nh?Z+0an`@^׌kwkm,{;+6ˊWx_1(XiBe.`IZʿsXpߦCB86Y5Ze3>2; sP~K+G LyFgr:MyNI&KGgجt*'c->rn A+pr >:kt@vP| <.wlt*møў/7ΓW$)KqV9wE1~t$At÷.Xk2Ѓ2㟽D#HTj)H"|MlG|q|),]<^Yl\)DžWkv;9˅|<3s VɽR&9t-c2ZrMc:(lUH6K4R8A|)0Y p`?3ztі\\R}Y;+v r:[qc*3H$vy)t;ղҶx(D vf.r֗ò8*|ƖW5E=Z7W$8nRR1^YlJ#v 1 tW] kW_q d&dtU_]]Ҏ;óX<#&,7°o`풚ً4ىeXY> *RGb-h/f ?q՜Ǻıff?.7lMCO/J* ދ]]5UB-ln=Hõ5<䳪I[,hNQtpfV~ͩgXfM5lN V|*D 9XcukZnVӆ펍æN\o 97ǫ;8J,'GS#NUc3f 9&m|ϬLJ[u&<( &Cأ[amqm&GwjE؀ !Q*q[c Y+#`[82SKb0CȪM@K#VQgkN7]W:2c759}7ol#tcL=0pןQQpP!Hb~ơk^mNJ.^Rh-0l/u)18NDfR' zՔ=v8E^`遨 gtcwAt;b2ex9rR7_z wfe &u_'vg7M[K%ksc Eh3!i˦ߥ䳿6ܵTPӪiѿ113:a{HV'@nߘ`8)'MnZx`[ Zso܎V>hwv5 ֳ8M!1L{fgawg8icqh?%`]u/ûraG<7,|#J}P.ttwFLN)$rL$Ei)? ݂x W- tt ;Fa?o L@ZCpjqP(R۳%m)8-ѠТ'S [uS\ٓ秪~O.L]aHigK2O1󚟄S֔'^iۜU˂_>Qy+)ii]+fz;QzD $,F'kHwd^@jjI,'nr6cC04 ~NF716 74R\3"jg+@0j.i2([ءh14Qhm4iۉ%:#!w$}A)$tĶQՃܸ\B up1 /JO *_Kۻ>Ufߝ*-\YhWKF>iƁ@a^R$-K3QCiM[)[4۽p\na^wDupM]$1*ޓ_Z١`"TU! PN5AVU wK1Qrj,hM[ZxAG\ cS%,(P}s#ե%R\*m#zJ2X=e_4܍?cZKfj^ڋ"m$ؘA~H T"SY|uxMyGu'P' oK@Wn!(Hc2@H_\x^˃"#(OXœcMmFF&8=k"@;5 K8ܕ~N~7㼚xR[OtpS=bP$W jhowLKvjFo=tY@݈G2&M oq}cr-Qb=8>2Cƥ^ѯK#I<% ]䐉)#ZJ)B@xrl^fA${Mbq='-C79&0rS#b/$ ېa+\ GԢ1b{lOaFpFbPTuY1{p{@[[u{[mqPT'<] qֵ4u X\  bV?TQYCSqyر߂.iIDaRia,d JaB@vK O&U'yѢ^ul|սFݮCN W%! zM;y;858f"|;Y&>?_Gg -.)g[ʙc03O EwZ?wڿx/5S;>0Y*}}aJ{}}s1C785%zcswZI[FFs?yh3gNžVt76+^-}@{x+}c"0 P{^*~K,T-l*,N]<.bPv=3~ȡ 3='Ճ$0./(a-SO')4C/Ll[ezds8`6 rW>>>5}p@Mȯ|P!֬*3Mf v;CĭR`Plv5IF  D{ Y#:e[ 0t"4(ex'S,uw1Nj5s&$xh^`[MG(XgДV)*SQ> yٸk Q +j^InqPD4.,T9g1/ǀB=}'-=xPXx|X% $\DX4:s[6WRbY 菉geW$V[;♨?q8=* u4DW 9M'[nQ2:07qEbT|cdHo\׌; Y 7~Rm}]d2Y1 9w_߅tL["|-4k-{^O~ϋzg+g.`/nR鞌)ſ< c 7E#Me>dTn넠p9vI#L#6ed<:ZF6#G6r`CpgILh'mz.d) U 1~ d2ϰ\ ߍ [()#+~wT~| 7S4qW.-?(Y@Hpit^JRoWY5]?-#TjL\ݦ>dgzɫ3iTSdh#ϸG%)΂⽠z}E7>j߼眶[M:u?K -~%de^-gQ95oYAG5FIZNL{hŊUI 7HJYNҶm~59;wQ!/w !Nc|T&rf}DWB}z!(aǞTFs؇iBVwuqm~#_?!dCN.ekkFE`?FwS]j /6,#2Rt q"4/>LofxDuyve7[z0--ҵl /E+X:1vj5}}Ծ&(60$,6Yn-|3Eբ=-bD^Ba:s$Hxm#Lg1;5j` fUF6LlǤ h?8qn [K<$܎+nj+l0ٝb4Q`*Sl= ᳖WAUy"l4+kgu\sō$Gqb?ܓ+Rk޺~zdJʷA~U}yGP]:@.{fZ%q&0L3ed&i~O]^;$mJl_r`e'v?YrWfIkߞ+,&`&&e)c#~h,*3A-Tg<97$2GWtG <ۏ^E',iȱfh[/,Bt fR{')$&gZo&U)\҈~!{XF s?iS9FG:KW+{ ^G7$Ux蟔vuBT,ӵUEW+/$t i]I,_.!wk)dXΣ̿"+!/+߻=O`A],xwܯa; ˥`, Tw1ߺ0Sʊ虦7g=t^(%8mU!z) =V^>]b݈p:al&6xF?9ӗ5>>9#!zgir1wB3+ESjw23?1u$OgV׵ר!zꜞ$::8y`Q1<d"Nײ󈬐 GuWbI|vz+uhm/jS7&+6CNk+2iY7O8m*\:OR~ܕR*i}fN2o FkYF@= .ba7jܯf۬;jq9>6'y#T-߱3 %fO`-I⊔'X\A 7t*c?r(WU ׹jv8zqs.r$c)L8/{ gX}|D9h=R,Yʟ v#xG[Uf{sN 7/fS>B3,#U14jiΉMhYKea#,eLg'3:Oҕ wl(=z]P}'nY*:HE49_hK%cjp4GI9jb+\0?=?wؙ3L}Mgw sZV/@6Zu!9J Z@O4kqlp7+r5$ uL7/ZA<=v* <zp!j&\&UVpOlP2mQ^#T+}J T1X"ʱ|b8D"ĭs"2E-ێ"j2VL`}ڜ,Z} `2mGi!EXY0:W%b2x>o۟{uwl `5+aE\N8Lxu&LO̚Rne7Dɲ%rhsdih̠JGQQl0wG)A/LXnQohZ'%QE2ݵf@V U欢 h7q*u(^$VtJ]tYF(amGj>מ #IG&6+ѓ`f^(NO?Vz/~y==c^lR;Lƾ??~_&BQ3y%@b,2X]?rL-<QYOp^~|VZ`3dsk}I *'^vnYȝzh@ضtf8kamDg$|9ĎA41ȳc܏ؽ/sey맆}|g}M$X+(Oqgҍ3ȡg*I,qޮ? t[^-G?$,rHo̚=|8DN>Mˢ4O$@"Wb,+=^n1+ٱ-^J[vJt͹TQrFxps:ԗTM _czM; q_pSH (/V7<5÷~D, "IiMZot?"Ei>\ O3HމӤ7 /!೟6n)&\ cxjktni 5 e2ڜ~̰9",d1h^gyS$4BƟA Ć7S*s^QowS|{@*y\ 3{tkM(WV ぃS;ݍ^/B$;?SYd]f|[9z1_Ch1$.4"xK< iAٓ@H;Ak2V"29F5'5_Jit -0k& if'V׉#i.\Wfs4nU gt?5_Y_ouzL䵈y4"p# t޺i2@"X?r=20H?W;gŶeXXt8>|bח)LUtNhG*U'vJIʣ1ʭC[/b-?;[&naGSaڔ"95Zz0<%n fF7{38fgP?OPLPdNͻ(PtC1lH=3Ǡ&́pIx"k\?kTP(( RJNkJey :?\'!gO}^R\KW/eMx܀_or삟㇋F<2I >rKdmCP 9,{J9\,;,* m/ds)T%mciSO HLcuk9ºC-ExǕ/vȇ'%>`IS:j$oq9:xM4zKiPuKskt9F|(;!2Z鸭v$_mSJn5gaPo#Aހ³O}uU"}˷|F4{&V" N\Zա]esЪỉ$hö́0S9E(6y-VrNBÓXA9l}\I_}SCiGlԤm4)''t!< F#N d1o)? ν苙rkgэ5j f20p~8\n MN[;Ad+n.X)([ƌ:4uH4T0On&I͹\= ׄr$r"4}0!mۢ~D)z.2I|尿s+ﵵ6rQ<5fCI&6b&ݣpA?5]A)M}n5GCl,Ê MU9"nd4%"Pɔ9FnlP-2wW*!] S˛]ʼn >zvjf @kT7ji)wźyMC SNILEьz#e!ܘE%BQlH ޗ}7M3tO|TE K ZМ':qwB]0`8QYY-Uts9A⯆,.:Zn|t˖OJ0m Tl@c~L$ΏzwydM"ׇozw{*n߃93$:OJy`Gk4nz+}gHhҫ" (D2&`雬QXeɸʏ6Umվ}m Đ1s2UɐTD֤ROHޓ{L =$m Sa'qL [W\+Dh4Ia&FYh7rd`dџFDYH!9 a/kg>̀Q+"A#X+فA-vz"oU1yVIޫt@qd[k݄]'2Q bXp+ƚWCF%EsuGg?p-G:Mw[ fɮf#(5&n,0*~oVџAO#<~f ˘elZGjK5 d*}Nã7 ۲Ώu:o%et^PXvznE'fn.&_w].ӗ> stream xlsp.'xb;ض?RLLv75P::ML]l-m<?dٙCT&.jF?pϭx9ʿcVT$YhobigPqO#'Q۬hd /f\,=:L J}7= '' ]L\M?gdja ][[4̖CN.3LuXZ^ޫ^H7ŚOLF-Uo+Յ_C!n~߹)LedWK;H0GA"oY]x֣DM oO[raT( v&9v'"?FO[[XAF̓b-nL:(%FE,YcV~C3^үH^( Ж%8+?|LlizP&4jӝ8=qp,o~|eRD셒5UfPX { Lݪ&ܫ~'b1EUgg.+l^=ps0A&_ͳ< ~dNF @B)@N̓ެtarm:\$})4>~%-dD)BpWB=QF0Z\+D扩Y n4 JI(709v*vΆb=DFFR'4ɛ]N%[q,2u = mwJ)5S9X x L 1"Fdh-LO7U=Í0h9ӕEdžI%Mla<,? .:؍m/}߯#gjY2rl6L֢ghzph#_OU!/^|\emte%) [U¼ _nUumIu<-鼋dr£uGֲ2wc* (T[yTC1|ѓ҂/fۚgaϱhMp?0 ͸7]GH}цe-yRI+P?NnK) Pok"ɂfFZJp-<}&L(@.N Wc_ gVL"b7PPfN'O6V)8l3a:TC޹ A_z1h&%l@{T{~>g)윇aK{u bs'5;CN8V}U@FMӆPpc5ܕI9"ʏ<ĩ[߶zL< ѧIp!|il| ZP hR[o*sYIjlsQYw?W~ Yu:89`I~I^L{TP ;7daF1zPAzΜG4TlX(`Z+i./jmg{arɎ| ! FCs'"qtᲹgc(<?р^{Y諽zn}IC"l ݷHŶl b^+xsjm@CdEPYv"o'3D5=']n-/e ="L*+Gx(tc VM W;R}r L8R(ڼ:KP@! Z/G)=/r=iI<.Fb)=|ꗚ3)'pXjO8kb86̂dOqc ͢Yl<\H8B{ʁ;#%E}ޤɲୣVQbڿ[>˟:vi])-uyb]Dppp7ud,K@f6d] -_ɶ'gpfc2Uo?Z6U*EޖZ7 9W7#hxWa22 B^T070=ta [$Bg_s%A6e@m#Է-B¶Jqa7D oSw:V *^zhiTizȜ: 9!NI|FƯO"OuCu¤><1G͒1X}u!/@ɥUia`Pa֢R_.>jcyFIO8jV;_c72q?ezGcl֬ euNP5C d Pjוg$yLg~aDІ[fźx| ``GjJnسs7o4 n;|C|")F=r+OOAt0_@~b~\ܬ7,0SpH#_&m?[[5]Lgt {AQUCy⽭#m;g7wRyX cĭ2P\ۥ}ڊNKO]>NAj]6}rP?"/SK|Zd4婔Cl>FYg3D52A1Up-*KJۼtWBIrɂ[5w#LAuqe @\j!)L?Ɲb3MI#`ܽ@9 U룻-Amjw_aAPbRct)mWtbiTX*m)qtxbB_5tjo+iuga0[.`_FŪ3[yGd.HEDN=Ɔ 3Nms=9q LzԀMx,d$N]QcIcb\1QcY/0旞ެZy 2vdW'3-8"9DKFVjktjZ`#8nd@ވx&Ρ8"ISڿin;߁TaOʔT6='F] Qm laׇB:q@yT' w&A-"C\w- ,gTvxX$ :$|Gݢn{Ē zfC?=*~9O'T8eQQQ}j q׸'" Qxw.{cs{:I#z|WغΡcGy4^]4[;m\7c4c݂ދӼ_&aEUE5]$NKN oW:1q_c"iFxZ- l* E騪%r?XIߪy&*M]Iˬ{HՓz6@oKj|^%' | O 7J^( eD+W̶w/< ؾDvR5FE6c`Ww}dYS#%QV9"GpZ3#:":eud/iأ'q\u^oU3ǔ7ƢCG5d )=]fR/?t0MQ!mshumM]oMًj6p3Jw<7P4PSbNj%w?i9=2/;7qD@;߮ s+hpWJ:,0Bɓݯ3k횸g<^IHBI4A,FEYaG'V2DB .eNog2pQ@fĝ%x9׸HtŪ1YBewmj2+8t{MK&qzF3A 즖5ׇ#Dhydnp UARr]-;Ʊ@)"9̓)$okVe5"P[AuF+O5E+͓ygLO(8eǓEj`3_{y1wPGq1"EЮYγQjРeO8- ;ʹG(O>.lQ"1t$r%vɩ."ڒ, 8d~OV̑A-4tnWN5)ZaB-J·hʴ䐓 \Jjn<>G  ye1Yk<-6lШcR"4%"ګT /tRĸa*M\gpΗ aKI`ANrZcc3+z?+;3 V{ ͮGϠZo^<7E; /X'Y"7 _U%U&YQ}U0Aw5n$ ۲O-CVG+"s&$؜ b m?x 75wV:t!zg`SVig̩DO$0Dr+8{gp)Q6{CJ97]u="Xw}\f86;M^gy*D:Uaj}ܚL/2jCTٴav2#8xIzEr;6WA?͑ 5~ϰCj GT%rjDe??*8#f=m"%/HSH.Q%ƣb(8EYAV 9d=3G Q~ 2kX62uP&yDB08h9 SUx5m?)Yӳ;R+WX5=#=ښ6 .ǀQɉƏ@,@E`-݊_A_(-i>!P5_KVjlзJ kpq-?{ j }mYiMJ|57F"ԭPCbFfi y) g5pJJ 1 qD=&$\aHlo .>ʙMq8©sar+yY +@l晔gπ3F}\H7dЅjb/Eg;z};;C^9{ hճӈ].-m-W_AR+c* M llY`1D0Sr|u4 6<;,E1 ۵JPQڵAH7±P:\< Be\1zCCH&H Tq5"Q 2{'6*N2_ מ#L%,6lT |ZdQy:\it_^5(*!iGRdfp^naS%˿CsMҝ`GC-ufSXx{.Iw`O3n*2MѼR,%_'R p&-* Ə_٧ȍ#q/0h_ W'vH_gG4W:>4~gVW\*X%+S)2^S`k3_`7LFu)z]^Q&jI\QW٪i˾7/.YfCaC;Gj@5٧yzAWסo)A[>)`Xj'~<6 DN?K&Mw |5?;}xi5-Qt '65Ba+ & K% ND, |'l+V_u UgFС*'cNs0,EsIZ̵q}m3o*e5R8}À.v*)}g ~Fk,(cTTl:!)U' C lB)b/'A^=9sP/xDv¤xq~?4W.0bq]sWZ|Jh| !& Ɨ\maz*IFT[觯7J^_Y+l_3P+ngnhiCW,wz|vC E`„C ՟ SKt}ܪ-Y`2O̤+qBc"陎SZu>ڽ䞽jMA+}fmlx""Pwq;jH{njO|Y?v۝JEeOȑ׫853[ᖢo o"*h xY9˧}6>yocE=}+<27ڛJ k>{Ek"W0Z ~TEܔS7@{v=o8>;ҴWNRׄ`(b[ PZ_Lɑ.kGsG 7(_taOtIFOH"$ caE/qz8>B~ssfT86y"sU3M*T|T&N~a]_+dwj;ou/Ob5۰ZSw>=x@.QAbIfIX6F,+Ult+FӪ<46^{$V*/xW>Z?x{!v7Drq;1,[ X%|s:=+_+| LsCxm}Kq,^6нT(m.O@cl.~I*UZMU+d3]jj5{9Ĩ%ox!E85K~jϒGJ yk(+TBNNy^ 9(%Zm)15A7VA^'93-[HչE?*Oajr@)3)O_%H{q#ljC3IȰuooN*φ q$kbY3d%E :k)<i/7h>ه9IzT a =l)otLA&ucV^6VW[fKZ8Jkm{RLԲDZ:-&*"*Kښٲ#ˆQSa^n^HNXS !Z\FYnq*3FMT] BId"jjKW0pSrJ6+K+]7D bYҦ8uݿC:['RfNS3U :a*ͭ];DP@E?97nb|lcO,aGޛkO>, d_MBZ޹85{-6!MyjM( MT\c̏"Nx/2t?T\ą%;ᷓd=#sg0{(e sШ}-D!59=fh驏Byc[6}<$2n; L%|{ AO )apHK$|}tS֔4QCJZj?c*`"4 '-1;HpS&܅tZ^[Xz LG7%svE?Ƕ}s|~rfZ%τ`fБ|o1iSv#胗vߓ틼5@ =c !2gu Wj4Fר^ 5%&Z6,D>d%R߉^&rSܝ;}1 ڳ|[Q|ۅ#IWe.woM;Jez3A,[ H9+ sfa3HX`7o|*(j֐*| ҢE [,=gU639OJ ,W^'JrO6H1'E-Pn_7_A/&ڷiq!sV!_Í_%TR* uGo)+1HGf/8b E Ծ^llv'nēQnbkpbosE+s{,,YHߢzpA ZWa#=dU$1ÿ IOiup􉃍L#kz,8#os,}Q߃yȲME&=*S%_Cܷ'B%xVR)k.-( ݜ5zA^{WǁqMJMK~oGYiIFއfŞGc)5^>cVhCK嵷^jZ8I. '0ltjzVCK(sijT\Gӎ(=e 5yc'nցPx"cl?ndhIYbAAk?{xŪAȾӂ VitH1|NBHG[)g|kNgo1#'g 6c75iIaKƩ 4fTtk}Qj`3G3O=#v᭭o =]p uW8ox"!N+r F(kqz4WA\rÚi={^w>AS B[ŮO+K? %TkZdEbٻ&\Ο1BXf2ZC^DiFbώ߾e؏vQ?rd^)XTv"HYCftG#>nY2R"]^ P<2A=7OF̖ Dʔ5r_ t*j9۩_+bԊ ё={bw;)f3Bϡ<@kW;I㒌uu3#\|L2\%x&)2u\"T(*CF01C ꑆ܋ E؏^>ۀ8?Y2,ph`u 9`-Fg&6`"o!όf-ᢸ>-5[WJ` gM ٻzvZuN\FAݹod#Xݦ@Y>PB2Uķx2?+ļY_\ ѡK;?`$( t ]gzM^\b9va7fM$ .9KcE@vKz-)%n:/6JJ]\i>\xä߾:d|'^I)}ĽNw N^qrk{zH!+W)2b2I p'ᄬ+ O YlT*_TpuTjҦs:h+m0hF|2![xCY 6#P7 ʣtK%z6Y4\ #}IZkM}2&<'"2؈2ıqHIsr]/JI[ST11kDP$n򁯬\2{ C](,QvJ,.Eft^1gi.$ʠG,ʸg=G\Ċo\-%zSibؤڕ-+)0N }>j00$F{ ;H4OF ݌}D@Z!V}n!ܵE 2鋣EwWhS`: ܄dz=ct=Fޙ d`ySX2zk Q_v;y&-zqm1,x ޞњpT ie~wIsI YAwݼY1N+Q\7XP1><FpWʶqMݓ*ܻ%v Ԃ=_w?uS3[8ڧ^`vOehMFC3tG}: J i D fDŽ<"W9V5c7^libى\@Eo &O\9ԊZLc }uj-{`yAقr (<.EgES+Ee-BJ-{yL 'r&:&Q' +`zst| c w"ύVMQ^oO u$yPE1ax{ aaA? Ԋi|PC˸-|~уu Wy be&I]@Mg|P渉ܨO{!'|3z*zҸ[\oµG*79evl)| h2ve$~ߩ,I@)Me̞nUt寛Y LWVd(߇Hϥ>9eU..}n- { GJ\O1iX nZ@u>20fU {FYC;@ĿP |s@!=嶟E*y4chPw PbZ4o !}#OY A待S;rښ C&?"Б`-T,'TƢF͛,K2ܨ sAL[ ئ5#:(lQ/#;U{FKQK9̥m9o;}E$޽u1732F袸࠻ V]?0GдIwŢ|4 0c kiڐ-ѸEa" &&slr ܫ A# 9LCY=$0.^]uCM@J;/!aތRDYWJ~ZT 硵.h=#QUV(j0Yl ZOwRG}4g*oxo,2LYl1WQUw} ~ Ŷ,zFcyk +;RjSo}p1Axp㙂%⻰\LTM;H?EW9˜P !oLi m)pZF֊R=ID4 t[{kpe< R5"s2PL޺f+BxUyDqkLg/fNb_| rng;ÖSVlđB ,C ;c6<}Gn*jǛ +)u $˟^@4M 6 9˲bG!eIxJիR_=WyKqҮݥJ-&Y)`E`%kl[?:W>?晟f0 LahPJ:AO{cQ!d"&~Z Q؈ɴ[6F(5^w< Ém_"%J=Ӳ6A6mLJ?ndl1rdz$DƮ$xQTL2:5acQvH0Ba6jwykcDR30'WЄ 8ݮ@.Ԁ@4]49[8!q>y LͰV]H.xׂ鏀,o̟֨gp/#t.RdFcps:V{h3=.<j χU6:AĖ.Z~h5Y9-)*ٺ3"Z Q]{*,BZVrVLղvKm,a}ʷht,AxՃyMbqQEȩUi,$Ey~Hy!88*FYCMs6*KHfɕe\btˏPʥT < @?4rbܼj X=*>\[<Uhb@54)|lYO* ߙsDdlUNHgY%T>FMf'Kk4h ߚRͲsӵGte]PE'85c-#lUVAbm o~-Ev/9E98IǤyqq=u.. ?yC h,@z\{wX&7u( uy+$]F27PkPvWM\\I ~@C١lp[ xiQL~ +t ')O !eB'5R^δ%} 7pMLfk.SZ˗A @o>1<[izaphԿ9DsQ6(|\I5f;əړG4>Wxœy:5D;pqr2NA~0?c ~>"b 7tųnzsѮX즮XْNW# Gcl9mJlHD"ZK+r;cPz4a|JK|J<']9ĉnxNIb{& ۅ߀t~tB Nz> cYv3bTsZ+]S?8R`53Ik7$7C@'9`gvp[a Qa}oSۡ1GdK (xC=75*5 8Ȓ!Ӊ*7%pڨxi5ׅ5keʎizp|\(oC"9h֯ iE$)9aԔ> ~UD瘡ntOiOnEUF+?R! -(A/j4/&cs5ɳjuϊXˌ3/*~Fb{~R@,7%bvjآ=qZԔ/?[hgGY\JKAU!sĔ,L~J]/ m, |pŞUK8cj*2P0$k{u>ϧ?A ܹ/;H\E6@qB)c 2MjH6˔!Q.QxBAم}(JBOǗUBANdDOc1>`UlfW HkG-B+2f.`=%+ V@jZ.6J\hX vx<KZ%^ncюitʸ~Bp U;{K>hy̓TĢ-O,=tm$a &ɸ'HexMZ"ۃ$ "^E0K^*T  }m~'эqoL ɓXCmósehqP l/5S{ XfGK:o}Ś/ҫH~ӹi@1'vE[ĥ%J>"<&lG=Ƶ܇]ibrt 1]1E饢`?EMq7LVZdK@Py m sypmFA=N.siEa݆8" YtV]&R[?W_}H"BѲu5d<..-8,uwhJtZʚ)D,J@K~WA3I@J?]7^CZ_W}ZF:c.gMa!m'bmI|1ꘚϟrIINhc6tP1|-nR0T ؘEV9zmVA!|iCz"':Zv皀4!s(y"nXh˿vSfYxϺ Mg9%PΝ=ȠmGFniAwIѹI 2}T!4r:D+mMݐ+Vej S:8H424 1[,^{E N),Ҫw˩^yWt5.QLOx^$C5cg܈4gSl1iW_;SIOќ!Lͼ0LBpq{z|m$]xxdp9<(OThTS0\qncUJt`[mPcwӁ?;'`bT*ab8| +HTamՌ@ܸ,B~[.ĕu78.`VM-5/`WɈv.f#xh'?,ZQ4l; {uJAN( mg0YO}SC`䛹>3 l Nxںһ % ,:AM+llM- M-YD Ԡ{Jzʹf S)F&$(!,x~\嚷)h;^S)j,J8v -w51&1Rj ${KcDA`/AoR巩*rܚ7bl0)䱷X^!i燬j*lj eD (K1w * ]NsŊF*1lYt geNʹ7HrX}(}.nw+ϛ ^I gEo~ z beN8~m!qmӓYߨhΞ !WA:X5 Ai"G5gi<#;觞RDf.G( %u!!t.ʘǏfe9%<* P KdmɲGZ66sq@+;u /H1ji%/s)N1'*ʥH&dKǴy@TԊCp(ttke|y},"Y<!/|〦#86Ηiuq^"j|RXt8N'][.oepWX3|ڕ,y v5W5(,Kx!n ,'l G'*WiH^'W=->t[qe]-DZ9$S)*ƹHfp37/xX&!Tȡl*E,с;NPU0fؽ[^{M̘m zCj#\Js7Lo"'|/U-  W Cvx7ҜrK8QR;P#oʼxc9q=ҮN%QrN[]Ʃ:Ԃ\ۏRN/e*4\,hI8D (7kQ鷿Z$[f\.Q>zXYj^Sum.f 5>I.6$jOԏdz,r-;bWv!GZ<8Nake6[nlS$ɯfVU\GC4@K塼lZdM⁐* /ݽk 3& t%ר3P+Z#?ʲmq*/W'jky K"ݾ,agQѕQWc/ĈL$o:H zCA/vl-\y"ڇǫ]A.]՗=7NTR˪픕lY7N98:]h8$S*ݘEe.~Ƚ(S"繚i#ho, 9Ô/H[XG|j]_Hgl &*q0hbg8|EYN4k5Ȟmy |n$Rj@+p?#E77;74jnǯ5ى"_fHnǰu7.5Ȝg̊H C%mϞirdzκy),MI,ellqfaɽH=U\BޱlI;g?u}dT쨩<<t2098T"uL⍢U<^%9G %5(Gup(gSB +O9 x@ڹ b~:B?H;(EʞKʹ15ydTyD>] Uhi?#;a`SPR[g'ܑ'lƀxpBx?~l@8q?j?5r s}20R)W綟%e=M/_sM.8T}EE4'3j :s-ȝQ;|"տ]Ꮷs"IRdwC5Jv$ D\Rr2Bx'iV?;aּD:f>P8/ՂC l']Mc gkr7Κyhv'z+"۬c”to"&=N!*˂x::BXõ#KybUo{>FӸEg059 ˔,wÒ|ۧ ^ͫ6y9rqsy>K}I-BW(!kcgil_/w"z Ym=l!h;уHbW?xpWAG,r˼jS GYUjؼ% vݭꔊ&s3U]ul~%$bl2=l4vũJ^#;RJ?Qy2:~E'꥝O|kĐ[r&B7ACQYfݤ,X ;Y2|SY%C1;EQ"bO6.\=J8]ckt=<֥cq\Nvhnb$<[5*smmp#Q0╮bE *(x7Jv%>GqPɈWZ]$y?+"DMb}`Ǽ<:zDn JTڦgf^ҽfh}#)s|PSyD>jg!&(ܲ#㉩VH]@x;7s)rr,2uENY :5nLw~[l4Cmf 5Y`& AS%n: rkGZSeGiln ?:I}:f*+gᴲؓU! Zՙ{ki/ u f_6vSK8 OT_cix֑q:2(jZ#ѷԇ9["ssh2iF5yժ \O>Px6QPX܆y[`fqu'm6+/NZruĶgfY 5[*f*S2ALK[O- s)BS]z9.4MLN"gؐ.Hه0uH]"vFkr1' vK+BVqxV.I4sMlP2ey)p俨@ʷ(# u^.Μ WNqwko>ЉWˍMh&]c(NQ}Ė2ϔBg|5MP?8glS] %sѸ(/r%tjD荺xoV1پ#+1 3BH B0(:Ya}EE*.*dzqGϱր=ssY%egRJ'kPi0% f$ؔDi|Y+m6,زHxuVW,Ze7cm 4_XsIPU1"O~"ߞ5I,K1#9nQi"Ȼ}f|$f SFIc{ KGɁ~E-$)VÑIɄU]a"$xPY$69a|fmUq E//0^"l]4>+*}3qLIґGK{C+w-ûX[? @e5! 2#M!¿GK(5/P+Sʓ4[<#u\qe͎IiMjujiG{tE{Ic`qv0-%g4*+jIW1p_]IN#_ji[j[8)^4{A/ZnરGi5?vW:\Dzځ\ z bnT vن#7LǚzsrQtMJ=n$]"<0({/&GGR3No>X FAcٓe6p5 2"]6 j.}{Ӗa NTuhXUCYfLq |8|~B_닶!Q2I ;bV.T8f Ed"hgQYhW|rJeP`6]eBh]7^6לs9_ '3< w*edPm|=mVv#NNjq?Y|ɖjMUQK(CT^'EsWŤf e`/7[~R`sqDx~Q1;{P9R2qev#ۭ,~vfec>(8z[(9Mi:ocd-;}SA^P?D WbA(8ewL{];Y[$NPJոUUtq35iF;[TRԍУ4^OT͌3r]SS.p "CxVAWJb!cakK)ݔ%gz"ph phEDʽTz_-"VgU;%r1ǧTvD`@_OkT)CJ1J"gΙ.6[o8ο/wqқ40oh.cv T^f7 _i\)Ll'\02gV)wfg<5A]BeDr@}xР{fll?<3Id:3ίgǓؤkW^4ώZj -57Xe/B.AT=XH\5kugfo'}I,SP*ENTh3iT+gÛ2T<Mۘi}tAPKהq<+pf&1| ~o[&wvj'Eq^tI1Ԇfb#ɇ wFs"u<\GM1 3BK;bm ]>&jQGU܀=ەd\:%d[L4 ҪRA9w ()P:Iߝ݅.PDtiRv/øxsMՄv9Pk`m d.kK٩Kcڷo|&PrE۪cxvF!32>L"i$HB ;.+!br{ ŝn!.ِ yغA٢RٛQB{sH+U^uM&s~"싀ؒ\@Di&ŤܸaYAdPup/\h$Gͯh_#8 MjY3PS 9FJA覅H| u rr`J1 *N я;![Kl=0z,C$ZIW2p1>Sֈ^6 ~塚y_+qC%e4qSzd?&ql">#y JX2OoZbҌ~Oǚ6poh_\tNkkqHLn "4ÎZA6A9[" eXiD}\jx+U>e$5*X~: ݿOzՑ_42"<4T79ͯ(eaV'['Y`? ?HcNUbOR=Y=vPKDv6 2q! y߭EUBPjߍ$Glil볖<1~sB.1FoWd[E'#bhphp ۽ۖCc,f^#m%C )/'K\J7u:Dm/j5#>uK$ߨ= xoV":3f<=~TcM9-⍩upŃPV"+dy#OM<,*-GlJ6䲍u~W_Wv=Yf\?#=o_*qy1VrweWU6'BIdPkh.d-0˷d.d*1wVwǂB뺡 )̳&ԅ$^ ѓ@,iTsc^"/ =ɉ oA7i 0L7]Yc8/~Y;Z.y$"?Ph\\&6Ϥ e({P:D"2ʚwJ˯(*ڟ,π<_j߃D4:2ӧUPR[\ @-X5eWи|iXV}:aPecGGeQuQF܅ 7j̷98Jރ9ΗfV6׵"QVÑ^ -ĽI+~+d+Ų/ E'mwR59 'V_Aa f5vig՛EA &ܜ5mqs :e-sYO1WV0|r7`lB0 v3WP [D& $!q lͶgR)%,t^b!9wpsxcO3(\HVlvl$n;Hu8UxזGSV8*qRu$;OйW^Mb^vP*V7!Qnfg*e`'WŊCvA\ ]&ASeDJ'|TByrk\Y,>\nPSY!~;?b@ZRΗ'\*VE#O8}C(#T5kU*U‡ OV'D5)wJ#BAgJd{P 7w4Zɥ08jȤ ?]‚gne%FqB{-wMT?jo)`:$AQ҅LFdZx3f>!^\ ogo>*g^&E)c ;3=Zg{rC*ӒF*r!( XWuRCsjȞ0Tf1#C[@68+İf F*9jyֲE(MtMzh=:ʳlR⼬4G%퉫b Xh&j<.W*ZCqZ4t(Tp 4l+ hl7M}rUF=Zl$&iMm 7[ /٨A{9'p b^ˇ?rB@@zڒH@3fS͍}- ۥ @[8!"I_Z4|^֦-P9{SD9~8fY܏J,`"8 e(xhZ,#=C d~b_%%@,бMSzwҤ]2;{`b7ί_#Y`F1ܠ@ajuWFy i.Zf(Ć!b4bwrz_>`x) #r(k&?SugMH-%{.nYF&<=a*6y< F-VW(aa2 ZDzm[lCz8r%Y4u},S\=u(l+(Lwć0a s7=exl8qpLuP4G1FY(pogN=d;wL.g],yV 2)8m!JaZ|-d!2#n3x!H ն.2FzESwAv1SeK Y(u`m 6,pK"+~ɳݽ}H9cԣv$VӾw~D''tl(ķ rvDIN:4 gmopUg|x7^،f$Mt9&Jk6<Cs6B6Ȯ3N7uB ?hZ7]"cEy5 }t7%6N:FQXGX(\f,4O R&61I\< E6toмǬ ض@BҎ|!ʮuЎwɤޕ >i?M&2gdodŗoՍtHMx%؂4șT wAypx{z dq՟vF28ƥNr6BK^b-"_.jWAp=]R1]xY?ަ %נ Uчa0@#/++LINp"u9$E6 DiK+|Xrh0B:[*/3OcK#B e|"C<#P_'zXE ȍ Z$*tT"viuvH:҃<nU8umN/zn .<YZj~)`F)8<yevc!~ufR-v<[ב J)4C2۸__RobGzv*EPtêtR <KgUXZ2-y n{.K{@qX~kI.g'|XZka_fC'!rݚ᯽9nxٌDUֽ3^+:&Z/4q1HJ*D0V 3N,XRZ;;zGs W [B&S2VL `Wl Hci?7LPT][~œi4BIwg‰,LAisil'^?"M~b*A %*B$g"?tG(d5 Bxu$P(8jLfUiƌ~p>҈,m13eAƻX+*g{jdq}ʆ5G5𴶫ԀmxZPPVnIő;cǎ}SG7eÐF` ڔt>] 1 ѯA =+F yBJ^AttL9V|MTT=%Xm8X6~>/M@,VQ\ JU*oG lU8y5o?.t;1HW Bv)Ψ&z^{[ȉlmdבi=2Xl (1Q5"J'hG[B Ŋ"'SD;i#p0q_ <'XmJvKKeeqgZU?] ii{n)d,M{}`u+J M!= KAbnIq<"k} {pD >aNd4H2b4;Oۼ\$!bوif E K Ϡ||fZ\W |Z|S6F"TOŞۉ̢&Id cZЛFuNWo.QT^gϘt>NGd℣CljFk$|n>h'f<Ƨn6M>"[]R?datjfOE]ї lRנDχL '. HT%w,Ǔ}MYd%sAma.K:V6C{1\yVTu̧6tz\F@@BUc"t2k2.gd y5J%?o,ZG @Y?k$[?d緌Dhu L2Uo::%_}08eiD6aMo1@J1"TZX_$ KPz{co )JtT6!~\0= A k/ -c(쥊KxVn,X7Pmn5_kL'Xzz'?BjlMQzN Bufq8gnH0kenj"^<&+izQdSZa3g/qC!NP'4OnWR"-8f ]{ۼj%Z~pQd m8ܖѰ"qeخNykzZKfm*snSJe5jnf4^>:ǿ$\UO J%G@ޣv# K?L/+#룺F_w Us _4%Y8xַȼDON 6[A o!.mVᝮ5 ZɌy r=3u+w`f1hMS{yN0jh6kk_=HDq_bpyxlXC됧.$3 70PجEGy\O-8F20U]צE{`Q3^/${]Ŷ>|f1ŽYe޽wI W'>_.GtN].ږ}rV@z7%{W}CN(8N&,KW=`pC.ܢC| j.Xh +u|O&uyr:;%5'4@86GOr  P!WLlʼck b;HGQOg)lVAo{LdqM*P { EHsOwg˨/ ^6#q۳ Q?T VJ}s2V-1 Zu~{\,7cpX5s%)hv;ω^?G$`U%GRN:[?]MFodwG&r ByUM/Ř0r&[Abn;DxTeT" ^ @nk`2 $I`hsu[y_8U4Ӟ9&`hjg엡BkpQeym|^hʛ3a ŞKKrk{ Zd4/ϴaӤq&w@8X)) 7tJR]k,)#T@3_Q<"mKoy2}ΓXsY']6NI_9m}_wH۩L1Y=}4e2(s!F@]lx2?5Z  ̝`hh#HUCFW[~xo7){׆_&1& ^j%kSiS;С!W0prgJᩘZri^R1tS8ƍp%yX qMrBkӞ jݎ-'h_b0@.lVi MBRz{`h@1 ={((̋8=vtkJVm`ŰhOyh*{90[+ g)YJ@> stream xlctf.NǶq۶m;cvl۶͎m۶g}{wo?S5ꪫfHYHHPSQadd01%4t1trԁ&e=  lghaf 0fmhbacPs06𸺺 :93H8@8B\N :Z\-2@[' %``lgkb/LNt` tt @VTEPL^N *L" 05H3ىhVGp$`ba 0Y7I[S;&.u|8Mv3(l]Y;-_ܻ9Zcoot6 A[cIh`Ύ.ՁY]53G/)!-#J?Io@> Mo2XQ:;Z" z+(!!;w/Z&-3#8:mM?kd݁0Kv܁)e>33SK?'-M.qTprxw.% cpGDK8/E$f>՛oyuzW`j6r`aik T,gR%⌑H[+┺(Z_p=*+#UА?;p׿B.-5f;%0sE6ɶ\?6.w!R7ts y7eo 3>+xTc6yY;v]}uuDa`mvפe8GWQ,f70+"ZOߜy )B8ȝ[7=> 9im+c~y 1 c1CNEpv49%[07F{ &,흩փ?]A8.Ks?-?|H໦ix`$p 4Cv'C ꙿqF~u=OB]9W4b 5V:R*C./8Ŷ{vIc2[nXiAў`eK{7G*|+;D+I?[$/q;#T?^t:2CУ]s;=&Uq&H4ay!yˤ/4ՊmZLW2&ž8Vù+U!Bn wqWFCbW'̎~zupL4URPvPW-ZSqYʲ'ϚT 2;#+BE")/\H$-y?tHT'JJ E[!D,Hvaїӆ'Wb*yl}NE#t#b1a?,G5Ka&B;‘vEe)}yFs |^0/,H8,҆[ͮ hSobHX mKZF; hXWa@Gָ_h7ft1~9d寗0KMW-($t\x k >=Erow[-{[)Dq7]ZhE]"EFOD~^ᄱHΧ?UG(d%+}/ߡ@`S;l_ <@KR8b]uz_lhD\4,:F20 { z<ʜ!h鷗dzDsӉkf{+Xa\^*{;Be-nje _y3VVN.&[ FkS j64$,]ٙd2P >!Ig0fԋ\"=C)BNa)\ڠ)9Dy q8זiJ"Ʒ9(Wog VU˴ɚ j$Df?)mYQjEwn=ډBH tK0_EI0 3?/H#V1+aKOlc+ U38]1]i/=az:kZ/>3?s4\,/XQ7gp 4ۏٕq-F:M08udDɦä@=يYo5,zRe,"{eK>R =,|iV0YYk}'.GCCû'oFgEJrȄ=ujF݀_S5R0AeI޾NThηIIYŵRwɏIIZ=P6w2Py*c4t|NJVeaGl{ĭ&&AMEy"_4 b{=1e?C5Sq7,|wŮi-,r:Z;NfM Nm/XU>WsWg}W8Lg97>` 9ٌ/@ ױʴӀN]Li-g;_0n*nDx\xDsy%I'O͋XwdwOz uSB9z@ ]$A6)JayW$Mdn%Q vǬjO ҃kRRxO>>;bܲ*N<}cvI tҊ~K2BM ٘ǼI ɶ: Ax k/Odo-ek Bud0drHH yKZxlBTаà`zʶ%%ҡ\0ۗtŞ*6(z| :}wAܔ ls?3231G̕㞴b*ńIBwh@ǰ uڥ -\Z|Ө q9m/<*xhWzhN~$41Xk#o)%֘rmًDq,zw)֦iz+m@G.Fk2G(B`IK4ٿ#^ _Lb'Lv SiZ Nɳ78 JQՓ}ŭjza0^W W͕",!emcB  d*EVYSiJ] ·jUp\::&޵Wg-͹אaO# xB[֜0bf9dži|!3K\6grp~x] d?MRʹ piSט!hp7:Gwr?Nm֣ L-QrD_Gf dUd4] ͈'YrB?e@h7M L3cu=; h8w׺3#vԢ*e `߭wNu\!-!$y<5BSSD[t>C:䦃jLPYPc0bu@P{ Ռ^^yAEAjxG §Pt+x i*|0-c>ITN,vڟd}5*1#֗CO_C(l)ǣ>r<7c٦ZOqbY4 +r:_Kw8gwH H,4۠B,𜴜U/?bWG_hS(?ųr 53K]0@U9ZYa4#^{>T7SJɘr%"},bWLJ,/ars IuH*m­ |,iX cnǧEP&8. fBd|EZ܄U$G[­3ւ)ݓE޺f_bKZAxSL_T&=`x" $S&ӯ,_e̜)/#ʑZ]/e3ᯞZMGB&T<>8pI3UxU~=K*A3""t}*BjFhJ8} .PXGoAIbM(u"EbX禖K2( {{WN G>s>(շHZ`ެ. S[V)Xݓ?}OwH BS쀨Ѧԏs%!1NJ U O_Aʉؽ Ly]%BfJtJ;X[1H@<5 XF !$#֧߫.јq- y:Ϫ{kJ0fjb'EZI,<6h_J6A;#lJꞡ55Ӝ["&&Q"aN$zO(##x/]XI^f@hm6יɗW[Ľ(+^30wK;,'# Q@g[1TBٻo+SZDjLm|Baݎ˒Drv- ^C۔nc,EM`Jµ:惜G^ ѽEM{Yi@]bFj/ջj@ e ,&1XcK'ޫe(6cKxl6ĭY fr (~fˎzK^`QxuCwQ8FǶϳ6(V]Vz-_()u)DWmE/q5'yeKSj *ye!2t7].lk^*UN6)q#mR;(fB+W Gpd[dp\ gR,n}Ct c7E[ō'([T1x]QX|Z%AoO>ͱ.u׆3[f Aqm<n ]g$]8"i d~B$хs",4-1 -ȸkgWl@&dS'u5'cju>ymS sB0}^\ZBܸ? 4$5_t"ԼӕűE7eRB{wA'=wĭAP;BRZZ1@ED9}(U=+1R>ZM]88 2޽b{F(/,&vauB!a(ȧ^dq+?#&ʎ+r["Gs<="ˆGh+i9xĪN4{$u6öh gT:$4 X7ǝ;.p]I-Kh͇{KoP/Bɚ k^aHznW}--,9!E2l6Nza:lRFN[ `$hTԝqGLM2/q`] GnUτ4TWm(xsxW>*G߬&N$hSյ)suan~ZX'/:HPpVS4{ڒA/+eT?6aR^l<&KΥ+kIP]kUQOĤg"!4[jK&QXlӚV>e-mn|bzs-j-;yy^Rl?vcS헿|7gТq]c֊P }x6o®9MR0ntdexEܧ$,jvc^b78;EK[zp3!oE~ q>Q=tH(7-geh+%'5&/ zs Z61p0oF^EaՐ^ͮnwV #C1[Og97n#l |{GhʆRy3~Xh.]Ej;v]EwĶr"ƒ8Wf' RaXZZ\^ 6!eG7;%eP:ՀmJ7:S'jX?|YLY!]+q_&NT + .)_GZ}5o3S@5*Je㞬#?py=\bjq${zENH,PQckH1׵k}[8c֑5X E4x#m*| :SC g@@E6W8':-Sz:M}tkd&ӊƉ imS X+`p t` {8VCý0\/~C R箾1WD :I8l K0TpzDWnalNJ r/ZQҡF55'!w]XGi|r< suU!/,?Y"m{Z)ZD0ajر)3*=J~d)cb~ ߠEFv"Qu) )AFv\_ XkM:;_*AK $]Y2FEgC Qr$6Z'Mc8G=g,gN )$6cO7}56 1 aXJL}1eJ„s`Th J$^tͩ-K P dQj&XHFbnun2x_E rg1Ҕn^'*xx{6'Ɋ8"aCyiLB">fvl.{v@`ECvN Zc~Q!H]zk:%+ o=դfGHzRHi9gTU#dUh\Źޝn&K1imr|pEĿz~ #]d1] !1E m5ێUC; 7^≄v4o-cst+m"gҶBx\mʬ€!dM;uP8=<+{cADi;fO %[Uɼ=c97l d&bU )9Tk`b0oͣN{Vs PpX\Hߤ_wtV;SOQ:g1ӛNQق[ƽ͗+LϢK9Ǫp4l?ʭU: YΥWL]kP&(CN܅ѩU^]7AB?i9C%kegl<ݼ$c~ԇ [8. e:PUJǦ'>?ۿ> "n)+\v.a,.50$99HW% TdrD ?ePC,e8u^kҨnT3{WA:}SԧiLx4"Ը9\*8@*V>k I}ϲK@o'ّ\'ey?ZPi͇ff)SΟվ=c—?@8C~g5ZNV,"͇tA庽oѹDU@>w3Z$WܰY9x?y]*,u4>ݭPh3=5a[Bp􁊹HTC,O'[=rgA35>M扢Qn-̨VQMnšw}JVȟ`~\U5Bp~82t3(@v6lX/5Nq63 J4畎&`5)ϟhx8Xf'WC[OePB!ºpPyl€k"?-RKy&'Qb뻂 Qy`M"}L/ *P hmCjW g ,$ڱ*ai%%"Ehߘ#haB% hكIV/+D_6͓v{Bߊ:TOר>CAW4AFf3wiw_p*ʙjC6-_:ݸ3x檹TTtN샮,V΢Lh9+ɒƢB_o(3(8Z$62_n\r}9D@jE`i^'D]^a1ttNM[|ax] L^(UWWu^z. AbB2%҂A)Oc<9` $l[g-wLN8$_j~By'sBj/GigxpY; ʍg DEͧC9-~ m(]VsᏦ݆DG\xY0*9/~NL7Ok3WA( J8:T'I=.3Ua{@+X'~a~dM[ŮO1v?d- KaL[lH(=WO;4Zf6']IAر神˦\zz]}1Q8p+%;T%|ŋp?:Qs,S aZM8ar邫tjHޝ~%a/tz;]7D; *ޟ,]=w^9$U #.I6g7K^#Ÿ̈FjfAϯwo >qG흍)74M*=FBWa=@gz %jԈ*Rك@L)A:D[7"bq4li-*W‡5сV]e ` y|`6W@fj?xǯ^lfh Փ&ABTTnhoD=HTsҥm_ɔ .eoʎIBY'𘙊orn|@$l,rOd<fCl6;0;~:xU=(vhw3 SLC{y({(?7TC #O\-T9Z+4680@ {ǯ#s 5ΓMc|U-8$̂pc&^v"_'^v@"\~<7ft5vU^`cAQx-M:c|6ߥO$h,@yEoQ?5i=x>rkM(@Ԛ3ʂ>t,l'?A$N^^-t9{[j:[ν )f)*OR+:Zb+GjkbC}y$4ǥ W:{"V9y%J!mblNL; "0TA&)iRR(? {p]9N_fsO; TԷL(0JtHh9 _|g2a'G 7JwD`۶G)b*`/;S)+G ttÀQu/,p `98#jͲpg\~@nֹNΘkipqW%N"0 5aƟM,O:"WIc: Me0XN0 WbL2qX;4 /J:ҷXt7%Qe -dRe=+tO"C|&|FNOv6*V.w~?rg'c~Vh^Cq|7fl3+9") [[Ok*<]#-p6CQzAv9YFق\:'A֒pNNCȋ]*u#:}*yb,%FN(Y!~d k)gW m5fiМۚHmn!~v9p˄ID28-2t]k1./>UrjLB=\9`ꋻ_p>F17? ˜@wX_@ɛ{Ds+D +eՊ/HGn*T|akG,1lxFdu]Xf~.=Iyg8SFj[#H&&0Pk>] z A~t0G+?PtڃVNOI5ZIcì}M~wr^FN}H֯PuwPtmq8rP*J޾Rlߣ&_ *:dJ"S+M85pb@T[〿dylkUH}7<Ly e0M 4&DBndVF}}^zW峧{Ez4\"^F+PO2r3*=IH2orU5\Wih^X`>A ww]MӮTG@R`ĠyNLԞ'Ċo9?s܊/$&%D_ 6f:q'oU];X $ތE̩([)dF̗bÀL" ~`(oM820$, &ܯvpy=iwy%oF+$ $Fc Pl/ͦCDlRDY61H'*Er>*y|.C1Rgi)w/(wK 6JhA,Ω64kG1稗B_ێDRA&G>[0?!I$4neW1(y_1>v_VZSAs<;٘âC;tu<-v;3?Uv &ӾJ!NXA;rت -gs{4ֈ<'ujiީԎUi|%oe{LhZ`{эDp#H&/ZYtfk+4-E‡Red>MV(F<}CP}&Bo-_^AzM ݻ* O0$X TZ5!!Tq &=η'Ҭx8Wfk@F)O<+G>͕uSos4ݪf;)6A!Q`JÜ0)Ga?K$Ljۇ-Gkj!_zЯp1HFt> =ͥ2X4/P+5Z%fED٣?Ń8-|L\ !)9$ Oߤ6)A2]A!M敽84ܰh8<ܜ|@c1f,)X.k酪թõw)[ਙcw?fLZ:o+(j!UR)9ZoJ#~Owg/se#x,OFu#9Eyw 53$2r#`µdq-ˋzF n -CTǁrrލZ|s [vod[2 %W?'PdCpϓ(|F,G_[M[LT?l@5y$)Uu!I\0O9 '_6^ 'Y(;Q> 2K, [R_o`}$-l]4;}@m76:n3 ]BЃhH@nثVNoЛ-;k p=FFco x )p'.Ո=bJGM5KjÜrHmJUUf\WwqR2S5'хM#<\Ned`tMK!8M+r@ѣ("*s(u6Ww 7(f7g=H?|`/~'p+S>3Ã!=iL:~("$wiPukL"eCOü>@ȭ/iK?Y&sf^.\'O{O.3 j*=%ר̿Iνz?i7zV9i կ[FQ!Ql \84hrw(c*rj͆2dUsXՕ9Kak&o `EǼH Om6r5kC:^*ܚ1~ZllE3N 0ed4 Bg:'7.`nU Q`zC@Z ?_o*6 1ctvL @~Ϥl&z3wp|,:̚藻UGao6բK{h6'_uTp6w>+Z+u<%Nz&2Q">̂_ds~?y;XO:gJlbөGX@%nI.*Jr'̔-v ؎#tQig O1Tb;=B`zHR#ay & /޲o@d0_Z7*DEaòY2?Wjq3G2;#^bo}@[^DΜ #$l}~ݖEeI"r%<}EL֡DdH,DYT:ߠ{eofSY~URCcfu=c]VHY 0/s˺VLt8@t2S5i~O-5.7m}G.#J%4(d #8 Nj@F짖0 6-d-4[01/>X4{f :vVQ`f[XD1ɶwL$F\:։~_92f $n-BR\6{ hG9 I4H0uO7_|u"P'潅f`צu$õ1\-y'kC+nZ^rut@M.K$TЄ$ DDuCޭB_]@˼nm)n|Wx:hiC]ŢAk[nԧ[%?)\J=i]2@`L &`o#ؑjaT>37~ nptbyGE]饍fB}/toV2Q^`6f0%g±oD p[WHPbѺ۴F( iADǨ MD0ɡ~@62DBiYօʵ˛;*ϒp[yU3[T[6xAroėp]M.r)RjVN)v Z'N)yYXxoaQӽIC*UơĠR"l vtۑr OY1QpSC ipXD[?1c2A3h^LX$BO28@[!Š1|>0x`)a}wbj @< {.)R@֢;ë1|)9aAvun䖔+:<__jr9@ÐD4h܌>Ξ3a9aga0ARO^h8f9!]^{bq۠M+$ANe>H_0=ŰXKon,DS3/GbXeu捇ŏVS1p\]c!T}%OĊtTzL 98X|=t)@4sM5C]{"֝H(smFjfJ2H fovaO!ASتw?pj`Iһ99)qdqYƭ 빋K@Ɍȷ " +%]bP"dU*@IjNPkx3؝o%+ /zll83%~hNi%}~8$iJ7s*KBQScMPN@(!g ^QMK PEJlc'od}of Ɨ(!Pظ+wv`J-!hɹwwh oco g*k+( {ǿP`}(-zH+b"3f0I>r[+CsTz&}ՁKuV(W߈ƘDH:.pqv[9ܘxk9zT9qdگ Fx. !k'U|d I"mVG\99Pi;nT.bH[zt J]Wdl!I8l~CSѯg y ( ~>Cdy yqvuuxlXi6ITH\D>dZvqzX<%히gMxCc_CQ(v'ב2i!(m&pic2[2vvL?#p{PYF]6VبWHU\{(#ϋBq:[}SLe2a F_~)gu,+/Y:DD:ءTdM!+&ee|} A2D؟D T xh٨9Gp@}[1h*M%$|\\e}i'rTHOzOڈ N肐v}O PP\Il`L~rnqy6JbP}(xEB{Icгl.fGa:Rc,ՠx`ȍ+O^' 3Uvba#t܇"!DWEL;U:^8%&ʽ>|Yc.V|Ǽk%3eJ h;F8ӻ'WkKl'M_6HuuQ*HzC7_{Rb1SVv&f:TyZgS֫]I`*cqZXrV"mzh/Hߝ0=ŖhsЛ6 a2̽\YcXhsT岸H!@l<8lYg̉"(%1Hr HDp<%di0aQq:ϛ'UcK%! 0ACWcT;5󖵎h.\4Z4,7&{<Ճ5%}{vu֐7.eNK%.+G<Us8TmL8(P%bܳG3Dh$ Cw vB6H3 5vӺkt%LI6''E`"+dhu%(VTIpx%C$ӖNԍi'Us:rɫer+VPBZ qz:"KBxq#h7aRROUR /B L*k),etuAj3m"/"Scñi#~Ϻj52sea'v>S Oa7]uٹlʬ%7\#CHRX7YH[3y6`3vj@ldăK@byt GP18W?Thq13~h=1Cߝ)oYg|7o7ؐsS/'|TG* YZpk~qq|ӛNws$=5Zj_͢?;+ c\}˜P<DqMe 9HV%7>.FE\֝dB}x|(,5Yu@_L<"hBttPndf7r2,6fe2%#rMXT_w[Xdɂ!(n{x<׆ ` v/] :D"[@M)ࣗ6`SHvWHbJ%iGh<%pO `suF&CX;䪲qpþ\V 3Up#L}\M:܇ail)/|!uC#\gv;_bI@.M#6kY7| 85ntfV&LNwdd@CP9]KJ3ٍqz!paщ Q'TYv8m(SжM)S$|{I*xz0$_E nEjaliΙeFЦSh]Yx+H@8A@EvgaA~UwPDb*h aLe4_kKxpOhA{gP7&j$끳*(||1~NO2~1O,cVzG DѢ;\( fE1n QzB oV,;҄#ܪ]^A3}?-v4Q, ~Yek٥W5P{oE7³f]./MW&+ K0Z#5桹iPO4eC}>~rX 1r~7lŚ|zUGΉQ u+1ͬnfqlT"H[FAn0R.7gWtf&;a m v%"lAKVo ;ɹR*3Ѷ d$SB 8kJqC1gvL|~l]6Mٷv[K \r+22sJWfIuTQ Jp:*| *F8Pף;W>a 8ZgxcZJWI[69$lOHCcB5Og+C]:a< >BnE6_%@@SowW\!wGIykbNҬ,, Ĕ9՜t6A[wVPdt#=`gNF17;MDE0_ U̫+[rasn=&V "f*'i"`A)ڙVgda9xZԳ$j6[4BGӽgAzgu=Jq/ZBދ7ĽCp6YE9kJ!E-dVkPa'qY25ghlΧK<2H)ԲFձX\RSsP8Lf>!Y7EıSVB5+ᎌd |ג|ԎIMΈXbJl:)`3C㺲,:sp3_g^cb#~Ԝl\t|@ F5ˊ^'X N6 ^.Tb>zm? .@w&TZǕ@FbB& ^t>r5JiI?cN͗:)G6߰Ǫ wc zrܮTƣ?k r+z]b; pF[jji(ZTǝCbBq] IlfӝY7Khi@HK<۱' ftv/ %$czdE N+Q!auÞD 7K rP>Qu^xKZ~n_+ Ҹ*~՞yQ `9JWS˰,mg糂$P)ljU$k^R|Uyt%(F4%f[NmvAGɄR0fLSQV |$Uv$!f+*ƥ)RϚ/W}YOe-zzrXkW]TOq-3xwN>%$؇rO_x'fCg̑Vnscl{4j*-I8dr tu LGq-P:)5}j8a▹Iw9ͼ]1d{mXLtL#cr™J2kb',)=<0{z59Ssr?a;-qGpY١_Q CdEX;{pʮ*ֲU o^V#ǜia Un`8f.f7'㼥AW6mnȩ. GW'XKAlL-׹cl@FmŮǨDhH}N-;tjJ%K0Zbq)M_W˛Vd9v^lC\K2&J h{WM՟'^2i>a'{'GҦ;/e~!$l"nǮNj,xvZ56S bͿՂ7-ilHΔKl,V7}t 8㼘jBlöUҀW>F}Snlm6 slM\>6p%:C ϡFNURAᰠމږe +dw:[G/TO-;.֖Yg羪uɈ^Q|j_z70x5G'),PW6ѲJ} hJ?ZtU>.\qYS*V*:n=:-ZCnN*aklE Էn@(k(%(cJnX7k 8aI :(8-=JQDr$ )Eb~E 4dɔ7LE.dѬbr#n J#fVRpTs\z_~,&cڞxceJ= *{,m7X?eG@8Ikz!A~4!̃,œJH|?baߙvڋ**q- DMD>aQvٱ i;u b ;Ή<:g4/Ҙ>9~*ڤuRȴ>X%R BUGuLy/rg`\70- Y1ވEiV2^d RF)4X E'd!cHps478Z>`䤚(Ç@їe4!PKV}ϱ +n 7*[Q&n`[a<钚`rY؄죝#c3L }z9NICU>ڶӾx}ϒ=}\*:WmחG`ZJ0 bLc55ԜiϪn$%%n#b7GS,jQ(jr&pE%t[' o1|ph^oya=wN,N`ҁE"gX-HFo.vXNgW]Hty"sHOVP丹ٳ$F RWH'͸Xvq2?TZ\&@n -o>dѢ bX~J4yҁP5r®VI 'Eˇ,#L#K6s{,i踤S؃+:Ig؂ H9ӓQlb׀8h0۬P6-Ѵ+Sf(d|-*x\GXuÀ]5K[S21}" ݉ 4|e2ZK!'YJeiF}:1n.t,1ﳞ'p"Ex%I"+vBs"cÏ*y(Vhb8̛aUܡ} p#(5[W87Z|$}8HU"fTYag)n=TbHgX%E)s[g`16'q80CW9?Eqj ._?\8n\7O_b/U<@8:]}!ʹ!Bmb `/WoVyw?sZ`2?gݓF{8/È1F~&5]C/$}p'%2Ғe.&p_cC$Â|!ޭ^ o8e$<$>su#+Cm(N} 8, @uX/5|ht,f+GO <:T`$(~r:mGlĨh1|;6ѫC.%gh٭$) qkpt, %@[ )xpVNklkXﷂMr' 3a{O^ݜ"!D 3xI޽5`^5-f73gٴt`d2aB(z[AfA)ޑFQ=[ PC c-#أ8VT1Aʰ{VirHɾt%0ꓥah<7h&=H[yTVc8qޛW4/&>JXV3QmeJ+{ %mRhоaӶI~3u5 ِM*n|h1tg#/=]6tC#<>71ENU%kGW bi#"{N0 -xJ1^&L`lk>F%PN$5ض^Ū lFt*$: <ؓ{c0F2гaP)uYO5 ZxMAC ʨg/Gԏ`ᄃ YN:TZ ~"M;RU>1cj鍹@{.>.XP_ xSŊ]q)TR.$//)uP_%97 U?&#DйSrE,n*$ cdc/󕲁)ҷ]+~ y0*v %KEu65*Ɔc>v/LKEt&*LOo4yD_]'}:SM8;N\A.ՁgUWa:v)yaIT+rŃHh:yKh?,!Y>=29hƙB=Ա3WӳR(v/åH.CLڰפǍ?V1!}toKεa ʛ%,#O t9X6[Πi8[jّ б]VyNyj%zUZJG!f:m,-~TfȨbGg\rO E>ӚA~OH/OW(aFbڇCGZCF/u.gj8s#bprhz\_h0noLrݒ@?O/aqg.1 E|2eݤ z8kϿeFJIhE-e_'W#\8 }LhCw%ː0/D7>\ycK# Bja$UY̢X~E!昦M*@3tU74?C&:sjm-K\aW=ɐZ?XqZ&V\*Q.xTθ&6 zݞдm»SxEO;jeGߐH 9ZM(1̨ב3ƭC6f\@M5\2HՓ fi/3r2_ǎ*5.>2ݝ^0c~Ԯ*auqOu:s/Le\EzL`>f6~,e#sZSBF9iW5zI!F$A(\ƌ =Zh=LȊcȲ(v RQY屄%§=*CUnY2B鯼)Г_PpZC8'0WKi.C?ATxqw0g|0v)vCg bO´Z7AnFbnaeO BEN%J8!cFڒ.|] HJ5@dr6Zm_gVgމlA  T_"9a^.D?/R-uykRj No RxK#!z 5*:7u[ OE{q07t:n\?pa>p5TNqn".1ʍhA^PHb'ʚvax t8”\[@mdk?A: >aHGmPo_{TܙSKٞr p@8 7g]*b\r5 i CQ񅻘%5D2_$0<{7l CgkG CMR8=&,VRax 4j@6ԝЪHb7z/ 3$05N%W/ rO"H GjE8pexQJcG's= J*A޽z6c1l>Qd$ <<ܬjevb1tXl-!K(R=qPSf>%kZ uCTkg pP_!i`/W$;l E?kWiB b3cdzJld>Vc K)K!M* h_H4pC_c@2xZɅK>mδR>~֭&Je<,1.͕*mć9t_ Nӟu[j1"5~o\ԠPu'c9[5)Crexq@\b;C-G68Zq'iMdG|bTZI̴F i2&l1^t?[z(gQr֤^J6}K$Y7MOU /%1Q\g{|W\tb_eOl~0xW~zs l3>usm4X .醂J#EQW4B+D` 6JX 7E〓{Y*l7J=vHk #7F ;&j7f&{j=Fyȳf;*2imǛy{YV+݇҅/W6V'l̓s'@Uzu})YUznq1 S!]ӺZ|^ ]yϰD4a|e+§7ˀזܯ4H1+mWWOB#w<<z QH|`CNi*Y]JM˴Ej; n6w?͗M"3ٲZq-rSGcv|V|{*=G.bx5E ɟtA65 L+&>LAC.B-1jMqYJtzSfO{Iaqbm1H5;5HM?"0V$y Iq73/3 NG9:?w{;9,>՚N#fˁ's .A/j*A'@x@Z$2!0RNdN:vs?$aw. f#$yLTϚI 2P/Fy>'f3|r%@2+bA9t~~)&;{-~놙FSѰ[/ z@鄮هP$z P,S*IDm@3q `5BX:w`X,}w}f<{T߅5 /5{\2^-ܧH|ORF-=5<2Ѝ@oxX~$)I(m8SP,ulL?ܜ`Kc=adu0Y  rs`4œOEBnE;.H۞AŶpJDҰ*Ce2vy{u[ FB/QпplSvſ7) mIR& h2pwe,)0ȭܼJ?_(ю*b0@7MyF] OJ&ZHX π(ɷf2C:ѹn0܇'#<{6p!NNJS&d.@wҡ5wʪﮅ=w]UH=v2PϾ61WA" Yĉk݀R0εW{A>?HD(7pSz}.$7M=`NriiY!dƉͧbSN}|sZe1{ dNB߽Gɟ tEk(xrAdN4:Uz#,6a9Kf;C]R\)n M_`S^ (4 ))< ̙l2n(%Yˣ`W>;7čLE SWsbfۺtN7j@EwlЩĭNL]HĠP l󖃁j4ka<1&nw]C@=IvO} =Ōq&psͷ^`Yո.Ug;"bNJ <7 ލM0M>8i%@LU(Y1BA$^w} D US '(6+l(@v @SRzHENْ ok i)Dۏ36R!o=n8ge+ ~x-\19 }%V- V{wtĴvPE͋=a**U6Yc4%VɭnM!&$GG endstream endobj 425 0 obj << /Length1 725 /Length2 11984 /Length3 0 /Length 12550 /Filter /FlateDecode >> stream xmyctfͶulv'v:mm۶ձmv۶m}{ϹgaQsZ?jW:xb**ĽFz822aG34(L̀&823ҘA#@*Bo2p6L-ayMI9q*@h t4(Y[d,N@*#`lgkb/NN&` ttK +"(&/fPښd$:;qE--Z:c11L,F@3 [8&ikj`'lb_BN(jH0EX[v6.@G /-F5!lW A[1pp(X8OXM,\l)ﮚZ{ϊ[z Z 4EmL,l4t4oiC&?\3Qe -ڌ}t%$dE cag028|]cGGE4[Y3 Lk --4PYd]F47߿UwC 0>ߒm&1"G.>0xURw cc,qq㜱@=Κ{Z#Pʇ*mPGX}^ɽ$}1<~j<Y. Ggv KYfxRoUwװe7$.fN1_=FKHNجkltàӪN$:@z}'aFqgFL`ϧE^!e36]uZt9ZW%]8IӒ;kQOyhj 1|-='B?Q×S7Pȅ$P/VS.XtZԉpH_La4*rZ:ŽdҴ\3>DԞ_ex9 0^Xk ;cA4M<@ąD"&=_{.J6 sAIpڰ!llZ oD12!.b֧:dy)"g:@5(^Kx b'|h^9Q!RYu=F"!RR)]I o~ݴkɺ9)4I}ƺ+ X [Ng"G `3ZɖG;,y{ u\C\4$qW&wKԨuFT(B,s#3QߊECKr&Qd;Vk[&̾{).%@~cs0|ep ?svzgtij&c՗x٫RD4C,z"Jڼcy+2NjO ~w?3FuYpMF.ӛKI~rͫU*o-^שׂ&%zW471فa[Ɛ!Nuh{=C%]rڡWu-^/_ ruslװA.]тi{Yn0J>Hf`1R{Zɖn8!].L=*"9;ai(d܏;x#г MwM?Qv'AAcS(2_c3,72n Id$2N쳁)g*pm@cP{i1%,b|es;1DuPFQ6,iC8\ؠ}MzpٷHlFs6675jآ_H)8 XͲx$c H/<~c8Œj>TP q.i4( UiX7}­*;VѭmV` e9K9KEsBBU+]R'M{+giS9MO=z鸚1lFAa%cc1B79\lDفޟiI:轾nnDg1Ąƒ"|aM/QURj` kIe8{]L:jYbh$W&>JJxD&CfW*HQ8?Dkhϳ `_YH|w J:OTwzٳL8 "0ئqzA' nᆖnu/x;cWSsDLJwERn(֩D@~ m9uPaΝC;@98[wO| ԄمH*^:wL*JU+4hŊ}߆0m j[؝qJ(iGR+a 3.YWJrl"E``^̃؁OC?TLٺ:!\BO &m l]򂠷aS1QcMB'8*V$afXg'le\'B#]i`(|q]o1JvI2]L4M?nl8MP #\`!f\d/;~x j"ss*,DGЕ6'[hEqhy _ka9w}4 j" <ں]rZa<ٱw#N(J0zWŊ%mɫT8²~oWುrL !J 1Y䷻_S54W3sM0]eO(nuJxgt9/G3צ&MK/? fO08!om&у&L=B8ﻳ=|yBBMSMfmiVn?qmQuaFZ!'Xѭ9joFkkϑ̰zQE~97 fC< yUi.aUNT RQT7ɓ*4gv.2VjB1MBSBu,@ Yq`XQ4 JR;} G`بX ę|6Dy>?maӽӦiLw 7T_|ܙ.D oyH+1DigCh؄`YV8>t߃s12=ٚ-|bjlLgm#ϤPv ;Ӂ06inc%th|A |K텎2y)3QXϣHsNJ0U\V(oeIr#s?435#L=72!f$u>@YëX@gQ .{fu+5Th* N<A-kad=|-\ D?a]BVee73)^Msz zPk4M&߃%Dp( FdAT)%mFsg~6v lY\wlG!n}iqӝwda[6F>sC-L-PtP/z;Nvb7 ƛ?I(S (|6ˮo^NBSsbU#_}{H=wN:A=_AҪT/Ipln ٺ! +shEW@ {E_tɸs~3}hCF7󤢑=M֝a;fŢFm5AvZ>XiL>32R!g֕mę5' g3kgEFk `o 3[} jYTZCp Z:/{:&(Q_ꭊm}*W*dKvK[)T?~}F\b V׀,:Uo-ݠP#rV= iG-C*> 0Ɍr?˳Ԯ$$I1z OBX fC7ZQ]+mfKXO MFy(j,r63kO湻;"9ńH&)8vִQX(8`A+>1i\nbqYN9 ." ;? oP)fCZEpKwkI2z!bz,JJ;ӾVn+}5 L+ E.a892Zt6ڔ `R%rm!Iٹx~MB E5(_<5<7qV}m AlO1Y:gyN<4n~Xr8o\ôt2c3ƹHNoY5f+98 ("6< "{o K&ZmǑruHgSMV㗨g ֝Nٽg6CVԅatVG/DvUgXw !#[KMKu# Y.4V9sAm%qh[I޲s.ܧP$>)?{$YK:h﷐>.y,:fU1@+RQƏV=;Ll=3h#ԾBY+.M2rm=庽ȂX':j&KR#Q5TjC kQ1=ՙrqD۾_y h;"34?}9*3;,t i~+!`#F>?hWj*Q,n)y^rV8#C|~PP[K7BLkL`눉YrRK<1|J@U٪x.e$w[x?Eɽ/޵סUUۚ4 j UJI>vՄ8'Hg`54&f|4%̞LNs=jȰ֏!^ym< 27l|vu#7X⇾x騄(_7dfv< FOxHir&Q˞Y㮻bߠahC( SQ56o] ?ATaj辀 e"c^`1$E(šg,4bFs>_4zR::!2S |o+ȍ%h[4ęR%L̋|`ed֞@db|c"E7f6X77T0d3Ba*LHb]@Pr##־6eD6=( l:N[n?˔^Q9y9/cH_WmEᅤG-M0.N?&w3J2CceL0eICeBʯ.% >Z52a67M2,CQj#'VoƭڋY]nr<SEJg#X4UM}$Ys/(u4vGqֲ\V2! Ё_>ˮpy|!eaei! ¥5~YWʱ:QGF(h/AUz#Yf&2F$uޗE_ל|󃴵~cӾQTy~H}:^"$:K\*CL?̽c5NFd_YoQcߦ~߂+%7kn|1DqQje RQva,qȼx}m-Ck~E>R`J|;֘n`Ho+~2= f]^eQ1JA~o*OB8hHǞ2$1ON*|= &CPhlelތ!r_WjAqhgVs=+-J)4+ьOgOzX<F9%'(AQTs.Ӈab[$YKQS$kT >i|yˇ%PAqBm`m!H!{ jrZ8{eޢ4S,&o˗VR L0CHyV#b%:.B2ơ=H;@HG>]l H![0lWMsv-W I>뽆I3m,OMmzZw꾜s&}BU 7Xv7jM:R= 9ҿ@j|ءUzӐ'p?Ij0t%]J4y(L^-bK UN~@U Eqܓ[l&*$RТLދZx"Mrs*]~rfwY=~"|}XIc#xC\#ϙBxu.^Q'n q{C}AfZYu.՝a[,'J⎝k+rREͩR>J A$@Y`8> ` qhc#xHbTP 2Yt1XF\4_ZbxafjCDLͽpRDQs31؂5J [fScș13m6fw`GӅ$oͰ/+Nu׾'^;sP [td؆K`_|h -2~?҃͟ϼ ܆cËwI rnB|@j3q5 #Haљψ>d ɥ#bdz ~ё [6#X,뇯w f~f+b -/+7O={$b_ GJKԢt NxT~̑au52m:J?C<jk ^VޝU,Qk -˸w8ܧ["d{ať6v7~si?hZe ]0B^ ##k?#]yXKmĎwHH競E!"x0* )(E3e\)@i-ܦƛ3ƗYaoh0Z}YybHT(xʿXFUrM,2G=(DZ'+#+RRntd]:Jk)GLlmk-La~zh=Yv\?W,OKK+6;ӠIr%UQ2N9$ ;Mar]JgjX4~)wI3E,?{i܏%EW5ib bLõKr;m9t:P8V4m̃*pyEX~)o)P\b7,3Iqȫj5Ws ʵ˔c[r L P 6dpnBG0jElxu_MV袄ntCl2uӹRkhJ_σr,\9ᬕ;Eڥ%k=%Lh3z+3EEf̏W[F|WZ0mZ\;#37]Rּv"Wyݡ^'emOX#p|JNroCMG)3)·ERȊe1}|ꀷ啗s>GU>!g©Nwڒ^zM  UWky2cL;0h|3> _0e;8*AxNARQ mK2iG5M ]41Ch0L3HN"֊8i˃e @`dok#T8̫aފ9KLZ445:}/L !Q+߯B"ϸR!`v c#;9Xi<-ԼE=0WXZCW# Ǵ?)O?ϾSd,hc=z6v^~.67'o> J: ݕ1cߞ7a/nr4.8.VPAƛjx+ G2/nrV#1&'Wo u \ ʘ4HէAd ΟlT엕P-hϵiM]}D=)=OH-{u"jfs>1U^l'ė2 3b";YYz2^; q;׳`(h4+VxM^£=*ɪlhq)g4 jz3F $${a,wcr&a&tz=5M4Kg;D-9tǯ05AK*?ihNs4^yl X3nXڙx cwAK|f0$'+6 {}!"*ӫOGCI˵LyaáGDK73n!ëٹ/_04,'@C/d8-sZ~^Vfk#dvNTd~+γ|uwF/=Z_]gKťA&=x~_[4b=[v): :m RPE1w5CtG]Px l5ut:[]" =yai5@DZK gR &f,|)~yCdWm'SwI'8wI f5J0}rPX |< ѢVa{P_" )AWAE~> stream xuSu\[EI)Nf`%DB ArnQ{ι9{'^偖QÐ|<@1c S~q܀B,,P_ !X"p%׵u["@P ("&w GPG'@ Jvu:NNP3 o:wU "z 889FDEE ԟ @XonӯJ7)!0i_Z֖O_mH'1^^'kK b y9n} ;JK3y( Oapw׿`k(HVNz0+DYo 1 gl. [¬|NkKrrtW%s~Cث["P }n. s@ahhrsde7) EnrQTHO~ZwJe5 87:9rMos3 C[(q͏Z?jPpup rnp~)`W#_3)>@H )O֝5qhw48D)w4|pFzv/TZjNT jɊH-F:eFB{ Zb-gMͷZr"2x zP'SSRsѦfu6 Lp,6A#< 3]pOjƛ&6fQ]䍵cTf}ڛU1M0 n:۲ScDeKVYAKbӯ}57gBuz,_ 7αVR׀UAçZe#PutW5&v|ؑ kG>ζ)P¤Y~09>!5w穧 QT֕a<=Eww>HE򤿨NZ ^Ҙ)jDa|SB=nC^P:X*,KK$Ad@GC+EǏJcjvIcZ ř$c{_L򚍂 ̫əlY<)mOC >(jH)8;K3O[<$glD1Jj;k"3ڿOy>ՓTW |#zդr8+i?\1dGKKlyf޽iӐAo-:31KJvir|3-B6GR1>ߝpҿM EB4mx0ҷOZ,Ib]Hsn}$0/H7.A|5z"8T:8S5R![QfƄh%Pv1q8bԈ`WNF'JY^'Jˡe4MaYd2p?\I e廙3϶|J|zԷNXO5g6W[$)瑨$ב`,90@O z8JrMv%cZ yiWN JE2Ӷd@j)OO꒛E%??@` aX 9kC.9Q@H`d%q3&spC%YpKa*d2bƮ0`u-َ{YB<;bs =äSBU>PxvɏC*GF"U{e^ٺojJ.^!z貒\^ϻt*[(O$ 񓌇=(}"TVؓoqT0grF$f@u!!i):ְW#Ԋ9x|v&6>>-y"5BC&Nx[DUcXG !Mj_X^UE=\K&:n\h ׵wfL!5grDl !PGЁU[]O1S^ t+Afwb-(S}09S(ҍ ]1IA7(w`QhL ҏf -5Cńpƙ[[Îef _Q< ֘M*䜸j'Ŗ䇫!o}%W[,t|j9}DS*$&mcv~Q>zog/5{8}s$Kd\?>J:d(ٚx_BoWc2iVp@xmP?˕D0i~J/->1Tݶ~|joN3T.uzO59OFp&Zg:8HFCSj?p{:0d[_VXskDag쮍IQs~A9DoQtV5j)4v}I?xk.Dw9XSeI:v/L'$VkhOuD͈4J2WM2A #R?c+jq$h1l=W|ZYxvy6޾wX'j.Ijmz=2I+OQ_& kR7D:fwInjng5Ox8 4*0Sh)LĨ[lUL*s!ꌢ>\qz-@ݹ>H]@`Mp<~|OW'=1y6"؝餐.ty=m*`q/w^i]Șxy_B[H1|<0a~+K<ElmMv1_4VpwNDᱡv:FIM+"J TgI5j]S'&5ADޞnF Spnۍ횚yTwmԄ%ZV-:\_Z}Nyb<ҩzT>|?^O"R<%p=y#>wIW t܌-H 9BـW7C6tᆰΠw[MNj~bH]j'wJ1Mj2-l}ޘ&`HPk9aM?HTtb0S $srs]'>H? RpYW@^ړAr'dDR<ِwu ORkkrBc- ۣ*p=Sվ,APҵIv~cK(O/G]eVVKm#F5z&vE39Go 1VI: endstream endobj 429 0 obj << /Length1 1606 /Length2 975 /Length3 0 /Length 1772 /Filter /FlateDecode >> stream xڭTkXWA6K.ZD@  D6v9!DҪmieYiնh/BkW *jx*H"k+= ZZv#仜{=R &2 Kd@-`4qڤO2ɦ|}gpHRu X B f0#3t7w>P3Za)QbH7(A z3!9%qF!"qDa2 34AI ,It qCAy<0Z@8e _@XAzC`*x#Y~yE1F<QJ yL6c9At $y ltcY88~@ <<D" IW 2@.Yl z!`hIUϡʼn$}!9?1 20zi3(*#i = Ń$ez\a0np8APtL"w|,ipb?& G4D:fATgI:B&w4qϊБB: &zlհ(dSeb2Z' }䲜Ŕ$gcG,;2f&3jO a&) [5ft!ǾS"% zyD .E@{f;B#E nO˄=>k<i4VԤn-ϯbyIj-t&w=qRz/ϼC/]XؾR½s~avWsR[O͙hۓac-u9>K4}{:yrs:9q{c7o6*w%mvpX̦ܠ,xHW5"q~KW/7Pn!ND;Gw.тH"rܻ&9kG#^brOVh(2CYFRٞ`/<ݮ!yn\ ǖK [Ǻ O[ּ*[`G,BwIWuLp=ɬ\sGoX6V.s~m.mb[ZX,W{=V4ůQߜ]\k_-_N~d҂YT~{yBg:QWyymSw];Q~dSnOAvvklĽ|~ˏDx-#S)nv&Wrhg/z/,&;"`j VoX>tN=8<xxlŞމܿ'ṃO"K.)mjM%Q_e]b9^E d᪝9䉕9`b>WWJ0IAg>uIBvˊ]>ʳ[ 8|pZF8fݥ4=<̣. .ֻZeGKN m_ʦ] yZIm郵|/mpc͗m܉[,gwU:E-u{h*ݷDGKE _Z1U< j1+:U+\_^mi"w3-^cE-,Xm]0"vnIA |c endstream endobj 431 0 obj << /Length1 1626 /Length2 15124 /Length3 0 /Length 15973 /Filter /FlateDecode >> stream xڭct&vvŶmm'6*F۬b۶sNw=a[||Z* Pޕ`eg`-G/4Ñ:]Ō]<M@ h `a0sssÑD,,]T*Դte'`?=3],?܁v@{׿׉@ 0D$T I=fbke 2ڻfVK` pqZMzqvV..V. gc{׿3puXٛںC_FSrpqu1urt$&oƮv84s0u[ٻ\2̬\m l/n.Vŀ 0v6tOֽ׿8XmY4u[]7w03n?}@ ꟝K `4cTpp[@2 "?qS -fk`lw>2 @CfJ1JhMي8ؚOH-o'L`nlw^ۛmuHLLS2GfIT"Ϩ /!Jx\w \ռr;?0""zf.=+߻7俀,ol 7:?kjlow_uv?y h `bZ?<) >X֨(֡' #bg(ï)6SǏ}^,[ʞ4e!)u_E'AAbfռΤA;T3u {Q ٣#izC@>1pA&亜v#L m='6$2甄خb1$ؐ}rmIji3^=nUztqB4NfZ'۪I#fA? f'rb@qaE9G5> M*Pk*KcY@Qn/CGUmtP mP]䏯~f~FwS|L_閮2Seˁמ'h&+JM?=%@byH-,i1, @ Hy.,| 8+Q_86.*InK$Q9"f1u0J0DeWXa^^֙lܹ9NԿ0hY>& #"LRohk/`s/Kr㭻 K/8w&"&k慑d",3-קLܒ78ph +hz\ХtW_f vEcHMk'X 2rѸST`N6Ki;O$csSsW V3j~ck9Fs3o|5D'+ s[L]O8+2#W S.#)*L 5<-K p0NjOt#L,%i`G %,)Rǔ\g8(&c;n-smG$mo/Ɇ #cyF͕}=J9]-]= JsCJ=gg/`XLzTbQ EMo.㘄jnaNWb~.*&2s[9INM:|G>>;t/zO@nONM9&Լ:M7XOP fF. 3)k6.{*%xK;G) !@[B^ZI>4g (xn-r!'ox'ISNckLH$"O yF~xIRI Nĥe}ߔI;E%<cL}hԨ;^mȈbjx"z9t7o/D/tb\ѤaيҾψwc>,vuMl!L 6,e6# Gۂzͯt#yq|HX + oR6|z Y}Xp1\nD5bu&vhhd/Cld! )xמ zu?gg-鄊oBkҴGemٰpfa)lvsHi)bCg:ooU5 ux#y充Ɵ[Ưk^[/sM#ؔA["vɥBS> a2"xcIi ߗ_{I;*$2hMȠ x'y[ر P/F|FybPifmcqroz:FY,=g"NKv5P;(U\ Un8/Q-kVg^CI)J$LQop; 8%9T58Az-ȸY \zFjMaSw^"R^l0QR,jbQ=j XE(w)^/D)(iKDAٜ2C N)`F3nзmPT͛پ]cBYy%}\z|ws)HpqT-'k{L'."p ߟ4;di꬯8_rhH_?.Awf!T`Y~h H8r?leևôVq ^*efDJc CpC"шcpg,<=4q[c+ 0T2L@w?Oi2Kf=3?зYwW}8&j8u.0e3IV'^ZPp@~\=WP91_q3b2hഛ>wt򻾻A?t4Q'+qD9UGf VxfZLIK5rid=6 ϗe唭GNU\;Y"董z15Rb0\)7)T :ð<׌!y^gގ-^܁$`tYCF-;$),vհUZǵI,1~q,$KRhqQ7ҰΦ|9n}6R]~c# ?ڇӇxJIMf\(^j 6"xC蹿{s_';)EA@u!JLN=A ]m{v+op#9]5KA=/w($W4s  e4ݼ:}>*1g'_C:|m BT@8rfhޯsc4?ڲt$?l7$Vf:Vm!28[j(燗ǃo~~U4|^-CNqtvgJv$e5Oi6 U_[zlQX'chnL77իpiGBeJHYPs!eL}(Ȇ7ћ~+H5UQv#p|E/[>֙-!ϕ+QRGY($9½m( Lw^(iS0:;\6 ym ,"őIw".MmhA̮׎9>T)W*Y*%G}G|/C*'GuixV6܍c={(;uO/K4&OTY?(r^뎾yr(stIZ{IrdމX뭺+*i?å^b ւk2\V9S3)?G,vzlNuzNLRDE^pnDKT68PbJ,DECLBۇ|}mᷩD^p]2=Cw $ickKnpeBUa3HcFTxٜS l]Cu8֦o,JrPїz՜hv/<jQ#0w?{OQw7g$UүIOYfLJlRcFYNbֳs܈H]{gtFIΌU@y/V$R6ZH(NSwv<tqU*ƲwHU6to\K4ch҄~>ACL)mХ<;ޑ2☗B"L Q=S%U\%@tGG-~ZZ؉/!)ۏ@7Gw\nw> Qr+5s6]23+<;ZܣXP59]éNG8XAC)NzSݜސI&+vԉQ_h& dGXÿCJ0uMnOʍjvq) d22 8ui_~ :OȮPQ:9AN.҃B2TeGaTE쾅;D*?KvS|X $;gn|(A 詣)c;LBnՑW-xv*jC"qL=-A̅a0Fj>:{Ql~T6f?留uΖ1eV΍?ǫFJMHPS2'J#gyJl}He=CXX6R +fB)Sk0#7̥UrͦӸrEnmWY$thR^bMv{ZTBEh") Zg~z՝Mm)Lj L27 .n۔jQCI.)UCjqmK+veO82*p#$FS ęV&DNH3N]q΅:ʵnA5"kG[zW D=O[_TNr{31t6rݽAODƬd%IЈ xji2tOҶM7P>:|PM`j\vR~kGeptzbX[ĻCd{g~L}A _!CzS dw`{vB.xY^-`~2l Ǘm\Tg;ԙo߹$idC">"#^]W%*|m򍾞GX KcIF9z4!zf84NB `Oň"KN%ةeü[w\Qlu'V(w.gMDTһu!Ad4S4lE>5EcϠp:!dyVp{~0gh N*$IC ' RU|U dPՀyWQ z&&Z9 wVgQ C&*?LٞV µW9X_~X"6/iP #Tqu B1]}'C^d2Cʷ~>~y* VH2>܆{V`bG*k@~*L'P'uou `WQuK& *{tdnPYpc/ U:+1~rQzX?; MaW&Jl#XE#*׹th&`AL:,X#̗ Y(e' Nw_gjv6Nf/d1b#i6$,ML zOb d.6n9وÀzғf}θƋ(7\鮥E luv6w@b[O1NBVZ.h%b9*ui<_Kj^^ޟ"Oz%Aw6›8yxws;%~DP;Ҟ t*d}xRedȮ%;wDgrzU7 /7HHј#٠tZY4O(gbqN+3Unn'u*dT[nX4?8?2V1ιt?{G Y}x_\+1\XEx{!fnli|[Њ_@4OI Yc'cLN;"%1,DϦrQ0H%mMlf1o`z0 ~dj JVNdz~:fзuPnH ݷ?? GUHSҘ~{oY.)1WHds߸& ! FpLkf JER&^ $n%,G݆ߩ)· "\ Dx_!d jb3:WU_ѐMdfi zQW1V8m6h߀pzl\5VTA/ C PNk\Tq6Wn1:_Eǹ#k 3rAp8X(x)[Ed6tvp%>EIyKZS1z̳Ϩ;LO# B$VH(N7LᛚZm˔{[qN5!i 7FhBkoڢP|7QK9MLq"⌵|~k؉ٹ:'&,9] W-'֡j), 5=(1uNb\qm-E)oz(\&$ vc:R/iÈ>OLON`j tw23悚'1uo9#WEJj(v 'Pԍ=(#Z%irG& ) +DV߫]qHYg˯wj e) !ìJZ]EZ7&uXaUi]Nܵ'zf Ӑ~]Sl0EWz)0Th]SɮQij}ALg`Oz= ePUV/_4J>{&ۛEUv_8PC3"HcjG֋ eM&Ncs67aПl]L"rp#ke(ݹ&&rԷ HRgk PXWA [fU Mea/0{&T ( وi@ﮈ>P#? ?fY_Wct}pܯI۪K;yCr^~Kg߼&P{zES,2I  C2em5vϬK-T' !7*2veBMT}ftAjC߳U wjY/([KŶA>qW|{۶|,jBxJQpɫ#Tex Y>dGx)^iq4 %H­#rz&'fuAY 9v5Y΍z\M%i厶aӄ2*ߕNTSaQ&_I(GR;Wy:&D'Zk:kwZ 2R(6뵞H8U/P)D N[ɩvmlG>5m6FeYY.O^27X$ m-;t} Mӯ%ZW9ЧVwz6O4h)xl;rxmΎWveG“}Ó͌5lY¨اy/*k> &G2\bTוvh'ΛgG_լNn{^ҷJ9&ޝjW0$H2f6'X ޓHRr‚v:tV\1P(%!zc8 oˉRL6g09r^8{"ϺO| Sb1i8Ӳ%ӎ_b3Hkm}b C+"l5' /'R@tH&J/Vʝ|w>y@z}ozRb{GloVf eOA+xAX:4}~6Y fVVY,:dŇ9oC2l:C~'mat>_>=ٙr%dFj(v>ѳ:d @BX?A[0GTr=s@* QX]3dj2lˢxӊ>7pI }l?$p.ۜ|&\*6/'2t+Fb@4&qZk7"Q33*;LDF"0~ )+9Cޯӽ^]6QpmrUl)af̞Ojۥɍ^plnJ" K7V;_0ٱKqrOyHP}ia)C6YȆn"S@>Q^{vwFMG)} MscRG6ޤfxeՁ~ݥ9خf}_>s(GВ<^Hdxu1s3_c8t[ X(OU[q\.Z{TTVS ձltr&4-zzkWv/5 +.wEYQH޲>/ّlt0zs#Жd?Jqq'ݣx0^9*Gi|BSLhmd4'hgWp vGjwXׁ\OU @7HyGhPA-|b1qS{z)~hnn<ފXQHe%,;i`H7${Lm#󆇕0ber|lSگ\^9^@O ,I"\9cNZtV ju6y늫U̾+X:<xcDF<_cF?*|ݓ&W:92e ?! |@7?kA.Ec\` ʼNw<d[wܒȀ]=0-77u?bWy&/,+kUmP))03w_Vht8vw3ɡ'uueyEVײ4K:_Ҩ (C-tv(W-Y񞜠( ٭+%}f,(lDV쐶QT+>ƒQ|HmkPiA^ԡpQ(*@P^#?O$,<r` 2ى/@IAaxz3b\Q)CuJM&{J2 cw9!A1M}U`FpeAK_xN7W '>{ ^^pc[=X^\B`ZBm͆ _'0UCëeMY*- v/Ao<̕j`LÖ .mlz3"|eWd4ǰƂ>ƌfUd8RxYu3CM;nÂG)d1ƯwٍSa>м8utNpn|) ״⫈a"l%0"<ݘO79:*wƖZQ41X.]$UX!fP> 9L6r;t:.YAÿiHh ΃|$nv j^Fk*Y nr4F̱+PܦK"H $ +Y@VFЩZR"WoH^Q300G#U(K#m^;i *M @ \!c*aDtbǍj!h^n:@U SW1>.&G=HO{V'*8,%j!v^ LjXNZur6Y>*SP3)I(7lMm@1ք yJׂIo/sN8g3b+ 5-s.D%1bl2L*K uGRͫѮ.|6Kz`vHHڲ - [6$;:M>X3Y .C}YsSe{iTV2}nɖj2/7k ^O~ֽF i.xEig(ɥ-dȕٷ1,L~,em^ 3vL6_D'y?c2Q0 t6B0\ ?V2E89`,[72%`i'D"^ TbYsaTֻR]h)t)xz˖Rʌi;8SCP/?_%Nx \',?|XiY <4͈ead9+0X+7.ROq4J!Dm.#'e8Šrv!h5V2cc90'|[/񽮵w ra!l^%Cq(0JtP|Ӽ!wgk.1D =r!as.qz MI +PJK~,si-K,ip'ɗ?)!ptu麟 ^ux>ɥ1g9ʲɐJ.g1N ]bS~*g_|=-AͽqoqTα"U~9Ƌ%kԺlnLC|5Ӌק-MK:՜̃o=+4?XXV-+ Z7eK%MĪҢHmLp/3}1Y Cl((bIGϨHBhNVѸ&m#ު+*yO5'0NZ`36 DdURl48`g#n"uAt+,/KkW)Cm)·gC|+)DX|-fz[&3in`4qr#HD۫mz Xϑ߷Q=A׳WPkyK-ΐ%`ByEi,ݲ^Ά="=5[nrz[I+d0ZE"eQC*1 &%H#\Sw ti2m[Z󧤕%"=TH1wZчz@D|vrÂZ\kb3w^^acIEF ?Q9K< FoҘz nD endstream endobj 433 0 obj << /Length1 1630 /Length2 18197 /Length3 0 /Length 19026 /Filter /FlateDecode >> stream xڬctem&msIŶm;ٱmm۶mWXӧt{uO\׼Xcmrbe:!8Ι gikr)`EM -vΦuS1K{8Z[8TԩihhS ?4=,\Mmv!MM3KSJBN ajghhPp14Z9R̀@;Js%08ٛ[u3u76GE 7utr t;93`iglbOf%dkaWLdhi UATy:[:4ki4v:Z9Mݝed 0t1/pq3 h憎&6NNabӝTohoo/o࿬gN6fLc;mniϬHٙL_ gf&ah2P߱LG-FB%chg_MLo[RHoo%W31u3 cbd/: KckH`V #+ IY2T;*s?0@w;'3&俀nFU?~y/0bv@FGO?jcGǿ$k?{SSwScصe1OUjFs-Vv/p}IJa5/5|&qc@h/ eOe)u_>Ea ^ Bڙzբ;IE%wHG'jR|tG{D__qȍ gI)Fzn h`y |O:{87Br8U.eW$y-=1] }g\6q e.L%Q֫\:[e_?NX劵;jZH%-dDQ\ M0TcDNST` G+[(FهJ%u.Ln.-ށQPP*Y#ԫRk/.hV#pU@jSlJ>9+Nm#wT]^KvWw[ ‚qLohaM RX\_dEFZ?:x)={?y2W{y)ֈ CcmN5`<ZQfybqFdߧ6D@@VmGQxf,Taw.}6y%Ҝ+ұoHߜqH(45&PO2ߥ$Wb(84%W驒0!/bE -qsRC~tuGgzW`Q4sk " ]?WADX~3QS5ɕ[oxL˭z=dcqҷsd-qagEXh{/O̎ ۘnl^Q^Yj֢\Bzo'=f9ĄlSofaj[?hKVt"x7KM=6; [A=tP'֛İ道^DhD&~Q6;4uNam"Y'zC5M,`5^ Ol:X>,jl- MR!`fd?uir/gRZVci97ˮ) X쓚WPq4,,k cvG+KOxo'r(#4iC( %O܌MhUG*In%ZU:W?B!C}=bl*ś"YŖSGܻz]8.ʐxϥx4*rG?`8wV\k ]%#Z@On-*\c1OA&Uy*vap/NYTF [4p+$ke6-hH$TuK["e̱]43{" I|CjAg:3lޤYsNq Focfj40Y>x}G_,NΑ5krl\/ n*G2[$WXqQXd'H.Iع'& `nشLFQmΓĎԕ/~Iv.\f^^81%U5{&Ȝu 8p"B<~pI( /%Pk#^eɄ80_T,]\83k08f.RdhD^hE m#:iT~agMeX;5q.8Mt? 1+"[kpLX01nv#ZpQx/LBvbp NVc, n3/*-˦f Qdw>Y`^VFnж۝ӌidi E \]>)I-"q8(:ԟ'm[>(YQ ._I'd1[!M~{}vى~J`.?+D̽H0ڦ-5x/TϧrKa=yA?v:;IVMs>3]˲ _50z~U.}OQ+qrNԬC.QV7 Q.j+Cj mⰝ V48ti),zt?joWKj*b[ݤ>[>ui|o?mPdhIs#P@}zL@ÆxR(⼖m'2U@isQ%q#D x#F9QkF-WIHK2+6CKQħN%Kj<ۖu o- j-ƃ.ibSsZmpxNXT㬗-ʝK?Sf~\oj4" *1VqܸSDcV%Kȼ]äMx?YiCҏMk fpT}.ZH#8<$K&oB. a%]jp:?\=d~xe ݺ3=sYHR{ӂc -4\bvfP!̩Vɝqx,֊T^ZYLJ$4+ʝO%+xCFy{FD@d"qg~OYH8w|oyz#~x҅dHCn-0ȹJ7a|$,S^<^;i+7OwSeVU %(E15HՊ $Mk~\s3ҹީgUޤ1+|Z}J5Ka^vI%2PjF  ԭl*u`X.Pxym,'ÜbWn0"3٭xeS;঍4"C:C Ɇnfa,ef./ȸk̑]̰M.u/ioQ[ks 2 [N%"A3O9XϊΈ.LuJ0O#Uq^:xkry#6{sr|p6:rlffNX(oL[ \ߪۦ8vp!^Uh6 eI'(ugYms fmM=ʑZop}O. %h]*E*mD-;ff](ѡdlqI:K]v L9 +"!5d=M b3D5*jݙ(=ik ;p6Wǭ-KT1-ڇPj[*.~k>>>۰!z32i{* 5I69žXK JmS3X˳`+!-Fk02iVUTJ{y{'n9߬=̯PXk(G#'U%+V"w`J)S+Lx\LԢڈld8<^G"Ip G5Gvpە_R)Т%nmӂPf_Au772D='V$' }oa*eloCnwm}kdEjߛyY ;)x^d!~s䥅Dwu5MxI92 CK|7/aN5]%v@E<Oac=?rEjK٘(ڽ|oQЋmxO#t4r``£ Mf/m>@Y ^XwA.t:L+q9, Fxع&$gxJKS_r@E cJTzmeG3$w!'TLj[GN]yhaIy<s3kvU<ݓcMw1١TS} g⧺a3 -S%Y@.(iz7ώ#SrI2޷$.7KP/H]Iܘt:z a ^5iWpA06n )m jeTRP^7<,dJKS  +w$t|OD?n x<2Ak߱jq%piz!9x=Y5(?ndQZsL4(1Dٕ7:g$RضxIdkGzWhsE/yo^n{&Q ~PӀ{]{ӚnRFnS5a9_V才Y2CsK|ܜ[xh-RUe\T ~)#~EK%Yf»|dFSC(%Kl;vU3FȥZHD9:d; *X_4.RK Z3@ 4 kM6'?~n{y[7bho slOW*^o="jI#AdT,*7䌒H?կ0/ưmnjk'EJu ѬG@Qo\ -. ''g{ Q¾qh!B6^$֥s-=ȂHׅS;$IMK19I?Y]~h|_'=u3*Z2v/jH{ڸI~̩Bx;|JـEz ? ?J+j,#tHgzHԱfU[W -qK Ž9v17%&t=9+5=K>K,zYKim}ov]tΦxXsIS@C Mjѧ xnFB_"CesNDZm}4]S (GfA2~8Tb\:(zG!,vc?n28"$ P`f?ŜP*2xbVFReN'@#-W[ꂄsv)H SmV[[mjp*զC; 5Om#MLQcݻ :µֳ!M۴-H$$;`\ÉɠW* /T3af∸T?` 7Φmdk!Σ`Niݗh6lȫ5.Hŷ'sl@ḃGgdń)",L$| h'FjÎ*zj圖ߦ)_x,QXlL(A~HOf3KP YP5AE-C($6b%A'`0wpw/ |G䒳|wsHCedI3e8Q\+$B (x2,5b;5cl?_ 3iۗ(ne.1N`d= eA}"(lŁM|j%rxMxIk>U6;ǻI`! l𨡒m*?Vwna\Uy}~C]D\&K ؽar$,]]M^:93,i DtB.zfn)-'B 働>E=1js;fQ+SءnÄ&WR7|ED?Л\L+,CU1cd&{’ pcQXr /p1 ^ *:4MOYejPfWQ _I LJ VPSw<ψnI]ԼZk\w[5YZǤgcz`$Y9fgWL }.LEݖ y4 ~W=\mL)xb}|ODb6>Ѻ;rv8HLCR=th_GݤSHKw[dZ~2ҁC m`zeګxɉe;,]i9,{\ fGQjFa$a`gFSe`iۦ1Z_ULOxῘ4CfSV0Ogcse(|Y(7EMa TJ#/Z2G.>m/*Hɞ8Ьׇ{1`|&!PP> 1~ƛQNmA7})lI8" r(7s۽+_\[x!w`r9):~eÕBUY^unFeV̅"lϚuJ?D(ŤQt/yox*ȕ4w3P,hgHRU:>_ZƊPPd9UY *dIem=#BBO[P{4̨/t\?;ϓ:'(霞2;ٻ3%sxQ_`j0} SZS3vdl.*ܲGr{(U3Qz$.kNp]Ԗ'!sf>a0y`L!k8j ယ";xiųҒ)h*7jO"TS1b143gĻS uu܃qtR\J :(|o[S_1ƻK'E͖&47!;uB \N%qMHF\gT-]mNp?]Ds*% "-CEvM{]c~_MDiZ+jo0 ɱ3q8DD5b ؤ7-H|[a׮aYBb`^JPq*uѐIc Dkm #{H!>RD;sjΘDZǹBvs^A \xyǘOX[uTk<$!ܽ5 $v)q3d 6w0;:ZvIfDFK"h쨝xp.;UKzk$$4F?Cԃq{j慚-2"B6N҂3 0¬~3`K9 ;ތ){UMË|d+b,ldUq˖ʊQY ߘC4>4*TGp :6;^0l+=E(P-5J{ 5-zc«U"eٖA&:5\F_fK'qJf.O6QWhԳIHT];2kE6Lb6H0xJ)r7,%AH !; , / h\D݃"Ooi_㒥8KnWB $բTw`fgzAG0N0XPI$?U";V8ytođʩLUl*9a/ }M]_ðuz;KȘAT[yVt8߾ UD̮ϧ oՃ-zmj n\~d%ˆ"W?ʜ(g$H\Ϊd}Ixo 6T:Z9nd>Z.H8p z$d8:"E*_^+k'/붩ˎu1Uk,ezLNE\[iXn-΀+gAO {˴SjHHaqI ,)xq0kd0=tVV6&Y#,xsS6oJ , RR.fI4))iPhJNJ-t',P,pYo OƔ\wRB.h3Ƈ{yñ,·(Iv9 `\XkXs@>s:wY7ln˟PmO{1x[, 9SOUqb.ZɃÔ]#H6coo[pJPh'mԅüpsEib6%!- D8Aқ@D߾q):)tPָtȈ[wo ?vnK@O,;iF0;opzKUo_-"d NEW8zj\{@01=ٝd |â6ΟѦސeֻBWLOKmD6 c:Ҍ;L7CEФTj|>N|K4.Ir ,Vް5.sK5*^TkD[_(&YT}kI^B~X- $7>b/!QݬZ9Alp\Y4=Fbt8 ;ٿ>ji>BQxA?ٻ/^:TgJ>{̭+|oY#m1jOl8K4q%PjnRƛj}:uH?M**frGPEp:Az@Ü,$&v/W(TV+_JL~B@jөGas1 I:쏙JC 'N2R :4RC)qAk@ۆ<!t•vV[s\ |oKI{j?mOJ\HHXjQ>H)jjH4:0O.'=ZLXS@kAlP  yiWv+_Nk)s'X[?.%ȜW9 sBkU4Jd9{B,yaڳap] 5%ohrBfbp(^dq7 'H 0z}^<[/./r;oa̦j:@z(Z ?OxI-$7zPh2Qrμt%G{)8IkwGgC]T.~#!dI/L?ZK^X (\Rvl\uӏ V?ǝSԀ^a uRcד&!2NCZ=#.8G q1r֘Jɧr 6 .N.#+`)o~D{ƈQ؞!;{!o~"r Ϩ)g,p3u.p%x|'3Rc) H`WJU Oq lH.Ọ̇]/B՜B< )]:Iu6߃+WCG]Χ_0n_]@uH()EYóf2E~Bs#Bðx7.շka;ЦJ]/(Hi#vP E~.P!?,!$-|=`:Q/:[= sVW</'} D9Y@dd3B\rxA^o kȆ:Cz1v[Yt+[kQiQIES9ihk jV9 үHc` ~~ߣI~ŊyC#+f) mƒJ9ay \(bϠw"x^PLOxp6}UD[qEoM GhЅkdH}31q5R@MSm)uDy} 9 Yf]8=#)2 e1DV]:@)Q9)Y-KҬ6_עbG JmWua(aG[=~؎;ncr ~ _qF= Th4|$1vk9mKjXF Z 1.OG{<;: 6o͝_9Y{Oash&jqd&wr3;C" 4uN#bVh1l78I`PqЦfA |UG}]QF[VA\o߲HiўɞB'N}DZ FJ${@|~ws }]@d:X(KomqmE8= ЕT1{E"#HO*2%nOA`a$d\QiKX~B H(T]I ΁jAxl+G{]CMKk㖯8eOCW% ?v}>v-+ȗJP#'ܰ`r9Ʊ^׏說m)X]q?.(d琹]23jSq38pOQ5 #'4S$F(Yqcɀ>*;7 : OU pb#٨I{C>x7į*j}cyܱ03'k.ܴ2eSg ?R#V[M6`LX?RipXz{h$V뜨t(({EEim!%De7롣;dD՘/ʸHs8{Sz%)a~;5s6r&}H1Nρ  :7+E.wN~XCHHhn.T%Fe/ JW¸1jxSҤ1$C;iKPWdſtWMRkA2:v~QԵV:RV)GIBq=Hq:y* ͪuҢ`R%uMîx6yƱSUdn?/jq,LơSEBs!ޒ΋4g5Ϭ,Uؖx%Cf+kRa51Pi_,-r!+=jtBI7V+ 6=ۚu4\Ge$ 9?Fu/E rm%r4-uʪkP)S%F>/bW|0BԘ8f%o;ڳ}O:ꪵSST3y\4I YPu0{$:˓KoB7%h ]v8@5%I)F)o>N4Za^ҾBpFx>_S/*mkZRgڌ8+.7X$a|BRgnp z`Q9KFɅrz,uQ[.!D:18=5[Wx910-۝X2dީdCUBN<}Ř]O wR8AxJyM:nˇ "V-ݒt U3{E2>HԭY<%ެi#{m.~tdXcUM-)#b-)xi&@]`>Tk?39~/eE.׹Zkgd^vLGUsˢu~M*7\+AQ849@ ()iuEq}2L E4G/<9T*{NtYؚ8㋱Dmd_o6ZMڴ c_#`^K .nP\38}b6Rj_(oΰB{nr9ZCj&Tc"k *8꺶|Mo@h9;Ѳ\B:zkǭrA0.u*,. V܋z+BZNI7*tlD7;BY\B'ste5:4Oo]ŽDUcZq|nEGB~OSF'Lq*S]'lh3x_4}ڍX`U|CGjQ%&>wAT17`lXoJ]n2 3(̎[4V# \ťN+Vجr%}E&˱08h}}K-8谉Jz:dV#u:` $K5t/&mq.Tfĥ ̔!rɶ)d OXp"ťᶙa&R,  7PwU<ʢȷi'@aV-XXc9SRO@) OVmDg&K/8vyfvgJzY$G!FCvSqZYK2v]Ra{Ss0?j!O,kag ^-rB'V9iȧ̏Hߗ']Moe0^ILRXt d)Фع`\ƧR=RKAx-Ys:?3LbK㧲w*fX$@}7 OR6Q΋錷Oqf2Lx85VEScq endstream endobj 435 0 obj << /Length1 1644 /Length2 7926 /Length3 0 /Length 8780 /Filter /FlateDecode >> stream xڭwuX6"%)9HKHwt034 ))--% ]!();y{Žu]?F: mi0uDppsrl,\ZP5*h( "lr@D [XX #@ pFXtYis`ȣ'b9@kGm,m!Yu jE5]" hXۀ6 # :>@PG͟\pA@6nwb 6p ` tD<8]x[BJ }=i@8tc[+ظC65hط캎`#Q߿Z LdG!#_x^)i*aKCq̸vx  @8!8O𿈸y~D8۸8Ir;?:g?0Qcy@ ГY(H465# QC?"gō+)_K [.7lo P~Ԟ3rGCpMm3i1nڞ~WohF\z#ZEcmXG.`xvg5?v./?uwoPe`3|~%"<̝A׮&*]7OʛYZ5"^i\R1*nBqy %iduMkg_ ,Ie Gl5D*H)}aV"H4ԋ䫥d,K\*2mC`BIAr ?s㒒2 }yyU-]%yTlԶbS21M#wJ+ "syJ2m4*;-i>ӠRQoD["Z-ח/hEu_CqĎZ9efLrFgDQ w&WIݼ!Pp;辚gʃfw mFƖuPb,ToG1eoPPݖs[`Lޮ39$?:hf] ' M`iqW̥X /*jd4d"QFeRWw La(DQ?RTśRL_nTW%W@Zb^ #pusF|>3 %}Pz8 2X,8 8Wm"^#JnϑnnCʷ)qd%mˆ-Y$zXڝ'(QN<6{W5eֻ9F_ZXeӻRMM8I8{E`neUyݣ=A+rw5*?G귧/*n>ѕkgM_}BUHŊxElkLe神:5q/=X+ld@G*ytD?/I]\)e4R"RvyIԩ bxN1;Qo QeF5zQE9.@Jg‰?2qzł]ң T״KKs`̻MukiT zٺt[im/`l@9*+OX)3tYByBKи26Cݎx{'11uVb!ҊU.6Nt EĔ<vZ4 ;pIOP5&26L%O=CKACNa!5Wg|q<wߥ̏V3O4W@# 5$m9opm/uQdR6`I4rX[co~;QSY]ёKjƥjㅗr8ɚ`=Qtr8˗tEqcO;nD*9qΎ`{M 1a\/4ROZ5ŁϬ.P!ē7JJLiXĪ3W6VT>U¯oATJ?d)k~`Mv]]ܥ+,q4zDĥ!Tf0ոk1娬|g8@4&e%I61.g. ʭ*VX,$eP߼ 5IGt_x_PI֣tCtZlpaLRi MEJq*.N :7qnsK2^oSd%6ELdkiDdfѢsR$0kШoN; D'dž ݲg}[ $ũhHJ[3ފ|r6_iz:J޾n[P3o9ܖu* ?a)xgdsav2_΀Yci "7x2G"缸BL>/F9 hsmQh6JƁP ?d+=3V5$[+븛 ? /*@'%gvtTك{,=sԣpCxr8jY1a`eD6\((zqɧFL|)} ,l^v:fwMYHˣzHciHvWP=^ /\},AyDA : 39i/62 uef };GcľwbfybkxA|Do+=ء EK|*AC@AJCxToǻU;lǐC"r"OW6kgkJCT_=%3qY"дۦ0.ZWy+9T7"S'k;~]{ 3{܋6or_\"ϧ[ߙW &=T+jfkܬ*ߣ"OFUYQ ɗj抻_{ MEHng ϞY2EyҜ,+ 4I[ ^Lv$`SԮU/ !IO-]f5'kSunzڑd(MGd!Ȣ_L b]u"+^XL\´ak """i}|_¬;g0$ͻD?M?譥M3̒ix w57yvA*ᙜl_f EqՖ4ͫ .3e&b&k:Ѳ~vl^Ж /I椒"P%?XK395y[?y!Vâi9IM=B03+^ꪼSdg0R+̓{!)W7MXAϞ,mmU@iPOqS!Iʀ_4afτww1,|p~LO;;{Ji4~Hdj,A}q^E] <ʾ=^JL1:އ6cj3˲Hz(ȵQAKvu!+W)w*0{.%i݊`0}A#kW( _-I7N}ꌈh V錟>;d_wiM_:_ Y7E7hTr OR>_"hq|+ő@0ZgG jnĠ5t/D׆[|ٲ @źC5sc3/;܊VyhF>j7%+d$])%45cּʇ_+{Zph(k$7%Hfr[Q֎!G_|kHdxP]B7x,N;W:oACa{=c˼m|eam]'9ϒ*߲`dLU8$OS4*߉¥p.AYŽyܛҚ!  4a-fZ|j?P[rS+:_D(i*=#GS=6YGC;zO$!+{X>cgTKe}zOkdXkQu9Ӿ 8\HЖ:;W9`]P;LKf\ $(WH^-G+5 3[[ZL(=O׹[[s6\Rh(+oT2Q,LoH@O/R}腺)vr<ܩG-9X|a/eہSFUW)H]/+:KQ{8!Ŗ@Enq`d6biwk3vKI4.Ct(~F}[?Ѭa1K2c{?MD ލ?^"gx[;,~X0m&ZRPdŜNNfkFDŽIs.[3OVjl mIXgV=LY#`r9ʸpK F^75Z&gdĺTzKx ݛ% ! w2k2| Se-*a>NQ hķ ҳ _Lzv)QiNkF7vKaa49͛t`TYs7~Er[NBX^S=~2h0dz]!k:8tIM{@0mp{eYLt7 ~ڝ2 [jWmOS1 3EM$+⒑{.au[vI5+XfsĤ{{!B0ߍghf{|dY0335rU~c5O>G48 u$]AQ@* O;j&̶~kf(ؗh隒qĴ^ ;VMQ(Opؖ~.o΀x- ܼat{Γ*˩adF;CE?я80gF?7)@]Kb/H>t dygbe UY;8!+"U (roG.ػx!Jk'c0N6kYESRv"fO_6;ݵOc:,B2D]}TD.kOX7+ B |()/V=@5%3fw*˕ai_m"T?5c)'/N8Ul?U*VE^кX#i5RQ_V?btXv}SH{R_d܍$|po/%r]ܩ|$P]yQ4„.?~H8f3ü/`h5>HLZ {cXJ>ʤ]_`xgvk1l-zoSzeYKE|M|gW"$qё]ݐoOyo9Q]7ڨ4pYWls5iXhXʾF2f My6t/5k0ENg8')Pg׌3ľ.5KH) οwƈJy$sstLGMZ ዜha&粂<ɾ6gKq&9|:~7%ș;E@Ur~v*bU7eW<~Ba|:1_p^'kyj-3$fHG4A Ci eYVO>2=rR,;p\0@dn-E, 8J%1LEX)%RfRhڶS κ%,Ezo71q"@7ZʈSkHg|鼺Fj4;DP4GQv,&eAG(p9ڈ/:aVgt*)/,'wki+8u9 1E9FoK}) DzO*@\geSk<ʏ$h0o"BR] Α]]T^#^Yd0Yzï@lELTDϬ%h2C3Oɴݖ6zu)Mc`jV+ia2v&•gQOg8|PC <_ۣ{g endstream endobj 437 0 obj << /Length1 1647 /Length2 11152 /Length3 0 /Length 12002 /Filter /FlateDecode >> stream xڭweTܒ-Nhݝơ 4 $xp݃ݹsgϼѽԮUuvZ)IUE-@f@)#d`rP*0\ewRh 9J|m@h`c"RAN6V`6-==ÿ,%)OwM++/WrGxMKuXK͢u-y 9 (9_<<m# QfZmB3 {ډiu2q:1W_yhjGI긃C8_d 4F(1<8[2 U-.F]y>W[sac`N}5=p|Z_+avݱ/ֆW5\u)@'z{}Q^6 0󒬜Q*T̄{$(dVZ[3>8ȂN1?:\dIil +GcQkۜċB.a%^qgH3 Ah06f5FkYOx8\F-azS{uRm7]ԐEc]_o晤<. 0<@<T:ǨS_xՉvyTgP* D6_ڣfSG:Vwa(Ru3Ee0#T|׫[4)l<]w*p.\4X=?pA0,la]6կDfC|OQv CCVom^M&Ң{B&R:$C 1؎a~fm5h0ɖ>I-"nZ=jDT2'F2 Ff ?B 2lȭ+["xx>/75J V?,^eo1W1]ʿۋfM|:!h}{q2kҲcĸL!R?y=H_k;u< jW֗O1XA+PfԚRLc^V !C{@AI؜.CoO_;T&܃|n!, P#(l?pJli$e[=SU 㓍}Fa-3рsl4e5IčfkևS].3,԰BMl8uXuqzC#.vda&|)X d<+EQOg8B4)D4J)gۣGxf&p){]=*pMK^httv\D6y9 Ft$SEe΁Zn>ZW0f=wO¡ ś% :gbA9M0o!;BT0Pc.V.#\c#tW03ӵ \$op:YE VaKbҜlEsFPL/9?~7 ˀ}Zi%J"9$,.Am9vtނkv|ĨT=dlOƠI}|TGG)J{"gU`]0 V#w=bz:6A#HGPo!~J#[ Y%NtNԔm22GL9v0O,ʞ} {(-QDE.TAb<|bEؒhhN$g>'IBY\nҬ% Y(r -@n3;Kuk<`A"!D 4>Scțak|Knh/Do/R(F10twHf0,WZLoY4!c!/ωtE b$TpytoP!8O"XFP"GLb KpƂN ·&P@nqpS-:Ni(jVܫ)[.,F=CcṂ?2H: 8/)Y u[vsZ%>{$q(\IDH3~uFr!#XNJCd]A MT2juݡ,<il7RD~?߰~S٩xkW"(tήEdAelP^BRu✗FC2u7G g_PWVJn;5ŷѫxQC/ɊaP2 q?@U}5[:xQ_VtPSMu[pEklSt.hͶb/4) ן)L]}QU [a N/W4:Vi~-ժv+u0pdL$mj,z=/rDpd*Iw+N,>$1yG,djz~"wmWSX9 kBuXJi6 LkqǫbAng Cd` -ӽT$UeCt JNyjC::}3壆\Bf=3*jErN 5t ꕿ5@`\[VE\}(֊!<;8)1GeH-`}YUsAЭPnBczTw-x\G{S+ih 3,n) 1Л$:^KM5Ǵa$#}k "3 (B7,FX$!:|ީ`h l|Dt/#]e NJI.93}͎X(L011tVy6O1V៻ oN73;:VWH.A^NC~@0LJfh]c7iyD!ۅWy& H9 dIq7)i).I.#;_:By7Nuf^8J ڥ7z7xor> ~Hڀmȭ€_u&_Lq!O^O|.5~iv3?g_gߤA!6z;`hzˁQ߂ڽD'ڷ='9=?s,w'u =HkUt>\`^l堰Z74 ]PuvT|8kgns-+fkNq{Oغ){\H](35|?ر sH9e)b btB=}a''PFڌΥ~5/55xb lF`DMo;ZebRR?W\ڂʉ~)M/"g 9i%(WT?zB%U_meq<GhI2f. 3VVP&&Ǒ[GM&0ig3&A~~)jńTfq⣲<)x5m ;ޒ%hmc[+ϣn Dpp4ՙ.21 I,tU[j.wv3 _(|Zv6#/I?ǽҽMLh4ǶAx03&ȑ*Nf5-Ee*nhe5l.'x>)HA̝&,6OsI=B$3-jFG#sm4 ND\pOmWbo$J; KBi|/_N`e8{i\JFx,i`Ґ[ E"L_BWrS~%#"3ɲ҅UV|i.ҧKcOLHaWcfO@En]({+%vGǞI;U@?|r gj<5@V"ZOݩ(9@QΪtGĎlmC#[d||Bo>}6qY$f!(PgZ|e 4DHm+Ѯ";5& u"^Ww>5B{/Hjp P'NNa6"sgF(_gvvfZ/aJ'po[4eRp:ge?wTic[A cjCf7ZBt. ^+5]!xV/rHM<_ Z̫K$C2-E4>oMU䅙L 3jR’Ri`bw\9Ϛ'CE)txBN{r)v>De%Wy$[ðP:Jik| vŽZl)0QŕʇHD/ |甈fT^ =W2] @X $"x¦4pbhU8N\+7GB\aE~b"<1~l4Y0`Z%Qְ$3Uv&U7g&F:h^&4 ⡦T瞜7V7'WYJo"$"d3XzM5d&p!3]"_"al}Bc.0V8~+< BDWmwK}+]~S!Z)[eзKf hug$,.~ C FX᱙m驪Pis)w@WC`y7M6Skd|/ӓvTWg8 k" (]ZIԨ-[Y{3ޟKһM^;O%ا~b\H u2!<}QiIh٣"-[M0fbV*z_j!ੳX١F6&7*NUuz@<+B9g Z -L lQsȯYEU`, }Nɥ^)C,^,K%O'ٸ>eRWKhcӳ hoJÈ_7% D*{^ɖa"GŪUaoW9i/5Po"P TĖ:r32mN6Gё^'ϗ:U}0_[ױ%0 }?MvoņЗ-d GD6a}M>r\,]d,7.{HhܬjQҮV4Oa>)@$ sg|VH j)e -?A9QMޙ,sx9 hwxVrhK'[A9iP)'R8àT;^ۣVy8܀H T*draWa~v=^Rm/6vqD #a="vPV}ǟ YZϮTeCU$KSft%]Dt\vՠ67 U|MQh`\KVu:^mD}=G2׽6%Qh ^qS4ayAeHdㄌ+aAq`Z%tx'47ԫ]Bqlh^L6Y`JwKGMnRoG 7&ce(5Й԰i fi*d 2ƴZeIX oX"oj$ϯQb4+Y'6%8ÐMdL=2,tl=3O#O 깽]ZE4ƠmMBȧ@:bݥrv_*W/\!2HTQ~A +}8ZZ3Ȏts~tG,9[Y]h/~4MTB44 3#u c7jb.J{zVKrD !*d Җ$>븱q6Z >QB<[s<7SdZBMlʝ֥o+5Jy[ J)ɯ|s##,|NnkwcC mZsq` ('ʎ@2׵K0"m|33ڣudKN$ ]uo(NLyO#t5Ȭ|nHl,r(PyS5D{+Qь2y,tV^W;㷚rs321 ԝ'V+X5\[|+:J,v1,7+m1 {WB)80-ps {f%٧*%]g8[:BF)Rέ4cyU-$`FDI{ov ;φ&BCkM@a_BwS_O pzi ko0cxRѯ<%jtenicQ=n,݀: V[Ն32=_nNUOg˸R*ՖUٓ-Ti Q#-<"^}~U)93pqC<[RJzCL}TK,𬼒lŭ1}!A]"]^.Cx1F`TĩɠWɛO\P sr_|l*ZGFb'\܊|[Qj*˫nSNX(ŜD?!<5'eȶcoT '.ƪ8L&= bMAR;R"S_rtdK|uy4D6v?=p;fj"h3/J3S?z? 2$c d/CC澥-~Ffg??U_C:PEi=3ӗV\tmLD_PC ]tf!0`_dD*1NA}͸d&f=ޮ{G7 /XYUvEgCL 1IJEG*Cٰ~h{ׁ+ _o%ˀ7čd،q+!av^!m=𯿰}?D|Ŭ,—jb4`I3Qؓ]nKCc+.'6ʋ11%$L$8;^>c9,ilަ.oiZ}9}j&)zp|EgϩX,wD9ZmaL/\{ (Kٹ?L^rI0'^&z}GK-똥w;C` ijk{dMw^,-SsKmSՕ5NrqñJbO6&ʼ=I81t ۳(|* tRK0 Py1xG4ݾIkljڄA4Z>fx۹hu_$ =C2nK4)f3nJkƐar*q0jMw\nSi%`]F*K=n'n[9I66_|*au1ۼ]lj8'1^uG^Ig< @l6BrB{\vfP5qՐgh } (L2<9Y-OE99M3t룘"ɍ06rxj޹cuDӐ"58>p0RnϤ7ٝBg2W2נ9~2vC֝lF|Y HͳDՖ~:tA+C-` )/2WFB*յ1:.-򲩑XGC쩽KE)=ؤ]L i϶? ڴ yeX&=ݬ.adQjxg?Aӯ>`[P4W'9%9^POoӧl8Iȉэ$.\=.| pI)Bk;G͡{DpP ,L_~ڇlذTr"~ŭmꙥ@bA5̸.;oq^tHOx_+nELk7tG9߂SrД_BK+=Í"{]U=Q8"Y|wϓR%#jPJ(㾧s~Y#LJ´ޏF+_NW]JtMv9cBs9v5U4c ڳΞ$y|Sgʧ_F9]9p#5#2o po%:&Po §髾/ endstream endobj 391 0 obj << /Type /ObjStm /N 100 /First 924 /Length 4459 /Filter /FlateDecode >> stream x\[o~P,NcNӤ fʒ+mr~Y.%E* HH.63̮$K #2¥''hxBxJ"FS9< B4psg0D:Riqµ +(HPaG < vVDpl(x'$B* I"Q`,`u(ƈbP ^XpQb0(eBŽr8#IA0 8(nkqUP(+T PHC;#H-$R[@ (9 f+@zn8$f0HpP^h< РF0n rPΌYq 1o7b4- F:TI5 ƙ=+( d뱳s(x0s Vtu#(N)$0 s{?G/r^\=ڟͯ{ }'9=|}_-{PKQaϜЯG~ Bg3B䇻M}O{x06l"mE恳GdB 4b(L 8GdA |0qi>-uf5<f<*4؝"?5( Zo3NP蕭3Od gNr/E (3}LG䁣bdG'$P7}|~iLṚ2RdCk㞆0"F<: Y `p2'fO r#2L4z B'PRL9^y(Ỹk\g"$9 P/3 q_ԘLfmĀ0 # };TeCW"17v%]ߜr8.CL`eÐ q&Lx",= ̿,I.HqG.!U< ]! `,R#c}:2k)%ȎY#%Y!/7kRf2mK$sH KYH e ,/G(e;q%bDSٰeqlM>9G|mh=HFt]eҌ+eDAOYzཌྷ-<{WM#@k]1.Ų^/=yxNs 1B$#Ͳ㤐.~A@kkz7u.蝼EK|~MKH%CdJ՚Jnd*!=/9}E_wu.2=;>zv1v88Zů9/5ҪU_kJeh|7 ^{Mog:S:Kz?狫<_:yK O6U{(l 4z#:c꿠_W舎n5-(/ǓƋh`hJw^_x̦Vg L JD~~ڻ#|;:Os:ŒoPϳ1xAgt9~xlsv\ҋZ <˿fW6FKg5S;'/NKSZy)45ڥ[+o[SK mefmc^ zE˩Mj2I}VQ Z3bHzMT33 /?TW{ۏu~st,N8Z&u%=;^ Y7}4h`hs urO^~9yv54__|=@abfNy/`i"%516UHqF& ]%K ,Ӱ`CHú ˞+1ZϥKin~#.xY:U܄z7«ϕV ѵrBDhr ҙ妮ʛ;:2Ǯ Ga֢ј?PI>\q%FeMM%^Lj9sVҴz >Di:^2avq&_cJp"_^;yE\t8/X4 ~Jx8Z]'??zJP !܇@9a`xZ1mop58kQ:`M"S}z}4,rhԀ:oZP 0;D~Y{fp`ĀnL> endobj 446 0 obj << /Type /ObjStm /N 22 /First 191 /Length 1256 /Filter /FlateDecode >> stream xڭWKoFW3; $u >( 3\RZTCc)TA O_P?cdT o1t.PA')]%< DKlLh=3X({luU3L9|AZYp\o6՟.B[ryka)9Ej] .xߒg/U?=8K׸RXCYr%qyK.nP^`Kf=եƶ^چ^mLc=ymNb*8)vJR:ne\LUUF*ijlUzy}}")bFX,H6LRkXVI=|H+}oWg)p`_6߷ r@5֚3N%GId!)G !Gdv " Q.GLߤê3œtXJW"uK"B DJOa^[WB( j-HJQsDnT2@r h^ͳp|;37Wx9_".&zwOȥ+dJ+[7vuM%J ׃+anuDczĈz pcPcP&;88Y|Vr]^O1ș>Ą1șX}NtRr'yLD7M񸺉<Y7{ GAkf]2%֝o3!ibtI_c\*D3.9<~>JPi{),6a^,z.z' ;dc$QQz韓w|o~x|SʖUꏚHO߾~Ocza]$?Mҳa[l{'Rb\~緍W^MXluo/֟8G^oݓ wUZviכoۇWƧB4[-,Ö,˖,ǖ,ϖVH;+ٺgh$&*H\ d@ Bb B / /&^^L(xQx1r U/Y endstream endobj 469 0 obj << /Type /XRef /Index [0 470] /Size 470 /W [1 3 1] /Root 467 0 R /Info 468 0 R /ID [<36C83ECF5FB95E3E239E4C16A53D13E8> <36C83ECF5FB95E3E239E4C16A53D13E8>] /Length 1115 /Filter /FlateDecode >> stream x%9l]E;%^&ޒY؎_DZyIY8BC@hDA(Is;{&B( T/T봃fvmОրZhOiChўցcà Ѐ m#h &m38v!m hEBڠmh\Hh#8֍vtG[,'h{K* 8B .ݣ=Ѯݥh7a{hiG(-10L;&Ag8o!4t,8ǿ̓ .k\ ^kQ̀Yӭp,` FzU6G>9#LVJ-v!DS&8xBݗZ?#zhw,~U|N]'讠o'Ϯ<+]m; T7Z'V@XàBOZLl wqt}y? k>H#q0⛓!'C([b"xx 0111111111111/yp@I?N2!P;)qRI'N,8 ugɋ3.`e5 XXj!oכZw4z@JU)]h-,Pu+ 2Mhau]z 4x4iNY04n<Y^U͗Ӡ uVL8 AInEKq0i"Fk`i '^nP zep‡/n,;6X,%- V&X>x8vↅux 8{ m<$m"I%v'؝;頒u@%'LN:I7%.yZ/#I'"@@{"бCH"$j!,ݹBPUo߫;ZT5h6!T [;U#VOUV}O՘^j b&BVgU,{KXrߟ8c@ƀ2d 1 c@ƀ2d xf3;#ٙmVMQ endstream endobj startxref 258019 %%EOF GAPDoc-1.5.1/example/chapInd_mj.html0000644000175000017500000000671012026346064015565 0ustar billbill GAP (GAPDoc Example) - Index
Goto Chapter: Top 1 2 A B Bib Ind

Index

\^\{\}\[\]\<\&, for nothing 1.2-2
Aachen, Hauptbahnhof 2.3
AllBlibbs 1.2-9
BlibbsFamily 1.2-10
f 1.2-1
GAP, GAPDoc 2.3
InfoBlibbs 1.2-11
IsBla 1.2-6
IsBlubb 1.2-7
MyOperation 1.2-3
MyOperation, First 1.2-4
MyOperation, for bla 1.2-5
NumberBlobbs 1.2-8
RWTH 2.3
TeX-UserGroup 2.3

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chapB_mj.html0000644000175000017500000005735512026346064015247 0ustar billbill GAP (GAPDoc Example) - Appendix B: The Source
Goto Chapter: Top 1 2 A B Bib Ind

B The Source

B.1 TitlePage (Source)

<TitlePage>
  <Title>A Complete Example (&see; <Ref Sect="One"/>)</Title>
  <Subtitle>Every element shows up</Subtitle>
  <Version>Version 1.5.1
</Version>
  <TitleComment>
  If the subtitle ist not sufficient, this &lt;TitleComment> 
  element can be used for a slightly longer text on the front page.
  </TitleComment>
  <Author>Frank Lübeck 
          <Email>Frank.Luebeck@Math.RWTH-Aachen.De</Email> 
  </Author>
  <Author> Max Neunhöffer 
          <Email>neunhoef at mcs.st-and.ac.uk</Email>
  </Author>
  <Date>September 2011</Date>
  <Address>
  Lehrstuhl D für Mathematik<Br/> Templergraben 
  64<Br/> 52062 Aachen<Br/> (Germany)
  </Address>
  <Abstract>This document tries to use all elements that exist in &GAPDoc;.
            In addition, the final output not only contains the usual
            content, but also an appendix with the source text. There
            are also links from the usual content to the corresponding
            source text. This should enable new users to learn &GAPDoc;
            quickly.
  </Abstract>
  <Copyright>&copyright; 2000-2011 by Frank Lübeck and Max Neunhöffer
  </Copyright>
  <Acknowledgements>We thank Lehrstuhl D für Mathematik.
  </Acknowledgements>
  <Colophon>This is the Colophon page.
  </Colophon>
</TitlePage>

B.2 Before First Chapter (Source)

<TableOfContents/>

<Body>

  Text before chapter <Ref Chap="First"/>.

<Chapter Label="First"><Heading>Sectioning Elements</Heading>

  Text before the section <Ref Sect="FirstSect"/>.

B.3 First Chapter (Source)

[1.]

<Section Label="FirstSect"><Heading>Normal subsections</Heading>

  <Subsection Label="Asub"><Heading>A subsection</Heading>

   This is text in the first subsection.

  </Subsection>

  <Subsection Label="Another"><Heading>Another subsection</Heading>
   
   This is text in the second subsection. This subsection 
   has a label, such that one can reference it.

  </Subsection>

 </Section>

B.4 ManSections (Source)

[1.2]

<Section><Heading>ManSections</Heading>

  <ManSection>
   <Func Name="f" Arg="x[,y]" Comm="calculates something"/>
   <Returns>an element in <Ref Filt="IsBlubb" /> or <K>fail</K>.</Returns>
   <Description>
    This function calculates something.
   </Description>
  </ManSection>

  <ManSection>
   <Meth Name="\^\{\}\[\]\&lt;\&amp;" Arg="c" 
         Label="for nothing" Comm="tricky name"/>
   <Description>
    This method is for an operation with a tricky name.
   </Description>
  </ManSection>

  <ManSection>
   <Oper Name="MyOperation" Arg="x" Comm="calculates something"/>
   <Description>
    The operation <Ref Oper="MyOperation"/> operates on <Arg>x</Arg>.
   </Description>
  </ManSection>
   
  <ManSection>
   <Meth Name="MyOperation" Label="First" Arg="x" 
         Comm="generic method"/>
   <Description>
    This method calculates something by the generic method.
   </Description>
  </ManSection>

  <ManSection>
   <Meth Name="MyOperation" Label="for bla" Arg="x[, good_hint]"
         Comm="for bla arguments"/>
   <Description>
    This is the super-fast method for the operation
    <Ref Oper="MyOperation"/> if the argument <A>x</A> is in the
    representation <Ref Filt="IsBla"/>. It will become even faster if
    the optional argument <A>good_hint</A> is given.
   </Description>
  </ManSection>

  <ManSection>
   <Filt Name="IsBla" Arg="obj" Comm="representation bla"
         Type="representation"/>
   <Description>
    For objects in this representation there is a super-fast method
    (see <Ref Meth="MyOperation" Label="for bla"/>) for the operation
    <Ref Oper="MyOperation"/>.
   </Description>
  </ManSection>

  <ManSection>
   <Prop Name="IsBlubb" Arg="obj" Comm="property, whether object is blubb"/>
   <Description>
    A property.
   </Description>
  </ManSection>

  <ManSection>
   <Attr Name="NumberBlobbs" Arg="obj" Comm="number of blobbs"/>
   <Description>
    An attribute. Number of blobbs.
   </Description>
  </ManSection>

  <ManSection>
   <Var Name="AllBlibbs" Comm="list of all blibbs in the system"/>
   <Description>
    This global variable holds a list of all blibbs.
   </Description>
  </ManSection>

  <ManSection>
   <Fam Name="BlibbsFamily" Comm="family of blibbs"/>
   <Description>
    Family of all blibbs.
   </Description>
  </ManSection>

  <ManSection>
   <InfoClass Name="InfoBlibbs" Comm="InfoClass for the library of blibbs"/>
   <Description>
    This info class is used throughout the library of blibbs.
   </Description>
  </ManSection>
    
 </Section>

B.5 Various Types of Text (Source)

[2.]

<Chapter><Heading>Other Markup</Heading>

<Section><Heading>Various types of text</Heading>

In this section we present examples for all the various types of text
that are possible in &GAPDoc;: 
<List>
 <Item>
  <Emph>This</Emph> is <E>emphasized</E>.</Item>
 <Item>
  <E>Keywords</E> are typeset like <Keyword>this</Keyword> and <K>that</K>.
  </Item>
 <Item>
  <E>Arguments</E> of functions have an element. They look like this: 
    <Arg>x</Arg> and <A>y</A>.</Item>
 <Item> 
  <E>Code</E> can be written with the Code element: 
    <Code>if x = y then Print("Equal"); fi;</Code> or
    <C>while true do Print("Hello"); od;</C>.</Item> 
 <Item>
  <E>Filenames</E> have their own element:
    <File>/usr/local/ca/gap4r2</File> or <F>pkg/xgap/doc</F>.</Item>
 <Item>
  <E>Buttons</E>, <E>menus</E>, <E>menu entries</E>, and such things
    are also supported: <B>OK</B> or <Button>Cancel</Button>.</Item>
 <Item>
  <E>Packages</E> are typeset like this: 
    <Package>Small Groups Library</Package>
 </Item>
 <Item>
  <E>Quoted</E> text: <Q>This is a text in quotes.</Q>
 </Item>
</List>

<E>Paragraphs</E> are separated by the empty <C>Par</C> or <C>P</C> element.
<Par/><E>Alternatives</E> for different output formats:

<Alt Only="LaTeX">This is &LaTeX; output.</Alt>
<Alt Not="LaTeX">This is other than &LaTeX; output, namely:
<Alt Only="HTML"><![CDATA[<b>HTML</b>]]></Alt>
<Alt Only="Text">Text</Alt> output.</Alt>

<P/>

B.6 Verbatim-like text (Source)

[2.1]

There are also three elements to typeset <Q>verbatim-like</Q> text.
<P/>
The first is a <E>Listing</E>:

<Listing Type="GAP code">
<![CDATA[Sieve := function(n)
  # Returns the primes less than n
  local l,p,i;
  l := [1..n]; Unbind(l[1]);
  p := 2;
  while p^2 <= n do
      if IsBound(l[p]) then
          i := 2 * p;
          while i <= n do Unbind(l[i]); i := i + p; od;
      fi;
      p := p + 1;
  od;
  return Compacted(l);
end;]]>
</Listing>

Here is a <E>Log</E> of a &GAP; session using this function:

<Log>
gap&gt; Sieve(100);
[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
  67, 71, 73, 79, 83, 89, 97 ]
gap&gt; Length(last);
25
</Log>

Here is a &GAP; <E>Example</E> session that is automatically tested:

<Example>
gap&gt; s := Size(CharacterTable("M"));
808017424794512875886459904961710757005754368000000000
gap&gt; s &lt; 10^53;                     
false
gap&gt; s &lt; 10^54;
true
</Example>

</Section>

B.7 Formulae (Source)

[2.2]

<Section><Heading>Formulae</Heading>

There are three types of formulae. <P/>
The first is the <E>normal math mode</E> of &LaTeX;: 

<Math>b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k</Math>. 

Then there are <E>displayed formulae</E>:
<Display>
   \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot
   \left(\sum_{j=1}^d y_j b_j \right) =
   \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k 
</Display>

If possible,  use the <C>Alt</C> element  to specify a better  readable text
version of such a formula as in the following example:<P/>

<Alt Not="Text,HTML"><Display>
   \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot
   \left(\sum_{j=1}^d y_j b_j \right) =
   \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k 
</Display></Alt>
<Alt Only="Text,HTML"><Verb>
         d                d                 d   
       -----            -----             -----  -----                 
        \                \                 \      \                    
 ==> (   )  x_i b_i )(    )  y_i b_i ) =    )  (   )  x_i y_j h_ijk ) b_k
        /                /                 /      /                    
       -----            -----             -----  -----                
       i = 1            i = 1             k = 1   i,j                
</Verb><P/></Alt>

For small formulae without <Q>difficult</Q> parts use the <C>M</C>
element: <M>b_i</M>,
<M>x^2</M>, <M>x^2 + 2x + 1 = (x + 1)^2</M>. Note that here whitespace 
matters for text (or HTML) output).<P/>

Here are two formulae containing less than characters which are special
characters for XML:
<M><![CDATA[a < b < c < d]]></M> and  <M>e &lt; f</M>.
</Section>

B.8 Crossreferencing (Source)

[2.3]

<Section Label="Cross"><Heading>Crossreferencing</Heading>

<Label Name="there"/>

In this section we demonstrate various references to parts of this
document. Here is a reference to this section: <Ref Sect="Cross"/>.
Here is a reference to chapter <Ref Chap="First"/>, to appendix
<Ref Appendix="Appendix"/>, and to subsection <Ref Subsect="Asub"/>. 
<P/>

We distinguish among others references 
 to functions (see <Ref Func="f"/>), 
 to methods with tricky name (see 
                 <Ref Meth="\^\{\}\[\]\&lt;\&amp;" Label="for nothing"/>),
 to operations (see <Ref Oper="MyOperation"/>), 
 to methods (see <Ref Meth="MyOperation" Label="First"/> or 
                 <Ref Meth="MyOperation" Label="for bla"/>), 
 to filters (see <Ref Filt="IsBla"/>), 
 to properties (see <Ref Prop="IsBlubb"/>),
 to attributes (see <Ref Attr="NumberBlobbs"/>), 
 to variables (<Ref Var="AllBlibbs"/>), 
 to families (see <Ref Fam="BlibbsFamily"/>),
 and to info classes (see <Ref InfoClass="InfoBlibbs"/>).
<P/>

There are also references to labels: see <Ref Text="here" Label="there"/>,
to other books: see <Ref Sect="syntaxXML" BookName="gapdoc"/> or
<Ref Oper="IsSubgroup" BookName="ref"/> in the &GAP; reference
manual.
<P/>

References to sections come in two styles: 
<Ref Chap="First" Style="Number"/>
or <Ref Chap="First" Style="Text"/>.
<P/>

Another type of cross referencing is bibliography. Here is a 
citation: <Cite Key="CR1" Where="(5.22)"/> is an interesting lemma.
<P/>

There are also URLs:<P/>

<URL>http://www.math.rwth-aachen.de/LDfM/</URL><P/>

Email addresses have a special element:
<Email>Frank.Luebeck@Math.RWTH-Aachen.De</Email>
<P/>

and Homepages another one:
<Homepage>http://www-groups.mcs.st-and.ac.uk/~neunhoef/</Homepage>
<P/>

One can generate index entries as follows (look up the words 
<Q>&TeX;-UserGroup</Q>, <Q>RWTH</Q>, and <Q>Aachen, Hauptbahnhof</Q>).
<Index Key="TeX-Usergroup">&TeX;-UserGroup</Index>
<Index Key="Aachen" Subkey="Hauptbahnhof">Aachen</Index>
<Index>RWTH</Index>

</Section>

B.9 Lists and Tables (Source)

[2.4]

<Section><Heading>Lists and Tables</Heading>

There are
<List>
 <Item>lists</Item>
 <Item>enumerations, and</Item>
 <Item>tables</Item>
</List>
or:
<Enum>
 <Item>lists</Item>
 <Item>enumerations, and</Item>
 <Item>tables</Item>
</Enum>
or with marks:
<List>
 <Mark>lists:</Mark><Item> not numbered</Item>
 <Mark>enumerations:</Mark><Item> numbered</Item>
 <Mark>tables:</Mark><Item> two-dimensional</Item>
</List>

Lists can also be nested:
<Enum>
 <Item>
   <Enum>
     <Item>first item of inner enumeration </Item>
     <Item>second item of inner enumeration </Item>
   </Enum>
 </Item>
 <Item>
   <List>
     <Item>first item of inner list </Item>
     <Item>second item of inner list </Item>
   </List>
  </Item>
</Enum>

Here is a <E>table</E>:

<Table Align="|r|c|l|">
 <Caption>Prices</Caption>
 <HorLine/>
  <Row>
   <Item>Object</Item><Item>Price</Item><Item>available</Item>
  </Row>
 <HorLine/>
 <HorLine/>
  <Row>
   <Item>Shoe</Item><Item>$1,00</Item><Item>there</Item>
  </Row>
 <HorLine/>
  <Row>
   <Item>Hat</Item><Item>$2,00</Item><Item>not there</Item>
  </Row>
 <HorLine/>
</Table>

</Section>

B.10 Entities and Special Characters (Source)

[2.5]

<Section><Heading>Entities and Special Characters</Heading>
<Label Name="TenBack"/>

[&see; <Ref Sect="Ten"/>]<P/>

Here is a table of special characters, the first two are special for
XML and must be typed in by entities in &GAPDoc; documents. The other 
characters are special for &LaTeX; but in &GAPDoc; they can be typed
directly. 

<Table Align="|c|c|c|c|c|c|c|c|c|c|c|c|c|" Label="charsInCDATA"> 
 <Caption>Special characters in character data</Caption>
 <HorLine/> <Row> 
  <Item><C>&amp;</C></Item>
  <Item><C>&lt;</C></Item>
  <Item><C>></C></Item>
  <Item><C>#</C></Item>
  <Item><C>$</C></Item>
  <Item><C>%</C></Item>
  <Item><C>~</C></Item>
  <Item><C>\</C></Item>   
  <Item><C>{</C></Item>
  <Item><C>}</C></Item>
  <Item><C>_</C></Item>
  <Item><C>^</C></Item>
  <Item><C>&nbsp;</C></Item>
 </Row> <HorLine/>
</Table>

And here are the predefined entities in &GAPDoc;:

<Table Align="|l|l|">
<Caption>Predefined Entities in the &GAPDoc; system</Caption>
<HorLine/>
<Row> <Item><C>&amp;GAP;</C></Item>       <Item>&GAP;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;GAPDoc;</C></Item>    <Item>&GAPDoc;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;TeX;</C></Item>       <Item>&TeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;LaTeX;</C></Item>     <Item>&LaTeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;BibTeX;</C></Item>    <Item>&BibTeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;MeatAxe;</C></Item>   <Item>&MeatAxe;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;XGAP;</C></Item>      <Item>&XGAP;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;copyright;</C></Item> <Item>&copyright;</Item> </Row>
<HorLine/>
</Table>

And some more for mathematical symbols: 
&CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR;.

</Section>

</Chapter>

</Body>

B.11 Appendix (Source)

[A.]

<Appendix><Heading>An Appendix</Heading>

This is an appendix.
</Appendix>
Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chap1_mj.html0000644000175000017500000002426212026346064015215 0ustar billbill GAP (GAPDoc Example) - Chapter 1: Sectioning Elements
Goto Chapter: Top 1 2 A B Bib Ind

1 Sectioning Elements

Text before the section 1.1. (→ B.2)

1.1 Normal subsections

[→ B.3]

1.1-1 A subsection

This is text in the first subsection.

1.1-2 Another subsection

This is text in the second subsection. This subsection has a label, such that one can reference it.

1.2 ManSections

[→ B.4]

1.2-1 f
‣ f( x[, y] )( function )

Returns: an element in IsBlubb (1.2-7) or fail.

This function calculates something.

1.2-2 \^\{\}\[\]\<\&
‣ \^\{\}\[\]\<\&( c )( method )

This method is for an operation with a tricky name.

1.2-3 MyOperation
‣ MyOperation( x )( operation )

The operation MyOperation operates on x.

1.2-4 MyOperation
‣ MyOperation( x )( method )

This method calculates something by the generic method.

1.2-5 MyOperation
‣ MyOperation( x[, good_hint] )( method )

This is the super-fast method for the operation MyOperation (1.2-3) if the argument x is in the representation IsBla (1.2-6). It will become even faster if the optional argument good_hint is given.

1.2-6 IsBla
‣ IsBla( obj )( representation )

For objects in this representation there is a super-fast method (see MyOperation (1.2-5)) for the operation MyOperation (1.2-3).

1.2-7 IsBlubb
‣ IsBlubb( obj )( property )

A property.

1.2-8 NumberBlobbs
‣ NumberBlobbs( obj )( attribute )

An attribute. Number of blobbs.

1.2-9 AllBlibbs
‣ AllBlibbs( global variable )

This global variable holds a list of all blibbs.

1.2-10 BlibbsFamily
‣ BlibbsFamily( family )

Family of all blibbs.

1.2-11 InfoBlibbs
‣ InfoBlibbs( info class )

This info class is used throughout the library of blibbs.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chap0_mj.html0000644000175000017500000002357412026346064015221 0ustar billbill GAP (GAPDoc Example) - Contents
Goto Chapter: Top 1 2 A B Bib Ind

A Complete Example (→ B.1)

Every element shows up

Version 1.5.1

February 2012

If the subtitle ist not sufficient, this <TitleComment> element can be used for a slightly longer text on the front page.

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De

Max Neunhöffer
Email: neunhoef at mcs.st-and.ac.uk

Address:
Lehrstuhl D für Mathematik
Templergraben 64
52062 Aachen
(Germany)

Abstract

This document tries to use all elements that exist in GAPDoc. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn GAPDoc quickly.

Copyright

© 2000-2012 by Frank Lübeck and Max Neunhöffer

Acknowledgements

We thank Lehrstuhl D für Mathematik.

Colophon

This is the Colophon page.

Text before chapter 1. (→ B.2)

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/example.toc0000644000175000017500000001023412026346064015001 0ustar billbill\contentsline {chapter}{\numberline {1}\leavevmode {\color {Chapter }Sectioning Elements}}{5}{chapter.1} \contentsline {section}{\numberline {1.1}\leavevmode {\color {Chapter }Normal subsections}}{5}{section.1.1} \contentsline {subsection}{\numberline {1.1.1}\leavevmode {\color {Chapter }A subsection}}{5}{subsection.1.1.1} \contentsline {subsection}{\numberline {1.1.2}\leavevmode {\color {Chapter }Another subsection}}{5}{subsection.1.1.2} \contentsline {section}{\numberline {1.2}\leavevmode {\color {Chapter }ManSections}}{5}{section.1.2} \contentsline {subsection}{\numberline {1.2.1}\leavevmode {\color {Chapter }f}}{5}{subsection.1.2.1} \contentsline {subsection}{\numberline {1.2.2}\leavevmode {\color {Chapter }\texttt {\char 92\relax }\texttt {\char 94\relax }\texttt {\char 92\relax }\texttt {\char 123\relax }\texttt {\char 92\relax }\texttt {\char 125\relax }\texttt {\char 92\relax }[\texttt {\char 92\relax }]\texttt {\char 92\relax }{\textless }\texttt {\char 92\relax }\& (for nothing)}}{5}{subsection.1.2.2} \contentsline {subsection}{\numberline {1.2.3}\leavevmode {\color {Chapter }MyOperation}}{6}{subsection.1.2.3} \contentsline {subsection}{\numberline {1.2.4}\leavevmode {\color {Chapter }MyOperation (First)}}{6}{subsection.1.2.4} \contentsline {subsection}{\numberline {1.2.5}\leavevmode {\color {Chapter }MyOperation (for bla)}}{6}{subsection.1.2.5} \contentsline {subsection}{\numberline {1.2.6}\leavevmode {\color {Chapter }IsBla}}{6}{subsection.1.2.6} \contentsline {subsection}{\numberline {1.2.7}\leavevmode {\color {Chapter }IsBlubb}}{6}{subsection.1.2.7} \contentsline {subsection}{\numberline {1.2.8}\leavevmode {\color {Chapter }NumberBlobbs}}{6}{subsection.1.2.8} \contentsline {subsection}{\numberline {1.2.9}\leavevmode {\color {Chapter }AllBlibbs}}{6}{subsection.1.2.9} \contentsline {subsection}{\numberline {1.2.10}\leavevmode {\color {Chapter }BlibbsFamily}}{6}{subsection.1.2.10} \contentsline {subsection}{\numberline {1.2.11}\leavevmode {\color {Chapter }InfoBlibbs}}{7}{subsection.1.2.11} \contentsline {chapter}{\numberline {2}\leavevmode {\color {Chapter }Other Markup}}{8}{chapter.2} \contentsline {section}{\numberline {2.1}\leavevmode {\color {Chapter }Various types of text}}{8}{section.2.1} \contentsline {section}{\numberline {2.2}\leavevmode {\color {Chapter }Formulae}}{9}{section.2.2} \contentsline {section}{\numberline {2.3}\leavevmode {\color {Chapter }Crossreferencing}}{10}{section.2.3} \contentsline {section}{\numberline {2.4}\leavevmode {\color {Chapter }Lists and Tables}}{10}{section.2.4} \contentsline {section}{\numberline {2.5}\leavevmode {\color {Chapter }Entities and Special Characters}}{11}{section.2.5} \contentsline {chapter}{\numberline {A}\leavevmode {\color {Chapter }An Appendix}}{12}{appendix.A} \contentsline {chapter}{\numberline {B}\leavevmode {\color {Chapter }The Source}}{13}{appendix.B} \contentsline {section}{\numberline {B.1}\leavevmode {\color {Chapter }TitlePage (Source)}}{13}{section.B.1} \contentsline {section}{\numberline {B.2}\leavevmode {\color {Chapter }Before First Chapter (Source)}}{14}{section.B.2} \contentsline {section}{\numberline {B.3}\leavevmode {\color {Chapter }First Chapter (Source)}}{14}{section.B.3} \contentsline {section}{\numberline {B.4}\leavevmode {\color {Chapter }ManSections (Source)}}{14}{section.B.4} \contentsline {section}{\numberline {B.5}\leavevmode {\color {Chapter }Various Types of Text (Source)}}{16}{section.B.5} \contentsline {section}{\numberline {B.6}\leavevmode {\color {Chapter }Verbatim-like text (Source)}}{17}{section.B.6} \contentsline {section}{\numberline {B.7}\leavevmode {\color {Chapter }Formulae (Source)}}{18}{section.B.7} \contentsline {section}{\numberline {B.8}\leavevmode {\color {Chapter }Crossreferencing (Source)}}{19}{section.B.8} \contentsline {section}{\numberline {B.9}\leavevmode {\color {Chapter }Lists and Tables (Source)}}{20}{section.B.9} \contentsline {section}{\numberline {B.10}\leavevmode {\color {Chapter }Entities and Special Characters (Source)}}{21}{section.B.10} \contentsline {section}{\numberline {B.11}\leavevmode {\color {Chapter }Appendix (Source)}}{23}{section.B.11} \contentsline {chapter}{References}{24}{appendix*.6} \contentsline {chapter}{Index}{25}{section*.7} GAPDoc-1.5.1/example/rainbow.js0000644000175000017500000000533612026346064014645 0ustar billbill function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); GAPDoc-1.5.1/example/chapB.html0000644000175000017500000005675612026346064014565 0ustar billbill GAP (GAPDoc Example) - Appendix B: The Source
Goto Chapter: Top 1 2 A B Bib Ind

B The Source

B.1 TitlePage (Source)

<TitlePage>
  <Title>A Complete Example (&see; <Ref Sect="One"/>)</Title>
  <Subtitle>Every element shows up</Subtitle>
  <Version>Version 1.5.1
</Version>
  <TitleComment>
  If the subtitle ist not sufficient, this &lt;TitleComment> 
  element can be used for a slightly longer text on the front page.
  </TitleComment>
  <Author>Frank Lübeck 
          <Email>Frank.Luebeck@Math.RWTH-Aachen.De</Email> 
  </Author>
  <Author> Max Neunhöffer 
          <Email>neunhoef at mcs.st-and.ac.uk</Email>
  </Author>
  <Date>September 2011</Date>
  <Address>
  Lehrstuhl D für Mathematik<Br/> Templergraben 
  64<Br/> 52062 Aachen<Br/> (Germany)
  </Address>
  <Abstract>This document tries to use all elements that exist in &GAPDoc;.
            In addition, the final output not only contains the usual
            content, but also an appendix with the source text. There
            are also links from the usual content to the corresponding
            source text. This should enable new users to learn &GAPDoc;
            quickly.
  </Abstract>
  <Copyright>&copyright; 2000-2011 by Frank Lübeck and Max Neunhöffer
  </Copyright>
  <Acknowledgements>We thank Lehrstuhl D für Mathematik.
  </Acknowledgements>
  <Colophon>This is the Colophon page.
  </Colophon>
</TitlePage>

B.2 Before First Chapter (Source)

<TableOfContents/>

<Body>

  Text before chapter <Ref Chap="First"/>.

<Chapter Label="First"><Heading>Sectioning Elements</Heading>

  Text before the section <Ref Sect="FirstSect"/>.

B.3 First Chapter (Source)

[1.]

<Section Label="FirstSect"><Heading>Normal subsections</Heading>

  <Subsection Label="Asub"><Heading>A subsection</Heading>

   This is text in the first subsection.

  </Subsection>

  <Subsection Label="Another"><Heading>Another subsection</Heading>
   
   This is text in the second subsection. This subsection 
   has a label, such that one can reference it.

  </Subsection>

 </Section>

B.4 ManSections (Source)

[1.2]

<Section><Heading>ManSections</Heading>

  <ManSection>
   <Func Name="f" Arg="x[,y]" Comm="calculates something"/>
   <Returns>an element in <Ref Filt="IsBlubb" /> or <K>fail</K>.</Returns>
   <Description>
    This function calculates something.
   </Description>
  </ManSection>

  <ManSection>
   <Meth Name="\^\{\}\[\]\&lt;\&amp;" Arg="c" 
         Label="for nothing" Comm="tricky name"/>
   <Description>
    This method is for an operation with a tricky name.
   </Description>
  </ManSection>

  <ManSection>
   <Oper Name="MyOperation" Arg="x" Comm="calculates something"/>
   <Description>
    The operation <Ref Oper="MyOperation"/> operates on <Arg>x</Arg>.
   </Description>
  </ManSection>
   
  <ManSection>
   <Meth Name="MyOperation" Label="First" Arg="x" 
         Comm="generic method"/>
   <Description>
    This method calculates something by the generic method.
   </Description>
  </ManSection>

  <ManSection>
   <Meth Name="MyOperation" Label="for bla" Arg="x[, good_hint]"
         Comm="for bla arguments"/>
   <Description>
    This is the super-fast method for the operation
    <Ref Oper="MyOperation"/> if the argument <A>x</A> is in the
    representation <Ref Filt="IsBla"/>. It will become even faster if
    the optional argument <A>good_hint</A> is given.
   </Description>
  </ManSection>

  <ManSection>
   <Filt Name="IsBla" Arg="obj" Comm="representation bla"
         Type="representation"/>
   <Description>
    For objects in this representation there is a super-fast method
    (see <Ref Meth="MyOperation" Label="for bla"/>) for the operation
    <Ref Oper="MyOperation"/>.
   </Description>
  </ManSection>

  <ManSection>
   <Prop Name="IsBlubb" Arg="obj" Comm="property, whether object is blubb"/>
   <Description>
    A property.
   </Description>
  </ManSection>

  <ManSection>
   <Attr Name="NumberBlobbs" Arg="obj" Comm="number of blobbs"/>
   <Description>
    An attribute. Number of blobbs.
   </Description>
  </ManSection>

  <ManSection>
   <Var Name="AllBlibbs" Comm="list of all blibbs in the system"/>
   <Description>
    This global variable holds a list of all blibbs.
   </Description>
  </ManSection>

  <ManSection>
   <Fam Name="BlibbsFamily" Comm="family of blibbs"/>
   <Description>
    Family of all blibbs.
   </Description>
  </ManSection>

  <ManSection>
   <InfoClass Name="InfoBlibbs" Comm="InfoClass for the library of blibbs"/>
   <Description>
    This info class is used throughout the library of blibbs.
   </Description>
  </ManSection>
    
 </Section>

B.5 Various Types of Text (Source)

[2.]

<Chapter><Heading>Other Markup</Heading>

<Section><Heading>Various types of text</Heading>

In this section we present examples for all the various types of text
that are possible in &GAPDoc;: 
<List>
 <Item>
  <Emph>This</Emph> is <E>emphasized</E>.</Item>
 <Item>
  <E>Keywords</E> are typeset like <Keyword>this</Keyword> and <K>that</K>.
  </Item>
 <Item>
  <E>Arguments</E> of functions have an element. They look like this: 
    <Arg>x</Arg> and <A>y</A>.</Item>
 <Item> 
  <E>Code</E> can be written with the Code element: 
    <Code>if x = y then Print("Equal"); fi;</Code> or
    <C>while true do Print("Hello"); od;</C>.</Item> 
 <Item>
  <E>Filenames</E> have their own element:
    <File>/usr/local/ca/gap4r2</File> or <F>pkg/xgap/doc</F>.</Item>
 <Item>
  <E>Buttons</E>, <E>menus</E>, <E>menu entries</E>, and such things
    are also supported: <B>OK</B> or <Button>Cancel</Button>.</Item>
 <Item>
  <E>Packages</E> are typeset like this: 
    <Package>Small Groups Library</Package>
 </Item>
 <Item>
  <E>Quoted</E> text: <Q>This is a text in quotes.</Q>
 </Item>
</List>

<E>Paragraphs</E> are separated by the empty <C>Par</C> or <C>P</C> element.
<Par/><E>Alternatives</E> for different output formats:

<Alt Only="LaTeX">This is &LaTeX; output.</Alt>
<Alt Not="LaTeX">This is other than &LaTeX; output, namely:
<Alt Only="HTML"><![CDATA[<b>HTML</b>]]></Alt>
<Alt Only="Text">Text</Alt> output.</Alt>

<P/>

B.6 Verbatim-like text (Source)

[2.1]

There are also three elements to typeset <Q>verbatim-like</Q> text.
<P/>
The first is a <E>Listing</E>:

<Listing Type="GAP code">
<![CDATA[Sieve := function(n)
  # Returns the primes less than n
  local l,p,i;
  l := [1..n]; Unbind(l[1]);
  p := 2;
  while p^2 <= n do
      if IsBound(l[p]) then
          i := 2 * p;
          while i <= n do Unbind(l[i]); i := i + p; od;
      fi;
      p := p + 1;
  od;
  return Compacted(l);
end;]]>
</Listing>

Here is a <E>Log</E> of a &GAP; session using this function:

<Log>
gap&gt; Sieve(100);
[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
  67, 71, 73, 79, 83, 89, 97 ]
gap&gt; Length(last);
25
</Log>

Here is a &GAP; <E>Example</E> session that is automatically tested:

<Example>
gap&gt; s := Size(CharacterTable("M"));
808017424794512875886459904961710757005754368000000000
gap&gt; s &lt; 10^53;                     
false
gap&gt; s &lt; 10^54;
true
</Example>

</Section>

B.7 Formulae (Source)

[2.2]

<Section><Heading>Formulae</Heading>

There are three types of formulae. <P/>
The first is the <E>normal math mode</E> of &LaTeX;: 

<Math>b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k</Math>. 

Then there are <E>displayed formulae</E>:
<Display>
   \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot
   \left(\sum_{j=1}^d y_j b_j \right) =
   \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k 
</Display>

If possible,  use the <C>Alt</C> element  to specify a better  readable text
version of such a formula as in the following example:<P/>

<Alt Not="Text,HTML"><Display>
   \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot
   \left(\sum_{j=1}^d y_j b_j \right) =
   \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k 
</Display></Alt>
<Alt Only="Text,HTML"><Verb>
         d                d                 d   
       -----            -----             -----  -----                 
        \                \                 \      \                    
 ==> (   )  x_i b_i )(    )  y_i b_i ) =    )  (   )  x_i y_j h_ijk ) b_k
        /                /                 /      /                    
       -----            -----             -----  -----                
       i = 1            i = 1             k = 1   i,j                
</Verb><P/></Alt>

For small formulae without <Q>difficult</Q> parts use the <C>M</C>
element: <M>b_i</M>,
<M>x^2</M>, <M>x^2 + 2x + 1 = (x + 1)^2</M>. Note that here whitespace 
matters for text (or HTML) output).<P/>

Here are two formulae containing less than characters which are special
characters for XML:
<M><![CDATA[a < b < c < d]]></M> and  <M>e &lt; f</M>.
</Section>

B.8 Crossreferencing (Source)

[2.3]

<Section Label="Cross"><Heading>Crossreferencing</Heading>

<Label Name="there"/>

In this section we demonstrate various references to parts of this
document. Here is a reference to this section: <Ref Sect="Cross"/>.
Here is a reference to chapter <Ref Chap="First"/>, to appendix
<Ref Appendix="Appendix"/>, and to subsection <Ref Subsect="Asub"/>. 
<P/>

We distinguish among others references 
 to functions (see <Ref Func="f"/>), 
 to methods with tricky name (see 
                 <Ref Meth="\^\{\}\[\]\&lt;\&amp;" Label="for nothing"/>),
 to operations (see <Ref Oper="MyOperation"/>), 
 to methods (see <Ref Meth="MyOperation" Label="First"/> or 
                 <Ref Meth="MyOperation" Label="for bla"/>), 
 to filters (see <Ref Filt="IsBla"/>), 
 to properties (see <Ref Prop="IsBlubb"/>),
 to attributes (see <Ref Attr="NumberBlobbs"/>), 
 to variables (<Ref Var="AllBlibbs"/>), 
 to families (see <Ref Fam="BlibbsFamily"/>),
 and to info classes (see <Ref InfoClass="InfoBlibbs"/>).
<P/>

There are also references to labels: see <Ref Text="here" Label="there"/>,
to other books: see <Ref Sect="syntaxXML" BookName="gapdoc"/> or
<Ref Oper="IsSubgroup" BookName="ref"/> in the &GAP; reference
manual.
<P/>

References to sections come in two styles: 
<Ref Chap="First" Style="Number"/>
or <Ref Chap="First" Style="Text"/>.
<P/>

Another type of cross referencing is bibliography. Here is a 
citation: <Cite Key="CR1" Where="(5.22)"/> is an interesting lemma.
<P/>

There are also URLs:<P/>

<URL>http://www.math.rwth-aachen.de/LDfM/</URL><P/>

Email addresses have a special element:
<Email>Frank.Luebeck@Math.RWTH-Aachen.De</Email>
<P/>

and Homepages another one:
<Homepage>http://www-groups.mcs.st-and.ac.uk/~neunhoef/</Homepage>
<P/>

One can generate index entries as follows (look up the words 
<Q>&TeX;-UserGroup</Q>, <Q>RWTH</Q>, and <Q>Aachen, Hauptbahnhof</Q>).
<Index Key="TeX-Usergroup">&TeX;-UserGroup</Index>
<Index Key="Aachen" Subkey="Hauptbahnhof">Aachen</Index>
<Index>RWTH</Index>

</Section>

B.9 Lists and Tables (Source)

[2.4]

<Section><Heading>Lists and Tables</Heading>

There are
<List>
 <Item>lists</Item>
 <Item>enumerations, and</Item>
 <Item>tables</Item>
</List>
or:
<Enum>
 <Item>lists</Item>
 <Item>enumerations, and</Item>
 <Item>tables</Item>
</Enum>
or with marks:
<List>
 <Mark>lists:</Mark><Item> not numbered</Item>
 <Mark>enumerations:</Mark><Item> numbered</Item>
 <Mark>tables:</Mark><Item> two-dimensional</Item>
</List>

Lists can also be nested:
<Enum>
 <Item>
   <Enum>
     <Item>first item of inner enumeration </Item>
     <Item>second item of inner enumeration </Item>
   </Enum>
 </Item>
 <Item>
   <List>
     <Item>first item of inner list </Item>
     <Item>second item of inner list </Item>
   </List>
  </Item>
</Enum>

Here is a <E>table</E>:

<Table Align="|r|c|l|">
 <Caption>Prices</Caption>
 <HorLine/>
  <Row>
   <Item>Object</Item><Item>Price</Item><Item>available</Item>
  </Row>
 <HorLine/>
 <HorLine/>
  <Row>
   <Item>Shoe</Item><Item>$1,00</Item><Item>there</Item>
  </Row>
 <HorLine/>
  <Row>
   <Item>Hat</Item><Item>$2,00</Item><Item>not there</Item>
  </Row>
 <HorLine/>
</Table>

</Section>

B.10 Entities and Special Characters (Source)

[2.5]

<Section><Heading>Entities and Special Characters</Heading>
<Label Name="TenBack"/>

[&see; <Ref Sect="Ten"/>]<P/>

Here is a table of special characters, the first two are special for
XML and must be typed in by entities in &GAPDoc; documents. The other 
characters are special for &LaTeX; but in &GAPDoc; they can be typed
directly. 

<Table Align="|c|c|c|c|c|c|c|c|c|c|c|c|c|" Label="charsInCDATA"> 
 <Caption>Special characters in character data</Caption>
 <HorLine/> <Row> 
  <Item><C>&amp;</C></Item>
  <Item><C>&lt;</C></Item>
  <Item><C>></C></Item>
  <Item><C>#</C></Item>
  <Item><C>$</C></Item>
  <Item><C>%</C></Item>
  <Item><C>~</C></Item>
  <Item><C>\</C></Item>   
  <Item><C>{</C></Item>
  <Item><C>}</C></Item>
  <Item><C>_</C></Item>
  <Item><C>^</C></Item>
  <Item><C>&nbsp;</C></Item>
 </Row> <HorLine/>
</Table>

And here are the predefined entities in &GAPDoc;:

<Table Align="|l|l|">
<Caption>Predefined Entities in the &GAPDoc; system</Caption>
<HorLine/>
<Row> <Item><C>&amp;GAP;</C></Item>       <Item>&GAP;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;GAPDoc;</C></Item>    <Item>&GAPDoc;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;TeX;</C></Item>       <Item>&TeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;LaTeX;</C></Item>     <Item>&LaTeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;BibTeX;</C></Item>    <Item>&BibTeX;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;MeatAxe;</C></Item>   <Item>&MeatAxe;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;XGAP;</C></Item>      <Item>&XGAP;</Item> </Row>
<HorLine/>
<Row> <Item><C>&amp;copyright;</C></Item> <Item>&copyright;</Item> </Row>
<HorLine/>
</Table>

And some more for mathematical symbols: 
&CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR;.

</Section>

</Chapter>

</Body>

B.11 Appendix (Source)

[A.]

<Appendix><Heading>An Appendix</Heading>

This is an appendix.
</Appendix>
Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/nocolorprompt.css0000644000175000017500000000031312026346064016263 0ustar billbill /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } GAPDoc-1.5.1/example/chapBib.txt0000644000175000017500000000037212026346063014731 0ustar billbill References [CR81] Curtis, C. W. and Reiner, I., Methods of Representation Theory, John Wiley & Sons, I, New York, Chichester, Brisbane, Toronto, Singapore (1981).  GAPDoc-1.5.1/example/chapA.html0000644000175000017500000000433612026346064014547 0ustar billbill GAP (GAPDoc Example) - Appendix A: An Appendix
Goto Chapter: Top 1 2 A B Bib Ind

A An Appendix

[→ B.11]

This is an appendix.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/examplebib.xml0000644000175000017500000000074712026346064015501 0ustar billbill Charles W.Curtis IrvingReiner Methods of Representation Theory John Wiley & Sons 1981 I
New York, Chichester, Brisbane, Toronto, Singapore
GAPDoc-1.5.1/example/example.tex0000644000175000017500000011073312026346064015021 0ustar billbill% generated by GAPDoc2LaTeX from XML source (Frank Luebeck) \documentclass[a4paper,11pt]{report} \usepackage{a4wide} \sloppy \pagestyle{myheadings} \usepackage{amssymb} \usepackage[latin1]{inputenc} \usepackage{makeidx} \makeindex \usepackage{color} \definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083} \definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179} \definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894} \definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894} \definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000} \definecolor{Black}{rgb}{0.0,0.0,0.0} \definecolor{linkColor}{rgb}{0.0,0.0,0.554} \definecolor{citeColor}{rgb}{0.0,0.0,0.554} \definecolor{fileColor}{rgb}{0.0,0.0,0.554} \definecolor{urlColor}{rgb}{0.0,0.0,0.554} \definecolor{promptColor}{rgb}{0.0,0.0,0.589} \definecolor{brkpromptColor}{rgb}{0.589,0.0,0.0} \definecolor{gapinputColor}{rgb}{0.589,0.0,0.0} \definecolor{gapoutputColor}{rgb}{0.0,0.0,0.0} %% for a long time these were red and blue by default, %% now black, but keep variables to overwrite \definecolor{FuncColor}{rgb}{0.0,0.0,0.0} %% strange name because of pdflatex bug: \definecolor{Chapter }{rgb}{0.0,0.0,0.0} \definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064} \usepackage{fancyvrb} \usepackage{mathptmx,helvet} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage[ pdftex=true, bookmarks=true, a4paper=true, pdftitle={Written with GAPDoc}, pdfcreator={LaTeX with hyperref package / GAPDoc}, colorlinks=true, backref=page, breaklinks=true, linkcolor=linkColor, citecolor=citeColor, filecolor=fileColor, urlcolor=urlColor, pdfpagemode={UseNone}, ]{hyperref} \newcommand{\maintitlesize}{\fontsize{50}{55}\selectfont} % write page numbers to a .pnr log file for online help \newwrite\pagenrlog \immediate\openout\pagenrlog =\jobname.pnr \immediate\write\pagenrlog{PAGENRS := [} \newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}} %% were never documented, give conflicts with some additional packages \newcommand{\GAP}{\textsf{GAP}} %% nicer description environments, allows long labels \usepackage{enumitem} \setdescription{style=nextline} %% depth of toc \setcounter{tocdepth}{1} %% command for ColorPrompt style examples \newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}} \newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}} \newcommand{\gapinput}[1]{\color{gapinputColor}{#1}} \begin{document} \logpage{[ 0, 0, 0 ]} \begin{titlepage} \mbox{}\vfill \begin{center}{\maintitlesize \textbf{A Complete Example ($\to$ \ref{One})\mbox{}}}\\ \vfill \hypersetup{pdftitle=A Complete Example ($\to$ \ref{One})} \markright{\scriptsize \mbox{}\hfill A Complete Example ($\to$ \ref{One}) \hfill\mbox{}} {\Huge \textbf{Every element shows up\mbox{}}}\\ \vfill {\Huge Version 1.5.1 \mbox{}}\\[1cm] {February 2012\mbox{}}\\[1cm] \mbox{}\\[2cm] {\Large \textbf{Frank L{\"u}beck \mbox{}}}\\ {\Large \textbf{ Max Neunh{\"o}ffer \mbox{}}}\\ \hypersetup{pdfauthor=Frank L{\"u}beck ; Max Neunh{\"o}ffer } \mbox{}\\[2cm] \begin{minipage}{12cm}\noindent If the subtitle ist not sufficient, this {\textless}TitleComment{\textgreater} element can be used for a slightly longer text on the front page. \end{minipage} \end{center}\vfill \mbox{}\\ {\mbox{}\\ \small \noindent \textbf{Frank L{\"u}beck } Email: \href{mailto://Frank.Luebeck@Math.RWTH-Aachen.De} {\texttt{Frank.Luebeck@Math.RWTH-Aachen.De}}}\\ {\mbox{}\\ \small \noindent \textbf{ Max Neunh{\"o}ffer } Email: \href{mailto://neunhoef at mcs.st-and.ac.uk} {\texttt{neunhoef at mcs.st-and.ac.uk}}}\\ \noindent \textbf{Address: }\begin{minipage}[t]{8cm}\noindent Lehrstuhl D f{\"u}r Mathematik\\ Templergraben 64\\ 52062 Aachen\\ (Germany) \end{minipage} \end{titlepage} \newpage\setcounter{page}{2} {\small \section*{Abstract} \logpage{[ 0, 0, 1 ]} This document tries to use all elements that exist in \textsf{GAPDoc}. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn \textsf{GAPDoc} quickly. \mbox{}}\\[1cm] {\small \section*{Copyright} \logpage{[ 0, 0, 2 ]} {\copyright} 2000-2012 by Frank L{\"u}beck and Max Neunh{\"o}ffer \mbox{}}\\[1cm] {\small \section*{Acknowledgements} \logpage{[ 0, 0, 3 ]} We thank Lehrstuhl D f{\"u}r Mathematik. \mbox{}}\\[1cm] {\small \section*{Colophon} \logpage{[ 0, 0, 4 ]} This is the Colophon page. \mbox{}}\\[1cm] \newpage \def\contentsname{Contents\logpage{[ 0, 0, 5 ]}} \tableofcontents \newpage Text before chapter \ref{First}. ($\to$ \ref{Two}) \chapter{\textcolor{Chapter }{Sectioning Elements}}\label{First} \logpage{[ 1, 0, 0 ]} \hyperdef{L}{X80E2AD7481DD69D9}{} { Text before the section \ref{FirstSect}. ($\to$ \ref{Two}) \label{ThreeBack} \section{\textcolor{Chapter }{Normal subsections}}\label{FirstSect} \logpage{[ 1, 1, 0 ]} \hyperdef{L}{X7818BD01870A269E}{} { [$\to$ \ref{Three}] \subsection{\textcolor{Chapter }{A subsection}}\label{Asub} \logpage{[ 1, 1, 1 ]} \hyperdef{L}{X7E193BD379F58A4C}{} { This is text in the first subsection. } \subsection{\textcolor{Chapter }{Another subsection}}\label{Another} \logpage{[ 1, 1, 2 ]} \hyperdef{L}{X79C2A0097ADE9776}{} { This is text in the second subsection. This subsection has a label, such that one can reference it. } } \section{\textcolor{Chapter }{ManSections}}\logpage{[ 1, 2, 0 ]} \hyperdef{L}{X7C2D89087EA8BC84}{} { \label{FourBack} [$\to$ \ref{Four}] \subsection{\textcolor{Chapter }{f}} \logpage{[ 1, 2, 1 ]}\nobreak \hyperdef{L}{X7FA1D0937FA1D093}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{f({\mdseries\slshape x[, y]})\index{f@\texttt{f}} \label{f} }\hfill{\scriptsize (function)}}\\ \textbf{\indent Returns:\ } an element in \texttt{IsBlubb} (\ref{IsBlubb}) or \texttt{fail}. This function calculates something. } \subsection{\textcolor{Chapter }{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{92}}\texttt{\symbol{123}}\texttt{\symbol{92}}\texttt{\symbol{125}}\texttt{\symbol{92}}[\texttt{\symbol{92}}]\texttt{\symbol{92}}{\textless}\texttt{\symbol{92}}\& (for nothing)}} \logpage{[ 1, 2, 2 ]}\nobreak \hyperdef{L}{X822B5C487B29E799}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{92}}\texttt{\symbol{123}}\texttt{\symbol{92}}\texttt{\symbol{125}}\texttt{\symbol{92}}[\texttt{\symbol{92}}]\texttt{\symbol{92}}{\textless}\texttt{\symbol{92}}\&({\mdseries\slshape c})\index{^{}[]<&@\texttt{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{92}}\texttt{\symbol{123}}\texttt{\symbol{92}}\texttt{\symbol{125}}\texttt{\symbol{92}}[\texttt{\symbol{92}}]\texttt{\symbol{92}}{\textless}\texttt{\symbol{92}}\&}!for nothing} \label{^{}[]<&:for nothing} }\hfill{\scriptsize (method)}}\\ This method is for an operation with a tricky name. } \subsection{\textcolor{Chapter }{MyOperation}} \logpage{[ 1, 2, 3 ]}\nobreak \hyperdef{L}{X7D33C2597988F481}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MyOperation({\mdseries\slshape x})\index{MyOperation@\texttt{MyOperation}} \label{MyOperation} }\hfill{\scriptsize (operation)}}\\ The operation \texttt{MyOperation} operates on \mbox{\texttt{\mdseries\slshape x}}. } \subsection{\textcolor{Chapter }{MyOperation (First)}} \logpage{[ 1, 2, 4 ]}\nobreak \hyperdef{L}{X783DCD4E826289D4}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MyOperation({\mdseries\slshape x})\index{MyOperation@\texttt{MyOperation}!First} \label{MyOperation:First} }\hfill{\scriptsize (method)}}\\ This method calculates something by the generic method. } \subsection{\textcolor{Chapter }{MyOperation (for bla)}} \logpage{[ 1, 2, 5 ]}\nobreak \hyperdef{L}{X7A5F4A287D06988C}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{MyOperation({\mdseries\slshape x[, good{\textunderscore}hint]})\index{MyOperation@\texttt{MyOperation}!for bla} \label{MyOperation:for bla} }\hfill{\scriptsize (method)}}\\ This is the super-fast method for the operation \texttt{MyOperation} (\ref{MyOperation}) if the argument \mbox{\texttt{\mdseries\slshape x}} is in the representation \texttt{IsBla} (\ref{IsBla}). It will become even faster if the optional argument \mbox{\texttt{\mdseries\slshape good{\textunderscore}hint}} is given. } \subsection{\textcolor{Chapter }{IsBla}} \logpage{[ 1, 2, 6 ]}\nobreak \hyperdef{L}{X82954B687D2DF3C2}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsBla({\mdseries\slshape obj})\index{IsBla@\texttt{IsBla}} \label{IsBla} }\hfill{\scriptsize (representation)}}\\ For objects in this representation there is a super-fast method (see \texttt{MyOperation} (\ref{MyOperation:for bla})) for the operation \texttt{MyOperation} (\ref{MyOperation}). } \subsection{\textcolor{Chapter }{IsBlubb}} \logpage{[ 1, 2, 7 ]}\nobreak \hyperdef{L}{X80C364DD7C919CCE}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{IsBlubb({\mdseries\slshape obj})\index{IsBlubb@\texttt{IsBlubb}} \label{IsBlubb} }\hfill{\scriptsize (property)}}\\ A property. } \subsection{\textcolor{Chapter }{NumberBlobbs}} \logpage{[ 1, 2, 8 ]}\nobreak \hyperdef{L}{X8052A45E7F9F054C}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{NumberBlobbs({\mdseries\slshape obj})\index{NumberBlobbs@\texttt{NumberBlobbs}} \label{NumberBlobbs} }\hfill{\scriptsize (attribute)}}\\ An attribute. Number of blobbs. } \subsection{\textcolor{Chapter }{AllBlibbs}} \logpage{[ 1, 2, 9 ]}\nobreak \hyperdef{L}{X7C00E05A7DDEF003}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{AllBlibbs\index{AllBlibbs@\texttt{AllBlibbs}} \label{AllBlibbs} }\hfill{\scriptsize (global variable)}}\\ This global variable holds a list of all blibbs. } \subsection{\textcolor{Chapter }{BlibbsFamily}} \logpage{[ 1, 2, 10 ]}\nobreak \hyperdef{L}{X7CBC935A8142E374}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{BlibbsFamily\index{BlibbsFamily@\texttt{BlibbsFamily}} \label{BlibbsFamily} }\hfill{\scriptsize (family)}}\\ Family of all blibbs. } \subsection{\textcolor{Chapter }{InfoBlibbs}} \logpage{[ 1, 2, 11 ]}\nobreak \hyperdef{L}{X84D7D77378AD030A}{} {\noindent\textcolor{FuncColor}{$\triangleright$\ \ \texttt{InfoBlibbs\index{InfoBlibbs@\texttt{InfoBlibbs}} \label{InfoBlibbs} }\hfill{\scriptsize (info class)}}\\ This info class is used throughout the library of blibbs. } } } \chapter{\textcolor{Chapter }{Other Markup}}\logpage{[ 2, 0, 0 ]} \hyperdef{L}{X82793A7E7A3F2A54}{} { \label{FiveBack} \section{\textcolor{Chapter }{Various types of text}}\logpage{[ 2, 1, 0 ]} \hyperdef{L}{X7A480B9A795EF264}{} { [$\to$ \ref{Five}] In this section we present examples for all the various types of text that are possible in \textsf{GAPDoc}: \begin{itemize} \item \emph{This} is \emph{emphasized}. \item \emph{Keywords} are typeset like \texttt{this} and \texttt{that}. \item \emph{Arguments} of functions have an element. They look like this: \mbox{\texttt{\mdseries\slshape x}} and \mbox{\texttt{\mdseries\slshape y}}. \item \emph{Code} can be written with the Code element: \texttt{if x = y then Print("Equal"); fi;} or \texttt{while true do Print("Hello"); od;}. \item \emph{Filenames} have their own element: \texttt{/usr/local/ca/gap4r2} or \texttt{pkg/xgap/doc}. \item \emph{Buttons}, \emph{menus}, \emph{menu entries}, and such things are also supported: \textsc{OK} or \textsc{Cancel}. \item \emph{Packages} are typeset like this: \textsf{Small Groups Library} \item \emph{Quoted} text: ``This is a text in quotes.'' \end{itemize} \emph{Paragraphs} are separated by the empty \texttt{Par} or \texttt{P} element. \emph{Alternatives} for different output formats: This is {\LaTeX} output. \label{SixBack} There are also three elements to typeset ``verbatim-like'' text. ($\to$ \ref{Six}) The first is a \emph{Listing}: \begin{Verbatim}[fontsize=\small,frame=single,label=GAP code] Sieve := function(n) # Returns the primes less than n local l,p,i; l := [1..n]; Unbind(l[1]); p := 2; while p^2 <= n do if IsBound(l[p]) then i := 2 * p; while i <= n do Unbind(l[i]); i := i + p; od; fi; p := p + 1; od; return Compacted(l); end; \end{Verbatim} Here is a \emph{Log} of a \textsf{GAP} session using this function: \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@Sieve(100);| [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ] !gapprompt@gap>| !gapinput@Length(last);| 25 \end{Verbatim} Here is a \textsf{GAP} \emph{Example} session that is automatically tested: \begin{Verbatim}[commandchars=!@|,fontsize=\small,frame=single,label=Example] !gapprompt@gap>| !gapinput@s := Size(CharacterTable("M"));| 808017424794512875886459904961710757005754368000000000 !gapprompt@gap>| !gapinput@s < 10^53; | false !gapprompt@gap>| !gapinput@s < 10^54;| true \end{Verbatim} } \section{\textcolor{Chapter }{Formulae}}\logpage{[ 2, 2, 0 ]} \hyperdef{L}{X7AA5BF0279938BE0}{} { \label{SevenBack} [$\to$ \ref{Seven}] There are three types of formulae. The first is the \emph{normal math mode} of {\LaTeX}: $b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k$. Then there are \emph{displayed formulae}: \[ \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k \] If possible, use the \texttt{Alt} element to specify a better readable text version of such a formula as in the following example: \[ \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k \] For small formulae without ``difficult'' parts use the \texttt{M} element: $b_i$, $x^2$, $x^2 + 2x + 1 = (x + 1)^2$. Note that here whitespace matters for text (or HTML) output. Here are two formulae containing less than characters which are special characters for XML: $a < b < c < d$ and $e < f$. Using the \texttt{Mode} attribute of a \texttt{Display} element formulae like \[a \longrightarrow a \bmod m\prime\] can also be displayed nicely in text and HTML output. } \section{\textcolor{Chapter }{Crossreferencing}}\label{Cross} \logpage{[ 2, 3, 0 ]} \hyperdef{L}{X833C410D85CF96A4}{} { \label{EightBack} [$\to$ \ref{Eight}] \label{there} In this section we demonstrate various references to parts of this document. Here is a reference to this section: \ref{Cross}. Here is a reference to chapter \ref{First}, to appendix \ref{Appendix}, and to subsection \ref{Asub}. We distinguish among others references to functions (see \texttt{f} (\ref{f})), to methods with tricky name (see \texttt{\texttt{\symbol{92}}\texttt{\symbol{94}}\texttt{\symbol{92}}\texttt{\symbol{123}}\texttt{\symbol{92}}\texttt{\symbol{125}}\texttt{\symbol{92}}[\texttt{\symbol{92}}]\texttt{\symbol{92}}{\textless}\texttt{\symbol{92}}\&} (\ref{^{}[]<&:for nothing})), to operations (see \texttt{MyOperation} (\ref{MyOperation})), to methods (see \texttt{MyOperation} (\ref{MyOperation:First}) or \texttt{MyOperation} (\ref{MyOperation:for bla})), to filters (see \texttt{IsBla} (\ref{IsBla})), to properties (see \texttt{IsBlubb} (\ref{IsBlubb})), to attributes (see \texttt{NumberBlobbs} (\ref{NumberBlobbs})), to variables (\texttt{AllBlibbs} (\ref{AllBlibbs})), to families (see \texttt{BlibbsFamily} (\ref{BlibbsFamily})), and to info classes (see \texttt{InfoBlibbs} (\ref{InfoBlibbs})). There are also references to labels: see \ref{there}, to other books: see (\textbf{GAPDoc: What is a DTD?}) or \texttt{IsSubgroup} (\textbf{Reference: IsSubgroup}) in the \textsf{GAP} reference manual. References to sections come in two styles: \ref{First} or \hyperref[First]{`Sectioning Elements'}. Another type of cross referencing is bibliography. Here is a citation: \cite[(5.22)]{CR1} is an interesting lemma. There are also URLs: \href{http://www.math.rwth-aachen.de/} {\texttt{http://www.math.rwth-aachen.de/}} Email addresses have a special element: \href{mailto://Frank.Luebeck@Math.RWTH-Aachen.De} {\texttt{Frank.Luebeck@Math.RWTH-Aachen.De}} and Homepages another one: \href{http://www-groups.mcs.st-and.ac.uk/~neunhoef/} {\texttt{http://www-groups.mcs.st-and.ac.uk/\texttt{\symbol{126}}neunhoef/}} And here is a link to the \href{http://www.math.rwth-aachen.de/~Frank.Luebeck/gap/EDIM/index.html#ARCHS} {\textsf{EDIM} archives}. One can generate index entries as follows (look up the words ``{\TeX}-UserGroup'', ``RWTH'', ``Aachen, Hauptbahnhof'', and ``\textsf{GAP}, \textsf{GAPDoc}''). \index{TeX-Usergroup@{\TeX}-UserGroup} \index{Aachen@Aachen!Hauptbahnhof} \index{GAP@\textsf{GAP}!\textsf{GAPDoc}} \index{RWTH} } \section{\textcolor{Chapter }{Lists and Tables}}\logpage{[ 2, 4, 0 ]} \hyperdef{L}{X7F10E951789D6EDF}{} { \label{NineBack} [$\to$ \ref{Nine}] There are \begin{itemize} \item lists \item enumerations, and \item tables \end{itemize} or: \begin{enumerate} \item lists \item enumerations, and \item tables \end{enumerate} or with marks: \begin{description} \item[{lists:}] not numbered \item[{enumerations:}] numbered \item[{tables:}] two-dimensional \end{description} Lists can also be nested: \begin{enumerate} \item \begin{enumerate} \item first item of inner enumeration \item second item of inner enumeration \end{enumerate} \item \begin{itemize} \item first item of inner list \item second item of inner list \end{itemize} \end{enumerate} Here is a \emph{table}: \begin{center} \begin{tabular}{|r|c|l|}\hline Object& Price& available\\ \hline \hline Shoe& \$1,00& there\\ \hline Hat& \$2,00& not there\\ \hline \end{tabular}\\[2mm] \textbf{Table: }Prices\end{center} } \section{\textcolor{Chapter }{Entities and Special Characters}}\logpage{[ 2, 5, 0 ]} \hyperdef{L}{X83A355E68485D6D1}{} { \label{TenBack} [$\to$ \ref{Ten}] Here is a table of special characters, the first two are special for XML and must be typed in by entities in \textsf{GAPDoc} documents. The other characters are special for {\LaTeX} but in \textsf{GAPDoc} they can be typed directly. \mbox{}\label{charsInCDATA}\begin{center} \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|}\hline \texttt{\&}& \texttt{{\textless}}& \texttt{{\textgreater}}& \texttt{\#}& \texttt{\$}& \texttt{\%}& \texttt{\texttt{\symbol{126}}}& \texttt{\texttt{\symbol{92}}}& \texttt{\texttt{\symbol{123}}}& \texttt{\texttt{\symbol{125}}}& \texttt{{\textunderscore}}& \texttt{\texttt{\symbol{94}}}& \texttt{{\nobreakspace}}\\ \hline \end{tabular}\\[2mm] \textbf{Table: }Special characters in character data\end{center} And here are the predefined entities in \textsf{GAPDoc}: \begin{center} \begin{tabular}{|l|l|}\hline \texttt{\&GAP;}& \textsf{GAP}\\ \hline \texttt{\&GAPDoc;}& \textsf{GAPDoc}\\ \hline \texttt{\&TeX;}& {\TeX}\\ \hline \texttt{\&LaTeX;}& {\LaTeX}\\ \hline \texttt{\&BibTeX;}& Bib{\TeX}\\ \hline \texttt{\&MeatAxe;}& \textsf{MeatAxe}\\ \hline \texttt{\&XGAP;}& \textsf{XGAP}\\ \hline \texttt{\©right;}& {\copyright}\\ \hline \end{tabular}\\[2mm] \textbf{Table: }Predefined Entities in the \textsf{GAPDoc} system\end{center} And some more for mathematical symbols: {\ensuremath{\mathbb C}}, {\ensuremath{\mathbb Z}}, {\ensuremath{\mathbb N}}, {\ensuremath{\mathbb P}}, {\ensuremath{\mathbb Q}}, {\ensuremath{\mathbb H}}, {\ensuremath{\mathbb R}}. } } \appendix \chapter{\textcolor{Chapter }{An Appendix}}\label{Appendix} \logpage{[ "A", 0, 0 ]} \hyperdef{L}{X7B53252784137533}{} { \label{ElevenBack} [$\to$ \ref{Eleven}] This is an appendix. } \chapter{\textcolor{Chapter }{The Source}}\label{Source} \logpage{[ "B", 0, 0 ]} \hyperdef{L}{X7B4F7623844A7E32}{} { \section{\textcolor{Chapter }{TitlePage (Source)}}\label{One} \logpage{[ "B", 1, 0 ]} \hyperdef{L}{X7CFACB517D259F59}{} { \begin{Verbatim}[fontsize=\small,frame=single,label=] A Complete Example (&see; <Ref Sect="One"/>) Every element shows up Version 1.5.1 If the subtitle ist not sufficient, this <TitleComment> element can be used for a slightly longer text on the front page. Frank Lbeck Frank.Luebeck@Math.RWTH-Aachen.De Max Neunhffer neunhoef at mcs.st-and.ac.uk September 2011
Lehrstuhl D fr Mathematik
Templergraben 64
52062 Aachen
(Germany)
This document tries to use all elements that exist in &GAPDoc;. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn &GAPDoc; quickly. ©right; 2000-2011 by Frank Lbeck and Max Neunhffer We thank Lehrstuhl D fr Mathematik. This is the Colophon page.
\end{Verbatim} } \section{\textcolor{Chapter }{Before First Chapter (Source)}}\label{Two} \logpage{[ "B", 2, 0 ]} \hyperdef{L}{X7A4D1C8680D81F2A}{} { \begin{Verbatim}[fontsize=\small,frame=single,label=] Text before chapter . Sectioning Elements Text before the section . \end{Verbatim} } \section{\textcolor{Chapter }{First Chapter (Source)}}\label{Three} \logpage{[ "B", 3, 0 ]} \hyperdef{L}{X78308EBC7C2FF426}{} { [\ref{ThreeBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
Normal subsections A subsection This is text in the first subsection. Another subsection This is text in the second subsection. This subsection has a label, such that one can reference it.
\end{Verbatim} } \section{\textcolor{Chapter }{ManSections (Source)}}\label{Four} \logpage{[ "B", 4, 0 ]} \hyperdef{L}{X814E3376826E1DB0}{} { [\ref{FourBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
ManSections an element in or fail. This function calculates something. This method is for an operation with a tricky name. The operation operates on x. This method calculates something by the generic method. This is the super-fast method for the operation if the argument x is in the representation . It will become even faster if the optional argument good_hint is given. For objects in this representation there is a super-fast method (see ) for the operation . A property. An attribute. Number of blobbs. This global variable holds a list of all blibbs. Family of all blibbs. This info class is used throughout the library of blibbs.
\end{Verbatim} } \section{\textcolor{Chapter }{Various Types of Text (Source)}}\label{Five} \logpage{[ "B", 5, 0 ]} \hyperdef{L}{X82A731CA83FB9ADD}{} { [\ref{FiveBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=] Other Markup
Various types of text In this section we present examples for all the various types of text that are possible in &GAPDoc;: This is emphasized. Keywords are typeset like this and that. Arguments of functions have an element. They look like this: x and y. Code can be written with the Code element: if x = y then Print("Equal"); fi; or while true do Print("Hello"); od;. Filenames have their own element: /usr/local/ca/gap4r2 or pkg/xgap/doc. Buttons, menus, menu entries, and such things are also supported: OK or . Packages are typeset like this: Small Groups Library Quoted text: This is a text in quotes. Paragraphs are separated by the empty Par or P element. Alternatives for different output formats: This is &LaTeX; output. This is other than &LaTeX; output, namely: HTML]]> Text output.

\end{Verbatim} } \section{\textcolor{Chapter }{Verbatim-like text (Source)}}\label{Six} \logpage{[ "B", 6, 0 ]} \hyperdef{L}{X824BD70087820CF0}{} { [\ref{SixBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=] There are also three elements to typeset verbatim-like text.

The first is a Listing:

Here is a Log of a &GAP; session using this function: gap> Sieve(100); [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ] gap> Length(last); 25 Here is a &GAP; Example session that is automatically tested: gap> s := Size(CharacterTable("M")); 808017424794512875886459904961710757005754368000000000 gap> s < 10^53; false gap> s < 10^54; true
\end{Verbatim} } \section{\textcolor{Chapter }{Formulae (Source)}}\label{Seven} \logpage{[ "B", 7, 0 ]} \hyperdef{L}{X8516FAA07A95BBB5}{} { [\ref{SevenBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
Formulae There are three types of formulae.

The first is the normal math mode of &LaTeX;: b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k. Then there are displayed formulae: \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k If possible, use the Alt element to specify a better readable text version of such a formula as in the following example:

\Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k d d d ----- ----- ----- ----- \ \ \ \ ==> ( ) x_i b_i )( ) y_i b_i ) = ) ( ) x_i y_j h_ijk ) b_k / / / / ----- ----- ----- ----- i = 1 i = 1 k = 1 i,j

For small formulae without difficult parts use the M element: b_i, x^2, x^2 + 2x + 1 = (x + 1)^2. Note that here whitespace matters for text (or HTML) output).

Here are two formulae containing less than characters which are special characters for XML: and e < f.

\end{Verbatim} } \section{\textcolor{Chapter }{Crossreferencing (Source)}}\label{Eight} \logpage{[ "B", 8, 0 ]} \hyperdef{L}{X7D19CF4782309661}{} { [\ref{EightBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
Crossreferencing
\end{Verbatim} } \section{\textcolor{Chapter }{Lists and Tables (Source)}}\label{Nine} \logpage{[ "B", 9, 0 ]} \hyperdef{L}{X7BB822947F626E1A}{} { [\ref{NineBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
Lists and Tables There are lists enumerations, and tables or: lists enumerations, and tables or with marks: lists: not numbered enumerations: numbered tables: two-dimensional Lists can also be nested: first item of inner enumeration second item of inner enumeration first item of inner list second item of inner list Here is a table: ObjectPriceavailable Shoe$1,00there Hat$2,00not there
Prices
\end{Verbatim} } \section{\textcolor{Chapter }{Entities and Special Characters (Source)}}\label{Ten} \logpage{[ "B", 10, 0 ]} \hyperdef{L}{X80B478CD7E584F6F}{} { [\ref{TenBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=]
Entities and Special Characters
\end{Verbatim} } \section{\textcolor{Chapter }{Appendix (Source)}}\label{Eleven} \logpage{[ "B", 11, 0 ]} \hyperdef{L}{X85E7E6BA81367928}{} { [\ref{ElevenBack}] \begin{Verbatim}[fontsize=\small,frame=single,label=GAPDoc source] An Appendix This is an appendix. \end{Verbatim} } } \def\bibname{References\logpage{[ "Bib", 0, 0 ]} \hyperdef{L}{X7A6F98FD85F02BFE}{} } \bibliographystyle{alpha} \bibliography{examplebib.xml} \addcontentsline{toc}{chapter}{References} \def\indexname{Index\logpage{[ "Ind", 0, 0 ]} \hyperdef{L}{X83A0356F839C696F}{} } \cleardoublepage \phantomsection \addcontentsline{toc}{chapter}{Index} \printindex \newpage \immediate\write\pagenrlog{["End"], \arabic{page}];} \immediate\closeout\pagenrlog \end{document} GAPDoc-1.5.1/example/manual.js0000644000175000017500000001003412026346064014450 0ustar billbill/* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { document.writeln(''); document.writeln(''); } } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } GAPDoc-1.5.1/example/chap1.html0000644000175000017500000002364712026346064014535 0ustar billbill GAP (GAPDoc Example) - Chapter 1: Sectioning Elements
Goto Chapter: Top 1 2 A B Bib Ind

1 Sectioning Elements

Text before the section 1.1. (→ B.2)

1.1 Normal subsections

[→ B.3]

1.1-1 A subsection

This is text in the first subsection.

1.1-2 Another subsection

This is text in the second subsection. This subsection has a label, such that one can reference it.

1.2 ManSections

[→ B.4]

1.2-1 f
‣ f( x[, y] )( function )

Returns: an element in IsBlubb (1.2-7) or fail.

This function calculates something.

1.2-2 \^\{\}\[\]\<\&
‣ \^\{\}\[\]\<\&( c )( method )

This method is for an operation with a tricky name.

1.2-3 MyOperation
‣ MyOperation( x )( operation )

The operation MyOperation operates on x.

1.2-4 MyOperation
‣ MyOperation( x )( method )

This method calculates something by the generic method.

1.2-5 MyOperation
‣ MyOperation( x[, good_hint] )( method )

This is the super-fast method for the operation MyOperation (1.2-3) if the argument x is in the representation IsBla (1.2-6). It will become even faster if the optional argument good_hint is given.

1.2-6 IsBla
‣ IsBla( obj )( representation )

For objects in this representation there is a super-fast method (see MyOperation (1.2-5)) for the operation MyOperation (1.2-3).

1.2-7 IsBlubb
‣ IsBlubb( obj )( property )

A property.

1.2-8 NumberBlobbs
‣ NumberBlobbs( obj )( attribute )

An attribute. Number of blobbs.

1.2-9 AllBlibbs
‣ AllBlibbs( global variable )

This global variable holds a list of all blibbs.

1.2-10 BlibbsFamily
‣ BlibbsFamily( family )

Family of all blibbs.

1.2-11 InfoBlibbs
‣ InfoBlibbs( info class )

This info class is used throughout the library of blibbs.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/example.out0000644000175000017500000000301712026346064015024 0ustar billbill\BOOKMARK [0][-]{chapter.1}{Sectioning Elements}{}% 1 \BOOKMARK [1][-]{section.1.1}{Normal subsections}{chapter.1}% 2 \BOOKMARK [1][-]{section.1.2}{ManSections}{chapter.1}% 3 \BOOKMARK [0][-]{chapter.2}{Other Markup}{}% 4 \BOOKMARK [1][-]{section.2.1}{Various types of text}{chapter.2}% 5 \BOOKMARK [1][-]{section.2.2}{Formulae}{chapter.2}% 6 \BOOKMARK [1][-]{section.2.3}{Crossreferencing}{chapter.2}% 7 \BOOKMARK [1][-]{section.2.4}{Lists and Tables}{chapter.2}% 8 \BOOKMARK [1][-]{section.2.5}{Entities and Special Characters}{chapter.2}% 9 \BOOKMARK [0][-]{appendix.A}{An Appendix}{}% 10 \BOOKMARK [0][-]{appendix.B}{The Source}{}% 11 \BOOKMARK [1][-]{section.B.1}{TitlePage \(Source\)}{appendix.B}% 12 \BOOKMARK [1][-]{section.B.2}{Before First Chapter \(Source\)}{appendix.B}% 13 \BOOKMARK [1][-]{section.B.3}{First Chapter \(Source\)}{appendix.B}% 14 \BOOKMARK [1][-]{section.B.4}{ManSections \(Source\)}{appendix.B}% 15 \BOOKMARK [1][-]{section.B.5}{Various Types of Text \(Source\)}{appendix.B}% 16 \BOOKMARK [1][-]{section.B.6}{Verbatim-like text \(Source\)}{appendix.B}% 17 \BOOKMARK [1][-]{section.B.7}{Formulae \(Source\)}{appendix.B}% 18 \BOOKMARK [1][-]{section.B.8}{Crossreferencing \(Source\)}{appendix.B}% 19 \BOOKMARK [1][-]{section.B.9}{Lists and Tables \(Source\)}{appendix.B}% 20 \BOOKMARK [1][-]{section.B.10}{Entities and Special Characters \(Source\)}{appendix.B}% 21 \BOOKMARK [1][-]{section.B.11}{Appendix \(Source\)}{appendix.B}% 22 \BOOKMARK [0][-]{appendix*.6}{References}{}% 23 \BOOKMARK [0][-]{section*.7}{Index}{}% 24 GAPDoc-1.5.1/example/chap2_mj.html0000644000175000017500000004055012026346064015214 0ustar billbill GAP (GAPDoc Example) - Chapter 2: Other Markup
Goto Chapter: Top 1 2 A B Bib Ind

2 Other Markup

2.1 Various types of text

[→ B.5]

In this section we present examples for all the various types of text that are possible in GAPDoc:

  • This is emphasized.

  • Keywords are typeset like this and that.

  • Arguments of functions have an element. They look like this: x and y.

  • Code can be written with the Code element: if x = y then Print("Equal"); fi; or while true do Print("Hello"); od;.

  • Filenames have their own element: /usr/local/ca/gap4r2 or pkg/xgap/doc.

  • Buttons, menus, menu entries, and such things are also supported: OK or Cancel.

  • Packages are typeset like this: Small Groups Library

  • Quoted text: "This is a text in quotes."

Paragraphs are separated by the empty Par or P element.

Alternatives for different output formats: This is other than LaTeX output, namely: HTML output.

There are also three elements to typeset "verbatim-like" text. (→ B.6)

The first is a Listing:

Sieve := function(n)
  # Returns the primes less than n
  local l,p,i;
  l := [1..n]; Unbind(l[1]);
  p := 2;
  while p^2 <= n do
      if IsBound(l[p]) then
          i := 2 * p;
          while i <= n do Unbind(l[i]); i := i + p; od;
      fi;
      p := p + 1;
  od;
  return Compacted(l);
end;

Here is a Log of a GAP session using this function:

gap> Sieve(100);
[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
  67, 71, 73, 79, 83, 89, 97 ]
gap> Length(last);
25

Here is a GAP Example session that is automatically tested:

gap> s := Size(CharacterTable("M"));
808017424794512875886459904961710757005754368000000000
gap> s < 10^53;                     
false
gap> s < 10^54;
true

2.2 Formulae

[→ B.7]

There are three types of formulae.

The first is the normal math mode of LaTeX: \(b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k\). Then there are displayed formulae:

\[ \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k \]

If possible, use the Alt element to specify a better readable text version of such a formula as in the following example:


         d                d                 d   
       -----            -----             -----  -----                 
        \                \                 \      \                    
 ==> (   )  x_i b_i )(    )  y_j b_j ) =    )  (   )  x_i y_j h_ijk ) b_k
        /                /                 /      /                    
       -----            -----             -----  -----                
       i = 1            j = 1             k = 1   i,j                

For small formulae without "difficult" parts use the M element: \(b_i\), \(x^2\), \(x^2 + 2x + 1 = (x + 1)^2\). Note that here whitespace matters for text (or HTML) output.

Here are two formulae containing less than characters which are special characters for XML: \(a < b < c < d\) and \(e < f\).

Using the Mode attribute of a Display element formulae like

\[a \longrightarrow a \bmod m\prime\]

can also be displayed nicely in text and HTML output.

2.3 Crossreferencing

[→ B.8]

In this section we demonstrate various references to parts of this document. Here is a reference to this section: 2.3. Here is a reference to chapter 1, to appendix A, and to subsection 1.1-1.

We distinguish among others references to functions (see f (1.2-1)), to methods with tricky name (see \^\{\}\[\]\<\& (1.2-2)), to operations (see MyOperation (1.2-3)), to methods (see MyOperation (1.2-4) or MyOperation (1.2-5)), to filters (see IsBla (1.2-6)), to properties (see IsBlubb (1.2-7)), to attributes (see NumberBlobbs (1.2-8)), to variables (AllBlibbs (1.2-9)), to families (see BlibbsFamily (1.2-10)), and to info classes (see InfoBlibbs (1.2-11)).

There are also references to labels: see here, to other books: see GAPDoc: What is a DTD? or IsSubgroup (Reference: IsSubgroup) in the GAP reference manual.

References to sections come in two styles: 1 or Sectioning Elements.

Another type of cross referencing is bibliography. Here is a citation: [CR81, (5.22)] is an interesting lemma.

There are also URLs:

http://www.math.rwth-aachen.de/

Email addresses have a special element: Frank.Luebeck@Math.RWTH-Aachen.De

and Homepages another one: http://www-groups.mcs.st-and.ac.uk/~neunhoef/

And here is a link to the EDIM archives.

One can generate index entries as follows (look up the words "TeX-UserGroup", "RWTH", "Aachen, Hauptbahnhof", and "GAP, GAPDoc").

2.4 Lists and Tables

[→ B.9]

There are

  • lists

  • enumerations, and

  • tables

or:

  1. lists

  2. enumerations, and

  3. tables

or with marks:

lists:

not numbered

enumerations:

numbered

tables:

two-dimensional

Lists can also be nested:

    1. first item of inner enumeration

    2. second item of inner enumeration

    • first item of inner list

    • second item of inner list

Here is a table:

Table: Prices
Object Price available
Shoe $1,00 there
Hat $2,00 not there

 


2.5 Entities and Special Characters

[→ B.10]

Here is a table of special characters, the first two are special for XML and must be typed in by entities in GAPDoc documents. The other characters are special for LaTeX but in GAPDoc they can be typed directly.

Table: Special characters in character data
& < > # $ % ~ \ { } _ ^  

 


And here are the predefined entities in GAPDoc:

Table: Predefined Entities in the GAPDoc system
&GAP; GAP
&GAPDoc; GAPDoc
&TeX; TeX
&LaTeX; LaTeX
&BibTeX; BibTeX
&MeatAxe; MeatAxe
&XGAP; XGAP
&copyright; ©

 


And some more for mathematical symbols: ℂ, ℤ, ℕ, ℙ, ℚ, ℍ, ℝ.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/toggless.css0000644000175000017500000000167212026346064015206 0ustar billbill/* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } GAPDoc-1.5.1/example/lefttoc.css0000644000175000017500000000047412026346064015016 0ustar billbill/* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } GAPDoc-1.5.1/example/chap2.html0000644000175000017500000004001612026346064014523 0ustar billbill GAP (GAPDoc Example) - Chapter 2: Other Markup
Goto Chapter: Top 1 2 A B Bib Ind

2 Other Markup

2.1 Various types of text

[→ B.5]

In this section we present examples for all the various types of text that are possible in GAPDoc:

  • This is emphasized.

  • Keywords are typeset like this and that.

  • Arguments of functions have an element. They look like this: x and y.

  • Code can be written with the Code element: if x = y then Print("Equal"); fi; or while true do Print("Hello"); od;.

  • Filenames have their own element: /usr/local/ca/gap4r2 or pkg/xgap/doc.

  • Buttons, menus, menu entries, and such things are also supported: OK or Cancel.

  • Packages are typeset like this: Small Groups Library

  • Quoted text: "This is a text in quotes."

Paragraphs are separated by the empty Par or P element.

Alternatives for different output formats: This is other than LaTeX output, namely: HTML output.

There are also three elements to typeset "verbatim-like" text. (→ B.6)

The first is a Listing:

Sieve := function(n)
  # Returns the primes less than n
  local l,p,i;
  l := [1..n]; Unbind(l[1]);
  p := 2;
  while p^2 <= n do
      if IsBound(l[p]) then
          i := 2 * p;
          while i <= n do Unbind(l[i]); i := i + p; od;
      fi;
      p := p + 1;
  od;
  return Compacted(l);
end;

Here is a Log of a GAP session using this function:

gap> Sieve(100);
[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
  67, 71, 73, 79, 83, 89, 97 ]
gap> Length(last);
25

Here is a GAP Example session that is automatically tested:

gap> s := Size(CharacterTable("M"));
808017424794512875886459904961710757005754368000000000
gap> s < 10^53;                     
false
gap> s < 10^54;
true

2.2 Formulae

[→ B.7]

There are three types of formulae.

The first is the normal math mode of LaTeX: b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k. Then there are displayed formulae:

\Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot \left(\sum_{j=1}^d y_j b_j \right) = \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k

If possible, use the Alt element to specify a better readable text version of such a formula as in the following example:


         d                d                 d   
       -----            -----             -----  -----                 
        \                \                 \      \                    
 ==> (   )  x_i b_i )(    )  y_j b_j ) =    )  (   )  x_i y_j h_ijk ) b_k
        /                /                 /      /                    
       -----            -----             -----  -----                
       i = 1            j = 1             k = 1   i,j                

For small formulae without "difficult" parts use the M element: b_i, x^2, x^2 + 2x + 1 = (x + 1)^2. Note that here whitespace matters for text (or HTML) output.

Here are two formulae containing less than characters which are special characters for XML: a < b < c < d and e < f.

Using the Mode attribute of a Display element formulae like

a ⟶ a mod m'

can also be displayed nicely in text and HTML output.

2.3 Crossreferencing

[→ B.8]

In this section we demonstrate various references to parts of this document. Here is a reference to this section: 2.3. Here is a reference to chapter 1, to appendix A, and to subsection 1.1-1.

We distinguish among others references to functions (see f (1.2-1)), to methods with tricky name (see \^\{\}\[\]\<\& (1.2-2)), to operations (see MyOperation (1.2-3)), to methods (see MyOperation (1.2-4) or MyOperation (1.2-5)), to filters (see IsBla (1.2-6)), to properties (see IsBlubb (1.2-7)), to attributes (see NumberBlobbs (1.2-8)), to variables (AllBlibbs (1.2-9)), to families (see BlibbsFamily (1.2-10)), and to info classes (see InfoBlibbs (1.2-11)).

There are also references to labels: see here, to other books: see GAPDoc: What is a DTD? or IsSubgroup (Reference: IsSubgroup) in the GAP reference manual.

References to sections come in two styles: 1 or Sectioning Elements.

Another type of cross referencing is bibliography. Here is a citation: [CR81, (5.22)] is an interesting lemma.

There are also URLs:

http://www.math.rwth-aachen.de/

Email addresses have a special element: Frank.Luebeck@Math.RWTH-Aachen.De

and Homepages another one: http://www-groups.mcs.st-and.ac.uk/~neunhoef/

And here is a link to the EDIM archives.

One can generate index entries as follows (look up the words "TeX-UserGroup", "RWTH", "Aachen, Hauptbahnhof", and "GAP, GAPDoc").

2.4 Lists and Tables

[→ B.9]

There are

  • lists

  • enumerations, and

  • tables

or:

  1. lists

  2. enumerations, and

  3. tables

or with marks:

lists:

not numbered

enumerations:

numbered

tables:

two-dimensional

Lists can also be nested:

    1. first item of inner enumeration

    2. second item of inner enumeration

    • first item of inner list

    • second item of inner list

Here is a table:

Table: Prices
Object Price available
Shoe $1,00 there
Hat $2,00 not there

 


2.5 Entities and Special Characters

[→ B.10]

Here is a table of special characters, the first two are special for XML and must be typed in by entities in GAPDoc documents. The other characters are special for LaTeX but in GAPDoc they can be typed directly.

Table: Special characters in character data
& < > # $ % ~ \ { } _ ^  

 


And here are the predefined entities in GAPDoc:

Table: Predefined Entities in the GAPDoc system
&GAP; GAP
&GAPDoc; GAPDoc
&TeX; TeX
&LaTeX; LaTeX
&BibTeX; BibTeX
&MeatAxe; MeatAxe
&XGAP; XGAP
&copyright; ©

 


And some more for mathematical symbols: ℂ, ℤ, ℕ, ℙ, ℚ, ℍ, ℝ.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chapB.txt0000644000175000017500000005157212026346063014426 0ustar billbill B The Source B.1 TitlePage (Source)    A Complete Example (&see; <Ref Sect="One"/>)  Every element shows up  Version 1.5.1     If the subtitle ist not sufficient, this <TitleComment>   element can be used for a slightly longer text on the front page.    Frank Lübeck   Frank.Luebeck@Math.RWTH-Aachen.De     Max Neunhöffer   neunhoef at mcs.st-and.ac.uk    September 2011 
  Lehrstuhl D für Mathematik
Templergraben   64
52062 Aachen
(Germany) 
  This document tries to use all elements that exist in &GAPDoc;.  In addition, the final output not only contains the usual  content, but also an appendix with the source text. There  are also links from the usual content to the corresponding  source text. This should enable new users to learn &GAPDoc;  quickly.    ©right; 2000-2011 by Frank Lübeck and Max Neunhöffer    We thank Lehrstuhl D für Mathematik.    This is the Colophon page.   
  B.2 Before First Chapter (Source)       Text before chapter .  Sectioning Elements   Text before the section .  B.3 First Chapter (Source) [1.]  
Normal subsections   A subsection   This is text in the first subsection.      Another subsection    This is text in the second subsection. This subsection   has a label, such that one can reference it.     
  B.4 ManSections (Source) [1.2]  
ManSections       an element in or fail.    This function calculates something.             This method is for an operation with a tricky name.             The operation operates on x.              This method calculates something by the generic method.             This is the super-fast method for the operation  if the argument x is in the  representation . It will become even faster if  the optional argument good_hint is given.             For objects in this representation there is a super-fast method  (see ) for the operation  .             A property.             An attribute. Number of blobbs.             This global variable holds a list of all blibbs.             Family of all blibbs.             This info class is used throughout the library of blibbs.       
  B.5 Various Types of Text (Source) [2.]  Other Markup  
Various types of text  In this section we present examples for all the various types of text that are possible in &GAPDoc;:      This is emphasized.    Keywords are typeset like this and that.      Arguments of functions have an element. They look like this:   x and y.    Code can be written with the Code element:   if x = y then Print("Equal"); fi; or  while true do Print("Hello"); od;.     Filenames have their own element:  /usr/local/ca/gap4r2 or pkg/xgap/doc.    Buttons, menus, menu entries, and such things  are also supported: OK or .    Packages are typeset like this:   Small Groups Library      Quoted text: This is a text in quotes.     Paragraphs are separated by the empty Par or P element. Alternatives for different output formats:  This is &LaTeX; output. This is other than &LaTeX; output, namely: HTML]]> Text output.  

  B.6 Verbatim-like text (Source) [2.1]  There are also three elements to typeset verbatim-like text. 

 The first is a Listing:  

    Here is a Log of a &GAP; session using this function:   gap> Sieve(100); [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,  67, 71, 73, 79, 83, 89, 97 ] gap> Length(last); 25   Here is a &GAP; Example session that is automatically tested:   gap> s := Size(CharacterTable("M")); 808017424794512875886459904961710757005754368000000000 gap> s < 10^53;  false gap> s < 10^54; true   
  B.7 Formulae (Source) [2.2]  
Formulae  There are three types of formulae.

 The first is the normal math mode of &LaTeX;:   b_i \cdot b_j = \sum_{k=1}^d h_{ijk} b_k.   Then there are displayed formulae:   \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot  \left(\sum_{j=1}^d y_j b_j \right) =  \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k    If possible, use the Alt element to specify a better readable text version of such a formula as in the following example:

    \Longrightarrow \quad \left(\sum_{i=1}^d x_i b_i \right) \cdot  \left(\sum_{j=1}^d y_j b_j \right) =  \sum_{k=1}^d \left( \sum_{i,j} x_i y_j h_{ijk} \right) b_k     d d d   ----- ----- ----- -----   \ \ \ \   ==> ( ) x_i b_i )( ) y_i b_i ) = ) ( ) x_i y_j h_ijk ) b_k  / / / /   ----- ----- ----- -----   i = 1 i = 1 k = 1 i,j  

  For small formulae without difficult parts use the M element: b_i, x^2, x^2 + 2x + 1 = (x + 1)^2. Note that here whitespace  matters for text (or HTML) output).

  Here are two formulae containing less than characters which are special characters for XML:  and e < f. 

  B.8 Crossreferencing (Source) [2.3]  
Crossreferencing  
  B.9 Lists and Tables (Source) [2.4]  
Lists and Tables  There are   lists  enumerations, and  tables  or:   lists  enumerations, and  tables  or with marks:   lists: not numbered  enumerations: numbered  tables: two-dimensional   Lists can also be nested:       first item of inner enumeration   second item of inner enumeration           first item of inner list   second item of inner list        Here is a table:          ObjectPriceavailable          Shoe$1,00there        Hat$2,00not there     
Prices
  
  B.10 Entities and Special Characters (Source) [2.5]  
Entities and Special Characters 
      B.11 Appendix (Source) [A.]  GAPDoc source  An Appendix  This is an appendix.   GAPDoc-1.5.1/example/chapBib_mj.html0000644000175000017500000000510612026346064015545 0ustar billbill GAP (GAPDoc Example) - References
Goto Chapter: Top 1 2 A B Bib Ind

References

[CR81] Curtis, C. W. and Reiner, I., Methods of Representation Theory, John Wiley & Sons, I, New York, Chichester, Brisbane, Toronto, Singapore (1981).

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chapInd.txt0000644000175000017500000000104412026346063014744 0ustar billbill Index \^\{\}\[\]\<\& (for nothing) 1.2-2 Aachen, Hauptbahnhof 2.3 AllBlibbs 1.2-9 BlibbsFamily 1.2-10 f 1.2-1 GAP, GAPDoc 2.3 InfoBlibbs 1.2-11 IsBla 1.2-6 IsBlubb 1.2-7 MyOperation 1.2-3 MyOperation (First) 1.2-4 MyOperation (for bla) 1.2-5 NumberBlobbs 1.2-8 RWTH 2.3 TeX-UserGroup 2.3 ------------------------------------------------------- GAPDoc-1.5.1/example/chap0.txt0000644000175000017500000000641012026346064014374 0ustar billbill A Complete Example (→ B.1) Every element shows up Version 1.5.1 February 2012 Frank Lübeck Max Neunhöffer If the subtitle ist not sufficient, this element can be used for a slightly longer text on the front page. Frank Lübeck Email: mailto:Frank.Luebeck@Math.RWTH-Aachen.De Max Neunhöffer Email: mailto:neunhoef at mcs.st-and.ac.uk Address: Lehrstuhl D für Mathematik Templergraben 64 52062 Aachen (Germany) ------------------------------------------------------- Abstract This document tries to use all elements that exist in GAPDoc. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn GAPDoc quickly. ------------------------------------------------------- Copyright © 2000-2012 by Frank Lübeck and Max Neunhöffer ------------------------------------------------------- Acknowledgements We thank Lehrstuhl D für Mathematik. ------------------------------------------------------- Colophon This is the Colophon page. ------------------------------------------------------- Contents (GAPDoc Example) 1 Sectioning Elements 1.1 Normal subsections 1.1-1 A subsection 1.1-2 Another subsection 1.2 ManSections 1.2-1 f 1.2-2 \^\{\}\[\]\<\& 1.2-3 MyOperation 1.2-4 MyOperation 1.2-5 MyOperation 1.2-6 IsBla 1.2-7 IsBlubb 1.2-8 NumberBlobbs 1.2-9 AllBlibbs 1.2-10 BlibbsFamily 1.2-11 InfoBlibbs 2 Other Markup 2.1 Various types of text 2.2 Formulae 2.3 Crossreferencing 2.4 Lists and Tables 2.5 Entities and Special Characters A An Appendix B The Source B.1 TitlePage (Source) B.2 Before First Chapter (Source) B.3 First Chapter (Source) B.4 ManSections (Source) B.5 Various Types of Text (Source) B.6 Verbatim-like text (Source) B.7 Formulae (Source) B.8 Crossreferencing (Source) B.9 Lists and Tables (Source) B.10 Entities and Special Characters (Source) B.11 Appendix (Source)  Text before chapter 1. (→ B.2) GAPDoc-1.5.1/example/chapInd.html0000644000175000017500000000634112026346064015077 0ustar billbill GAP (GAPDoc Example) - Index
Goto Chapter: Top 1 2 A B Bib Ind

Index

\^\{\}\[\]\<\&, for nothing 1.2-2
Aachen, Hauptbahnhof 2.3
AllBlibbs 1.2-9
BlibbsFamily 1.2-10
f 1.2-1
GAP, GAPDoc 2.3
InfoBlibbs 1.2-11
IsBla 1.2-6
IsBlubb 1.2-7
MyOperation 1.2-3
MyOperation, First 1.2-4
MyOperation, for bla 1.2-5
NumberBlobbs 1.2-8
RWTH 2.3
TeX-UserGroup 2.3

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chapA_mj.html0000644000175000017500000000464412026346063015236 0ustar billbill GAP (GAPDoc Example) - Appendix A: An Appendix
Goto Chapter: Top 1 2 A B Bib Ind

A An Appendix

[→ B.11]

This is an appendix.

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/example.bib0000644000175000017500000000036212026346064014751 0ustar billbill @BOOK{CR1, AUTHOR = "Charles W. Curtis and Irving Reiner", TITLE = {Methods of Representation Theory}, PUBLISHER = {John Wiley \& Sons}, ADDRESS = "New York, Chichester, Brisbane, Toronto, Singapore", YEAR = 1981, VOLUME = "I"} GAPDoc-1.5.1/example/ragged.css0000644000175000017500000000023112026346064014576 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } GAPDoc-1.5.1/example/manual.css0000644000175000017500000001575412026346064014642 0ustar billbill/* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } GAPDoc-1.5.1/example/manual.lab0000644000175000017500000000617612026346064014606 0ustar billbill\GAPDocLabFile{gapdoc example} \makelabel{gapdoc example:Title page}{}{X7D2C85EC87DD46E5} \makelabel{gapdoc example:Abstract}{}{X7AA6C5737B711C89} \makelabel{gapdoc example:Copyright}{}{X81488B807F2A1CF1} \makelabel{gapdoc example:Acknowledgements}{}{X82A988D47DFAFCFA} \makelabel{gapdoc example:Colophon}{}{X7982162280BC7A61} \makelabel{gapdoc example:Table of Contents}{}{X8537FEB07AF2BEC8} \makelabel{gapdoc example:Sectioning Elements}{1}{X80E2AD7481DD69D9} \makelabel{gapdoc example:Normal subsections}{1.1}{X7818BD01870A269E} \makelabel{gapdoc example:A subsection}{1.1.1}{X7E193BD379F58A4C} \makelabel{gapdoc example:Another subsection}{1.1.2}{X79C2A0097ADE9776} \makelabel{gapdoc example:ManSections}{1.2}{X7C2D89087EA8BC84} \makelabel{gapdoc example:Other Markup}{2}{X82793A7E7A3F2A54} \makelabel{gapdoc example:Various types of text}{2.1}{X7A480B9A795EF264} \makelabel{gapdoc example:Formulae}{2.2}{X7AA5BF0279938BE0} \makelabel{gapdoc example:Crossreferencing}{2.3}{X833C410D85CF96A4} \makelabel{gapdoc example:Lists and Tables}{2.4}{X7F10E951789D6EDF} \makelabel{gapdoc example:Entities and Special Characters}{2.5}{X83A355E68485D6D1} \makelabel{gapdoc example:An Appendix}{A}{X7B53252784137533} \makelabel{gapdoc example:The Source}{B}{X7B4F7623844A7E32} \makelabel{gapdoc example:TitlePage (Source)}{B.1}{X7CFACB517D259F59} \makelabel{gapdoc example:Before First Chapter (Source)}{B.2}{X7A4D1C8680D81F2A} \makelabel{gapdoc example:First Chapter (Source)}{B.3}{X78308EBC7C2FF426} \makelabel{gapdoc example:ManSections (Source)}{B.4}{X814E3376826E1DB0} \makelabel{gapdoc example:Various Types of Text (Source)}{B.5}{X82A731CA83FB9ADD} \makelabel{gapdoc example:Verbatim-like text (Source)}{B.6}{X824BD70087820CF0} \makelabel{gapdoc example:Formulae (Source)}{B.7}{X8516FAA07A95BBB5} \makelabel{gapdoc example:Crossreferencing (Source)}{B.8}{X7D19CF4782309661} \makelabel{gapdoc example:Lists and Tables (Source)}{B.9}{X7BB822947F626E1A} \makelabel{gapdoc example:Entities and Special Characters (Source)}{B.10}{X80B478CD7E584F6F} \makelabel{gapdoc example:Appendix (Source)}{B.11}{X85E7E6BA81367928} \makelabel{gapdoc example:Bibliography}{Bib}{X7A6F98FD85F02BFE} \makelabel{gapdoc example:References}{Bib}{X7A6F98FD85F02BFE} \makelabel{gapdoc example:Index}{Ind}{X83A0356F839C696F} \makelabel{gapdoc example:f}{1.2.1}{X7FA1D0937FA1D093} \makelabel{gapdoc example:MyOperation}{1.2.3}{X7D33C2597988F481} \makelabel{gapdoc example:MyOperation (First)}{1.2.4}{X783DCD4E826289D4} \makelabel{gapdoc example:MyOperation (for bla)}{1.2.5}{X7A5F4A287D06988C} \makelabel{gapdoc example:IsBla}{1.2.6}{X82954B687D2DF3C2} \makelabel{gapdoc example:IsBlubb}{1.2.7}{X80C364DD7C919CCE} \makelabel{gapdoc example:NumberBlobbs}{1.2.8}{X8052A45E7F9F054C} \makelabel{gapdoc example:AllBlibbs}{1.2.9}{X7C00E05A7DDEF003} \makelabel{gapdoc example:BlibbsFamily}{1.2.10}{X7CBC935A8142E374} \makelabel{gapdoc example:InfoBlibbs}{1.2.11}{X84D7D77378AD030A} \makelabel{gapdoc example:TeX-UserGroup}{2.3}{X833C410D85CF96A4} \makelabel{gapdoc example:Aachen Hauptbahnhof}{2.3}{X833C410D85CF96A4} \makelabel{gapdoc example:GAP GAPDoc}{2.3}{X833C410D85CF96A4} \makelabel{gapdoc example:RWTH}{2.3}{X833C410D85CF96A4} GAPDoc-1.5.1/example/chapBib.html0000644000175000017500000000460612026346063015062 0ustar billbill GAP (GAPDoc Example) - References
Goto Chapter: Top 1 2 A B Bib Ind

References

[CR81] Curtis, C. W. and Reiner, I., Methods of Representation Theory, John Wiley & Sons, I, New York, Chichester, Brisbane, Toronto, Singapore (1981).

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chap0.html0000644000175000017500000002311212026346064014517 0ustar billbill GAP (GAPDoc Example) - Contents
Goto Chapter: Top 1 2 A B Bib Ind

A Complete Example (→ B.1)

Every element shows up

Version 1.5.1

February 2012

If the subtitle ist not sufficient, this <TitleComment> element can be used for a slightly longer text on the front page.

Frank Lübeck
Email: Frank.Luebeck@Math.RWTH-Aachen.De

Max Neunhöffer
Email: neunhoef at mcs.st-and.ac.uk

Address:
Lehrstuhl D für Mathematik
Templergraben 64
52062 Aachen
(Germany)

Abstract

This document tries to use all elements that exist in GAPDoc. In addition, the final output not only contains the usual content, but also an appendix with the source text. There are also links from the usual content to the corresponding source text. This should enable new users to learn GAPDoc quickly.

Copyright

© 2000-2012 by Frank Lübeck and Max Neunhöffer

Acknowledgements

We thank Lehrstuhl D für Mathematik.

Colophon

This is the Colophon page.

Text before chapter 1. (→ B.2)

Goto Chapter: Top 1 2 A B Bib Ind

generated by GAPDoc2HTML

GAPDoc-1.5.1/example/chap1.txt0000644000175000017500000000542412026346063014400 0ustar billbill 1 Sectioning Elements Text before the section 1.1. (→ B.2) 1.1 Normal subsections [→ B.3] 1.1-1 A subsection This is text in the first subsection. 1.1-2 Another subsection This is text in the second subsection. This subsection has a label, such that one can reference it. 1.2 ManSections [→ B.4] 1.2-1 f f( x[, y] )  function Returns: an element in IsBlubb (1.2-7) or fail. This function calculates something. 1.2-2 \^\{\}\[\]\<\& \^\{\}\[\]\<\&( c )  method This method is for an operation with a tricky name. 1.2-3 MyOperation MyOperation( x )  operation The operation MyOperation operates on x. 1.2-4 MyOperation MyOperation( x )  method This method calculates something by the generic method. 1.2-5 MyOperation MyOperation( x[, good_hint] )  method This is the super-fast method for the operation MyOperation (1.2-3) if the argument x is in the representation IsBla (1.2-6). It will become even faster if the optional argument good_hint is given. 1.2-6 IsBla IsBla( obj )  representation For objects in this representation there is a super-fast method (see MyOperation (1.2-5)) for the operation MyOperation (1.2-3). 1.2-7 IsBlubb IsBlubb( obj )  property A property. 1.2-8 NumberBlobbs NumberBlobbs( obj )  attribute An attribute. Number of blobbs. 1.2-9 AllBlibbs AllBlibbs global variable This global variable holds a list of all blibbs. 1.2-10 BlibbsFamily BlibbsFamily family Family of all blibbs. 1.2-11 InfoBlibbs InfoBlibbs info class This info class is used throughout the library of blibbs. GAPDoc-1.5.1/example/times.css0000644000175000017500000000026112026346064014471 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } GAPDoc-1.5.1/example/toggless.js0000644000175000017500000000420512026346064015025 0ustar billbill/* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); GAPDoc-1.5.1/example/manual.six0000644000175000017500000001421612026346064014645 0ustar billbill#SIXFORMAT GapDocGAP HELPBOOKINFOSIXTMP := rec( encoding := "UTF-8", bookname := "GAPDocExample", entries := [ [ "Title page", ".", [ 0, 0, 0 ], 1, 1, "title page", "X7D2C85EC87DD46E5" ], [ "Abstract", ".-1", [ 0, 0, 1 ], 40, 2, "abstract", "X7AA6C5737B711C89" ], [ "Copyright", ".-2", [ 0, 0, 2 ], 49, 2, "copyright", "X81488B807F2A1CF1" ] , [ "Acknowledgements", ".-3", [ 0, 0, 3 ], 54, 2, "acknowledgements", "X82A988D47DFAFCFA" ], [ "Colophon", ".-4", [ 0, 0, 4 ], 59, 2, "colophon", "X7982162280BC7A61" ], [ "Table of Contents", ".-5", [ 0, 0, 5 ], 64, 3, "table of contents", "X8537FEB07AF2BEC8" ], [ "\033[1X\033[33X\033[0;-2YSectioning Elements\033[133X\033[101X", "1", [ 1, 0, 0 ], 1, 5, "sectioning elements", "X80E2AD7481DD69D9" ], [ "\033[1X\033[33X\033[0;-2YNormal subsections\033[133X\033[101X", "1.1", [ 1, 1, 0 ], 6, 5, "normal subsections", "X7818BD01870A269E" ], [ "\033[1X\033[33X\033[0;-2YA subsection\033[133X\033[101X", "1.1-1", [ 1, 1, 1 ], 11, 5, "a subsection", "X7E193BD379F58A4C" ], [ "\033[1X\033[33X\033[0;-2YAnother subsection\033[133X\033[101X", "1.1-2", [ 1, 1, 2 ], 16, 5, "another subsection", "X79C2A0097ADE9776" ], [ "\033[1X\033[33X\033[0;-2YManSections\033[133X\033[101X", "1.2", [ 1, 2, 0 ], 22, 5, "mansections", "X7C2D89087EA8BC84" ], [ "\033[1X\033[33X\033[0;-2YOther Markup\033[133X\033[101X", "2", [ 2, 0, 0 ], 1, 8, "other markup", "X82793A7E7A3F2A54" ], [ "\033[1X\033[33X\033[0;-2YVarious types of text\033[133X\033[101X", "2.1", [ 2, 1, 0 ], 4, 8, "various types of text", "X7A480B9A795EF264" ] , [ "\033[1X\033[33X\033[0;-2YFormulae\033[133X\033[101X", "2.2", [ 2, 2, 0 ], 78, 9, "formulae", "X7AA5BF0279938BE0" ], [ "\033[1X\033[33X\033[0;-2YCrossreferencing\033[133X\033[101X", "2.3", [ 2, 3, 0 ], 120, 10, "crossreferencing", "X833C410D85CF96A4" ], [ "\033[1X\033[33X\033[0;-2YLists and Tables\033[133X\033[101X", "2.4", [ 2, 4, 0 ], 161, 10, "lists and tables", "X7F10E951789D6EDF" ], [ "\033[1X\033[33X\033[0;-2YEntities and Special Characters\033[133X\033[101X\ ", "2.5", [ 2, 5, 0 ], 217, 11, "entities and special characters", "X83A355E68485D6D1" ], [ "\033[1X\033[33X\033[0;-2YAn Appendix\033[133X\033[101X", "a", [ "A", 0, 0 ], 1, 12, "an appendix", "X7B53252784137533" ], [ "\033[1X\033[33X\033[0;-2YThe Source\033[133X\033[101X", "b", [ "B", 0, 0 ], 1, 13, "the source", "X7B4F7623844A7E32" ], [ "\033[1X\033[33X\033[0;-2YTitlePage (Source)\033[133X\033[101X", "b.1", [ "B", 1, 0 ], 4, 13, "titlepage source", "X7CFACB517D259F59" ], [ "\033[1X\033[33X\033[0;-2YBefore First Chapter (Source)\033[133X\033[101X" , "b.2", [ "B", 2, 0 ], 44, 14, "before first chapter source", "X7A4D1C8680D81F2A" ], [ "\033[1X\033[33X\033[0;-2YFirst Chapter (Source)\033[133X\033[101X", "b.3", [ "B", 3, 0 ], 59, 14, "first chapter source", "X78308EBC7C2FF426" ], [ "\033[1X\033[33X\033[0;-2YManSections (Source)\033[133X\033[101X", "b.4", [ "B", 4, 0 ], 83, 14, "mansections source", "X814E3376826E1DB0" ], [ "\033[1X\033[33X\033[0;-2YVarious Types of Text (Source)\033[133X\033[101X" , "b.5", [ "B", 5, 0 ], 181, 16, "various types of text source", "X82A731CA83FB9ADD" ], [ "\033[1X\033[33X\033[0;-2YVerbatim-like text (Source)\033[133X\033[101X", "b.6", [ "B", 6, 0 ], 232, 17, "verbatim-like text source", "X824BD70087820CF0" ], [ "\033[1X\033[33X\033[0;-2YFormulae (Source)\033[133X\033[101X", "b.7", [ "B", 7, 0 ], 283, 18, "formulae source", "X8516FAA07A95BBB5" ], [ "\033[1X\033[33X\033[0;-2YCrossreferencing (Source)\033[133X\033[101X", "b.8", [ "B", 8, 0 ], 332, 19, "crossreferencing source", "X7D19CF4782309661" ], [ "\033[1X\033[33X\033[0;-2YLists and Tables (Source)\033[133X\033[101X", "b.9", [ "B", 9, 0 ], 399, 20, "lists and tables source", "X7BB822947F626E1A" ], [ "\033[1X\033[33X\033[0;-2YEntities and Special Characters (Source)\033[133X\ \033[101X", "b.10", [ "B", 10, 0 ], 465, 21, "entities and special characters source", "X80B478CD7E584F6F" ], [ "\033[1X\033[33X\033[0;-2YAppendix (Source)\033[133X\033[101X", "b.11", [ "B", 11, 0 ], 533, 23, "appendix source", "X85E7E6BA81367928" ], [ "Bibliography", "bib", [ "Bib", 0, 0 ], 1, 24, "bibliography", "X7A6F98FD85F02BFE" ], [ "References", "bib", [ "Bib", 0, 0 ], 1, 24, "references", "X7A6F98FD85F02BFE" ], [ "Index", "ind", [ "Ind", 0, 0 ], 1, 25, "index", "X83A0356F839C696F" ], [ "\033[2Xf\033[102X", "1.2-1", [ 1, 2, 1 ], 27, 5, "f", "X7FA1D0937FA1D093" ], [ "\033[2X\\^\\{\\}\\[\\]\\<\\&\033[102X (for nothing)", "1.2-2", [ 1, 2, 2 ], 34, 5, "^{}[]<& for nothing", "X822B5C487B29E799" ], [ "\033[2XMyOperation\033[102X", "1.2-3", [ 1, 2, 3 ], 40, 6, "myoperation", "X7D33C2597988F481" ], [ "\033[2XMyOperation\033[102X (First)", "1.2-4", [ 1, 2, 4 ], 46, 6, "myoperation first", "X783DCD4E826289D4" ], [ "\033[2XMyOperation\033[102X (for bla)", "1.2-5", [ 1, 2, 5 ], 52, 6, "myoperation for bla", "X7A5F4A287D06988C" ], [ "\033[2XIsBla\033[102X", "1.2-6", [ 1, 2, 6 ], 60, 6, "isbla", "X82954B687D2DF3C2" ], [ "\033[2XIsBlubb\033[102X", "1.2-7", [ 1, 2, 7 ], 67, 6, "isblubb", "X80C364DD7C919CCE" ], [ "\033[2XNumberBlobbs\033[102X", "1.2-8", [ 1, 2, 8 ], 73, 6, "numberblobbs", "X8052A45E7F9F054C" ], [ "\033[2XAllBlibbs\033[102X", "1.2-9", [ 1, 2, 9 ], 79, 6, "allblibbs", "X7C00E05A7DDEF003" ], [ "\033[2XBlibbsFamily\033[102X", "1.2-10", [ 1, 2, 10 ], 85, 6, "blibbsfamily", "X7CBC935A8142E374" ], [ "\033[2XInfoBlibbs\033[102X", "1.2-11", [ 1, 2, 11 ], 91, 7, "infoblibbs", "X84D7D77378AD030A" ], [ "TeX-UserGroup", "2.3", [ 2, 3, 0 ], 120, 10, "tex-usergroup", "X833C410D85CF96A4" ], [ "Aachen Hauptbahnhof", "2.3", [ 2, 3, 0 ], 120, 10, "aachen hauptbahnhof", "X833C410D85CF96A4" ], [ "\033[5XGAP\033[105X GAPDoc", "2.3", [ 2, 3, 0 ], 120, 10, "gap gapdoc", "X833C410D85CF96A4" ], [ "RWTH", "2.3", [ 2, 3, 0 ], 120, 10, "rwth", "X833C410D85CF96A4" ] ] ); GAPDoc-1.5.1/lib/0000755000175000017500000000000012174444011011745 5ustar billbillGAPDoc-1.5.1/lib/UnicodeTools.gi0000644000175000017500000013777712026346064014730 0ustar billbill############################################################################# ## #W UnicodeTools.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2007, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files UnicodeTools.g{d,i} contain utilities for converting text ## between different encodings. They introduce unicode strings and ## characters as GAP objects. ## # reading some extendible tables of translations of unicode characters ReadPackage("GAPDoc", "lib/UnicodeTabs.g"); # UNICODE_RECODE is a is a record. For some string enc, describing a # character encoding, UNICODE_RECODE.(enc) is a function which translates # a GAP string in encoding enc to a list of integers describing the unicode # codepoints of the characters in the string. # # UNICODE_RECODE.TABLES contains some embeddings of 8 bit code pages into # unicode as lists of length 256, codepoint of character i in [0..255] in # position i+1. # normalize encoding names UNICODE_RECODE.NormalizedEncodings := rec( latin1 := "ISO-8859-1", latin2 := "ISO-8859-2", latin3 := "ISO-8859-3", latin4 := "ISO-8859-4", latin5 := "ISO-8859-9", latin6 := "ISO-8859-10", latin7 := "ISO-8859-13", latin8 := "ISO-8859-14", latin9 := "ISO-8859-15", latin0 := "ISO-8859-15", utf8 := "UTF-8", UTF8 := "UTF-8", ASCII := "ANSI_X3.4-1968", US\-ASCII := "ANSI_X3.4-1968", xml := "XML", url := "URL", URL := "URL", percent := "URL", ); UNICODE_RECODE.f := function() local nam, i; for i in Concatenation([1..11],[13..15]) do nam := Concatenation("ISO-8859-",String(i)); UNICODE_RECODE.NormalizedEncodings.(nam) := nam; UNICODE_RECODE.Decoder.(nam) := function(str) return UNICODE_RECODE.TABLES.(nam){List(str, INT_CHAR)+1}; end; od; nam := "ANSI_X3.4-1968"; UNICODE_RECODE.NormalizedEncodings.(nam) := nam; UNICODE_RECODE.Decoder.(nam) := function(str) return UNICODE_RECODE.TABLES.(nam){List(str, INT_CHAR)+1}; end; UNICODE_RECODE.NormalizedEncodings.("UTF-8") := "UTF-8"; UNICODE_RECODE.NormalizedEncodings.("XML") := "XML"; end; UNICODE_RECODE.f(); Unbind(UNICODE_RECODE.f); # slightly more efficient for latin1: UNICODE_RECODE.Decoder.("ISO-8859-1") := function(str) return List(str, INT_CHAR); end; # helper function; arg: str[, start], translate single UTF-8 character # to its unicode number UNICODE_RECODE.UnicodeUTF8Char := function(arg) local str, i, a, i1, i2, i3; str := arg[1]; if Length(arg)>1 then i := arg[2]; else i := 1; fi; a := INT_CHAR(str[i]); if a < 128 then return a; elif a < 224 then if i = Length(str) then return fail; fi; i1 := INT_CHAR(str[i+1]); if i1 < 128 or i1 > 191 then return fail; fi; return (a mod 192)*64 + (i1 mod 64); elif a < 240 then if Length(str) < i+2 then return fail; fi; i1 := INT_CHAR(str[i+1]); i2 := INT_CHAR(str[i+2]); if i1 < 128 or i2 < 128 or i1 > 191 or i2 > 191 then return fail; fi; return (a mod 224)*4096 + (i1 mod 64)*64 + (i2 mod 64); else if Length(str) < i+3 then return fail; fi; i1 := INT_CHAR(str[i+1]); i2 := INT_CHAR(str[i+2]); i3 := INT_CHAR(str[i+3]); if i1<128 or i2<128 or i3<128 or i1>191 or i2>191 or i3>191 then return fail; fi; return (a mod 240)*262144 + (i1 mod 64)*4096 + (i2 mod 64)*64 + (i3 mod 64); fi; end; ## UNICODE_RECODE.Decoder.("UTF-8") := function(str) ## local res, c, i; ## res := []; ## for i in [1..Length(str)] do ## c := INT_CHAR(str[i]); ## if c < 128 or c > 191 then ## Add(res, UNICODE_RECODE.UnicodeUTF8Char(str, i)); ## fi; ## od; ## if fail in res then return fail; fi; ## return res; ## end; UNICODE_RECODE.Decoder.("UTF-8") := function(str) local res, i, n; res := []; i := 1; while i <= Length(str) do n := UNICODE_RECODE.UnicodeUTF8Char(str, i); if n = fail then return fail; elif n < 128 then i := i+1; elif n < 2048 then i := i+2; elif n < 65536 then i := i+3; else i := i+4; fi; Add(res, n); od; if fail in res then return fail; fi; return res; end; UNICODE_RECODE.Decoder.("XML") := function(str) local res, i, j, n; res := []; i := 1; while i <= Length(str) do if str[i] = '&' and i < Length(str) and str[i+1] = '#' then j := Position(str, ';', i); n := str{[i+2..j-1]}; if n[1] = 'x' then n := IntHexString(n{[2..Length(n)]}); else n := Int(n); fi; Add(res, n); i := j+1; else Add(res, INT_CHAR(str[i])); i := i+1; fi; od; return res; end; UNICODE_RECODE.Decoder.("URL") := function(str) local res, i; res := ""; i := 1; while i <= Length(str) do if str[i] = '%' then Add(res, CHAR_INT(IntHexString(str{[i+1,i+2]}))); i := i+3; else Add(res, str[i]); i := i+1; fi; od; return IntListUnicodeString(Unicode(res, "UTF-8")); end; ################################################ UNICODE_RECODE.TABLES := rec( ANSI_X3\.4\-1968 := [0..127], ISO\-8859\-1 := [ 0 .. 255 ], ISO\-8859\-2 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 260, 728, 321, 163, 317, 346, 166, 167, 352, 350, 356, 377, 172, 381, 379, 175, 261, 731, 322, 179, 318, 347, 711, 183, 353, 351, 357, 378, 733, 382, 380, 340, 192, 193, 258, 195, 313, 262, 198, 268, 200, 280, 202, 282, 204, 205, 270, 272, 323, 327, 210, 211, 336, 213, 214, 344, 366, 217, 368, 219, 220, 354, 222, 341, 224, 225, 259, 227, 314, 263, 230, 269, 232, 281, 234, 283, 236, 237, 271, 273, 324, 328, 242, 243, 337, 245, 246, 345, 367, 249, 369, 251, 252, 355, 729, 255 ], ISO\-8859\-3 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 294, 728, 162, 163, 164, 292, 166, 167, 304, 350, 286, 308, 172, 173, 379, 175, 295, 177, 178, 179, 180, 293, 182, 183, 305, 351, 287, 309, 188, 189, 380, 191, 192, 193, 194, 195, 266, 264, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 288, 213, 214, 284, 216, 217, 218, 219, 364, 348, 222, 223, 224, 225, 226, 227, 267, 265, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 289, 245, 246, 285, 248, 249, 250, 251, 365, 349, 729, 255 ], ISO\-8859\-4 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 260, 312, 342, 163, 296, 315, 166, 167, 352, 274, 290, 358, 172, 381, 174, 175, 261, 731, 343, 179, 297, 316, 711, 183, 353, 275, 291, 359, 330, 382, 331, 256, 192, 193, 194, 195, 196, 197, 302, 268, 200, 280, 202, 278, 204, 205, 298, 272, 325, 332, 310, 211, 212, 213, 214, 215, 370, 217, 218, 219, 360, 362, 222, 257, 224, 225, 226, 227, 228, 229, 303, 269, 232, 281, 234, 279, 236, 237, 299, 273, 326, 333, 311, 243, 244, 245, 246, 247, 371, 249, 250, 251, 361, 363, 729, 255 ], ISO\-8859\-5 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 172, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 8470, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 167, 1118, 1119, 255 ], ISO\-8859\-6 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 1548, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 1563, 187, 188, 189, 1567, 191, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 218, 219, 220, 221, 222, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 ], ISO\-8859\-7 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 701, 700, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 8213, 175, 176, 177, 178, 900, 901, 902, 182, 904, 905, 906, 186, 908, 188, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 209, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 254, 255 ], ISO\-8859\-8 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 215, 170, 171, 172, 173, 8254, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 247, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 8215, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 250, 251, 252, 253, 254, 255 ], ISO\-8859\-9 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 286, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 304, 350, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 287, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 305, 351, 254, 255 ], ISO\-8859\-10 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 260, 274, 290, 298, 296, 310, 166, 315, 272, 352, 358, 381, 172, 362, 330, 175, 261, 275, 291, 299, 297, 311, 182, 316, 273, 353, 359, 382, 8213, 363, 331, 256, 192, 193, 194, 195, 196, 197, 302, 268, 200, 280, 202, 278, 204, 205, 206, 207, 325, 332, 210, 211, 212, 213, 360, 215, 370, 217, 218, 219, 220, 221, 222, 257, 224, 225, 226, 227, 228, 229, 303, 269, 232, 281, 234, 279, 236, 237, 238, 239, 326, 333, 242, 243, 244, 245, 361, 247, 371, 249, 250, 251, 252, 253, 312, 255 ], ISO\-8859\-11 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 218, 219, 220, 221, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 251, 252, 253, 254, 255 ], ISO\-8859\-13 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 8221, 161, 162, 163, 8222, 165, 166, 216, 168, 342, 170, 171, 172, 173, 198, 175, 176, 177, 178, 8220, 180, 181, 182, 248, 184, 343, 186, 187, 188, 189, 230, 260, 302, 256, 262, 195, 196, 280, 274, 268, 200, 377, 278, 290, 310, 298, 315, 352, 323, 325, 210, 332, 212, 213, 214, 370, 321, 346, 362, 219, 379, 381, 222, 261, 303, 257, 263, 227, 228, 281, 275, 269, 232, 378, 279, 291, 311, 299, 316, 353, 324, 326, 242, 333, 244, 245, 246, 371, 322, 347, 363, 251, 380, 382, 8217, 255 ], ISO\-8859\-14 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 7682, 7683, 162, 266, 267, 7690, 166, 7808, 168, 7810, 7691, 7922, 172, 173, 376, 7710, 7711, 288, 289, 7744, 7745, 181, 7766, 7809, 7767, 7811, 7776, 7923, 7812, 7813, 7777, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 372, 208, 209, 210, 211, 212, 213, 7786, 215, 216, 217, 218, 219, 220, 374, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 373, 240, 241, 242, 243, 244, 245, 7787, 247, 248, 249, 250, 251, 252, 375, 254, 255 ], ISO\-8859\-15 := [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 8364, 164, 352, 166, 353, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 381, 180, 181, 182, 382, 184, 185, 186, 338, 339, 376, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 ] ); # reverse tables are only generated when needed UNICODE_RECODE.TABLES.reverse := rec(); ## # this created the code tables for ISO-8859: ## for i in Concatenation([1..11],[13..15]) do ## fn := Concatenation("iso8859-",String(i),".txt"); ## str := StringFile(fn); ## str := SplitString(str,"","\n"); ## str := List(str, a-> SplitString(a,""," \t")); ## str := List(str, a-> List([1,2], k-> IntHexString( ## Filtered(a[k], x-> not x in "=+U")))); ## str := Filtered(str, a-> a[1]<>a[2]); ## fn := Concatenation("ISO-8859-",String(i)); ## res := [0..255]; ## for a in str do ## res[a[1]] := a[2]; ## od; ## UNICODE_RECODE.TABLES.(fn) := res; ## od; ################################################ # wrap and cache integers as unicode characters InstallMethod(UChar, [IsInt], function(n) local res; if not IsInt(n) or n < 0 or n > 2097151 then return fail; fi; if IsBound(UNICODECHARCACHE[n]) then return UNICODECHARCACHE[n]; fi; res := rec(codepoint := n); Objectify(UnicodeCharacterType, res); UNICODECHARCACHE[n] := res; return res; end); # interpret GAP characters as latin 1 encoded InstallMethod(UChar, [IsChar], function(c) return UChar(INT_CHAR(c)); end); # viewing and printing unicode characters InstallMethod(ViewObj, [IsUnicodeCharacter], function(c) Print("'", UNICODE_RECODE.UTF8UnicodeChar(c!.codepoint), "'"); end); InstallMethod(PrintObj, [IsUnicodeCharacter], function(c) Print("UChar(",c!.codepoint,")"); end); # \= InstallMethod(\=, [IsUnicodeCharacter, IsUnicodeCharacter], function(c, d) return c!.codepoint = d!.codepoint; end); InstallOtherMethod(Int, [IsUnicodeCharacter], function(uc) return uc!.codepoint; end); ## <#GAPDoc Label="Unicode"> ## ## Unicode Strings and Characters ## ## ## ## ## ## ## ## Unicode characters are described by their codepoint, an ## integer in the range from 0 to 2^{21}-1. ## For details about unicode, see http://www.unicode.org.

## ## The function wraps an integer num into ## a &GAP; object lying in the filter . ## Use Int to get the codepoint back. The argument num can ## also be a &GAP; character which is then translated to an integer via ## .

## ## produces a &GAP; object in the filter ## . This is a wrapped list of integers ## for the unicode characters in the string. The function gives access to this list of integers. ## Basic list functionality is available for ## elements. The entries are in . ## The argument list for is either a list of ## integers or a &GAP; string. In the latter case an encoding can be ## specified as string, its default is "UTF-8".

## ## URL encodingRFC 3986 ## Currently supported encodings can be found in ## UNICODE_RECODE.NormalizedEncodings (ASCII, ## ISO-8859-X, UTF-8 and aliases). The encoding "XML" means an ASCII ## encoding in which non-ASCII characters are specified by XML character ## entities. The encoding "URL" is for URL-encoded (also called ## percent-encoded strings, as specified in RFC 3986 ## (http://www.ietf.org/rfc/rfc3986.txt). ## The listed encodings "LaTeX" and aliases ## cannot be used with . ## See the operation for mapping a unicode string ## to a &GAP; string.

## ## gap> ustr := Unicode("a and \366", "latin1"); ## Unicode("a and \303\266") ## gap> ustr = Unicode("a and &#246;", "XML"); ## true ## gap> IntListUnicodeString(ustr); ## [ 97, 32, 97, 110, 100, 32, 246 ] ## gap> ustr[7]; ## 'ö' ## ## ## ## ## <#/GAPDoc> # NC method, assume that l is (plain?) list of integers in correct range InstallMethod(Unicode, [IsList], function(l) local res; res := [l]; Objectify(UnicodeStringType, res); return res; end); # extract the list of integers InstallGlobalFunction("IntListUnicodeString", function(ustr) return ustr![1]; end); InstallMethod(Unicode, [IsString, IsString], function(str, enc) local res; if Length(str) > 0 and not IsStringRep(str) then ## Info(InfoWarning, 1, "#W Changing argument to IsStringRep"); ## Info(InfoWarning, 2, ":\n ", str); ## Info(InfoWarning, 1, "\n"); ## ConvertToStringRep(str); str := ShallowCopy(str); ConvertToStringRep(str); fi; if not IsBound(UNICODE_RECODE.NormalizedEncodings.(enc)) then Error("Sorry, only the following encodings are supported for 'Unicode':\n", RecFields(UNICODE_RECODE.Decoder), "\n"); fi; enc := UNICODE_RECODE.NormalizedEncodings.(enc); res := UNICODE_RECODE.Decoder.(enc)(str); if res = fail then return fail; fi; return Unicode(res); end); # just a string as argument is assumed to be in UTF-8 encoding InstallMethod(Unicode, [IsStringRep], function(str) return Unicode(str, "UTF-8"); end); # view and print InstallMethod(ViewObj, [IsUnicodeString], function(ustr) local l; l := IntListUnicodeString(ustr); if Length(l) > 40 then l := l{[1..37]}; Append(l, [46,46,46]); fi; Print("Unicode("); ViewObj(Concatenation(List(l, UNICODE_RECODE.UTF8UnicodeChar))); Print(")"); end); InstallMethod(PrintObj, [IsUnicodeString], function(ustr) Print("Unicode("); PrintObj(Concatenation(List(IntListUnicodeString(ustr), UNICODE_RECODE.UTF8UnicodeChar))); Print(")"); end); # the *basic* list operations InstallMethod(Length, [IsUnicodeString], function(ustr) return Length(IntListUnicodeString(ustr)); end); InstallMethod(\[\], [IsUnicodeString, IsPosInt], function(ustr, i) return UChar(IntListUnicodeString(ustr)[i]); end); InstallOtherMethod(\[\]\:\=, [IsUnicodeString and IsMutable, IsPosInt, IsUnicodeCharacter], function(ustr, i, x) local l; if i > Length(ustr)+1 then Error("no unicode string assignment at position ",i,"\n"); fi; l := IntListUnicodeString(ustr); l[i] := x!.codepoint; end); InstallMethod(Unbind\[\], [IsUnicodeString and IsMutable, IsPosInt], function(ustr, i) local l; if i < Length(ustr) then Error("can only unbind last character in unicode string\n"); fi; if i = Length(ustr) then l := IntListUnicodeString(ustr); Unbind(l[Length(l)]); fi; end); # let ShallowCopy produce a unicode string InstallMethod(ShallowCopy, [IsUnicodeString], function(ustr) return Unicode(ShallowCopy(IntListUnicodeString(ustr))); end); # let sublists be unicode strings InstallMethod(\{\}, [IsUnicodeString, IsList], function(ustr, poss) return Unicode(IntListUnicodeString(ustr){poss}); end); # a better Append for efficiency InstallMethod(Append, [IsUnicodeString and IsMutable, IsUnicodeString], function(ustr, ustr2) Append(IntListUnicodeString(ustr), IntListUnicodeString(ustr2)); end); # better \= for efficiency InstallMethod(\=, [IsUnicodeString, IsUnicodeString], function(ustr1, ustr2) return IntListUnicodeString(ustr1) = IntListUnicodeString(ustr2); end); # better Position, PositionSublist InstallMethod(Position, [IsUnicodeString, IsUnicodeCharacter], function(ustr, c) return Position(IntListUnicodeString(ustr), c!.codepoint); end); InstallMethod(Position, [IsUnicodeString, IsUnicodeCharacter, IsInt], function(ustr, c, pos) return Position(IntListUnicodeString(ustr), c!.codepoint, pos); end); InstallOtherMethod(PositionSublist, [IsUnicodeString, IsUnicodeString], function(ustr, ustr2) return PositionSublist(IntListUnicodeString(ustr), IntListUnicodeString(ustr2)); end); InstallMethod(PositionSublist, [IsUnicodeString, IsUnicodeString, IsInt], function(ustr, ustr2, pos) return PositionSublist(IntListUnicodeString(ustr), IntListUnicodeString(ustr2), pos); end); ## <#GAPDoc Label="Encode"> ## ## ## a &GAP; string ## ## a unicode string ## ## a unicode string ## ## a unicode string ## ## ## ## ## ## The operation translates a unicode string ustr ## into a &GAP; string in some specified encoding. The default ## encoding is "UTF-8".

## ## Supported encodings can be found in ## UNICODE_RECODE.NormalizedEncodings. Except for some cases ## mentioned below characters which are not available in the target ## encoding are substituted by '?' characters.

## ## If the encoding is "URL" (see ) then ## an optional argument encreserved can be given, it must be a list ## of reserved characters which should be percent encoded; the default is ## to encode only the % character.

## ## The encoding "LaTeX" substitutes ## non-ASCII characters and &LaTeX; special characters by &LaTeX; code ## as given in an ordered list ## LaTeXUnicodeTable of pairs [codepoint, string]. If you have a ## unicode character for which no substitution is contained in that list, ## you will get a warning and the translation is Unicode(nr). ## In this case find a substitution and add a ## corresponding [codepoint, string] ## pair to LaTeXUnicodeTable using . Also, please, tell the &GAPDoc; authors about your ## addition, such that we can extend the list LaTeXUnicodeTable. ## (Most of the initial entries were generated from lists in the ## &TeX; projects enc&TeX; and ucs.) ## There are some variants of this encoding:

## "LaTeXleavemarkup" does ## the same translations for non-ASCII characters but leaves the &LaTeX; ## special characters (e.g., any &LaTeX; commands) as they are.

## "LaTeXUTF8" does not give a warning about unicode characters ## without explicit translation, instead it translates the character ## to its UTF-8 encoding. Make sure to setup your &LaTeX; document such ## that all these characters are understood.

## "LaTeXUTF8leavemarkup" is a combination of the last two variants.

## ## Note that the "LaTeX" encoding can only be used with but not for the opposite translation with (which would need far too complicated heuristics).

## ## The function can be used to ## substitute many non-ASCII characters by related ASCII characters ## or strings (e.g., by a corresponding character without accents). ## The argument ustr and the result are unicode strings, if ## encoding is "ASCII" then all non-ASCII characters are ## translated, otherwise only the non-latin1 characters. If the string ## "single" in an argument then only substitutions are considered ## which don't make the result string longer. The translations are stored ## in a sorted list SimplifiedUnicodeTable. Its entries are of the ## form [codepoint, trans1, trans2, ...]. Here trans1 and so ## on is either an integer for the codepoint of a substitution character or ## it is a list of codepoint integers. If you are missing characters in ## this list and know a sensible ASCII approximation, then add an entry ## (with ) and tell the &GAPDoc; ## authors about it. (The initial content of SimplifiedUnicodeTable ## was mainly generated from the transtab tables by Markus ## Kuhn.)

## ## The function gets and returns a ## unicode string and translates each uppercase character to its ## corresponding lowercase version. This function uses a list ## LowercaseUnicodeTable of pairs of codepoint integers. ## This list was generated using the file UnicodeData.txt from the ## unicode definition (field 14 in each row).

## ## The function does the similar ## translation to uppercase characters. ## ## ## gap> ustr := Unicode("a and &#246;", "XML"); ## Unicode("a and \303\266") ## gap> SimplifiedUnicodeString(ustr, "ASCII"); ## Unicode("a and oe") ## gap> SimplifiedUnicodeString(ustr, "ASCII", "single"); ## Unicode("a and o") ## gap> ustr2 := UppercaseUnicodeString(ustr);; ## gap> Print(Encode(ustr2, GAPInfo.TermEncoding), "\n"); ## A AND Ö ## ## ## ## ## <#/GAPDoc> ## # helper function for encoding a unicode character to UTF-8 UNICODE_RECODE.UTF8UnicodeChar := function(n) local res, a, b, c, d; res := ""; if n < 0 then return fail; elif n < 128 then Add(res, CHAR_INT(n)); elif n < 2048 then a := n mod 64; b := (n - a) / 64; Add(res, CHAR_INT(b + 192)); Add(res, CHAR_INT(a + 128)); elif n < 65536 then a := n mod 64; n := (n - a)/64; b := n mod 64; c := (n - b)/64; Add(res, CHAR_INT(c + 224)); Add(res, CHAR_INT(b + 128)); Add(res, CHAR_INT(a + 128)); elif n < 2097152 then a := n mod 64; n := (n - a)/64; b := n mod 64; n := (n - b)/64; c := n mod 64; d := (n - c)/64; Add(res, CHAR_INT(d + 240)); Add(res, CHAR_INT(c + 128)); Add(res, CHAR_INT(b + 128)); Add(res, CHAR_INT(a + 128)); else return fail; fi; return res; end; # encode unicode string to GAP string in UTF-8 encoding UNICODE_RECODE.Encoder.("UTF-8") := function(ustr) local res, f, n; res := ""; f := UNICODE_RECODE.UTF8UnicodeChar; for n in IntListUnicodeString(ustr) do Append(res, f(n)); od; return res; end; # non-ASCII characters to XML character entities UNICODE_RECODE.Encoder.("XML") := function(ustr) local res, n; res := ""; for n in IntListUnicodeString(ustr) do if n < 128 then Add(res, CHAR_INT(n)); else Append(res, Concatenation("&#x", LowercaseString(HexStringInt(n)),";")); fi; od; return res; end; UNICODE_RECODE.RFC3986Unreserved := Set(List( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~", INT_CHAR)); UNICODE_RECODE.RFC3986Reserved := Set(List("!*'();:@&=+$,/?%#[]", INT_CHAR)); UNICODE_RECODE.Encoder.("URL") := function(arg) local ustr, encreserved, res, s, i, j; ustr := arg[1]; # also allow UTF-8 GAP string if not IsUnicodeString(ustr) then ustr := Unicode(ustr); fi; if Length(arg) > 1 then encreserved := arg[2]; else encreserved := "%"; fi; if IsString(encreserved) then encreserved := Set(List(encreserved, INT_CHAR)); fi; res := ""; for i in IntListUnicodeString(ustr) do if i in UNICODE_RECODE.RFC3986Unreserved then Add(res, CHAR_INT(i)); elif i in UNICODE_RECODE.RFC3986Reserved and not i in encreserved then Add(res, CHAR_INT(i)); elif i < 128 then Add(res, '%'); if i < 16 then Add(res, '0'); fi; Append(res, HexStringInt(i)); else s := Encode(Unicode([i]), "UTF-8"); for j in List(s, INT_CHAR) do Add(res, '%'); Append(res, HexStringInt(j)); od; fi; od; return res; end; # non-ASCII characters to LaTeX code, if known from LaTeXUnicodeTable # args: unicodestring[, leavemarkup[, leaveutf8]] UNICODE_RECODE.Encoder.("LaTeX") := function(arg) local ustr, leavemarkup, tt, res, pos, s, n, leaveutf8; ustr := arg[1]; if Length(arg) > 1 then leavemarkup := arg[2]; else leavemarkup := false; fi; if Length(arg) > 2 then leaveutf8 := arg[3]; else leaveutf8 := false; fi; tt := LaTeXUnicodeTable; res := ""; for n in IntListUnicodeString(ustr) do pos := Position([ 35, 36, 37, 38, 60, 62, 92, 94, 95, 123, 125, 126], n); if pos <> fail and not leavemarkup then Append(res, tt[pos][2]); elif n < 128 then Add(res, CHAR_INT(n)); else pos := POSITION_FIRST_COMPONENT_SORTED(tt, n); if IsBound(tt[pos]) and tt[pos][1] = n then Append(res, tt[pos][2]); elif leaveutf8 = true then Append(res, UNICODE_RECODE.UTF8UnicodeChar(n)); else s := Encode(Unicode([n]), GAPInfo.TermEncoding); Info(InfoWarning, 1, "#W Missing LaTeX translation of unicode character ", String(n), ":", s, ",\nadd to LaTeXUnicodeTable\n"); Append(res, Concatenation("Unicode(", String(n), ")")); fi; fi; od; return res; end; UNICODE_RECODE.NormalizedEncodings.LaTeX := "LaTeX"; UNICODE_RECODE.NormalizedEncodings.latex := "LaTeX"; UNICODE_RECODE.NormalizedEncodings.BibTeX := "LaTeX"; UNICODE_RECODE.Encoder.("LaTeXleavemarkup") := function(ustr) return UNICODE_RECODE.Encoder.("LaTeX")(ustr, true); end; UNICODE_RECODE.NormalizedEncodings.LaTeXleavemarkup := "LaTeXleavemarkup"; UNICODE_RECODE.NormalizedEncodings.latexleavemarkup := "LaTeXleavemarkup"; UNICODE_RECODE.NormalizedEncodings.BibTeXleavemarkup := "LaTeXleavemarkup"; UNICODE_RECODE.Encoder.("LaTeXUTF8leavemarkup") := function(ustr) return UNICODE_RECODE.Encoder.("LaTeX")(ustr, true, true); end; UNICODE_RECODE.NormalizedEncodings.LaTeXUTF8leavemarkup := "LaTeXUTF8leavemarkup"; UNICODE_RECODE.NormalizedEncodings.BibTeXUTF8leavemarkup := "LaTeXUTF8leavemarkup"; UNICODE_RECODE.Encoder.("LaTeXUTF8") := function(ustr) return UNICODE_RECODE.Encoder.("LaTeX")(ustr, false, true); end; UNICODE_RECODE.NormalizedEncodings.LaTeXUTF8 := "LaTeXUTF8"; UNICODE_RECODE.NormalizedEncodings.BibTeXUTF8:= "LaTeXUTF8"; InstallGlobalFunction(SimplifiedUnicodeString, function(arg) local ustr, single, max, tt, res, pos, a, f, n; ustr := arg[1]; # at most single character substitutions? single := false; # maximal untouched character (255 for latin1 and 127 for ASCII) max := 255; if "single" in arg then single := true; fi; if "ascii" in arg or "ASCII" in arg or "ANSI_X3.4-1968" in arg then max := 127; fi; tt := SimplifiedUnicodeTable; res := []; for n in IntListUnicodeString(ustr) do if n <= max then Add(res, n); else pos := POSITION_FIRST_COMPONENT_SORTED(tt, n); if IsBound(tt[pos]) and tt[pos][1] = n then a := tt[pos]; f := Filtered([2..Length(a)], i-> (IsInt(a[i]) and a[i] <= max) or (IsList(a[i]) and ForAll(a[i], j-> j <= max))); if single then f := Filtered(f, i-> IsInt(a[i]) or Length(a[i]) <= 1); fi; if Length(f) > 0 then a := a[f[1]]; if IsInt(a) then Add(res, a); else Append(res, a); fi; else # ? is '?' Add(res, 63); fi; else Add(res, 63); fi; fi; od; return Unicode(res); end); InstallGlobalFunction(LowercaseUnicodeString, function(ustr) local res, tt, pos, i; res := ShallowCopy(IntListUnicodeString(ustr)); tt := LowercaseUnicodeTable; for i in [1..Length(res)] do pos := POSITION_FIRST_COMPONENT_SORTED(tt, res[i]); if IsBound(tt[pos]) and tt[pos][1] = res[i] then res[i] := tt[pos][2]; fi; od; return Unicode(res); end); InstallGlobalFunction(UppercaseUnicodeString, function(ustr) local res, UppercaseUnicodeTable, tt, pos, i; res := ShallowCopy(IntListUnicodeString(ustr)); if not IsBound(UppercaseUnicodeTable) then UppercaseUnicodeTable := Set(List(LowercaseUnicodeTable, a-> [a[2],a[1]])); fi; tt := UppercaseUnicodeTable; for i in [1..Length(res)] do pos := POSITION_FIRST_COMPONENT_SORTED(tt, res[i]); if IsBound(tt[pos]) and tt[pos][1] = res[i] then res[i] := tt[pos][2]; fi; od; return Unicode(res); end); # ISO-8859 cases, substitute '?' for unknown characters UNICODE_RECODE.f := function() local nam, i; for i in Concatenation([1..11],[13..15]) do nam := Concatenation("ISO-8859-", String(i)); UNICODE_RECODE.Encoder.(nam) := function(ustr) local t, s, res, pos, c; if not IsBound(UNICODE_RECODE.TABLES.reverse.(nam)) then t := [0..255]; s := ShallowCopy(UNICODE_RECODE.TABLES.(nam)); SortParallel(s, t); UNICODE_RECODE.TABLES.reverse.(nam) := [s, t]; fi; t := UNICODE_RECODE.TABLES.reverse.(nam); res := []; for c in IntListUnicodeString(ustr) do if c < 160 then Add(res, c); else pos := PositionSorted(t[1], c); if pos = fail then Add(res, 63); # '?' else Add(res, t[2][pos]); fi; fi; od; return STRING_SINTLIST(res); end; od; end; UNICODE_RECODE.f(); Unbind(UNICODE_RECODE.f); UNICODE_RECODE.Encoder.("ANSI_X3.4-1968") := function(ustr) local res; res := List(IntListUnicodeString(ustr), function(i) if i < 128 then return i; else return 63; fi; end); return STRING_SINTLIST(res); end; InstallMethod(Encode, [IsUnicodeString, IsString], function(ustr, enc) if not IsBound(UNICODE_RECODE.NormalizedEncodings.(enc)) then Error("Sorry, only the following encodings are supported for Encode:\n", RecFields(UNICODE_RECODE.Encoder), "\n"); fi; enc := UNICODE_RECODE.NormalizedEncodings.(enc); return UNICODE_RECODE.Encoder.(enc)(ustr); end); # generic dispatcher for encoding depending on extra data (e.g. used with "URL" InstallOtherMethod(Encode, [IsUnicodeString, IsString, IsObject], function(ustr, enc, data) if not IsBound(UNICODE_RECODE.NormalizedEncodings.(enc)) then Error("Sorry, only the following encodings are supported for Encode:\n", RecFields(UNICODE_RECODE.Encoder), "\n"); fi; enc := UNICODE_RECODE.NormalizedEncodings.(enc); return UNICODE_RECODE.Encoder.(enc)(ustr, data); end); # here the default is UTF-8 encoding InstallMethod(Encode, [IsUnicodeString], function(ustr) return UNICODE_RECODE.Encoder.("UTF-8")(ustr); end); ## <#GAPDoc Label="WidthUTF8String"> ## ## Lengths of UTF-8 strings ## ## ## an integer ## ## Let str be a &GAP; string with text in UTF-8 encoding. There are ## three lengths of such a string which must be distinguished. The ## operation returns the number of ## bytes and so the memory occupied by str. The function returns the number of unicode characters in ## str, that is the length of Unicode(str).

## ## In many applications the function is more ## interesting, it returns the number of columns needed by the string if ## printed to a terminal. This takes into account that some unicode ## characters are combining characters and that there are wide characters ## which need two columns (e.g., for Chinese or Japanese). (To be precise: ## This implementation assumes that there are no control characters in ## str and uses the character width returned by the wcwidth ## function in the GNU C-library called with UTF-8 locale.) ## ## gap> # A, German umlaut u, B, zero width space, C, newline ## gap> str := Encode( Unicode( "A&#xFC;B&#x200B;C\n", "XML" ) );; ## gap> Print(str); ## AüB​C ## gap> # umlaut u needs two bytes and the zero width space three ## gap> Length(str); ## 9 ## gap> NrCharsUTF8String(str); ## 6 ## gap> # zero width space and newline don't contribute to width ## gap> WidthUTF8String(str); ## 4 ## ## ## ## <#/GAPDoc> InstallGlobalFunction(NrCharsUTF8String, function(str) local n, nc, c; n := 0; for c in str do nc := INT_CHAR(c); if nc < 128 or nc > 191 then n := n+1; fi; od; return n; end); InstallGlobalFunction(WidthUTF8String, function(str) local res, pos, i; if not IsUnicodeString(str) then str := Unicode(str, "UTF-8"); fi; str := IntListUnicodeString(str); res := 0; for i in str do if i > 31 and i < 127 then res := res+1; else pos := POSITION_FIRST_COMPONENT_SORTED(WidthUnicodeTable, i); if not IsBound(WidthUnicodeTable[pos]) or WidthUnicodeTable[pos][1] <> i then pos := pos-1; fi; res := res + WidthUnicodeTable[pos][2]; fi; od; return res; end); # Not (yet?) documented utility to translate a latin1 or UTF-8 encoded # GAP string to a string with lowercase ASCII characters. Can be used for # sorting and searching, allowing some freedom for the input of non-ASCII # characters. InstallGlobalFunction(LowerASCIIString, function(str) local u; # heuristic to distinguish UTF-8 and latin1 u := Unicode(str); if u = fail then u := Unicode(str, "latin1"); fi; u := SimplifiedUnicodeString(u, "ASCII"); u := LowercaseUnicodeString(u); return Encode(u); end); # overwrite library method if sensible depending on term encoding and # encoding of string InstallMethod(ViewObj, "IsString", true, [IsString and IsFinite],0, function(s) local u, c; u := Unicode(s, GAPInfo.TermEncoding); if u <> fail then Print("\""); u := IntListUnicodeString(u); for c in u do if c = 34 then Print("\\\""); elif c = 92 then Print("\\\\"); elif c < 32 then Print(SPECIAL_CHARS_VIEW_STRING[2][c+1]); else Print(Encode(Unicode([c]), GAPInfo.TermEncoding)); fi; od; Print("\""); else PrintObj(s); fi; end); GAPDoc-1.5.1/lib/getdtd.g0000644000175000017500000000630512026346064013401 0ustar billbill############################################################################# ## #W getdtd.g GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## This is a utility file for the GAPDoc package, which reads ## gapdoc.dtd, creates the content of `GAPDOCDTDINFO' and writes it to ## `GAPDocDtdInfo.g'. (Because we don't have a dtd-parser.) ## ## This is not read by the package and only used when gapdoc.dtd is ## changed. ## #Revision.getdtd.g := # some hacks instead of writing a dtd-parser dtd := StringFile("gapdoc.dtd");; pos := PositionSublist(dtd, " fail do pos2 := Position(dtd, '>', pos); Add(elementdecs, dtd{[pos+10..pos2-1]}); pos := pos2; pos := PositionSublist(dtd, "', pos); innertxt := WordsString(dtd{[pos+13..pos2]}); txt := Concatenation(innertxt, [ "Enum", "List", "Table" ]); ssent := [ "Subsection", "ManSection" ]; for x in elements do if "InnerText" in elementcontents.(x) then elementcontents.(x) := Concatenation(Difference(elementcontents.(x), ["InnerText"]), innertxt); fi; if "Text" in elementcontents.(x) then elementcontents.(x) := Set(Concatenation(Difference(elementcontents.(x), ["Text"]), txt)); fi; if "SubsectionEnt" in elementcontents.(x) then elementcontents.(x) := Set(Concatenation(Difference(elementcontents.(x), ["SubsectionEnt"]), ssent)); fi; od; pos := PositionSublist(dtd, " fail do pos2 := Position(dtd, '>', pos); Add(elementatts, dtd{[pos+10..pos2-1]}); pos := pos2; pos := PositionSublist(dtd, " not x in WHITESPACE); Add(s,'\n'); FileString("GAPDocDtdInfo.g",s); Read("GAPDocDtdInfo.g"); Print(GAPDOCDTDINFO); GAPDoc-1.5.1/lib/GAPDoc.gd0000644000175000017500000000271612026346064013331 0ustar billbill############################################################################# ## #W GAPDoc.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc.g{d,i} contain some utilities for trees returned by ## ParseTreeXMLString applied to a GAPDoc document. ## DeclareGlobalFunction("CheckAndCleanGapDocTree"); DeclareGlobalFunction("AddParagraphNumbersGapDocTree"); DeclareGlobalFunction("AddPageNumbersToSix"); DeclareGlobalFunction("PrintSixFile"); DeclareGlobalFunction("PrintGAPDocElementTemplates"); DeclareGlobalFunction("TextM"); DeclareGlobalFunction("NormalizedArgList"); ## <#GAPDoc Label="InfoGAPDoc"> ## ## ## ## The default level of this info class is 1. The converter functions ## for &GAPDoc; documents are then ## printing some information. You can suppress this by setting the ## level of to 0. With level 2 there ## may be some more information for debugging purposes. ## ## ## <#/GAPDoc> ## # Info class with default level 1 BindGlobal("InfoGAPDoc", NewInfoClass("InfoGAPDoc")); SetInfoLevel(InfoGAPDoc, 1); if CompareVersionNumbers(GAPInfo.Version, "4.dev") then SetInfoHandler(InfoGAPDoc, PlainInfoHandler); fi; DeclareGlobalVariable("GAPDocTexts"); DeclareGlobalFunction("SetGapDocLanguage"); GAPDoc-1.5.1/lib/bibxmlextinfo.g0000644000175000017500000004374712026346064015013 0ustar billbillBibxmlext := [ rec( string := [ "EMPTY" ], entry := [ "article", "or", "book", "or", "booklet", "or", "manual", "or", "techreport", "or", "mastersthesis", "or", "phdthesis", "or", "inbook", "or", "incollection", "or", "proceedings", "or", "inproceedings", "or", "conference", "or", "unpublished", "or", "misc" ], file := [ [ "string", "or", "entry" ], "repeated" ], article := [ "author", "title", "journal", "year", "volume", "optional", "number", "optional", "pages", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], book := [ [ "author", "or", "editor" ], "title", "publisher", "year", [ "volume", "or", "number" ], "optional", "series", "optional", "address", "optional", "edition", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], booklet := [ "author", "optional", "title", "howpublished", "optional", "address", "optional", "month", "optional", "year", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], conference := [ "author", "title", "booktitle", "year", "editor", "optional", [ "volume", "or", "number" ], "optional", "series", "optional", "pages", "optional", "address", "optional", "month", "optional", "organization", "optional", "publisher", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], inbook := [ [ "author", "or", "editor" ], "title", [ [ "chapter", "pages", "optional" ], "or", "pages" ], "publisher", "year", [ "volume", "or", "number" ], "optional", "series", "optional", "type", "optional", "address", "optional", "edition", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], incollection := [ "author", "title", "booktitle", "publisher", "year", "editor", "optional", [ "volume", "or", "number" ], "optional", "series", "optional", "type", "optional", "chapter", "optional", "pages", "optional", "address", "optional", "edition", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], inproceedings := [ "author", "title", "booktitle", "year", "editor", "optional", [ "volume", "or", "number" ], "optional", "series", "optional", "pages", "optional", "address", "optional", "month", "optional", "organization", "optional", "publisher", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], manual := [ "author", "optional", "title", "organization", "optional", "address", "optional", "edition", "optional", "month", "optional", "year", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], mastersthesis := [ "author", "title", "school", "year", "type", "optional", "address", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], misc := [ "author", "optional", "title", "optional", "howpublished", "optional", "month", "optional", "year", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], phdthesis := [ "author", "title", "school", "year", "type", "optional", "address", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], proceedings := [ "editor", "optional", "title", "year", [ "volume", "or", "number" ], "optional", "series", "optional", "address", "optional", "month", "optional", "organization", "optional", "publisher", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], techreport := [ "author", "title", "institution", "year", "type", "optional", "number", "optional", "address", "optional", "month", "optional", "note", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], unpublished := [ "author", "title", "note", "month", "optional", "year", "optional", "key", "optional", "annotate", "optional", "crossref", "optional", "abstract", "optional", "affiliation", "optional", "contents", "optional", "copyright", "optional", [ "isbn", "or", "issn" ], "optional", "keywords", "optional", "language", "optional", "lccn", "optional", "location", "optional", "mrnumber", "optional", "mrclass", "optional", "mrreviewer", "optional", "price", "optional", "size", "optional", "url", "optional", "category", "optional", "other", "repeated" ], M := [ [ "PCDATA", "or", "Alt" ], "repeated" ], Math := [ [ "PCDATA", "or", "Alt" ], "repeated" ], URL := [ [ "PCDATA", "or", "Alt" ], "repeated" ], value := [ "EMPTY" ], C := [ [ "PCDATA", "or", "value", "or", "Alt", "or", "M", "or", "Math", "or" , "Wrap", "or", "URL" ], "repeated" ], Alt := [ [ "PCDATA", "or", "value", "or", "C", "or", "M", "or", "Math", "or", "Wrap", "or", "URL" ], "repeated" ], Wrap := [ "EMPTY" ], address := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], author := [ [ "name" ], "repeated" ], name := [ "first", "optional", "last" ], first := [ "PCDATA" ], last := [ "PCDATA" ], booktitle := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], chapter := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], edition := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], editor := [ [ "name" ], "repeated" ], howpublished := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], institution := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], journal := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], month := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], note := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], number := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], organization := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], pages := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], publisher := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], school := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], series := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], title := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], type := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], volume := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], year := [ "PCDATA" ], annotate := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], crossref := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], key := [ "PCDATA" ], abstract := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], affiliation := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], contents := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], copyright := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], isbn := [ "PCDATA" ], issn := [ "PCDATA" ], keywords := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], language := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], lccn := [ "PCDATA" ], location := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], mrnumber := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], mrclass := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], mrreviewer := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], price := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], size := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], url := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], category := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ], other := [ [ "PCDATA", "or", "value", "or", "M", "or", "Math", "or", "Wrap", "or", "URL", "or", "C", "or", "Alt" ], "repeated" ] ), rec( string := [ "key", "CDATA", "REQUIRED", "value", "CDATA", "REQUIRED" ], entry := [ "id", "CDATA", "REQUIRED" ], URL := [ "Text", "CDATA", "IMPLIED" ], value := [ "key", "CDATA", "REQUIRED" ], Alt := [ "Only", "CDATA", "IMPLIED", "Not", "CDATA", "IMPLIED" ], Wrap := [ "Name", "CDATA", "REQUIRED" ], other := [ "type", "CDATA", "REQUIRED" ] ) ]; GAPDoc-1.5.1/lib/GAPDoc.gi0000644000175000017500000006601512026346064013340 0ustar billbill############################################################################# ## #W GAPDoc.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc.g{d,i} contain some utilities for trees returned by ## ParseTreeXMLString applied to a GAPDoc document. ## ## <#GAPDoc Label="CheckAndCleanGapDocTree"> ## ## ## nothing ## ## The argument tree of this function is a parse tree from ## of some &GAPDoc; document. This ## function does an (incomplete) validity check of the document ## according to the document type declaration in gapdoc.dtd. ## It also does some additional checks which cannot be described in ## the DTD (like checking whether chapters and sections have a heading). ## For elements with element content the whitespace between these ## elements is removed.

## ## In case of an error the break loop is entered and the position ## of the error in the original XML document is printed. With ## Show(); one can browse the original input in the . ## ## ## <#/GAPDoc> ## # GAPDOCDTDINFO contains essentially the declaration information from # gapdoc.dtd Add(GAPDOCDTDINFO, rec(name := "WHOLEDOCUMENT", attr := [ ], reqattr := [ ], type := "elements", content := ["Book"])); BindGlobal("GAPDOCDTDINFOELS", List(GAPDOCDTDINFO, a-> a.name)); InstallGlobalFunction(CheckAndCleanGapDocTree, function(arg) local r, str, name, pos, type, namc, l, i, namattr, typ, c; # we save orignal XML input string if available (as r.input on top # level and as second argument in recursive calls of this function) # This allows to browse the input if an error occurs. r := arg[1]; if Length(arg) > 1 then str := arg[2]; elif IsBound(r.input) then str := r.input; else str := "input string not available"; fi; name := r.name; if name = "PCDATA" then return true; fi; if Length(name)>2 and name{[1..3]} = "XML" then return true; fi; pos := Position(GAPDOCDTDINFOELS, name); if pos=fail then ParseError(str, r.start, Concatenation("element ", name, " not known")); fi; type := GAPDOCDTDINFO[pos].type; # checking content if type = "empty" then # case that empty element is not input as such if IsList(r.content) and Length(r.content) = 0 then r.content := EMPTYCONTENT; fi; if not r.content = EMPTYCONTENT then ParseError(str, r.start, Concatenation("element ", name, " must be empty")); fi; elif type = "elements" then # white space between elements is ignored r.content := Filtered(r.content, c-> c.name <> "PCDATA" or not ForAll(c.content, x-> x in WHITESPACE)); for c in r.content do namc := c.name; if not ((Length(namc)>2 and namc{[1..3]}="XML") or (namc = "PCDATA" and ForAll(c.content, x-> x in WHITESPACE)) or namc in GAPDOCDTDINFO[pos].content) then ParseError(str, r.start, Concatenation("Wrong element in ", name, ": ", namc)); else fi; od; r.content := Filtered(r.content, a-> a.name <> "PCDATA"); elif type = "mixed" then l := List(r.content, c-> (Length(c.name)>2 and c.name{[1..3]} = "XML") or c.name in GAPDOCDTDINFO[pos].content); if false in l then ParseError(str, r.start, Concatenation("Wrong element in ", name, ": ", r.content[Position(l, false)].name)); fi; # compactifying sequences of PCDATA entries i := 1; while i < Length(r.content) do if r.content[i].name = "PCDATA" and r.content[i+1].name = "PCDATA" then Append(r.content[i].content, r.content[i+1].content); r.content := r.content{Concatenation([1..i], [i+2..Length(r.content)])}; else i := i + 1; fi; od; fi; # checking existing attributes: namattr := NamesOfComponents(r.attributes); for c in namattr do if not c in GAPDOCDTDINFO[pos].attr then ParseError(str, r.start, Concatenation("Attribute ", c, " not declared for ", name)); fi; od; # checking required attributes for c in GAPDOCDTDINFO[pos].reqattr do if not c in namattr then ParseError(str, r.start, Concatenation("Attribute ", c, " must be given in element ", name)); fi; od; # some extra checks if name = "Ref" then if IsBound(r.attributes.BookName) and not IsBound(r.attributes.Label) then typ := Difference(NamesOfComponents(r.attributes), ["BookName", "Style", "Text"]); if Length(typ) <> 1 then ParseError(str, r.start, Concatenation( "Ref with strange attribute set: ", typ)); fi; fi; elif name in [ "Chapter", "Section", "Subsection" ] and not "Heading" in List(r.content, a-> a.name) then ParseError(str, r.start, "Chapter, Section or Subsection must have a heading"); fi; if r.content = EMPTYCONTENT then return true; else return ForAll(r.content, x-> CheckAndCleanGapDocTree(x, str)); fi; end); ## <#GAPDoc Label="AddParagraphNumbersGapDocTree"> ## ## ## nothing ## ## The argument tree must be an XML tree returned by applied to a &GAPDoc; document. This ## function adds to each node of the tree a component .count ## which is of form [Chapter[, Section[, Subsection, Paragraph] ] ## ]. Here the first three numbers should be the same as ## produced by the &LaTeX; version of the document. Text before the ## first chapter is counted as chapter 0 and similarly for ## sections and subsections. Some elements are always considered to ## start a new paragraph. ## ## ## <#/GAPDoc> ## InstallGlobalFunction(AddParagraphNumbersGapDocTree, function(r) local parels, cssp, setcount; if IsBound(r.count) then return; fi; # these elements are paragraphs parels := [ "List", "Enum", "Table", "Item", "Heading", "Attr", "Fam", "Filt", "Func", "InfoClass", "Meth", "Oper", "Prop", "Var", "Display", "Example", "Listing", "Log", "Verb", "Address", "TitleComment"]; # reset counter cssp := [0, 0, 0, 1]; # the counter setting recursive function setcount := function(rr) local a; if rr.name <> "Ignore" and IsList(rr.content) and not IsString(rr.content) then for a in rr.content do # new chapter, text before first section is counted as section 0 if a.name = "Chapter" then cssp := [cssp[1]+1, 0, 0, 1]; a.count := cssp; elif a.name = "Section" then cssp := [cssp[1], cssp[2]+1, 0, 1]; elif a.name in ["Subsection", "ManSection", "Abstract", "Copyright", "TableOfContents", "Acknowledgements", "Colophon"] then cssp := [cssp[1], cssp[2], cssp[3]+1, 1]; elif a.name in ["P", "Par"] or a.name in parels then cssp := [cssp[1], cssp[2], cssp[3], cssp[4]+1]; elif a.name = "Appendix" then # here we number with capital letters if IsInt(cssp[1]) then cssp := ["A", 0, 0, 1]; else cssp := [[CHAR_INT(INT_CHAR(cssp[1][1])+1)], 0, 0, 1]; ConvertToStringRep(cssp[1]); fi; # bib and index are counted as new chapters elif a.name = "Bibliography" then cssp := ["Bib", 0, 0, 1]; elif a.name = "TheIndex" then cssp := ["Ind", 0, 0, 1]; fi; a.count := cssp; # recursion setcount(a); if a.name in parels then cssp := [cssp[1], cssp[2], cssp[3], cssp[4]+1]; fi; od; fi; end; r.count := cssp; setcount(r); end); ## <#GAPDoc Label="AddPageNumbersToSix"> ## ## ## nothing ## ## Here tree must be the XML tree of a &GAPDoc; ## document, returned by . ## Running latex on the result of GAPDoc2LaTeX(tree) ## produces a file pnrfile (with ## extension .pnr). The command GAPDoc2Text(tree) ## creates a component tree.six ## which contains all information about the document for the &GAP; ## online help, except the page numbers in the .dvi, .ps, ## .pdf versions of the document. This command adds the missing ## page number information to tree.six. ## ## ## <#/GAPDoc> ## PAGENRS := 0; InstallGlobalFunction(AddPageNumbersToSix, function(r, pnrfile) local six, a, pos; Read(pnrfile); six := r.six; for a in six do pos := Position(PAGENRS, a[3]); a[5] := PAGENRS[pos+1]; od; Unbind(PAGENRS); end); ## <#GAPDoc Label="PrintSixFile"> ## ## ## nothing ## ## This function prints the .six file fname for ## a &GAPDoc; document stored in tree with name ## bookname. Such a file contains all information about the ## book which is needed by the &GAP; online help. This information ## must first be created by calls of and ## . ## ## ## <#/GAPDoc> ## InstallGlobalFunction(PrintSixFile, function(file, r, bookname) local f; f := function(a) local res; res := ShallowCopy(a); res[2] := STRING_LOWER(res[2]); return res; end; PrintTo(file, "#SIXFORMAT GapDocGAP\nHELPBOOKINFOSIXTMP := rec(\n", "encoding := \"UTF-8\",\n", "bookname := \"", bookname, "\",\n", "entries :=\n", List(r.six, f), "\n);\n"); end); # non-documented utility ## This prints templates for all elements (e.g., for editor helper functions) InstallGlobalFunction(PrintGAPDocElementTemplates, function ( file ) local a, x; PrintTo(file, "<-- Templates for GAPDoc XML Elements -->\n"); Sort(GAPDOCDTDINFO, function(a,b) return a.name#\n\n"); else AppendTo(file, ">XXX#\n\n" ); fi; od; return; end); # these are simple translations from former GAPDoc version, below we add # more using unicode characters BindGlobal("TEXTMTRANSLATIONS", rec( ldots := "...", mid := "|", vert := "|", left := "", right := "", mathbb := "", mathop := "", limits := "", cdot := "*", ast := "*", geq := ">=", leq := "<=", neq := "<>", pmod := "mod ", bmod := "mod ", equiv := "=", sim := "~", rightarrow := "->", hookrightarrow := "->", to := "->", longrightarrow := "-->", Rightarrow := "=>", Longrightarrow := "==>", Leftarrow := "<=", iff := "<=>", mapsto := "->", # "|->" looks ugly! leftarrow := "<-", langle := "<", prime := "'", rangle := ">", vee := "v", setminus := "\\", times := "x", colon := ":", bf := "", rm := "", textrm := "", sf := "", germ := "", text := "", thinspace := " ", \, := "", \! := "", \; := " ", \{ := "{", \} := "}", ) ); # add more text M translations using unicode characters, for those of these # unicode characters which do not yet have a simplification, we add their # LaTeX code as simplification to SimplifiedUnicodeTable (sometimes without # the leading backslash) GAPInfo.addMoreTEXTMUnicode := function() local hash, s, str, pos, a; hash := List(SimplifiedUnicodeTable, a-> a[1]); # the candidates to add are found in the LaTeXUnicodeTable for a in LaTeXUnicodeTable do if a[1] < 100000 and PositionSublist(a[2], "\\ensuremath") <> fail then s := ShallowCopy(a[2]); s := SubstitutionSublist(s, "\\ensuremath", ""); RemoveCharacters(s, "{}"); if not (s[1] <> '\\' or (Length(Positions(s, '\\')) > 1 and s{[1..5]}<>"\\not\\") or ' ' in s) then str := Encode(Unicode([a[1]]), "UTF-8"); pos := Position(hash, a[1]); TEXTMTRANSLATIONS.(s{[2..Length(s)]}) := str; if pos = fail then # for greek letters and a few more we simplify without backslash if (913 <= a[1] and 1014 >= a[1]) or a[1] in [8465,8476,8501,8502, 8503,8504,8707,8710,8711,8712] then s := s{[2..Length(s)]}; fi; Add(SimplifiedUnicodeTable, [a[1], IntListUnicodeString(Unicode(s))]); fi; fi; fi; od; Sort(SimplifiedUnicodeTable); end; GAPInfo.addMoreTEXTMUnicode(); Unbind(GAPInfo.addMoreTEXTMUnicode); InstallGlobalFunction(TextM, function(str) local subs, res, i, j; subs := Immutable(Set(NamesOfComponents(TEXTMTRANSLATIONS))); res := ""; i := 1; while i <= Length(str) do # handle macros if str[i] = '\\' then j := i+1; while j <= Length(str) and str[j] in LETTERS do j := j+1; od; # we go on if we have a \not so far if j = i+4 and j <= Length(str) and str[j] = '\\' and str{[i+1..i+3]} = "not" then j := j+1; while j <= Length(str) and str[j] in LETTERS do j := j+1; od; fi; # some spacing macros and braces if j = i+1 and str[j] in ";,!{}" then j := j+1; fi; if str{[i+1..j-1]} in subs then Append(res, TEXTMTRANSLATIONS.(str{[i+1..j-1]})); else Append(res, str{[i+1..j-1]}); fi; i := j; elif str[i] = '{' then if i < Length(str) and str[i+1] = '{' then Add(res, '{'); i := i + 2; else i := i + 1; fi; elif str[i] = '}' then if i < Length(str) and str[i+1] = '}' then Add(res, '}'); i := i + 2; else i := i + 1; fi; else Add(res, str[i]); i := i + 1; fi; od; NormalizeWhitespace(res); return res; end); # non-documented utility ## normalizes the Args attribute in function like elements InstallGlobalFunction(NormalizedArgList, function(argl) local pos, opt, f, tr, g; # first optional arguments pos := Position(argl, ':'); if pos <> fail then opt := argl{[pos+1..Length(argl)]}; argl := argl{[1..pos-1]}; opt := SubstitutionSublist(opt, ":=", " := "); NormalizeWhitespace(opt); opt := SubstitutionSublist(opt, " := ", "OPTIONASSxpty"); opt := NormalizedArgList(opt); opt := SubstitutionSublist(opt, "OPTIONASSxpty", " := "); else opt := ""; fi; # remove ',' and split into tree argl := NormalizedWhitespace(SubstitutionSublist(argl, ",", " ")); argl := SubstitutionSublist(argl, "[]", ""); argl := SubstitutionSublist(argl, "[ ]", ""); f := function(argl) local tr, pos, pos2; tr := []; pos := 0; while true do pos2 := Position(argl, '[', pos); if pos2 <> fail then Append(tr, SplitString(argl{[pos+1..pos2-1]}, "", " ")); pos := pos2; pos2 := PositionMatchingDelimiter(argl, "[]", pos); Add(tr, f(argl{[pos+1..pos2-1]})); pos := pos2; else Append(tr, SplitString(argl{[pos+1..Length(argl)]}, "", " ")); return tr; fi; od; end; tr := f(argl); # put it back in a string with ','s and '[]'s in the right places g := function(tr, ne) local res, r, a, pos; res := ""; for a in tr do if IsString(a) then if ne then Append(res, ", "); elif Length(res) > 0 then ## Append(res, "[,]"); pos := Length(res); while pos > 0 and res[pos] in " []," do pos := pos - 1; od; Add(res, ',', pos+1); Add(res, ' ', pos+2); fi; ne := true; Append(res, a); else r := Concatenation("[", g(a, ne), "]"); if not ne and Length(res) > 0 then ## Append(res, "[,]"); pos := Length(res); while pos > 0 and res[pos] in " []," do pos := pos - 1; od; Add(res, ',', pos+1); Add(res, ' ', pos+2); fi; Append(res, r); fi; od; return res; end; tr := g(tr, false); if Length(opt) > 0 then Append(tr, ": "); Append(tr, opt); fi; return tr; end); # shared utility for the converters to read data for bibliography BindGlobal("GAPDocAddBibData", function(r) local dat, datbt, bib, bibbt, b, keys, need, labels, tmp, pos, diff, a, j; if IsBound(r.bibentries) and IsBound(r.biblabels) then return; fi; Info(InfoGAPDoc, 1, "#I Reading bibliography data files . . . \n"); dat := SplitString(r.bibdata, "", ", \t\b\n"); datbt := Filtered(dat, a-> Length(a) < 4 or a{[Length(a)-3..Length(a)]} <> ".xml"); bib := rec(entries := [], strings := [], entities := []); # first BibTeX files, then BibXMLext files if Length(datbt) > 0 then Info(InfoGAPDoc, 1, "#I BibTeX format: ", JoinStringsWithSeparator(datbt), "\n"); bibbt := CallFuncList(ParseBibFiles, List(datbt, f-> Filename(r.bibpath, f))); Info(InfoGAPDoc, 1, "#I checking and translating to BibXMLext . . .\n"); for a in bibbt[1] do b := StringBibAsXMLext(a, bibbt[2], bibbt[3]); if b <> fail then b := ParseBibXMLextString(b, bib); fi; od; fi; dat := Difference(dat, datbt); if Length(dat) > 0 then Info(InfoGAPDoc, 1, "#I BibXMLext format: ", JoinStringsWithSeparator(dat), "\n"); dat := List(dat, f-> Filename(r.bibpath, f)); CallFuncList(ParseBibXMLextFiles, Concatenation(dat, [bib])); fi; keys := Immutable(Set(r.bibkeys)); need := []; for a in bib.entries do if a.attributes.id in keys then Add(need, a); fi; od; need := List(need, a-> [a, RecBibXMLEntry(a, "Text")]); SortParallel(List(need, a-> SortKeyRecBib(a[2])), need); keys := List(need, a-> a[2].Label); labels := List(need, function(a) if IsBound(a[2].key) then return a[2].key; else return a[2].printedkey; fi; end); # make labels unique tmp := Filtered(Collected(labels), a-> a[2] > 1); for a in tmp do pos := Positions(labels, a[1]); for j in [1..Length(pos)] do Add(labels[pos[j]], SMALLLETTERS[j]); od; od; diff := Difference(r.bibkeys, keys); if Length(diff) > 0 then Info(InfoGAPDoc, 1, "#W WARNING: could not find these references: \n", diff, "\n"); fi; r.bibkeys := keys; r.biblabels := labels; r.bibentries := List(need, a-> a[1]); r.bibstrings := bib.strings; if Length(r.bibstrings) = 0 then # to avoid that this is an empty string r.bibstrings := [[0,0]]; fi; end); ## <#GAPDoc Label="SetGapDocLanguage"> ## ## ## nothing ## ## Using &GAPDoc; with other languages ## The &GAPDoc; converter programs sometimes produce text which is ## not explicit in the document, e.g., headers like Abstract, ## Appendix, links to Next Chapter, variable types ## function and so on.

## With the language for these texts can be ## changed. The argument lang must be a string. Calling without ## argument or with a language name for which no translations are available ## is the same as using the default "english".

## If your language lang is not yet available, look at the record ## GAPDocTexts.english and translate all the strings to lang. ## Then assign this record to GAPDocTexts.(lang) and send ## it to the &GAPDoc; authors for inclusion in future versions of ## &GAPDoc;. (Currently, there are translations for english, ## german, russian and ukrainian.)

## ## Further hints: To get strings produced by &LaTeX; ## right you will probably use the babel package with option ## lang, see the information on ExtraPreamble in . If lang cannot be encoded in latin1 ## encoding you can consider the use of "utf8" with . ## ## ## <#/GAPDoc> # language dependent string used in converted documents InstallValue(GAPDocTexts, rec()); # default is english GAPDocTexts.english := rec( # for title page Titlepage := "Title page", Abstract := "Abstract", Copyright := "Copyright", Contents := "Contents", Email := "Email", Homepage := "Homepage", Address := "Address", Acknowledgements := "Acknowledgements", Colophon := "Colophon", # HTML navigation GotoChapter := "Goto Chapter", TopofBook := "Top of Book", PreviousChapter := "Previous Chapter", NextChapter := "Next Chapter", Top := "Top", # sectioning Chapter := "Chapter", Appendix := "Appendix", Index := "Index", References := "References", Bibliography := "Bibliography", TableofContents := "Table of Contents", # Other Returns := "Returns", Example := "Example", Log := "Example", Table := "Table", # variable types, should these be translated? Func := "function", Oper := "operation", Meth := "method", Filt := "filter", Prop := "property", Attr := "attribute", Var := "global variable", Fam := "family", InfoClass := "info class", ); InstallGlobalFunction(SetGapDocLanguage, function(arg) local lang; if Length(arg) > 0 then lang := arg[1]; else lang := "english"; fi; lang := LowercaseString(lang); if not IsBound(GAPDocTexts.(lang)) then Info(InfoGAPDoc, 1, "#W No texts in language ", lang, " available - ", "using English.\n"); Info(InfoGAPDoc, 1, "#W Please, provide translation of GAPDocTexts.", "english in GAPDocTexts.", lang, ".\n"); lang := "english"; fi; GAPDocTexts.d := GAPDocTexts.(lang); end); # default SetGapDocLanguage(); # translation to Russian and Ukrainian, provided by Alexander Konovalov GAPDocTexts.russian := rec( # for title page Titlepage := "Титульная страница", Abstract := "Реферат", Copyright := "Copyright", # internationally recognized Contents := "Содержание", Email := "Email", # internationally recognized Homepage := "WWW", # internationally recognized Address := "Адрес", Acknowledgements := "Благодарности", Colophon := "Выходные данные", # HTML navigation GotoChapter := "Перейти к главе", TopofBook := "Начало книги", PreviousChapter := "Предыдущая глава", NextChapter := "Следующая глава", Top := "Начало", # sectioning Chapter := "Глава", Appendix := "Приложение", Index := "Индекс", References := "Ссылки", Bibliography := "Библиография", TableofContents := "Содержание", # Other Returns := "Результат", # The Russian word for "Returns" is actually the translation of "Result", # hope this does not make any harm in the context. Example := "Пример", Log := "Пример", Table := "Таблица", # variable types, should these be translated? Func := "функция", Oper := "операция", Meth := "метод", Filt := "фильтр", Prop := "свойство", Attr := "атрибут", Var := "глобальная переменная", Fam := "семейство", InfoClass := "инфокласс", ); GAPDocTexts.ukrainian := rec( # for title page Titlepage := "Титульна сторінка", Abstract := "Реферат", Copyright := "Copyright", # internationally recognized Contents := "Зміст", Email := "Email", # internationally recognized Homepage := "WWW", # internationally recognized Address := "Адреса", Acknowledgements := "Подяки", Colophon := "Вихідні дані", # HTML navigation GotoChapter := "Перейти до розділу", TopofBook := "Початок книги", PreviousChapter := "Попередній розділ", NextChapter := "Наступний розділ", Top := "Початок", # sectioning Chapter := "Розділ", Appendix := "Додаток", Index := "Індекс", References := "Посилання", Bibliography := "Бібліографія", TableofContents := "Зміст", # Other Returns := "Результат", # The Ukrainian word for "Returns" is actually the translation of "Result", # hope this does not make any harm in the context. Example := "Приклад", Log := "Приклад", Table := "Таблиця", # variable types, should these be translated? Func := "функція", Oper := "операція", Meth := "метод", Filt := "фільтр", Prop := "властивість", Attr := "атрибут", Var := "глобальна змінна", Fam := "родина", InfoClass := "інфоклас", ); # ok, I can do this one GAPDocTexts.german := rec( # for title page Titlepage := "Titelseite", Abstract := "Zusammenfassung", Copyright := "Copyright", Contents := "Inhalt", Email := "Email", Homepage := "WWW", Address := "Adresse", Acknowledgements := "Danksagungen", Colophon := "Kolofon", # HTML navigation GotoChapter := "Zum Kapitel", TopofBook := "Buchanfang", PreviousChapter := "Voriges Kapitel", NextChapter := "Nächstes Kapitel", Top := "Nach oben", # sectioning Chapter := "Kapitel", Appendix := "Anhang", Index := "Stichwortverzeichnis", References := "Literatur", Bibliography := "Literatur", TableofContents := "Inhaltsverzeichnis", # Other Returns := "Gibt zurück", Example := "Beispiel", Log := "Beispiel", Table := "Tabelle", # variable types, should these be translated? Func := "Funktion", Oper := "Operation", Meth := "Methode", Filt := "Filter", Prop := "Eigenschaft", Attr := "Attribut", Var := "globale Variable", Fam := "Familie", InfoClass := "Info-Klasse", ); GAPDoc-1.5.1/lib/GAPDoc2Text.gi0000644000175000017500000017563212026346064014275 0ustar billbill############################################################################# ## #W GAPDoc2Text.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2Text.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document a text version for viewing the ## document on screen (GAP online help). ## ## ## We add a link to the document root to all recursively called functions ## by adding .root entries. The toc-, index- and bib-information is ## collected in the root. ## ## The set of elements is partitioned into two subsets - those which ## contain whole paragraphs and those which don't. ## ## The handler of a paragraph containing element (see ## GAPDoc2TextProcs.ParEls below) gets a list as argument to which it adds ## entries pairwise: the first of such a pair is the paragraph counter ## (like [3,2,1,5] meaning Chap.3, Sec.2, Subsec.1, Par.5) and the second ## is the formatted text of this paragraph. ## ## Some handlers of paragraph containing elements do the formatting ## themselves (e.g., .List), the others are handled in the main recursion ## function 'GAPDoc2TextContent'. ## ## We produce a full version of the document in text format, including ## title page, abstract and other front matter, table of contents, ## bibliography (via BibTeX-data files) and index. Highlighting with ## colors for ANSI color sequence capable terminals is included. ## ## In this text converter we also produce the manual.six data. For ## getting page numbers in .dvi and .pdf versions, the LaTeX-converter ## and LaTeX must be run first. This produces a .pnr file. ## InstallValue(GAPDoc2TextProcs, rec()); ## Some text attributes for display on ANSI terminals ## We do all the formatting with not used escape sequences of form ## [X. These are substituted by user configurable sequences ## before an actual display. ## ## the actual themes are in the file TextThemes.g ## ## <#GAPDoc Label="SetGAPDocTextTheme"> ## ## ## nothing ## ## This utility function is for readers of the screen version of &GAP; ## manuals which are generated by the &GAPDoc; package. It allows to ## configure the color and attribute layout of the displayed text. ## There is a default which can be reset by calling this function ## without argument.

## ## As an abbreviation the arguments optrec1 and so on can be ## strings for the known name of a theme. Information about valid ## names is shown with SetGAPDocTextTheme("");.

## ## Otherwise, optrec1 and so on must be a record. Its entries ## overwrite the corresponding entries in the default and in previous ## arguments. To construct valid markup you ## can use . Entries must be either pairs of ## strings, which are put before and after the corresponding text, or ## as an abbreviation it can be a single string. In the latter case, ## the second string is implied; if the string contains an escape ## sequence the second string is TextAttr.reset, otherwise the ## given string is used. The following components are recognized: ## ## ## flush"both" for left-right justified ## paragraphs, and "left" for ragged right ones ## Headingchapter and (sub-)section headings ## Funcfunction, operation, ... names ## Argargument names in descriptions ## Exampleexample code ## Packagepackage names ## ReturnsReturns-line in descriptions ## URLURLs ## MarkMarks in description lists ## K&GAP; keywords ## Ccode or text to type ## Ffile names ## Bbuttons ## Msimplified math elements ## Mathnormal math elements ## Displaydisplayed math elements ## Emphemphasized text ## Qquoted text ## Refreference text ## Prompt&GAP; prompt in examples ## BrkPrompt&GAP; break prompt in examples ## GAPInput&GAP; input in examples ## resetreset to default, don't change this ## BibAuthorauthor names in bibliography ## BibTitletitles in bibliography ## BibJournaljournal names in bibliography ## BibVolumevolume number in bibliography ## BibLabellabels for bibliography entries ## BibResetreset for bibliography, ## don't change ## ListBulletbullet for simple lists (2 ## visible characters long) ## EnumMarksone visible character before and ## after the number in enumerated lists ## DefLineMarkermarker before function and variable ## definitions (2 visible characters long) ## FillStringfor filling in definitions and ## example separator lines ## ## ## ## gap> # use no colors for GAP examples and ## gap> # change display of headings to bold green ## gap> SetGAPDocTextTheme("noColorPrompt", ## > rec(Heading:=Concatenation(TextAttr.bold, TextAttr.2))); ## ## ## ## <#/GAPDoc> ## # used fields GAPDoc2TextProcs.TextAttrFields := [ "reset", "Heading", "Func", "Arg", "Example", "Package", "Returns", "URL", "Mark", "K", "C", "F", "B", "Emph", "Ref", "BibReset", "BibAuthor", "BibTitle", "BibJournal", "BibVolume", "BibLabel", "Q", "M", "Math", "Display", "Prompt", "BrkPrompt", "GAPInput", "GAPOutput", "DefLineMarker", "ListBullet", "EnumMarks", "FillString", "format", "flush" ]; ## We produce a text document with markup that is ignored by terminals, ## this can be substituted on the fly before display according to the ## current GAPDocTextTheme. GAPDoc2TextProcs.TextAttr := rec(); GAPDoc2TextProcs.TextAttr.f := function() local i, l, fs; fs := GAPDoc2TextProcs.TextAttrFields; l := Length(fs); # begin and end markers ESC[(i)X and ESC[(i+100)X for i in [1..l] do GAPDoc2TextProcs.TextAttr.(fs[i]) := [Concatenation(TextAttr.CSI, String(i-1), "X"), Concatenation(TextAttr.CSI, String(100+i-1), "X")]; od; end; GAPDoc2TextProcs.TextAttr.f(); Unbind(GAPDoc2TextProcs.TextAttr.f); GAPDoc2TextProcs.ParEls := [ "Display", "Example", "Log", "Listing", "List", "Enum", "Item", "Table", "TitlePage", "Address", "TitleComment", "Abstract", "Copyright", "Acknowledgements", "Colophon", "TableOfContents", "Bibliography", "TheIndex", "Subsection", "ManSection", "Description", "Returns", "Section", "Chapter", "Appendix", "Body", "Book", "WHOLEDOCUMENT", "Attr", "Fam", "Filt", "Func", "Heading", "InfoClass", "Meth", "Oper", "Prop", "Var", "Verb" ]; ## arg: a list of strings ## nothing for now, may be enhanced and documented later. SetGapDocTxtOptions := function(arg) local gdp; gdp := GAPDoc2TextProcs; return; end; ## here we collect paragraphs to whole chapters and remember line numbers ## of subsections for the .six information GAPDoc2TextProcs.PutFilesTogether := function(l, six) local countandshift, concat, files, n, i, p, a, tmp; # count number of lines in txt and add 2 spaces in the beginning of # each line, returns [newtxt, nrlines] countandshift := function(txt) local new, ind, n, p, pos; # sometimes there may occur paragraph elements inside text elements # (like list in list item) - we concatenate the text here. concat := function(txt) local new, a; if not IsString(txt) then new := ""; for a in txt do if IsChar(a) then Add(new, a); elif IsList(a) then Append(new, concat(a)); fi; od; else new := txt; fi; ConvertToStringRep(new); return new; end; txt := concat(txt); new := " "; ind := " "; n := 0; p := 0; pos := Position(txt, '\n'); while pos <> fail do Append(new, txt{[p+1..pos]}); if pos < Length(txt) then Append(new, ind); fi; n := n+1; p := pos; pos := Position(txt, '\n', p); od; if p < Length(txt) then Append(new, txt{[p+1..Length(txt)]}); fi; return [new, n]; end; # putting the paragraphs together (one string (file) for each chapter) files := rec(); for n in Set(List([2,4..Length(l)], i-> l[i-1][1])) do files.(n) := rec(text := "", ssnr := [], linenr := [], len := 0); od; for i in [2,4..Length(l)] do n := files.(l[i-1][1]); p := countandshift(l[i]); if Length(n.ssnr)=0 or l[i-1]{[1..3]} <> n.ssnr[Length(n.ssnr)] then Add(n.ssnr, l[i-1]{[1..3]}); Add(n.linenr, n.len+1); fi; Append(n.text, p[1]); n.len := n.len + p[2]; od; # - add line numbers to six information # - add simplified strings for searching # - add hash strings of the latter for links in HTML and PDF version # (such that links remain stable as long as the (sub)section exists # and stays in the same chapter) Info(InfoGAPDoc, 1, "#I Producing simplified search strings and labels ", "for hyperlinks . . .\n"); tmp := ShallowCopy(six); SortParallel(List([1..Length(tmp)], i-> [tmp[i][3],i]), tmp); for i in [1..Length(six)] do a := tmp[i]; p := Position(files.(a[3][1]).ssnr, a[3]); if p = fail then Error("don't find subsection ", a[3], " in text documention"); fi; Add(a, files.(a[3][1]).linenr[p]); a[6] := SIMPLE_STRING(StripEscapeSequences(a[1])); NormalizeWhitespace(a[6]); # the 'X' is to start with a proper letter, since this will be used # for ID type attributes; we use the same label for all entries with # the same subsection number if i > 1 and a[3] = tmp[i-1][3] then a[7] := tmp[i-1][7]; else a[7] := Concatenation("X", HexStringInt(CrcText(a[6])+2^31), HexStringInt(CrcText(Reversed(a[6]))+2^31)); fi; od; return files; end; ## <#GAPDoc Label="GAPDoc2Text"> ## ## ## record containing text files as strings and other ## information ## ## The argument tree for this function is a tree ## describing a &GAPDoc; XML document as returned by (probably also checked with ). This function produces a text ## version of the document which can be used with &GAP;'s online ## help (with the "screen" viewer, see ). It includes title page, bibliography ## and index. The bibliography is made from BibXMLext or &BibTeX; ## databases, see . ## Their location must be given with the argument bibpath (as ## string or directory object).

## ## The output is a record with one component for each chapter ## (with names "0", "1", ..., "Bib" and ## "Ind"). Each such component is again a record with ## the following components: ## ## ## text ## the text of the whole chapter as a string ## ssnr ## list of subsection numbers in this chapter (like [3, 2, ## 1] for chapter 3, section 2, subsection 1) ## ## linenr ## corresponding list of line numbers where the subsections ## start ## len ## number of lines of this chapter ## ## ## The result can be written into files with the command .

## ## As a side effect this function also produces the ## manual.six information which is used for searching in ## &GAP;'s online help. This is stored in tree.six ## and can be printed into a manual.six file with ## (preferably after producing a ## &LaTeX; version of the document as well and adding the ## page number information to tree.six, see and ).

## ## The text produced by this function contains some markup via ## ANSI escape sequences. The sequences used here are usually ## ignored by terminals. But the &GAP; help system will substitute ## them by interpreted color and attribute sequences (see ) before displaying them. There is a default ## markup used for this but it can also be configured by the ## user, see . Furthermore, the text ## produced is in UTF-8 encoding. The encoding is also translated on ## the fly, if GAPInfo.TermEncoding is set to some encoding ## supported by , e.g., "ISO-8859-1" or ## "latin1".

## ## With the optional argument width a different length of the ## output text lines can be chosen. The default is 76 and all lines ## in the resulting text start with two spaces. This looks good on a ## terminal with a standard width of 80 characters and you probably ## don't want to use this argument. ## ## ## <#/GAPDoc> ## # the basic call, used recursively with a result r from GetElement # and a string str or list l to which the output should be appended # arg: r[, linelength] (then a list is returned, only for whole document) # or: r, str[, linelength] (then the output is appended to string or # list str) InstallGlobalFunction(GAPDoc2Text, function(arg) local r, str, linelength, name; r := arg[1]; if Length(arg)=2 and (IsList(arg[2]) or (r.name = "WHOLEDOCUMENT" and IsDirectory(arg[2]))) then str := arg[2]; linelength := 76; elif Length(arg)=2 and IsInt(arg[2]) then linelength := arg[2]; str := ""; elif Length(arg)=3 then str := arg[2]; linelength := arg[3]; else str := ""; linelength := 76; fi; if r.name = "WHOLEDOCUMENT" then r.linelength := linelength; r.indent := ""; if IsDirectory(str) then r.bibpath := str; else if Length(str) = 0 then str := "."; fi; r.bibpath := Directory(str); fi; str := ""; fi; name := r.name; if not IsBound(GAPDoc2TextProcs.(name)) then Info(InfoGAPDoc, 1, "#W WARNING: Don't know how to process element ", name, " ---- ignored\n"); else GAPDoc2TextProcs.(r.name)(r, str); fi; if r.name = "WHOLEDOCUMENT" then # generate sorted list of counts from .six entries, makes LaTeX and HTML # converter much faster on large documents r.sixcount := List(r.six, a-> a[3]); r.sixindex := [1..Length(r.six)]; SortParallel(r.sixcount, r.sixindex); # put final record together and return it, also add line numbers to # .six entries return GAPDoc2TextProcs.PutFilesTogether(str, r.six); fi; return str; end); ## to format paragraph which can be reformatted before display GAPDoc2TextProcs.MarkAndFormat := function(str, flush, indlen, len) local f, fnr, res, par; # only handle non-empty strings if flush = "auto" then f := "both"; fnr := 0; elif flush = "left" then f := flush; fnr := 1; elif flush = "center" then f := flush; fnr := 2; fi; par := FormatParagraph(str, len - indlen, f, [RepeatedString(" ", indlen), ""], WidthUTF8String); if Length(par) = 0 then return ""; fi; res := Concatenation(TextAttr.CSI,String(fnr),";",String(indlen),"Y", par{[indlen+1..Length(par)-1]}); res := Concatenation(par{[1..indlen]}, WrapTextAttribute(res, GAPDoc2TextProcs.TextAttr.format), "\n"); return res; end; ## recursion through the tree and formatting paragraphs BindGlobal("GAPDoc2TextContent", function(r, l) local tmp, par, cont, count, s, a; # inline needed Alt elements if IsList(r.content) and ForAny(r.content, a-> IsRecord(a) and a.name = "Alt") then tmp := r.content; r := ShallowCopy(r); r.content := []; for a in tmp do if IsRecord(a) and a.name = "Alt" then if GAPDoc2TextProcs.AltYes(a) then Append(r.content, a.content); fi; else Add(r.content, a); fi; od; fi; # utility: append counter and formatted paragraph to l par := function(s, name) local sn, ss, pos; # extra call for each part until a forced line break pos := Position(s, '\004'); sn := ""; while pos <> 0 do if pos = fail then ss := s; pos := 0; else ss := s{[1..pos-1]}; s := s{[pos+1..Length(s)]}; pos := Position(s, '\004'); fi; Append(sn, GAPDoc2TextProcs.MarkAndFormat(ss, "auto", Length(r.root.indent), r.root.linelength)); od; if Length(sn)>0 then GAPDoc2TextProcs.P(0, sn); Add(l, count); Add(l, sn); fi; end; # if not containing paragraphs, then l is string to append to if not r.name in GAPDoc2TextProcs.ParEls then for a in r.content do GAPDoc2Text(a, l); od; return; fi; # otherwise we have to collect text and paragraphs cont := r.content; count := r.count; s := ""; for a in cont do if a.count <> count then par(s, a.name); count := a.count; s := ""; fi; if a.name in GAPDoc2TextProcs.ParEls then # recursively collect paragraphs GAPDoc2Text(a, l); else # collect text for current paragraph GAPDoc2Text(a, s); fi; od; if Length(s)>0 then par(s, 0); fi; end); ## write head and foot of Txt file. GAPDoc2TextProcs.WHOLEDOCUMENT := function(r, par) local i, pi, t, el, str, dat, datbt, bib, b, keys, need, labels, tmp, pos, j, diff, text, stream, a, ansi; ## add paragraph numbers to all nodes of the document AddParagraphNumbersGapDocTree(r); ## add a link .root to the root of the document to all nodes ## (then we can collect information about indexing and so on ## there) AddRootParseTree(r); r.index := []; r.toc := ""; r.labels := rec(); r.labeltexts := rec(); r.bibkeys := []; # and the .six information for the online help index # will contain pairs [string, [chap, sect, subsect]] r.six := []; ## checking for processing instructions before the book starts ## example: i := 1; pi := rec(); while not r.content[i].name = "Book" do if r.content[i].name = "XMLPI" then t := r.content[i].content; if Length(t) > 3 and t{[1..4]} = "Txt " then el := GetSTag(Concatenation("<", t, ">"), 2); for a in NamesOfComponents(el.attributes) do pi.(a) := el.attributes.(a); od; fi; fi; i := i+1; od; ## Now the actual work starts, we give the processing instructions found ## so far to the Book handler. ## We call the Book handler twice and produce index, bibliography, toc ## in between. Info(InfoGAPDoc, 1, "#I First run, collecting cross references, ", "index, toc, bib and so on . . .\n"); # with this flag we avoid unresolved references warnings in first run GAPDoc2TextProcs.FirstRun := true; GAPDoc2TextProcs.Book(r.content[i], "", pi); GAPDoc2TextProcs.FirstRun := false; # now the toc is ready Info(InfoGAPDoc, 1, "#I Table of contents complete.\n"); r.toctext := r.toc; # .index has entries of form [sorttext, subsorttext, numbertext, # entrytext, count[, subtext]] Info(InfoGAPDoc, 1, "#I Producing the index . . .\n"); Sort(r.index); str := ""; for a in r.index do Append(str, a[4]); if IsBound(a[6]) then Append(str, ", "); Append(str, a[6]); elif Length(a[2])>0 then Append(str, ", "); Append(str, a[2]); fi; Append(str, " "); Append(str, a[3]); Add(str, '\n'); od; r.indextext := str; if Length(r.bibkeys) > 0 then GAPDocAddBibData(r); Info(InfoGAPDoc, 1, "#I Writing bibliography . . .\n"); need := List(r.bibentries, a-> RecBibXMLEntry(a, "Text", r.bibstrings)); # copy the unique labels for a in [1..Length(need)] do need[a].printedkey := r.biblabels[a]; od; text := ""; ansi := rec( Bib_author := GAPDoc2TextProcs.TextAttr.BibAuthor, Bib_title := GAPDoc2TextProcs.TextAttr.BibTitle, Bib_journal := GAPDoc2TextProcs.TextAttr.BibJournal, Bib_volume := GAPDoc2TextProcs.TextAttr.BibVolume, Bib_Label := GAPDoc2TextProcs.TextAttr.BibLabel, Bib_reset := GAPDoc2TextProcs.TextAttr.BibReset[1]); for a in need do Append(text, StringBibAsText(a, ansi)); od; r.bibtext := text; fi; # second run r.six := []; r.index := []; Info(InfoGAPDoc, 1, "#I Second run through document . . .\n"); GAPDoc2TextProcs.Book(r.content[i], par, pi); # adding .six entries from index for a in r.index do if Length(a[2]) > 0 then Add(r.six, [Concatenation(a[4], " ", a[2]), a[3], a[5]]); else Add(r.six, [a[4], a[3], a[5]]); fi; od; ## remove the links to the root ??? ## RemoveRootParseTree(r); end; ## comments and processing instructions are in general ignored GAPDoc2TextProcs.XMLPI := function(r, str) return; end; GAPDoc2TextProcs.XMLCOMMENT := function(r, str) return; end; # do nothing with Ignore GAPDoc2TextProcs.Ignore := function(arg) end; # just process content ??? putting together here GAPDoc2TextProcs.Book := function(r, par, pi) r.root.Name := r.attributes.Name; GAPDoc2TextContent(r, par); end; ## Body is sectioning element GAPDoc2TextProcs.Body := GAPDoc2TextContent; ## the title page, the most complicated looking function GAPDoc2TextProcs.TitlePage := function(r, par) local strn, l, s, a, aa, cont, ss, st, stmp, ind, len; strn := "\n\n"; # the .six entry Add(r.root.six, [GAPDocTexts.d.Titlepage, GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"), r.count{[1..3]}]); # title l := Filtered(r.content, a-> a.name = "Title"); s := ""; GAPDoc2TextContent(l[1], s); s := FormatParagraph(WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.Heading), r.root.linelength, "center", WidthUTF8String); Append(strn, s); Append(strn, "\n\n"); # subtitle l := Filtered(r.content, a-> a.name = "Subtitle"); if Length(l)>0 then s := ""; GAPDoc2TextContent(l[1], s); s := FormatParagraph(WrapTextAttribute(s,GAPDoc2TextProcs.TextAttr.Heading), r.root.linelength, "center", WidthUTF8String); Append(strn, s); Append(strn, "\n\n"); fi; # version l := Filtered(r.content, a-> a.name = "Version"); if Length(l)>0 then s := ""; GAPDoc2TextContent(l[1], s); while Length(s)>0 and s[Length(s)] in WHITESPACE do Unbind(s[Length(s)]); od; s := FormatParagraph(s, r.root.linelength, "center", WidthUTF8String); Append(strn, s); Append(strn, "\n\n"); fi; # date l := Filtered(r.content, a-> a.name = "Date"); if Length(l)>0 then s := ""; GAPDoc2TextContent(l[1], s); s := FormatParagraph(s, r.root.linelength, "center", WidthUTF8String); Append(strn, s); Append(strn, "\n\n"); fi; # author name(s) l := Filtered(r.content, a-> a.name = "Author"); for a in l do s := ""; aa := ShallowCopy(a); aa.content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"]); GAPDoc2TextContent(aa, s); s := FormatParagraph(s, r.root.linelength, "center", WidthUTF8String); Append(strn, s); Append(strn, "\n"); od; Append(strn, "\n\n"); # short comment for front page l := Filtered(r.content, a-> a.name = "TitleComment"); if Length(l)>0 then # format narrower than later text st := ""; r.root.linelength := r.root.linelength - 10; s := r.root.indent; r.root.indent := Concatenation(s, " "); GAPDoc2TextContent(l[1], st); r.root.indent := s; r.root.linelength := r.root.linelength + 10; Append(strn, st); Append(strn, "\n\n"); fi; # email and WWW-homepage of author(s), if given l := Filtered(r.content, a-> a.name = "Author"); for a in l do cont := List(a.content, b-> b.name); if "Email" in cont or "Homepage" in cont then s := ""; aa := ShallowCopy(a); aa.content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"]); GAPDoc2TextContent(aa, s); NormalizeWhitespace(s); Append(strn, s); if "Email" in cont then Append(strn, Concatenation("\n ", GAPDocTexts.d.Email, ": ")); GAPDoc2Text(a.content[Position(cont, "Email")], strn); fi; if "Homepage" in cont then Append(strn, "\n"); Append(strn, Concatenation(" ", GAPDocTexts.d.Homepage, ": ")); GAPDoc2Text(a.content[Position(cont, "Homepage")], strn); fi; if "Address" in cont then Append(strn, "\n"); stmp := ""; ind := a.root.indent; len := Length(GAPDocTexts.d.Address); a.root.indent := Concatenation(ind, RepeatedString(' ', len+7)); GAPDoc2TextContent(a.content[Position(cont, "Address")], stmp); a.root.indent := ind; stmp[2]{Length(ind)+[1..len+7]} := Concatenation(" ", GAPDocTexts.d.Address, ": "); Append(strn, stmp); fi; Append(strn, "\n"); fi; od; # if an address is given outside the element(s) l := Filtered(r.content, a-> a.name = "Address"); if Length(l) > 0 then Append(strn, "\n\n"); stmp := ""; ind := r.root.indent; len := Length(GAPDocTexts.d.Address); r.root.indent := Concatenation(ind, RepeatedString(' ', len+2)); GAPDoc2TextContent(l[1], stmp); r.root.indent := ind; stmp[2]{Length(ind)+[1..len+2]} := Concatenation(GAPDocTexts.d.Address, ": "); Append(strn, stmp); fi; Append(strn, "\n-------------------------------------------------------\n"); Add(par, r.count); Add(par, strn); # abstract, copyright page, acknowledgements, colophon for ss in ["Abstract", "Copyright", "Acknowledgements", "Colophon" ] do l := Filtered(r.content, a-> a.name = ss); if Length(l)>0 then # the .six entry Add(r.root.six, [GAPDocTexts.d.(ss), GAPDoc2TextProcs.SectionNumber(l[1].count, "Subsection"), l[1].count{[1..3]}]); Add(par, l[1].count); Add(par, Concatenation(WrapTextAttribute(GAPDocTexts.d.(ss), GAPDoc2TextProcs.TextAttr.Heading), "\n")); GAPDoc2TextContent(l[1], par); Append(par[Length(par)], "\n-------------------------------------------------------\n"); fi; od; end; ## these produce text for an URL ## arg: r, str[, pre] GAPDoc2TextProcs.Link := GAPDoc2TextContent; GAPDoc2TextProcs.LinkText := GAPDoc2TextContent; GAPDoc2TextProcs.URL := function(arg) local r, str, pre, rr, txt, s; r := arg[1]; str := arg[2]; if Length(arg)>2 then pre := arg[3]; else pre := ""; fi; rr := First(r.content, a-> a.name = "LinkText"); if rr <> fail then txt := ""; GAPDoc2TextContent(rr, txt); rr := First(r.content, a-> a.name = "Link"); if rr = fail then Info(InfoGAPDoc, 1, "#W missing element for text ", txt, "\n"); s := "MISSINGLINK"; else s := ""; GAPDoc2TextContent(rr, s); fi; else s := ""; GAPDoc2TextContent(r, s); if IsBound(r.attributes.Text) then txt := r.attributes.Text; else txt := s; fi; fi; NormalizeWhitespace(s); NormalizeWhitespace(txt); pre := WrapTextAttribute(Concatenation(pre, s), GAPDoc2TextProcs.TextAttr.URL); if txt=s then Append(str, pre); else Append(str, Concatenation(txt, " (", pre, ")")); fi; end; GAPDoc2TextProcs.Homepage := GAPDoc2TextProcs.URL; GAPDoc2TextProcs.Email := function(r, str) # we add the 'mailto://' phrase GAPDoc2TextProcs.URL(r, str, "mailto:"); end; GAPDoc2TextProcs.Address := function(r, str) # just process the text GAPDoc2TextContent(r, str); end; ## utility: generate a chapter or (sub)section-number string GAPDoc2TextProcs.SectionNumber := function(count, sect) local res; res := ""; if IsString(count[1]) or count[1]>0 then Append(res, String(count[1])); else res := ""; fi; if sect="Chapter" or sect="Appendix" then return res; fi; Add(res, '.'); if count[2]>0 then Append(res, String(count[2])); fi; if sect="Section" then return res; fi; if count[3]>0 then Append(res, Concatenation("-", String(count[3]))); fi; if sect="Par" then Append(res, Concatenation(".", String(count[4]))); return res; fi; # default is SubSection or ManSection number return res; end; ## the sectioning commands are just translated and labels are ## generated, if given as attribute GAPDoc2TextProcs.ChapSect := function(r, par, sect) local num, posh, s, ind, strn, sm, sms, t; # section number as string num := GAPDoc2TextProcs.SectionNumber(r.count, sect); # the heading posh := Position(List(r.content, a-> a.name), "Heading"); if posh <> fail then s := ""; # first the .six entry GAPDoc2TextProcs.Heading1(r.content[posh], s); # reset to heading markup if overwritten by inner elements sm := s; if PositionSublist(s{[5..Length(s)-8]}, "\033[1") <> fail then for t in [ "K", "B", "M", "C", "F", "Func", "Math", "Emph", "Q", "Package", "Arg" ] do sm := SubstitutionSublist(sm, GAPDoc2TextProcs.TextAttr.(t)[2], Concatenation(GAPDoc2TextProcs.TextAttr.(t)[2], GAPDoc2TextProcs.TextAttr.Heading[2],"\027", GAPDoc2TextProcs.TextAttr.Heading[1],"\027")); od; fi; # in six entry we don't want the extra indent on reformatting sms := SubstitutionSublist(sm, "\033[0;0Y", "\033[0;-2Y"); Add(r.root.six, [WrapTextAttribute(NormalizedWhitespace(sms), GAPDoc2TextProcs.TextAttr.Heading), num, r.count{[1..3]}]); # label entry, if present if IsBound(r.attributes.Label) then r.root.labels.(r.attributes.Label) := num; r.root.labeltexts.(r.attributes.Label) := s; fi; # the heading text sm := Concatenation(num, " ", sm); Add(par, r.count); # here we assume that r.indent = "" Add(par, Concatenation("\n", FormatParagraph(sm, r.root.linelength, GAPDoc2TextProcs.TextAttr.Heading, WidthUTF8String), "\n")); # table of contents entry if sect="Section" then ind := " "; elif sect="Subsection" then ind := " "; else ind := ""; fi; # here s without heading markup Append(r.root.toc, FormatParagraph(Concatenation(num, " ", s), r.root.linelength-Length(ind), "left", [ind, ""], WidthUTF8String)); fi; # the actual content GAPDoc2TextContent(r, par); end; ## this really produces the content of the heading GAPDoc2TextProcs.Heading1 := function(r, str) local a; a := ""; GAPDoc2TextContent(r, a); Append(str, a[2]); end; ## and this ignores the heading (for simpler recursion) GAPDoc2TextProcs.Heading := function(r, str) end; GAPDoc2TextProcs.Chapter := function(r, par) GAPDoc2TextProcs.ChapSect(r, par, "Chapter"); end; GAPDoc2TextProcs.Appendix := function(r, par) GAPDoc2TextProcs.ChapSect(r, par, "Appendix"); end; GAPDoc2TextProcs.Section := function(r, par) GAPDoc2TextProcs.ChapSect(r, par, "Section"); end; GAPDoc2TextProcs.Subsection := function(r, par) GAPDoc2TextProcs.ChapSect(r, par, "Subsection"); end; ## table of contents, just puts "TOC" in first run GAPDoc2TextProcs.TableOfContents := function(r, par) local s; # the .six entry Add(r.root.six, [GAPDocTexts.d.TableofContents, GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"), r.count{[1..3]}]); Add(par, r.count); if IsBound(r.root.toctext) then s := WrapTextAttribute(Concatenation(GAPDocTexts.d.Contents," (", r.root.Name, ")"), GAPDoc2TextProcs.TextAttr.Heading); Add(par, Concatenation("\n\n", s, "\n\n", r.root.toctext, "\n\n", GAPDoc2TextProcs.TextAttr.FillString[1],"\n")); else Add(par,"TOC\n-----------\n"); fi; end; ## bibliography, just "BIB" in first run, store databases in root GAPDoc2TextProcs.Bibliography := function(r, par) local s; # .six entries s := GAPDoc2TextProcs.SectionNumber(r.count, "Chapter"); Add(r.root.six, [GAPDocTexts.d.Bibliography, s, r.count{[1..3]}]); if GAPDocTexts.d.Bibliography <> GAPDocTexts.d.References then Add(r.root.six, [GAPDocTexts.d.References, s, r.count{[1..3]}]); fi; r.root.bibdata := r.attributes.Databases; Add(par, r.count); if IsBound(r.root.bibtext) then Add(par, Concatenation("\n\n", WrapTextAttribute(GAPDocTexts.d.References, GAPDoc2TextProcs.TextAttr.Heading), "\n\n", r.root.bibtext, "\n\n", GAPDoc2TextProcs.TextAttr.FillString[1], "\n")); else Add(par,"BIB\n-----------\n"); fi; end; ## inside element we don't want this filtering GAPDoc2TextProcs.PCDATANOFILTER := function(r, str) Append(str, r.content); end; ## default is with filter ???changed??? GAPDoc2TextProcs.PCDATAFILTER := GAPDoc2TextProcs.PCDATANOFILTER; GAPDoc2TextProcs.PCDATA := GAPDoc2TextProcs.PCDATAFILTER; ## end of paragraph (end with double newline) GAPDoc2TextProcs.P := function(r, str) local l, i; l := Length(str); if l>0 and str[l] <> '\n' then Append(str, "\n\n"); elif l>1 and str[l-1] <> '\n' then Add(str, '\n'); else # remove too many line breaks i := l-2; while i>0 and str[i] = '\n' do Unbind(str[i+2]); i := i-1; od; fi; end; ## end of line, same as with .P, but no empty line GAPDoc2TextProcs.Br := function(r, str) # we use character \004 to mark forced line breaks, used in 'par' above Add(str, '\004'); ## GAPDoc2TextProcs.P(r, str); ## if Length(str) > 0 and str[Length(str)] = '\n' then ## Unbind(str[Length(str)]); ## fi; end; ## wrapping text attributes GAPDoc2TextProcs.WrapAppend := function(str, s, a) Append(str, WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.(a))); end; GAPDoc2TextProcs.WrapAttr := function(r, str, a) local s; s := ""; GAPDoc2TextContent(r, s); GAPDoc2TextProcs.WrapAppend(str, s, a); end; ## GAP keywords GAPDoc2TextProcs.K := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "K"); end; ## verbatim GAP code GAPDoc2TextProcs.C := function(r, str) local s; s := ""; GAPDoc2TextContent(r, s); # elements are allowed inside , so maybe we need to repeat the markup # (with a char 23 such that it can be ignored in case of visible markup # substitution) s := SubstitutionSublist(s, GAPDoc2TextProcs.TextAttr.Arg[2], Concatenation(GAPDoc2TextProcs.TextAttr.Arg[2], GAPDoc2TextProcs.TextAttr.C[1],"\027")); GAPDoc2TextProcs.WrapAppend(str, s, "C"); end; ## file names GAPDoc2TextProcs.F := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "F"); end; ## argument names (same as Arg) GAPDoc2TextProcs.A := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "Arg"); end; ## simple maths, here we try to substitute TeX command to something which ## looks ok in text mode GAPDoc2TextProcs.M := function(r, str) local s; s := ""; GAPDoc2TextContent(r, s); s := TextM(s); GAPDoc2TextProcs.WrapAppend(str, s, "M"); end; ## in Txt this is shown in TeX format GAPDoc2TextProcs.Math := function(r, str) local s; s := ""; GAPDoc2TextProcs.PCDATA := GAPDoc2TextProcs.PCDATANOFILTER; GAPDoc2TextContent(r, s); GAPDoc2TextProcs.PCDATA := GAPDoc2TextProcs.PCDATAFILTER; GAPDoc2TextProcs.WrapAppend(str, s, "Math"); end; ## displayed maths (also in TeX format, but printed as paragraph enclosed ## by "\[" and "\]") GAPDoc2TextProcs.Display := function(r, par) local s; s := ""; GAPDoc2TextProcs.PCDATA := GAPDoc2TextProcs.PCDATANOFILTER; GAPDoc2TextContent(r, s); GAPDoc2TextProcs.PCDATA := GAPDoc2TextProcs.PCDATAFILTER; s := Concatenation(Filtered(s, IsString)); if IsBound(r.attributes.Mode) and r.attributes.Mode = "M" then s := TextM(s); fi; s := WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.Display); s := GAPDoc2TextProcs.MarkAndFormat(s, "left", Length(r.root.indent)+6, r.root.linelength); s := Concatenation("\n", s, "\n\n"); Add(par, r.count); Add(par, s); end; ## emphazised text GAPDoc2TextProcs.Emph := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "Emph"); end; ## quoted text GAPDoc2TextProcs.Q := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "Q"); end; ## Package names GAPDoc2TextProcs.Package := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "Package"); end; ## menu items GAPDoc2TextProcs.B := function(r, str) GAPDoc2TextProcs.WrapAttr(r, str, "B"); end; GAPDoc2TextProcs.AddColorPromptMarkup := function(cont) local res, pos, s; res := []; for s in cont do if Length(s) > 4 and s{[1..5]} = "gap> " then Add(res, Concatenation(WrapTextAttribute("gap>", GAPDoc2TextProcs.TextAttr.Prompt), " ", WrapTextAttribute(s{[6..Length(s)]}, GAPDoc2TextProcs.TextAttr.GAPInput))); elif Length(s) > 1 and s{[1,2]} = "> " then Add(res, Concatenation(WrapTextAttribute(">", GAPDoc2TextProcs.TextAttr.Prompt), " ", WrapTextAttribute(s{[3..Length(s)]}, GAPDoc2TextProcs.TextAttr.GAPInput))); elif Length(s) > 2 and s{[1..3]} = "brk" then pos := Position(s, ' '); if pos <> fail then Add(res, Concatenation(WrapTextAttribute(s{[1..pos-1]}, GAPDoc2TextProcs.TextAttr.BrkPrompt), " ", WrapTextAttribute(s{[pos+1..Length(s)]}, GAPDoc2TextProcs.TextAttr.GAPInput))); else Add(res, WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.BrkPrompt)); fi; else Add(res, WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.GAPOutput)); fi; od; return res; end; GAPDoc2TextProcs.ExampleLike := function(r, par, label) local str, cont, a, s, len, l1; if Length(label) = 0 then str := Concatenation(r.root.indent, GAPDoc2TextProcs.TextAttr.FillString[1]); else str := Concatenation(r.root.indent, GAPDoc2TextProcs.TextAttr.FillString[1], " ", label, " ", GAPDoc2TextProcs.TextAttr.FillString[1]); fi; str := WrapTextAttribute(str, GAPDoc2TextProcs.TextAttr.Example); Add(str, '\n'); cont := ""; for a in r.content do # here we try to avoid reformatting if IsString(a.content) then Append(cont, a.content); else s := ""; GAPDoc2Text(a, s); Append(cont, s); fi; od; cont := SplitString(cont, "\n", ""); # delete first line, if whitespace only if Length(cont) > 0 and ForAll(cont[1], x-> x in WHITESPACE) then cont := cont{[2..Length(cont)]}; fi; # color prompt markup in and elements if label in [GAPDocTexts.d.Example, GAPDocTexts.d.Log] then cont := GAPDoc2TextProcs.AddColorPromptMarkup(cont); fi; cont := Concatenation(List(cont, a-> Concatenation(r.root.indent, " ", WrapTextAttribute(a, GAPDoc2TextProcs.TextAttr.Example), "\n"))); Append(str, cont); Append(str, Concatenation(r.root.indent, WrapTextAttribute(GAPDoc2TextProcs.TextAttr.FillString[1], GAPDoc2TextProcs.TextAttr.Example), "\n\n")); Add(par, r.count); Add(par, str); end; ## log of session and GAP code is typeset the same way as GAPDoc2TextProcs.Example := function(r, par) GAPDoc2TextProcs.ExampleLike(r, par, GAPDocTexts.d.Example); end; GAPDoc2TextProcs.Log := function(r, par) GAPDoc2TextProcs.ExampleLike(r, par, GAPDocTexts.d.Log); end; GAPDoc2TextProcs.Listing := function(r, par) if IsBound(r.attributes.Type) then GAPDoc2TextProcs.ExampleLike(r, par, r.attributes.Type); else GAPDoc2TextProcs.ExampleLike(r, par, ""); fi; end; ## Verb is without any formatting GAPDoc2TextProcs.Verb := function(r, par) local cont, s, pos, a; cont := ""; for a in r.content do # here we try to avoid reformatting if IsString(a.content) then Append(cont, a.content); else s := ""; GAPDoc2Text(a, s); Append(cont, s); fi; od; # delete first line if it contains only whitespace pos := Position(cont, '\n'); if pos <> fail and ForAll(cont{[1..pos]}, x-> x in WHITESPACE) then cont := cont{[pos+1..Length(cont)]}; fi; # adjust trailing newlines GAPDoc2TextProcs.P(0, cont); Append(par, [r.count, cont]); end; ## explicit labels GAPDoc2TextProcs.Label := function(r, str) r.root.labels.(r.attributes.Name) := GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"); end; ## citations GAPDoc2TextProcs.Cite := function(r, str) local key, pos; key := r.attributes.Key; pos := Position(r.root.bibkeys, key); if pos = fail then Add(r.root.bibkeys, key); Append(str, Concatenation("[?", key, "?]")); elif not IsBound(r.root.biblabels) then Append(str, Concatenation("[?", key, "?]")); else Append(str, Concatenation("[", r.root.biblabels[pos])); if IsBound(r.attributes.Where) then Append(str, ", "); Append(str, r.attributes.Where); fi; Add(str, ']'); fi; end; ## explicit index entries GAPDoc2TextProcs.Subkey := GAPDoc2TextContent; GAPDoc2TextProcs.Index := function(r, str) local s, sub, entry, a; s := ""; sub := ""; for a in r.content do if a.name = "Subkey" then GAPDoc2Text(a, sub); else GAPDoc2Text(a, s); fi; od; NormalizeWhitespace(s); NormalizeWhitespace(sub); if IsBound(r.attributes.Key) then entry := [STRING_LOWER(r.attributes.Key)]; else entry := [STRING_LOWER(StripEscapeSequences(s))]; fi; if IsBound(r.attributes.Subkey) then Add(entry, r.attributes.Subkey); else Add(entry, STRING_LOWER(StripEscapeSequences(sub))); fi; Add(entry, GAPDoc2TextProcs.SectionNumber(r.count, "Subsection")); Add(entry, s); Add(entry, r.count{[1..3]}); if Length(sub) > 0 then Add(entry, sub); fi; Add(r.root.index, entry); end; ## helper to add markup to the args GAPDoc2TextProcs.WrapArgs := function(argstr) local res, noletter, c; res := ""; noletter := true; for c in argstr do if noletter then if not c in ", []" then noletter := false; Append(res, GAPDoc2TextProcs.TextAttr.Arg[1]); fi; elif c in ", []" then noletter := true; Append(res, GAPDoc2TextProcs.TextAttr.Arg[2]); fi; Add(res, c); od; if not noletter then Append(res, GAPDoc2TextProcs.TextAttr.Arg[2]); fi; return res; end; ## this produces an implicit index entry and a label entry GAPDoc2TextProcs.LikeFunc := function(r, par, typ) local str, s, name, lab, i; s := Concatenation(GAPDoc2TextProcs.TextAttr.DefLineMarker[1], WrapTextAttribute(r.attributes.Name, GAPDoc2TextProcs.TextAttr.Func)); if IsBound(r.attributes.Arg) then Append(s, "( "); Append(s, GAPDoc2TextProcs.WrapArgs(NormalizedArgList(r.attributes.Arg))); Append(s, " ) "); fi; # label (if not given, the default is the Name) if IsBound(r.attributes.Label) then lab := Concatenation(" (", r.attributes.Label, ")"); else lab := ""; fi; GAPDoc2TextProcs.Label(rec(count := r.count, attributes := rec(Name := Concatenation(r.attributes.Name, lab)), root := r.root), par); # index entry name := r.attributes.Name; Add(r.root.index, [STRING_LOWER(name), "", GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"), Concatenation(WrapTextAttribute(name, GAPDoc2TextProcs.TextAttr.Func), lab), r.count{[1..3]}]); # some hint about the type of the variable Append(s, GAPDoc2TextProcs.TextAttr.FillString[1]); Append(s, Concatenation(" ",typ,"\n")); Add(par, r.count); Add(par, s); end; GAPDoc2TextProcs.Func := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Func); end; GAPDoc2TextProcs.Oper := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Oper); end; GAPDoc2TextProcs.Meth := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Meth); end; GAPDoc2TextProcs.Filt := function(r, str) # r.attributes.Type could be "representation", "category", ... if IsBound(r.attributes.Type) then GAPDoc2TextProcs.LikeFunc(r, str, r.attributes.Type); else GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Filt); fi; end; GAPDoc2TextProcs.Prop := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Prop); end; GAPDoc2TextProcs.Attr := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Attr); end; GAPDoc2TextProcs.Var := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Var); end; GAPDoc2TextProcs.Fam := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.Fam); end; GAPDoc2TextProcs.InfoClass := function(r, str) GAPDoc2TextProcs.LikeFunc(r, str, GAPDocTexts.d.InfoClass); end; ## using the HelpData(.., .., "ref") interface GAPDoc2TextProcs.ResolveExternalRef := function(bookname, label, nr) local info, match, res; info := HELP_BOOK_INFO(bookname); if info = fail then return fail; fi; match := Concatenation(HELP_GET_MATCHES(info, SIMPLE_STRING(label), true)); if Length(match) < nr then return fail; fi; res := HELP_BOOK_HANDLER.(info.handler).HelpData(info, match[nr][2], "ref"); res[1] := SubstitutionSublist(res[1], " (not loaded): ", ": ", "one"); return res; end; GAPDoc2TextProcs.Ref := function(r, str) local funclike, int, txt, ref, lab, sectlike; # function like cases funclike := [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; int := Intersection(funclike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := Concatenation(txt, " (", r.attributes.Label, ")"); else lab := txt; fi; if IsBound(r.attributes.BookName) then ref := GAPDoc2TextProcs.ResolveExternalRef(r.attributes.BookName, lab, 1); if ref = fail then if GAPDoc2TextProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation(lab, "???"); else # the search text for online help including book name ref := ref[1]; fi; else if IsBound(r.root.labels.(lab)) then ref := r.root.labels.(lab); else if GAPDoc2TextProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation("???", lab, "???"); fi; fi; Append(str, WrapTextAttribute(txt, GAPDoc2TextProcs.TextAttr.Func)); # add reference by subsection number or text if external, # but only if it does not point to current subsection if GAPDoc2TextProcs.SectionNumber(r.count, "Subsection") <> ref then Append(str, Concatenation(" (", WrapTextAttribute(ref, GAPDoc2TextProcs.TextAttr.Ref), ")")); fi; return; fi; # section like cases sectlike := ["Chap", "Sect", "Subsect", "Appendix"]; int := Intersection(sectlike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := Concatenation(txt, r.attributes.Label); else lab := txt; fi; if IsBound(r.attributes.BookName) then ref := GAPDoc2TextProcs.ResolveExternalRef(r.attributes.BookName, lab, 1); if ref = fail then if GAPDoc2TextProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation(lab, "???"); else # the search text for online help including book name ref := Concatenation("'", StripBeginEnd(ref[1], " "), "'"); fi; else # with sectioning references Label must be given lab := r.attributes.(int[1]); # default is printing section number, but we allow a Style="Text" # attribute if IsBound(r.attributes.Style) and r.attributes.Style = "Text" and IsBound(r.root.labeltexts.(lab)) then ref := Concatenation("'", StripBeginEnd( r.root.labeltexts.(lab), WHITESPACE), "'"); elif IsBound(r.root.labels.(lab)) then ref := r.root.labels.(lab); else if GAPDoc2TextProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation("???", lab, "???"); fi; fi; Append(str, WrapTextAttribute(ref, GAPDoc2TextProcs.TextAttr.Ref)); return; fi; # neutral reference to a label lab := r.attributes.Label; if IsBound(r.attributes.BookName) then ref := GAPDoc2TextProcs.ResolveExternalRef(r.attributes.BookName, lab, 1); if ref = fail then ref := Concatenation(lab, "???"); else # the search text for online help including book name ref := ref[1]; fi; else if IsBound(r.root.labels.(lab)) then ref := r.root.labels.(lab); else ref := Concatenation("???", lab, "???"); fi; fi; Append(str, WrapTextAttribute(ref, GAPDoc2TextProcs.TextAttr.Ref)); return; end; GAPDoc2TextProcs.Description := function(r, par) local l, tmp; l := ""; GAPDoc2TextContent(r, l); # Add an empty line in front if not yet there if Length(par) > 0 and Length(par[Length(par)]) > 1 then tmp := par[Length(par)]; else tmp := ""; fi; if tmp[Length(tmp)-1] <> '\n' then Add(tmp, '\n'); fi; Append(par, l); end; GAPDoc2TextProcs.Returns := function(r, par) local l, ind, lr, pos; l := ""; ind := r.root.indent; r.root.indent := Concatenation(ind, " "); GAPDoc2TextContent(r, l); if Length(l) > 0 then lr := Length(GAPDocTexts.d.Returns)+1; pos := PositionSublist(l[2], RepeatedString(" ",lr), Length(ind)); l[2] := Concatenation(l[2]{[1..pos-1]}, WrapTextAttribute(Concatenation(GAPDocTexts.d.Returns,":"), GAPDoc2TextProcs.TextAttr.Returns), l[2]{[pos+lr..Length(l[2])]}); Append(par, l); fi; r.root.indent := ind; end; GAPDoc2TextProcs.ManSection := function(r, par) local funclike, i, num, s, strn; # if there is a Heading then handle as subsection if ForAny(r.content, a-> IsRecord(a) and a.name = "Heading") then GAPDoc2TextProcs.ChapSect(r, par, "Subsection"); return; fi; strn := ""; # function like elements funclike := [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; # heading comes from name of first function like element i := 1; while not r.content[i].name in funclike do i := i+1; od; num := GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"); s := Concatenation(num, " ", r.content[i].attributes.Name); Add(par, r.count); Add(par, Concatenation(WrapTextAttribute(s, GAPDoc2TextProcs.TextAttr.Heading), "\n\n")); # append to TOC as subsection Append(r.root.toc, Concatenation(" ", s, "\n")); # label entry, if present if IsBound(r.attributes.Label) then r.root.labels.(r.attributes.Label) := num; r.root.labeltexts.(r.attributes.Label) := s; fi; GAPDoc2TextContent(r, par); end; GAPDoc2TextProcs.Mark := function(r, str) local s; s := ""; GAPDoc2TextProcs.WrapAttr(r, s, "Mark"); Append(str, r.root.indent); Append(str, s); Append(str, "\n"); end; GAPDoc2TextProcs.Item := function(r, str) local s; # s := ""; s := r.root.indent; r.root.indent := Concatenation(s, " "); GAPDoc2TextContent(r, str); r.root.indent := s; # s:= FormatParagraph(s, r.root.linelength-6, "both", [" ", ""]); # Append(str, s); end; # must do the complete formatting GAPDoc2TextProcs.List := function(r, par) local s, ss, pos, a, i, start; if "Mark" in List(r.content, a-> a.name) then for a in r.content do if a.name = "Mark" then s := ""; GAPDoc2TextProcs.Mark(a, s); Append(par, [a.count, s]); elif a.name = "Item" then GAPDoc2TextProcs.Item(a, par); fi; od; else for a in Filtered(r.content, a-> a.name = "Item") do ss := ""; GAPDoc2TextProcs.Item(a, ss); # insert bullet start := ss[2]{[1..Length(r.root.indent)]}; ss[2] := ss[2]{[Length(r.root.indent)+1..Length(ss[2])]}; for i in [1..2] do Remove(ss[2], Position(ss[2],' ')); od; ss[2] := Concatenation(start, GAPDoc2TextProcs.TextAttr.ListBullet[1], ss[2]); Append(par, ss); od; fi; end; GAPDoc2TextProcs.Enum := function(r, par) local i, ss, num, a, j, start; i := 1; for a in Filtered(r.content, a-> a.name = "Item") do ss := ""; GAPDoc2TextProcs.Item(a, ss); # merge in the counter start := ss[2]{[1..Length(r.root.indent)]}; ss[2] := ss[2]{[Length(r.root.indent)+1..Length(ss[2])]}; for j in [1..Length(String(i))+2] do Remove(ss[2], Position(ss[2],' ')); od; num := WrapTextAttribute(String(i), GAPDoc2TextProcs.TextAttr.EnumMarks); ss[2] := Concatenation(start, num, ss[2]); Append(par, ss); i := i+1; od; end; GAPDoc2TextProcs.TheIndex := function(r, par) local s; # .six entry s := GAPDoc2TextProcs.SectionNumber(r.count, "Chapter"); Add(r.root.six, [GAPDocTexts.d.Index, s, r.count{[1..3]}]); # the text, if available Add(par, r.count); if IsBound(r.root.indextext) then Add(par, Concatenation("\n\n", WrapTextAttribute(GAPDocTexts.d.Index, GAPDoc2TextProcs.TextAttr.Heading), "\n\n", r.root.indextext, "\n\n-------------------------------------------------------\n")); else Add(par,"INDEX\n-----------\n"); fi; end; GAPDoc2TextProcs.AltYes := function(r) if (not IsBound(r.attributes.Only) and not IsBound(r.attributes.Not)) or (IsBound(r.attributes.Only) and "Text" in SplitString(r.attributes.Only, "", " ,")) or (IsBound(r.attributes.Not) and not "Text" in SplitString(r.attributes.Not, "", " ,")) then return true; else return false; fi; end; GAPDoc2TextProcs.Alt := function(r, str) if GAPDoc2TextProcs.AltYes(r) then GAPDoc2TextContent(r, str); fi; end; # copy a few entries with two element names GAPDoc2TextProcs.E := GAPDoc2TextProcs.Emph; GAPDoc2TextProcs.Keyword := GAPDoc2TextProcs.K; GAPDoc2TextProcs.Code := GAPDoc2TextProcs.C; GAPDoc2TextProcs.File := GAPDoc2TextProcs.F; GAPDoc2TextProcs.Button := GAPDoc2TextProcs.B; GAPDoc2TextProcs.Arg := GAPDoc2TextProcs.A; GAPDoc2TextProcs.Quoted := GAPDoc2TextProcs.Q; GAPDoc2TextProcs.Par := GAPDoc2TextProcs.P; # like PCDATA GAPDoc2TextProcs.EntityValue := GAPDoc2TextProcs.PCDATA; GAPDoc2TextProcs.Table := function(r, str) local a, align, bc, t, z, b, l, s, pos, lens, m, d, ind, hline, cap, i, j; if not GAPDoc2TextProcs.AltYes(r) then return; fi; # head part of table and tabular if IsBound(r.attributes.Label) then r.root.labels.(r.attributes.Label) := GAPDoc2TextProcs.SectionNumber(r.count, "Subsection"); fi; # add spaces as separators of colums if no "|" is given a := r.attributes.Align; align := ""; for i in [1..Length(a)-1] do if a[i] in "crl" then Add(align, a[i]); if a[i+1] <> '|' then Add(align, ' '); fi; elif a[i] = '|' then Add(align, '|'); fi; od; Add(align, a[Length(a)]); # make all odd positions separator descriptions if not align[1] in " |" then align := Concatenation(" ", align); fi; # box characters bc := List([1..11], i-> BOXCHARS{[3*i-2..3*i]}); # collect entries t := []; # the rows of the table for a in r.content do if a.name = "Row" then z := []; b := Filtered(a.content, x-> x.name = "Item"); for i in [1..Length(align)] do if i mod 2 = 1 then if align[i] = '|' then Add(z, Concatenation(" ", bc[2], " ")); else Add(z, Concatenation(" ", align{[i]}, " ")); fi; elif IsBound(b[i/2]) then l := ""; GAPDoc2TextProcs.Item(b[i/2], l); s := Concatenation(l{[2,4..Length(l)]}); NormalizeWhitespace(s); # do not reformat paragraphs later pos := PositionSublist(s, GAPDoc2TextProcs.TextAttr.format[1]); if pos = 1 then s := s{[Position(s, 'Y')+1..PositionSublist(s, GAPDoc2TextProcs.TextAttr.format[2])-1]}; fi; Add(z, s); else Add(z, ""); fi; od; Add(t, z); elif a.name = "HorLine" then Add(t, List(align, x-> "")); fi; od; # equalize width of entries in columns lens := []; for i in [2,4..2*QuoInt(Length(align), 2)] do a := List(t, b-> WidthUTF8String(StripEscapeSequences(b[i]))); m := Maximum(a); lens[i] := m; z := ""; for b in [1..m] do Add(z, ' '); od; if align[i] = 'r' then for j in [1..Length(t)] do t[j][i] := Concatenation(z{[1..m-a[j]]}, t[j][i]); od; elif align[i] = 'l' then for j in [1..Length(t)] do t[j][i] := Concatenation(t[j][i], z{[1..m-a[j]]}); od; else for j in [1..Length(t)] do d := m - a[j]; t[j][i] := Concatenation(z{[1..QuoInt(d, 2)]}, t[j][i], z{[1..d - QuoInt(d, 2)]}); od; fi; od; # put lines together for i in [1..Length(t)] do if Length(t[i][1])=0 then t[i] := ["-"]; fi; od; t := List(t, Concatenation); hline := function(t,l,m,r) local z, i, j; z := " "; if align[1] = '|' then Append(z, l); Append(z, t); else Append(z, " "); fi; for i in [2..Length(align)-1] do if i mod 2 = 0 then for j in [1..lens[i]] do Append(z, t); od; elif align[i] = '|' then Append(z, t); Append(z, m); Append(z, t); else Append(z, " "); fi; od; if align[Length(align)] = '|' then Append(z, t); Append(z, r); else Append(z, " "); fi; Add(z, '\n'); return z; end; for i in [1..Length(t)] do if t[i][1] = '-' then if i = 1 then t[i] := hline(bc[1],bc[3],bc[4],bc[5]); elif i = Length(t) then t[i] := hline(bc[1],bc[9],bc[10],bc[11]); else t[i] := hline(bc[1],bc[6],bc[7],bc[8]); fi; else t[i] := Concatenation(" ", t[i], "\n"); fi; od; t := Concatenation(t); Add(t, '\n'); # the caption, if given cap := Filtered(r.content, a-> a.name = "Caption"); if Length(cap) > 0 then s := ""; GAPDoc2TextProcs.Caption1(cap[1], s); Append(t, s); Append(t, "\n\n"); fi; Add(str, r.count); Add(str, t); end; # do nothing, we call .Caption1 directly in .Table GAPDoc2TextProcs.Caption := function(r, str) return; end; # here the caption for a table text is produced GAPDoc2TextProcs.Caption1 := function(r, str) local s; s := Concatenation(GAPDocTexts.d.Table,":"); s := WrapTextAttribute(s,GAPDoc2TextProcs.TextAttr.Heading); Append(s, " "); GAPDoc2TextContent(r, s); Append(str, FormatParagraph(s, r.root.linelength - 10, "both", [" ", ""], WidthUTF8String)); end; ## ## <#GAPDoc Label="GAPDoc2TextPrintTextFiles"> ## ## ## nothing ## ## The first argument must be a result returned by . The second argument is a path for the files ## to write, it can be given as string or directory object. The text ## of each chapter is written into a separate file with name ## chap0.txt, chap1.txt, ..., chapBib.txt, and ## chapInd.txt.

## ## If you want to make your document accessible via the &GAP; online ## help you must put at least these files for the text version ## into a directory, together with the file manual.six, ## see . Then specify the path to the ## manual.six file in the packages PackageInfo.g file, ## see . ##

## ## Optionally you can add the dvi- and pdf-versions of ## the document which are produced with to this directory. The files must have the names ## manual.dvi and manual.pdf, respectively. Also ## you can add the files of the HTML version produced with ## to this directory, see . The handler functions in ## &GAP; for this help format detect automatically which of the ## optional formats of a book are actually available. ## ## ## ## <#/GAPDoc> ## # arg: t (result of GAPDoc2Text)[, directory] InstallGlobalFunction(GAPDoc2TextPrintTextFiles, function(arg) local t, dir, a; t := arg[1]; if Length(arg)>1 then dir := arg[2]; if IsString(dir) then dir := Directory(dir); fi; else dir := Directory(""); fi; for a in NamesOfComponents(t) do FileString(Filename(dir,Concatenation("chap",a,".txt")), t.(a).text); od; end); GAPDoc-1.5.1/lib/GAPDoc2HTML.gd0000644000175000017500000000116112026346064014071 0ustar billbill############################################################################# ## #W GAPDoc2HTML.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2HTML.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document an HTML version for reading the ## document with a Web-browser. ## DeclareGlobalVariable("GAPDoc2HTMLProcs"); DeclareGlobalFunction("GAPDoc2HTML"); DeclareGlobalFunction("GAPDoc2HTMLPrintHTMLFiles"); DeclareGlobalFunction("CopyHTMLStyleFiles"); GAPDoc-1.5.1/lib/PrintUtil.gd0000644000175000017500000000151712026346064014224 0ustar billbill############################################################################# ## #W PrintUtil.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files PrintUtil.gd and PrintUtil.gi contain utilities for printing ## objects or large amounts of data. ## ## a filter for a bit tricky objects DeclareFilter("IsObjToBePrinted"); DeclareGlobalVariable("DUMMYTBPTYPE"); DeclareGlobalFunction("PrintTo1"); DeclareGlobalFunction("AppendTo1"); ## meta `String' function for objects without String-method DeclareGlobalFunction("StringPrint"); DeclareGlobalFunction("StringView"); ## viewing "large" objects DeclareGlobalFunction("PrintFormattedString"); DeclareGlobalFunction("Page"); DeclareGlobalFunction("PageDisplay"); GAPDoc-1.5.1/lib/GAPDoc2LaTeX.gd0000644000175000017500000000101312026346064014276 0ustar billbill############################################################################# ## #W GAPDoc2LaTeX.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2LaTeX.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document a version which can be processed ## by LaTeX and pdfLaTeX. ## DeclareGlobalVariable("GAPDoc2LaTeXProcs"); DeclareGlobalFunction("GAPDoc2LaTeX"); GAPDoc-1.5.1/lib/Examples.gd0000644000175000017500000000140512026346064014044 0ustar billbill############################################################################# ## #W Examples.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2007, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files Examples.g{d,i} contain functions for extracting and checking ## GAP examples in GAPDoc manuals. ## # old, keep for compatibility DeclareGlobalFunction("ManualExamplesXMLTree"); DeclareGlobalFunction("ManualExamples"); DeclareGlobalFunction("ReadTestExamplesString"); DeclareGlobalFunction("TestExamplesString"); DeclareGlobalFunction("TestManualExamples"); # new DeclareGlobalFunction("ExtractExamplesXMLTree"); DeclareGlobalFunction("ExtractExamples"); DeclareGlobalFunction("RunExamples"); GAPDoc-1.5.1/lib/HelpBookHandler.g0000644000175000017500000003470612026346064015135 0ustar billbill############################################################################# ## #W HelpBookHandler.g GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## This file contains the HELP_BOOK_HANDLER functions for the GapDocGAP ## format. This is the interface between the converter programs ## contained in the GAPDoc package and GAP's help system. ## ## We support some user preferences for the display of GAPDoc manuals from ## the GAP help system. They explain themselves. DeclareUserPreference( rec( name:= "UseMathJax", description:= [ "Change this to true, if you want to use MathJax for display of formulae \ in HTML manuals pages. This will only work if your browser supports \ javascript (e.g., help viewer \"firefox\") and if you are online (because \ the MathJax code and math fonts are loaded from a central AMS server)." ], default:= false, values:= [ true, false ], multi:= false, package:= "GAPDoc", ) ); DeclareUserPreference( rec( name:= "TextTheme", description:= [ "Influences the layout of the onscreen help (help viewers \"screen\", \ \"less\", \"more\"), this is a list of arguments for 'SetGAPDocTextTheme'; \ current choices are shown by 'SetGAPDocTextTheme(\"\");'." ], default:= [ "default" ], values:= function() return RecNames( GAPDoc2TextProcs.OtherThemes ); end, multi:= true, package:= "GAPDoc", ) ); DeclareUserPreference( rec( name:= "HTMLStyle", description:= [ "Influences the layout of the HTML manuals when called from the GAP help \ system. Only relevant if your configured browser supports javascript \ e.g., help viewer \"firefox\"). To see the current choices click on \ the [Style] link at the top of each HTML manual page. \ This is a list of arguments for 'SetGAPDocHTMLStyle'." ], default:= [ "default" ], ) ); HELP_BOOK_HANDLER.GapDocGAP := rec(); ## ## The .entries info in the GapDocGAP six-format has entries of form ## ## [ showstring, ## sectionstring, (allows searching of section numbers, like: "1.3-4") ## [chapnr, secnr, subsecnr], ## linenr (for "text" format), ## pagenr (for .dvi, .pdf-formats), ## idstring (for a link L. in PDF file, ## searchstring (simplified lowercased version of ) ## ] ## HELPBOOKINFOSIXTMP := 0; # helper to set the text theme HELP_BOOK_HANDLER.GapDocGAP.setTextTheme := function() local theme; theme := UserPreference("GAPDoc", "TextTheme"); if IsString(theme) then theme := [theme]; fi; if theme = ["default"] then if UserPreference("UseColorsInTerminal") <> true then SetGAPDocTextTheme("none"); else SetGAPDocTextTheme(rec()); fi; else CallFuncList(SetGAPDocTextTheme, theme); fi; end; HELP_BOOK_HANDLER.GapDocGAP.setTextTheme(); # helper function for showing matches in current text theme HELP_BOOK_HANDLER.GapDocGAP.apptheme := function(res, theme) local a; if not IsBound(res.theme) or res.theme <> theme then for a in res.entries do a[1] := SubstituteEscapeSequences(a[8], theme); od; res.theme := ShallowCopy(theme); fi; end; ## <#GAPDoc Label="SetGAPDocHTMLStyle"> ## ## ## nothing ## ## This utility function is for readers of the HTML version of &GAP; ## manuals which are generated by the &GAPDoc; package. It allows to ## configure the display style of the manuals. This will only have an ## effect if you are using a browser that supports ## javascript. ## There is a default which can be reset by calling this function ## without argument.

## ## The arguments style1 and so on must be strings. You can find out ## about the valid strings by following the [Style] link on top ## of any manual page. (Going back to the original page, its address has a ## setting for GAPDocStyle which is the list of strings, separated ## by commas, you want to use here.) ## ## ## gap> # show/hide subsections in tables on contents only after click, ## gap> # and don't use colors in GAP examples ## gap> SetGAPDocHTMLStyle("toggless", "nocolorprompt"); ## ## ## ## <#/GAPDoc> BindGlobal("SetGAPDocHTMLStyle", function(arg) if Length(arg) = 0 then SetUserPreference("GAPDoc", "GAPDocHTMLStyle", "default"); else SetUserPreference("GAPDoc", "GAPDocHTMLStyle", JoinStringsWithSeparator(arg, ",")); fi; end); # set HTML style from gap.ini file HELP_BOOK_HANDLER.GapDocGAP.f := function() local st; st := UserPreference("GAPDoc", "HTMLStyle"); if IsString(st) then st := [st]; fi; CallFuncList(SetGAPDocHTMLStyle, st); end; HELP_BOOK_HANDLER.GapDocGAP.f(); Unbind(HELP_BOOK_HANDLER.GapDocGAP.f); HELP_BOOK_HANDLER.GapDocGAP.ReadSix := function(stream) local fname, res, bname, nam, a, apptheme; # our .six file is directly GAP-readable fname := ShallowCopy(stream![2]); #Read(stream); # this seems better on NFS file systems ... CloseStream(stream); Read(fname); res := HELPBOOKINFOSIXTMP; Unbind(HELPBOOKINFOSIXTMP); # adjust search strings to current text theme, save original in position 8 for a in res.entries do a[8] := a[1]; od; ## HELP_BOOK_HANDLER.GapDocGAP.setTextTheme(); HELP_BOOK_HANDLER.GapDocGAP.apptheme(res, GAPDocTextTheme); # in position 6 of each entry we put the corresponding search string for a in res.entries do if not IsBound(a[6]) then a[6] := SIMPLE_STRING(StripEscapeSequences(a[1])); NormalizeWhitespace(a[6]); fi; od; # We check the current availability of the different # formats. And we add the help directory. res.handler := "GapDocGAP"; res.directory := Directory(fname{[1..Length(fname)-10]}); res.types := ["text"]; # check if .dvi and .pdf files and HTML-version available bname := fname{[1..Length(fname)-4]}; nam := Concatenation(bname, ".dvi"); if IsExistingFile(nam) then res.dvifile := nam; Add(res.types, "dvi"); fi; nam := Concatenation(bname, ".pdf"); if IsExistingFile(nam) then res.pdffile := nam; Add(res.types, "pdf"); fi; nam := Concatenation(bname{[1..Length(bname)-6]}, "chap0.html"); if IsExistingFile(nam) then Add(res.types, "url"); Add(res.types, "url-text"); fi; nam := Concatenation(bname{[1..Length(bname)-6]}, "chap0_sym.html"); if IsExistingFile(nam) then Add(res.types, "url"); Add(res.types, "url-sym"); fi; nam := Concatenation(bname{[1..Length(bname)-6]}, "chap0_mml.xml"); if IsExistingFile(nam) then Add(res.types, "url"); Add(res.types, "url-mml"); fi; nam := Concatenation(bname{[1..Length(bname)-6]}, "chap0_mj.html"); if IsExistingFile(nam) then Add(res.types, "url"); Add(res.types, "url-mj"); fi; return res; end; Unbind(HELPBOOKINFOSIXTMP); # Our help output format contains the table of contents, # so we just delegate. HELP_BOOK_HANDLER.GapDocGAP.ShowChapters := function(book) local info, match; info := HELP_BOOK_INFO(book); match := Concatenation(HELP_BOOK_HANDLER.GapDocGAP.SearchMatches(book, "table of contents", true))[1]; return HELP_BOOK_HANDLER.GapDocGAP.HelpData(info, match, "text"); end; HELP_BOOK_HANDLER.GapDocGAP.ShowSections := HELP_BOOK_HANDLER.GapDocGAP.ShowChapters; # very similar to the .default handler, but we allow search for # (sub-)section numbers as well HELP_BOOK_HANDLER.GapDocGAP.SearchMatches := function (book, topic, frombegin) local info, exact, match, i; info := HELP_BOOK_INFO(book); exact := []; match := []; for i in [1..Length(info.entries)] do if topic=info.entries[i][6] or topic=info.entries[i][2] then Add(exact, i); elif frombegin = true then if MATCH_BEGIN(info.entries[i][6], topic) or MATCH_BEGIN(info.entries[i][2], topic) then Add(match, i); fi; else if IS_SUBSTRING(info.entries[i][6], topic) then Add(match, i); fi; fi; od; ## HELP_BOOK_HANDLER.GapDocGAP.setTextTheme(); HELP_BOOK_HANDLER.GapDocGAP.apptheme(info, GAPDocTextTheme); return [exact, match]; end; ## The data are all easy to get. if not IsBound(BROWSER_CAP) then BROWSER_CAP := []; fi; HELP_BOOK_HANDLER.GapDocGAP.HelpData := function(book, entrynr, type) local info, a, fname, str, formatted, enc, outenc, sline, pos, tmp, ext, label, res, st; info := HELP_BOOK_INFO(book); # we handle the special type "ref" for cross references first if type = "ref" then a := HELP_BOOK_HANDLER.HelpDataRef(info, entrynr); a[1] := StripEscapeSequences(a[1]); return a; fi; a := info.entries[entrynr]; # section number info if type = "secnr" then return a{[3,2]}; fi; if not type in info.types then return fail; fi; if type = "text" then fname := Filename(info.directory, Concatenation("chap", String(a[3][1]), ".txt")); str := StringFile(fname); if str = fail then return rec(lines := Concatenation("Sorry, file '", fname, "' seems to ", "be corrupted.\n"), formatted := true); fi; # maybe change encoding if IsBound(info.encoding) then enc := info.encoding; else # from older versions, so latin1 enc := "ISO-8859-1"; fi; if IsBound(GAPInfo.TermEncoding) then outenc := GAPInfo.TermEncoding; else outenc := "ISO-8859-1"; fi; enc := UNICODE_RECODE.NormalizedEncodings.(enc); outenc := UNICODE_RECODE.NormalizedEncodings.(outenc); if enc <> outenc then str := Unicode(str, enc); if outenc = "ISO-8859-1" then str := SimplifiedUnicodeString(str, "latin1"); elif outenc = "ANSI_X3.4-1968" then str := SimplifiedUnicodeString(str, "ascii"); fi; str := Encode(str, outenc); fi; sline := a[4]; # set the text theme ## HELP_BOOK_HANDLER.GapDocGAP.setTextTheme(); # substitute pseudo escape sequences via GAPDocTextTheme # split into two pieces to find new start line pos := PositionLinenumber(str, sline); tmp := SubstituteEscapeSequences(str{[1..pos-1]}, GAPDocTextTheme); str := SubstituteEscapeSequences(str{[pos..Length(str)]}, GAPDocTextTheme); sline := NumberOfLines(tmp)+1; str := Concatenation(tmp, str); return rec(lines := str, formatted := true, start := sline); fi; if type = "url" and "url" in info.types then ## # check preferred HTML version/extension ## if not IsBound(BROWSER_CAP) then ## BROWSER_CAP := []; ## fi; ## if "MathML" in BROWSER_CAP and "url-mml" in info.types then ## ext := "_mml.xml"; ## elif ("MathML" in BROWSER_CAP or "Symbol" in BROWSER_CAP) and ## "url-sym" in info.types then ## ext := "_sym.html"; ## elif "url-text" in info.types then ## ext := ".html"; ## else ## return fail; ## fi; if UserPreference("GAPDoc", "UseMathJax") = true and "url-mj" in info.types then ext := "_mj.html"; elif "url-text" in info.types then ext := ".html"; else return fail; fi; st := UserPreference("GAPDoc", "GAPDocHTMLStyle"); if st <> "default" then ext := Concatenation(ext, "?GAPDocStyle=", st); fi; fname := Filename(info.directory, Concatenation("chap", String(a[3][1]), ext)); if IsBound(a[7]) then label := a[7]; else # from older version of GAPDoc label := Concatenation("s", String(a[3][2]), "ss", String(a[3][3])); fi; # ??? return Concatenation("file:", fname, label); return Concatenation("", fname, "#", label); fi; if type = "dvi" then return rec(file := info.dvifile, page := a[5]); fi; if type = "pdf" then res := rec(file := info.pdffile, page := a[5]); if IsBound(a[7]) then res.label := Concatenation("L.", a[7]); fi; return res; fi; return fail; end; ## cache list of chapter numbers, but only if we need them HELP_BOOK_HANDLER.GapDocGAP.ChapNumbers := function(info) local l, sp; if not IsBound(info.ChapNumbers) then l := Set(List(info.entries,a->a[3][1])); sp := IntersectionSet(l, ["Bib", "Ind"]); l := Difference(l, sp); Append(l, sp); info.ChapNumbers := l; fi; end; ## for ?<<, ?>>, ?< and ?> HELP_BOOK_HANDLER.GapDocGAP.MatchPrevChap := function(book, entrynr) local info, chnums, ent, cnr, new, nr; info := HELP_BOOK_INFO(book); HELP_BOOK_HANDLER.GapDocGAP.ChapNumbers(info); chnums := info.ChapNumbers; ent := info.entries; cnr := ent[entrynr][3]; if cnr[2] <> 0 or cnr[3] <> 0 or cnr[1] = chnums[1] then new := [cnr[1], 0, 0]; else new := [chnums[Position(chnums, cnr[1])-1], 0, 0]; fi; nr := First([1..Length(ent)], i-> ent[i][3] = new); if nr = fail then # return current nr := entrynr; fi; return [info, nr]; end; HELP_BOOK_HANDLER.GapDocGAP.MatchNextChap := function(book, entrynr) local info, chnums, ent, cnr, new, nr; info := HELP_BOOK_INFO(book); HELP_BOOK_HANDLER.GapDocGAP.ChapNumbers(info); chnums := info.ChapNumbers; ent := info.entries; cnr := ent[entrynr][3]; if cnr[1] = chnums[Length(chnums)] then new := [cnr[1], 0, 0]; else new := [chnums[Position(chnums, cnr[1])+1], 0, 0]; fi; nr := First([1..Length(ent)], i-> ent[i][3] = new); if nr = fail then # return current nr := entrynr; fi; return [info, nr]; end; HELP_BOOK_HANDLER.GapDocGAP.MatchPrev := function(book, entrynr) local info, ent, old, new, nr, i; info := HELP_BOOK_INFO(book); ent := info.entries; old := ent[entrynr][3]; new := [-1,0,0]; nr := entrynr; for i in [1..Length(ent)] do if ent[i][3] < old and ent[i][3] > new and not ent[i][3][1] in ["Bib", "Ind"] then new := ent[i][3]; nr := i; fi; od; return [info, nr]; end; HELP_BOOK_HANDLER.GapDocGAP.MatchNext := function(book, entrynr) local info, ent, old, new, nr, i; info := HELP_BOOK_INFO(book); ent := info.entries; old := ent[entrynr][3]; new := ["ZZZ",0,0]; nr := entrynr; for i in [1..Length(ent)] do if ent[i][3] > old and ent[i][3] < new and not ent[i][3][1] in ["Bib", "Ind"] then new := ent[i][3]; nr := i; fi; od; return [info, nr]; end; GAPDoc-1.5.1/lib/XMLParser.gd0000644000175000017500000000306312026346064014105 0ustar billbill############################################################################# ## #W XMLParser.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files XMLParser.g{d,i} contain a non-validating XML parser and some ## utilities. ## DeclareGlobalFunction("GetEnt"); DeclareGlobalFunction("GetSTag"); DeclareGlobalFunction("GetETag"); DeclareGlobalFunction("GetElement"); DeclareGlobalFunction("ParseTreeXMLString"); DeclareGlobalFunction("ParseTreeXMLFile"); DeclareGlobalFunction("DisplayXMLStructure"); DeclareGlobalFunction("ApplyToNodesParseTree"); DeclareGlobalFunction("AddRootParseTree"); DeclareGlobalFunction("RemoveRootParseTree"); DeclareGlobalFunction("GetTextXMLTree"); DeclareGlobalFunction("XMLElements"); ## <#GAPDoc Label="InfoXMLParser"> ## ## ## ## The default level of this info class is 1. Functions like are then printing some information, in ## particular in case of errors. You can suppress it by setting the ## level of to 0. With level 2 there ## may be some more information for debugging purposes. ## ## ## <#/GAPDoc> ## # Info class with default level 1 BindGlobal("InfoXMLParser", NewInfoClass("InfoXMLParser")); SetInfoLevel(InfoXMLParser, 1); if CompareVersionNumbers(GAPInfo.Version, "4.dev") then SetInfoHandler(InfoXMLParser, PlainInfoHandler); fi; GAPDoc-1.5.1/lib/Make.g0000644000175000017500000001520012026346064012775 0ustar billbill############################################################################# ## #W Make.g GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## This file contains a function which may be used for building all ## output versions of a GAPDoc XML document which are provided by the ## GAPDoc package. ## ## args: ## path, main, files, bookname[, gaproot][, "MathML"][, "Tth"][, "MathJax"] BindGlobal("MakeGAPDocDoc", function(arg) local htmlspecial, path, main, files, bookname, gaproot, str, r, t, l, latex, null, log, pos, h, i, j; htmlspecial := Filtered(arg, a-> a in ["MathML", "Tth", "MathJax"]); if Length(htmlspecial) > 0 then arg := Filtered(arg, a-> not a in ["MathML", "Tth", "MathJax"]); fi; path := arg[1]; main := arg[2]; files := arg[3]; bookname := arg[4]; if IsBound(arg[5]) then gaproot := arg[5]; else gaproot := false; fi; # ensure that path is directory object if IsString(path) then path := Directory(path); fi; # ensure that .xml is stripped from name of main file if Length(main)>3 and main{[Length(main)-3..Length(main)]} = ".xml" then main := main{[1..Length(main)-4]}; fi; # compose the XML document Info(InfoGAPDoc, 1, "#I Composing XML document . . .\n"); str := ComposedDocument("GAPDoc", path, Concatenation(main, ".xml"), files, true); # parse the XML document Info(InfoGAPDoc, 1, "#I Parsing XML document . . .\n"); r := ParseTreeXMLString(str[1], str[2]); # clean the result Info(InfoGAPDoc, 1, "#I Checking XML structure . . .\n"); CheckAndCleanGapDocTree(r); # produce text version Info(InfoGAPDoc, 1, "#I Text version (also produces labels for hyperlinks):\n"); t := GAPDoc2Text(r, path); GAPDoc2TextPrintTextFiles(t, path); # produce LaTeX version Info(InfoGAPDoc, 1, "#I Constructing LaTeX version and calling pdflatex:\n"); r.bibpath := path; l := GAPDoc2LaTeX(r); Info(InfoGAPDoc, 1, "#I Writing LaTeX file, \c"); Info(InfoGAPDoc, 2, Concatenation(main, ".tex"), "\n#I "); FileString(Filename(path, Concatenation(main, ".tex")), l); if Filename(DirectoriesSystemPrograms(), "pdflatex") = fail then Info(InfoGAPDoc, 1, "\n#W WARNING: cannot find 'pdflatex', please install TeX.\n"); Info(InfoGAPDoc, 1, "#W WARNING: will NOT produce pdf version from LaTeX file.\n"); else # call latex and pdflatex (with bibtex, makeindex and dvips) latex := "latex -interaction=nonstopmode "; # sh-syntax for redirecting stderr and stdout to /dev/null null := " > /dev/null 2>&1 "; Info(InfoGAPDoc, 1, "3 x pdflatex with bibtex and makeindex, \c"); Exec(Concatenation("sh -c \" cd ", Filename(path,""), "; rm -f ", main, ".aux ", main, ".pdf ", main, ".log ", "; pdf", latex, main, null, "; bibtex ", main, null, "; pdf", latex, main, null, "; makeindex ", main, null, "; pdf", latex, main, null,"\"")); # check log file for errors, warning, overfull boxes log := Filename(path, Concatenation(main, ".log")); log := StringFile(log); if log = fail then Info(InfoGAPDoc, 1, "\n#W WARNING: Something wrong, don't find log file ", Filename(path, Concatenation(main, ".log")), "\n"); else log := SplitString(log, "\n", ""); pos := Filtered([1..Length(log)], i-> Length(log[i]) > 0 and log[i][1] = '!'); if Length(pos) > 0 then Info(InfoGAPDoc, 1, "\n#W There were LaTeX errors:\n"); for i in pos do for j in [i..Minimum(i+2, Length(log))] do Info(InfoGAPDoc, 1, log[j], "\n"); od; Info(InfoGAPDoc, 1, "____________________\n"); od; fi; pos := Filtered([1..Length(log)], i-> Length(log[i]) > 13 and log[i]{[1..14]} = "LaTeX Warning:"); if Length(pos) > 0 then Info(InfoGAPDoc, 1, "\n#W There were LaTeX Warnings:\n"); for i in pos do for j in [i..Minimum(i+2, Length(log))] do Info(InfoGAPDoc, 1, log[j], "\n"); od; Info(InfoGAPDoc, 1, "____________________\n"); od; fi; pos := Filtered([1..Length(log)], i-> Length(log[i]) > 7 and log[i]{[1..8]} = "Overfull"); if Length(pos) > 0 then Info(InfoGAPDoc, 1, "\n#W There are overfull boxes:\n"); for i in pos do Info(InfoGAPDoc, 1, log[i], "\n"); od; fi; fi; # check for BibTeX warnings log := StringFile(Filename(path, Concatenation(main, ".blg"))); if log <> fail then log := SplitString(log, "\n", ""); log := Filtered(log, z-> PositionSublist(z, "Warning--") = 1); if Length(log) > 0 then Info(InfoGAPDoc, 1, "\n#W BibTeX had warnings:\n", JoinStringsWithSeparator(log, "\n")); fi; fi; if not IsExistingFile(Filename(path, Concatenation(main, ".pdf"))) then Info(InfoGAPDoc, 1, "\n#I ERROR: no .pdf file produced (and no .six file)"); else Exec(Concatenation("sh -c \" cd ", Filename(path,""), "; mv ", main, ".pdf manual.pdf; ", "\"")); Info(InfoGAPDoc, 1, "\n"); # read page number information for .six file Info(InfoGAPDoc, 1, "#I Writing manual.six file ... \c"); Info(InfoGAPDoc, 2, Filename(path, "manual.six"), "\n"); Info(InfoGAPDoc, 1, "\n"); AddPageNumbersToSix(r, Filename(path, Concatenation(main, ".pnr"))); # print manual.six file PrintSixFile(Filename(path, "manual.six"), r, bookname); fi; fi; # produce html version Info(InfoGAPDoc, 1, "#I Finally the HTML version . . .\n"); # if MathJax version is also produced we include links to them if "MathJax" in htmlspecial then r.LinkToMathJax := true; fi; h := GAPDoc2HTML(r, path, gaproot); GAPDoc2HTMLPrintHTMLFiles(h, path); Unbind(r.LinkToMathJax); if "Tth" in htmlspecial then Info(InfoGAPDoc, 1, "#I - also HTML version with 'tth' translated formulae . . .\n"); h := GAPDoc2HTML(r, path, gaproot, "Tth"); GAPDoc2HTMLPrintHTMLFiles(h, path); fi; if "MathML" in htmlspecial then Info(InfoGAPDoc, 1, "#I - also HTML + MathML version with 'ttm' . . .\n"); h := GAPDoc2HTML(r, path, gaproot, "MathML"); GAPDoc2HTMLPrintHTMLFiles(h, path); fi; if "MathJax" in htmlspecial then Info(InfoGAPDoc, 1, "#I - also HTML version for MathJax . . .\n"); h := GAPDoc2HTML(r, path, gaproot, "MathJax"); GAPDoc2HTMLPrintHTMLFiles(h, path); fi; return r; end); GAPDoc-1.5.1/lib/gapdocdtdinfo.g0000644000175000017500000003537712026346064014746 0ustar billbillGAPDOCDTDINFO:=[rec(name:="Alt",attr:=["Not","Only"],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Emph",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="E",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Par",attr:=[],reqattr:=[],type:="empty"),rec(name:="P",attr:=[],reqattr:=[],type:="empty"),rec(name:="Br",attr:=[],reqattr:=[],type:="empty"),rec(name:="Keyword",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="K",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="Arg",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="A",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="Code",attr:=[],reqattr:=[],type:="mixed",content:=["A","Alt","Arg","PCDATA"]),rec(name:="C",attr:=[],reqattr:=[],type:="mixed",content:=["A","Alt","Arg","PCDATA"]),rec(name:="File",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="F",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="Button",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="B",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="Package",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","PCDATA"]),rec(name:="Quoted",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Q",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="M",attr:=[],reqattr:=[],type:="mixed",content:=["A","Alt","Arg","PCDATA"]),rec(name:="Math",attr:=[],reqattr:=[],type:="mixed",content:=["A","Alt","Arg","PCDATA"]),rec(name:="Display",attr:=["Mode"],reqattr:=[],type:="mixed",content:=["A","Alt","Arg","PCDATA"]),rec(name:="Example",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA"]),rec(name:="Log",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA"]),rec(name:="Listing",attr:=["Type"],reqattr:=[],type:="mixed",content:=["PCDATA"]),rec(name:="Verb",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA"]),rec(name:="URL",attr:=["Text"],reqattr:=[],type:="mixed",content:=["Alt","Link","LinkText","PCDATA"]),rec(name:="Link",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="LinkText",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Email",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","Link","LinkText","PCDATA"]),rec(name:="Homepage",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","Link","LinkText","PCDATA"]),rec(name:="Address",attr:=[],reqattr:=[],type:="mixed",content:=["Alt","Br","PCDATA"]),rec(name:="Cite",attr:=["Key","Where"],reqattr:=["Key"],type:="empty"),rec(name:="Label",attr:=["Name"],reqattr:=["Name"],type:="empty"),rec(name:="Ref",attr:=["Appendix","Attr","BookName","Chap","Fam","Filt","Func","InfoClass","Label","Meth","Oper","Prop","Sect","Style","Subsect","Text","Var"],reqattr:=[],type:="empty"),rec(name:="Index",attr:=["Key","Subkey"],reqattr:=[],type:="mixed",content:=["Subkey","PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Subkey",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Item",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Mark",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="BigMark",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="List",attr:=["Not","Only"],reqattr:=[],type:="elements",content:=["BigMark","Item","Mark"]),rec(name:="Enum",attr:=["Not","Only"],reqattr:=[],type:="elements",content:=["Item"]),rec(name:="Table",attr:=["Align","Label","Not","Only"],reqattr:=["Align"],type:="elements",content:=["Caption","HorLine","Row"]),rec(name:="Row",attr:=[],reqattr:=[],type:="elements",content:=["Item"]),rec(name:="HorLine",attr:=[],reqattr:=[],type:="empty"),rec(name:="Caption",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="TitlePage",attr:=[],reqattr:=[],type:="elements",content:=["Abstract","Acknowledgements","Address","Author","Colophon","Copyright","Date","Subtitle","Title","TitleComment","Version"]),rec(name:="Title",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Subtitle",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Version",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="TitleComment",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Author",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Date",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Abstract",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Copyright",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Acknowledgements",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Colophon",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="TableOfContents",attr:=[],reqattr:=[],type:="empty"),rec(name:="Bibliography",attr:=["Databases","Style"],reqattr:=["Databases"],type:="empty"),rec(name:="TheIndex",attr:=[],reqattr:=[],type:="empty"),rec(name:="Ignore",attr:=["Remark"],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Chapter","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Heading","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","ManSection","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Section","Subsection","Table","URL","Verb"]),rec(name:="Subsection",attr:=["Label"],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Heading","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="ManSection",attr:=["Label"],reqattr:=[],type:="elements",content:=["Attr","Description","Fam","Filt","Func","Heading","InfoClass","Meth","Oper","Prop","Returns","Var"]),rec(name:="Returns",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Description",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Table","URL","Verb"]),rec(name:="Func",attr:=["Arg","Comm","Label","Name"],reqattr:=["Arg","Name"],type:="empty"),rec(name:="Oper",attr:=["Arg","Comm","Label","Name"],reqattr:=["Arg","Name"],type:="empty"),rec(name:="Meth",attr:=["Arg","Comm","Label","Name"],reqattr:=["Arg","Name"],type:="empty"),rec(name:="Filt",attr:=["Arg","Comm","Label","Name","Type"],reqattr:=["Name"],type:="empty"),rec(name:="Prop",attr:=["Arg","Comm","Label","Name"],reqattr:=["Arg","Name"],type:="empty"),rec(name:="Attr",attr:=["Arg","Comm","Label","Name"],reqattr:=["Arg","Name"],type:="empty"),rec(name:="Var",attr:=["Comm","Label","Name"],reqattr:=["Name"],type:="empty"),rec(name:="Fam",attr:=["Comm","Label","Name"],reqattr:=["Name"],type:="empty"),rec(name:="InfoClass",attr:=["Comm","Label","Name"],reqattr:=["Name"],type:="empty"),rec(name:="Heading",attr:=[],reqattr:=[],type:="mixed",content:=["PCDATA","Alt","Emph","E","Par","P","Br","Keyword","K","Arg","A","Quoted","Q","Code","C","File","F","Button","B","Package","M","Math","Display","Example","Listing","Log","Verb","URL","Email","Homepage","Address","Cite","Label","Ref","Index","Ignore"]),rec(name:="Section",attr:=["Label"],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Heading","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","ManSection","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Subsection","Table","URL","Verb"]),rec(name:="Chapter",attr:=["Label"],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Heading","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Section","Table","URL","Verb"]),rec(name:="Appendix",attr:=["Label"],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Heading","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Section","Table","URL","Verb"]),rec(name:="Body",attr:=[],reqattr:=[],type:="mixed",content:=["A","Address","Alt","Arg","B","Br","Button","C","Chapter","Cite","Code","Display","E","Email","Emph","Enum","Example","F","File","Homepage","Ignore","Index","K","Keyword","Label","List","Listing","Log","M","Math","P","PCDATA","Package","Par","Q","Quoted","Ref","Section","Table","URL","Verb"]),rec(name:="Book",attr:=["Name"],reqattr:=["Name"],type:="elements",content:=["Appendix","Bibliography","Body","TableOfContents","TheIndex","TitlePage"])]; GAPDoc-1.5.1/lib/GAPDoc2Text.gd0000644000175000017500000000135012026346064014251 0ustar billbill############################################################################# ## #W GAPDoc2Text.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2Text.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document a text version for viewing the ## document on screen (GAP online help). ## DeclareGlobalVariable("GAPDoc2TextProcs"); DeclareGlobalFunction("GAPDoc2Text"); DeclareGlobalFunction("GAPDoc2TextPrintTextFiles"); # Just use this variable, will be really assigned in the .gi file. DeclareGlobalVariable("GAPDocTextTheme"); DeclareGlobalFunction("SetGAPDocTextTheme"); GAPDoc-1.5.1/lib/Examples.gi0000644000175000017500000004032112026346064014051 0ustar billbill############################################################################# ## #W Examples.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2007, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files Examples.g{d,i} contain functions for extracting and checking ## GAP examples in GAPDoc manuals. ## ## <#GAPDoc Label="ExtractExamples"> ## ## ## a list of lists ## ## a list of lists ## ## The argument tree must be a parse tree of a ## &GAPDoc; document, see . ## The function returns a data ## structure representing the <Example> elements of the document. ## The return value can be used with to check and ## optionally update the examples of the document.

## Depending ## on the argument units several examples are collected in one list. ## Recognized values for units are "Chapter", "Section", ## "Subsection" or "Single". The latter means that each example ## is in a separate list. For all other value of units just one list ## with all examples is returned.

## ## The arguments path, main and files of are the same as for . ## This function first contructs and parses the &GAPDoc; document and then ## applies . ## ## ## <#/GAPDoc> # obsolete # Extract examples units-wise from a GAPDoc document as XML tree, # 'units' can either be: "Chapter" or "Section" or "Subsection" or "Single" # then a list of strings is returned # For all other values of 'units' one string with all examples is returned. # Before each extracted example there is its paragraph number in a comment: # [ chapter, section, subsection, paragraph ] InstallGlobalFunction(ManualExamplesXMLTree, function( tree, units ) local secelts, sec, exelts, res, str, a, ex; if units = "Chapter" then secelts := ["Chapter", "Appendix"]; elif units = "Section" then secelts := ["Section"]; elif units = "Subsection" then secelts := ["Subsection", "ManSection"]; elif units = "Single" then secelts := ["Example"]; else secelts := 0; fi; if secelts <> 0 then sec := XMLElements(tree, secelts); else sec := [tree]; fi; # want to put section numbers in comments AddParagraphNumbersGapDocTree(tree); exelts := List(sec, a-> XMLElements(a, ["Example"])); res := []; for a in exelts do str := ""; for ex in a do Append(str, "# from paragraph "); if IsBound(ex.count) then Append(str, String(ex.count)); else Append(str, "in Ignore?"); fi; if IsBound(tree.inputorigins) then Append(str, String(OriginalPositionDocument( tree.inputorigins, ex.start))); fi; Append(str, "\n"); Append(str, GetTextXMLTree(ex)); Append(str, "\n"); od; Add(res, str); od; if secelts = 0 then res := res[1]; fi; return res; end); InstallGlobalFunction(ExtractExamplesXMLTree, function( tree, units ) local secelts, sec, exelts, orig, res, l, b, e, a, ex; if units = "Chapter" then secelts := ["Chapter", "Appendix"]; elif units = "Section" then secelts := ["Section"]; elif units = "Subsection" then secelts := ["Subsection", "ManSection"]; elif units = "Single" then secelts := ["Example"]; else secelts := 0; fi; if secelts <> 0 then sec := XMLElements(tree, secelts); else sec := [tree]; fi; exelts := List(sec, a-> XMLElements(a, ["Example"])); if IsBound(tree.inputorigins) then orig := tree.inputorigins; elif IsBound(tree.root) and IsBound(tree.root.inputorigins) then orig := tree.inputorigins; else orig := fail; fi; res := []; for a in exelts do l := []; for ex in a do if orig <> fail then b := OriginalPositionDocument(orig, ex.start); e := OriginalPositionDocument(orig, ex.stop); Add(b, e[2]); else b := [ex.start, ex.stop]; fi; Add(l, [GetTextXMLTree(ex), b]); od; Add(res, l); od; return res; end); # obsolete # compose and parse document, then extract examples units-wise InstallGlobalFunction(ManualExamples, function( path, main, files, units ) local str, xmltree; str:= ComposedDocument( "GAPDoc", path, main, files, true ); xmltree:= ParseTreeXMLString( str[1], str[2] ); return ManualExamplesXMLTree(xmltree, units); end); # compose and parse document, then extract examples units-wise InstallGlobalFunction(ExtractExamples, function( path, main, files, units ) local str, xmltree; str:= ComposedDocument( "GAPDoc", path, main, files, true ); xmltree:= ParseTreeXMLString( str[1], str[2] ); return ExtractExamplesXMLTree(xmltree, units); end); ## <#GAPDoc Label="TestExamples"> ## ## ## true or false ## ## true or a list of records ## ## true or a list of records ## ## The argument str must be a string containing lines for the test mode ## of &GAP;. The function just runs ## on this code.

## ## The function returns true if does not find differences. In the ## other case it returns a list of records, where each record describes one ## difference. The records have fields .line with the line number of the ## relevant input line of str, .input with the input line and ## .diff with the differences as displayed by . If the optional argument print is given and set ## to true then the differences are also printed before the function ## returns.

## ## The arguments of the function is either ## a parse tree of a &GAPDoc; document or the information to build and parse ## such a document. The function extracts all examples in "Single" ## units and applies to them.

## ## ## gap> TestExamplesString("gap> 1+1;\n2\n"); ## true ## gap> TestExamplesString("gap> 1+1;\n2\ngap> 2+3;\n4\n"); ## [ rec( diff := "+ 5\n- 4\n", input := "gap> 2+3;", line := 3 ) ] ## gap> TestExamplesString("gap> 1+1;\n2\ngap> 2+3;\n4\n", true); ## ----------- bad example -------- ## line: 3 ## input: gap> 2+3; ## differences: ## + 5 ## - 4 ## [ rec( diff := "+ 5\n- 4\n", input := "gap> 2+3;", line := 3 ) ] ## ## ## ## <#/GAPDoc> # obsolete # test a string with examples InstallGlobalFunction(ReadTestExamplesString, function(str) local res, file; file := InputTextString(str); res := ReadTest(file); CloseStream(file); return res; end); # obsolete # args: str, print InstallGlobalFunction(TestExamplesString, function(arg) local l, s, z, inp, out, f, lout, pos, bad, i, n, diffs, str; str := arg[1]; l := SplitString(str, "\n", ""); s := ""; for i in [1..Length(l)] do z := l[i]; if Length(z) > 4 and z{[1..5]} = "gap> " or Length(z) > 1 and z{[1,2]} = "> " then Append(s, " #IPL"); Append(s, String(i)); Append(s, "--->"); Append(s, z); Add(s, '\n'); fi; Append(s, z); Add(s, '\n'); od; inp := InputTextString(s); out := ""; f := OutputTextString(out, false); PrintTo1(f, function() ## READ_TEST_STREAM(inp); ReadTest(inp); end); if not IsClosedStream(inp) then CloseStream(inp); fi; if not IsClosedStream(f) then CloseStream(f); fi; lout := SplitString(out, "\n", ""); pos := First([1..Length(lout)], i-> Length(lout[i]) > 0 and lout[i][1] = '+'); if pos = fail then return true; fi; bad := []; while pos <> fail do i := pos-1; while Length(lout[i]) < 7 or lout[i]{[1..7]} <> "- #IPL" do i := i-1; od; n := lout[i]{[8..Length(lout[i])]}; n := Int(n{[1..Position(n, '-')-1]}); diffs := ""; while IsBound(lout[pos]) and (Length(lout[pos]) < 7 or lout[pos]{[1..7]} <> "- #IPL") do Append(diffs, lout[pos]); Add(diffs, '\n'); pos := pos+1; od; Add(bad, rec(line := n, input := l[n], diff := diffs)); pos := First([pos..Length(lout)], i-> Length(lout[i]) > 0 and lout[i][1] = '+'); od; if Length(arg) > 1 and arg[2] = true then for z in bad do Print("----------- bad example --------\n", "line: ", z.line, "\ninput: "); PrintFormattedString(z.input); Print("\n"); Print("differences:\n"); PrintFormattedString(z.diff); od; fi; return bad; end); # obsolete InstallGlobalFunction(TestManualExamples, function(arg) local ex, bad, res, a; if IsRecord(arg[1]) then ex := ManualExamplesXMLTree(arg[1], "Single"); else ex := ManualExamples(arg[1], arg[2], arg[3], "Single"); fi; bad := Filtered(ex, a-> TestExamplesString(a) <> true); res := []; for a in bad do Print("===========================\n"); PrintFormattedString(a); Add(res, TestExamplesString(a, true)); od; return res; end); ## <#GAPDoc Label="RunExamples"> ## ## ## nothing ## ## The argument exmpls must be the output of a call to ## or . ## The optional argument optrec must be a record, its components ## can change the default behaviour of this function. ##

## By default this function runs the &GAP; input of all examples and compares ## the actual output with the output given in the examples. If differences ## occur these are displayed together with information on the location of the ## source code of that example. Before running the examples in each unit (entry ## of exmpls) the function ## is called and the screen width is set to 72 characters. ##

## If the argument optrec is given, the following components are ## recognized: ## ## showDiffs ## ## The default value is true, if set to something else found differences ## in the examples are not displayed. ## ## width ## ## The value must be a positive integer which is used as screen width when ## running the examples. As mentioned above, the default is 72 which is a ## sensible value for the text version of the &GAPDoc; document used ## in a 80 character wide terminal. ## ## changeSources ## ## If this is set to true then the source code of all manual ## examples which show differences is adjusted to the current outputs. ## The default is false.
## Use this feature with care. ## Note that sometimes differences can indicate a bug, and in such a case ## it is more appropriate to fix the bug instead of changing the example ## output. ##
## compareFunction ## ## The function used to compare the output shown in the example and the ## current output. See for more ## details. ## ## checkWidth ## ## If this option is a positive integer n the function prints warnings ## if an example contains any line with more than n characters (input ## and output lines are considered). By default this option is set to ## false. ## ##
## ## ## ## <#/GAPDoc> InstallGlobalFunction(RunExamples, function(arg) local exlists, opts, oldscr, l, sp, bad, s, test, pex, new, inp, ch, fnams, str, fch, pos, pre, a, j, ex, i, attedStrin, f; exlists := arg[1]; opts := rec( showDiffs := true, changeSources := false, width := 72, compareFunction := EQ, checkWidth := false, ); if Length(arg) > 1 and IsRecord(arg[2]) then for a in RecFields(arg[2]) do opts.(a) := arg[2].(a); od; fi; if IsString(opts.compareFunction) then if IsBound(TEST.compareFunctions.(opts.compareFunction)) then opts.compareFunction := TEST.compareFunctions.(opts.compareFunction); else opts.compareFunction := EQ; fi; fi; oldscr := SizeScreen(); SizeScreen([opts.width, oldscr[2]]); for j in [1..Length(exlists)] do l := exlists[j]; Print("# Running list ",j," . . .\n"); START_TEST(""); for ex in l do if IsInt(opts.checkWidth) then sp := SplitString(ex[1], "\n", ""); bad := Filtered([1..Length(sp)], i-> Length(sp[i]) > opts.checkWidth); if Length(bad) > 0 then Print("# WARNING: Overlong lines ", bad, " in ", ex[2]{[1..3]}, "\n"); fi; fi; s := InputTextString(ex[1]); test := Test(s, rec(ignoreComments := false, width := opts.width, compareFunction := opts.compareFunction, reportDiff := Ignore ) ); CloseStream(s); pex := TEST.lastTestData; if test = false then for i in [1..Length(pex[1])] do if opts.compareFunction(pex[2][i], pex[4][i]) <> true then if opts.showDiffs = true then Print("########> Diff in ", ex[2]{[1..3]}, "\n# Input is:\n"); PrintFormattedString(pex[1][i]); Print("# Expected output:\n"); PrintFormattedString(pex[2][i]); Print("# But found:\n"); PrintFormattedString(pex[4][i]); Print("########\n"); fi; fi; od; fi; if test = false then new := ""; for i in [1..Length(pex[1])] do inp := Concatenation("gap> ", JoinStringsWithSeparator( SplitString(pex[1][i], "\n", ""), "\n> "), "\n"); Append(new, inp); Append(new, pex[4][i]); od; ex[2][4] := new; fi; od; od; if opts.changeSources = true then ch := []; for l in exlists do for ex in l do if IsString(ex[2][1]) and Length(ex[2]) > 3 then Add(ch, ex[2]); fi; od; od; if Length(ch) > 0 then Print("# Diffs found, changing source files ...\n"); fnams := Set(List(ch, a-> a[1])); for f in fnams do Print("# Changing ",f,"\n"); str := StringFile(f); if str = fail then Print("# WARNING: Cannot read file ",f,", skipping\n"); else str := SplitString(str, "\n", ""); for a in str do Add(a, '\n'); od; fch := Filtered(ch, a-> a[1] = f); for ex in fch do # change first line to everything new and empty the remaining ones pos := PositionSublist(str[ex[2]], " ## ## ## &LaTeX; document as string ## ## Nothing ## ## The argument tree for this function is a tree ## describing a &GAPDoc; XML document as returned by (probably also checked with ). The output is a string ## containing a version of the document which can be written to a ## file and processed with &LaTeX; or pdf&LaTeX; (and probably ## &BibTeX; and makeindex).

## ## The output uses the report document class and ## needs the following &LaTeX; packages: a4wide, ## amssymb, inputenc, makeidx, color, ## fancyvrb, psnfss, pslatex, enumitem ## and hyperref. These ## are for example provided by the teTeX-1.0 ## or texlive ## distributions of &TeX; (which in turn are used for ## most &TeX; packages of current Linux distributions); see ## http://www.tug.org/tetex/.

## ## In particular, the resulting pdf-output (and ## dvi-output) ## contains (internal and external) hyperlinks which can be very ## useful for onscreen browsing of the document.

## ## The &LaTeX; processing also produces a file with extension ## .pnr which is &GAP; readable and contains the page numbers ## for all (sub)sections of the document. This can be used by ## &GAP;'s online help; see . ## ## Non-ASCII characters in the &GAPDoc; document are translated to ## &LaTeX; input in ASCII-encoding with the help of ## and the option "LaTeX". See the documentation of ## for how to proceed if you have a character which ## is not handled (yet).

## ## This function works by running recursively through the document ## tree and calling a handler function for each &GAPDoc; ## XML element. Many of these handler functions (usually in ## GAPDoc2LaTeXProcs.<ElementName>) are not difficult to ## understand (the greatest complications are some commands for index ## entries, labels or the output of page number information). So it ## should be easy to adjust layout details to your own taste by slight ## modifications of the program.

## ## Former versions of &GAPDoc; supported some XML processing ## instructions to add some extra lines to the preamble of the &LaTeX; ## document. Its use is now deprecated, use the much more flexible instead: ## ## The default layout of the resulting documents can ## be changed with . This ## changes parts of the header of the &LaTeX; file ## produced by &GAPDoc;. You can see the header with ## some placeholders by Page(GAPDoc2LaTeXProcs.Head);. The ## placeholders are filled with components from the record ## GAPDoc2LaTeXProcs.DefaultOptions. The arguments of can be records with the same ## structure (or parts of it) with different values. As abbreviations ## there are also three strings supported as arguments. These ## are "nocolor" for switching all colors to black; then ## "nopslatex" to use standard &LaTeX; fonts instead of ## postscript fonts; and finally "utf8" to choose UTF-8 as input ## encoding for the &LaTeX; document. ## ## ## ## <#/GAPDoc> ## ## # the basic call, used recursivly with a result r from GetElement # and a string str to which the output should be appended # arg: r (then a string is returned) # or: r, str (then the output is appended to string str) InstallGlobalFunction(GAPDoc2LaTeX, function(arg) local r, str, name; r := arg[1]; if Length(arg)>1 then str := arg[2]; else AddRootParseTree(r); str := ""; fi; name := r.name; if not IsBound(GAPDoc2LaTeXProcs.(name)) then Info(InfoGAPDoc, 1, "#W WARNING: Don't know how to process element ", name, " ---- ignored\n"); else GAPDoc2LaTeXProcs.(r.name)(r, str); fi; if Length(arg)=1 then return str; fi; end); ## a common recursion loop BindGlobal("GAPDoc2LaTeXContent", function(r, str) local a; for a in r.content do GAPDoc2LaTeX(a, str); od; end); # width of index entries, we use a trick to split longer command names GAPDoc2LaTeXProcs.MaxIndexEntryWidth := 35; # a flag for recoding to LaTeX GAPDoc2LaTeXProcs.recode := true; # two utilities for attribute values like labels or text with special # XML or LaTeX characters which gets printed (always as \texttt text) GAPDoc2LaTeXProcs.EscapeAttrValOld := function(str) local res, c; res := ""; for c in str do if c = '\\' then ## Append(res, "{\\gdttbs}"); Append(res, "\\texttt{\\symbol{92}}"); elif c = '_' then Append(res, "\\_"); elif c = '{' then ## Append(res, "{\\gdttob}"); Append(res, "\\texttt{\\symbol{123}}"); elif c = '}' then ## Append(res, "{\\gdttcb}"); Append(res, "\\texttt{\\symbol{125}}"); elif c = '^' then ## Append(res, "{\\gdttht}"); Append(res, "\\texttt{\\symbol{94}}"); elif c = '~' then ## Append(res, "{\\gdttti}"); Append(res, "\\texttt{\\symbol{126}}"); elif c = '<' then Append(res, "{\\textless}"); elif c = '>' then Append(res, "{\\textgreater}"); elif c = '&' then Append(res, "\\&"); elif c = '%' then Append(res, "\\%"); elif c = '$' then Append(res, "\\$"); elif c = '#' then Append(res, "\\#"); else Add(res, c); fi; od; return res; end; # now via Unicode, handle many more characters as well GAPDoc2LaTeXProcs.EscapeAttrVal := function(str) return Encode(Unicode(str), GAPDoc2LaTeXProcs.Encoder); end; GAPDoc2LaTeXProcs.DeleteUsBs := function(str) return Filtered(str, x-> not (x in "\\_")); end; ## this is for getting a string "[ \"A\", 1, 1 ]" from [ "A", 1, 1 ] GAPDoc2LaTeXProcs.StringNrs := function(ssnr) if IsInt(ssnr[1]) then return String(ssnr); else return Concatenation("[ \"", ssnr[1], "\", ", String(ssnr[2]), ", ", String(ssnr[3]), " ]"); fi; end; GAPDoc2LaTeXProcs.Head := StringFile( Filename(DirectoriesPackageLibrary("gapdoc"),"latexhead.tex")); GAPDoc2LaTeXProcs.Tail := Concatenation( "\\newpage\n", "\\immediate\\write\\pagenrlog{[\"End\"], \\arabic{page}];}\n", "\\immediate\\closeout\\pagenrlog\n", "\\end{document}\n"); GAPDoc2LaTeXProcs.Options := rec(); GAPDoc2LaTeXProcs.DefaultOptions := rec( EarlyExtraPreamble := "", LateExtraPreamble := "", InputEncoding := "latin1", ColorDefinitions := rec( link := "0.0,0.0,0.554", cite := "0.0,0.0,0.554", file := "0.0,0.0,0.554", url := "0.0,0.0,0.554", prompt := "0.0,0.0,0.589", brkprompt := "0.589,0.0,0.0", gapinput := "0.589,0.0,0.0", gapoutput := "0.0,0.0,0.0", funcdefs := "0.0,0.0,0.0", chapter := "0.0,0.0,0.0" ), MoreColors := "\\definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064}\n", FontPackages := "\\usepackage{mathptmx,helvet}\n\\usepackage[T1]{fontenc}\n\ \\usepackage{textcomp}\n", HyperrefOptions := rec( pdftex := "true", bookmarks := "true", a4paper := "true", pdftitle := "{Written with GAPDoc}", pdfcreator := "{LaTeX with hyperref package / GAPDoc}", colorlinks := "true", backref := "page", breaklinks := "true", pdfpagemode := "{UseNone}", MoreHyperrefOptions := "" ), TocDepth := "\\setcounter{tocdepth}{1}", Maintitlesize := "\\fontsize{50}{55}\\selectfont", ); # helper function to apply the options to the generic LaTeX head GAPDoc2LaTeXProcs.HeadWithOptions := function(extra) local head, opt, f, ff; head := GAPDoc2LaTeXProcs.Head; opt := GAPDoc2LaTeXProcs.Options; for f in RecFields(opt) do if f = "ColorDefinitions" then for ff in RecFields(opt.(f)) do head := SubstitutionSublist(head, Concatenation("CONFIGCOLOR",ff), opt.(f).(ff)); od; elif f = "HyperrefOptions" then for ff in RecFields(opt.(f)) do head := SubstitutionSublist(head, Concatenation("CONFIGHR",ff), opt.(f).(ff)); od; else head := SubstitutionSublist(head, Concatenation("CONFIG", f), opt.(f)); fi; od; head := SubstitutionSublist(head, "PIExtraPreamble", extra); return head; end; ## arg: a list of strings ## for now only the output type (one of "dvi", "pdf" or "ps") is used # to be enhanced SetGapDocLaTeXOptions := function(arg) local new, recs, r, f, ff; GAPDoc2LaTeXProcs.Options := StructuralCopy(GAPDoc2LaTeXProcs.DefaultOptions); new := GAPDoc2LaTeXProcs.Options; recs := Filtered(arg, IsRecord); # handle some abbreviations if "nocolor" in arg then Add(recs, rec( ColorDefinitions := rec( link := "0.0,0.0,0.0", cite := "0.0,0.0,0.0", file := "0.0,0.0,0.0", url := "0.0,0.0,0.0", prompt := "0.0,0.0,0.0", brkprompt := "0.0,0.0,0.0", gapinput := "0.0,0.0,0.0", gapoutput := "0.0,0.0,0.0", funcdefs := "0.0,0.0,0.0", chapter := "0.0,0.0,0.0" ) ) ); fi; if "utf8" in arg then Add(recs, rec(InputEncoding := "utf8")); fi; if "nopslatex" in arg then Add(recs, rec(FontPackages := "\n")); fi; # now overwrite the defaults for r in recs do for f in RecFields(r) do if IsRecord(r.(f)) then if IsBound(new.(f)) then for ff in RecFields(r.(f)) do if IsBound(new.(f).(ff)) then new.(f).(ff) := r.(f).(ff); fi; od; fi; else if IsBound(new.(f)) then new.(f) := r.(f); fi; fi; od; od; # set encoder accordingly if new.InputEncoding = "utf8" then GAPDoc2LaTeXProcs.Encoder := "LaTeXUTF8"; else GAPDoc2LaTeXProcs.Encoder := "LaTeX"; fi; end; # set defaults SetGapDocLaTeXOptions(); GAPDoc2LaTeXProcs.firstsix := function(r, count) local a; a := PositionSet(r.root.sixcount, count{[1..3]}); if a <> fail then a := r.root.six[r.root.sixindex[a]]; fi; return a; end; ## write head and foot of LaTeX file. GAPDoc2LaTeXProcs.WHOLEDOCUMENT := function(r, str) local i, pi, t, el, a; ## add internal paragraph numbering AddParagraphNumbersGapDocTree(r); ## checking for processing instructions i := 1; pi := rec(); while not r.content[i].name = "Book" do if r.content[i].name = "XMLPI" then t := r.content[i].content; if Length(t) > 5 and t{[1..6]} = "LaTeX " then el := GetSTag(Concatenation("<", t, ">"), 2); for a in NamesOfComponents(el.attributes) do pi.(a) := el.attributes.(a); od; fi; fi; i := i+1; od; ## collect headings of labeled sections, here we must run through the ## whole parse tree first to know the headings of text style forward ## references GAPDoc2LaTeXProcs._labeledSections := rec(); ApplyToNodesParseTree(r, function(rr) if IsRecord(rr) and IsBound(rr.name) and rr.name in ["Chapter", "Section", "Subsection", "Appendix"] then # save heading for "Text" style references to section GAPDoc2LaTeXProcs.(rr.name)(rr,""); fi; end); ## warn if no labels via .six available if not IsBound(r.six) then Info(InfoGAPDoc, 1, "#W WARNING: No labels for section number independent ", "anchors available.\n", "#W Consider running the converter for the text version first!\n"); fi; ## now the actual work starts, we give the found processing instructions ## to the Book handler GAPDoc2LaTeXProcs.Book(r.content[i], str, pi); Unbind(GAPDoc2LaTeXProcs._labeledSections); end; ## comments and processing instructions are generally ignored GAPDoc2LaTeXProcs.XMLPI := function(r, str); end; GAPDoc2LaTeXProcs.XMLCOMMENT := function(r, str); end; # do nothing with Ignore GAPDoc2LaTeXProcs.Ignore := function(arg) end; ## this makes head and foot of the LaTeX output ## - the only processing instructions handled currently are ## - options for the report class (german, papersize, ...) and ## - extra entries in the preamble (\usepackage, macro definitions, ...) GAPDoc2LaTeXProcs.Book := function(r, str, pi) local a; if not IsBound(pi.ExtraPreamble) then pi.ExtraPreamble := ""; fi; Append(str, GAPDoc2LaTeXProcs.HeadWithOptions(pi.ExtraPreamble)); # and now the text of the document GAPDoc2LaTeXContent(r, str); # that's it Append(str, GAPDoc2LaTeXProcs.Tail); end; ## the Body just prints its content GAPDoc2LaTeXProcs.Body := GAPDoc2LaTeXContent; ## the title page, the most complicated looking function GAPDoc2LaTeXProcs.TitlePage := function(r, str) local l, ll, a, s, cont; # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); Append(str, "\\begin{titlepage}\n\\mbox{}\\vfill\n\n\\begin{center}"); # title l := Filtered(r.content, a-> a.name = "Title"); Append(str, "{\\maintitlesize \\textbf{"); s := ""; GAPDoc2LaTeXContent(l[1], s); Append(str, s); Append(str, "\\mbox{}}}\\\\\n\\vfill\n\n"); # set title in info part of PDF document Append(str, "\\hypersetup{pdftitle="); Append(str, s); Append(str, "}\n"); # the title is also used for the page headings Append(str, "\\markright{\\scriptsize \\mbox{}\\hfill "); Append(str, s); Append(str, " \\hfill\\mbox{}}\n"); # subtitle l := Filtered(r.content, a-> a.name = "Subtitle"); if Length(l)>0 then Append(str, "{\\Huge \\textbf{"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}}\\\\\n\\vfill\n\n"); fi; # version l := Filtered(r.content, a-> a.name = "Version"); if Length(l)>0 then Append(str, "{\\Huge "); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # date l := Filtered(r.content, a-> a.name = "Date"); if Length(l)>0 then Append(str, "{"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; Append(str, "\\mbox{}\\\\[2cm]\n"); # author name(s) l := Filtered(r.content, a-> a.name = "Author"); # collect author list for PDF info ll := []; for a in l do Append(str, "{\\Large \\textbf{"); s := ""; GAPDoc2LaTeXContent(rec(content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"])), s); Append(str, s); Add(ll, s); Append(str, "\\mbox{}}}\\\\\n"); od; Append(str, "\\hypersetup{pdfauthor="); Append(str, JoinStringsWithSeparator(ll, "; ")); Append(str, "}\n"); # extra comment for front page l := Filtered(r.content, a-> a.name = "TitleComment"); if Length(l) > 0 then Append(str, "\\mbox{}\\\\[2cm]\n\\begin{minipage}{12cm}\\noindent\n"); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\end{minipage}\n\n"); fi; Append(str, "\\end{center}\\vfill\n\n\\mbox{}\\\\\n"); # email, WWW-homepage and address of author(s), if given l := Filtered(r.content, a-> a.name = "Author"); for a in l do cont := List(a.content, b-> b.name); if "Email" in cont or "Homepage" in cont or "Address" in cont then Append(str, "{\\mbox{}\\\\\n\\small \\noindent \\textbf{"); GAPDoc2LaTeXContent(rec(content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"])), str); Append(str, "}"); if "Email" in cont then Append(str, Concatenation(" ", GAPDocTexts.d.Email, ": ")); GAPDoc2LaTeX(a.content[Position(cont, "Email")], str); fi; if "Homepage" in cont then Append(str, "\\\\\n"); Append(str, Concatenation(" ", GAPDocTexts.d.Homepage, ": ")); GAPDoc2LaTeX(a.content[Position(cont, "Homepage")], str); fi; if "Address" in cont then Append(str, "\\\\\n"); Append(str, Concatenation(" ", GAPDocTexts.d.Address, ": \\begin{minipage}[t]{8cm}\\noindent\n")); GAPDoc2LaTeX(a.content[Position(cont, "Address")], str); Append(str, "\\end{minipage}\n"); fi; Append(str, "}\\\\\n"); fi; od; # Address outside the Author elements l := Filtered(r.content, a-> a.name = "Address"); if Length(l)>0 then Append(str, "\n\\noindent "); Append(str, Concatenation("\\textbf{", GAPDocTexts.d.Address, ": }\\begin{minipage}[t]{8cm}\\noindent\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\end{minipage}\n"); fi; Append(str, "\\end{titlepage}\n\n\\newpage"); # to make physical page numbers same as document page numbers Append(str, "\\setcounter{page}{2}\n"); # abstract l := Filtered(r.content, a-> a.name = "Abstract"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Abstract, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # copyright page l := Filtered(r.content, a-> a.name = "Copyright"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Copyright, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # acknowledgement page l := Filtered(r.content, a-> a.name = "Acknowledgements"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Acknowledgements, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; # colophon page l := Filtered(r.content, a-> a.name = "Colophon"); if Length(l)>0 then Append(str, Concatenation("{\\small \n\\section*{", GAPDocTexts.d.Colophon, "}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(l[1].count{[1..3]}), "}\n")); GAPDoc2LaTeXContent(l[1], str); Append(str, "\\mbox{}}\\\\[1cm]\n"); fi; Append(str,"\\newpage\n\n"); end; ## this allows line breaks in URL strings s for use with \texttt{s} by ## inserting some "}\discretionary{}{}{}\texttt{" GAPDoc2LaTeXProcs.URLBreaks := function(s) local pos, ss, old; # not after :// pos := PositionSublist(s, "://"); if pos = fail then pos := Minimum(3, Length(s)); else pos := pos + 2; fi; ss := s{[1..pos]}; old := pos; pos := Position(s, '/', old); while pos <> fail and pos+3 < Length(s) do Append(ss, s{[old+1..pos]}); Append(ss, "}\\discretionary {}{}{}\\texttt{"); old := pos; pos := Position(s, '/', old); od; Append(ss, s{[old+1..Length(s)]}); return ss; end; ## ~ and # characters are correctly escaped ## arg: r, str[, pre] GAPDoc2LaTeXProcs.Link := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.LinkText := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.URL := function(arg) local r, str, pre, rr, txt, s; r := arg[1]; str := arg[2]; if Length(arg)>2 then pre := arg[3]; else pre := ""; fi; rr := First(r.content, a-> a.name = "LinkText"); if rr <> fail then txt := ""; GAPDoc2LaTeXContent(rr, txt); rr := First(r.content, a-> a.name = "Link"); if rr = fail then Info(InfoGAPDoc, 1, "#W missing element for text ", txt, "\n"); s := "MISSINGLINK"; else s := ""; # must avoid recoding for first argument of \href GAPDoc2LaTeXProcs.recode := false; GAPDoc2LaTeXContent(rr, s); GAPDoc2LaTeXProcs.recode := true; fi; else s := ""; GAPDoc2LaTeXProcs.recode := false; GAPDoc2LaTeXContent(r, s); GAPDoc2LaTeXProcs.recode := true; if IsBound(r.attributes.Text) then txt := r.attributes.Text; else # need recode in second argument of \href txt := Encode(Unicode(s, "UTF-8"), GAPDoc2LaTeXProcs.Encoder); txt := Concatenation("\\texttt{", txt, "}"); fi; fi; Append(str, Concatenation("\\href{", pre, s, "} {", txt, "}")); end; GAPDoc2LaTeXProcs.Homepage := GAPDoc2LaTeXProcs.URL; GAPDoc2LaTeXProcs.Email := function(r, str) # we add the `mailto://' phrase GAPDoc2LaTeXProcs.URL(r, str, "mailto://"); end; ## the sectioning commands are just translated and labels are ## generated, if given as attribute GAPDoc2LaTeXProcs.ChapSect := function(r, str, sect) local posh, a, s; posh := Position(List(r.content, a-> a.name), "Heading"); # heading Append(str, Concatenation("\n\\", sect, "{")); s := ""; if posh <> fail then GAPDoc2LaTeXProcs.Heading1(r.content[posh], s); fi; Append(str, "\\textcolor{Chapter }{"); Append(str, s); Append(str, "}}"); # label for references if IsBound(r.attributes.Label) then Append(str, "\\label{"); Append(str, r.attributes.Label); Append(str, "}\n"); # save heading for "Text" style references to section GAPDoc2LaTeXProcs._labeledSections.(r.attributes.Label) := s; fi; # page number info for online help (no r.count below Ignore), # we also add a section number and page number independent label, # if available if IsBound(r.count) then Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; # the actual content Append(str, "{\n"); GAPDoc2LaTeXContent(r, str); Append(str, "}\n\n"); fi; end; ## this really produces the content of the heading GAPDoc2LaTeXProcs.Heading1 := function(r, str) GAPDoc2LaTeXContent(r, str); end; ## and this ignores the heading (for simpler recursion) GAPDoc2LaTeXProcs.Heading := function(r, str) end; GAPDoc2LaTeXProcs.Chapter := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "chapter"); end; GAPDoc2LaTeXProcs.Appendix := function(r, str) if r.count[1] = "A" then Append(str, "\n\n\\appendix\n\n"); fi; GAPDoc2LaTeXProcs.ChapSect(r, str, "chapter"); end; GAPDoc2LaTeXProcs.Section := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "section"); end; GAPDoc2LaTeXProcs.Subsection := function(r, str) GAPDoc2LaTeXProcs.ChapSect(r, str, "subsection"); end; ## table of contents, the job is completely delegated to LaTeX GAPDoc2LaTeXProcs.TableOfContents := function(r, str) # page number info for online help Append(str, Concatenation("\\def\\contentsname{", GAPDocTexts.d.Contents, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}}\n")); Append(str, "\n\\tableofcontents\n\\newpage\n\n"); end; ## bibliography, the job is completely delegated to LaTeX and BibTeX GAPDoc2LaTeXProcs.Bibliography := function(r, str) local dat, fname, t, b, st, a; # check if bib data are in BibXMLext format, in that case produce a # BibTeX file dat := r.attributes.Databases; dat := SplitString(dat, "", ", \n\t\b"); dat := Filtered(dat, a-> Length(a) > 3 and a{[Length(a)-3..Length(a)]} = ".xml"); dat := List(dat, a-> Filename(r.root.bibpath, a)); for fname in dat do b := ParseBibXMLextFiles(fname); b := List(b.entries, a-> RecBibXMLEntry(a, b.strings, "BibTeX")); WriteBibFile(Concatenation(fname, ".bib"), [b, [], []]); od; if IsBound(r.attributes.Style) then st := r.attributes.Style; else st := "alpha"; fi; # page number info for online help Append(str, Concatenation("\\def\\bibname{", GAPDocTexts.d.References, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; Append(str, "}\n"); Append(str, "\n\\bibliographystyle{"); Append(str, st); Append(str,"}\n\\bibliography{"); Append(str, r.attributes.Databases); Append(str, "}\n\n"); # toc entry Append(str, "\\addcontentsline{toc}{chapter}{"); Append(str, GAPDocTexts.d.References); Append(str, "}\n\n"); end; ## as default we normalize white space in text and split the result ## into lines (leading and trailing white space is also substituted ## by one space). GAPDoc2LaTeXProcs.PCDATA := function(r, str) local lines, i; if Length(r.content)>0 and r.content[1] in WHITESPACE then Add(str, ' '); fi; lines := r.content; if GAPDoc2LaTeXProcs.recode = true then lines := Encode(Unicode(lines), GAPDoc2LaTeXProcs.Encoder); fi; lines := FormatParagraph(lines, "left"); if Length(lines)>0 then if r.content[Length(r.content)] in WHITESPACE then lines[Length(lines)] := ' '; else Unbind(lines[Length(lines)]); fi; fi; Append(str, lines); end; ## end of paragraph GAPDoc2LaTeXProcs.P := function(r, str) Append(str, "\n\n"); end; ## forced line break GAPDoc2LaTeXProcs.Br := function(r, str) Append(str, "\\\\\n"); end; ## generic function to get content and wrap by some markup GAPDoc2LaTeXProcs.WrapMarkup := function(r, str, pre, post) local s; s := ""; GAPDoc2LaTeXContent(r, s); Append(str, Concatenation(pre, s, post)); end; ## setting in typewriter GAPDoc2LaTeXProcs.WrapTT := function(r, str) GAPDoc2LaTeXProcs.WrapMarkup(r, str, "\\texttt{", "}"); end; ## GAP keywords GAPDoc2LaTeXProcs.K := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## verbatim GAP code GAPDoc2LaTeXProcs.C := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## file names GAPDoc2LaTeXProcs.F := function(r, str) GAPDoc2LaTeXProcs.WrapTT(r, str); end; ## argument names GAPDoc2LaTeXProcs.A := function(r, str) Append(str, "\\mbox{"); ## GAPDoc2LaTeXProcs.WrapTT(r, str); ## the \mdseries is necessary because there is no bold-sl which ## LaTeX substitutes by bold-normal, but we want medium-sl GAPDoc2LaTeXProcs.WrapMarkup(r, str, "\\texttt{\\mdseries\\slshape ", "}"); Append(str, "}"); end; ## simple maths GAPDoc2LaTeXProcs.M := function(r, str) local saveenc; Append(str, "$"); # here the input is already coded in LaTeX saveenc := GAPDoc2LaTeXProcs.Encoder; GAPDoc2LaTeXProcs.Encoder := "LaTeXleavemarkup"; GAPDoc2LaTeXContent(r, str); GAPDoc2LaTeXProcs.Encoder := saveenc; Append(str, "$"); end; ## in LaTeX same as GAPDoc2LaTeXProcs.Math := GAPDoc2LaTeXProcs.M; ## displayed maths GAPDoc2LaTeXProcs.Display := function(r, str) local saveenc; if Length(str)>0 and str[Length(str)] <> '\n' then Add(str, '\n'); fi; Append(str, "\\["); saveenc := GAPDoc2LaTeXProcs.Encoder; GAPDoc2LaTeXProcs.Encoder := "LaTeXleavemarkup"; GAPDoc2LaTeXContent(r, str); GAPDoc2LaTeXProcs.Encoder := saveenc; Append(str, "\\]\n"); end; ## emphazised text GAPDoc2LaTeXProcs.Emph := function(r, str) local a; Append(str, "\\emph{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; ## quoted text GAPDoc2LaTeXProcs.Q := function(r, str) local a; Append(str, "``"); GAPDoc2LaTeXContent(r, str); Append(str, "''"); end; ## Package names GAPDoc2LaTeXProcs.Package := function(r, str) local a; Append(str, "\\textsf{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; ## menu items GAPDoc2LaTeXProcs.B := function(r, str) local a; Append(str, "\\textsc{"); GAPDoc2LaTeXContent(r, str); Append(str, "}"); end; GAPDoc2LaTeXProcs.verbcontent := function(r, delfirst) local cont; # here we cannot use recoding, fall back to SimplifiedUnicodeString (latin1) # first collect content without recoding or reformatting cont := GetTextXMLTree(r); if GAPDoc2LaTeXProcs.Options.InputEncoding = "latin1" then cont := Encode(SimplifiedUnicodeString(Unicode(cont), "latin1"), "latin1"); fi; cont := SplitString(cont, "\n", ""); # if first line has white space only, we remove it if delfirst and Length(cont) > 0 and ForAll(cont[1], x-> x in WHITESPACE) then cont := cont{[2..Length(cont)]}; fi; cont := Concatenation(List(cont, a-> Concatenation(" ", a, "\n"))); return cont; end; ## verbatim GAP session GAPDoc2LaTeXProcs.Verb := function(r, str) local cont, a, s; Append(str, "\n\\begin{verbatim}"); Append(str, GAPDoc2LaTeXProcs.verbcontent(r, false)); Append(str, "\\end{verbatim}\n"); end; GAPDoc2LaTeXProcs.ExampleLike := function(r, str, label, findprompts) local cont, comopt, comchars, sp, pos, c; cont := GAPDoc2LaTeXProcs.verbcontent(r, true); comopt := ""; if findprompts then comchars := ""; for c in Concatenation("!@|", LETTERS) do if not c in cont then Add(comchars, c); if Length(comchars) = 3 then break; fi; fi; od; if Length(comchars) = 3 then comopt := Concatenation("commandchars=",comchars,","); sp := SplitString(cont, "\n", ""); cont := ""; for r in sp do if Length(r) > 6 and r{[1..7]} = " gap> " then Append(cont, Concatenation(" ",comchars{[1]}, "gapprompt",comchars{[2]}, "gap>",comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[8..Length(r)]},comchars{[3]},"\n")); elif Length(r) > 3 and r{[1..4]} = " > " then Append(cont, Concatenation(" ",comchars{[1]}, "gapprompt",comchars{[2]}, ">",comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[5..Length(r)]},comchars{[3]},"\n")); elif Length(r) > 5 and r{[1..5]} = " brk" then pos := Position(r, '>'); Append(cont, Concatenation(" ",comchars{[1]}, "gapbrkprompt",comchars{[2]}, r{[3..pos]},comchars{[3]}," ",comchars{[1]},"gapinput", comchars{[2]},r{[pos+2..Length(r)]},comchars{[3]},"\n")); else Append(cont, r); Add(cont, '\n'); fi; od; fi; fi; Append(str, Concatenation("\n\\begin{Verbatim}[",comopt, "fontsize=\\small,", "frame=single,label=", label, "]\n")); Append(str, cont); Append(str, "\\end{Verbatim}\n"); end; ## log of session and GAP code is typeset the same way as GAPDoc2LaTeXProcs.Example := function(r, str) GAPDoc2LaTeXProcs.ExampleLike(r, str, GAPDocTexts.d.Example, true); end; GAPDoc2LaTeXProcs.Log := function(r, str) GAPDoc2LaTeXProcs.ExampleLike(r, str, GAPDocTexts.d.Log, true); end; GAPDoc2LaTeXProcs.Listing := function(r, str) if IsBound(r.attributes.Type) then GAPDoc2LaTeXProcs.ExampleLike(r, str, r.attributes.Type, false); else GAPDoc2LaTeXProcs.ExampleLike(r, str, "", false); fi; end; ## explicit labels GAPDoc2LaTeXProcs.Label := function(r, str) Append(str, "\\label{"); Append(str, r.attributes.Name); Append(str, "}"); end; ## citations GAPDoc2LaTeXProcs.Cite := function(r, str) Append(str, "\\cite"); if IsBound(r.attributes.Where) then Add(str, '['); Append(str, Encode(Unicode(r.attributes.Where), GAPDoc2LaTeXProcs.Encoder)); Add(str, ']'); fi; Add(str, '{'); Append(str, r.attributes.Key); Add(str, '}'); end; ## explicit index entries GAPDoc2LaTeXProcs.Subkey := GAPDoc2LaTeXContent; GAPDoc2LaTeXProcs.Index := function(r, str) local s, sub, a; s := ""; sub := ""; for a in r.content do if a.name = "Subkey" then GAPDoc2LaTeX(a, sub); else GAPDoc2LaTeX(a, s); fi; od; NormalizeWhitespace(s); NormalizeWhitespace(sub); if IsBound(r.attributes.Key) then s := Concatenation(r.attributes.Key, "@", s); fi; if Length(sub) > 0 then s := Concatenation(s, "!", sub); elif IsBound(r.attributes.Subkey) then s := Concatenation(s, "!", r.attributes.Subkey); fi; Append(str, "\\index{"); Append(str, s); Append(str, "}"); end; ## this produces an implicit index entry and a label entry GAPDoc2LaTeXProcs.LikeFunc := function(r, str, typ) local nam, namclean, lab, inam, i; Append(str, "\\noindent\\textcolor{FuncColor}{$\\triangleright$\\ \\ \\texttt{"); nam := r.attributes.Name; namclean := GAPDoc2LaTeXProcs.DeleteUsBs(nam); # we allow _, \ and so on here nam := GAPDoc2LaTeXProcs.EscapeAttrVal(nam); Append(str, nam); if IsBound(r.attributes.Arg) then Append(str, "({\\mdseries\\slshape "); Append(str, GAPDoc2LaTeXProcs.EscapeAttrVal( NormalizedArgList(r.attributes.Arg))); Append(str, "})"); fi; # possible label if IsBound(r.attributes.Label) then lab := Concatenation("!", r.attributes.Label); else lab := ""; fi; # index entry # handle extremely long names if Length(nam) > GAPDoc2LaTeXProcs.MaxIndexEntryWidth then inam := nam{[1..3]}; for i in [4..Length(nam)-3] do if nam[i] in CAPITALLETTERS then Append(inam, "}\\-\\texttt{"); fi; Add(inam, nam[i]); od; Add(inam, nam[Length(nam)-2]); Add(inam, nam[Length(nam)-1]); Add(inam, nam[Length(nam)]); else inam := nam; fi; Append(str, Concatenation("\\index{", namclean, "@\\texttt{", inam, "}", lab, "}\n")); # label (if not given, the default is the Name) if IsBound(r.attributes.Label) then namclean := Concatenation(namclean, ":", r.attributes.Label); fi; Add(GAPDoc2LaTeXProcs._currentSubsection, namclean); Append(str, Concatenation("\\label{", namclean, "}\n")); # some hint about the type of the variable Append(str, "}\\hfill{\\scriptsize ("); Append(str, typ); Append(str, ")}}\\\\\n"); end; GAPDoc2LaTeXProcs.Func := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Func); end; GAPDoc2LaTeXProcs.Oper := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Oper); end; GAPDoc2LaTeXProcs.Meth := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Meth); end; GAPDoc2LaTeXProcs.Filt := function(r, str) # r.attributes.Type could be "representation", "category", ... if IsBound(r.attributes.Type) then GAPDoc2LaTeXProcs.LikeFunc(r, str, r.attributes.Type); else GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Filt); fi; end; GAPDoc2LaTeXProcs.Prop := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Prop); end; GAPDoc2LaTeXProcs.Attr := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Attr); end; GAPDoc2LaTeXProcs.Var := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Var); end; GAPDoc2LaTeXProcs.Fam := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.Fam); end; GAPDoc2LaTeXProcs.InfoClass := function(r, str) GAPDoc2LaTeXProcs.LikeFunc(r, str, GAPDocTexts.d.InfoClass); end; ## using the HelpData(.., .., "ref") interface GAPDoc2LaTeXProcs.ResolveExternalRef := function(bookname, label, nr) local info, match, res; info := HELP_BOOK_INFO(bookname); if info = fail then return fail; fi; match := Concatenation(HELP_GET_MATCHES(info, SIMPLE_STRING(label), true)); # maybe change, and check if there are matches to several subsections? #ssecs := List(match, i-> HELP_BOOK_HANDLER.(info.handler).HelpData(info, # match[i][2], "ref")[7]); if Length(match) < nr then return fail; fi; res := HELP_BOOK_HANDLER.(info.handler).HelpData(info, match[nr][2], "ref"); res[1] := SubstitutionSublist(res[1], " (not loaded): ", ": ", "one"); return res; end; GAPDoc2LaTeXProcs.Ref := function(r, str) local funclike, int, txt, ref, lab, sectlike, slab; # function like cases funclike := [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; int := Intersection(funclike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := Concatenation(txt, ":", r.attributes.Label); else lab := txt; fi; if IsBound(r.attributes.BookName) then slab := txt; if IsBound(r.attributes.Label) then slab := Concatenation(slab, " (", r.attributes.Label, ")"); fi; ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, slab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" (", Encode(Unicode(lab), GAPDoc2LaTeXProcs.Encoder) , "???)"); else # the search text for online help including book name ref := Concatenation(" (\\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "})"); fi; else ref := Concatenation(" (\\ref{", GAPDoc2LaTeXProcs.DeleteUsBs(lab), "})"); fi; # delete ref, if pointing to current subsection if not IsBound(r.attributes.BookName) and IsBound(GAPDoc2LaTeXProcs._currentSubsection) and lab in GAPDoc2LaTeXProcs._currentSubsection then ref := ""; fi; Append(str, Concatenation("\\texttt{", GAPDoc2LaTeXProcs.EscapeAttrVal(txt), "}", ref)); return; fi; # section like cases sectlike := ["Chap", "Sect", "Subsect", "Appendix"]; int := Intersection(sectlike, NamesOfComponents(r.attributes)); if Length(int)>0 then txt := r.attributes.(int[1]); if IsBound(r.attributes.Label) then lab := r.attributes.Label; else lab := txt; fi; if IsBound(r.attributes.BookName) then ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, lab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" (", lab, "???)"); else # the search text for online help including book name ref := Concatenation(" (\\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "})"); fi; elif IsBound(r.attributes.Style) and r.attributes.Style = "Text" then if IsBound(GAPDoc2LaTeXProcs._labeledSections.(lab)) then ref := Concatenation("\\hyperref[",lab,"]{`", StripBeginEnd( GAPDoc2LaTeXProcs._labeledSections.(lab), WHITESPACE), "'}"); else Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := "`???'"; fi; else # with sectioning references Label must be given lab := r.attributes.(int[1]); #ref := Concatenation("\\ref{", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "}"); ref := Concatenation("\\ref{", lab, "}"); fi; Append(str, ref); return; fi; # neutral reference to a label if IsBound(r.attributes.BookName) then if IsBound(r.attributes.Label) then lab := r.attributes.Label; else lab := "_X_X_X"; fi; ref := GAPDoc2LaTeXProcs.ResolveExternalRef( r.attributes.BookName, lab, 1); if ref = fail then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); ref := Concatenation(" ", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "??? "); else # the search text for online help including book name ref := Concatenation(" \\textbf{", GAPDoc2LaTeXProcs.EscapeAttrVal(ref[1]), "}"); fi; else lab := r.attributes.Label; ref := Concatenation("\\ref{", GAPDoc2LaTeXProcs.EscapeAttrVal(lab), "}"); fi; Append(str, ref); return; end; # just process GAPDoc2LaTeXProcs.Address := function(r, str) GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.Description := function(r, str) Append(str, "\n\n"); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.Returns := function(r, str) Append(str, Concatenation("\\textbf{\\indent ", GAPDocTexts.d.Returns, ":\\ }\n")); GAPDoc2LaTeXContent(r, str); Append(str,"\n\n"); end; GAPDoc2LaTeXProcs.ManSection := function(r, str) local funclike, f, lab, i, a; # if there is a Heading then handle as subsection if ForAny(r.content, a-> IsRecord(a) and a.name = "Heading") then GAPDoc2LaTeXProcs._currentSubsection := r.count{[1..3]}; GAPDoc2LaTeXProcs.ChapSect(r, str, "subsection"); Unbind(GAPDoc2LaTeXProcs._currentSubsection); return; fi; # function like elements funclike := [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; # heading comes from name of first function like element i := 1; while not r.content[i].name in funclike do i := i+1; od; f := r.content[i]; if IsBound(f.attributes.Label) then lab := Concatenation(" (", f.attributes.Label, ")"); else lab := ""; fi; Append(str, Concatenation("\n\n\\subsection{\\textcolor{Chapter }{", GAPDoc2LaTeXProcs.EscapeAttrVal(f.attributes.Name), lab, "}}\n")); # page number info for online help Append(str, Concatenation("\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\\nobreak\n")); # label for references if IsBound(r.attributes.Label) then Append(str, "\\label{"); Append(str, r.attributes.Label); Append(str, "}\n"); # save heading for "Text" style references to section GAPDoc2LaTeXProcs._labeledSections.(r.attributes.Label) := Concatenation( GAPDoc2LaTeXProcs.EscapeAttrVal(f.attributes.Name), lab); fi; if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; # to avoid references to local subsection in description: GAPDoc2LaTeXProcs._currentSubsection := r.count{[1..3]}; Append(str, "{"); GAPDoc2LaTeXContent(r, str); Append(str, "}\n\n"); Unbind(GAPDoc2LaTeXProcs._currentSubsection); end; GAPDoc2LaTeXProcs.Mark := function(r, str) Append(str, "\n\\item[{"); GAPDoc2LaTeXContent(r, str); Append(str, "}] "); end; GAPDoc2LaTeXProcs.Item := function(r, str) Append(str, "\n\\item "); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.List := function(r, str) local item, type, a; if "Mark" in List(r.content, a-> a.name) then item := ""; type := "description"; else item := "\n\\item "; type := "itemize"; fi; Append(str, Concatenation("\n\\begin{", type, "}")); for a in r.content do if a.name = "Mark" then GAPDoc2LaTeXProcs.Mark(a, str); elif a.name = "Item" then Append(str, item); GAPDoc2LaTeXContent(a, str); fi; od; Append(str, Concatenation("\n\\end{", type, "}\n")); end; GAPDoc2LaTeXProcs.Enum := function(r, str) Append(str, "\n\\begin{enumerate}"); GAPDoc2LaTeXContent(r, str); Append(str, "\n\\end{enumerate}\n"); end; GAPDoc2LaTeXProcs.TheIndex := function(r, str) local a; # page number info for online help Append(str, Concatenation("\\def\\indexname{", GAPDocTexts.d.Index, "\\logpage{", GAPDoc2LaTeXProcs.StringNrs(r.count{[1..3]}), "}\n")); if IsBound(r.root.six) then ## a := First(r.root.six, x-> x[3] = r.count{[1..3]}); a := GAPDoc2LaTeXProcs.firstsix(r, r.count); if a <> fail and IsBound(a[7]) then Append(str, Concatenation("\\hyperdef{L}{", a[7], "}{}\n")); fi; fi; Append(str, "}\n\n"); # toc entry Append(str, "\\cleardoublepage\n\\phantomsection\n"); Append(str, "\\addcontentsline{toc}{chapter}{"); Append(str, GAPDocTexts.d.Index); Append(str, "}\n"); Append(str, "\n\n\\printindex\n\n"); end; # like PCDATA GAPDoc2LaTeXProcs.EntityValue := GAPDoc2LaTeXProcs.PCDATA; GAPDoc2LaTeXProcs.Table := function(r, str) local cap; if (IsBound(r.attributes.Only) and r.attributes.Only <> "LaTeX") or (IsBound(r.attributes.Not) and r.attributes.Not = "LaTeX") then return; fi; # head part of table and tabular if IsBound(r.attributes.Label) then Append(str, "\\mbox{}\\label{"); Append(str, r.attributes.Label); Add(str, '}'); fi; Append(str, "\\begin{center}\n\\begin{tabular}{"); Append(str, r.attributes.Align); Add(str, '}'); # the rows of the table GAPDoc2LaTeXContent(r, str); # the trailing part with caption, if given Append(str, "\\end{tabular}\\\\[2mm]\n"); cap := Filtered(r.content, a-> a.name = "Caption"); if Length(cap) > 0 then GAPDoc2LaTeXProcs.Caption1(cap[1], str); fi; Append(str, "\\end{center}\n\n"); end; # do nothing, we call .Caption1 directly in .Table GAPDoc2LaTeXProcs.Caption := function(r, str) return; end; # here the caption text is produced GAPDoc2LaTeXProcs.Caption1 := function(r, str) Append(str, Concatenation("\\textbf{", GAPDocTexts.d.Table, ": }")); GAPDoc2LaTeXContent(r, str); end; GAPDoc2LaTeXProcs.HorLine := function(r, str) Append(str, "\\hline\n"); end; GAPDoc2LaTeXProcs.Row := function(r, str) local i, l; l := Filtered(r.content, a-> a.name = "Item"); for i in [1..Length(l)-1] do GAPDoc2LaTeXContent(l[i], str); Append(str, "&\n"); od; GAPDoc2LaTeXContent(l[Length(l)], str); Append(str, "\\\\\n"); end; GAPDoc2LaTeXProcs.Alt := function(r, str) local take, types; take := false; if IsBound(r.attributes.Only) then NormalizeWhitespace(r.attributes.Only); types := SplitString(r.attributes.Only, "", " ,"); if "LaTeX" in types or "BibTeX" in types then take := true; GAPDoc2LaTeXProcs.recode := false; fi; fi; if IsBound(r.attributes.Not) then NormalizeWhitespace(r.attributes.Not); types := SplitString(r.attributes.Not, "", " ,"); if not "LaTeX" in types then take := true; fi; fi; if take then GAPDoc2LaTeXContent(r, str); fi; GAPDoc2LaTeXProcs.recode := true; end; # copy a few entries with two element names GAPDoc2LaTeXProcs.E := GAPDoc2LaTeXProcs.Emph; GAPDoc2LaTeXProcs.Keyword := GAPDoc2LaTeXProcs.K; GAPDoc2LaTeXProcs.Code := GAPDoc2LaTeXProcs.C; GAPDoc2LaTeXProcs.File := GAPDoc2LaTeXProcs.F; GAPDoc2LaTeXProcs.Button := GAPDoc2LaTeXProcs.B; GAPDoc2LaTeXProcs.Arg := GAPDoc2LaTeXProcs.A; GAPDoc2LaTeXProcs.Quoted := GAPDoc2LaTeXProcs.Q; GAPDoc2LaTeXProcs.Par := GAPDoc2LaTeXProcs.P; GAPDoc-1.5.1/lib/XMLParser.gi0000644000175000017500000010767412026346064014127 0ustar billbill############################################################################# ## #W XMLParser.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files XMLParser.g{d,i} contain a non-validating XML parser and some ## utilities. ## BindGlobal("EMPTYCONTENT", 0); BindGlobal("XMLPARSERFLAGS", rec()); BindGlobal("NAMECHARS", ## here ':' is missing since it will probably become reserved ## for name space syntax in future XML Set(List(Concatenation([45,46], [48..57], [58], [65..90], [95], [97..122]), CHAR_INT)) ); ## two helper functions for parsing # next successive characters not in delim (resp. enddelim) - default WHITESPACE # arg: str, pos[, delim[, enddelim]] BindGlobal("GetWord", function(arg) local str, pos, delim, enddelim, len, pos2; str := arg[1]; pos := arg[2]; if Length(arg)>2 then delim := arg[3]; if Length(arg)>3 then enddelim := arg[4]; else enddelim := delim; fi; else delim := WHITESPACE; enddelim := WHITESPACE; fi; len := Length(str); while pos <= len and str[pos] in delim do pos := pos + 1; od; pos2 := pos; while pos2 <= len and not str[pos2] in enddelim do pos2 := pos2 + 1; od; if pos2>len then return fail; else return [pos, pos2-1]; fi; end); # first position after pos with character outside chars BindGlobal("GetChars", function(str, pos, chars) local len; len := Length(str); while pos <= len and str[pos] in chars do pos := pos + 1; od; if pos > len then return fail; else return pos; fi; end); # returns for string, position: [line number, [begin..end position of # line]] (range without the '\n') BindGlobal("LineNumberStringPosition", function(str, pos) local p, nl, l; p := 0; l := 0; nl := 0; while p<>fail and p < pos do l := p; p := Position(str, '\n', p); nl := nl+1; od; if p=fail then p := Length(str)+1; fi; if pos = p then nl := nl - 1; fi; return [nl, [l+1..p-1]]; end); # printing of error message for non-well formed XML document, # also shows some text around position of error. XMLPARSEORIGINS := false; BindGlobal("ParseError", function(str, pos, comment) local Show, nl, ShowOrigin, r, badline, i, off; # for examination of error Show := function() Pager(rec(lines := str, start := nl[1])); end; ShowOrigin := function() if XMLPARSEORIGINS <> false then Pager(rec(lines := StringFile(r[1]), start := r[2])); else Show(); fi; end; if InfoLevel(InfoXMLParser) > 0 then if XMLPARSERFLAGS.Encoding <> "UTF-8" then # we have an 8 bit encoding and must compute offset for original # position off := Number([1..pos], function(i) local c; c := INT_CHAR(str[i]); return c > 127 and c < 192; end); else off := 0; fi; # this is in UTF-8 document nl := LineNumberStringPosition(str, pos); if XMLPARSEORIGINS <> false then # need offset since in original encoding r := OriginalPositionDocument(XMLPARSEORIGINS, pos-off); fi; Print("XML Parse Error: Line ", nl[1]); Print(" Character ", pos-nl[2][1]+1, "\n"); if XMLPARSEORIGINS <> false then Print("Original file: ", r[1], ", line number ", r[2],".\n"); fi; badline := str{nl[2]}; # to be perfect, consider current TERM encoding, ignore for now Print("-----------\n", badline, "\n"); # this uses the same non-' ' whitespace to get the '^' at the right position for i in [1..pos-nl[2][1]] do if not badline[i] in WHITESPACE then badline[i] := ' '; fi; od; Print(badline{[1..pos-nl[2][1]]}); Print("^", "\n-----------\n", comment, "\n!!! Type 'Show();' to watch the", " input string in pager - starting with\n line containing error !!!\n"); if XMLPARSEORIGINS <> false then Print("Or 'ShowOrigin();' to look it up in its source file.\n"); fi; fi; Error(); end); ## a container to collect named entities for the parser BindGlobal("ENTITYDICT", rec()); ## the default XML entities BindGlobal("ENTITYDICT_default", rec( lt := "&#60;", gt := ">", amp := "&#38;", apos := "'", quot := """) ); ## the predefined entities of the GAPDoc package ## in LaTeX we use some saved boxes defined in our preamble for ## \, ~, ^, {, } because we think that the \texttt versions of these ## characters look better (than mathmode chars or accents without letter) # (although this is a general XML parser, we make it convenient for # GAPDoc documents) BindGlobal("ENTITYDICT_GAPDoc", rec( # compatibility entities, no longer needed by GAPDoc >= 1.0 tamp := "&", tlt := "<", tgt := ">", hash := "#", dollar := "$", percent := "%", tilde := "~", bslash := "\\", obrace := "{", cbrace := "}", uscore := "_", circum := "^", nbsp := " ", copyright := "©", ndash := "–", GAP := "GAP", GAPDoc := "GAPDoc", TeX := "{\\TeX}TeX", LaTeX := "{\\LaTeX}LaTeX", BibTeX := "Bib{\\TeX}BibTeX", MeatAxe := "MeatAxe", XGAP := "XGAP", CC := "ℂ", ZZ := "ℤ", NN := "ℕ", PP := "ℙ", QQ := "ℚ", HH := "ℍ", RR := "ℝ", ) ); ## Parsing and resolving an entity, the needed substitution text for ## non-character entities must be bound in ENTITYDICT. ## -- assuming str[pos-1] = '&' ## -- returns pseudo-element (Char)EntityValue with content the result string ## -- character entities are just substituted and returned as string ## -- the replacement for other entities is reparsed for recursive ## substitution InstallGlobalFunction(GetEnt, function(str, pos) local d, i, ch, pos1, nam, doc, res, ent; # character entity if str[pos] = '\#' then d := ""; if str[pos+1] = 'x' then i := pos + 2; while str[i] <> ';' do Add(d, str[i]); i := i+1; od; d := NumberDigits(d, 16); else i := pos+1; while str[i] <> ';' do Add(d, str[i]); i := i+1; od; d := NumberDigits(d, 10); fi; # must consider this as unicode, translate it to UTF-8 res := rec(name := "CharEntityValue", next := i+1, content := Encode(Unicode([d]), "UTF-8")); return res; fi; # else replace and reparse for recursive entity replacements pos1 := Position(str, ';', pos-1); if pos1=pos then ParseError(str, pos, "empty entity name not allowed"); elif pos1 = fail then ParseError(str, pos, "no semicolon in entity reference"); fi; nam := str{[pos..pos1-1]}; if not IsBound(ENTITYDICT.(nam)) then # XXX error or better going on here? ## ParseError(str, pos, "don't know entity name"); Info(InfoXMLParser, 1, "#W WARNING: Entity with name `", nam, "' not known!\n#W", " (Specify in tag or ", "in argument to parser!)\n"); doc := Concatenation("UNKNOWNEntity(", nam, ")"); else doc := ENTITYDICT.(nam); fi; i := 1; res := ""; while i <= Length(doc) do if doc[i] <> '&' or (i '\#') then Add(res, doc[i]); i := i+1; else ent := GetEnt(doc, i+1); Append(res, ent.content); i := ent.next; fi; od; return rec(name := "EntityValue", content := res, next := pos1+1); end); ## reading a start tag including attribute values # returns rec(name := elementname, # attributes := rec( attributename1 := attributevalue1, ...) # content := EMPTYCONTENT or [] (to be filled recursively) # next := positon in string after start tag ) # Special handling of case pos=1: the element name is not parsed but assumed # to be WHOLEDOCUMENT; this way a complete document can be put in one pseudo # element of this name. # assuming str[pos-1] = '<' and str[pos]<>'/' InstallGlobalFunction(GetSTag, function(str, pos) local res, pos2, start, attr, atval, delim, a, ent; res := rec(attributes := rec()); # a small hack that allows to call GetElement with a whole document # after appending "" if pos=1 then res.name := "WHOLEDOCUMENT"; res.next := 1; res.content := []; res.input := ShallowCopy(str); return res; fi; # name of element pos2 := GetChars(str, pos, NAMECHARS); if pos2=fail then ParseError(str, pos, "documents ends in element name"); fi; if pos2=pos then ParseError(str, pos, "tag must start with name \'" do if not str[pos-1] in WHITESPACE then ParseError(str, pos-1, Concatenation("there must be white space ", "before attribute name")); fi; pos2 := GetChars(str, pos, NAMECHARS); if pos2=fail then ParseError(str, pos, "document ends in attribute name"); fi; if pos2=pos then ParseError(str, pos, "attribute must have non-empty name"); fi; # reading attribute value attr := str{[pos..pos2-1]}; ## if not (str[pos2] = '=' and str[pos2+1] in "\"'") then ## ParseError(str, pos2, Concatenation("attribute must be specified ", ## "in form \'attr=\"text\"\'")); ## fi; ## delim := str[pos2+1]; # can be white space around = pos2 := GetChars(str, pos2, WHITESPACE); if pos2 = fail or str[pos2] <> '=' then ParseError(str, pos2, "expecting '=' for attribute value"); fi; pos2 := GetChars(str, pos2+1, WHITESPACE); if pos2 = fail or not str[pos2] in "\"'" then ParseError(str, pos2, "expecting quotes for attribute value"); fi; delim := str[pos2]; atval := ""; pos2 := pos2 + 1; while str[pos2] <> delim do # we allow attr='fkjf"fafds' as well, see AnnStd 2.3 pos2 := GetWord(str, pos2, "", "<&\"'"); if pos2=fail then ParseError(str, pos, "document ends in attribute value"); fi; # must allow &xyz; for entity resolution as well if not str[pos2[2]+1] = delim then if str[pos2[2]+1] = '&' then ent := GetEnt(str, pos2[2]+2); Append(atval, str{[pos2[1]..pos2[2]]}); start := pos2[2]+2; pos2 := ent.next; if ent.name = "CharEntityValue" then Append(atval, ent.content); else # now ent.content may still contain some character entities, but # no '<' and so no markup if '<' in ent.content then ParseError(str, start, "entity replacement in attribute value cannot contain '<'"); fi; ent := GetElement(Concatenation(ent.content,""),1); if IsString(ent.content) then Append(atval, ent.content); else for a in ent.content do Append(atval, a.content); od; fi; fi; elif str[pos2[2]+1] in "\"'" then Append(atval, str{[pos2[1]..pos2[2]+1]}); pos2 := pos2[2]+2; else ParseError(str, pos2[2]+1, "non valid character in attribute value"); fi; else Append(atval, str{[pos2[1]..pos2[2]]}); pos2 := pos2[2]+1; fi; od; res.attributes.(attr) := atval; pos2 := pos2+1; pos := GetChars(str, pos2, WHITESPACE); if pos=fail then ParseError(str, pos2, "document ends in tag"); fi; od; if str[pos] = '/' then res.content := EMPTYCONTENT; pos := pos+1; else res.content := []; fi; if not str[pos] = '>' then ParseError(str, pos, "expecting end of tag \'>\' here"); fi; res.next := pos+1; return res; end); ## reading an end tag, ## returns rec( name := elementname, ## next := first position after this end tag) # assuming str{[pos-2,pos-1]} = " '>' then ParseError(str, pos2, "expecting end of tag \'>\' here"); fi; res.next := pos2+1; return res; end); ## reading an element: start tag, content (with recursive calls of ## GetElement) and end tag # returns record explained before GetSTag, but with .content component # filled # assuming str[pos-1] = '<' and str[pos] in NAMECHARS # (in this function we read entity definitions inside a "); r := GetElement(s, 1); Append(res.content, r.content); fi; elif str[pos] = '<' then if str[pos+1] = '?' then # processing instruction (PI), we repeat it literally pos2 := PositionSublist(str, "?>", pos+2); if pos2=fail then ParseError(str, pos+2, "document ends within processing instruction"); fi; tmp := str{[pos+2..pos2-1]}; Add(res.content, rec(name := "XMLPI", content := tmp)); # check for encoding information if Length(tmp) > 3 and tmp{[1..4]} = "xml " then tmp := Concatenation(tmp, "/>"); tmp := GetElement(tmp, 3); if IsBound(tmp.attributes.encoding) then tmp := tmp.attributes.encoding; if not IsBound(UNICODE_RECODE.NormalizedEncodings.(tmp)) then Error("Cannot parse document in encoding ", tmp, "\n"); fi; XMLPARSERFLAGS.Encoding := UNICODE_RECODE.NormalizedEncodings.(tmp); # if not in UTF-8 encoding we recode rest of the document now if XMLPARSERFLAGS.Encoding <> "UTF-8" then Info(InfoGAPDoc, 1, "#I recoding input from ", XMLPARSERFLAGS.Encoding, " to UTF-8 . . .\n"); tmp := Encode(Unicode(str{[pos..Length(str)]}, XMLPARSERFLAGS.Encoding), "UTF-8"); str{[pos..pos-1+Length(tmp)]} := tmp; fi; fi; fi; pos := pos2+2; elif str[pos+1] = '!' then if str[pos+2] = '-' and str[pos+3] = '-' then ## comment # here we ignore the restriction that inside comment # no "--" is allowed. pos2 := PositionSublist(str, "-->", pos+4); if pos2=fail then ParseError(str,pos+4, "document ends within comment"); fi; Add(res.content, rec(name := "XMLCOMMENT", content := str{[pos+4..pos2-1]})); pos := pos2+3; elif str[pos+2] = 'D' and str{[pos+3..pos+8]} = "OCTYPE" and str[pos+9] in WHITESPACE then ## " ## we have to read ENTITY declarations pos2 := pos+10; lev := 0; while str[pos2] <> '>' or lev > 0 do if str[pos2] = '<' then lev := lev+1; elif str[pos2] = '>' then lev := lev-1; fi; pos2 := pos2+1; if pos2>Length(str) then ParseError(str,pos+10, "document ends within DOCTYPE tag"); fi; od; dt := rec(name := "XMLDOCTYPE", content := str{[pos+10..pos2-1]}); ## convenience for parsing GAPDoc document, here we add the ## GAPDoc defined entities automatically pos := PositionSublist(dt.content, "gapdoc.dtd"); if pos <> fail and dt.content[pos-1] in "'\"/" then for p in RecFields(ENTITYDICT_GAPDoc) do ENTITYDICT.(p) := ENTITYDICT_GAPDoc.(p); od; fi; Add(res.content, dt); ## parse entity declarations in here (no good error checking) pos := PositionSublist(dt.content, " fail do p := GetWord(dt.content, pos+8); nam := dt.content{[p[1]..p[2]]}; # value enclosed in ".." or '..' p := p[2]+1; while dt.content[p] in WHITESPACE do p := p + 1; od; p := [p+1]; Add(p, Position(dt.content, dt.content[p[1]-1], p[1])-1); val := dt.content{[p[1]..p[2]]}; ENTITYDICT.(nam) := val; pos := PositionSublist(dt.content, "" pos2 := PositionSublist(str, "]]>", pos+9); if pos2=fail then ParseError(str,pos+10, "document ends within CDATA text"); fi; if pos2>pos+9 then Add(res.content, rec(name := "PCDATA", content := str{[pos+9..pos2-1]})); fi; pos := pos2+3; else ParseError(str, pos, "unknown \" el.name then ParseError(str, pos, Concatenation("wrong end tag, expecting \"\" (starts line ", String(LineNumberStringPosition(str, res.start)[1]), ")")); else res.stop := el.next - 1; res.next := el.next; break; fi; elif not str[pos+1] in NAMECHARS then ParseError(str, pos+1, "not allowed character after '<'"); else ## a new element starts, call GetElement recursively el := GetElement(str, pos+1); Add(res.content, el); pos := el.next; fi; else pos2 := GetWord(str, pos, "", "<&"); if pos2 = fail then ParseError(str, pos, "document ends before end of current element"); fi; if pos2[2] >= pos then Add(res.content, rec(name := "PCDATA", content := str{[pos..pos2[2]]})); fi; pos := pos2[2]+1; fi; od; return res; end); ## the user function for parsing an XML document stored in a string, ## adds end tag for pseudo element WHOLEDOCUMENT (see before GetSTag) ## and calls GetElement ## <#GAPDoc Label="ParseTreeXMLString"> ## ## ## ## a record which is root of a tree structure ## ## The first function parses an XML-document stored in string str ## and returns the document in form of a tree.

## ## The optional argument srcinfo must have the same format ## as in . If it is given then ## error messages refer to the original source of the text with the ## problem.

## ## With the optional argument entitydict named entities can be ## given to the parser, for example entities which are defined in the ## .dtd-file (which is not read by this parser). The standard ## XML-entities do not need to be provided, and for &GAPDoc; documents ## the entity definitions from gapdoc.dtd are automatically ## provided. Entities in the document's <!DOCTYPE declaration ## are parsed and also need not to be provided here. The argument ## entitydict must be a record where each component name is an entity ## name (without the surrounding & and ;) to which is assigned its ## substitution string.

## ## The second function is just a shortcut for ParseTreeXMLString( ## StringFile(fname), ... ), see . ##

## ## After these functions return the list of named entities which were known ## during the parsing can be found in the record ENTITYDICT.

## ## A node in the result tree corresponds to an XML element, or to some ## parsed character data. In the first case it looks as follows: ## ##

## rec( name := "Book", ## attributes := rec( Name := "EDIM" ), ## content := [ ... list of nodes for content ...], ## start := 312, ## stop := 15610, ## next := 15611 ) ## ## ## This means that str{[312..15610]} looks like ## <Book Name="EDIM"> ... content ... </Book>.

## ## The leaves of the tree encode parsed character data as in the ## following example: ## ##

## rec( name := "PCDATA", ## content := "text without markup " ) ## ## ## This function checks whether the XML document is well ## formed, see for an explanation. ## If an error in the XML structure is found, a break loop is ## entered and the text around the position where the problem starts ## is shown. With Show(); one can browse the original input ## in the , starting with the ## line where the error occurred. ## ## All entities are resolved when they are either entities defined ## in the &GAPDoc; package (in particular the standard XML entities) ## or if their definition is included in the <!DOCTYPE ..> ## tag of the document.

## ## Note that does not parse ## and interpret the corresponding document type definition (the ## .dtd-file given in the <!DOCTYPE ..> tag). Hence ## it also does not check the validity of the document ## (i.e., it is no validating XML parser).

## ## If you are using this function to parse a &GAPDoc; document ## you can use for some ## validation and additional checking of the document structure. ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(ParseTreeXMLString, function(arg) local str, ents, res, a; # artificial end tag to wrap document in one element str := Concatenation(arg[1], ""); # default encoding is UTF-8, may be changed if we find a 1 and IsList(arg[2]) then XMLPARSEORIGINS := arg[2]; else XMLPARSEORIGINS := false; fi; # reset ENTITYDICT for a in RecFields(ENTITYDICT) do Unbind(ENTITYDICT.(a)); od; for a in RecFields(ENTITYDICT_default) do ENTITYDICT.(a) := ENTITYDICT_default.(a); od; # maybe load more entities from last argument if Length(arg) > 1 and IsRecord(arg[Length(arg)]) then ents := arg[Length(arg)]; for a in RecFields(ents) do ENTITYDICT.(a) := ents.(a); od; fi; res := GetElement(str, 1); res.input := ShallowCopy(arg[1]); if XMLPARSEORIGINS <> false then res.inputorigins := XMLPARSEORIGINS; fi; return res; end); InstallGlobalFunction(ParseTreeXMLFile, function(arg) arg := ShallowCopy(arg); arg[1] := StringFile(arg[1]); return CallFuncList(ParseTreeXMLString, arg); end); ## Print document tree structure (without the PCDATA entries) ## <#GAPDoc Label="DisplayXMLStructure"> ## ## ## ## This utility displays the tree structure of an XML document as it ## is returned by (without the ## PCDATA leaves).

## ## Since this is usually quite long the result is shown using the ## . ## ## ## <#/GAPDoc> ## InstallGlobalFunction(DisplayXMLStructure, function(doc) local NL, prs, app, str; str := ""; NL := "\n"; app := function(arg) local i; for i in [2..Length(arg)] do Append(arg[1], arg[i]); od; end; prs := function(doc, indent) local a, c, indentnext; if doc.name = "PCDATA" then return; fi; if IsBound(doc.count) then c := String(doc.count); else c := ""; fi; app(str, indent, c, " ", doc.name, NL); if IsBound(doc.attributes) then for a in NamesOfComponents(doc.attributes) do app(str, indent," #",a,":",doc.attributes.(a), NL); od; fi; if doc.content = EMPTYCONTENT then app(str, indent, " # empty element\n"); elif IsString(doc.content) then ## ??? too much output ## Print(indent, " # data\n"); else for a in doc.content do indentnext := Concatenation(indent, " "); prs(a, indentnext); od; fi; end; prs(doc, ""); Page(str); end); ## apply a function to all nodes of a parse tree ## <#GAPDoc Label="ApplyToNodesParseTree"> ## ## ## ## ## ## The function applies a ## function fun to all nodes of the parse tree tree ## of an XML document returned by .

## ## The function is an application of ## this. It adds to all nodes a component .root to which ## the top node tree tree is assigned. These components can be ## removed afterwards with . ## ## ## <#/GAPDoc> ## InstallGlobalFunction(ApplyToNodesParseTree, function(r, f) local ff; ff := function(rr) local a; if IsList(rr.content) and not IsString(rr.content) then for a in rr.content do f(a); ff(a); od; fi; end; f(r); ff(r); end); ## This is useful for things like indexing where one should have ## access to the root of the document tree during the whole processing InstallGlobalFunction(AddRootParseTree, function(r) ApplyToNodesParseTree(r, function(a) a.root := r; end); end); ## And this throws away the links InstallGlobalFunction(RemoveRootParseTree, function(r) ApplyToNodesParseTree(r, function(a) Unbind(a.root); end); end); ## <#GAPDoc Label="StringXMLElement"> ## ## ## a list [string, positions] ## ## ## The argument tree must have a format of a node in the parse tree ## of an XML document as returned by ## (including the root node representing the full document). This function ## computes a pair [string, positions] where string contains ## XML code which is equivalent to the code which was parsed to get ## tree. And positions is a list of lists of four numbers ## [eltb, elte, contb, conte]. There is one such list for each XML ## element occuring in string, where eltb and elte are ## the begin and end position of this element in string and where ## contb and conte are begin and end position of the content ## of this element, or both are 0 if there is no content.

## ## Note that parsing XML code is an irreversible task, we can only expect ## to get equivalent XML code from this function. But parsing the resulting ## string again and applying again ## gives the same result. See the function ## for back-substitutions of entities in the result. ## ## ## <#/GAPDoc> # args: r[, count, pos, str] count, pos, str is for use within recursion StringXMLElement := function(arg) local r, str, pos, p, tmp, att, a; if Length(arg) = 1 then r := arg[1]; str := StringXMLElement(r, [], ""); # revert the WHOLEDOCUMENT trick of the parser if IsRecord(r) and r.name = "WHOLEDOCUMENT" then str[1] := str[1]{[16..Length(str[1])-16]}; str[2] := str[2] - 15; str[2][Length(str[2])] := [1, Length(str[1]), 1, Length(str[1])]; for a in str[2] do if a[3] = -15 then a[3] := 0; a[4] := 0; fi; od; fi; return str; fi; # now we are in the recursion r := arg[1]; pos := arg[2]; str := arg[3]; if IsRecord(r) then if r.name = "PCDATA" then return StringXMLElement(r.content, pos, str); elif r.name = "XMLPI" then p := Length(str)+1; Append(str, Concatenation("")); Add(pos, [p, Length(str), 0, 0]); return [str, pos]; elif r.name = "XMLDOCTYPE" then p := Length(str)+1; Append(str, Concatenation("")); Add(pos, [p, Length(str), 0, 0]); return [str, pos]; elif r.name = "XMLCOMMENT" then p := Length(str)+1; Append(str, Concatenation("")); Add(pos, [p, Length(str), 0, 0]); return [str, pos]; fi; fi; if IsString(r) then r := SubstitutionSublist(r, "&", "&"); r := SubstitutionSublist(r, "<", "<"); if Length(r) > 0 then Append(str, r); fi; return [str, pos]; fi; p := [Length(str)+1]; Append(str, "<"); Append(str, r.name); for att in RecFields(r.attributes) do Add(str, ' '); Append(str, att); Append(str, "=\""); tmp := SubstitutionSublist(r.attributes.(att), "\"", """); tmp := SubstitutionSublist(tmp, "&", "&"); tmp := SubstitutionSublist(tmp, "<", "<"); if Length(tmp)>0 then fi; Append(str, tmp); Append(str, "\""); od; if r.content = 0 then Append(str, "/>"); Add(pos, [p[1], Length(str), 0, 0]); return [str, pos]; fi; Add(str, '>'); p[3] := Length(str)+1; if IsString(r.content) then StringXMLElement(r.content, pos, str); else for a in r.content do StringXMLElement(a, pos, str); od; fi; p[4] := Length(str); Append(str, "'); p[2] := Length(str); Add(pos, p); return [str, pos]; end; ## <#GAPDoc Label="EntitySubstitution"> ## ## ## a string ## ## The argument xmlstring must be a string containing XML ## code or a pair [string, positions] as returned by . The argument entities specifies entity ## names (without the surrounding & and ;) and their ## substitution strings, either a list of pairs of strings or as a record ## with the names as components and the substitutions as values.

## ## This function tries to substitute non-intersecting parts of ## string by the given entities. If the positions information ## is given then only parts of the document which allow a valid ## substitution by an entity are considered. Otherwise a simple text ## substitution without further check is done.

## ## Note that in general the entity resolution in XML documents is a ## complicated and non-reversible task. But nevertheless this utility may ## be useful in not too complicated situations. ## ## ## <#/GAPDoc> EntitySubstitution := function(xmlstr, entities) local posinfo, entities2, check, subs, pos, npos, new, res, off, a; if not IsString(xmlstr) then posinfo := xmlstr[2]; xmlstr := xmlstr[1]; else posinfo := fail; fi; if IsRecord(entities) then entities := List(RecFields(entities), f-> [f, entities.(f)]); fi; # parse and rewrite entities entities2 := List(entities, a-> [a[1], StringXMLElement( ParseTreeXMLString(a[2]))[1]]); # checks if beginning and end of a substring are in the content of the # same element (if this information is available) check := function(b, e) local pb, a; if posinfo = fail then return true; fi; pb := [-1]; for a in posinfo do if a[1] <= b and a[1] > pb[1] and a[2] >= e then pb := a; fi; od; if b = pb[1] and e = pb[2] then return true; fi; for a in posinfo do if a <> pb and a[1] > pb[1] and a[2] < pb[2] then if not Intersection([b..e],[a[1]..a[2]]) in [[], [a[1]..a[2]]] then return false; fi; fi; od; return true; end; subs := []; for a in entities2 do if not a[1] in ["lt", "gt", "amp", "apos", "quot"] then pos := 0; while pos <> fail do npos := PositionSublist(xmlstr, a[2], pos); if npos <> fail and check(npos, npos-1+Length(a[2])) then new := [npos, npos-1+Length(a[2]), a]; if ForAll(subs, b-> b[1] > new[2] or b[2] < new[1]) then Add(subs, new); fi; pos := new[2]; else pos := npos; fi; od; fi; od; Sort(subs); if Length(subs) > 0 then res := xmlstr{[1..subs[1][1]-1]}; off := 0; res := ""; for a in subs do Append(res, xmlstr{[off+1..a[1]-1]}); Append(res, Concatenation("&", a[3][1], ";")); off := a[2]; od; Append(res, xmlstr{[off+1..Length(xmlstr)]}); xmlstr := res; fi; return xmlstr; end; ## <#GAPDoc Label="GetTextXMLTree"> ## ## ## a string ## ## The argument tree must be a node of a parse tree of some ## XML document, see . ## This function collects the content of this and all included elements ## recursively into a string. ## ## ## <#/GAPDoc> # extract and collect text in elements recursively InstallGlobalFunction(GetTextXMLTree, function(r) local res, fun; res := ""; fun := function(r) if IsString(r.content) then Append(res, r.content); fi; end; ApplyToNodesParseTree(r, fun); return res; end); ## <#GAPDoc Label="XMLElements"> ## ## ## a list of nodes ## ## The argument tree must be a node of a parse tree of some ## XML document, see . ## This function returns a list of all subnodes of tree (possibly ## including tree) of elements with name given in the list of strings ## eltnames. Use "PCDATA" as name for leave nodes which contain ## the actual text of the document. As an abbreviation eltnames can also ## be a string which is then put in a one element list. ## ## ## <#/GAPDoc> # return list of nodes of elements with name in 'eltnames' from XML tree r InstallGlobalFunction(XMLElements, function(r, eltnames) local res, fun; if IsString(eltnames) then eltnames := [eltnames]; fi; res := []; fun := function(r) if r.name in eltnames then Add(res, r); fi; end; ApplyToNodesParseTree(r, fun); return res; end); GAPDoc-1.5.1/lib/BibXMLextTools.gd0000644000175000017500000000235612026346064015113 0ustar billbill############################################################################# ## #W BibXMLextTools.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2006, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files BibXMLextTools.g{d,i} contain utility functions for dealing ## with bibliography data in the BibXMLext format. The corresponding DTD ## is in ../bibxmlext.dtd. ## # these are utilities to help to translate BibTeX entries to BibXMLext entries DeclareGlobalFunction("TemplateBibXML"); DeclareGlobalFunction("StringBibAsXMLext"); DeclareGlobalFunction("WriteBibXMLextFile"); # parsing BibXMLext strings and files DeclareGlobalFunction("ParseBibXMLextString"); DeclareGlobalFunction("ParseBibXMLextFiles"); # tranforming parse trees to records and strings BindGlobal("RECBIBXMLHNDLR", rec()); DeclareGlobalFunction("BuildRecBibXMLEntry"); DeclareGlobalFunction("ContentBuildRecBibXMLEntry"); DeclareGlobalFunction("AddHandlerBuildRecBibXMLEntry"); DeclareGlobalFunction("RecBibXMLEntry"); BindGlobal("STRINGBIBXMLHDLR", rec()); DeclareGlobalFunction("StringBibXMLEntry"); # utilities DeclareGlobalFunction("SortKeyRecBib"); DeclareGlobalVariable("HeuristicTranslationsLaTeX2XML"); GAPDoc-1.5.1/lib/latexhead.tex0000644000175000017500000000514312026346064014436 0ustar billbill% generated by GAPDoc2LaTeX from XML source (Frank Luebeck) \documentclass[a4paper,11pt]{report} CONFIGEarlyExtraPreamble \usepackage{a4wide} \sloppy \pagestyle{myheadings} \usepackage{amssymb} \usepackage[CONFIGInputEncoding]{inputenc} \usepackage{makeidx} \makeindex \usepackage{color} \definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083} \definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179} \definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894} \definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894} \definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000} \definecolor{Black}{rgb}{0.0,0.0,0.0} \definecolor{linkColor}{rgb}{CONFIGCOLORlink} \definecolor{citeColor}{rgb}{CONFIGCOLORcite} \definecolor{fileColor}{rgb}{CONFIGCOLORfile} \definecolor{urlColor}{rgb}{CONFIGCOLORurl} \definecolor{promptColor}{rgb}{CONFIGCOLORprompt} \definecolor{brkpromptColor}{rgb}{CONFIGCOLORbrkprompt} \definecolor{gapinputColor}{rgb}{CONFIGCOLORgapinput} \definecolor{gapoutputColor}{rgb}{CONFIGCOLORgapoutput} %% for a long time these were red and blue by default, %% now black, but keep variables to overwrite \definecolor{FuncColor}{rgb}{CONFIGCOLORfuncdefs} %% strange name because of pdflatex bug: \definecolor{Chapter }{rgb}{CONFIGCOLORchapter} CONFIGMoreColors \usepackage{fancyvrb} CONFIGFontPackages \usepackage[ pdftex=CONFIGHRpdftex, bookmarks=CONFIGHRbookmarks, a4paper=CONFIGHRa4paper, pdftitle=CONFIGHRpdftitle, pdfcreator=CONFIGHRpdfcreator, colorlinks=CONFIGHRcolorlinks, backref=CONFIGHRbackref, breaklinks=CONFIGHRbreaklinks, linkcolor=linkColor, citecolor=citeColor, filecolor=fileColor, urlcolor=urlColor, pdfpagemode=CONFIGHRpdfpagemode, CONFIGHRMoreHyperrefOptions ]{hyperref} \newcommand{\maintitlesize}{CONFIGMaintitlesize} % write page numbers to a .pnr log file for online help \newwrite\pagenrlog \immediate\openout\pagenrlog =\jobname.pnr \immediate\write\pagenrlog{PAGENRS := [} \newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}} %% were never documented, give conflicts with some additional packages \newcommand{\GAP}{\textsf{GAP}} %% nicer description environments, allows long labels \usepackage{enumitem} \setdescription{style=nextline} %% depth of toc CONFIGTocDepth CONFIGLateExtraPreamble PIExtraPreamble %% command for ColorPrompt style examples \newcommand{\gapprompt}[1]{\color{promptColor}{\bfseries #1}} \newcommand{\gapbrkprompt}[1]{\color{brkpromptColor}{\bfseries #1}} \newcommand{\gapinput}[1]{\color{gapinputColor}{#1}} \begin{document} GAPDoc-1.5.1/lib/ComposeXML.gi0000644000175000017500000002260612026346064014267 0ustar billbill############################################################################# ## #W ComposeXML.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files ComposeXML.gi/.gd contain a function which allows to construct ## a GAPDoc-XML document from several source files. ## These tools can also be used for collection/extracting other types of ## documents. ## ## <#GAPDoc Label="ComposedDocument"> ## ## ## ## a document as string, or a list with this string and ## information about the source positions ## ## ## The argument tagname is the string used for the pseudo elements ## which mark the pieces of a document to collect. (In ## we used GAPDoc as tagname. The second function ## ( ... ) is an abbreviation for ## ("GAPDoc", ... ).

## ## The argument path must be a path to some directory (as ## string or directory object), main the name of a file ## in this directory and source a list of file names, ## all of these relative to path. The document is ## constructed via the mechanism described in Section .

## ## First the files given in source are scanned for ## chunks of the document marked by <#tagname ## Label="..."> and </#tagname> pairs. ## Then the file main is read and all <#Include ... ## >-tags are substituted recursively by other files or chunks ## of documentation found in the first step, respectively. ## ## If the optional argument info is given and set to ## true this function returns a list [str, origin], ## where str is a string containing the composed document and ## origin is a sorted list of entries of the form [pos, ## filename, line]. Here pos runs through all character ## positions of starting lines or text pieces from different files in ## str. The filename and line describe the ## origin of this part of the collected document. ## ## Without the fourth argument only the string str is returned. ## ## ## gap> doc := ComposedDocument("GAPDoc", "/my/dir", "manual.xml", ## > ["../lib/func.gd", "../lib/func.gi"], true);; ## ## ## ## <#/GAPDoc> ## # reset this if not found files or chunks should not run into an error DOCCOMPOSEERROR := true; InstallGlobalFunction(ComposedDocument, function(arg) local path, main, source, info, tagname, btag, etag, pieces, origin, fname, str, posnl, i, j, pre, pos, name, piece, b, len, Collect, res, src, f, a, usedpieces, lenb; # get arguments, 5th arg is optional for compatibility with older versions tagname := arg[1]; btag := Concatenation("<#", tagname, " Label=\""); lenb := Length(btag); etag := Concatenation("<#/", tagname, ">"); path := arg[2]; main := arg[3]; source := arg[4]; if Length(arg) > 4 and arg[5] = true then info := true; else info := false; fi; if IsString(path) then path := Directory(path); fi; # first we fetch the chunks from the source files pieces := rec(); origin := rec(); for f in source do fname := Filename(path, f); Info(InfoGAPDoc, 2, "#I ComposedDocument: Searching for chunks in ", fname, "\n"); str := StringFile(fname); if str = fail then Info(InfoGAPDoc, 1, "#W WARNING: no file ", fname, " to compose document.\n"); continue; fi; posnl := Positions(str, '\n'); i := PositionSublist(str, btag); while i <> fail do j := i-1; while j > 0 and str[j] <> '\n' do j := j-1; od; pre := str{[j+1..i-1]}; pos := Position(str, '\"', i+lenb-1); if pos=fail then Error(f, ": File ends within <#", tagname, " tag.\n"); fi; name := str{[i+lenb..pos-1]}; i := Position(str, '\n', pos); if i=fail then Error(f, ": File ends within <#", tagname, " piece.\n"); fi; pos := PositionSublist(str, etag, i); if pos=fail then Error(f, ": File ends within <#", tagname, " piece.\n"); fi; while str[pos-1] <> '\n' do pos := pos-1; od; piece := SplitString(str{[i+1..pos-1]}, "\n", ""); for a in [1..Length(piece)] do b := 1; len := Minimum(Length(piece[a]), Length(pre)); while b <= len and pre[b] = piece[a][b] do b := b+1; od; if b > 1 then piece[a] := piece[a]{[b..Length(piece[a])]}; fi; od; for a in piece do Add(a, '\n'); od; Info(InfoGAPDoc, 3, "Found piece ", name, "\n"); if IsBound(pieces.(name)) then Info(InfoGAPDoc, 1, "#W WARNING: overwriting piece with label \"", name,"\"\n#W Previous occurrence: ",origin.(name)[1], " line ", origin.(name)[2],"\n", "#W New occurrence: ",fname," line ",PositionSorted(posnl, i+1),"\n"); fi; pieces.(name) := Concatenation(piece); # for each found piece store the filename and number of the first # line of the piece in that file origin.(name) := [fname, PositionSorted(posnl, i+1)]; i := PositionSublist(str, btag, pos); od; od; # we do some bookkeeping which pieces are actually used usedpieces := []; # recursive substitution of files and chunks from above # In this helper [cont, from] is a pair [piece, orig] from above # or a pair [filename, 0]. Collect := function(res, src, cont, from) local posnl, pos, i, len, new, p, j, piece, fname; # if piece is a whole file we simulate info as in 'pieces' if from = 0 then fname := cont; cont := StringFile(fname); if cont = fail and DOCCOMPOSEERROR = true then Error("Cannot include file ", fname, ".\n"); elif cont = fail then cont := Concatenation("MISSING FILE ", fname, "\n"); from := [fname, 1]; else from := [fname, 1]; fi; fi; posnl := Positions(cont, '\n'); pos := 0; while pos <> fail do i := PositionSublist(cont, "<\#Include ", pos); if i = fail then # in this case add the rest to res i := Length(cont) + 1; fi; len := Length(res); new := cont{[pos+1..i-1]}; Append(res, new); p := PositionSorted(posnl, pos+1) + from[2] - 1; # add entry to 'src' for first character from current piece Add(src, [len+1, from[1], p]); j := Position(new, '\n'); while j <> fail and j < Length(new) do # further entries to 'src' for each new line in current piece Add(src, [len+j+1, from[1], p+1]); j := Position(new, '\n', j); p := p+1; od; # now include by recursive call of this function if i <= Length(cont) then pos := Position(cont, '>', i); if pos = fail then Error("Input ends within <\#Include ... tag."); fi; piece := SplitString(cont{[i+9..pos-1]}, "", "\"= "); if piece[1]="SYSTEM" then Collect(res, src, Filename(path, piece[2]), 0); elif piece[1]="Label" then if not IsBound(pieces.(piece[2])) and DOCCOMPOSEERROR=true then Error("Did not find chunk ", piece[2]); elif not IsBound(pieces.(piece[2])) then pieces.(piece[2]) := Concatenation("MISSING CHUNK ", piece[2]); origin.(piece[2]) := [Concatenation("MISSINGCHUNK ",piece[2]),1]; fi; Add(usedpieces, piece[2]); Collect(res, src, pieces.(piece[2]), origin.(piece[2])); fi; else pos := fail; fi; od; end; res := ""; src := []; # now start the recursion as #Include of the main file in empty string Collect(res, src, Filename(path, main), 0); Info(InfoGAPDoc, 2, "#I Labels of chunks which were not used: ", Difference(RecFields(pieces), usedpieces), "\n"); if info then return [res, src]; else # we allow this for compatibility with former versions return res; fi; end); InstallGlobalFunction(ComposedXMLString, function(arg) return CallFuncList(ComposedDocument, Concatenation(["GAPDoc"], arg)); end); ## <#GAPDoc Label="OriginalPositionDocument"> ## ## ## A pair [filename, linenumber]. ## ## Here srcinfo must be a data structure as returned as ## second entry by called with ## info=true. It returns for a given position pos in ## the composed document the file name and line number from which that ## text was collected. ## ## ## <#/GAPDoc> InstallGlobalFunction(OriginalPositionDocument, function(srcinfo, pos) local r; r := PositionSorted(srcinfo, [pos]); if not IsBound(srcinfo[r]) or srcinfo[r][1] > pos then r := r-1; fi; return [srcinfo[r][2], srcinfo[r][3]]; end); GAPDoc-1.5.1/lib/parsedtd.g0000644000175000017500000000423512026346064013734 0ustar billbill # this is a development utility to generate the files like # bibxmlextinfo.g or gapdocdtdinfo.g ## not interesting enough to properly parse DTDs, we later give ## access to a proper validating parser instead dtd := StringFile("bibxmlext.dtd"); NormalizeWhitespace(dtd); # read entities entities := rec(); pos := PositionSublist(dtd, " fail do pos := pos+11; tmp := Position(dtd, ' ', pos); nam := dtd{[pos..tmp-1]}; cont := dtd{[tmp+2..Position(dtd, '"', tmp+1)-1]}; entities.(nam) := cont; pos := PositionSublist(dtd, " PositionSublist(dtd, Concatenation("%",a)) <> fail) do for a in RecFields(entities) do dtd := SubstitutionSublist(dtd, Concatenation("%",a,";"), entities.(a)); od; od; # get elements elements := rec(); pos := PositionSublist(dtd, " fail do pos := pos+2; tmp := Position(dtd, '>', pos); if dtd[tmp-1] = ' ' then tmp := tmp-1; fi; s := dtd{[pos..tmp-1]}; tmp := Position(s, ' ',8); nam := s{[9..tmp-1]}; s := s{[tmp+1..Length(s)]}; s := SubstitutionSublist(s, "?", ", optional"); s := SubstitutionSublist(s, "*", ", repeated"); s := SubstitutionSublist(s, "(", "["); s := SubstitutionSublist(s, ")", "]"); s := SubstitutionSublist(s, "|", ", or,"); s := SubstitutionSublist(s, "#", ""); if s{[1,Length(s)]} <> "[]" then s := Concatenation("[",s,"]"); fi; ss := ""; inword := false; for x in s do if (not inword and x in LETTERS) or (inword and not x in LETTERS) then Add(ss,'"'); inword := not inword; fi; Add(ss, x); od; elements.(nam) := EvalString(ss); pos := PositionSublist(dtd, " fail do pos2 := Position(dtd, '>', pos); a := dtd{[pos+10..pos2-1]}; pos := pos2; tmp := WordsString(a); attributes.(tmp[1]) := tmp{[2..Length(tmp)]}; pos := PositionSublist(dtd, ""], Emph := Concatenation(TextAttr.bold, ""), Ref := TextAttr.6, BibReset := TextAttr.reset, BibAuthor := Concatenation(TextAttr.bold, TextAttr.1), BibTitle := TextAttr.4, BibJournal := ["",""], BibVolume := TextAttr.4, BibLabel := TextAttr.3, Q := ["\"","\""], M := ["",""], Math := ["$","$"], Display := ["",""], Prompt := Concatenation(TextAttr.bold,TextAttr.4), BrkPrompt := Concatenation(TextAttr.bold,TextAttr.1), GAPInput := TextAttr.1, GAPOutput := TextAttr.reset, DefLineMarker := "\342\200\243 ", # must be two visible characters long ListBullet := " \342\200\242", # must be together two visible characters long EnumMarks := [" ","."], FillString := "\342\224\200\342\224\200\342\224\200", format := "", flush := "both", ); GAPDoc2TextProcs.OtherThemes.classic := rec( info := "similar to GAPDoc default until GAP 4.4", reset := TextAttr.reset, Heading := Concatenation(TextAttr.bold, TextAttr.underscore, TextAttr.1), Func := Concatenation(TextAttr.bold, TextAttr.4), Arg := Concatenation(TextAttr.normal, TextAttr.4), Example := Concatenation(TextAttr.normal, TextAttr.5), Package := TextAttr.bold, Returns := TextAttr.bold, URL := TextAttr.4, Mark := Concatenation(TextAttr.bold, TextAttr.3), K := Concatenation(TextAttr.normal, TextAttr.2), C := Concatenation(TextAttr.normal, TextAttr.2), F := Concatenation(TextAttr.bold, ""), B := Concatenation(TextAttr.bold, TextAttr.b6), Emph := Concatenation(TextAttr.normal, TextAttr.6), Ref := TextAttr.bold, BibReset := TextAttr.reset, BibAuthor := Concatenation(TextAttr.bold, TextAttr.1), BibTitle := TextAttr.4, BibJournal := ["",""], BibVolume := TextAttr.4, BibLabel := TextAttr.3, Q := ["\"","\""], M := ["",""], Math := ["$","$"], Display := ["",""], Prompt := Concatenation(TextAttr.bold,TextAttr.4), BrkPrompt := Concatenation(TextAttr.bold,TextAttr.1), GAPInput := TextAttr.1, GAPOutput := TextAttr.reset, DefLineMarker := "> ", # must be two visible characters long ListBullet := "--", # must be together two visible characters long EnumMarks := [" ","."], FillString := "------", format := "", flush := "both", ); GAPDoc2TextProcs.OtherThemes.old := rec( info := "similar to old style manuals in GAP 3 and GAP 4.4", reset := "", Heading := ["",""], Func := ["`","'"], Arg := ["<", ">"], Example := ["",""], Package := ["",""], Returns := ["",""], URL := ["<",">"], Mark := ["",""], K := ["`","'"], C := ["`","'"], F := ["`","'"], B := ["",""], Q := ["\"","\""], Emph := ["*","*"], Ref := ["\"","\""], BibReset := "", BibAuthor := ["",""], BibTitle := ["",""], BibJournal := ["",""], BibVolume := ["",""], BibLabel := ["",""], M := ["$", "$"], Math := ["$", "$"], Display := ["$$","$$"], Prompt := "", BrkPrompt := "", GAPInput := "", GAPOutput := "", DefLineMarker := "> ", # must be two visible characters long ListBullet := " -", # must be together two visible characters long EnumMarks := [" ","."], FillString := "---", format := "", flush := "both" ); GAPDoc2TextProcs.OtherThemes.equalquotes := rec( info := "(together with \"old\") uses '...' instead of `...'", C := "'", F := "'", K := "'", Func := "'" ); GAPDoc2TextProcs.OtherThemes.none := rec(); GAPDoc2TextProcs.f := function() local dt, a; dt := GAPDoc2TextProcs.OtherThemes.default; # most empty, some copied from default for a in RecFields(dt) do GAPDoc2TextProcs.OtherThemes.none.(a) := ""; od; for a in ["Q", "DefLineMarker", "ListBullet", "FillString", "EnumMarks"] do GAPDoc2TextProcs.OtherThemes.none.(a) := dt.(a); od; GAPDoc2TextProcs.OtherThemes.none.info := "plain text without markup"; end; GAPDoc2TextProcs.f(); Unbind(GAPDoc2TextProcs.f); GAPDoc2TextProcs.OtherThemes.ColorPrompt := rec( info := "show examples in ColorPrompt(true) style (default)", Prompt := Concatenation(TextAttr.bold,TextAttr.4), BrkPrompt := Concatenation(TextAttr.bold,TextAttr.1), GAPInput := TextAttr.1, GAPOutput := TextAttr.reset ); GAPDoc2TextProcs.OtherThemes.noColorPrompt := rec( info := "show examples in ColorPrompt(false) style", Prompt := "", BrkPrompt := "", GAPInput := "", GAPOutput := "" ); GAPDoc2TextProcs.OtherThemes.justify := rec( info := "left-right justify paragraphs (default)", flush := "left", ); GAPDoc2TextProcs.OtherThemes.raggedright := rec( info := "do not left-right justify paragraphs", flush := "left", ); InstallValue(GAPDocTextTheme, rec()); # argument doesn't need all component, the missing ones are taken from default InstallGlobalFunction(SetGAPDocTextTheme, function(arg) local r, res, h, af, v, a, nam, f, i; r := rec(); for a in arg do if IsString(a) then if not IsBound(GAPDoc2TextProcs.OtherThemes.(a)) then Print("Only the following named text themes are available \ (choose one or several):\n"); for nam in RecFields(GAPDoc2TextProcs.OtherThemes) do Print(" ",String(Concatenation("\"",nam,"\""), -25), GAPDoc2TextProcs.OtherThemes.(nam).info, "\n"); od; return; else for f in RecFields(GAPDoc2TextProcs.OtherThemes.(a)) do r.(f) := GAPDoc2TextProcs.OtherThemes.(a).(f); od; fi; else for f in RecFields(a) do r.(f) := a.(f); od; fi; od; res := rec(hash := [[], []]); h := res.hash; af := GAPDoc2TextProcs.TextAttrFields; for i in [1..Length(af)] do if IsBound(r.(af[i])) then v := r.(af[i]); else v := GAPDoc2TextProcs.OtherThemes.default.(af[i]); fi; if IsString(v) then Add(h[1], Concatenation(String(i-1), "X")); Add(h[2], v); Add(h[1], Concatenation(String(100+i-1), "X")); if Length(v) > 1 and v{[1,2]} = TextAttr.CSI then Add(h[2], TextAttr.reset); else Add(h[2], v); fi; else Add(h[1], Concatenation(String(i-1), "X")); Add(h[2], v[1]); Add(h[1], Concatenation(String(100+i-1), "X")); Add(h[2], v[2]); fi; res.(af[i]) := [[h[1][2*i-1], h[1][2*i]],[h[2][2*i-1], h[2][2*i]]]; od; SortParallel(h[1], h[2]); for f in RecFields(res) do GAPDocTextTheme.(f) := res.(f); od; end); SetGAPDocTextTheme(rec()); GAPDoc-1.5.1/lib/BibTeX.gd0000644000175000017500000000317112026346064013405 0ustar billbill############################################################################# ## #W BibTeX.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files BibTeX.g{d,i} contain a parser for BibTeX files and some ## functions for printing BibTeX entries in different formats. ## DeclareGlobalFunction("ParseBibStrings"); DeclareGlobalFunction("ParseBibFiles"); DeclareGlobalFunction("NormalizedNameAndKey"); DeclareGlobalFunction("NormalizeNameAndKey"); DeclareGlobalFunction("WriteBibFile"); DeclareGlobalFunction("StringBibAsBib"); DeclareGlobalFunction("PrintBibAsBib"); DeclareGlobalFunction("StringBibAsText"); DeclareGlobalFunction("PrintBibAsText"); DeclareGlobalFunction("StringBibAsHTML"); DeclareGlobalFunction("PrintBibAsHTML"); DeclareGlobalFunction("SearchMR"); DeclareGlobalFunction("SearchMRBib"); ## <#GAPDoc Label="InfoBibTools"> ## ## ## ## The default level of this info class is 1. Functions like , StringBibAs... are then ## printing some information. You can suppress it by setting the ## level of to 0. With level 2 there ## may be some more information for debugging purposes. ## ## ## <#/GAPDoc> ## # Info class with default level 1 BindGlobal("InfoBibTools", NewInfoClass("InfoBibTools")); SetInfoLevel(InfoBibTools, 1); if CompareVersionNumbers(GAPInfo.Version, "4.dev") then SetInfoHandler(InfoBibTools, PlainInfoHandler); fi; GAPDoc-1.5.1/lib/GAPDoc2HTML.gi0000644000175000017500000021276412026346064014113 0ustar billbill############################################################################# ## #W GAPDoc2HTML.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files GAPDoc2HTML.g{d,i} contain a conversion program which ## produces from a GAPDoc XML-document an HTML version for reading the ## document with a Web-browser. ## ## REMARKS: ## ## We add to all nodes of the parse tree an entry .root which points to ## the document root. The toc-, index- and bib-information is collected ## in the root. ## ## The set of elements is partitioned into two subsets - those which ## contain whole paragraphs and those which don't. ## ## The handler of a paragraph containing element (see ## GAPDoc2HTMLProcs.ParEls below) gets a list as argument to which it ## adds entries pairwise: the first of such a pair is the paragraph ## counter (like [3,2,1,5] meaning Chap.3, Sec.2, Subsec.1, Par.5) and ## the second is the formatted text of this paragraph. ## ## Some handlers of paragraph containing elements do the formatting ## themselves (e.g., .List), the others are handled in the main recursion ## function `GAPDoc2HTMLContent'. ## ## We produce a full version of the document in HTML format, including ## title page, abstract and other front matter, table of contents, ## bibliography (via BibTeX-data files) and index. For this we have to ## process a document twice (similar to LaTeX). ## ## Small utility to throw away SGML markup BindGlobal("FilterSGMLMarkup", function(str) local p2, p1, res; p2 := Position(str, '<'); if p2 = fail then return str; fi; p1 := 0; res := ""; while p2 <> fail do Append(res, str{[p1+1..p2-1]}); p1 := Position(str, '>', p2); if p1 = fail then return res; fi; p2 := Position(str, '<', p1); if p2 = fail then Append(res, str{[p1+1..Length(str)]}); return res; fi; od; end); InstallValue(GAPDoc2HTMLProcs, rec()); ## Some text attributes ([begin, end] pairs) GAPDoc2HTMLProcs.TextAttr := rec(); GAPDoc2HTMLProcs.TextAttr.Heading := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Func := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Arg := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Example := ["

", "
"]; GAPDoc2HTMLProcs.TextAttr.Package := ["", ""]; GAPDoc2HTMLProcs.TextAttr.URL := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Mark := ["", ""]; GAPDoc2HTMLProcs.TextAttr.K := ["", ""]; GAPDoc2HTMLProcs.TextAttr.C := ["", ""]; GAPDoc2HTMLProcs.TextAttr.F := ["", ""]; GAPDoc2HTMLProcs.TextAttr.I := ["", ""]; GAPDoc2HTMLProcs.TextAttr.B := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Emph := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Ref := ["", ""]; GAPDoc2HTMLProcs.TextAttr.M := ["", ""]; GAPDoc2HTMLProcs.TextAttr.Math := ["", ""]; GAPDoc2HTMLProcs.TextAttr.GAPprompt := ["", ""]; GAPDoc2HTMLProcs.TextAttr.GAPbrkprompt := ["", ""]; GAPDoc2HTMLProcs.TextAttr.GAPinput := ["", ""]; # like in Text converter, but a heading and an address are not a paragraph here GAPDoc2HTMLProcs.ParEls := [ "Display", "Example", "Log", "Listing", "List", "Enum", "Item", "Table", "TitlePage", "Abstract", "Copyright", "Acknowledgements", "Colophon", "TableOfContents", "Bibliography", "TheIndex", "Subsection", "ManSection", "Description", "Returns", "Section", "Chapter", "Appendix", "Body", "Book", "WHOLEDOCUMENT", "Attr", "Fam", "Filt", "Func", "InfoClass", "Meth", "Oper", "Prop", "Var", "Verb" ]; ## arg: a list of strings ## for now only ?????? SetGapDocHTMLOptions := function(arg) local gdp; gdp := GAPDoc2HTMLProcs; return; end; GAPDoc2HTMLProcs.Head1 := "\ \n\ \n\ \n\ \n\ \n\ \n\ GAP ("; GAPDoc2HTMLProcs.MathJaxURL := "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; GAPDoc2HTMLProcs.Head1MathJax := "\ <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ \n\ <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\ \n\ <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\ <head>\n\ <script type=\"text/javascript\"\n\ src=\"MATHJAXURL\">\n\ </script>\n\ <title>GAP ("; GAPDoc2HTMLProcs.Head1Trans := "\ <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ \n\ <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\ \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n\ \n\ <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n\ <head>\n\ <title>GAP ("; GAPDoc2HTMLProcs.Head1MML := "\ <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ <?xml-stylesheet type=\"text/xsl\" href=\"mathml.xsl\"?>\n\ \n\ <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN\"\n\ \"http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd\" [\n\ <!ENTITY mathml \"http://www.w3.org/1998/Math/MathML\">\n\ ] >\n\ \n\ <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\ <head>\n\ <link rel=\"stylesheet\" type=\"text/css\" href=\"mathml.css\" />\n\ <title>GAP ("; GAPDoc2HTMLProcs.Head2 := "\ \n\ \n\ \n\ \n\ \n\ \n\ \n\n"; GAPDoc2HTMLProcs.Tail := "\n\
\n\

generated by GAPDoc2HTML\

\ \n\n\n"; GAPDoc2HTMLProcs.PutFilesTogether := function(l, r) local files, n, tt, i, chnrs, chlink, prev, next, toplink; chnrs := Set(List([2,4..Length(l)], i-> l[i-1][1])); chnrs := Concatenation(Filtered(chnrs, a-> not a in ["Bib", "Ind"]), Filtered(chnrs, a-> a in ["Bib", "Ind"])); chlink := Concatenation("\n
", GAPDocTexts.d.GotoChapter, ": "); for n in chnrs do Append(chlink, Concatenation("")); if n = 0 then Append(chlink, GAPDocTexts.d.Top); else Append(chlink, String(n)); fi; Append(chlink," "); od; Append(chlink, "
\n"); toplink := Concatenation( " [", GAPDocTexts.d.TopofBook, "]  ", "[", GAPDocTexts.d.Contents, "]  " ); prev := []; next := []; for i in [1..Length(chnrs)] do if i > 1 then Add(prev, Concatenation(" [", GAPDocTexts.d.PreviousChapter, "]  ")); else Add(prev, ""); fi; if i < Length(chnrs) then Add(next, Concatenation(" [", GAPDocTexts.d.NextChapter, "]  ")); else Add(next, ""); fi; od; # putting the paragraphs together (one string (file) for each chapter) files := rec(); for i in [1..Length(chnrs)] do n := chnrs[i]; if r.root.mathmode = "MathML" then files.(n) := rec(text := ShallowCopy(GAPDoc2HTMLProcs.Head1MML), ssnr := []); elif r.root.mathmode = "Tth" then files.(n) := rec(text := ShallowCopy(GAPDoc2HTMLProcs.Head1Trans), ssnr := []); elif r.root.mathmode = "MathJax" then files.(n) := rec(text := SubstitutionSublist( GAPDoc2HTMLProcs.Head1MathJax, "MATHJAXURL", GAPDoc2HTMLProcs.MathJaxURL), ssnr := []); else files.(n) := rec(text := ShallowCopy(GAPDoc2HTMLProcs.Head1), ssnr := []); fi; tt := Concatenation(r.bookname, ") - "); if n=0 then Append(tt, GAPDocTexts.d.Contents); elif IsInt(n) then Append(tt, Concatenation(GAPDocTexts.d.Chapter, " ", String(n), ": ", FilterSGMLMarkup(r.chaptitle.(n)))); elif n="Bib" then Append(tt, GAPDocTexts.d.References); elif n="Ind" then Append(tt, GAPDocTexts.d.Index); else Append(tt, Concatenation(GAPDocTexts.d.Appendix, " ", n, ": ", FilterSGMLMarkup(r.chaptitle.(n)))); fi; Append(files.(n).text, tt); Append(files.(n).text, GAPDoc2HTMLProcs.Head2); # allow for chapter-wise CSS config files.(n).text := SubstitutionSublist(files.(n).text, "", toplink, prev[i], next[i], "\n\n")); if IsBound(r.root.LinkToMathJax) then # cross link to same chapter with MathJax enabled Append(files.(n).text, Concatenation("

[MathJax on]

\n")); elif r.root.mathmode = "MathJax" then # cross link to non-MathJax version Append(files.(n).text, Concatenation("

[MathJax off]

\n")); fi; od; for i in [2,4..Length(l)] do n := files.(l[i-1][1]); if Length(n.ssnr)=0 or l[i-1]{[1..3]} <> n.ssnr[Length(n.ssnr)] then Add(n.ssnr, l[i-1]{[1..3]}); tt := GAPDoc2HTMLProcs.SectionLabel(r, l[i-1], "Subsection")[2]; Append(n.text, Concatenation("

\n")); fi; Append(n.text, l[i]); od; for i in [1..Length(chnrs)] do n := chnrs[i]; Append(files.(n).text, Concatenation( "\n
", toplink, prev[i], next[i], "
\n\n")); Append(files.(n).text, SubstitutionSublist(chlink, "chlinktop", "chlinkbot", false)); Append(files.(n).text, GAPDoc2HTMLProcs.Tail); od; # finally tell result the file extensions files.ext := GAPDoc2HTMLProcs.ext; return files; end; ## ## <#GAPDoc Label="GAPDoc2HTML"> ## ## ## record containing HTML files as strings and other ## information ## ## MathJax ## The argument tree for this function is a tree ## describing a &GAPDoc; XML document as returned by (probably also checked with ). Without an mtrans ## argument this function produces an HTML version of the document ## which can be read with any Web-browser and also be used with ## &GAP;'s online help (see ). It includes title page, bibliography, and index. The ## bibliography is made from &BibTeX; databases. Their location must ## be given with the argument bibpath (as string or directory ## object, if not given the current directory is used). If the third ## argument gaproot is given and is a string then this string ## is interpreted as relative path to &GAP;'s main root directory. ## Reference-URLs to external HTML-books which begin with the &GAP; ## root path are then rewritten to start with the given relative ## path. This makes the HTML-documentation portable provided a ## package is installed in some standard location below the &GAP; ## root.

## ## The output is a record with one component for each chapter ## (with names "0", "1", ..., "Bib", and ## "Ind"). Each such component is again a record with ## the following components: ## ## ## text ## the text of an HTML file containing the whole chapter (as a ## string) ## ssnr ## list of subsection numbers in this chapter (like [3, 2, ## 1] for chapter 3, section 2, subsection 1) ## ## ## ## Standard output format without mtrans ## argument

## ## The HTML code produced with this converter conforms ## to the W3C specification XHTML 1.0 strict, see ## http://www.w3.org/TR/xhtml1. First, this means that ## the HTML files are valid XML files. Secondly, the ## extension strict says in particular that the code ## doesn't contain any explicit font or color information.

## ## Mathematical formulae are handled as in the text converter ## . We don't want to assume that the ## browser can use symbol fonts. Some &GAP; users like to browse ## the online help with lynx, see , which runs inside the same terminal ## windows as &GAP;.

## ## To view the generated files in graphical browsers, stylesheet files ## with layout configuration should be copied into the directory ## with the generated HTML files, see . ##

## ##

## ## Currently, there are three variants of this converter available ## which handle mathematical formulae differently. They are accessed ## via the optional last mtrans argument.

## ## If mtrans is set to "MathJax" the formulae ## are essentially translated as for &LaTeX; documents (there ## is no processing of <M> elements as decribed ## in ). Inline formulae are delimited by ## \( and \) and displayed formulae by \[ ## and \]. With MathJax webpages ## can contain nicely formatted scalable and searchable ## formulae. The resulting files link by default to http://cdn.mathjax.org to get ## the MathJax script and fonts. This means ## that they can only be used on computers with internet ## access. An alternative URL can be set by overwriting ## GAPDoc2HTMLProcs.MathJaxURL before building the HTML ## version of a manual. This way a local installation ## of MathJax could be used. See http://www.mathjax.org/ for ## more details.

## ## The following possibilities for mtrans are still supported, ## but since the MathJax approach seems much better, ## their use is deprecated.

## ## If the argument mtrans is set to "Tth" it is ## assumed that you have installed the &LaTeX; to HTML translation ## program tth. This is used to translate the contents of the ## M, Math and Display elements into HTML ## code. Note that the resulting code is not compliant with any ## standard. Formally it is XHTML 1.0 Transitional, it ## contains explicit font specifications and the characters of ## mathematical symbols are included via their position in a ## Symbol font. Some graphical browsers can be configured ## to display this in a useful manner, check http://hutchinson.belmont.ma.us/tth/ for more ## details.

## ## If the mtrans argument is set to "MathML" ## it is assumed that you have installed the translation ## program ttm, see also http://hutchinson.belmont.ma.us/tth/). This is ## used to translate the contents of the M, ## Math and Display elements to MathML 2.0 ## markup. The resulting files should conform to the "XHTML ## 1.1 plus MathML 2.0" standard, see http://www.w3.org/TR/MathML2/ for more ## details. It is expected that the next generation of graphical ## browsers will be able to render such files (try for example ## Mozilla, at least 0.9.9). You must copy the .xsl ## and .css files from &GAPDoc;s mathml directory to ## the directory containing the output files. The translation with ## ttm is still experimental. The output of this converter ## variant is garbage for browsers which don't support MathML.

## ## This function works by running recursively through the document ## tree and calling a handler function for each &GAPDoc; ## XML element. Many of these handler functions (usually in ## GAPDoc2TextProcs.<ElementName>) are not difficult to ## understand (the greatest complications are some commands for index ## entries, labels or the output of page number information). So it ## should be easy to adjust certain details to your own taste by slight ## modifications of the program.

## ## The result of this converter can be written to files with the ## command .

## ## There are two user preferences for reading the HTML manuals produced by ## &GAPDoc;. A user can choose among several style files which determine the ## appearance of the manual pages with ## SetUserPreference("GAPDoc", "HTMLStyle", [...]); where the list in ## the third argument are arguments for . ## The second preference is set by ## SetUserPreference("GAPDoc", "UseMathJax", ...); where the third ## argument is true or false (default). If this is set to ## true, the &GAP; help system displays the MathJax ## version of the HTML manuals. ## ## ## <#/GAPDoc> ## ## <#GAPDoc Label="HTMLStyleSheets"> ## ## Stylesheet files ## CSS stylesheets ## ## For graphical browsers the layout of the generated HTML manuals can be ## highly configured by cascading stylesheet (CSS) and javascript ## files. Such files are provided in the styles directory of the ## &GAPDoc; package.

## ## We recommend that these files are copied into each manual directory ## (such that each of them is selfcontained). There is a utility ## function which does this. Of ## course, these files may be changed or new styles may be added. New ## styles may also be sent to the &GAPDoc; authors for possible ## inclusion in future versions.

## ## The generated HTML files refer to the file manual.css ## which conforms to the W3C specification CSS 2.0, see ## http://www.w3.org/TR/REC-CSS2, and the javascript file ## manual.js (only in browsers which support CSS or javascript, ## respectively; but the HTML files are also readable without ## any of them). To add a style mystyle one or both of ## mystyle.css and mystyle.js must be provided; these can ## overwrite default settings and add new javascript functions. For ## more details see the comments in manual.js.

## ## ## ## nothing ## ## This utility function copies the *.css and *.js files ## from the styles directory of the &GAPDoc; package into the ## directory ## dir. ## ## ## <#/GAPDoc> ## ## the basic call, used recursively with a result r from GetElement ## and a string str or list l to which the output should be appended # arg: r[, bibpath] (then a list is returned, only for whole document) # or: r, str (then the output is appended to string or list str) InstallGlobalFunction(GAPDoc2HTML, function(arg) local r, str, linelength, name; r := arg[1]; # first check for the mode if arg[Length(arg)] in ["MathML", "Tth", "MathJax"] then r.mathmode := arg[Length(arg)]; arg := arg{[1..Length(arg)-1]}; else r.mathmode := "Text"; fi; if Length(arg) > 1 then str := arg[2]; else str := []; fi; if r.name = "WHOLEDOCUMENT" then # choose different file name conventions such that these # conversions can coexist if r.mathmode = "MathML" then GAPDoc2HTMLProcs.ext := "_mml.xml"; elif r.mathmode = "Tth" then GAPDoc2HTMLProcs.ext := "_sym.html"; elif r.mathmode = "MathJax" then GAPDoc2HTMLProcs.ext := "_mj.html"; else GAPDoc2HTMLProcs.ext := ".html"; fi; if IsDirectory(str) then r.bibpath := str; else if Length(str) = 0 then str := "."; fi; r.bibpath := Directory(str); fi; str := []; if Length(arg) > 2 and IsString(arg[3]) then GAPDoc2HTMLProcs.RelPath := arg[3]; GAPInfo.MainRootPath := Filtered(GAPInfo.RootPaths, a-> Filename([Directory(a)], "lib/init.g")<>fail)[1]; else Unbind(GAPDoc2HTMLProcs.RelPath); fi; fi; name := r.name; if not IsBound(GAPDoc2HTMLProcs.(name)) then Info(InfoGAPDoc, 1, "#W WARNING: Don't know how to process element ", name, " ---- ignored\n"); else GAPDoc2HTMLProcs.(r.name)(r, str); fi; if r.name ="WHOLEDOCUMENT" then # put final record together and return it return GAPDoc2HTMLProcs.PutFilesTogether(str, r); fi; return str; end); ## recursion through the tree and collecting paragraphs BindGlobal("GAPDoc2HTMLContent", function(r, l) local par, cont, i, count, s, a; # utility: append counter and formatted paragraph to l par := function(s) if Length(s)>0 then s := NormalizedWhitespace(s); if Length(s)>0 then Add(l, count); Add(l, Concatenation("

", s, "

\n\n")); fi; fi; end; # if not containing paragraphs, then l is string to append to if not r.name in GAPDoc2HTMLProcs.ParEls then for a in r.content do GAPDoc2HTML(a, l); od; return; fi; # otherwise we have to collect text and paragraphs cont := r.content; # checking for alternatives i := 1; while i < Length(cont) do if cont[i].name = "Alt" and GAPDoc2HTMLProcs.AltYes(cont[i]) then cont := Concatenation(cont{[1..i-1]}, cont[i].content, cont{[i+1..Length(cont)]}); else i := i + 1; fi; od; count := r.count; s := ""; for a in cont do if a.count <> count then par(s); count := a.count; s := ""; fi; if a.name in GAPDoc2HTMLProcs.ParEls then # recursively collect paragraphs GAPDoc2HTML(a, l); else # collect text for current paragraph GAPDoc2HTML(a, s); fi; od; if Length(s)>0 then par(s); fi; end); ## write head and foot of HTML file. GAPDoc2HTMLProcs.WHOLEDOCUMENT := function(r, par) local i, pi, t, el, remdiv, math, pos, pos1, str, dat, datbt, bib, b, keys, need, labels, tmp, j, diff, text, a; ## add paragraph numbers to all nodes of the document AddParagraphNumbersGapDocTree(r); if not IsBound(r.six) then Info(InfoGAPDoc, 1, "#W WARNING: Using labels from section numbers, \n", "#W consider running the converter for the text version first!\n"); fi; ## add a link .root to the root of the document to all nodes ## (then we can collect information about indexing and so on ## there) AddRootParseTree(r); r.index := []; r.toc := ""; r.labels := rec(); r.labeltexts := rec(); if not IsBound(r.bibkeys) then r.bibkeys := []; fi; r.chaptitle := rec(); r.chapsectlinks := rec(); ## checking for processing instructions before the book starts ## example: i := 1; pi := rec(); while not r.content[i].name = "Book" do if r.content[i].name = "XMLPI" then t := r.content[i].content; if Length(t) > 4 and t{[1..5]} = "HTML " then el := GetSTag(Concatenation("<", t, ">"), 2); for a in NamesOfComponents(el.attributes) do pi.(a) := el.attributes.(a); od; fi; fi; i := i+1; od; # setup for external conversion of maths (MathML with ttm, tth, ...) if r.mathmode in ["MathML", "Tth"] then r.ConvInput := ""; r.MathCount := 0; fi; ## Now the actual work starts, we give the processing instructions found ## so far to the Book handler. ## We call the Book handler twice and produce index, bibliography, toc ## in between. Info(InfoGAPDoc, 1, "#I First run, collecting cross references, ", "index, toc, bib and so on . . .\n"); # with this flag we avoid unresolved references warnings in first run GAPDoc2HTMLProcs.FirstRun := true; GAPDoc2HTMLProcs.Book(r.content[i], [], pi); GAPDoc2HTMLProcs.FirstRun := false; # now the toc is ready Info(InfoGAPDoc, 1, "#I Table of contents complete.\n"); r.toctext := r.toc; r.chapsectlinkstext := r.chapsectlinks; # utility to remove
tags remdiv := function(s) local pos, pos1; pos := PositionSublist(s, " fail do pos1 := Position(s, '>', pos); s := Concatenation(s{[1..pos-1]}, s{[pos1+1..Length(s)]}); pos := PositionSublist(s, " fail do pos1 := Position(s, '>', pos); s := Concatenation(s{[1..pos-1]}, s{[pos1+1..Length(s)]}); pos := PositionSublist(s, " tempCONV.html"); elif r.mathmode = "Tth" then Info(InfoGAPDoc, 1, "tth.\n"); Exec("rm -f tempCONV.html; tth -w2 -r -u tempCONV.tex > tempCONV.html"); fi; math := StringFile("tempCONV.html"); # correct the tags math := SubstitutionSublist(math, "< var >", ""); math := SubstitutionSublist(math, "< /var >", ""); math := SubstitutionSublist(math, "<var>", ""); math := SubstitutionSublist(math, "</var>", ""); r.MathList := []; pos := PositionSublist(math, "TeXFormulaeDelim"); while pos <> fail do pos1 := PositionSublist(math, "TeXFormulaeDelim", pos); if pos1 <> fail then Add(r.MathList, remdiv(math{[pos+16..pos1-1]})); else Add(r.MathList, remdiv(math{[pos+16..Length(math)]})); fi; pos := pos1; od; fi; # .index has entries of form [sorttext, subsorttext, numbertext, # entrytext, url[, subtext]] Info(InfoGAPDoc, 1, "#I Producing the index . . .\n"); Sort(r.index); str := ""; for a in r.index do Append(str, a[4]); if IsBound(a[6]) then Append(str, ", "); Append(str, a[6]); elif Length(a[2])>0 then Append(str, ", "); Append(str, a[2]); fi; Append(str, Concatenation(" ", a[3], "
\n")); od; r.indextext := str; if Length(r.bibkeys) > 0 then GAPDocAddBibData(r); Info(InfoGAPDoc, 1, "#I Writing bibliography . . .\n"); need := List(r.bibentries, a-> RecBibXMLEntry(a, "HTML", r.bibstrings)); # copy the unique labels for a in [1..Length(need)] do need[a].printedkey := r.biblabels[a]; od; text := ""; for a in need do # an anchor for links from the citations Append(text, Concatenation("\n

\n")); Append(text, StringBibAsHTML(a, false)); od; r.bibtext := text; fi; # second run r.index := []; Info(InfoGAPDoc, 1, "#I Second run through document . . .\n"); GAPDoc2HTMLProcs.Book(r.content[i], par, pi); for a in ["MathList", "MathCount", "index", "toc"] do Unbind(r.(a)); od; ## remove the links to the root ??? ## RemoveRootParseTree(r); end; ## comments and processing instructions are in general ignored GAPDoc2HTMLProcs.XMLPI := function(r, str) return; end; GAPDoc2HTMLProcs.XMLCOMMENT := function(r, str) return; end; # two utilities for attribute values like labels or text with special # XML (or LaTeX) characters which gets printed GAPDoc2HTMLProcs.EscapeAttrVal := function(str) str := SubstitutionSublist(str, "&", "&"); str := SubstitutionSublist(str, "<", "<"); str := SubstitutionSublist(str, ">", ">"); return str; end; # do nothing with Ignore GAPDoc2HTMLProcs.Ignore := function(arg) end; # just process content GAPDoc2HTMLProcs.Book := function(r, par, pi) # copy the name of the book to the root r.root.bookname := r.attributes.Name; GAPDoc2HTMLContent(r, par); end; ## Body is sectioning element GAPDoc2HTMLProcs.Body := GAPDoc2HTMLContent; ## the title page, the most complicated looking function GAPDoc2HTMLProcs.TitlePage := function(r, par) local strn, l, s, a, aa, cont, ss; strn := "
\n"; # title l := Filtered(r.content, a-> a.name = "Title"); s := ""; GAPDoc2HTMLContent(l[1], s); s := Concatenation("\n

", NormalizedWhitespace(s), "

\n\n"); Append(strn, s); # subtitle l := Filtered(r.content, a-> a.name = "Subtitle"); if Length(l)>0 then s := ""; GAPDoc2HTMLContent(l[1], s); s := Concatenation("\n

", NormalizedWhitespace(s), "

\n\n"); Append(strn, s); fi; # version l := Filtered(r.content, a-> a.name = "Version"); if Length(l)>0 then s := "

"; GAPDoc2HTMLContent(l[1], s); while Length(s)>0 and s[Length(s)] in WHITESPACE do Unbind(s[Length(s)]); od; Append(s, "

\n\n"); Append(strn, s); fi; # date l := Filtered(r.content, a-> a.name = "Date"); if Length(l)>0 then s := "

"; GAPDoc2HTMLContent(l[1], s); Append(strn, s); Append(strn, "

\n\n"); fi; Append(strn, "
\n"); # an extra comment l := Filtered(r.content, a-> a.name = "TitleComment"); if Length(l) > 0 then s := "

"; GAPDoc2HTMLContent(l[1], s); Append(s, "

\n"); Append(strn, s); fi; # author name(s) l := Filtered(r.content, a-> a.name = "Author"); for a in l do s := "

"; aa := ShallowCopy(a); aa.content := Filtered(a.content, b-> not b.name in ["Email", "Homepage", "Address"]); GAPDoc2HTMLContent(aa, s); Append(strn, s); Append(strn, "\n"); cont := List(a.content, b-> b.name); if "Email" in cont then s := ""; GAPDoc2HTML(a.content[Position(cont, "Email")], s); s := NormalizedWhitespace(s); Append(strn, Concatenation("
", GAPDocTexts.d.Email, ": ", s, "\n")); fi; if "Homepage" in cont then s := ""; GAPDoc2HTML(a.content[Position(cont, "Homepage")], s); s := NormalizedWhitespace(s); Append(strn, Concatenation("
", GAPDocTexts.d.Homepage, ": ", s, "\n")); fi; if "Address" in cont then s := ""; GAPDoc2HTMLContent(a.content[Position(cont, "Address")], s); s := NormalizedWhitespace(s); Append(strn, Concatenation("
", GAPDocTexts.d.Address, ":
", s, "\n")); fi; Append(strn, "

"); od; Append(strn, "\n\n"); Add(par, r.count); Add(par, strn); # an Address element in title page l := Filtered(r.content, a-> a.name = "Address"); if Length(l) > 0 then s := ""; GAPDoc2HTMLContent(l[1], s); s := NormalizedWhitespace(s); Append(strn, Concatenation("

", GAPDocTexts.d.Address, ":
\n", s, "

\n")); fi; # abstract, copyright page, acknowledgements, colophon for ss in ["Abstract", "Copyright", "Acknowledgements", "Colophon" ] do l := Filtered(r.content, a-> a.name = ss); if Length(l)>0 then Add(par, l[1].count); Add(par, Concatenation("

", GAPDocTexts.d.(ss), "

\n")); GAPDoc2HTMLContent(l[1], par); fi; od; end; ## these produce text for an URL ## arg: r, str[, pre] GAPDoc2HTMLProcs.Link := GAPDoc2HTMLContent; GAPDoc2HTMLProcs.LinkText := GAPDoc2HTMLContent; GAPDoc2HTMLProcs.URL := function(arg) local r, str, pre, rr, txt, s; r := arg[1]; str := arg[2]; if Length(arg)>2 then pre := arg[3]; else pre := ""; fi; rr := First(r.content, a-> a.name = "LinkText"); if rr <> fail then txt := ""; GAPDoc2HTML(rr, txt); rr := First(r.content, a-> a.name = "Link"); if rr = fail then Info(InfoGAPDoc, 1, "#W missing element for text ", txt, "\n"); s := "MISSINGLINK"; else s := ""; GAPDoc2HTMLContent(rr, s); fi; else s := ""; GAPDoc2HTMLContent(r, s); if IsBound(r.attributes.Text) then txt := r.attributes.Text; else txt := s; fi; fi; Append(str, Concatenation(GAPDoc2HTMLProcs.TextAttr.URL[1], "", txt, "")); Append(str, GAPDoc2HTMLProcs.TextAttr.URL[2]); end; GAPDoc2HTMLProcs.Homepage := GAPDoc2HTMLProcs.URL; GAPDoc2HTMLProcs.Email := function(r, str) # we add the `mailto:' phrase GAPDoc2HTMLProcs.URL(r, str, "mailto:"); end; ## utility: generate a chapter or (sub)section-number string GAPDoc2HTMLProcs.SectionNumber := function(count, sect) local res; res := ""; if IsString(count[1]) or count[1]>0 then Append(res, String(count[1])); fi; if sect="Chapter" or sect="Appendix" then return res; fi; Add(res, '.'); if count[2]>0 then Append(res, String(count[2])); fi; if sect="Section" then return res; fi; if count[3]>0 then Append(res, Concatenation("-", String(count[3]))); fi; return res; end; ## utility: generate a chapter or (sub)section-number string GAPDoc2HTMLProcs.SectionLabel := function(r, count, sect) local res, a; if IsString(count[1]) or count[1]>0 then res := Concatenation("chap", String(count[1]), GAPDoc2HTMLProcs.ext); else res := Concatenation("chap0", GAPDoc2HTMLProcs.ext); fi; res := [res, ""]; if not IsBound(r.root.six) then if sect="Chapter" then return res; fi; Append(res[2], Concatenation("s", String(count[2]))); Append(res[2], Concatenation("ss", String(count[3]))); return res; else ## a := First(r.root.six, a-> a[3] = count{[1..3]}); a := PositionSet(r.root.sixcount, count{[1..3]}); if a <> fail then a := r.root.six[r.root.sixindex[a]]; fi; if a = fail or not IsBound(a[7]) then return GAPDoc2HTMLProcs.SectionLabel(rec(root:=rec()), count, sect); else Append(res[2], a[7]); return res; fi; fi; end; ## the sectioning commands are just translated and labels are ## generated, if given as attribute GAPDoc2HTMLProcs.ChapSect := function(r, par, sect) local num, posh, s, ind, strn, lab, types, nrs, hord, a, pos, l, i; types := ["Chapter", "Appendix", "Section", "Subsection"]; nrs := ["3", "3", "4", "5"]; hord := nrs[Position(types, sect)]; Add(par, r.count); # if available, start with links to sections in chapter/appendix if sect in ["Chapter", "Appendix"] then if IsBound(r.root.chapsectlinkstext) and IsBound(r.root.chapsectlinkstext.(r.count[1])) then Add(par, r.root.chapsectlinkstext.(r.count[1])); fi; fi; if par[Length(par)] = r.count then Add(par, ""); fi; # section number as string num := GAPDoc2HTMLProcs.SectionNumber(r.count, sect); # and as anchor lab := GAPDoc2HTMLProcs.SectionLabel(r, r.count, "Subsection"); lab := Concatenation(lab[1], "#", lab[2]); # the heading posh := Position(List(r.content, a-> a.name), "Heading"); if posh <> fail then s := ""; # first the .six entry GAPDoc2HTMLProcs.Heading1(r.content[posh], s); if hord = "3" then r.root.chaptitle.(r.count[1]) := s; fi; # label entry, if present if IsBound(r.attributes.Label) then r.root.labels.(r.attributes.Label) := [num, lab]; r.root.labeltexts.(r.attributes.Label) := s; fi; # the heading text Append(par[Length(par)], Concatenation("\n", num, " ", s, "\n\n")); # table of contents entry s := Concatenation( num, " ", s); if sect in ["Chapter", "Appendix"] then if r.count[1] >= 1 then ind := "
"; fi; elif sect="Section" then ind := ""; if r.count[2] >= 1 then Append(ind, "
"); fi; Append(ind, " "); elif sect="Subsection" then ind := "
  "; else ind := ""; fi; Append(r.root.toc, Concatenation(ind, "", s, "\n")); if sect="Section" then Append(r.root.toc, "
\n
\n"); fi; fi; # the actual content GAPDoc2HTMLContent(r, par); # possibly close
or in content if posh <> fail then if sect in ["Chapter", "Appendix" ] then Append(r.root.toc, "
\n"); elif sect="Section" then # remove last line if no subsections l := Length(r.root.toc); if r.root.toc{[l-25..l]} = "
\n" then for i in [0..25] do Unbind(r.root.toc[l-i]); od; Append(r.root.toc, "
\n"); else Append(r.root.toc, "
\n"); fi; elif sect="Subsection" then Append(r.root.toc, "\n"); fi; fi; # if in chapter, also use the section links in top of page if sect in ["Chapter", "Appendix"] then a := Reversed(r.root.toc); pos := PositionSublist(a, Reversed("
")); a := Reversed(a{[1..pos-1]}); r.root.chapsectlinks.(r.count[1]) := Concatenation( "
", a); fi; end; ## this really produces the content of the heading GAPDoc2HTMLProcs.Heading1 := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "Heading"); end; ## and this ignores the heading (for simpler recursion) GAPDoc2HTMLProcs.Heading := function(r, str) end; GAPDoc2HTMLProcs.Chapter := function(r, par) GAPDoc2HTMLProcs.ChapSect(r, par, "Chapter"); end; GAPDoc2HTMLProcs.Appendix := function(r, par) GAPDoc2HTMLProcs.ChapSect(r, par, "Appendix"); end; GAPDoc2HTMLProcs.Section := function(r, par) GAPDoc2HTMLProcs.ChapSect(r, par, "Section"); end; GAPDoc2HTMLProcs.Subsection := function(r, par) GAPDoc2HTMLProcs.ChapSect(r, par, "Subsection"); end; ## table of contents, just puts "TOC" in first run GAPDoc2HTMLProcs.TableOfContents := function(r, par) Add(par, r.count); if IsBound(r.root.toctext) then Add(par, Concatenation("\n
\n

", GAPDocTexts.d.Contents, "

\n\n", r.root.toctext, "
\n
\n")); else Add(par,"

TOC\n-----------

\n\n"); fi; end; ## bibliography, just "BIB" in first run, store databases in root GAPDoc2HTMLProcs.Bibliography := function(r, par) local s; # add references to TOC Append(r.root.toc, Concatenation("\n")); r.root.bibdata := r.attributes.Databases; Add(par, r.count); if IsBound(r.root.bibtext) then Add(par, Concatenation("\n

", GAPDocTexts.d.References, "

\n\n", r.root.bibtext, "

\n\n")); else Add(par,"

BIB\n-----------

\n"); fi; end; GAPDoc2HTMLProcs.PCDATAFILTER := function(r, str) local s, a; s := r.content; if not IsBound(r.HTML) and (Position(s, '<') <> fail or Position(s, '&') <> fail or Position(s, '>') <> fail) then for a in s do if a='<' then Append(str, "<"); elif a='&' then Append(str, "&"); elif a='>' then Append(str, ">"); else Add(str, a); fi; od; else Append(str, s); fi; end; # and without filter (e.g., for collecting formulae GAPDoc2HTMLProcs.PCDATANOFILTER := function(r, str) Append(str, r.content); end; GAPDoc2HTMLProcs.PCDATAFILTER; ## default is with filter GAPDoc2HTMLProcs.PCDATA := GAPDoc2HTMLProcs.PCDATAFILTER; ## end of paragraph (end with double newline) GAPDoc2HTMLProcs.P := function(r, str) # nothing to do, the "

" are added in main loop (GAPDoc2HTML) end; GAPDoc2HTMLProcs.Br := function(r, str) Append(str, "
\n"); end; ## wrapping text attributes GAPDoc2HTMLProcs.WrapAttr := function(r, str, a) local s, tt; s := ""; GAPDoc2HTMLContent(r, s); tt := GAPDoc2HTMLProcs.TextAttr.(a); Append(str, Concatenation(tt[1], s, tt[2])); end; ## GAP keywords GAPDoc2HTMLProcs.K := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "K"); end; ## buttons GAPDoc2HTMLProcs.B := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "B"); end; ## verbatim GAP code GAPDoc2HTMLProcs.C := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "C"); end; ## file names GAPDoc2HTMLProcs.F := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "F"); end; ## argument names (same as Arg) GAPDoc2HTMLProcs.A := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "Arg"); end; GAPDoc2HTMLProcs.MathConvHelper := function(r, str, db, de) local s, x; if IsBound(r.root.MathList) then # conversion already available r.root.MathCount := r.root.MathCount + 1; Append(str, r.root.MathList[r.root.MathCount]); else # add to input for converter if IsString(r.content) then s := r.content; else s := ""; GAPDoc2HTMLProcs.PCDATA := GAPDoc2HTMLProcs.PCDATANOFILTER; for x in r.content do GAPDoc2HTML(x, s); od; GAPDoc2HTMLProcs.PCDATA := GAPDoc2HTMLProcs.PCDATAFILTER; fi; s := Concatenation("TeXFormulaeDelim", db, s, de); Append(r.root.ConvInput, s); Append(str, "FORMULA"); fi; end; ## simple maths, here we try to substitute TeX command to something which ## looks ok in text mode GAPDoc2HTMLProcs.M := function(r, str) local s, ss, save; if r.root.mathmode in ["MathML", "Tth"] then GAPDoc2HTMLProcs.MathConvHelper(r, str, "$", "$"); return; fi; s := ""; GAPDoc2HTMLProcs.PCDATA := GAPDoc2HTMLProcs.PCDATANOFILTER; # a hack, since we want to allow in formulae save := GAPDoc2HTMLProcs.TextAttr.Arg; GAPDoc2HTMLProcs.TextAttr.Arg := ["TEXTaTTRvARBEGIN", "TEXTaTTRvAREND"]; GAPDoc2HTMLContent(r, s); GAPDoc2HTMLProcs.TextAttr.Arg := save; GAPDoc2HTMLProcs.PCDATA := GAPDoc2HTMLProcs.PCDATAFILTER; ss := ""; if r.root.mathmode = "MathJax" then s := Concatenation("\\(",s,"\\)"); GAPDoc2HTMLProcs.PCDATAFILTER(rec(content := s), ss); ss := SubstitutionSublist(ss, "TEXTaTTRvARBEGIN", "\\textit{"); ss := SubstitutionSublist(ss, "TEXTaTTRvAREND", "}"); else s := TextM(s); GAPDoc2HTMLProcs.PCDATAFILTER(rec(content := s), ss); ss := SubstitutionSublist(ss, "TEXTaTTRvARBEGIN", save[1]); ss := SubstitutionSublist(ss, "TEXTaTTRvAREND", save[2]); fi; Append(str, WrapTextAttribute(ss, GAPDoc2HTMLProcs.TextAttr.M)); end; ## in HTML this is shown in TeX format GAPDoc2HTMLProcs.Math := function(r, str) local s; if r.root.mathmode in ["MathML", "Tth"] then GAPDoc2HTMLProcs.MathConvHelper(r, str, "$", "$"); return; fi; if r.root.mathmode = "MathJax" then s := ""; GAPDoc2HTMLProcs.M(r, s); Append(str, s); return; fi; s := ""; GAPDoc2HTMLContent(r, s); Append(str, WrapTextAttribute(s, GAPDoc2HTMLProcs.TextAttr.Math)); end; ## displayed maths (also in TeX format, but centered paragraph in itself) GAPDoc2HTMLProcs.Display := function(r, par) local s, a, str; if r.root.mathmode in ["MathML", "Tth"] then str := ""; GAPDoc2HTMLProcs.MathConvHelper(r, str, "\n\\[", "\\]\n\n"); Add(par, r.count); Add(par, Concatenation("", "
", str, "
\n")); return; fi; s := ""; for a in r.content do GAPDoc2HTML(a, s); od; if r.root.mathmode = "MathJax" then Add(par, r.count); Add(par, Concatenation("

\\[", s, "\\]

\n\n")); return; fi; if IsBound(r.attributes.Mode) and r.attributes.Mode = "M" then s := TextM(s); fi; s := Concatenation("

", s, "

\n\n"); Add(par, r.count); Add(par, s); end; ## emphazised text GAPDoc2HTMLProcs.Emph := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "Emph"); end; ## quoted text GAPDoc2HTMLProcs.Q := function(r, str) Append(str, "\""); GAPDoc2HTMLContent(r, str); Append(str, "\""); end; ## Package names GAPDoc2HTMLProcs.Package := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "Package"); end; ## menu items GAPDoc2HTMLProcs.I := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "I"); end; GAPDoc2HTMLProcs.AddColorPromptMarkup := function(cont) local patt, batt, iatt, res, pos, s, rows; patt := GAPDoc2HTMLProcs.TextAttr.GAPprompt; batt := GAPDoc2HTMLProcs.TextAttr.GAPbrkprompt; iatt := GAPDoc2HTMLProcs.TextAttr.GAPinput; res := ""; rows := SplitString(cont, "\n", ""); for s in rows do if Length(s) > 7 and s{[1..8]} = "gap> " then Append(res, Concatenation(WrapTextAttribute("gap>", patt), " ", WrapTextAttribute(s{[9..Length(s)]}, iatt))); elif Length(s) > 4 and s{[1..5]} = "> " then Append(res, Concatenation(WrapTextAttribute(">", patt), " ", WrapTextAttribute(s{[6..Length(s)]}, iatt))); elif Length(s) > 2 and s{[1..3]} = "brk" then pos := Position(s, ' '); if pos <> fail then Append(res, Concatenation(WrapTextAttribute(s{[1..pos-1]}, batt), " ", WrapTextAttribute(s{[pos+1..Length(s)]}, iatt))); else Append(res, WrapTextAttribute(s, batt)); fi; else Append(res, WrapTextAttribute(s, ["",""])); fi; Add(res, '\n'); od; if Length(cont) > 0 and cont[Length(cont)] <> '\n' then Unbind(res[Length(res)]); fi; return res; end; GAPDoc2HTMLProcs.ExampleLike := function(r, par, label, colorpr) local str, cont, a, s; str := "\n
";
  cont := "";
  for a in r.content do 
    # here we try to avoid reformatting
    if IsString(a.content) then
      GAPDoc2HTMLProcs.PCDATA(a, cont); 
    else
      s := "";
      GAPDoc2HTML(a, s);
      Append(cont, s);
    fi;
  od;
  if colorpr then
    cont := GAPDoc2HTMLProcs.AddColorPromptMarkup(cont);
  fi;
  Append(str, cont);
  Append(str, "
\n\n"); Add(par, r.count); Add(par, str); end; ## log of session and GAP code is typeset the same way as GAPDoc2HTMLProcs.Example := function(r, par) GAPDoc2HTMLProcs.ExampleLike(r, par, "Example", true); end; GAPDoc2HTMLProcs.Log := function(r, par) GAPDoc2HTMLProcs.ExampleLike(r, par, "Log", true); end; GAPDoc2HTMLProcs.Listing := function(r, par) GAPDoc2HTMLProcs.ExampleLike(r, par, "Code", false); end; GAPDoc2HTMLProcs.Verb := function(r, par) local str, cont, a, s; str := "\n
\n";
  cont := "";
  for a in r.content do 
    # here we try to avoid reformatting
    if IsString(a.content) then
      GAPDoc2HTMLProcs.PCDATA(a, cont); 
    else
      s := "";
      GAPDoc2HTML(a, s);
      Append(cont, s);
    fi;
  od;
  Append(str, cont);
  Append(str, "\n
\n\n"); Add(par, r.count); Add(par, str); end; ## explicit labels GAPDoc2HTMLProcs.Label := function(r, str) local num, lab; num := GAPDoc2HTMLProcs.SectionNumber(r.count, "Subsection"); lab := GAPDoc2HTMLProcs.SectionLabel(r, r.count, "Subsection"); r.root.labels.(r.attributes.Name) := [num, Concatenation(lab[1],"#",lab[2])]; end; ## citations GAPDoc2HTMLProcs.Cite := function(r, str) local key, pos; key := r.attributes.Key; pos := Position(r.root.bibkeys, key); if pos = fail then Add(r.root.bibkeys, key); Append(str, Concatenation("[?", key, "?]")); elif not IsBound(r.root.biblabels) then Append(str, Concatenation("[?", key, "?]")); else # here we include a link to the corresponding entry in bibliography Append(str, Concatenation("
[", r.root.biblabels[pos])); if IsBound(r.attributes.Where) then Append(str, ", "); Append(str, r.attributes.Where); fi; Append(str, "]"); fi; end; ## explicit index entries GAPDoc2HTMLProcs.Subkey := GAPDoc2HTMLContent; GAPDoc2HTMLProcs.Index := function(r, str) local s, sub, entry, url, a; s := ""; sub := ""; for a in r.content do if a.name = "Subkey" then GAPDoc2HTML(a, sub); else GAPDoc2HTML(a, s); fi; od; NormalizeWhitespace(s); NormalizeWhitespace(sub); if IsBound(r.attributes.Key) then entry := [STRING_LOWER(r.attributes.Key)]; else entry := [STRING_LOWER(s)]; fi; if IsBound(r.attributes.Subkey) then Add(entry, r.attributes.Subkey); else Add(entry, STRING_LOWER(sub)); fi; Add(entry, GAPDoc2HTMLProcs.SectionNumber(r.count, "Subsection")); Add(entry, s); url := GAPDoc2HTMLProcs.SectionLabel(r, r.count, "Subsection"); Add(entry, Concatenation(url[1],"#",url[2])); if Length(sub) > 0 then Add(entry, sub); fi; Add(r.root.index, entry); end; ## helper to add markup to the args GAPDoc2HTMLProcs.WrapArgs := function(argstr) local res, noletter, c; res := ""; noletter := true; for c in argstr do if noletter then if not c in ", []" then noletter := false; Append(res, GAPDoc2HTMLProcs.TextAttr.Arg[1]); fi; elif c in ", []" then noletter := true; Append(res, GAPDoc2HTMLProcs.TextAttr.Arg[2]); fi; Add(res, c); od; if not noletter then Append(res, GAPDoc2HTMLProcs.TextAttr.Arg[2]); fi; return res; end; ## this produces an implicit index entry and a label entry GAPDoc2HTMLProcs.LikeFunc := function(r, par, typ) local attr, s, name, lab, url; attr := GAPDoc2HTMLProcs.TextAttr.Func; name := GAPDoc2HTMLProcs.EscapeAttrVal(r.attributes.Name); s := Concatenation(attr[1], "‣ ", name, attr[2]); if IsBound(r.attributes.Arg) then Append(s, Concatenation("( ", GAPDoc2HTMLProcs.WrapArgs( GAPDoc2HTMLProcs.EscapeAttrVal( NormalizedArgList(r.attributes.Arg))), " )")); fi; # index entry attr := GAPDoc2HTMLProcs.TextAttr.Func; url := GAPDoc2HTMLProcs.SectionLabel(r, r.count, "Subsection"); url := Concatenation(url[1],"#",url[2]); if IsBound(r.attributes.Label) then lab := r.attributes.Label; else lab := ""; fi; Add(r.root.index, [STRING_LOWER(name), lab, GAPDoc2HTMLProcs.SectionNumber(r.count, "Subsection"), Concatenation(attr[1], name, attr[2]), url]); # label (if not given, the default is the Name) if IsBound(r.attributes.Label) then if IsBound(r.attributes.Name) then lab := Concatenation(r.attributes.Name, " (", r.attributes.Label, ")"); else lab := r.attributes.Label; fi; else lab := r.attributes.Name; fi; GAPDoc2HTMLProcs.Label(rec(count := r.count, attributes := rec(Name := lab), root := r.root), par); # adding hint about the type of the variable s := Concatenation("
", "
", s, "( ", typ, " )
\n"); Add(par, r.count); Add(par, s); end; GAPDoc2HTMLProcs.Func := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Func); end; GAPDoc2HTMLProcs.Oper := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Oper); end; GAPDoc2HTMLProcs.Meth := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Meth); end; GAPDoc2HTMLProcs.Filt := function(r, str) # r.attributes.Type could be "representation", "category", ... if IsBound(r.attributes.Type) then GAPDoc2HTMLProcs.LikeFunc(r, str, LowercaseString(r.attributes.Type)); else GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Filt); fi; end; GAPDoc2HTMLProcs.Prop := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Prop); end; GAPDoc2HTMLProcs.Attr := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Attr); end; GAPDoc2HTMLProcs.Var := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Var); end; GAPDoc2HTMLProcs.Fam := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.Fam); end; GAPDoc2HTMLProcs.InfoClass := function(r, str) GAPDoc2HTMLProcs.LikeFunc(r, str, GAPDocTexts.d.InfoClass); end; ## using the HelpData(.., .., "ref") interface GAPDoc2HTMLProcs.ResolveExternalRef := function(bookname, label, nr) local info, match, res; info := HELP_BOOK_INFO(bookname); if info = fail then return fail; fi; match := Concatenation(HELP_GET_MATCHES(info, SIMPLE_STRING(label), true)); if Length(match) < nr then return fail; fi; res := HELP_BOOK_HANDLER.(info.handler).HelpData(info, match[nr][2], "ref"); res[1] := SubstitutionSublist(res[1], " (not loaded): ", ": ", "one"); return res; end; ## helper for external URLs, remove GAPDocStyle part and maybe add "_mj" GAPDoc2HTMLProcs.AdjustExtURL := function(r, url) local pos, pos2, res, fnam, mjnam; pos := PositionSublist(url, "?GAPDocStyle="); if pos <> fail then pos2 := Position(url, '#', pos); if pos2 = fail then pos2 := Length(url)+1; fi; res := url{[1..pos-1]}; Append(res, url{[pos2..Length(url)]}); else res :=url; fi; if r.root.mathmode = "MathJax" then pos := Position(res, '#'); if pos <> fail then fnam := res{[1..pos-1]}; else pos := Length(res)+1; fnam := res; fi; if Length(fnam) >= 5 and fnam{[Length(fnam)-4..Length(fnam)]} = ".html" then mjnam := Concatenation(fnam{[1..Length(fnam)-5]}, "_mj.html"); if IsExistingFile(mjnam) then res := Concatenation(mjnam, res{[pos..Length(res)]}); fi; fi; fi; return res; end; ## a try to make it somewhat shorter than for the Text and LaTeX conversions GAPDoc2HTMLProcs.Ref := function(r, str) local int, txt, ref, lab, attr, sectlike, rattr; rattr := GAPDoc2HTMLProcs.TextAttr.Ref; int := Difference(NamesOfComponents(r.attributes), ["BookName", "Label", "Style"]); if Length(int)>0 and int[1] <> "Text" then lab := r.attributes.(int[1]); else lab := ""; fi; if IsBound(r.attributes.Label) then if Length(lab) > 0 then lab := Concatenation(lab, " (", r.attributes.Label, ")"); else lab := r.attributes.Label; fi; fi; if IsBound(r.attributes.BookName) then ref := GAPDoc2HTMLProcs.ResolveExternalRef(r.attributes.BookName, lab, 1); if ref <> fail and ref[6] <> fail then ref[6] := GAPDoc2HTMLProcs.AdjustExtURL(r, ref[6]); if IsBound(GAPDoc2HTMLProcs.RelPath) and PositionSublist(ref[6], GAPInfo.MainRootPath) = 1 then ref[6] := Concatenation(GAPDoc2HTMLProcs.RelPath, "/", ref[6]{[Length(GAPInfo.MainRootPath)+1..Length(ref[6])]}); fi; if IsBound(r.attributes.Style) and r.attributes.Style = "Number" then ref := Concatenation("",rattr[1], r.attributes.BookName, " ", ref[2], rattr[2],""); elif IsBound(r.attributes.Text) then ref := Concatenation("", rattr[1], r.attributes.Text, rattr[2], ""); else ref := Concatenation("", rattr[1], ref[1], rattr[2], ""); fi; elif ref <> fail then ref := Concatenation(rattr[1], ref[1], rattr[2]); else if GAPDoc2HTMLProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation(rattr[1], "???", rattr[2]); fi; else if IsBound(r.root.labels.(lab)) then if not IsBound(r.attributes.Text) then ref := Concatenation("", rattr[1], r.root.labels.(lab)[1], rattr[2], ""); else ref := Concatenation("", rattr[1], r.attributes.Text, rattr[2], ""); fi; else if GAPDoc2HTMLProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; ref := Concatenation(rattr[1], "???", rattr[2]); fi; fi; if Length(int)>0 and int[1] in [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ] then attr := GAPDoc2HTMLProcs.TextAttr.Func; txt := Concatenation(attr[1], GAPDoc2HTMLProcs.EscapeAttrVal(r.attributes.(int[1])), attr[2]); # avoid reference to current subsection if IsBound(r.attributes.BookName) or not IsBound(r.root.labels.(lab)) or GAPDoc2HTMLProcs.SectionNumber(r.count, "Subsection") <> r.root.labels.(lab)[1] then Append(txt, Concatenation(" (", ref, ")")); fi; elif Length(int)>0 and int[1] in [ "Sect", "Subsect", "Chap", "Appendix"] and IsBound(r.attributes.Style) and r.attributes.Style = "Text" then if IsBound(r.root.labeltexts.(lab)) then txt := Concatenation("",rattr[1],r.root.labeltexts.(lab),rattr[2],""); else if GAPDoc2HTMLProcs.FirstRun <> true then Info(InfoGAPDoc, 1, "#W WARNING: non resolved reference: ", r.attributes, "\n"); fi; txt := Concatenation(rattr[1], "???", rattr[2]); fi; else txt := ref; fi; Append(str, txt); end; GAPDoc2HTMLProcs.Description := GAPDoc2HTMLContent; GAPDoc2HTMLProcs.Returns := function(r, par) local l; l := []; GAPDoc2HTMLContent(r, l); if Length(l) > 0 then l[2] := Concatenation("

", GAPDocTexts.d.Returns, ": ", l[2]{[4..Length(l[2])]}); fi; Append(par, l); end; GAPDoc2HTMLProcs.ManSection := function(r, par) local strn, funclike, i, num, s, lab, ind; # if there is a Heading then handle as subsection if ForAny(r.content, a-> IsRecord(a) and a.name = "Heading") then GAPDoc2HTMLProcs.ChapSect(r, par, "Subsection"); return; fi; strn := ""; # function like elements funclike := [ "Func", "Oper", "Meth", "Filt", "Prop", "Attr", "Var", "Fam", "InfoClass" ]; # heading comes from name of first function like element i := 1; while not r.content[i].name in funclike do i := i+1; od; num := GAPDoc2HTMLProcs.SectionNumber(r.count, "Subsection"); s := Concatenation(num, " ", GAPDoc2HTMLProcs.EscapeAttrVal(r.content[i].attributes.Name)); Add(par, r.count); Add(par, Concatenation("\n

", s, "
\n\n")); # append to TOC as subsection lab := GAPDoc2HTMLProcs.SectionLabel(r, r.count, "Subsection"); lab := Concatenation(lab[1], "#", lab[2]); ind := "
  "; Append(r.root.toc, Concatenation(ind, "", s, "
\n")); # label entry, if present if IsBound(r.attributes.Label) then r.root.labels.(r.attributes.Label) := [num, lab]; r.root.labeltexts.(r.attributes.Label) := s; fi; GAPDoc2HTMLContent(r, par); end; GAPDoc2HTMLProcs.Mark := function(r, str) GAPDoc2HTMLProcs.WrapAttr(r, str, "Mark"); end; GAPDoc2HTMLProcs.Item := function(r, str) GAPDoc2HTMLContent(r, str); end; # must do the complete formatting GAPDoc2HTMLProcs.List := function(r, par) local s, a, ss, i; s := "\n"; if "Mark" in List(r.content, a-> a.name) then # a
list Append(s, "
\n"); for a in r.content do if a.name = "Mark" then ss := ""; GAPDoc2HTMLProcs.Mark(a, ss); Append(s, Concatenation("
", ss, "
\n")); elif a.name = "Item" then ss := ""; GAPDoc2HTMLProcs.Item(a, ss); ss := Concatenation(Filtered(ss, IsString)); ss := Concatenation("
", ss, "
\n"); Append(s, ss); fi; od; Append(s, "
\n"); else # a
    list Append(s, "
      \n"); for a in r.content do if a.name = "Item" then ss := ""; GAPDoc2HTMLProcs.Item(a, ss); ss := Concatenation(Filtered(ss, IsString)); Append(s, Concatenation("
    • ", ss, "
    • \n")); fi; od; Append(s, "
    \n"); fi; Add(par, r.count); Add(par, s); end; ## and this is an
      list GAPDoc2HTMLProcs.Enum := function(r, par) local s, i, a, ss, num; s := ""; # a
        list Append(s, "
          \n"); for a in r.content do if a.name = "Item" then ss := ""; GAPDoc2HTMLProcs.Item(a, ss); if not IsString(ss) then ss := Concatenation(Filtered(ss, IsString)); fi; Append(s, Concatenation("
        1. ", ss, "
        2. \n")); fi; od; Append(s, "
        \n"); Add(par, r.count); Add(par, s); end; GAPDoc2HTMLProcs.TheIndex := function(r, par) local s; # add index to TOC Append(r.root.toc, Concatenation("\n")); # the text, if available Add(par, r.count); if IsBound(r.root.indextext) then Add(par, Concatenation("\n
        \n

        ", GAPDocTexts.d.Index, "

        \n\n", r.root.indextext, "

        \n
        \n")); else Add(par,"

        INDEX\n-----------

        \n\n"); fi; end; GAPDoc2HTMLProcs.AltYes := function(r) local mark; # recursively mark text as HTML code (no escaping of HTML markup) mark := function(r) local a; if IsString(r.content) then r.HTML := true; elif IsList(r.content) then for a in r.content do mark(a); od; fi; end; if IsBound(r.attributes.Only) then if "HTML" in SplitString(r.attributes.Only, "", "\n\r\t ,") then mark(r); return true; else return false; fi; elif IsBound(r.attributes.Not) then if not "HTML" in SplitString(r.attributes.Not, "", "\n\r\t ,") then return true; else return false; fi; fi; return true; end; GAPDoc2HTMLProcs.Alt := function(r, str) if GAPDoc2HTMLProcs.AltYes(r) then GAPDoc2HTMLContent(r, str); fi; end; # nothing special to do GAPDoc2HTMLProcs.Address := function(r, str) GAPDoc2HTMLContent(r, str); end; # copy a few entries with two element names GAPDoc2HTMLProcs.E := GAPDoc2HTMLProcs.Emph; GAPDoc2HTMLProcs.Keyword := GAPDoc2HTMLProcs.K; GAPDoc2HTMLProcs.Code := GAPDoc2HTMLProcs.C; GAPDoc2HTMLProcs.File := GAPDoc2HTMLProcs.F; GAPDoc2HTMLProcs.Button := GAPDoc2HTMLProcs.B; GAPDoc2HTMLProcs.Arg := GAPDoc2HTMLProcs.A; GAPDoc2HTMLProcs.Quoted := GAPDoc2HTMLProcs.Q; GAPDoc2HTMLProcs.Par := GAPDoc2HTMLProcs.P; # tables and utilities, not so nice since | and cannot be handled GAPDoc2HTMLProcs.Table := function(r, s) local str, cap, al, a, i; str := ""; if not GAPDoc2HTMLProcs.AltYes(r) then return; fi; # label if IsBound(r.attributes.Label) then GAPDoc2HTMLProcs.Label(rec(count := r.count, root := r.root, attributes := rec(Name := r.attributes.Label)), str); fi; # alignments, table has borders and lines everywhere if any | or HorLine # is specified Append(str, "
        \n"); # the caption, if given cap := Filtered(r.content, a-> a.name = "Caption"); if Length(cap) > 0 then GAPDoc2HTMLProcs.Caption1(cap[1], str); fi; al := Filtered(r.attributes.Align, x-> x <> '|'); for i in [1..Length(al)] do if al[i] = 'c' then al[i] := "\"tdcenter\""; elif al[i] = 'l' then al[i] := "\"tdleft\""; else al[i] := "\"tdright\""; fi; od; # the rows of the table for a in r.content do if a.name = "Row" then GAPDoc2HTMLProcs.Row(a, str, al); fi; od; Append(str, "

         


        \n"); Append(str, "
        \n\n"); Add(s, r.count); Add(s, str); end; # do nothing, we call .Caption1 directly in .Table GAPDoc2HTMLProcs.Caption := function(r, str) return; end; # here the caption text is produced GAPDoc2HTMLProcs.Caption1 := function(r, str) Append(str, Concatenation("", GAPDocTexts.d.Table, ": ")); GAPDoc2HTMLContent(r, str); Append(str, "\n"); end; # cannot be chosen in HTML GAPDoc2HTMLProcs.HorLine := function(r, str) end; GAPDoc2HTMLProcs.Row := function(r, str, al) local s, i, l; Append(str, "\n"); l := Filtered(r.content, a-> a.name = "Item"); for i in [1..Length(l)] do s := ""; GAPDoc2HTMLContent(l[i], s); if not IsString(s) then s := Concatenation(Filtered(s, IsString)); fi; # throw away

        tags in table entries if Length(s) > 5 and s{[1..3]} = "

        " and s{[Length(s)-5..Length(s)]} = "

        \n\n" then s := s{[4..Length(s)-6]}; fi; Append(str, Concatenation("", s, "\n")); od; while i < Length(al) do Append(str, " \n"); i := i+1; od; Append(str, "\n"); end; ## ## <#GAPDoc Label="GAPDoc2HTMLPrintHTMLFiles"> ## ## ## nothing ## ## The first argument must be a result returned by . The second argument is a path for the files ## to write, it can be given as string or directory object. The text ## of each chapter is written into a separate file with name ## chap0.html, chap1.html, ..., chapBib.html, ## and chapInd.html.

        ## ## The MathJax versions are written to files ## chap0_mj.html, ..., chapInd_mj.html.

        ## ## The experimental versions which are produced with tth ## or ttm use different names for the files, namely ## chap0_sym.html, and so on for files which need ## symbol fonts and chap0_mml.xml for files with ## MathML translations.

        ## ## You should also add stylesheet files to the directory with the HTML ## files, see . ## ## ## <#/GAPDoc> ## ## Finally a function to print the text files: InstallGlobalFunction(GAPDoc2HTMLPrintHTMLFiles, function(t, path) local a; if IsString(path) then path := Directory(path); fi; for a in NamesOfComponents(t) do if IsRecord(t.(a)) and IsBound(t.(a).text) then FileString(Filename(path, Concatenation("chap", a, t.ext)), t.(a).text); fi; od; end); InstallGlobalFunction(CopyHTMLStyleFiles, function(dir) local d, todo, l, s, e, f; d := Filename(DirectoriesPackageLibrary("GAPDoc","styles"),""); todo := []; for f in DirectoryContents(d) do if f = "chooser.html" then Add(todo, f); else l := Length(f); if l > 3 and f{[l-2..l]} = ".js" then Add(todo, f); elif l > 4 and f{[l-3..l]} = ".css" then Add(todo, f); fi; fi; od; for f in todo do s := StringFile(Filename(Directory(d),f)); if s = fail then Info(InfoGAPDoc, 1, "Cannot read file ", Filename(Directory(d),f), "\n"); else e := FileString(Filename(Directory(dir),f), s); if e = fail then Info(InfoGAPDoc, 1, "Cannot write file ", Filename(Directory(dir),f), "\n"); fi; fi; od; end); GAPDoc-1.5.1/lib/UnicodeTabs.g0000644000175000017500000021343412026346064014331 0ustar billbill############################################################################# ## #W UnicodeTabs.g GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2007, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## This file contains non-reversible maps from unicode characters to ## LaTeX, ASCII, lower case, ... ## Only some characters are handled, proposed further entries for these ## tables are welcome! ## # This table translates some unicode characters to LaTeX code. It is started # with data from various data files for supporting UTF-8 in LaTeX, # ("ucs" package, "enctex") InstallValue(LaTeXUnicodeTable, [ # we actually start with the ASCII characters which are special characters # in LaTeX [ 35, "\\#" ], [ 36, "\\$" ], [ 37, "\\%" ], [ 38, "\\&" ], [ 60, "{\\textless}" ], [ 62, "{\\textgreater}" ], [ 92, "\\texttt{\\symbol{92}}" ], [ 94, "\\texttt{\\symbol{94}}" ], [ 95, "{\\textunderscore}" ], [ 123, "\\texttt{\\symbol{123}}" ], [ 125, "\\texttt{\\symbol{125}}" ], [ 126, "\\texttt{\\symbol{126}}" ], [ 160, "{\\nobreakspace}" ], [ 161, "{\\textexclamdown}" ], [ 162, "{\\textcent}" ], [ 163, "{\\pounds}" ], [ 164, "{\\textcurrency}" ], [ 165, "{\\textyen}" ], [ 166, "{\\textbrokenbar}" ], [ 167, "{\\S}" ], [ 168, "{\\\"{\\empty}" ], [ 169, "{\\copyright}" ], [ 170, "{\\textordfeminine}" ], [ 171, "{\\guillemotleft}" ], [ 172, "{\\ensuremath{\\lnot}}" ], [ 173, "{\\-}" ], [ 174, "{\\textregistered}" ], [ 175, "{\\a={\\empty}" ], [ 176, "{\\textdegree}" ], [ 177, "{\\ensuremath{\\pm}}" ], [ 178, "{\\textsuperscript2}" ], [ 179, "{\\textsuperscript3}" ], [ 180, "{\\a'{\\empty}" ], [ 181, "{\\ensuremath{\\mu}}" ], [ 182, "{\\P}" ], [ 183, "{\\textperiodcentered}" ], [ 184, "{\\c\\space}" ], [ 185, "{\\textsuperscript1}" ], [ 186, "{\\textordmasculine}" ], [ 187, "{\\guillemotright}" ], [ 188, "{\\textonequarter}" ], [ 189, "{\\textonehalf}" ], [ 190, "{\\textthreequarters}" ], [ 191, "{\\textquestiondown}" ], [ 192, "{\\a`A}" ], [ 193, "{\\a'A}" ], [ 194, "{\\^A}" ], [ 195, "{\\~A}" ], [ 196, "{\\\"A}" ], [ 197, "{\\r A}" ], [ 198, "{\\AE}" ], [ 199, "{\\c C}" ], [ 200, "{\\a`E}" ], [ 201, "{\\a'E}" ], [ 202, "{\\^E}" ], [ 203, "{\\\"E}" ], [ 204, "{\\a`I}" ], [ 205, "{\\a'I}" ], [ 206, "{\\^I}" ], [ 207, "{\\\"I}" ], [ 208, "{\\DH}" ], [ 209, "{\\~N}" ], [ 210, "{\\a`O}" ], [ 211, "{\\a'O}" ], [ 212, "{\\^O}" ], [ 213, "{\\~O}" ], [ 214, "{\\\"O}" ], [ 215, "{\\ensuremath{\\times}}" ], [ 216, "{\\O}" ], [ 217, "{\\a`U}" ], [ 218, "{\\a'U}" ], [ 219, "{\\^U}" ], [ 220, "{\\\"U}" ], [ 221, "{\\a'Y}" ], [ 222, "{\\TH}" ], [ 223, "{\\ss}" ], [ 224, "{\\a`a}" ], [ 225, "{\\a'a}" ], [ 226, "{\\^a}" ], [ 227, "{\\~a}" ], [ 228, "{\\\"a}" ], [ 229, "{\\r a}" ], [ 230, "{\\ae}" ], [ 231, "{\\c c}" ], [ 232, "{\\a`e}" ], [ 233, "{\\a'e}" ], [ 234, "{\\^e}" ], [ 235, "{\\\"e}" ], [ 236, "{\\a`\\i}" ], [ 237, "{\\a'\\i}" ], [ 238, "{\\^\\i}" ], [ 239, "{\\\"\\i}" ], [ 240, "{\\dh}" ], [ 241, "{\\~n}" ], [ 242, "{\\a`o}" ], [ 243, "{\\a'o}" ], [ 244, "{\\^o}" ], [ 245, "{\\~o}" ], [ 246, "{\\\"o}" ], [ 247, "{\\ensuremath{\\div}}" ], [ 248, "{\\o}" ], [ 249, "{\\a`u}" ], [ 250, "{\\a'u}" ], [ 251, "{\\^u}" ], [ 252, "{\\\"u}" ], [ 253, "{\\a'y}" ], [ 254, "{\\th}" ], [ 255, "{\\\"y}" ], [ 256, "{\\a=A}" ], [ 257, "{\\a=a}" ], [ 258, "{\\u A}" ], [ 259, "{\\u a}" ], [ 260, "{\\k A}" ], [ 261, "{\\k a}" ], [ 262, "{\\a'C}" ], [ 263, "{\\a'c}" ], [ 264, "{\\^C}" ], [ 265, "{\\^c}" ], [ 266, "{\\.C}" ], [ 267, "{\\.c}" ], [ 268, "{\\v C}" ], [ 269, "{\\v c}" ], [ 270, "{\\v D}" ], [ 271, "{\\v d}" ], [ 272, "{\\DJ}" ], [ 273, "{\\dj}" ], [ 274, "{\\a=E}" ], [ 275, "{\\a=e}" ], [ 276, "{\\u E}" ], [ 277, "{\\u e}" ], [ 278, "{\\.E}" ], [ 279, "{\\.e}" ], [ 280, "{\\k E}" ], [ 281, "{\\k e}" ], [ 282, "{\\v E}" ], [ 283, "{\\v e}" ], [ 284, "{\\^G}" ], [ 285, "{\\^g}" ], [ 286, "{\\u G}" ], [ 287, "{\\u g}" ], [ 288, "{\\.G}" ], [ 289, "{\\.g}" ], [ 290, "{\\c G}" ], [ 292, "{\\^H}" ], [ 293, "{\\^h}" ], [ 295, "{\\ensuremath{\\hbar}}" ], [ 296, "{\\~I}" ], [ 297, "{\\~\\i}" ], [ 298, "{\\a=I}" ], [ 299, "{\\a=\\i}" ], [ 300, "{\\u I}" ], [ 301, "{\\u\\i}" ], [ 302, "{\\k I}" ], [ 303, "{\\k i}" ], [ 304, "{\\.I}" ], [ 305, "{\\i}" ], [ 308, "{\\^J}" ], [ 309, "{\\^\\j}" ], [ 310, "{\\c K}" ], [ 311, "{\\c k}" ], [ 313, "{\\a'L}" ], [ 314, "{\\a'l}" ], [ 315, "{\\c L}" ], [ 316, "{\\c l}" ], [ 317, "{\\v L}" ], [ 318, "{\\v l}" ], [ 321, "{\\L}" ], [ 322, "{\\l}" ], [ 323, "{\\a'N}" ], [ 324, "{\\a'n}" ], [ 325, "{\\c N}" ], [ 326, "{\\c n}" ], [ 327, "{\\v N}" ], [ 328, "{\\v n}" ], [ 330, "{\\NG}" ], [ 331, "{\\ng}" ], [ 332, "{\\a=O}" ], [ 333, "{\\a=o}" ], [ 334, "{\\u O}" ], [ 335, "{\\u o}" ], [ 336, "{\\H O}" ], [ 337, "{\\H o}" ], [ 338, "{\\OE}" ], [ 339, "{\\oe}" ], [ 340, "{\\a'R}" ], [ 341, "{\\a'r}" ], [ 342, "{\\c R}" ], [ 343, "{\\c r}" ], [ 344, "{\\v R}" ], [ 345, "{\\v r}" ], [ 346, "{\\a'S}" ], [ 347, "{\\a's}" ], [ 348, "{\\^S}" ], [ 349, "{\\^s}" ], [ 350, "{\\c S}" ], [ 351, "{\\c s}" ], [ 352, "{\\v S}" ], [ 353, "{\\v s}" ], [ 354, "{\\c T}" ], [ 355, "{\\c t}" ], [ 356, "{\\v T}" ], [ 357, "{\\v t}" ], [ 358, "{\\ensuremath{\\bar{\\mathrm{T}}}}" ], [ 359, "{\\ensuremath{\\bar{\\mathrm{t}}}}" ], [ 360, "{\\~U}" ], [ 361, "{\\~u}" ], [ 362, "{\\a=U}" ], [ 363, "{\\a=u}" ], [ 364, "{\\u U}" ], [ 365, "{\\u u}" ], [ 366, "{\\r U}" ], [ 367, "{\\r u}" ], [ 368, "{\\H U}" ], [ 369, "{\\H u}" ], [ 370, "{\\k U}" ], [ 371, "{\\k u}" ], [ 372, "{\\^W}" ], [ 373, "{\\^w}" ], [ 374, "{\\^Y}" ], [ 375, "{\\^y}" ], [ 376, "{\\\"Y}" ], [ 377, "{\\a'Z}" ], [ 378, "{\\a'z}" ], [ 379, "{\\.Z}" ], [ 380, "{\\.z}" ], [ 381, "{\\v Z}" ], [ 382, "{\\v z}" ], [ 461, "{\\v A}" ], [ 462, "{\\v a}" ], [ 463, "{\\v I}" ], [ 464, "{\\v\\i}" ], [ 465, "{\\v O}" ], [ 466, "{\\v o}" ], [ 467, "{\\v U}" ], [ 468, "{\\v u}" ], [ 469, "{\\a={\\\"U}" ], [ 470, "{\\a={\\\"u}" ], [ 471, "{\\a'{\\\"U}" ], [ 472, "{\\a'{\\\"u}" ], [ 473, "{\\v{\\\"U}" ], [ 474, "{\\v{\\\"u}" ], [ 475, "{\\a`{\\\"U}" ], [ 476, "{\\a`{\\\"u}" ], [ 478, "{\\a={\\\"A}" ], [ 479, "{\\a={\\\"a}" ], [ 482, "{\\a=\\AE}" ], [ 483, "{\\a=\\ae}" ], [ 486, "{\\v G}" ], [ 487, "{\\v g}" ], [ 488, "{\\v K}" ], [ 489, "{\\v k}" ], [ 490, "{\\k O}" ], [ 491, "{\\k o}" ], [ 496, "{\\v\\j}" ], [ 500, "{\\a'G}" ], [ 501, "{\\a'g}" ], [ 504, "{\\a`N}" ], [ 505, "{\\a`n}" ], [ 506, "{\\a'{\\r A}" ], [ 507, "{\\a'{\\r a}" ], [ 508, "{\\a'\\AE}" ], [ 509, "{\\a'\\ae}" ], [ 510, "{\\a'\\O}" ], [ 511, "{\\a'\\o}" ], [ 542, "{\\v H}" ], [ 543, "{\\v h}" ], [ 550, "{\\.A}" ], [ 551, "{\\.a}" ], [ 552, "{\\c E}" ], [ 553, "{\\c e}" ], [ 554, "{\\a={\\\"O}" ], [ 555, "{\\a={\\\"o}" ], [ 556, "{\\a={\\~O}" ], [ 557, "{\\a={\\~o}" ], [ 558, "{\\.O}" ], [ 559, "{\\.o}" ], [ 562, "{\\a=Y}" ], [ 563, "{\\a=y}" ], [ 697, "{\\ensuremath{'}}" ], [ 698, "{\\ensuremath{''}}" ], [ 699, "{\\ensuremath{'''}}" ], [ 913, "{\\ensuremath\\Alpha}" ], [ 914, "{\\ensuremath\\Beta}" ], [ 915, "{\\ensuremath\\Gamma}" ], [ 916, "{\\ensuremath\\Delta}" ], [ 917, "{\\ensuremath\\Epsilon}" ], [ 918, "{\\ensuremath\\Zeta}" ], [ 919, "{\\ensuremath\\Eta}" ], [ 920, "{\\ensuremath\\Theta}" ], [ 921, "{\\ensuremath\\Iota}" ], [ 922, "{\\ensuremath\\Kappa}" ], [ 923, "{\\ensuremath\\Lambda}" ], [ 924, "{\\ensuremath\\Mu}" ], [ 925, "{\\ensuremath\\Nu}" ], [ 926, "{\\ensuremath\\Xi}" ], [ 927, "{\\ensuremath\\Omicron}" ], [ 928, "{\\ensuremath\\Pi}" ], [ 929, "{\\ensuremath\\Rho}" ], [ 931, "{\\ensuremath\\Sigma}" ], [ 932, "{\\ensuremath\\Tau}" ], [ 933, "{\\ensuremath\\Upsilon}" ], [ 934, "{\\ensuremath\\Phi}" ], [ 935, "{\\ensuremath\\Chi}" ], [ 936, "{\\ensuremath\\Psi}" ], [ 937, "{\\ensuremath\\Omega}" ], [ 945, "{\\ensuremath\\alpha}" ], [ 946, "{\\ensuremath\\beta}" ], [ 947, "{\\ensuremath\\gamma}" ], [ 948, "{\\ensuremath\\delta}" ], [ 949, "{\\ensuremath\\varepsilon}" ], [ 950, "{\\ensuremath\\zeta}" ], [ 951, "{\\ensuremath\\eta}" ], [ 952, "{\\ensuremath\\theta}" ], [ 953, "{\\ensuremath\\iota}" ], [ 954, "{\\ensuremath\\kappa}" ], [ 955, "{\\ensuremath\\lambda}" ], [ 956, "{\\ensuremath\\mu}" ], [ 957, "{\\ensuremath\\nu}" ], [ 958, "{\\ensuremath\\xi}" ], [ 959, "{\\ensuremath\\omicron}" ], [ 960, "{\\ensuremath\\pi}" ], [ 961, "{\\ensuremath\\rho}" ], [ 962, "{\\ensuremath\\varsigma}" ], [ 963, "{\\ensuremath\\sigma}" ], [ 964, "{\\ensuremath\\tau}" ], [ 965, "{\\ensuremath\\upsilon}" ], [ 966, "{\\ensuremath\\varphi}" ], [ 967, "{\\ensuremath\\chi}" ], [ 968, "{\\ensuremath\\psi}" ], [ 969, "{\\ensuremath\\omega}" ], [ 977, "{\\ensuremath\\vartheta}" ], [ 981, "{\\ensuremath\\phi}" ], [ 982, "{\\ensuremath\\varpi}" ], [ 1008, "{\\ensuremath\\varkappa}" ], [ 1009, "{\\ensuremath\\varrho}" ], [ 1013, "{\\ensuremath\\epsilon}" ], [ 1014, "{\\ensuremath\\backepsilon}" ], [ 7682, "{\\.B}" ], [ 7683, "{\\.b}" ], [ 7684, "{\\d B}" ], [ 7685, "{\\d b}" ], [ 7686, "{\\b B}" ], [ 7687, "{\\b b}" ], [ 7690, "{\\.D}" ], [ 7691, "{\\.d}" ], [ 7692, "{\\d D}" ], [ 7693, "{\\d d}" ], [ 7694, "{\\b D}" ], [ 7695, "{\\b d}" ], [ 7696, "{\\c D}" ], [ 7697, "{\\c d}" ], [ 7710, "{\\.F}" ], [ 7711, "{\\.f}" ], [ 7712, "{\\a=G}" ], [ 7713, "{\\a=g}" ], [ 7714, "{\\.H}" ], [ 7715, "{\\.h}" ], [ 7716, "{\\d H}" ], [ 7717, "{\\d h}" ], [ 7718, "{\\\"H}" ], [ 7719, "{\\\"h}" ], [ 7720, "{\\c H}" ], [ 7721, "{\\c h}" ], [ 7728, "{\\a'K}" ], [ 7729, "{\\a'k}" ], [ 7730, "{\\d K}" ], [ 7731, "{\\d k}" ], [ 7732, "{\\b K}" ], [ 7733, "{\\b k}" ], [ 7734, "{\\d L}" ], [ 7735, "{\\d l}" ], [ 7738, "{\\b L}" ], [ 7739, "{\\b l}" ], [ 7742, "{\\a'M}" ], [ 7743, "{\\a'm}" ], [ 7744, "{\\.M}" ], [ 7745, "{\\.m}" ], [ 7746, "{\\d M}" ], [ 7747, "{\\d m}" ], [ 7748, "{\\.N}" ], [ 7749, "{\\.n}" ], [ 7750, "{\\d N}" ], [ 7751, "{\\d n}" ], [ 7752, "{\\b N}" ], [ 7753, "{\\b n}" ], [ 7764, "{\\a'P}" ], [ 7765, "{\\a'p}" ], [ 7766, "{\\.P}" ], [ 7767, "{\\.p}" ], [ 7768, "{\\.R}" ], [ 7769, "{\\.r}" ], [ 7770, "{\\d R}" ], [ 7771, "{\\d r}" ], [ 7774, "{\\b R}" ], [ 7775, "{\\b r}" ], [ 7776, "{\\.S}" ], [ 7777, "{\\.s}" ], [ 7778, "{\\d S}" ], [ 7779, "{\\d s}" ], [ 7786, "{\\.T}" ], [ 7787, "{\\.t}" ], [ 7788, "{\\d T}" ], [ 7789, "{\\d t}" ], [ 7790, "{\\b T}" ], [ 7791, "{\\b t}" ], [ 7804, "{\\~V}" ], [ 7805, "{\\~v}" ], [ 7806, "{\\d V}" ], [ 7807, "{\\d v}" ], [ 7808, "{\\a`W}" ], [ 7809, "{\\a`w}" ], [ 7810, "{\\a'W}" ], [ 7811, "{\\a'w}" ], [ 7812, "{\\\"W}" ], [ 7813, "{\\\"w}" ], [ 7814, "{\\.W}" ], [ 7815, "{\\.w}" ], [ 7816, "{\\d W}" ], [ 7817, "{\\d w}" ], [ 7818, "{\\.X}" ], [ 7819, "{\\.x}" ], [ 7820, "{\\\"X}" ], [ 7821, "{\\\"x}" ], [ 7822, "{\\.Y}" ], [ 7823, "{\\.y}" ], [ 7824, "{\\^Z}" ], [ 7825, "{\\^z}" ], [ 7826, "{\\d Z}" ], [ 7827, "{\\d z}" ], [ 7828, "{\\b Z}" ], [ 7829, "{\\b z}" ], [ 7830, "{\\b h}" ], [ 7831, "{\\\"t}" ], [ 7832, "{\\r w}" ], [ 7833, "{\\r y}" ], [ 7840, "{\\d A}" ], [ 7841, "{\\d a}" ], [ 7864, "{\\d E}" ], [ 7865, "{\\d e}" ], [ 7868, "{\\~E}" ], [ 7869, "{\\~e}" ], [ 7882, "{\\d I}" ], [ 7883, "{\\d i}" ], [ 7884, "{\\d O}" ], [ 7885, "{\\d o}" ], [ 7908, "{\\d U}" ], [ 7909, "{\\d u}" ], [ 7922, "{\\a`Y}" ], [ 7923, "{\\a`y}" ], [ 7924, "{\\d Y}" ], [ 7925, "{\\d y}" ], [ 7928, "{\\~Y}" ], [ 7929, "{\\~y}" ], [ 8192, "{\\enskip}" ], [ 8193, "{\\quad}" ], [ 8194, "{\\enskip}" ], [ 8195, "{\\quad}" ], [ 8201, "{\\thinspace}" ], [ 8203, "" ], [ 8208, "{-}" ], [ 8211, "{\\textendash}" ], [ 8212, "{\\textemdash}" ], [ 8216, "{\\textquoteleft}" ], [ 8217, "{\\textquoteright}" ], [ 8218, "{\\quotesinglbase}" ], [ 8220, "{\\textquotedblleft}" ], [ 8221, "{\\textquotedblright}" ], [ 8222, "{\\quotedblbase}" ], [ 8224, "{\\dag}" ], [ 8225, "{\\ddag}" ], [ 8226, "{\\textbullet}" ], [ 8230, "{\\dots}" ], [ 8232, "{\\leavevmode\\newline}" ], [ 8240, "{\\textperthousand}" ], [ 8241, "{\\textpertenthousand}" ], [ 8242, "{\\ensuremath{^\\prime}}" ], [ 8243, "{\\ensuremath{^{\\prime\\prime}}" ], [ 8244, "{\\ensuremath{^{\\prime\\prime\\prime}}" ], [ 8249, "{\\guilsinglleft}" ], [ 8250, "{\\guilsinglright}" ], [ 8251, "{\\textreferencemark}" ], [ 8253, "{\\textinterrobang}" ], [ 8304, "{\\textsuperscript0}" ], [ 8305, "{\\textsuperscript i}" ], [ 8308, "{\\textsuperscript4}" ], [ 8309, "{\\textsuperscript5}" ], [ 8310, "{\\textsuperscript6}" ], [ 8311, "{\\textsuperscript7}" ], [ 8312, "{\\textsuperscript8}" ], [ 8313, "{\\textsuperscript9}" ], [ 8314, "{\\textsuperscript+}" ], [ 8315, "{\\textsuperscript-}" ], [ 8316, "{\\textsuperscript=}" ], [ 8317, "{\\textsuperscript(}" ], [ 8318, "{\\textsuperscript)}" ], [ 8319, "{\\textsuperscript n}" ], [ 8320, "{\\ensuremath{_0}}" ], [ 8321, "{\\ensuremath{_1}}" ], [ 8322, "{\\ensuremath{_2}}" ], [ 8323, "{\\ensuremath{_3}}" ], [ 8324, "{\\ensuremath{_4}}" ], [ 8325, "{\\ensuremath{_5}}" ], [ 8326, "{\\ensuremath{_6}}" ], [ 8327, "{\\ensuremath{_7}}" ], [ 8328, "{\\ensuremath{_8}}" ], [ 8329, "{\\ensuremath{_9}}" ], [ 8330, "{\\ensuremath{_+}}" ], [ 8331, "{\\ensuremath{_-}}" ], [ 8332, "{\\ensuremath{_=}}" ], [ 8333, "{\\ensuremath{_(}}" ], [ 8334, "{\\ensuremath{_)}}" ], [ 8353, "{\\textcolonmonetary}" ], [ 8356, "{\\textlira}" ], [ 8358, "{\\textnaira}" ], [ 8361, "{\\textwon}" ], [ 8363, "{\\textdong}" ], [ 8364, "{\\ifx\\euro\\undefined\\texteuro\\else\\euro\\fi}" ], [ 8450, "{\\ensuremath{\\mathbb C}}" ], [ 8451, "{\\ensuremath\\degreeC}" ], [ 8457, "{\\ensuremath\\degreeF}" ], [ 8460, "{\\ensuremath{\\mathfrak H}}" ], [ 8461, "{\\ensuremath{\\mathbb H}}" ], [ 8462, "{\\ensuremath{\\mathit h}}" ], [ 8463, "{\\ensuremath{\\hbar}}" ], [ 8465, "{\\ensuremath{\\Im}}" ], [ 8467, "{\\ensuremath{\\ell}}" ], [ 8469, "{\\ensuremath{\\mathbb N}}" ], [ 8470, "{\\textnumero}" ], [ 8472, "{\\ensuremath{\\wp}}" ], [ 8473, "{\\ensuremath{\\mathbb P}}" ], [ 8474, "{\\ensuremath{\\mathbb Q}}" ], [ 8476, "{\\ensuremath{\\Re}}" ], [ 8477, "{\\ensuremath{\\mathbb R}}" ], [ 8480, "{\\textsuperscript{SM}}" ], [ 8482, "{\\texttrademark}" ], [ 8484, "{\\ensuremath{\\mathbb Z}}" ], [ 8486, "{\\ensuremath{\\Omega}}" ], [ 8487, "{\\ensuremath{\\mho}}" ], [ 8488, "{\\ensuremath{\\mathfrak Z}}" ], [ 8490, "{\\ensuremath{\\mathrm K}}" ], [ 8491, "{\\ensuremath\\Angstrom}" ], [ 8493, "{\\ensuremath{\\mathfrak C}}" ], [ 8498, "{\\ensuremath\\Finv}" ], [ 8500, "{\\ensuremath{o}}" ], [ 8501, "{\\ensuremath\\aleph}" ], [ 8502, "{\\ensuremath\\beth}" ], [ 8503, "{\\ensuremath\\gimel}" ], [ 8504, "{\\ensuremath\\daleth}" ], [ 8544, "{\\ensuremath\\romannumI}" ], [ 8545, "{\\ensuremath\\romannumII}" ], [ 8546, "{\\ensuremath\\romannumIII}" ], [ 8547, "{\\ensuremath\\romannumIV}" ], [ 8548, "{\\ensuremath\\romannumV}" ], [ 8549, "{\\ensuremath\\romannumVI}" ], [ 8550, "{\\ensuremath\\romannumVII}" ], [ 8551, "{\\ensuremath\\romannumVIII}" ], [ 8552, "{\\ensuremath\\romannumIX}" ], [ 8553, "{\\ensuremath\\romannumX}" ], [ 8554, "{\\ensuremath\\romannumXI}" ], [ 8555, "{\\ensuremath\\romannumXII}" ], [ 8556, "{\\ensuremath\\romannumL}" ], [ 8557, "{\\ensuremath\\romannumC}" ], [ 8558, "{\\ensuremath\\romannumD}" ], [ 8559, "{\\ensuremath\\romannumM}" ], [ 8560, "{\\ensuremath\\romannumi}" ], [ 8561, "{\\ensuremath\\romannumii}" ], [ 8562, "{\\ensuremath\\romannumiii}" ], [ 8563, "{\\ensuremath\\romannumiv}" ], [ 8564, "{\\ensuremath\\romannumv}" ], [ 8565, "{\\ensuremath\\romannumvi}" ], [ 8566, "{\\ensuremath\\romannumvii}" ], [ 8567, "{\\ensuremath\\romannumviii}" ], [ 8568, "{\\ensuremath\\romannumix}" ], [ 8569, "{\\ensuremath\\romannumx}" ], [ 8570, "{\\ensuremath\\romannumxi}" ], [ 8571, "{\\ensuremath\\romannumxii}" ], [ 8572, "{\\ensuremath\\romannuml}" ], [ 8573, "{\\ensuremath\\romannumc}" ], [ 8574, "{\\ensuremath\\romannumd}" ], [ 8575, "{\\ensuremath\\romannumm}" ], [ 8592, "{\\ensuremath{\\leftarrow}}" ], [ 8593, "{\\ensuremath{\\uparrow}}" ], [ 8594, "{\\ensuremath{\\rightarrow}}" ], [ 8595, "{\\ensuremath{\\downarrow}}" ], [ 8596, "{\\ensuremath{\\leftrightarrow}}" ], [ 8597, "{\\ensuremath{\\updownarrow}}" ], [ 8598, "{\\ensuremath\\nwarrow}" ], [ 8599, "{\\ensuremath\\nearrow}" ], [ 8600, "{\\ensuremath\\searrow}" ], [ 8601, "{\\ensuremath\\swarrow}" ], [ 8602, "{\\ensuremath\\nleftarrow}" ], [ 8603, "{\\ensuremath\\nrightarrow}" ], [ 8605, "{\\ensuremath\\leadsto}" ], [ 8606, "{\\ensuremath\\twoheadleftarrow}" ], [ 8608, "{\\ensuremath\\twoheadrightarrow}" ], [ 8610, "{\\ensuremath\\leftarrowtail}" ], [ 8611, "{\\ensuremath\\rightarrowtail}" ], [ 8614, "{\\ensuremath\\mapsto}" ], [ 8617, "{\\ensuremath\\hookleftarrow}" ], [ 8618, "{\\ensuremath\\hookrightarrow}" ], [ 8619, "{\\ensuremath\\looparrowright}" ], [ 8620, "{\\ensuremath\\looparrowleft}" ], [ 8622, "{\\ensuremath\\nleftrightarrow}" ], [ 8624, "{\\ensuremath\\Lsh}" ], [ 8625, "{\\ensuremath\\Rsh}" ], [ 8630, "{\\ensuremath\\curvearrowleft}" ], [ 8631, "{\\ensuremath\\curvearrowright}" ], [ 8634, "{\\ensuremath\\circlearrowleft}" ], [ 8635, "{\\ensuremath\\circlearrowright}" ], [ 8636, "{\\ensuremath\\leftharpoonup}" ], [ 8637, "{\\ensuremath\\leftharpoondown}" ], [ 8638, "{\\ensuremath\\upharpoonright}" ], [ 8639, "{\\ensuremath\\upharpoonleft}" ], [ 8640, "{\\ensuremath\\rightharpoonup}" ], [ 8641, "{\\ensuremath\\rightharpoondown}" ], [ 8642, "{\\ensuremath\\downharpoonright}" ], [ 8643, "{\\ensuremath\\downharpoonleft}" ], [ 8644, "{\\ensuremath\\rightleftarrows}" ], [ 8646, "{\\ensuremath\\leftrightarrows}" ], [ 8647, "{\\ensuremath\\leftleftarrows}" ], [ 8648, "{\\ensuremath\\upuparrows}" ], [ 8649, "{\\ensuremath\\rightrightarrows}" ], [ 8650, "{\\ensuremath\\downdownarrows}" ], [ 8651, "{\\ensuremath\\leftrightharpoons}" ], [ 8652, "{\\ensuremath{\\rightleftharpoons}}" ], [ 8653, "{\\ensuremath\\nLeftarrow}" ], [ 8654, "{\\ensuremath\\nLeftrightarrow}" ], [ 8655, "{\\ensuremath\\nRightarrow}" ], [ 8656, "{\\ensuremath\\Leftarrow}" ], [ 8657, "{\\ensuremath\\Uparrow}" ], [ 8658, "{\\ensuremath{\\Rightarrow}}" ], [ 8659, "{\\ensuremath\\Downarrow}" ], [ 8660, "{\\ensuremath{\\Leftrightarrow}}" ], [ 8661, "{\\ensuremath\\Updownarrow}" ], [ 8666, "{\\ensuremath\\Lleftarrow}" ], [ 8667, "{\\ensuremath\\Rrightarrow}" ], [ 8669, "{\\ensuremath\\rightsquigarrow}" ], [ 8672, "{\\ensuremath\\dashleftarrow}" ], [ 8674, "{\\ensuremath\\dashrightarrow}" ], [ 8704, "{\\ensuremath{\\forall}}" ], [ 8705, "{\\ensuremath\\complement}" ], [ 8706, "{\\ensuremath{\\partial}}" ], [ 8707, "{\\ensuremath{\\exists}}" ], [ 8708, "{\\ensuremath\\nexists}" ], [ 8709, "{\\ensuremath{\\emptyset}}" ], [ 8710, "{\\ensuremath{\\Delta}}" ], [ 8711, "{\\ensuremath{\\nabla}}" ], [ 8712, "{\\ensuremath{\\in}}" ], [ 8713, "{\\ensuremath{\\notin}}" ], [ 8715, "{\\ensuremath{\\ni}}" ], [ 8716, "{\\ensuremath{\\not\\ni}}" ], [ 8718, "{\\ensuremath\\blacksquare}" ], [ 8719, "{\\ensuremath{\\prod}}" ], [ 8720, "{\\ensuremath{\\coprod}}" ], [ 8721, "{\\ensuremath{\\sum}}" ], [ 8722, "{\\ensuremath{-}}" ], [ 8723, "{\\ensuremath{\\mp}}" ], [ 8724, "{\\ensuremath\\dotplus}" ], [ 8725, "{\\ensuremath{/}}" ], [ 8726, "{\\ensuremath{\\setminus}}" ], [ 8727, "{\\ensuremath{\\ast}}" ], [ 8728, "{\\ensuremath{\\circ}}" ], [ 8729, "{\\ensuremath{\\bullet}}" ], [ 8730, "{\\ensuremath{\\surd}}" ], [ 8733, "{\\ensuremath{\\propto}}" ], [ 8734, "{\\ensuremath{\\infty}}" ], [ 8736, "{\\ensuremath{\\angle}}" ], [ 8737, "{\\ensuremath\\measuredangle}" ], [ 8738, "{\\ensuremath\\sphericalangle}" ], [ 8739, "{\\ensuremath{\\mid}}" ], [ 8740, "{\\ensuremath\\nmid}" ], [ 8741, "{\\ensuremath{\\parallel}}" ], [ 8742, "{\\ensuremath\\nparallel}" ], [ 8743, "{\\ensuremath{\\wedge}}" ], [ 8744, "{\\ensuremath{\\vee}}" ], [ 8745, "{\\ensuremath{\\cap}}" ], [ 8746, "{\\ensuremath{\\cup}}" ], [ 8747, "{\\ensuremath{\\int}}" ], [ 8748, "{\\ensuremath\\iint}" ], [ 8749, "{\\ensuremath\\iiint}" ], [ 8750, "{\\ensuremath{\\oint}}" ], [ 8756, "{\\ensuremath\\therefore}" ], [ 8757, "{\\ensuremath\\because}" ], [ 8758, "{\\ensuremath{:}}" ], [ 8764, "{\\ensuremath{\\sim}}" ], [ 8765, "{\\ensuremath\\backsim}" ], [ 8768, "{\\ensuremath{\\wr}}" ], [ 8769, "{\\ensuremath\\nsim}" ], [ 8771, "{\\ensuremath{\\simeq}}" ], [ 8772, "{\\ensuremath{\\not\\simeq}}" ], [ 8773, "{\\ensuremath{\\cong}}" ], [ 8775, "{\\ensuremath\\ncong}" ], [ 8776, "{\\ensuremath{\\approx}}" ], [ 8777, "{\\ensuremath{\\not\\approx}}" ], [ 8778, "{\\ensuremath\\approxeq}" ], [ 8781, "{\\ensuremath{\\asymp}}" ], [ 8782, "{\\ensuremath\\Bumpeq}" ], [ 8783, "{\\ensuremath\\bumpeq}" ], [ 8784, "{\\ensuremath{\\doteq}}" ], [ 8785, "{\\ensuremath\\doteqdot}" ], [ 8786, "{\\ensuremath\\fallingdotseq}" ], [ 8787, "{\\ensuremath\\risingdotseq}" ], [ 8790, "{\\ensuremath\\eqcirc}" ], [ 8791, "{\\ensuremath\\circeq}" ], [ 8796, "{\\ensuremath\\triangleq}" ], [ 8800, "{\\ensuremath{\\neq}}" ], [ 8801, "{\\ensuremath{\\equiv}}" ], [ 8802, "{\\ensuremath{\\not\\equiv}}" ], [ 8804, "{\\ensuremath{\\leq}}" ], [ 8805, "{\\ensuremath{\\geq}}" ], [ 8806, "{\\ensuremath\\leqq}" ], [ 8807, "{\\ensuremath\\geqq}" ], [ 8808, "{\\ensuremath\\lneqq}" ], [ 8809, "{\\ensuremath\\gneqq}" ], [ 8810, "{\\ensuremath{\\ll}}" ], [ 8811, "{\\ensuremath{\\gg}}" ], [ 8812, "{\\ensuremath\\between}" ], [ 8813, "{\\ensuremath{\\not\\asymp}}" ], [ 8814, "{\\ensuremath\\nless}" ], [ 8815, "{\\ensuremath\\ngtr}" ], [ 8816, "{\\ensuremath\\nleq}" ], [ 8817, "{\\ensuremath\\ngeq}" ], [ 8818, "{\\ensuremath\\lesssim}" ], [ 8819, "{\\ensuremath\\gtrsim}" ], [ 8820, "{\\ensuremath{\\not\\lesssim}}" ], [ 8821, "{\\ensuremath{\\not\\gtrsim}}" ], [ 8822, "{\\ensuremath\\lessgtr}" ], [ 8823, "{\\ensuremath\\gtrless}" ], [ 8826, "{\\ensuremath{\\prec}}" ], [ 8827, "{\\ensuremath{\\succ}}" ], [ 8828, "{\\ensuremath\\preccurlyeq}" ], [ 8829, "{\\ensuremath\\succcurlyeq}" ], [ 8830, "{\\ensuremath\\precsim}" ], [ 8831, "{\\ensuremath\\succsim}" ], [ 8832, "{\\ensuremath\\nprec}" ], [ 8833, "{\\ensuremath\\nsucc}" ], [ 8834, "{\\ensuremath{\\subset}}" ], [ 8835, "{\\ensuremath{\\supset}}" ], [ 8836, "{\\ensuremath{\\not\\subset}}" ], [ 8837, "{\\ensuremath{\\not\\supset}}" ], [ 8838, "{\\ensuremath{\\subseteq}}" ], [ 8839, "{\\ensuremath{\\supseteq}}" ], [ 8840, "{\\ensuremath\\nsubseteq}" ], [ 8841, "{\\ensuremath\\nsupseteq}" ], [ 8842, "{\\ensuremath\\subsetneq}" ], [ 8843, "{\\ensuremath\\supsetneq}" ], [ 8846, "{\\ensuremath{\\uplus}}" ], [ 8847, "{\\ensuremath\\sqsubset}" ], [ 8848, "{\\ensuremath\\sqsupset}" ], [ 8849, "{\\ensuremath{\\sqsubseteq}}" ], [ 8850, "{\\ensuremath{\\sqsupseteq}}" ], [ 8851, "{\\ensuremath{\\sqcap}}" ], [ 8852, "{\\ensuremath{\\sqcup}}" ], [ 8853, "{\\ensuremath{\\oplus}}" ], [ 8854, "{\\ensuremath{\\ominus}}" ], [ 8855, "{\\ensuremath{\\otimes}}" ], [ 8856, "{\\ensuremath{\\oslash}}" ], [ 8857, "{\\ensuremath{\\odot}}" ], [ 8858, "{\\ensuremath\\circledcirc}" ], [ 8859, "{\\ensuremath\\circledast}" ], [ 8861, "{\\ensuremath\\circleddash}" ], [ 8862, "{\\ensuremath\\boxplus}" ], [ 8863, "{\\ensuremath\\boxminus}" ], [ 8864, "{\\ensuremath\\boxtimes}" ], [ 8865, "{\\ensuremath\\boxdot}" ], [ 8866, "{\\ensuremath{\\vdash}}" ], [ 8867, "{\\ensuremath{\\dashv}}" ], [ 8868, "{\\ensuremath{\\top}}" ], [ 8869, "{\\ensuremath{\\bot}}" ], [ 8871, "{\\ensuremath\\models}" ], [ 8873, "{\\ensuremath\\Vdash}" ], [ 8874, "{\\ensuremath\\Vvdash}" ], [ 8876, "{\\ensuremath\\nvdash}" ], [ 8877, "{\\ensuremath\\nvDash}" ], [ 8878, "{\\ensuremath\\nVdash}" ], [ 8879, "{\\ensuremath\\nVDash}" ], [ 8882, "{\\ensuremath\\lhd}" ], [ 8883, "{\\ensuremath\\rhd}" ], [ 8884, "{\\ensuremath\\unlhd}" ], [ 8885, "{\\ensuremath\\unrhd}" ], [ 8888, "{\\ensuremath\\multimap}" ], [ 8890, "{\\ensuremath\\intercal}" ], [ 8891, "{\\ensuremath\\veebar}" ], [ 8892, "{\\ensuremath\\barwedge}" ], [ 8896, "{\\ensuremath{\\bigwedge}}" ], [ 8897, "{\\ensuremath{\\bigvee}}" ], [ 8898, "{\\ensuremath{\\bigcap}}" ], [ 8899, "{\\ensuremath{\\bigcup}}" ], [ 8900, "{\\ensuremath{\\diamond}}" ], [ 8901, "{\\ensuremath{\\cdot}}" ], [ 8902, "{\\ensuremath{\\star}}" ], [ 8903, "{\\ensuremath\\divideontimes}" ], [ 8904, "{\\ensuremath{\\bowtie}}" ], [ 8905, "{\\ensuremath\\ltimes}" ], [ 8906, "{\\ensuremath\\rtimes}" ], [ 8907, "{\\ensuremath\\leftthreetimes}" ], [ 8908, "{\\ensuremath\\rightthreetimes}" ], [ 8909, "{\\ensuremath\\backsimeq}" ], [ 8910, "{\\ensuremath\\curlyvee}" ], [ 8911, "{\\ensuremath\\curlywedge}" ], [ 8912, "{\\ensuremath\\Subset}" ], [ 8913, "{\\ensuremath\\Supset}" ], [ 8914, "{\\ensuremath\\Cap}" ], [ 8915, "{\\ensuremath\\Cup}" ], [ 8916, "{\\ensuremath\\pitchfork}" ], [ 8918, "{\\ensuremath\\lessdot}" ], [ 8919, "{\\ensuremath\\gtrdot}" ], [ 8920, "{\\ensuremath\\lll}" ], [ 8921, "{\\ensuremath\\ggg}" ], [ 8922, "{\\ensuremath\\lesseqgtr}" ], [ 8923, "{\\ensuremath\\gtreqless}" ], [ 8926, "{\\ensuremath\\curlyeqprec}" ], [ 8927, "{\\ensuremath\\curlyeqsucc}" ], [ 8928, "{\\ensuremath{\\not\\preccurlyeq}}" ], [ 8929, "{\\ensuremath{\\not\\succcurlyeq}}" ], [ 8930, "{\\ensuremath{\\not\\sqsubseteq}}" ], [ 8931, "{\\ensuremath{\\not\\sqsupseteq}}" ], [ 8934, "{\\ensuremath\\lnsim}" ], [ 8935, "{\\ensuremath\\gnsim}" ], [ 8936, "{\\ensuremath\\precnsim}" ], [ 8937, "{\\ensuremath\\succnsim}" ], [ 8938, "{\\ensuremath\\ntriangleleft}" ], [ 8939, "{\\ensuremath\\ntriangleright}" ], [ 8940, "{\\ensuremath\\ntrianglelefteq}" ], [ 8941, "{\\ensuremath\\ntrianglerighteq}" ], [ 8942, "{\\ensuremath{\\vdots}}" ], [ 8943, "{\\ensuremath{\\cdots}}" ], [ 8945, "{\\ensuremath{\\ddots}}" ], [ 8960, "{\\ensuremath\\varemptyset}" ], [ 8968, "{\\ensuremath{\\lceil}}" ], [ 8969, "{\\ensuremath{\\rceil}}" ], [ 8970, "{\\ensuremath{\\lfloor}}" ], [ 8971, "{\\ensuremath{\\rfloor}}" ], [ 8988, "{\\ensuremath\\ulcorner}" ], [ 8989, "{\\ensuremath\\urcorner}" ], [ 8990, "{\\ensuremath\\llcorner}" ], [ 8991, "{\\ensuremath\\lrcorner}" ], [ 8994, "{\\ensuremath\\frown}" ], [ 8995, "{\\ensuremath\\smile}" ], [ 9633, "{\\ensuremath\\Box}" ], [ 9651, "{\\ensuremath\\bigtriangleup}" ], [ 9657, "{\\ensuremath\\triangleright}" ], [ 9661, "{\\ensuremath\\bigtriangledown}" ], [ 9667, "{\\ensuremath\\triangleleft}" ], [ 9671, "{\\ensuremath\\Diamond}" ], [ 9674, "{\\ensuremath\\lozenge}" ], [ 9824, "{\\ensuremath{\\spadesuit}}" ], [ 9825, "{\\ensuremath{\\heartsuit}}" ], [ 9826, "{\\ensuremath{\\diamondsuit}}" ], [ 9827, "{\\ensuremath{\\clubsuit}}" ], [ 9837, "{\\ensuremath{\\flat}}" ], [ 9838, "{\\ensuremath{\\natural}}" ], [ 9839, "{\\ensuremath{\\sharp}}" ], [ 10216, "{\\ensuremath{\\langle}}" ], [ 10217, "{\\ensuremath{\\rangle}}" ], [ 10229, "{\\ensuremath\\longleftarrow}" ], [ 10230, "{\\ensuremath\\longrightarrow}" ], [ 10231, "{\\ensuremath\\longleftrightarrow}" ], [ 10232, "{\\ensuremath\\Longleftarrow}" ], [ 10233, "{\\ensuremath\\Longrightarrow}" ], [ 10234, "{\\ensuremath\\Longleftrightarrow}" ], [ 10731, "{\\ensuremath\\blacklozenge}" ], [ 10752, "{\\ensuremath\\bigodot}" ], [ 10753, "{\\ensuremath\\bigoplus}" ], [ 10754, "{\\ensuremath\\bigotimes}" ], [ 10756, "{\\ensuremath\\biguplus}" ], [ 10757, "{\\ensuremath\\bigsqcap}" ], [ 10758, "{\\ensuremath\\bigsqcup}" ], [ 119808, "{\\ensuremath{\\mathbf A}}" ], [ 119809, "{\\ensuremath{\\mathbf B}}" ], [ 119810, "{\\ensuremath{\\mathbf C}}" ], [ 119811, "{\\ensuremath{\\mathbf D}}" ], [ 119812, "{\\ensuremath{\\mathbf E}}" ], [ 119813, "{\\ensuremath{\\mathbf F}}" ], [ 119814, "{\\ensuremath{\\mathbf G}}" ], [ 119815, "{\\ensuremath{\\mathbf H}}" ], [ 119816, "{\\ensuremath{\\mathbf I}}" ], [ 119817, "{\\ensuremath{\\mathbf J}}" ], [ 119818, "{\\ensuremath{\\mathbf K}}" ], [ 119819, "{\\ensuremath{\\mathbf L}}" ], [ 119820, "{\\ensuremath{\\mathbf M}}" ], [ 119821, "{\\ensuremath{\\mathbf N}}" ], [ 119822, "{\\ensuremath{\\mathbf O}}" ], [ 119823, "{\\ensuremath{\\mathbf P}}" ], [ 119824, "{\\ensuremath{\\mathbf Q}}" ], [ 119825, "{\\ensuremath{\\mathbf R}}" ], [ 119826, "{\\ensuremath{\\mathbf S}}" ], [ 119827, "{\\ensuremath{\\mathbf T}}" ], [ 119828, "{\\ensuremath{\\mathbf U}}" ], [ 119829, "{\\ensuremath{\\mathbf V}}" ], [ 119830, "{\\ensuremath{\\mathbf W}}" ], [ 119831, "{\\ensuremath{\\mathbf X}}" ], [ 119832, "{\\ensuremath{\\mathbf Y}}" ], [ 119833, "{\\ensuremath{\\mathbf Z}}" ], [ 119834, "{\\ensuremath{\\mathbf a}}" ], [ 119835, "{\\ensuremath{\\mathbf b}}" ], [ 119836, "{\\ensuremath{\\mathbf c}}" ], [ 119837, "{\\ensuremath{\\mathbf d}}" ], [ 119838, "{\\ensuremath{\\mathbf e}}" ], [ 119839, "{\\ensuremath{\\mathbf f}}" ], [ 119840, "{\\ensuremath{\\mathbf g}}" ], [ 119841, "{\\ensuremath{\\mathbf h}}" ], [ 119842, "{\\ensuremath{\\mathbf i}}" ], [ 119843, "{\\ensuremath{\\mathbf j}}" ], [ 119844, "{\\ensuremath{\\mathbf k}}" ], [ 119845, "{\\ensuremath{\\mathbf l}}" ], [ 119846, "{\\ensuremath{\\mathbf m}}" ], [ 119847, "{\\ensuremath{\\mathbf n}}" ], [ 119848, "{\\ensuremath{\\mathbf o}}" ], [ 119849, "{\\ensuremath{\\mathbf p}}" ], [ 119850, "{\\ensuremath{\\mathbf q}}" ], [ 119851, "{\\ensuremath{\\mathbf r}}" ], [ 119852, "{\\ensuremath{\\mathbf s}}" ], [ 119853, "{\\ensuremath{\\mathbf t}}" ], [ 119854, "{\\ensuremath{\\mathbf u}}" ], [ 119855, "{\\ensuremath{\\mathbf v}}" ], [ 119856, "{\\ensuremath{\\mathbf w}}" ], [ 119857, "{\\ensuremath{\\mathbf x}}" ], [ 119858, "{\\ensuremath{\\mathbf y}}" ], [ 119859, "{\\ensuremath{\\mathbf z}}" ], [ 119860, "{\\ensuremath{\\mathit A}}" ], [ 119861, "{\\ensuremath{\\mathit B}}" ], [ 119862, "{\\ensuremath{\\mathit C}}" ], [ 119863, "{\\ensuremath{\\mathit D}}" ], [ 119864, "{\\ensuremath{\\mathit E}}" ], [ 119865, "{\\ensuremath{\\mathit F}}" ], [ 119866, "{\\ensuremath{\\mathit G}}" ], [ 119867, "{\\ensuremath{\\mathit H}}" ], [ 119868, "{\\ensuremath{\\mathit I}}" ], [ 119869, "{\\ensuremath{\\mathit J}}" ], [ 119870, "{\\ensuremath{\\mathit K}}" ], [ 119871, "{\\ensuremath{\\mathit L}}" ], [ 119872, "{\\ensuremath{\\mathit M}}" ], [ 119873, "{\\ensuremath{\\mathit N}}" ], [ 119874, "{\\ensuremath{\\mathit O}}" ], [ 119875, "{\\ensuremath{\\mathit P}}" ], [ 119876, "{\\ensuremath{\\mathit Q}}" ], [ 119877, "{\\ensuremath{\\mathit R}}" ], [ 119878, "{\\ensuremath{\\mathit S}}" ], [ 119879, "{\\ensuremath{\\mathit T}}" ], [ 119880, "{\\ensuremath{\\mathit U}}" ], [ 119881, "{\\ensuremath{\\mathit V}}" ], [ 119882, "{\\ensuremath{\\mathit W}}" ], [ 119883, "{\\ensuremath{\\mathit X}}" ], [ 119884, "{\\ensuremath{\\mathit Y}}" ], [ 119885, "{\\ensuremath{\\mathit Z}}" ], [ 119886, "{\\ensuremath{\\mathit a}}" ], [ 119887, "{\\ensuremath{\\mathit b}}" ], [ 119888, "{\\ensuremath{\\mathit c}}" ], [ 119889, "{\\ensuremath{\\mathit d}}" ], [ 119890, "{\\ensuremath{\\mathit e}}" ], [ 119891, "{\\ensuremath{\\mathit f}}" ], [ 119892, "{\\ensuremath{\\mathit g}}" ], [ 119894, "{\\ensuremath{\\mathit i}}" ], [ 119895, "{\\ensuremath{\\mathit j}}" ], [ 119896, "{\\ensuremath{\\mathit k}}" ], [ 119897, "{\\ensuremath{\\mathit l}}" ], [ 119898, "{\\ensuremath{\\mathit m}}" ], [ 119899, "{\\ensuremath{\\mathit n}}" ], [ 119900, "{\\ensuremath{\\mathit o}}" ], [ 119901, "{\\ensuremath{\\mathit p}}" ], [ 119902, "{\\ensuremath{\\mathit q}}" ], [ 119903, "{\\ensuremath{\\mathit r}}" ], [ 119904, "{\\ensuremath{\\mathit s}}" ], [ 119905, "{\\ensuremath{\\mathit t}}" ], [ 119906, "{\\ensuremath{\\mathit u}}" ], [ 119907, "{\\ensuremath{\\mathit v}}" ], [ 119908, "{\\ensuremath{\\mathit w}}" ], [ 119909, "{\\ensuremath{\\mathit x}}" ], [ 119910, "{\\ensuremath{\\mathit y}}" ], [ 119911, "{\\ensuremath{\\mathit z}}" ], [ 120068, "{\\ensuremath{\\mathfrak A}}" ], [ 120069, "{\\ensuremath{\\mathfrak B}}" ], [ 120071, "{\\ensuremath{\\mathfrak D}}" ], [ 120072, "{\\ensuremath{\\mathfrak E}}" ], [ 120073, "{\\ensuremath{\\mathfrak F}}" ], [ 120074, "{\\ensuremath{\\mathfrak G}}" ], [ 120077, "{\\ensuremath{\\mathfrak J}}" ], [ 120078, "{\\ensuremath{\\mathfrak K}}" ], [ 120079, "{\\ensuremath{\\mathfrak L}}" ], [ 120080, "{\\ensuremath{\\mathfrak M}}" ], [ 120081, "{\\ensuremath{\\mathfrak N}}" ], [ 120082, "{\\ensuremath{\\mathfrak O}}" ], [ 120083, "{\\ensuremath{\\mathfrak P}}" ], [ 120084, "{\\ensuremath{\\mathfrak Q}}" ], [ 120086, "{\\ensuremath{\\mathfrak S}}" ], [ 120087, "{\\ensuremath{\\mathfrak T}}" ], [ 120088, "{\\ensuremath{\\mathfrak U}}" ], [ 120089, "{\\ensuremath{\\mathfrak V}}" ], [ 120090, "{\\ensuremath{\\mathfrak W}}" ], [ 120091, "{\\ensuremath{\\mathfrak X}}" ], [ 120092, "{\\ensuremath{\\mathfrak Y}}" ], [ 120094, "{\\ensuremath{\\mathfrak a}}" ], [ 120095, "{\\ensuremath{\\mathfrak b}}" ], [ 120096, "{\\ensuremath{\\mathfrak c}}" ], [ 120097, "{\\ensuremath{\\mathfrak d}}" ], [ 120098, "{\\ensuremath{\\mathfrak e}}" ], [ 120099, "{\\ensuremath{\\mathfrak f}}" ], [ 120100, "{\\ensuremath{\\mathfrak g}}" ], [ 120101, "{\\ensuremath{\\mathfrak h}}" ], [ 120102, "{\\ensuremath{\\mathfrak i}}" ], [ 120103, "{\\ensuremath{\\mathfrak j}}" ], [ 120104, "{\\ensuremath{\\mathfrak k}}" ], [ 120105, "{\\ensuremath{\\mathfrak l}}" ], [ 120106, "{\\ensuremath{\\mathfrak m}}" ], [ 120107, "{\\ensuremath{\\mathfrak n}}" ], [ 120108, "{\\ensuremath{\\mathfrak o}}" ], [ 120109, "{\\ensuremath{\\mathfrak p}}" ], [ 120110, "{\\ensuremath{\\mathfrak q}}" ], [ 120111, "{\\ensuremath{\\mathfrak r}}" ], [ 120112, "{\\ensuremath{\\mathfrak s}}" ], [ 120113, "{\\ensuremath{\\mathfrak t}}" ], [ 120114, "{\\ensuremath{\\mathfrak u}}" ], [ 120115, "{\\ensuremath{\\mathfrak v}}" ], [ 120116, "{\\ensuremath{\\mathfrak w}}" ], [ 120117, "{\\ensuremath{\\mathfrak x}}" ], [ 120118, "{\\ensuremath{\\mathfrak y}}" ], [ 120119, "{\\ensuremath{\\mathfrak z}}" ], [ 120120, "{\\ensuremath{\\mathbb A}}" ], [ 120121, "{\\ensuremath{\\mathbb B}}" ], [ 120123, "{\\ensuremath{\\mathbb D}}" ], [ 120124, "{\\ensuremath{\\mathbb E}}" ], [ 120125, "{\\ensuremath{\\mathbb F}}" ], [ 120126, "{\\ensuremath{\\mathbb G}}" ], [ 120128, "{\\ensuremath{\\mathbb I}}" ], [ 120129, "{\\ensuremath{\\mathbb J}}" ], [ 120130, "{\\ensuremath{\\mathbb K}}" ], [ 120131, "{\\ensuremath{\\mathbb L}}" ], [ 120132, "{\\ensuremath{\\mathbb M}}" ], [ 120134, "{\\ensuremath{\\mathbb O}}" ], [ 120138, "{\\ensuremath{\\mathbb S}}" ], [ 120139, "{\\ensuremath{\\mathbb T}}" ], [ 120140, "{\\ensuremath{\\mathbb U}}" ], [ 120141, "{\\ensuremath{\\mathbb V}}" ], [ 120142, "{\\ensuremath{\\mathbb W}}" ], [ 120143, "{\\ensuremath{\\mathbb X}}" ], [ 120144, "{\\ensuremath{\\mathbb Y}}" ], [ 120146, "{\\ensuremath{\\mathbb a}}" ], [ 120147, "{\\ensuremath{\\mathbb b}}" ], [ 120148, "{\\ensuremath{\\mathbb c}}" ], [ 120149, "{\\ensuremath{\\mathbb d}}" ], [ 120150, "{\\ensuremath{\\mathbb e}}" ], [ 120151, "{\\ensuremath{\\mathbb f}}" ], [ 120152, "{\\ensuremath{\\mathbb g}}" ], [ 120153, "{\\ensuremath{\\mathbb h}}" ], [ 120154, "{\\ensuremath{\\mathbb i}}" ], [ 120155, "{\\ensuremath{\\mathbb j}}" ], [ 120156, "{\\ensuremath{\\mathbb k}}" ], [ 120157, "{\\ensuremath{\\mathbb l}}" ], [ 120158, "{\\ensuremath{\\mathbb m}}" ], [ 120159, "{\\ensuremath{\\mathbb n}}" ], [ 120160, "{\\ensuremath{\\mathbb o}}" ], [ 120161, "{\\ensuremath{\\mathbb p}}" ], [ 120162, "{\\ensuremath{\\mathbb q}}" ], [ 120163, "{\\ensuremath{\\mathbb r}}" ], [ 120164, "{\\ensuremath{\\mathbb s}}" ], [ 120165, "{\\ensuremath{\\mathbb t}}" ], [ 120166, "{\\ensuremath{\\mathbb u}}" ], [ 120167, "{\\ensuremath{\\mathbb v}}" ], [ 120168, "{\\ensuremath{\\mathbb w}}" ], [ 120169, "{\\ensuremath{\\mathbb x}}" ], [ 120170, "{\\ensuremath{\\mathbb y}}" ], [ 120171, "{\\ensuremath{\\mathbb z}}" ], [ 120224, "{\\ensuremath{\\mathsf A}}" ], [ 120225, "{\\ensuremath{\\mathsf B}}" ], [ 120226, "{\\ensuremath{\\mathsf C}}" ], [ 120227, "{\\ensuremath{\\mathsf D}}" ], [ 120228, "{\\ensuremath{\\mathsf E}}" ], [ 120229, "{\\ensuremath{\\mathsf F}}" ], [ 120230, "{\\ensuremath{\\mathsf G}}" ], [ 120231, "{\\ensuremath{\\mathsf H}}" ], [ 120232, "{\\ensuremath{\\mathsf I}}" ], [ 120233, "{\\ensuremath{\\mathsf J}}" ], [ 120234, "{\\ensuremath{\\mathsf K}}" ], [ 120235, "{\\ensuremath{\\mathsf L}}" ], [ 120236, "{\\ensuremath{\\mathsf M}}" ], [ 120237, "{\\ensuremath{\\mathsf N}}" ], [ 120238, "{\\ensuremath{\\mathsf O}}" ], [ 120239, "{\\ensuremath{\\mathsf P}}" ], [ 120240, "{\\ensuremath{\\mathsf Q}}" ], [ 120241, "{\\ensuremath{\\mathsf R}}" ], [ 120242, "{\\ensuremath{\\mathsf S}}" ], [ 120243, "{\\ensuremath{\\mathsf T}}" ], [ 120244, "{\\ensuremath{\\mathsf U}}" ], [ 120245, "{\\ensuremath{\\mathsf V}}" ], [ 120246, "{\\ensuremath{\\mathsf W}}" ], [ 120247, "{\\ensuremath{\\mathsf X}}" ], [ 120248, "{\\ensuremath{\\mathsf Y}}" ], [ 120249, "{\\ensuremath{\\mathsf Z}}" ], [ 120250, "{\\ensuremath{\\mathsf a}}" ], [ 120251, "{\\ensuremath{\\mathsf b}}" ], [ 120252, "{\\ensuremath{\\mathsf c}}" ], [ 120253, "{\\ensuremath{\\mathsf d}}" ], [ 120254, "{\\ensuremath{\\mathsf e}}" ], [ 120255, "{\\ensuremath{\\mathsf f}}" ], [ 120256, "{\\ensuremath{\\mathsf g}}" ], [ 120257, "{\\ensuremath{\\mathsf h}}" ], [ 120258, "{\\ensuremath{\\mathsf i}}" ], [ 120259, "{\\ensuremath{\\mathsf j}}" ], [ 120260, "{\\ensuremath{\\mathsf k}}" ], [ 120261, "{\\ensuremath{\\mathsf l}}" ], [ 120262, "{\\ensuremath{\\mathsf m}}" ], [ 120263, "{\\ensuremath{\\mathsf n}}" ], [ 120264, "{\\ensuremath{\\mathsf o}}" ], [ 120265, "{\\ensuremath{\\mathsf p}}" ], [ 120266, "{\\ensuremath{\\mathsf q}}" ], [ 120267, "{\\ensuremath{\\mathsf r}}" ], [ 120268, "{\\ensuremath{\\mathsf s}}" ], [ 120269, "{\\ensuremath{\\mathsf t}}" ], [ 120270, "{\\ensuremath{\\mathsf u}}" ], [ 120271, "{\\ensuremath{\\mathsf v}}" ], [ 120272, "{\\ensuremath{\\mathsf w}}" ], [ 120273, "{\\ensuremath{\\mathsf x}}" ], [ 120274, "{\\ensuremath{\\mathsf y}}" ], [ 120275, "{\\ensuremath{\\mathsf z}}" ], [ 120432, "{\\ensuremath{\\mathtt A}}" ], [ 120433, "{\\ensuremath{\\mathtt B}}" ], [ 120434, "{\\ensuremath{\\mathtt C}}" ], [ 120435, "{\\ensuremath{\\mathtt D}}" ], [ 120436, "{\\ensuremath{\\mathtt E}}" ], [ 120437, "{\\ensuremath{\\mathtt F}}" ], [ 120438, "{\\ensuremath{\\mathtt G}}" ], [ 120439, "{\\ensuremath{\\mathtt H}}" ], [ 120440, "{\\ensuremath{\\mathtt I}}" ], [ 120441, "{\\ensuremath{\\mathtt J}}" ], [ 120442, "{\\ensuremath{\\mathtt K}}" ], [ 120443, "{\\ensuremath{\\mathtt L}}" ], [ 120444, "{\\ensuremath{\\mathtt M}}" ], [ 120445, "{\\ensuremath{\\mathtt N}}" ], [ 120446, "{\\ensuremath{\\mathtt O}}" ], [ 120447, "{\\ensuremath{\\mathtt P}}" ], [ 120448, "{\\ensuremath{\\mathtt Q}}" ], [ 120449, "{\\ensuremath{\\mathtt R}}" ], [ 120450, "{\\ensuremath{\\mathtt S}}" ], [ 120451, "{\\ensuremath{\\mathtt T}}" ], [ 120452, "{\\ensuremath{\\mathtt U}}" ], [ 120453, "{\\ensuremath{\\mathtt V}}" ], [ 120454, "{\\ensuremath{\\mathtt W}}" ], [ 120455, "{\\ensuremath{\\mathtt X}}" ], [ 120456, "{\\ensuremath{\\mathtt Y}}" ], [ 120457, "{\\ensuremath{\\mathtt Z}}" ], [ 120458, "{\\ensuremath{\\mathtt a}}" ], [ 120459, "{\\ensuremath{\\mathtt b}}" ], [ 120460, "{\\ensuremath{\\mathtt c}}" ], [ 120461, "{\\ensuremath{\\mathtt d}}" ], [ 120462, "{\\ensuremath{\\mathtt e}}" ], [ 120463, "{\\ensuremath{\\mathtt f}}" ], [ 120464, "{\\ensuremath{\\mathtt g}}" ], [ 120465, "{\\ensuremath{\\mathtt h}}" ], [ 120466, "{\\ensuremath{\\mathtt i}}" ], [ 120467, "{\\ensuremath{\\mathtt j}}" ], [ 120468, "{\\ensuremath{\\mathtt k}}" ], [ 120469, "{\\ensuremath{\\mathtt l}}" ], [ 120470, "{\\ensuremath{\\mathtt m}}" ], [ 120471, "{\\ensuremath{\\mathtt n}}" ], [ 120472, "{\\ensuremath{\\mathtt o}}" ], [ 120473, "{\\ensuremath{\\mathtt p}}" ], [ 120474, "{\\ensuremath{\\mathtt q}}" ], [ 120475, "{\\ensuremath{\\mathtt r}}" ], [ 120476, "{\\ensuremath{\\mathtt s}}" ], [ 120477, "{\\ensuremath{\\mathtt t}}" ], [ 120478, "{\\ensuremath{\\mathtt u}}" ], [ 120479, "{\\ensuremath{\\mathtt v}}" ], [ 120480, "{\\ensuremath{\\mathtt w}}" ], [ 120481, "{\\ensuremath{\\mathtt x}}" ], [ 120482, "{\\ensuremath{\\mathtt y}}" ], [ 120483, "{\\ensuremath{\\mathtt z}}" ], [ 120782, "{\\ensuremath{\\mathbf0}}" ], [ 120783, "{\\ensuremath{\\mathbf1}}" ], [ 120784, "{\\ensuremath{\\mathbf2}}" ], [ 120785, "{\\ensuremath{\\mathbf3}}" ], [ 120786, "{\\ensuremath{\\mathbf4}}" ], [ 120787, "{\\ensuremath{\\mathbf5}}" ], [ 120788, "{\\ensuremath{\\mathbf6}}" ], [ 120789, "{\\ensuremath{\\mathbf7}}" ], [ 120790, "{\\ensuremath{\\mathbf8}}" ], [ 120791, "{\\ensuremath{\\mathbf9}}" ], [ 120793, "{\\ensuremath{\\mathbb 1}}" ], [ 120794, "{\\ensuremath{\\mathbb 2}}" ], [ 120802, "{\\ensuremath{\\mathsf0}}" ], [ 120803, "{\\ensuremath{\\mathsf1}}" ], [ 120804, "{\\ensuremath{\\mathsf2}}" ], [ 120805, "{\\ensuremath{\\mathsf3}}" ], [ 120806, "{\\ensuremath{\\mathsf4}}" ], [ 120807, "{\\ensuremath{\\mathsf5}}" ], [ 120808, "{\\ensuremath{\\mathsf6}}" ], [ 120809, "{\\ensuremath{\\mathsf7}}" ], [ 120810, "{\\ensuremath{\\mathsf8}}" ], [ 120811, "{\\ensuremath{\\mathsf9}}" ], [ 120822, "{\\ensuremath{\\mathtt0}}" ], [ 120823, "{\\ensuremath{\\mathtt1}}" ], [ 120824, "{\\ensuremath{\\mathtt2}}" ], [ 120825, "{\\ensuremath{\\mathtt3}}" ], [ 120826, "{\\ensuremath{\\mathtt4}}" ], [ 120827, "{\\ensuremath{\\mathtt5}}" ], [ 120828, "{\\ensuremath{\\mathtt6}}" ], [ 120829, "{\\ensuremath{\\mathtt7}}" ], [ 120830, "{\\ensuremath{\\mathtt8}}" ], [ 120831, "{\\ensuremath{\\mathtt9}}" ], ]); # Some translations of unicode characters (codepoint in first position # of each entry) to "simpler" ones, often ASCII or sequence of ASCII # characters. This table is started using the "transtab" data by # Markus Kuhn (http://www.cl.cam.ac.uk/~mgk25/download/transtab.tar.gz) InstallValue(SimplifiedUnicodeTable, [ [160,32], [161,33], [162,99], [163,[71,66,80]], [165,89], [166,124], [167,83], [168,34], [169,[40,99,41],99], [170,97], [171,[60,60]], [172,45], [173,45], [174,[40,82,41]], [175,45], [176,32], [177,[43,47,45]], [178,[94,50],50], [179,[94,51],51], [180,39], [181,956,117], [182,80], [183,46], [184,44], [185,[94,49],49], [186,111], [187,[62,62]], [188,[32,49,47,52]], [189,[32,49,47,50]], [190,[32,51,47,52]], [191,63], [192,65], [193,65], [194,65], [195,65], [196,[65,101],65], [197,[65,97],65], [198,[65,69],65], [199,67], [200,69], [201,69], [202,69], [203,69], [204,73], [205,73], [206,73], [207,73], [208,68], [209,78], [210,79], [211,79], [212,79], [213,79], [214,[79,101],79], [215,120], [216,79], [217,85], [218,85], [219,85], [220,[85,101],85], [221,89], [222,[84,104]], [223,[115,115],946,115], [224,97], [225,97], [226,97], [227,97], [228,[97,101],97], [229,[97,97],97], [230,[97,101],97], [231,99], [232,101], [233,101], [234,101], [235,101], [236,105], [237,105], [238,105], [239,105], [240,100], [241,110], [242,111], [243,111], [244,111], [245,111], [246,[111,101],111], [247,58], [248,111], [249,117], [250,117], [251,117], [252,[117,101],117], [253,121], [254,[116,104]], [255,121], [256,65], [257,97], [258,65], [259,97], [260,65], [261,97], [262,67], [263,99], [264,[67,104],67], [265,[99,104],99], [266,67], [267,99], [268,67], [269,99], [270,68], [271,100], [272,68], [273,100], [274,69], [275,101], [276,69], [277,101], [278,69], [279,101], [280,69], [281,101], [282,69], [283,101], [284,[71,104],71], [285,[103,104],103], [286,71], [287,103], [288,71], [289,103], [290,71], [291,103], [292,[72,104],72], [293,[104,104],104], [294,72], [295,104], [296,73], [297,105], [298,73], [299,105], [300,73], [301,105], [302,73], [303,105], [304,73], [305,105], [306,[73,74]], [307,[105,106]], [308,[74,104],74], [309,[106,104],106], [310,75], [311,107], [312,107], [313,76], [314,108], [315,76], [316,108], [317,76], [318,108], [319,[76,183],[76,46],76], [320,[108,183],[108,46],108], [321,76], [322,108], [323,78], [324,110], [325,78], [326,110], [327,78], [328,110], [329,[39,110]], [330,[78,71],78], [331,[110,103],110], [332,79], [333,111], [334,79], [335,111], [336,79], [337,111], [338,[79,69]], [339,[111,101]], [340,82], [341,114], [342,82], [343,114], [344,82], [345,114], [346,83], [347,115], [348,[83,104],83], [349,[115,104],115], [350,83], [351,115], [352,83], [353,115], [354,84], [355,116], [356,84], [357,116], [358,84], [359,116], [360,85], [361,117], [362,85], [363,117], [364,85], [365,117], [366,85], [367,117], [368,85], [369,117], [370,85], [371,117], [372,87], [373,119], [374,89], [375,121], [376,89], [377,90], [378,122], [379,90], [380,122], [381,90], [382,122], [383,115], [402,102], [536,350,83], [537,351,115], [538,354,84], [539,355,116], [697,8242,39], [699,8216], [700,8217,39], [701,8219], [710,94], [712,39], [713,175], [716,44], [720,58], [730,176], [732,126], [733,34], [884,39], [885,44], [894,59], [7680,65], [7681,97], [7682,66], [7683,98], [7684,66], [7685,98], [7686,66], [7687,98], [7688,67], [7689,99], [7690,68], [7691,100], [7692,68], [7693,100], [7694,68], [7695,100], [7696,68], [7697,100], [7698,68], [7699,100], [7700,69], [7701,101], [7702,69], [7703,101], [7704,69], [7705,101], [7706,69], [7707,101], [7708,69], [7709,101], [7710,70], [7711,102], [7712,71], [7713,103], [7714,72], [7715,104], [7716,72], [7717,104], [7718,72], [7719,104], [7720,72], [7721,104], [7722,72], [7723,104], [7724,73], [7725,105], [7726,73], [7727,105], [7728,75], [7729,107], [7730,75], [7731,107], [7732,75], [7733,107], [7734,76], [7735,108], [7736,76], [7737,108], [7738,76], [7739,108], [7740,76], [7741,108], [7742,77], [7743,109], [7744,77], [7745,109], [7746,77], [7747,109], [7748,78], [7749,110], [7750,78], [7751,110], [7752,78], [7753,110], [7754,78], [7755,110], [7756,79], [7757,111], [7758,79], [7759,111], [7760,79], [7761,111], [7762,79], [7763,111], [7764,80], [7765,112], [7766,80], [7767,112], [7768,82], [7769,114], [7770,82], [7771,114], [7772,82], [7773,114], [7774,82], [7775,114], [7776,83], [7777,115], [7778,83], [7779,115], [7780,83], [7781,115], [7782,83], [7783,115], [7784,83], [7785,115], [7786,84], [7787,116], [7788,84], [7789,116], [7790,84], [7791,116], [7792,84], [7793,116], [7794,85], [7795,117], [7796,85], [7797,117], [7798,85], [7799,117], [7800,85], [7801,117], [7802,85], [7803,117], [7804,86], [7805,118], [7806,86], [7807,118], [7808,87], [7809,119], [7810,87], [7811,119], [7812,87], [7813,119], [7814,87], [7815,119], [7816,87], [7817,119], [7818,88], [7819,120], [7820,88], [7821,120], [7822,89], [7823,121], [7824,90], [7825,122], [7826,90], [7827,122], [7828,90], [7829,122], [7830,104], [7831,116], [7832,119], [7833,121], [7834,97], [7840,65], [7841,97], [7842,65], [7843,97], [7844,65], [7845,97], [7846,65], [7847,97], [7848,65], [7849,97], [7850,65], [7851,97], [7852,65], [7853,97], [7854,65], [7855,97], [7856,65], [7857,97], [7858,65], [7859,97], [7860,65], [7861,97], [7862,65], [7863,97], [7864,69], [7865,101], [7866,69], [7867,101], [7868,69], [7869,101], [7870,69], [7871,101], [7872,69], [7873,101], [7874,69], [7875,101], [7876,69], [7877,101], [7878,69], [7879,101], [7880,73], [7881,105], [7882,73], [7883,105], [7884,79], [7885,111], [7886,79], [7887,111], [7888,79], [7889,111], [7890,79], [7891,111], [7892,79], [7893,111], [7894,79], [7895,111], [7896,79], [7897,111], [7898,79], [7899,111], [7900,79], [7901,111], [7902,79], [7903,111], [7904,79], [7905,111], [7906,79], [7907,111], [7908,85], [7909,117], [7910,85], [7911,117], [7912,85], [7913,117], [7914,85], [7915,117], [7916,85], [7917,117], [7918,85], [7919,117], [7920,85], [7921,117], [7922,89], [7923,121], [7924,89], [7925,121], [7926,89], [7927,121], [7928,89], [7929,121], [8192,32], [8193,[32,32]], [8194,32], [8195,[32,32]], [8196,32], [8197,32], [8198,32], [8199,32], [8200,32], [8201,32], [8202,[]], [8203,[]], [8204,[]], [8205,[]], [8206,[]], [8207,[]], [8208,45], [8209,45], [8210,45], [8211,45], [8212,[45,45]], [8213,[45,45]], [8214,[124,124]], [8215,95], [8216,39], [8217,39], [8218,39], [8219,39], [8220,34], [8221,34], [8222,34], [8223,34], [8224,43], [8225,[43,43]], [8226,111], [8227,62], [8228,46], [8229,[46,46]], [8230,[46,46,46]], [8231,45], [8234,[]], [8235,[]], [8236,[]], [8237,[]], [8238,[]], [8239,32], [8240,[32,48,47,48,48]], [8242,39], [8243,34], [8244,[39,39,39]], [8245,96], [8246,[96,96]], [8247,[96,96,96]], [8249,60], [8250,62], [8252,[33,33]], [8254,45], [8259,45], [8260,47], [8264,[63,33]], [8265,[33,63]], [8266,55], [8304,[94,48],48], [8308,[94,52],52], [8309,[94,53],53], [8310,[94,54],54], [8311,[94,55],55], [8312,[94,56],56], [8313,[94,57],57], [8314,[94,43],43], [8315,[94,45],45], [8316,[94,61],61], [8317,[94,40],40], [8318,[94,41],41], [8319,[94,110],110], [8320,[95,48],48], [8321,[95,49],49], [8322,[95,50],50], [8323,[95,51],51], [8324,[95,52],52], [8325,[95,53],53], [8326,[95,54],54], [8327,[95,55],55], [8328,[95,56],56], [8329,[95,57],57], [8330,[95,43],43], [8331,[95,45],45], [8332,[95,61],61], [8333,[95,40],40], [8334,[95,41],41], [8364,[69,85,82],69], [8448,[97,47,99]], [8449,[97,47,115]], [8450,[67]], [8451,[176,67],67], [8453,[99,47,111]], [8454,[99,47,117]], [8457,[176,70],70], [8461,[72]], [8467,108], [8469,[78]], [8470,[78,186],[78,111]], [8471,[40,80,41]], [8473,[80]], [8474,[81]], [8477,[82]], [8480,[91,83,77,93]], [8481,[84,69,76]], [8482,[91,84,77,93]], [8484,[90]], [8486,937,[111,104,109],79], [8490,75], [8491,197], [8494,101], [8531,[32,49,47,51]], [8532,[32,50,47,51]], [8533,[32,49,47,53]], [8534,[32,50,47,53]], [8535,[32,51,47,53]], [8536,[32,52,47,53]], [8537,[32,49,47,54]], [8538,[32,53,47,54]], [8539,[32,49,47,56]], [8540,[32,51,47,56]], [8541,[32,53,47,56]], [8542,[32,55,47,56]], [8543,[32,49,47]], [8544,73], [8545,[73,73]], [8546,[73,73,73]], [8547,[73,86]], [8548,86], [8549,[86,73]], [8550,[86,73,73]], [8551,[86,73,73,73]], [8552,[73,88]], [8553,88], [8554,[88,73]], [8555,[88,73,73]], [8556,76], [8557,67], [8558,68], [8559,77], [8560,105], [8561,[105,105]], [8562,[105,105,105]], [8563,[105,118]], [8564,118], [8565,[118,105]], [8566,[118,105,105]], [8567,[118,105,105,105]], [8568,[105,120]], [8569,120], [8570,[120,105]], [8571,[120,105,105]], [8572,108], [8573,99], [8574,100], [8575,109], [8592,[60,45]], [8593,94], [8594,[45,62]], [8595,118], [8596,[60,45,62]], [8614,[45,62]], [8618,[45,62]], [8656,[60,61]], [8658,[61,62]], [8660,[60,61,62]], [8722,8211,45], [8725,47], [8726,92], [8727,42], [8728,111], [8729,183], [8734,[105,110,102]], [8739,124], [8741,[124,124]], [8744,118], [8758,58], [8764,126], [8800,[60,62]], [8801,61], [8804,[60,61]], [8805,[62,61]], [8806,[60,61]], [8807,[62,61]], [8810,[60,60]], [8811,[62,62]], [8826,60], [8827,62], [8853,[40,43,41]], [8854,[40,45,41]], [8855,[40,120,41]], [8856,[40,47,41]], [8866,[124,45]], [8867,[45,124]], [8870,[124,45]], [8871,[124,61]], [8872,[124,61]], [8873,[124,124,45]], [8901,183], [8902,42], [8917,35], [8920,[60,60,60]], [8921,[62,62,62]], [8943,[46,46,46]], [9001,60], [9002,62], [9216,[78,85,76]], [9217,[83,79,72]], [9218,[83,84,88]], [9219,[69,84,88]], [9220,[69,79,84]], [9221,[69,78,81]], [9222,[65,67,75]], [9223,[66,69,76]], [9224,[66,83]], [9225,[72,84]], [9226,[76,70]], [9227,[86,84]], [9228,[70,70]], [9229,[67,82]], [9230,[83,79]], [9231,[83,73]], [9232,[68,76,69]], [9233,[68,67,49]], [9234,[68,67,50]], [9235,[68,67,51]], [9236,[68,67,52]], [9237,[78,65,75]], [9238,[83,89,78]], [9239,[69,84,66]], [9240,[67,65,78]], [9241,[69,77]], [9242,[83,85,66]], [9243,[69,83,67]], [9244,[70,83]], [9245,[71,83]], [9246,[82,83]], [9247,[85,83]], [9248,[83,80]], [9249,[68,69,76]], [9251,95], [9252,[78,76]], [9253,[47,47,47]], [9254,63], [9312,[40,49,41],49], [9313,[40,50,41],50], [9314,[40,51,41],51], [9315,[40,52,41],52], [9316,[40,53,41],53], [9317,[40,54,41],54], [9318,[40,55,41],55], [9319,[40,56,41],56], [9320,[40,57,41],57], [9321,[40,49,48,41]], [9322,[40,49,49,41]], [9323,[40,49,50,41]], [9324,[40,49,51,41]], [9325,[40,49,52,41]], [9326,[40,49,53,41]], [9327,[40,49,54,41]], [9328,[40,49,55,41]], [9329,[40,49,56,41]], [9330,[40,49,57,41]], [9331,[40,50,48,41]], [9332,[40,49,41],49], [9333,[40,50,41],50], [9334,[40,51,41],51], [9335,[40,52,41],52], [9336,[40,53,41],53], [9337,[40,54,41],54], [9338,[40,55,41],55], [9339,[40,56,41],56], [9340,[40,57,41],57], [9341,[40,49,48,41]], [9342,[40,49,49,41]], [9343,[40,49,50,41]], [9344,[40,49,51,41]], [9345,[40,49,52,41]], [9346,[40,49,53,41]], [9347,[40,49,54,41]], [9348,[40,49,55,41]], [9349,[40,49,56,41]], [9350,[40,49,57,41]], [9351,[40,50,48,41]], [9352,[49,46],49], [9353,[50,46],50], [9354,[51,46],51], [9355,[52,46],52], [9356,[53,46],53], [9357,[54,46],54], [9358,[55,46],55], [9359,[56,46],56], [9360,[57,46],57], [9361,[49,48,46]], [9362,[49,49,46]], [9363,[49,50,46]], [9364,[49,51,46]], [9365,[49,52,46]], [9366,[49,53,46]], [9367,[49,54,46]], [9368,[49,55,46]], [9369,[49,56,46]], [9370,[49,57,46]], [9371,[50,48,46]], [9372,[40,97,41],97], [9373,[40,98,41],98], [9374,[40,99,41],99], [9375,[40,100,41],100], [9376,[40,101,41],101], [9377,[40,102,41],102], [9378,[40,103,41],103], [9379,[40,104,41],104], [9380,[40,105,41],105], [9381,[40,106,41],106], [9382,[40,107,41],107], [9383,[40,108,41],108], [9384,[40,109,41],109], [9385,[40,110,41],110], [9386,[40,111,41],111], [9387,[40,112,41],112], [9388,[40,113,41],113], [9389,[40,114,41],114], [9390,[40,115,41],115], [9391,[40,116,41],116], [9392,[40,117,41],117], [9393,[40,118,41],118], [9394,[40,119,41],119], [9395,[40,120,41],120], [9396,[40,121,41],121], [9397,[40,122,41],122], [9398,[40,65,41],65], [9399,[40,66,41],66], [9400,[40,67,41],67], [9401,[40,68,41],68], [9402,[40,69,41],69], [9403,[40,70,41],70], [9404,[40,71,41],71], [9405,[40,72,41],72], [9406,[40,73,41],73], [9407,[40,74,41],74], [9408,[40,75,41],75], [9409,[40,76,41],76], [9410,[40,77,41],77], [9411,[40,78,41],78], [9412,[40,79,41],79], [9413,[40,80,41],80], [9414,[40,81,41],81], [9415,[40,82,41],82], [9416,[40,83,41],83], [9417,[40,84,41],84], [9418,[40,85,41],85], [9419,[40,86,41],86], [9420,[40,87,41],87], [9421,[40,88,41],88], [9422,[40,89,41],89], [9423,[40,90,41],90], [9424,[40,97,41],97], [9425,[40,98,41],98], [9426,[40,99,41],99], [9427,[40,100,41],100], [9428,[40,101,41],101], [9429,[40,102,41],102], [9430,[40,103,41],103], [9431,[40,104,41],104], [9432,[40,105,41],105], [9433,[40,106,41],106], [9434,[40,107,41],107], [9435,[40,108,41],108], [9436,[40,109,41],109], [9437,[40,110,41],110], [9438,[40,111,41],111], [9439,[40,112,41],112], [9440,[40,113,41],113], [9441,[40,114,41],114], [9442,[40,115,41],115], [9443,[40,116,41],116], [9444,[40,117,41],117], [9445,[40,118,41],118], [9446,[40,119,41],119], [9447,[40,120,41],120], [9448,[40,121,41],121], [9449,[40,122,41],122], [9450,[40,48,41],48], [9472,45], [9473,61], [9474,124], [9475,124], [9476,45], [9477,61], [9478,124], [9479,124], [9480,45], [9481,61], [9482,124], [9483,124], [9484,43], [9485,43], [9486,43], [9487,43], [9488,43], [9489,43], [9490,43], [9491,43], [9492,43], [9493,43], [9494,43], [9495,43], [9496,43], [9497,43], [9498,43], [9499,43], [9500,43], [9501,43], [9502,43], [9503,43], [9504,43], [9505,43], [9506,43], [9507,43], [9508,43], [9509,43], [9510,43], [9511,43], [9512,43], [9513,43], [9514,43], [9515,43], [9516,43], [9517,43], [9518,43], [9519,43], [9520,43], [9521,43], [9522,43], [9523,43], [9524,43], [9525,43], [9526,43], [9527,43], [9528,43], [9529,43], [9530,43], [9531,43], [9532,43], [9533,43], [9534,43], [9535,43], [9536,43], [9537,43], [9538,43], [9539,43], [9540,43], [9541,43], [9542,43], [9543,43], [9544,43], [9545,43], [9546,43], [9547,43], [9548,45], [9549,61], [9550,124], [9551,124], [9552,61], [9553,124], [9554,43], [9555,43], [9556,43], [9557,43], [9558,43], [9559,43], [9560,43], [9561,43], [9562,43], [9563,43], [9564,43], [9565,43], [9566,43], [9567,43], [9568,43], [9569,43], [9570,43], [9571,43], [9572,43], [9573,43], [9574,43], [9575,43], [9576,43], [9577,43], [9578,43], [9579,43], [9580,43], [9581,43], [9582,43], [9583,43], [9584,43], [9585,47], [9586,92], [9587,88], [9596,45], [9597,124], [9598,45], [9599,124], [9675,111], [9702,111], [9733,42], [9734,42], [9746,88], [9747,88], [9785,[58,45,40]], [9786,[58,45,41]], [9787,[40,45,58]], [9837,98], [9839,35], [9985,[37,60]], [9986,[37,60]], [9987,[37,60]], [9988,[37,60]], [9996,86], [10003,8730], [10004,8730], [10005,120], [10006,120], [10007,88], [10008,88], [10009,43], [10010,43], [10011,43], [10012,43], [10013,43], [10014,43], [10015,43], [10016,43], [10017,42], [10018,43], [10019,43], [10020,43], [10021,43], [10022,43], [10023,43], [10025,42], [10026,42], [10027,42], [10028,42], [10029,42], [10030,42], [10031,42], [10032,42], [10033,42], [10034,42], [10035,42], [10036,42], [10037,42], [10038,42], [10039,42], [10040,42], [10041,42], [10042,42], [10043,42], [10044,42], [10045,42], [10046,42], [10047,42], [10048,42], [10049,42], [10050,42], [10051,42], [10052,42], [10053,42], [10054,42], [10055,42], [10056,42], [10057,42], [10058,42], [10059,42], [10216,60], [10217,62], [10229,[60,45,45]], [10230,[45,45,62]], [10231,[60,45,62]], [10232,[60,61,61]], [10233,[61,61,62]], [10234,[60,61,62]], [64256,[102,102]], [64257,[102,105]], [64258,[102,108]], [64259,[102,102,105]], [64260,[102,102,108]], [64261,[383,116],[115,116]], [64262,[115,116]], [65279,[]], [65533,63] ]); # map to lower case, extracted from UnicodeData.txt field 14 # [get uppercase map by Set(List(lcmap, Reverse)); ] InstallValue(LowercaseUnicodeTable, [ [65,97],[66,98],[67,99],[68,100],[69,101],[70,102], [71,103],[72,104],[73,105],[74,106],[75,107], [76,108],[77,109],[78,110],[79,111],[80,112], [81,113],[82,114],[83,115],[84,116],[85,117], [86,118],[87,119],[88,120],[89,121],[90,122], [192,224],[193,225],[194,226],[195,227],[196,228], [197,229],[198,230],[199,231],[200,232],[201,233], [202,234],[203,235],[204,236],[205,237],[206,238], [207,239],[208,240],[209,241],[210,242],[211,243], [212,244],[213,245],[214,246],[216,248],[217,249], [218,250],[219,251],[220,252],[221,253],[222,254], [256,257],[258,259],[260,261],[262,263],[264,265], [266,267],[268,269],[270,271],[272,273],[274,275], [276,277],[278,279],[280,281],[282,283],[284,285], [286,287],[288,289],[290,291],[292,293],[294,295], [296,297],[298,299],[300,301],[302,303],[304,105], [306,307],[308,309],[310,311],[313,314],[315,316], [317,318],[319,320],[321,322],[323,324],[325,326], [327,328],[330,331],[332,333],[334,335],[336,337], [338,339],[340,341],[342,343],[344,345],[346,347], [348,349],[350,351],[352,353],[354,355],[356,357], [358,359],[360,361],[362,363],[364,365],[366,367], [368,369],[370,371],[372,373],[374,375],[376,255], [377,378],[379,380],[381,382],[385,595],[386,387], [388,389],[390,596],[391,392],[393,598],[394,599], [395,396],[398,477],[399,601],[400,603],[401,402], [403,608],[404,611],[406,617],[407,616],[408,409], [412,623],[413,626],[415,629],[416,417],[418,419], [420,421],[422,640],[423,424],[425,643],[428,429], [430,648],[431,432],[433,650],[434,651],[435,436], [437,438],[439,658],[440,441],[444,445],[452,454], [453,454],[455,457],[456,457],[458,460],[459,460], [461,462],[463,464],[465,466],[467,468],[469,470], [471,472],[473,474],[475,476],[478,479],[480,481], [482,483],[484,485],[486,487],[488,489],[490,491], [492,493],[494,495],[497,499],[498,499],[500,501], [502,405],[503,447],[504,505],[506,507],[508,509], [510,511],[512,513],[514,515],[516,517],[518,519], [520,521],[522,523],[524,525],[526,527],[528,529], [530,531],[532,533],[534,535],[536,537],[538,539], [540,541],[542,543],[544,414],[546,547],[548,549], [550,551],[552,553],[554,555],[556,557],[558,559], [560,561],[562,563],[570,11365],[571,572],[573,410], [574,11366],[577,578],[579,384],[580,649],[581,652], [582,583],[584,585],[586,587],[588,589],[590,591], [902,940],[904,941],[905,942],[906,943],[908,972], [910,973],[911,974],[913,945],[914,946],[915,947], [916,948],[917,949],[918,950],[919,951],[920,952], [921,953],[922,954],[923,955],[924,956],[925,957], [926,958],[927,959],[928,960],[929,961],[931,963], [932,964],[933,965],[934,966],[935,967],[936,968], [937,969],[938,970],[939,971],[984,985],[986,987], [988,989],[990,991],[992,993],[994,995],[996,997], [998,999],[1000,1001],[1002,1003],[1004,1005], [1006,1007],[1012,952],[1015,1016],[1017,1010], [1018,1019],[1021,891],[1022,892],[1023,893], [1024,1104],[1025,1105],[1026,1106],[1027,1107], [1028,1108],[1029,1109],[1030,1110],[1031,1111], [1032,1112],[1033,1113],[1034,1114],[1035,1115], [1036,1116],[1037,1117],[1038,1118],[1039,1119], [1040,1072],[1041,1073],[1042,1074],[1043,1075], [1044,1076],[1045,1077],[1046,1078],[1047,1079], [1048,1080],[1049,1081],[1050,1082],[1051,1083], [1052,1084],[1053,1085],[1054,1086],[1055,1087], [1056,1088],[1057,1089],[1058,1090],[1059,1091], [1060,1092],[1061,1093],[1062,1094],[1063,1095], [1064,1096],[1065,1097],[1066,1098],[1067,1099], [1068,1100],[1069,1101],[1070,1102],[1071,1103], [1120,1121],[1122,1123],[1124,1125],[1126,1127], [1128,1129],[1130,1131],[1132,1133],[1134,1135], [1136,1137],[1138,1139],[1140,1141],[1142,1143], [1144,1145],[1146,1147],[1148,1149],[1150,1151], [1152,1153],[1162,1163],[1164,1165],[1166,1167], [1168,1169],[1170,1171],[1172,1173],[1174,1175], [1176,1177],[1178,1179],[1180,1181],[1182,1183], [1184,1185],[1186,1187],[1188,1189],[1190,1191], [1192,1193],[1194,1195],[1196,1197],[1198,1199], [1200,1201],[1202,1203],[1204,1205],[1206,1207], [1208,1209],[1210,1211],[1212,1213],[1214,1215], [1216,1231],[1217,1218],[1219,1220],[1221,1222], [1223,1224],[1225,1226],[1227,1228],[1229,1230], [1232,1233],[1234,1235],[1236,1237],[1238,1239], [1240,1241],[1242,1243],[1244,1245],[1246,1247], [1248,1249],[1250,1251],[1252,1253],[1254,1255], [1256,1257],[1258,1259],[1260,1261],[1262,1263], [1264,1265],[1266,1267],[1268,1269],[1270,1271], [1272,1273],[1274,1275],[1276,1277],[1278,1279], [1280,1281],[1282,1283],[1284,1285],[1286,1287], [1288,1289],[1290,1291],[1292,1293],[1294,1295], [1296,1297],[1298,1299],[1329,1377],[1330,1378], [1331,1379],[1332,1380],[1333,1381],[1334,1382], [1335,1383],[1336,1384],[1337,1385],[1338,1386], [1339,1387],[1340,1388],[1341,1389],[1342,1390], [1343,1391],[1344,1392],[1345,1393],[1346,1394], [1347,1395],[1348,1396],[1349,1397],[1350,1398], [1351,1399],[1352,1400],[1353,1401],[1354,1402], [1355,1403],[1356,1404],[1357,1405],[1358,1406], [1359,1407],[1360,1408],[1361,1409],[1362,1410], [1363,1411],[1364,1412],[1365,1413],[1366,1414], [4256,11520],[4257,11521],[4258,11522],[4259,11523], [4260,11524],[4261,11525],[4262,11526],[4263,11527], [4264,11528],[4265,11529],[4266,11530],[4267,11531], [4268,11532],[4269,11533],[4270,11534],[4271,11535], [4272,11536],[4273,11537],[4274,11538],[4275,11539], [4276,11540],[4277,11541],[4278,11542],[4279,11543], [4280,11544],[4281,11545],[4282,11546],[4283,11547], [4284,11548],[4285,11549],[4286,11550],[4287,11551], [4288,11552],[4289,11553],[4290,11554],[4291,11555], [4292,11556],[4293,11557],[7680,7681],[7682,7683], [7684,7685],[7686,7687],[7688,7689],[7690,7691], [7692,7693],[7694,7695],[7696,7697],[7698,7699], [7700,7701],[7702,7703],[7704,7705],[7706,7707], [7708,7709],[7710,7711],[7712,7713],[7714,7715], [7716,7717],[7718,7719],[7720,7721],[7722,7723], [7724,7725],[7726,7727],[7728,7729],[7730,7731], [7732,7733],[7734,7735],[7736,7737],[7738,7739], [7740,7741],[7742,7743],[7744,7745],[7746,7747], [7748,7749],[7750,7751],[7752,7753],[7754,7755], [7756,7757],[7758,7759],[7760,7761],[7762,7763], [7764,7765],[7766,7767],[7768,7769],[7770,7771], [7772,7773],[7774,7775],[7776,7777],[7778,7779], [7780,7781],[7782,7783],[7784,7785],[7786,7787], [7788,7789],[7790,7791],[7792,7793],[7794,7795], [7796,7797],[7798,7799],[7800,7801],[7802,7803], [7804,7805],[7806,7807],[7808,7809],[7810,7811], [7812,7813],[7814,7815],[7816,7817],[7818,7819], [7820,7821],[7822,7823],[7824,7825],[7826,7827], [7828,7829],[7840,7841],[7842,7843],[7844,7845], [7846,7847],[7848,7849],[7850,7851],[7852,7853], [7854,7855],[7856,7857],[7858,7859],[7860,7861], [7862,7863],[7864,7865],[7866,7867],[7868,7869], [7870,7871],[7872,7873],[7874,7875],[7876,7877], [7878,7879],[7880,7881],[7882,7883],[7884,7885], [7886,7887],[7888,7889],[7890,7891],[7892,7893], [7894,7895],[7896,7897],[7898,7899],[7900,7901], [7902,7903],[7904,7905],[7906,7907],[7908,7909], [7910,7911],[7912,7913],[7914,7915],[7916,7917], [7918,7919],[7920,7921],[7922,7923],[7924,7925], [7926,7927],[7928,7929],[7944,7936],[7945,7937], [7946,7938],[7947,7939],[7948,7940],[7949,7941], [7950,7942],[7951,7943],[7960,7952],[7961,7953], [7962,7954],[7963,7955],[7964,7956],[7965,7957], [7976,7968],[7977,7969],[7978,7970],[7979,7971], [7980,7972],[7981,7973],[7982,7974],[7983,7975], [7992,7984],[7993,7985],[7994,7986],[7995,7987], [7996,7988],[7997,7989],[7998,7990],[7999,7991], [8008,8000],[8009,8001],[8010,8002],[8011,8003], [8012,8004],[8013,8005],[8025,8017],[8027,8019], [8029,8021],[8031,8023],[8040,8032],[8041,8033], [8042,8034],[8043,8035],[8044,8036],[8045,8037], [8046,8038],[8047,8039],[8072,8064],[8073,8065], [8074,8066],[8075,8067],[8076,8068],[8077,8069], [8078,8070],[8079,8071],[8088,8080],[8089,8081], [8090,8082],[8091,8083],[8092,8084],[8093,8085], [8094,8086],[8095,8087],[8104,8096],[8105,8097], [8106,8098],[8107,8099],[8108,8100],[8109,8101], [8110,8102],[8111,8103],[8120,8112],[8121,8113], [8122,8048],[8123,8049],[8124,8115],[8136,8050], [8137,8051],[8138,8052],[8139,8053],[8140,8131], [8152,8144],[8153,8145],[8154,8054],[8155,8055], [8168,8160],[8169,8161],[8170,8058],[8171,8059], [8172,8165],[8184,8056],[8185,8057],[8186,8060], [8187,8061],[8188,8179],[8486,969],[8490,107], [8491,229],[8498,8526],[8544,8560],[8545,8561], [8546,8562],[8547,8563],[8548,8564],[8549,8565], [8550,8566],[8551,8567],[8552,8568],[8553,8569], [8554,8570],[8555,8571],[8556,8572],[8557,8573], [8558,8574],[8559,8575],[8579,8580],[9398,9424], [9399,9425],[9400,9426],[9401,9427],[9402,9428], [9403,9429],[9404,9430],[9405,9431],[9406,9432], [9407,9433],[9408,9434],[9409,9435],[9410,9436], [9411,9437],[9412,9438],[9413,9439],[9414,9440], [9415,9441],[9416,9442],[9417,9443],[9418,9444], [9419,9445],[9420,9446],[9421,9447],[9422,9448], [9423,9449],[11264,11312],[11265,11313],[11266,11314], [11267,11315],[11268,11316],[11269,11317],[11270,11318], [11271,11319],[11272,11320],[11273,11321],[11274,11322], [11275,11323],[11276,11324],[11277,11325],[11278,11326], [11279,11327],[11280,11328],[11281,11329],[11282,11330], [11283,11331],[11284,11332],[11285,11333],[11286,11334], [11287,11335],[11288,11336],[11289,11337],[11290,11338], [11291,11339],[11292,11340],[11293,11341],[11294,11342], [11295,11343],[11296,11344],[11297,11345],[11298,11346], [11299,11347],[11300,11348],[11301,11349],[11302,11350], [11303,11351],[11304,11352],[11305,11353],[11306,11354], [11307,11355],[11308,11356],[11309,11357],[11310,11358], [11360,11361],[11362,619],[11363,7549],[11364,637], [11367,11368],[11369,11370],[11371,11372],[11381,11382], [11392,11393],[11394,11395],[11396,11397],[11398,11399], [11400,11401],[11402,11403],[11404,11405],[11406,11407], [11408,11409],[11410,11411],[11412,11413],[11414,11415], [11416,11417],[11418,11419],[11420,11421],[11422,11423], [11424,11425],[11426,11427],[11428,11429],[11430,11431], [11432,11433],[11434,11435],[11436,11437],[11438,11439], [11440,11441],[11442,11443],[11444,11445],[11446,11447], [11448,11449],[11450,11451],[11452,11453],[11454,11455], [11456,11457],[11458,11459],[11460,11461],[11462,11463], [11464,11465],[11466,11467],[11468,11469],[11470,11471], [11472,11473],[11474,11475],[11476,11477],[11478,11479], [11480,11481],[11482,11483],[11484,11485],[11486,11487], [11488,11489],[11490,11491],[65313,65345],[65314,65346], [65315,65347],[65316,65348],[65317,65349],[65318,65350], [65319,65351],[65320,65352],[65321,65353],[65322,65354], [65323,65355],[65324,65356],[65325,65357],[65326,65358], [65327,65359],[65328,65360],[65329,65361],[65330,65362], [65331,65363],[65332,65364],[65333,65365],[65334,65366], [65335,65367],[65336,65368],[65337,65369],[65338,65370], [66560,66600],[66561,66601],[66562,66602],[66563,66603], [66564,66604],[66565,66605],[66566,66606],[66567,66607], [66568,66608],[66569,66609],[66570,66610],[66571,66611], [66572,66612],[66573,66613],[66574,66614],[66575,66615], [66576,66616],[66577,66617],[66578,66618],[66579,66619], [66580,66620],[66581,66621],[66582,66622],[66583,66623], [66584,66624],[66585,66625],[66586,66626],[66587,66627], [66588,66628],[66589,66629],[66590,66630],[66591,66631], [66592,66632],[66593,66633],[66594,66634],[66595,66635], [66596,66636],[66597,66637],[66598,66638],[66599,66639] ]); MakeImmutable(LowercaseUnicodeTable); IsSet(LowercaseUnicodeTable); # map to character width on terminals # got from glibc wcwidth in UTF-8 locale, but ignoring the ranges where # -1 (invalid/control) character) is returned. # entry [pos, w] means that unicode character p has width w when pos <= p # < the pos part of the next entry InstallValue(WidthUnicodeTable, [ [0,0], [32,1], [173,0], [174,1], [768,0], [884,1], [1155,0], [1162,1], [1425,0], [1470,1], [1471,0], [1472,1], [1473,0], [1475,1], [1476,0], [1488,1], [1611,0], [1632,1], [1648,0], [1649,1], [1750,0], [1765,1], [1767,0], [1769,1], [1770,0], [1776,1], [1807,0], [1808,1], [1809,0], [1810,1], [1840,0], [1920,1], [1958,0], [1969,1], [2305,0], [2307,1], [2364,0], [2365,1], [2369,0], [2377,1], [2381,0], [2384,1], [2385,0], [2392,1], [2402,0], [2404,1], [2433,0], [2434,1], [2492,0], [2494,1], [2497,0], [2503,1], [2509,0], [2519,1], [2530,0], [2534,1], [2562,0], [2565,1], [2620,0], [2622,1], [2625,0], [2649,1], [2672,0], [2674,1], [2689,0], [2691,1], [2748,0], [2749,1], [2753,0], [2761,1], [2765,0], [2768,1], [2817,0], [2818,1], [2876,0], [2877,1], [2879,0], [2880,1], [2881,0], [2887,1], [2893,0], [2903,1], [2946,0], [2947,1], [3008,0], [3009,1], [3021,0], [3031,1], [3134,0], [3137,1], [3142,0], [3168,1], [3276,0], [3285,1], [3393,0], [3398,1], [3405,0], [3415,1], [3530,0], [3535,1], [3538,0], [3544,1], [3633,0], [3634,1], [3636,0], [3647,1], [3655,0], [3663,1], [3761,0], [3762,1], [3764,0], [3773,1], [3784,0], [3792,1], [3864,0], [3866,1], [3893,0], [3894,1], [3895,0], [3896,1], [3897,0], [3898,1], [3953,0], [3967,1], [3968,0], [3973,1], [3974,0], [3976,1], [3984,0], [4030,1], [4038,0], [4039,1], [4141,0], [4145,1], [4146,0], [4152,1], [4153,0], [4160,1], [4184,0], [4256,1], [4352,2], [4448,0], [4608,1], [5906,0], [5920,1], [5938,0], [5941,1], [5970,0], [5984,1], [6002,0], [6016,1], [6068,0], [6070,1], [6071,0], [6078,1], [6086,0], [6087,1], [6089,0], [6100,1], [6155,0], [6158,1], [6313,0], [7680,1], [8203,0], [8208,1], [8234,0], [8239,1], [8288,0], [8304,1], [8400,0], [8448,1], [9001,2], [9003,1], [11904,2], [12330,0], [12336,2], [12351,1], [12353,2], [12441,0], [12443,2], [57344,1], [63744,2], [64256,1], [64286,0], [64287,1], [65024,0], [65072,2], [65136,1], [65279,0], [65281,2], [65377,1], [65504,2], [65512,1], [65529,0], [65532,1], [119143,0], [119146,1], [119155,0], [119171,1], [119173,0], [119180,1], [119210,0], [119214,1], [131072,2], [917505,0], [983040,1], ]); MakeImmutable(WidthUnicodeTable); IsSet(WidthUnicodeTable); GAPDoc-1.5.1/lib/BibTeX.gi0000644000175000017500000012316012026346064013413 0ustar billbill############################################################################# ## #W BibTeX.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files BibTeX.g{d,i} contain a parser for BibTeX files and some ## functions for printing BibTeX entries in different formats. ## ## normalize author/editor name lists: last-name, initial(s) of first ## name(s) and ... ## see Lamport: LaTeX App.B 1.2 InstallGlobalFunction(NormalizedNameAndKey, function(str) local nbsp, new, pp, p, a, i, names, norm, keyshort, keylong, res; # do almost nothing if already list of strings (e.g., from BibXMLext tools if IsString(str) then # first normalize white space inside braces { ... } and change # spaces to non-breakable spaces nbsp := CHAR_INT(160); new := ""; pp := 0; p := Position(str, '{'); while p <> fail do Append(new, str{[pp+1..p-1]}); pp := PositionMatchingDelimiter(str, "{}", p); a := NormalizedWhitespace(str{[p..pp]}); for i in [1..Length(a)] do if a[i] = ' ' then a[i] := nbsp; fi; od; Append(new, a); p := Position(str, '{', pp); od; if Length(new)>0 then str := Concatenation(new, str{[pp+1..Length(str)]}); fi; # split into names: names := []; pp := 0; p := PositionSublist(str, "and"); while p <> fail do # "and" is only delimiter if surrounded by white space if not (str[p-1] in WHITESPACE and Length(str)>p+2 and str[p+3] in WHITESPACE) then p := PositionSublist(str, "and", p); else Add(names, str{[pp+1..p-2]}); pp := p+3; p := PositionSublist(str, "and", pp); fi; od; Add(names, str{[pp+1..Length(str)]}); # normalize a single name norm := function(str) local n, i, lnam, j, fnam, fnamfull; # special case "et. al." if str="others" then return ["others", "", ""]; fi; # first some normalization on the string RemoveCharacters(str,"[]"); str := SubstitutionSublist(str, "\\~", "BSLTILDE"); str := SubstitutionSublist(str, "~", " "); str := SubstitutionSublist(str, "BSLTILDE", "\\~"); str := SubstitutionSublist(str, ".", ". "); StripBeginEnd(str, WHITESPACE); n := SplitString(str, "", WHITESPACE); # check if in "lastname, firstname" notation # find last "," i := Length(n); while i>0 and n[i]<>"," and n[i][Length(n[i])] <> ',' do i := i-1; od; if i>0 then # last name lnam := ""; for j in [1..i] do Append(lnam, n[j]); if j < i then Add(lnam, ' '); fi; lnam := Filtered(lnam, x-> x<>','); od; # first name initials - wrong for UTF-8! fnam := ""; for j in [i+1..Length(n)] do Add(fnam, First(n[j], x-> not x in WHITESPACE and not x in "-.{}\\\"\'\`")); Append(fnam, ". "); od; fnamfull := JoinStringsWithSeparator(n{[i+1..Length(n)]}, " "); else # last name is last including words not starting with # capital letters i := Length(n); while i>1 and First(n[i-1], a-> a in LETTERS) in SMALLLETTERS do i := i-1; od; # last name lnam := ""; for j in [i..Length(n)] do Append(lnam, n[j]); if j < Length(n) then Add(lnam, ' '); fi; od; # first name capitals fnam := ""; for j in [1..i-1] do Add(fnam, First(n[j], x-> x in LETTERS)); Append(fnam, ". "); od; fnamfull := JoinStringsWithSeparator(n{[1..i-1]}, " "); fi; while Length(fnam) > 0 and fnam[Length(fnam)] in WHITESPACE do fnam := fnam{[1..Length(fnam)-1]}; od; return [lnam, fnam, fnamfull]; end; names := List(names, norm); else names := str; fi; keyshort := ""; keylong := ""; res := ""; for a in names do if Length(res)>0 then Append(res, " and "); fi; Append(res, a[1]); Append(res, ", "); Append(res, a[2]); if a[1] = "others" then Add(keyshort, '+'); else p := 1; while p <= Length(a[1]) and not a[1][p] in CAPITALLETTERS do p := p+1; od; if p > Length(a[1]) then p := 1; fi; if a[1][p] in LETTERS then Add(keyshort, a[1][p]); else Add(keyshort, 'X'); fi; Append(keylong, STRING_LOWER(Filtered(a[1]{[p..Length(a[1])]}, x-> x in LETTERS))); fi; od; if Length(keyshort)>3 then keyshort := keyshort{[1,2]}; Add(keyshort, '+'); fi; return [res, keyshort, keylong, names]; end); ## <#GAPDoc Label="ParseBibFiles"> ## ## ## ## list [list of bib-records, list of abbrevs, list of ## expansions] ## ## The first function parses the files bibfile1 and so on (if a file ## does not ## exist the extension .bib is appended) in &BibTeX; format ## and returns a list as follows: [entries, strings, texts]. ## Here entries is a list of records, one record for each ## reference contained in bibfile. Then strings is ## a list of abbreviations defined by @string-entries in ## bibfile and texts is a list which contains in the ## corresponding position the full text for such an abbreviation. ##

        ## The second function does the same, but the input is given as &GAP; strings ## str1 and so on.

        ## ## The records in entries store key-value pairs of a &BibTeX; ## reference in the form rec(key1 = value1, ...). The names ## of the keys are converted to lower case. The type of the ## reference (i.e., book, article, ...) and the citation key are ## stored as components .Type and .Label. The records ## also have a .From field that says that the data are read ## from a &BibTeX; source.

        ## ## As an example consider the following &BibTeX; file. ## ##

        ## @string{ j = "Important Journal" } ## @article{ AB2000, Author= "Fritz A. First and Sec, X. Y.", ## TITLE="Short", journal = j, year = 2000 } ## ## ## ## gap> bib := ParseBibFiles("doc/test.bib"); ## [ [ rec( From := rec( BibTeX := true ), Label := "AB2000", ## Type := "article", author := "Fritz A. First and Sec, X. Y." ## , journal := "Important Journal", title := "Short", ## year := "2000" ) ], [ "j" ], [ "Important Journal" ] ] ## ##
        ##
        ## <#/GAPDoc> ## InstallGlobalFunction(ParseBibFiles, function(arg) local s, entries, stringlabels, strings, str, file; s := Filtered(arg, x-> IsList(x) and not IsString(x)); if Length(s) > 0 then entries := s[1][1]; stringlabels := s[1][2]; strings := s[1][3]; arg := Filtered(arg, IsString); else entries := []; stringlabels := []; strings := []; fi; for file in arg do str := StringFile(file); if str=fail then str := StringFile(Concatenation(file, ".bib")); fi; if str=fail then Info(InfoBibTools, 1, "#W WARNING: Cannot find bib-file ", file, "[.bib]\n"); return fail; fi; ParseBibStrings(str, [entries, stringlabels, strings]); od; return [entries, stringlabels, strings]; end); InstallGlobalFunction(ParseBibStrings, function(arg) local s, entries, stringlabels, strings, p, r, pb, Type, ende, comp, pos, str; s := Filtered(arg, x-> IsList(x) and not IsString(x)); if Length(s) > 0 then entries := s[1][1]; stringlabels := s[1][2]; strings := s[1][3]; arg := Filtered(arg, IsString); else entries := []; stringlabels := []; strings := []; fi; for str in arg do # find entries p := Position(str, '@'); while p<>fail do r := rec(); # type pb := Position(str, '{', p); s := LowercaseString(StripBeginEnd(str{[p+1..pb-1]}, WHITESPACE)); p := pb; if s = "string" then # a string is normalized and stored for later substitutions pb := Position(str, '=', p); Add(stringlabels, LowercaseString(StripBeginEnd(str{[p+1..pb-1]}, WHITESPACE))); p := pb; pb := PositionMatchingDelimiter(str, "{}", p); s := StripBeginEnd(str{[p+1..pb-1]}, WHITESPACE); if (s[1]='\"' and s[Length(s)]='\"') or (s[1]='{' and s[Length(s)]='}') then s := s{[2..Length(s)-1]}; fi; Add(strings, s); p := pb; else # type and label of entry r := rec(From := rec(BibTeX := true), Type := s); # end of bibtex entry, for better recovery from errors ende := PositionMatchingDelimiter(str, "{}", p); pb := Position(str, ',', p); if not IsInt(pb) or pb > ende then # doesn't seem to be a correct entry, ignore p := Position(str, '@', ende); continue; fi; r.Label := StripBeginEnd(str{[p+1..pb-1]}, WHITESPACE); p := pb; # get the components pb := Position(str, '=', p); while pb<>fail and pb < ende do comp := LowercaseString(StripBeginEnd(str{[p+1..pb-1]}, Concatenation(",", WHITESPACE))); pb := pb+1; while str[pb] in WHITESPACE do pb := pb+1; od; p := pb; if str[p] = '\"' then pb := Position(str, '\"', p); # if double quote is escaped, then go to next one while str[pb-1]='\\' do pb := Position(str, '\"', pb); od; r.(comp) := str{[p+1..pb-1]}; elif str[p] = '{' then pb := PositionMatchingDelimiter(str, "{}", p); r.(comp) := str{[p+1..pb-1]}; else pb := p+1; while (not str[pb] in WHITESPACE) and str[pb] <> ',' and str[pb] <> '}' do pb := pb+1; od; s := str{[p..pb-1]}; # number if Int(s)<>fail then r.(comp) := s; else # abbrev string, look up and substitute s := LowercaseString(s); pos := Position(stringlabels, s); if pos=fail then r.(comp) := Concatenation("STRING-NOT-KNOWN: ", s); else r.(comp) := strings[pos]; fi; fi; fi; p := pb+1; pb := Position(str, '=', p); od; Add(entries, r); fi; p := Position(str, '@', p); od; od; return [entries, stringlabels, strings]; end); ## <#GAPDoc Label="NormalizeNameAndKey"> ## ## ## list of strings and names as lists ## ## nothing ## ## The argument namestr must be a string describing an author or a list ## of authors as described in the &BibTeX; documentation in . The function returns a list of the form [ normalized name string, short key, long ## key, names as lists]. The first entry is a normalized form ## of the input where names are written as lastname, first name ## initials. The second and third entry are the name parts of a short and ## long key for the bibliography entry, formed from the (initials of) last ## names. The fourth entry is a list of lists, one for each name, where a ## name is described by three strings for the last name, the first name ## initials and the first name(s) as given in the input.

        ## ## Note that the determination of the initials is limited to names where the ## first letter is described by a single character (and does not contain some ## markup, say for accents).

        ## ## The function gets as argument r ## a record for a bibliography entry as returned by . It substitutes .author and .editor fields of r by ## their normalized form, the original versions are stored in fields ## .authororig and .editororig.

        ## ## Furthermore a short and a long citation key is generated and stored ## in components .printedkey (only if no .key is already ## bound) and .keylong.

        ## ## We continue the example from . ## ## ## gap> bib := ParseBibFiles("doc/test.bib");; ## gap> NormalizedNameAndKey(bib[1][1].author); ## [ "First, F. A. and Sec, X. Y.", "FS", "firstsec", ## [ [ "First", "F. A.", "Fritz A." ], [ "Sec", "X. Y.", "X. Y." ] ] ] ## gap> NormalizeNameAndKey(bib[1][1]); ## gap> bib[1][1]; ## rec( From := rec( BibTeX := true ), Label := "AB2000", ## Type := "article", author := "First, F. A. and Sec, X. Y.", ## authororig := "Fritz A. First and Sec, X. Y.", ## journal := "Important Journal", keylong := "firstsec2000", ## printedkey := "FS00", title := "Short", year := "2000" ) ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(NormalizeNameAndKey, function(b) local yy, y, names, nn; if IsBound(b.year) then if IsInt(b.year) then yy := String(b.year); y := String(b.year mod 100); else yy := b.year; y := b.year{[Length(b.year)-1, Length(b.year)]}; fi; else yy := ""; y := ""; fi; for names in ["author", "editor"] do if IsBound(b.(names)) then nn := NormalizedNameAndKey(b.(names)); if nn[1] <> b.(names) then b.(Concatenation(names, "orig")) := b.(names); b.(names) := nn[1]; fi; if not IsBound(b.key) then b.printedkey := Concatenation(nn[2], y); fi; if not IsBound(b.keylong) then b.keylong := Concatenation(nn[3], yy); fi; fi; od; if not IsBound(b.keylong) then b.keylong := "xxx"; fi; if not (IsBound(b.key) or IsBound(b.printedkey)) then b.printedkey := "xxx"; fi; end); # small utility BindGlobal("AndToCommaNames", function(str) local n, p, i; str := NormalizedWhitespace(str); n := 0; p := PositionSublist(str, " and "); while p <> fail do n := n+1; p := PositionSublist(str, " and ", p); od; for i in [1..n-1] do str := SubstitutionSublist(str, " and ", ", ", false); od; if n > 1 then str := SubstitutionSublist(str, " and ", ", and ", false); fi; return str; end); # print out a bibtex entry, the ordering of fields is normalized and # type and field names are in lowercase, also some formatting is done # arg: entry[, abbrevs, texts] where abbrevs and texts are lists # of same length abbrevs[i] is string macro for texts[i] InstallGlobalFunction(StringBibAsBib, function(arg) local r, abbrevs, texts, res, ind, fieldlist, pos, lines, comp; # scan arguments r := arg[1]; if Length(arg)>2 then abbrevs := arg[2]; texts := arg[3]; else abbrevs := []; texts := []; fi; res := ""; if not IsBound(r.Label) then Info(InfoBibTools, 1, "#W WARNING: no .Label in Bib-record"); Info(InfoBibTools, 2, ":\n", r); Info(InfoBibTools, 1, "\n"); return fail; fi; ind := RepeatedString(' ', 22); fieldlist := [ "author", "editor", "booktitle", "title", "journal", "month", "organization", "institution", "publisher", "school", "edition", "series", "volume", "number", "address", "year", "pages", "chapter", "crossref", "note", "notes", "howpublished", "key", "coden", "fjournal", "isbn", "issn", "location", "mrclass", "mrnumber", "mrreviewer", "organisation", "reviews", "source", "url", "keywords" ]; Append(res, Concatenation("@", r.Type, "{ ", r.Label)); for comp in Concatenation(fieldlist, Difference(NamesOfComponents(r), Concatenation(fieldlist, ["From", "Type", "Label","authorAsList", "editorAsList"]) )) do if IsBound(r.(comp)) then Append(res, Concatenation(",\n ", comp, " = ", ListWithIdenticalEntries(16-Length(comp), ' '))); pos := Position(texts, r.(comp)); if pos <> fail then Append(res, abbrevs[pos]); else Append(res, "{"); lines := FormatParagraph(r.(comp), SizeScreen()[1]-26, "both", [ind, ""]); Append(res, lines{[Length(ind)+1..Length(lines)-1]}); Append(res, "}"); fi; fi; od; Append(res, "\n}\n"); return res; end); InstallGlobalFunction(PrintBibAsBib, function(arg) PrintFormattedString(CallFuncList(StringBibAsBib, arg)); end); ## <#GAPDoc Label="WriteBibFile"> ## ## ## nothing ## ## This is the converse of . Here ## bib either must have a format as list of three lists ## as it is returned by . Or bib can be a record as returned ## by . ## A &BibTeX; file bibfile is written ## and the entries are formatted in a uniform way. All given ## abbreviations are used while writing this file.

        ## ## We continue the example from . ## The command ## ## ## gap> WriteBibFile("nicer.bib", bib); ## ## ## produces a file nicer.bib as follows: ## ##

        ## @string{j = "Important Journal" } ## ## @article{ AB2000, ## author = {First, F. A. and Sec, X. Y.}, ## title = {Short}, ## journal = j, ## year = {2000}, ## authororig = {Fritz A. First and Sec, X. Y.}, ## keylong = {firstsec2000}, ## printedkey = {FS00} ## } ## ##
        ##
        ## <#/GAPDoc> ## InstallGlobalFunction(WriteBibFile, function(file, bib) local p, b3, a, b, pos, f; if IsRecord(bib) and IsBound(bib.entries) and IsBound(bib.strings) then b := bib; bib := []; bib[1] := List(b.entries, a-> RecBibXMLEntry(a, "BibTeX", b.strings)); bib[2] := List(b.strings, a-> a[1]); bib[3] := List(b.strings, a-> a[2]); fi; # collect abbrevs p := []; SortParallel(bib[3], bib[2]); b3 := Immutable(bib[3]); IsSet(b3); for a in bib[1] do for b in NamesOfComponents(a) do pos := Position(b3, a.(b)); if pos <> fail then Add(p, pos); fi; od; od; p := Set(p); f := function() local i, a; Print("\n\n"); # the `string's for i in p do Print("@string{", bib[2][i], " = \"", b3[i], "\" }\n"); od; Print("\n\n"); for a in bib[1] do PrintBibAsBib(a, bib[2], b3); od; end; PrintTo1(file, f); end); # a utility for translating LaTeX macros for non ascii characters into # HTML entities; also removing {}'s, and "\-" hyphenation hints. BindGlobal("LaTeXToHTMLString", function(str) local trans_bs, trans_qq, i, pos; # macros for accents starting with '\', add new entries - somehow more # frequent ones first - as they become necessary trans_bs := [ ["\\\"a","ä"], ["\\\"o","ö"], ["\\\"u","ü"], ["\\\"{a}","ä"], ["\\\"{o}","ö"], ["\\\"{u}","ü"], ["\\\"{s}","ß"], ["\\\"s","ß"], ["\\3","ß"], ["\\ss","ß"], ["\\\"A","Ä"], ["\\\"O","Ö"], ["\\\"U","Ü"], ["\\'e","é"], ["\\`e","è"], ["\\'E","É"], ["\\`E","È"], ["\\'a","á"], ["\\`a","à"], ["\\c{c}", "ç"], ["\\c c", "ç"], # long Hungarian umlaut, substituted by unicode entity # (see http://www.unicode.org/charts/) ["\\H{o}", "ő"], ["\\H o", "ő"], ["\\'A","Á"], ["\\'I","Í"], ["\\'O","Ó"], ["\\'U","Ú"], ["\\'i","í"], ["\\'o","ó"], ["\\'u","ú"], ["\\`A","À"], ["\\`I","Ì"], ["\\`O","Ò"], ["\\`U","Ù"], ["\\`i","ì"], ["\\`o","ò"], ["\\`u","ù"] ]; # and some starting with '"' from 'german' styles trans_qq := [ ["\"a","ä"], ["\"o","ö"], ["\"u","ü"], ["\"s","ß"], ["\"A","Ä"], ["\"O","Ö"], ["\"U","Ü"] ]; i := 0; pos := Position(str, '\\'); while pos <> fail and i < Length(trans_bs) do i := i + 1; str := ReplacedString(str, trans_bs[i][1], trans_bs[i][2]); pos := Position(str, '\\'); od; i := 0; pos := Position(str, '\"'); while pos <> fail and i < Length(trans_qq) do i := i + 1; str := ReplacedString(str, trans_qq[i][1], trans_qq[i][2]); pos := Position(str, '\"'); od; # throw away {}'s and "\-"'s if Position(str, '{') <> fail then str := Filtered(str, c-> c <> '{' and c <> '}'); fi; str := ReplacedString(str, "\\-", ""); return str; end); ## arg: r[, escape] (with escape = false it is assumed that entries are ## already HTML) InstallGlobalFunction(StringBibAsHTML, function(arg) local r, i, str, res, esc, key, mrnumber, booklike; r := arg[1]; if Length(arg)=2 then esc := arg[2]; else if IsBound(r.From) and IsBound(r.From.BibXML) and r.From.BibXML = true then esc := false; else esc := true; fi; fi; if not IsBound(r.Label) then Info(InfoBibTools, 1, "#W WARNING: no .Label in Bib-record"); Info(InfoBibTools, 2, ":\n", r); Info(InfoBibTools, 1, "\n"); return fail; fi; # some details are set differently for book-like references if r.Type in [ "book", "booklet", "manual", "techreport", "mastersthesis", "phdthesis", "proceedings" ] then booklike := true; else booklike := false; fi; res := ""; # remove SGML markup characters in entries and translate # LaTeX macros for accented characters to HTML, remove {}'s if esc = true then r := ShallowCopy(r); for i in NamesOfComponents(r) do if IsString(r.(i)) then str := ""; GAPDoc2HTMLProcs.PCDATAFILTER(rec(content := r.(i)), str); if str <> r.(i) then r.(i) := str; fi; r.(i) := LaTeXToHTMLString(r.(i)); if i in ["title", "subtitle", "booktitle"] then r.(i) := Filtered(r.(i), x -> not x in "{}"); fi; fi; od; fi; if IsBound(r.key) then key := r.key; elif IsBound(r.printedkey) then key := r.printedkey; else key := r.Label; fi; if IsBound(r.mrnumber) then mrnumber:= r.mrnumber; if ' ' in mrnumber then mrnumber:= mrnumber{ [ 1 .. Position( mrnumber, ' ' ) - 1 ] }; fi; Append(res, Concatenation( "

        \n[", key, "] ")); else Append(res, Concatenation("

        \n[", key, "] ")); fi; # standard BibTeX-styles typeset a type if not given if r.Type = "phdthesis" and not IsBound(r.type) then r := ShallowCopy(r); r.type := "Ph.D. thesis"; elif r.Type = "mastersthesis" and not IsBound(r.type) then r := ShallowCopy(r); r.type := "Master's thesis"; fi; # we assume with the "," delimiters that at least one of .author, # .editor or .title exist if IsBound(r.author) then Append(res, Concatenation("", AndToCommaNames(r.author),"")); fi; if IsBound(r.editor) then if PositionSublist( r.editor, " and " ) = fail then Append(res, Concatenation(" (", AndToCommaNames(r.editor), ", Ed.)")); else Append(res, Concatenation(" (", AndToCommaNames(r.editor), ", Eds.)")); fi; fi; if IsBound(r.title) then if ForAny(["author", "editor"], a-> IsBound(r.(a))) then Add(res, ','); fi; Append(res, Concatenation("\n ", r.title, "")); fi; if IsBound(r.booktitle) then Append( res, ",\n " ); if r.Type in ["inproceedings", "incollection"] then Append(res, " in "); fi; Append(res, Concatenation(" ", r.booktitle, "")); fi; if IsBound(r.subtitle) then Append(res, Concatenation("\n –", r.subtitle, "")); fi; if IsBound(r.journal) then Append(res, Concatenation(",\n ", r.journal, "")); fi; if IsBound(r.type) then Append(res, Concatenation(",\n ", r.type, "")); fi; if IsBound(r.organization) then Append(res, Concatenation(",\n ", r.organization, "")); fi; if IsBound(r.institution) then Append(res, Concatenation(",\n ", r.institution, "")); fi; if IsBound(r.publisher) then Append(res, Concatenation(",\n ", r.publisher, "")); fi; if IsBound(r.school) then Append(res, Concatenation(",\n ", r.school, "")); fi; if IsBound(r.edition) then Append(res, Concatenation(",\n ", r.edition, " edition", "")); fi; if IsBound(r.series) then Append(res, Concatenation(",\n ", r.series, "")); fi; if IsBound(r.volume) then Append(res, Concatenation(",\n ", r.volume, "")); fi; if IsBound(r.number) then Append(res, Concatenation(" (", r.number, ")")); fi; if IsBound(r.address) then Append(res, Concatenation(",\n ", r.address, "")); fi; if IsBound(r.year) then Append(res, Concatenation("\n (", r.year, ")")); fi; if IsBound(r.pages) then if booklike then Append(res, Concatenation(",\n ", r.pages, " pages")); else Append(res, Concatenation(",\n ", r.pages, "")); fi; fi; if IsBound(r.chapter) then Append(res, Concatenation(",\n Chapter ", r.chapter, "")); fi; if IsBound(r.note) then Append(res, Concatenation("
        \n(", r.note, "", ")")); fi; if IsBound(r.notes) then Append(res, Concatenation("
        \n(", r.notes, "", ")")); fi; if IsBound(r.howpublished) then Append(res, Concatenation(",\n", r.howpublished, "")); fi; if IsBound(r.BUCHSTABE) then Append(res, Concatenation("
        \nEinsortiert unter ", r.BUCHSTABE, ".
        \n")); fi; if IsBound(r.LDFM) then Append(res, Concatenation("Signatur ", r.LDFM, ".
        \n")); fi; if IsBound(r.BUCHSTABE) and i>=0 then Append(res, Concatenation("BibTeX Eintrag\n
        ")); elif not ( IsBound( r.BUCHSTABE ) or IsBound( r.LDFM ) ) then Append( res, ".\n" ); fi; Append(res, "

        \n\n"); return res; end); InstallGlobalFunction(PrintBibAsHTML, function(arg) PrintFormattedString(CallFuncList(StringBibAsHTML, arg)); end); ## arg: r[, ansi] (for link to BibTeX) InstallGlobalFunction(StringBibAsText, function(arg) local r, ansi, str, txt, s, f, field, booklike; r := arg[1]; ansi := rec( Bib_reset := TextAttr.reset, Bib_author := Concatenation(TextAttr.bold, TextAttr.1), ## Bib_editor := ~.Bib_author, Bib_title := TextAttr.4, ## Bib_subtitle := ~.Bib_title, Bib_journal := "", Bib_volume := TextAttr.4, Bib_Label := TextAttr.3, Bib_edition := ["", ""], Bib_year := ["", ""], Bib_note := ["(", ")"], Bib_chapter := ["Chapter ", ""], ); ansi.Bib_editor := ansi.Bib_author; ansi.Bib_subtitle := ansi.Bib_title; if Length(arg) = 2 and arg[2] <> true then for f in RecFields(arg[2]) do ansi.(f) := arg[2].(f); od; elif IsBound(r.From) and IsBound(r.From.options) and IsBound(r.From.options.ansi) then for f in RecFields(r.From.options.ansi) do ansi.(f) := r.From.options.ansi.(f); od; else for f in RecFields(ansi) do ansi.(f) := ""; od; fi; # some details are set differently for book-like references if r.Type in [ "book", "booklet", "manual", "techreport", "mastersthesis", "phdthesis", "proceedings" ] then booklike := true; else booklike := false; fi; if not IsBound(r.Label) then Info(InfoBibTools, 1, "#W WARNING: no .Label in Bib-record"); Info(InfoBibTools, 2, ":\n", r); Info(InfoBibTools, 1, "\n"); return; fi; str := ""; # helper adds markup txt := function(arg) local field, s, pp, pre, post; field := arg[1]; if Length(arg) > 1 then s := arg[2]; elif IsBound(r.(field)) then s := r.(field); else return; fi; if not IsBound(ansi.(Concatenation("Bib_", field))) then Append(str, s); else pp := ansi.(Concatenation("Bib_", field)); if not IsString(pp) then pre := pp[1]; post := pp[2]; else pre := pp; post := ansi.Bib_reset; fi; Append(str, pre); Append(str, s); Append(str, post); fi; end; if IsBound(r.key) then s := r.key; elif IsBound(r.printedkey) then s := r.printedkey; else s := r.Label; fi; Add(str, '['); txt("Label", s); Append(str, "] "); # we assume with the "," delimiters that at least one of .author, # .editor or .title exist txt("author"); if IsBound(r.editor) then Append(str, " ("); txt("editor"); if PositionSublist( r.editor, " and " ) = fail then Append(str, ", Ed.)"); else Append(str, ", Eds.)"); fi; fi; if IsBound(r.title) then if IsBound(r.author) or IsBound(r.editor) then Append(str, ", "); fi; txt("title"); fi; if IsBound(r.booktitle) then Append(str, ", "); if r.Type in ["inproceedings", "incollection"] then Append(str, " in "); fi; txt("booktitle"); fi; if IsBound(r.subtitle) then Append(str, "–"); txt("subtitle"); fi; # standard BibTeX-styles typeset a type if not given if r.Type = "phdthesis" and not IsBound(r.type) then r := ShallowCopy(r); r.type := "Ph.D. thesis"; elif r.Type = "mastersthesis" and not IsBound(r.type) then r := ShallowCopy(r); r.type := "Master's thesis"; fi; for field in [ "journal", "type", "organization", "institution", "publisher", "school", "edition", "series", "volume", "number", "address", "year", "pages", "chapter", "note", "notes", "howpublished" ] do if IsBound(r.(field)) then if field = "year" then Append(str, " ("); txt(field); Append(str, ")"); continue; elif field = "pages" then if booklike then Append(str, ", "); txt(field); Append(str, " pages"); else ## Append(str, ", p. "); Append(str, ", "); txt(field); fi; continue; elif field = "edition" then Append(str, ", "); txt(field); Append(str, " edition"); continue; elif field in ["note", "notes"] then Append(str, ",\n ("); txt(field); Append(str, ")"); continue; elif field = "chapter" then Append(str, ", Chapter "); txt(field); continue; else Append(str, ", "); fi; txt(field); fi; od; # some LDFM specific if IsBound(r.BUCHSTABE) then Append(str, Concatenation(", Einsortiert unter ", r.BUCHSTABE)); fi; if IsBound(r.LDFM) then Append(str, Concatenation(", Signatur ", r.LDFM)); fi; ## str := FormatParagraph(Filtered(str, x-> not x in "{}"), 72); Add(str, '.'); if Unicode(str, "UTF-8") <> fail then str := FormatParagraph(str, SizeScreen()[1]-4, WidthUTF8String); else str := FormatParagraph(str, SizeScreen()[1]-4); fi; Add(str, '\n'); return str; end); InstallGlobalFunction(PrintBibAsText, function(arg) PrintFormattedString(CallFuncList(StringBibAsText, arg)); end); ## <#GAPDoc Label="SearchMRSection"> ##
        ## Getting &BibTeX; entries from ## MathSciNet ## We provide utilities to access the http://www.ams.org/mathscinet/ ## MathSciNet ## data base from within GAP. One condition for this to work is that the ## IO-package is available. The other is, ## of course, that you use these functions from a computer which has access to ## MathSciNet.

        ## ## Please note, that the usual license for MathSciNet ## access does not allow for automated searches in the database. Therefore, ## only use the function for single queries, as you ## would do using your webbrowser.

        ## ## ## ## ## a list of strings, a string or fail ## ## The first function provides the same functionality ## as the Web interface http://www.ams.org/mathscinet/ ## MathSciNet. The query strings must be given as ## a record, and the following components of this record are recognized: ## Author, AuthorRelated, Title, ReviewText, ## Journal, InstitutionCode, Series, MSCPrimSec, ## MSCPrimary, MRNumber, Anywhere, References ## and Year. ##

        ## Furthermore, the component type can be specified. It can be one of ## "bibtex" (the default if not given), "pdf", "html" and ## probably others. In the last cases the function returns a string with ## the correspondig PDF-file or web page from MathSciNet. ## In the first case the MathSciNet interface returns a web ## page with &BibTeX; entries, for convenience this function returns a list ## of strings, each containing the &BibTeX; text for a single result entry. ##

        ## The format of a .Year component can be either a four digit number, ## optionally preceded by one of the characters '<', ## '>' or '=', or it can be two four digit numbers ## separated by a - to specify a year range.

        ## ## The function gets a record of a parsed &BibTeX; ## entry as input as returned by or . It tries to generate some sensible input from this ## information for and calls that function.

        ## ## ## gap> ll := SearchMR(rec(Author:="Gauss", Title:="Disquisitiones"));; ## gap> ll2 := List(ll, HeuristicTranslationsLaTeX2XML.Apply);; ## gap> bib := ParseBibStrings(Concatenation(ll2));; ## gap> bibxml := List(bib[1], StringBibAsXMLext);; ## gap> bib2 := ParseBibXMLextString(Concatenation(bibxml));; ## gap> for b in bib2.entries do ## > PrintFormattedString(StringBibXMLEntry(b, "Text")); od; ## [Gau95] Gauss, C. F., Disquisitiones arithmeticae, Academia ## Colombiana de Ciencias Exactas Físicas y Naturales, Colección ## Enrique Pérez Arbeláez [Enrique Pérez Arbeláez Collection], 10, ## Bogotá (1995), xliv+495 pages, (Translated from the Latin by Hugo ## Barrantes Campos, Michael Josephy and Ángel Ruiz Zúñiga, With a ## preface by Ruiz Zúñiga). ## ## [Gau86] Gauss, C. F., Disquisitiones arithmeticae, Springer-Verlag, ## New York (1986), xx+472 pages, (Translated and with a preface by ## Arthur A. Clarke, Revised by William C. Waterhouse, Cornelius ## Greither and A. W. Grootendorst and with a preface by Waterhouse). ## ## [Gau66] Gauss, C. F., Disquisitiones arithmeticae, Yale University ## Press, Translated into English by Arthur A. Clarke, S. J, New Haven, ## Conn. (1966), xx+472 pages. ## ## ## ## ## ## ## ## ##

        ## <#/GAPDoc> SEARCHMRHOST := "ams.org"; ## SEARCHMRHOST := "ams.math.uni-bielefeld.de"; if not IsBound(SingleHTTPRequest) then SingleHTTPRequest := 0; fi; InstallGlobalFunction(SearchMR, function(r) local trans, uri, i, l, res, extr, a, b; trans := [["Author", "AUCN"], ["AuthorRelated","ICN"], ["Title","TI"], ["ReviewText","RT"],["Journal","JOUR"],["InstitutionCode","IC"], ["Series","SE"],["MSCPrimSec","CC"],["MSCPrimary","PC"], ["MRNumber","MR"],["Anywhere","ALLF"],["References","REFF"]]; if LoadPackage("IO") <> true then Print("SearchMR not available because IO package not available.\n"); return fail; fi; if not IsBound(r.type) then r.type := "bibtex"; fi; uri := Concatenation("/mathscinet/search/publications.html?fmt=", r.type); if IsBound(r.Year) then if '-' in r.Year then extr := SplitString(r.Year,"","- "); Append(uri, "&dr=yearrange&yearRangeFirst="); Append(uri, extr[1]); Append(uri, "&yearRangeSecond="); Append(uri, extr[2]); else Append(uri, "&dr=pubyear&arg3="); Append(uri, Filtered(r.Year, c-> not c in "<>=")); if r.Year[1] = '<' then Append(uri, "&yrop=lt"); elif r.Year[1] = '>' then Append(uri, "&yrop=gt"); else Append(uri, "&yrop=eq"); fi; fi; fi; i := 4; for a in trans do if IsBound(r.(a[1])) then if IsString(r.(a[1])) then l := [r.(a[1])]; else l := r.(a[1]); fi; for b in l do Append(uri, Concatenation("&pg", String(i), "=", a[2], "&s", String(i), "=", Encode(Unicode(b),"URL"))); if i = 9 then break; else i := i+1; fi; od; fi; if i = 9 then break; fi; od; # get all entries Append(uri, "&extend=1"); res := SingleHTTPRequest(SEARCHMRHOST, 80, "GET", uri, rec(), false, false); while res.statuscode = 302 do res := SingleHTTPRequest(SEARCHMRHOST, 80, "GET", res.header.location, rec(), false, false); od; if not IsBound(res.body) then Info(InfoBibTools, 1, "Cannot reach MathSciNet service."); return fail; fi; if r.type = "bibtex" then i := PositionSublist(res.body, "
        \n@", i);
            extr := [];
            while i <> fail do
              Add(extr, res.body{[i+5..PositionSublist(res.body, "
        ", i)-1]}); i := PositionSublist(res.body, "
        \n@", i);
            od;
            return extr;
          else
            return res.body;
          fi;
        end);
        # args: record[, type]
        # records like entry from ParseBibStrings/Files, default for type is "bibtex"
        InstallGlobalFunction(SearchMRBib, function(arg)
          local nn, tt, r, a, f;
          a := arg[1];
          if IsBound(a.mrnumber) then
            r := rec(MRNumber := a.mrnumber);
            if ' ' in r.MRNumber then
              r.MRNumber := r.MRNumber{[1..Position(r.MRNumber, ' ')-1]};
            fi;
          else
            a := ShallowCopy(a);
            for f in RecFields(a) do
              if IsString(a.(f)) then
                a.(f) := HeuristicTranslationsLaTeX2XML.Apply(a.(f));
              fi;
            od;
            if IsBound(a.author) then
              a.author := SubstitutionSublist(a.author, "~", " ");
              nn := NormalizedNameAndKey(a.author)[4];
            elif IsBound(a.editor) then
              a.editor := SubstitutionSublist(a.editor, "~", " ");
              nn := NormalizedNameAndKey(a.editor)[4];
            else
              nn := [[""]];
            fi;
            # up to three longest words from title
            tt := SubstitutionSublist(a.title, "{", "");
            tt := SubstitutionSublist(tt, "}", "");
            tt := NormalizedWhitespace(tt);
            tt := WordsString(tt);
            SortParallel(List(tt, w-> 1000-Length(w)), tt);
            tt := tt{[1..Minimum(3, Length(tt))]};
            r := rec( Author := List(nn, a->a[1]),
                                          Title := tt);
          fi;
          if Length(arg) > 1 then
            r.type := arg[2];
          fi;
          return SearchMR(r);
        end);
        if SingleHTTPRequest = 0 then
          Unbind(SingleHTTPRequest);
        fi;
        
        GAPDoc-1.5.1/lib/ComposeXML.gd0000644000175000017500000000104712026346064014256 0ustar  billbill#############################################################################
        ##
        #W  ComposeXML.gi                GAPDoc                          Frank Lübeck
        ##
        ##
        #Y  Copyright (C)  2000,  Frank Lübeck,  Lehrstuhl D für Mathematik,  
        #Y  RWTH Aachen
        ##
        ## The files ComposeXML.gi/.gd contain a function which allows to construct
        ## a GAPDoc-XML document from several source files.
        ##  
        
        DeclareGlobalFunction("ComposedDocument");
        # for compatibility
        DeclareGlobalFunction("ComposedXMLString");
        DeclareGlobalFunction("OriginalPositionDocument");
        
        GAPDoc-1.5.1/lib/BibXMLextTools.gi0000644000175000017500000016204212026346064015117 0ustar  billbill#############################################################################
        ##
        #W  BibXMLextTools.gi             GAPDoc                         Frank Lübeck
        ##
        ##
        #Y  Copyright (C)  2006,  Frank Lübeck,  Lehrstuhl D für Mathematik,  
        #Y  RWTH Aachen
        ##  
        ##  The files BibXMLextTools.g{d,i} contain utility functions for dealing
        ##  with bibliography data in the BibXMLext format. The corresponding DTD
        ##  is in ../bibxmlext.dtd. 
        ##  
        
        
        ###########################################################################
        ##  
        ##  templates to fill for new entries, this describes the possible entries
        ##  and their structure
        ##  (This is generated from Bibxmlext from bibxmlextinfo.g, which is created
        ##  automatically with the adhoc utility parsedtd.g.)
        BindGlobal("BibXMLextStructure", rec());
        BibXMLextStructure.fill := function()
          local l, els, i, type;
          for type in Filtered(Bibxmlext[1].entry, a-> a <> "or") do
            l := Bibxmlext[1].(type);
            els := [];
            i := 1;
            while i <= Length(l) do
              if i = Length(l) or not l[i+1] in ["optional", "repeated"] then
                Add(els, [l[i], true]);
                i := i+1;
              else
                Add(els, [l[i], false]);
                i := i+2;
              fi;
            od;
            # Print(type,": ",Filtered(els, a->not IsString(a[1])),"\n");
            BibXMLextStructure.(type) := els;
          od;
          Unbind(BibXMLextStructure.fill);
        end;
        BibXMLextStructure.fill();
        
        
        ##  <#GAPDoc Label="TemplateBibXML">
        ##  
        ##  
        ##  list of types or string
        ##  
        ##  Without an argument this function returns a list of the supported entry
        ##  types in  BibXMLext documents.
        ##  

        ## With an argument type of one of the supported types the function ## returns a string which is a template for a corresponding BibXMLext entry. ## Optional field elements have a * appended. If an element has ## the word OR appended, then either this element or the next must/can ## be given, not both. If AND/OR is appended then this and/or the next ## can/must be given. Elements which can appear several times have a ## + appended. Places to fill are marked by an X. ## ## TemplateBibXML(); ## [ "article", "book", "booklet", "conference", "inbook", ## "incollection", "inproceedings", "manual", "mastersthesis", "misc", ## "phdthesis", "proceedings", "techreport", "unpublished" ] ## gap> Print(TemplateBibXML("inbook")); ## ## ## XX+ ## OR ## ## XX+ ## ## X ## XAND/OR ## X ## X ## X ## X*OR ## X* ## X* ## X* ##

        X
        * ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X*OR ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X* ## X*+ ## ## ]]> ##
        ##
        ## <#/GAPDoc> # args: [type] with no argument prints the possible types InstallGlobalFunction(TemplateBibXML, function(arg) local type, res, add, a, b; if Length(arg) = 0 then return Filtered(RecFields(BibXMLextStructure), a-> not a in ["fill"]); fi; type := arg[1]; if type = "fill" or not IsBound(BibXMLextStructure.(type)) then Error("There are no bib-entries of type ", type,".\n"); fi; res := "<"; Append(res, type); Append(res, ">\n"); add := function(a) if a[1] in [ "author", "editor" ] then Append(res, " <"); Append(res, a[1]); Append(res, ">\n XX+\n "); elif a[1] = "other" then Append(res, " X"); else Append(res, " <"); Append(res, a[1]); Append(res, ">X"); fi; if not a[2] then Add(res, '*'); fi; if a[1] = "other" then Add(res, '+'); fi; Append(res, "\n"); if not IsString(res) then Error("nanu");fi; end; for a in BibXMLextStructure.(type) do if IsString(a[1]) then add(a); elif Length(a[1]) = 3 and a[1][2] = "or" then if IsString(a[1][1]) then add([a[1][1], a[2]]); Unbind(res[Length(res)]); Append(res,"OR\n"); elif a[1][1] = [ "chapter", "pages", "optional" ] then add([a[1][1][1], a[2]]); Unbind(res[Length(res)]); Append(res,"AND/OR\n"); else Error("unknown case 1?"); fi; add([a[1][3], a[2]]); else Error("unknown case 2?"); fi; od; Append(res, "\n"); return res; end); ########################################################################### ## ## parsing BibXMLext files ## ## <#GAPDoc Label="ParseBibXMLextString"> ## ## ## ## a record with fields .entries, .strings and ## .entities ## ## The first function gets a string str containing a BibXMLext ## document or a part of it. It returns a record with the three mentioned ## fields. Here .entries is a list of partial XML parse trees for ## the <entry>-elements in str. The field .strings ## is a list of key-value pairs from the <string>-elements in ## str. And .strings is a list of name-value pairs of the ## named entities which were used during the parsing. ##

        ## ## The second function uses the first ## on the content of all files given by filenames fname1 and so on. ## It collects the results in a single record.

        ## ## As an example we parse the file testbib.xml shown in ## . ## ## ## gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; ## gap> RecFields(bib); ## [ "entries", "strings", "entities" ] ## gap> bib.entries; ## [ <BibXMLext entry: AB2000> ] ## gap> bib.strings; ## [ [ "j", "Important Journal" ] ] ## gap> bib.entities[1]; ## [ "amp", "&#38;#38;" ] ## ## ## ## <#/GAPDoc> ## # args: string with BibXMLext document[, record with three lists] # the three lists n: # .entries: parse trees of elements, # .strings: pairs [ key, value ], # .entities: pairs [ entity name, entity substitution ] BindGlobal("BibXMLEntryOps", rec( ViewObj := function(entry) Print(""); end, PrintObj := function(entry) Print(StringXMLElement(entry)[1]); end )); # the entities from bibxmlext.dtd BindGlobal("ENTITYDICT_bibxml", rec( nbsp := " " , copyright := "©", ndash := "–" )); InstallGlobalFunction(ParseBibXMLextString, function(arg) local str, res, tr, ent, strs, entries, a; str := arg[1]; if Length(arg) > 1 then res := arg[2]; else res := rec(entries := [], strings := [], entities := []); fi; tr := ParseTreeXMLString(str, ENTITYDICT_bibxml); # get used entities from ENTITYDICT ent := List(RecFields(ENTITYDICT), a-> [a, ENTITYDICT.(a)]); Append(res.entities, ent); res.entities := Set(res.entities); # read key value pairs strs := XMLElements(tr, ["string"]); for a in strs do AddSet(res.strings, [a.attributes.key, a.attributes.value]); od; entries := XMLElements(tr, ["entry"]); for a in entries do a.operations := BibXMLEntryOps; od; Append(res.entries, entries); return res; end); InstallGlobalFunction(ParseBibXMLextFiles, function(arg) local res, nam, s; if Length(arg) > 0 and not IsString(arg[Length(arg)]) then res := arg[Length(arg)]; arg := arg{[1..Length(arg)-1]}; else res := rec(entries := [], strings := [], entities := []); fi; for nam in arg do s := StringFile(nam); if s = fail then Error("Cannot read file ", nam, "\n"); else ParseBibXMLextString(StringFile(nam), res); fi; od; return res; end); ########################################################################### ## ## heuristic translation of BibTeX data to BibXMLext ## ## <#GAPDoc Label="StringBibAsXMLext"> ## ## ## ## a string ## ## nothing ## ## These utilities translate some &LaTeX; code into text in UTF-8 encoding. ## The input is given as a string str, or a file name fnam, ## respectively. The first function returns the translated string. The second ## function with one argument overwrites the given file with the translated ## text. Optionally, the translated file content can be written to another ## file, if its name is given as second argument outnam.

        ## The record HeuristicTranslationsLaTeX2XML mainly contains ## translations of &LaTeX; macros for special characters which were found ## in hundreds of &BibTeX; entries from ## http://www.ams.org/mathscinet/. Just look at ## this record if you want to know how it works. It is easy to extend, and if ## you have improvements which may be of general interest, please send them ## to the &GAPDoc; author. ## ## gap> s := "\\\"u\\'{e}\\`e{\\ss}";; ## gap> Print(s, "\n"); ## \"u\'{e}\`e{\ss} ## gap> Print(HeuristicTranslationsLaTeX2XML.Apply(s),"\n"); ## üéèß ## ## ## ## ## ## ## a string with XML code, or fail ## ## The argument bibentry is a record representing an entry from a ## &BibTeX; file, as returned in the first list of the result of . The optional two arguments abbrvs and ## vals can be ## lists of abbreviations and substitution strings, as returned as second ## and third list element in the result of . ## The optional argument encoding specifies the character ## encoding of the string components of bibentry. If this is not ## given it is checked if all strings are valid UTF-8 encoded strings, in ## that case it is assumed that the encoding is UTF-8, otherwise the ## latin1 encoding is assumed. ## ##

        ## The function creates XML code of an ## <entry>-element in BibXMLext format. The result is in ## UTF-8 encoding and contains ## some heuristic translations, like splitting name lists, finding places for ## <C>-elements, putting formulae in <M>-elements, ## substituting some characters. The result should always be checked and ## maybe improved by hand. Some validity checks are applied to the given data, ## for example if all non-optional fields ## are given. If this check fails the function returns fail.

        ## ## If your &BibTeX; input contains &LaTeX; markup for special characters, ## it can be convenient to translate this input with or before parsing it as ## &BibTeX;.

        ## ## As an example we consider again the short &BibTeX; file doc/test.bib ## shown in the example for . ## ## bib := ParseBibFiles("doc/test.bib");; ## gap> str := StringBibAsXMLext(bib[1][1], bib[2], bib[3]);; ## gap> Print(str, "\n"); ##

        ## ## Fritz A.First ## X. Y.Sec ## ## Short ## ## 2000 ##
        ]]> ## ##
        ##
        ## <#/GAPDoc> # args: bibrec[, abbrevs, strings][, encoding] InstallGlobalFunction(StringBibAsXMLext, function(arg) local r, abbrevs, texts, enc, MandC, struct, f, res, content, cont, tmp, nams, pos, a, b, i, lbl; r := arg[1]; if Length( arg ) > 2 then abbrevs := arg[2]; texts := arg[3]; else abbrevs := [ ]; texts := [ ]; fi; if not IsSet(texts) then SortParallel(texts, abbrevs); fi; if Length(arg) in [2, 4] then enc := arg[Length(arg)]; else # try to autodetect UTF-8, else assume latin1 if ForAny(RecFields(r), a-> IsString(r.(a)) and Unicode(r.(a)) = fail) or ForAny(abbrevs, a-> Unicode(a) = fail) or ForAny(texts, a-> Unicode(a) = fail) then enc := "ISO-8859-1"; else enc := "UTF-8"; fi; fi; if not IsBound(UNICODE_RECODE.NormalizedEncodings.(enc)) then Info(InfoBibTools, 1, "don't know encoding ", enc, " using ISO-8859-1\n"); enc := "ISO-8859-1"; else enc := UNICODE_RECODE.NormalizedEncodings.(enc); fi; if enc <> "UTF-8" then r := ShallowCopy(r); for a in RecFields(r) do if IsString(r.(a)) then r.(a) := Encode(Unicode(r.(a), enc)); fi; od; abbrevs := List(abbrevs, a-> Encode(Unicode(a, enc))); texts := List(texts, a-> Encode(Unicode(a, enc))); fi; # helper, to change {}'s outside math mode and $'s in # (book)title and -elements: MandC := function(str) local res, math, c; if Position(str, '{') = fail and Position(str, '$') = fail then return str; fi; # escape & and < str := SubstitutionSublist(str, "<", "<"); str := SubstitutionSublist(str, "&", "&"); res := ""; math := false; for c in str do if c = '$' then math := not math; if math then Append(res, ""); else Append(res, ""); fi; elif c = '{' and not math then Append(res, ""); elif c = '}' and not math then Append(res, ""); else Add(res, c); fi; od; return ParseTreeXMLString(res).content; end; if not (r.Type in RecFields(BibXMLextStructure)) then Info(InfoBibTools, 1, "#W WARNING: invalid .Type in Bib-record: ", r.Type, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; struct := BibXMLextStructure.(r.Type); f := RecFields(r); if "Label" in f then lbl:= Concatenation( " (", r.Label, ") " ); else lbl:= ""; fi; # checking conditions on certain related elements in an entry if "isbn" in f and "issn" in f then Info(InfoBibTools, 1, "#W WARNING: Cannot have both, ISBN and ISSN ", "in Bib-record", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; if r.Type in ["book", "inbook", "incollection", "proceedings", "inproceedings", "conference"] and "volume" in f and "number" in f then Info(InfoBibTools, 1, "#W WARNING: Cannot have both in ", r.Type, "-entry, 'volume' and 'number'", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; if r.Type in ["book", "inbook"] then if "author" in f and "editor" in f then Info(InfoBibTools, 1, "#W WARNING: Cannot have both in ", r.Type, "-entry, 'author' and 'editor'", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; elif not "author" in f and not "editor" in f then Info(InfoBibTools, 1, "#W WARNING: Must have 'author' or 'editor' in ", r.Type, "-entry", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; fi; if r.Type = "inbook" then if not "pages" in f then if not "chapter" in f then Info(InfoBibTools, 1,"#W WARNING: Must have 'chapter' and/or 'pages' ", "in inbook-entry", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; fi; fi; # now we can flatten struct struct := Concatenation(List(struct, function(a) if not IsString(a[1]) then return List(Filtered(a[1], x-> x<>"or"), b-> [b, false]); else return [a]; fi; end)); # now construct the result, first as XML tree res := rec(name := "entry", attributes := rec(id := r.Label), content := [rec(name := r.Type, attributes := rec(), content := [])]); cont := res.content[1].content; for a in struct do if a[2] = true and not a[1] in f then Info(InfoBibTools, 1, "#W WARNING: Must have '", a[1], "' in ", r.Type, "-entry", lbl, "\n"); Info(InfoBibTools, 2, r, "\n"); return fail; fi; if a[1] in f then Add(cont, "\n "); # special handling of author/editor if a[1] in ["author", "editor"] and IsString(r.(a[1])) then tmp := rec(name := a[1], attributes := rec(), content := ["\n "]); nams := NormalizedNameAndKey(r.(a[1])); for b in nams[4] do Add(tmp.content, " "); Add(tmp.content, rec(name := "name", attributes := rec(), content := [ rec(name := "first", attributes := rec(), content := b[3]), rec(name := "last", attributes := rec(), content := b[1]) ] )); Add(tmp.content, "\n "); od; Add(cont, tmp); Add(cont, " "); else if IsRecord(r.(a[1])) then Add(cont, r.(a[1])); else # string if a[1] in ["title", "booktitle"] then tmp := MandC(r.(a[1])); else tmp := r.(a[1]); pos := PositionSet(texts, tmp); if pos <> fail then tmp := [rec(name := "value", attributes := rec(key := abbrevs[pos]), content := 0)]; fi; fi; Add(cont, rec(name := a[1], attributes := rec(), content := tmp)); fi; fi; fi; od; # additional infos f := Difference(f, List(struct, a-> a[1])); f := Filtered(f, a-> not a in ["From", "Type", "Label"]); for a in f do Add(cont, "\n "); Add(cont, rec(name := "other", attributes := rec( type := a ), content := r.(a)) ); od; Add(cont, "\n"); res := StringXMLElement(res)[1]; res := SplitString(res, "\n", ""); for i in [1..Length(res)] do if Length(res[i]) > 76 then a := FormatParagraph(res[i], 76, "left", [" ",""]); Unbind(a[Length(a)]); a := a{[5..Length(a)]}; res[i] := a; fi; od; return JoinStringsWithSeparator(res, "\n"); end); # Heuristic LaTeX to BibXML markup translations InstallValue(HeuristicTranslationsLaTeX2XML, rec( CharacterMarkup := [ ["\\accent127", "\\\""], ["{\\\"a}", "ä"], ["\\\"a", "ä"], ["{\\\"A}", "Ä",], ["\\\"A", "Ä"], ["{\\'a}", "á"], ["\\'a", "á"], ["{\\'A}", "Á"], ["\\'A", "Á"], ["\\`a", "à"], ["{\\d{a}}", "ạ"], [ "\\=a", "ā" ], # 257 [ "{\\aa}", "å" ], # 229 [ "{\\u{a}}", "ă" ], # 259 [ "{\\c{c}}", "ç" ], # 231 [ "{\\'c}", "ć" ], # 263 [ "{\\v{c}}", "č" ], # 269 [ "{\\Dbar}", "Ð" ], # 208, defined in preamble ["\\'E", "É"], [ "{\\\"e}", "ë" ], # 235 [ "\\\"e", "ë" ], # 235 [ "{\\^e}", "ê" ], # 234 [ "\\^e", "ê" ], # 234 ["{\\'e}", "é"], ["{\\`e}", "è"], ["\\'e", "é"], ["\\`e", "è"], ["\\'{e}", "é"], ["\\`{e}", "è"], ["\\'{E}", "É"], ["{\\`E}", "È"], ["\\`{E}", "È"], ["{\\v{e}}", "ě"], [ "{\\u{g}}", "ğ" ], # 287 [ "{\\'{\\i}}", "í" ], # 237 [ "{\\'{\\i}}", "í" ], # 237 [ "{\\'\\i}", "í" ], # 237 [ "\\'\\i ", "í" ], # 237 [ "{\\u\\i}", "ĭ" ], # 301, must come before the next line! ["\\u\\i", "ĭ"], [ "{\\={\\i}}", "ī" ], # 299 [ "{\\i}", "ı" ], # 305 [ "{\\'n}", "ń" ], # 324 [ "{\\~n}", "ñ" ], # 241 [ "{\\tilde n}", "ñ" ], # 241 [ "\\tilde n", "ñ" ], # 241 ["{\\\"o}", "ö"], ["{\\\"O}", "Ö"], ["\\\"o", "ö"], ["\\\"O", "Ö"], ["{\\'o}", "ó"], ["\\'o", "ó"], [ "\\=o", "ō" ], # 333 [ "{\\H{O}}", "Ő" ], # 336 [ "{\\H o}", "ő" ], # 337 [ "{\\H{o}}", "ő" ], # 337 [ "\\H o", "ő" ], # 337 [ "\\^o", "ô" ], # 244 [ "\\^u", "û" ], # 251 [ "{\\o}", "ø" ], # 248 [ "{\\v{s}}", "š" ], # 353 [ "{\\c{S}}", "Ş" ], # 350 [ "{\\v{S}}", "Š" ], # 352 ["{\\\"u}", "ü"], ["{\\\"U}", "Ü"], ["\\\"{U}", "Ü"], ["\\\"u", "ü"], ["\\\"U", "Ü"], ["{\\\"{u}}", "ü"], ["\\\"{u}", "ü"], [ "{\\'u}", "ú" ], # 250 [ "\\'u", "ú" ], # 250 [ "{\\H{U}}", "Ű" ], # 368 [ "{\\H{u}}", "ű" ], # 369 [ "\\=u", "ū" ], # 363 [ "\\=u", "ū" ], # 363 ["{\\'y}", "ý"], ["\\v Z", "Ž"], [ "{\\v{Z}}", "Ž" ], # 381 ["{\\ss}", "ß"], [ "\\ss ", "ß" ], [ "\\eta", "η" ], # 951 [ "\\mu", "μ" ], # 956 [ "\\pm", "±" ], # 177 ["\\sb ", "_" ], ["\\sb\n", "_" ], ["\\sb{", "_{"], ["\\sp ", "^" ], ["\\sp\n", "^" ], ["\\sp{", "^{"], ["\\#", "#"], ["\\&", "&"], ["\\ ", " "], ["$'$", "ʹ"], ["{\\cprime}", "ʹ"], [ "\\cprime ", "ʹ" ], [ "\\cprime,", "ʹ," ], ["---", "—"], # — ["--", "–"], # – #T The following occurs once in the GAP bibliography, # inside an authors' name. [ "{-}", "-" ], # ??? #T The following occurs in Gri87a, in a cross-reference inside the TITLE #T (which is a bad idea ...) [ "[{\\it ", "[{" ], # more heuristics: [ "\\\n", "" ], # remove \ together with a following line break [ " _", "_" ], [ "_ ", "_" ], [ " ^", "^" ], [ "^ ", "^" ], [ "\\times", " \\times " ], [ " \\times", " \\times" ], [ "\\times ", "\\times " ], [ "\\cdot", " \\cdot " ], [ "\\cdot", " \\cdot " ], [ " \\cdot", " \\cdot" ], [ "\\cdot ", "\\cdot " ], [ "\\sf\n", "\\sf " ], # delete hyphenation hints, should be done by end user [ "\\-", "" ] ], RepeatedTranslations:= [ [ "_ ", "_" ], [ "^ ", "^" ], [ "\\sf ", "\\sf " ], ], TranslationsOfPairs := [ [ "\\sqrt{", "}", "\\sqrt{{", "}}" ], [ "\\sqrt{{{", "}}}", "\\sqrt{{", "}}" ], [ "^{", "}", "^{{", "}}" ], [ "^{{{", "}}}", "^{{", "}}" ], [ "_{", "}", "_{{", "}}" ], [ "_{{{", "}}}", "_{{", "}}" ], ], ## replace ... by ... #T would of course be better to prescribe a MATCHING of brackets ... TranslationOfOnePair:= function( str, start, eend, rstart, rend ) local pos, pos2; pos:= 0; while pos <> fail do pos:= PositionSublist( str, start, pos ); if pos <> fail then pos2:= PositionSublist( str, eend, pos ); if pos2 = fail then Error( "no match!" ); fi; str:= Concatenation( str{ [ 1 .. pos -1 ] }, rstart, str{ [ pos+Length( start ) .. pos2-1 ] }, rend, str{ [ pos2+Length( eend ) .. Length( str ) ] } ); fi; od; return str; end, )); # SubstitutionSublist is not good enough when a pure macro must be # substituted (don't substitute \pm in \pmod). HeuristicTranslationsLaTeX2XML.subsTeXMacro := function(str, old, new) local i, p, nstr, p1, p2; # check if old ends in macro i := Length(old); while i > 0 and old[i] in LETTERS do i := i-1; od; if i < Length(old) and old[i] = '\\' then p := PositionSublist(str, old); if p = fail then return str; fi; nstr := ""; p1 := 1; p2 := p; while p2 <> fail do if Length(str)=p2+Length(old)-1 or not str[p2+Length(old)] in LETTERS then Append(nstr, str{[p1..p2-1]}); Append(nstr, new); p1 := p2+Length(old); fi; p2 := PositionSublist(str, old, p2); od; Append(nstr, str{[p1..Length(str)]}); return nstr; else return SubstitutionSublist(str, old, new); fi; end; HeuristicTranslationsLaTeX2XML.Apply := function(str) local str2, pair, entry, s; s := HeuristicTranslationsLaTeX2XML.subsTeXMacro; for pair in HeuristicTranslationsLaTeX2XML.CharacterMarkup do str:= s( str, pair[1], pair[2] ); od; for pair in HeuristicTranslationsLaTeX2XML.RepeatedTranslations do str2:= s( str, pair[1], pair[2] ); while str2 <> str do str:= str2; str2:= s( str, pair[1], pair[2] ); od; od; for entry in HeuristicTranslationsLaTeX2XML.TranslationsOfPairs do str:= HeuristicTranslationsLaTeX2XML.TranslationOfOnePair( str, entry[1], entry[2], entry[3], entry[4] ); od; return str; end; HeuristicTranslationsLaTeX2XML.ApplyToFile := function(arg) local fnam, outnam, str; fnam := arg[1]; if Length(arg) > 1 then outnam := arg[2]; else outnam := fnam; fi; str := StringFile(fnam); str := HeuristicTranslationsLaTeX2XML.Apply(str); FileString(outnam, str); end; ## <#GAPDoc Label="WriteBibXMLextFile"> ## ## ## nothing ## ## This function writes a BibXMLext file with name fname.

        ## ## There are three possibilities to specify the bibliography entries in the ## argument bib. It can be a list of three lists as returned by . Or it can be just the first of such three lists ## in which case the other two lists are assumed to be empty. To all ## entries of the (first) list the function ## is applied and the resulting strings are written to the result file.

        ## ## The third possibility is that bib is a record in the ## format as returned by and . In this case the entries for the ## BibXMLext file are produced with , ## and if bib.entities is bound then it is tried to ## resubstitute parts of the string by the given entities with .

        ## ## As an example we write back the result of the example shown for ## to an equivalent XML file. ## ## ## gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; ## gap> WriteBibXMLextFile("test.xml", bib); ## ## ## ## <#/GAPDoc> InstallGlobalFunction(WriteBibXMLextFile, function(fname, bib) local i, a, s, f, strstr; f := OutputTextFile(fname, false); SetPrintFormattingStatus(f, false); PrintTo(f, "\n", "\n", "\n"); # a helper strstr := function(key, val) return StringXMLElement(rec(name := "string", attributes := rec( key := key, value := val), content := 0))[1]; end; # make sure, strings are sorted if IsList(bib) then if not IsRecord(bib[1]) then bib := ShallowCopy(bib); bib[2] := ShallowCopy(bib[2]); bib[3] := ShallowCopy(bib[3]); else bib := [bib, [], []]; fi; # strings first for i in [1..Length(bib[2])] do AppendTo(f, strstr(bib[2][i], bib[3][i]), "\n"); od; SortParallel(bib[3], bib[2]); for a in bib[1] do AppendTo(f, StringBibAsXMLext(a, bib[2], bib[3]), "\n"); od; else if IsBound(bib.strings) then for a in bib.strings do AppendTo(f, strstr(a[1], a[2]), "\n"); od; fi; for a in bib.entries do s := StringXMLElement(a); if IsBound(bib.entities) then s := EntitySubstitution(s, bib.entities); fi; AppendTo(f, s, "\n"); od; fi; AppendTo(f, "\n"); end); ########################################################################### ## ## translating BibXML entries to records ## ## ## <#GAPDoc Label="RecBibXMLEntry"> ## ## ## a record with fields as strings ## ## This function generates a content string for each field of a ## bibliography entry and assigns them to record components. This content ## may depend on the requested result type and possibly some given options. ##

        ## ## The arguments are as follows: entry is the parse ## tree of an <entry> element as returned by or . ## The optional argument restype describes the type of the ## result. This package supports currently the types "BibTeX", ## "Text" and "HTML". The default is "BibTeX". The ## optional argument strings must be a list of key-value pairs as ## returned in the component .strings in the result of . The argument options must be a ## record.

        ## ## If the entry contains an author field then the result will also ## contain a component .authorAsList which is a list containing for ## each author a list with three entries of the form [last name, first ## name initials, first name] (the third entry means the first name as ## given in the data). Similarly, an editor field is accompanied by ## a component .editorAsList.

        ## ## The following options are currently supported.

        ## ## If options.fullname is bound and set to true then the full ## given first names for authors and editors will be used, the default is ## to use the initials of the first names. Also, if ## options.namefirstlast is bound and set to true then the ## names are written in the form first-name(s) last-name, the ## default is the form last-name, first-name(s).

        ## ## If options.href is bound and set to false then the ## "BibTeX" type result will not use \href commands. ## The default is to produce \href commands from ## <URL>-elements such that &LaTeX; with the hyperref ## package can produce links for them.

        ## ## The content of an <Alt>-element with Only-attribute is ## included if restype is given in the attribute and ignored ## otherwise, and vice versa in case of a Not-attribute. If ## options.useAlt is bound, it must be a list of strings ## to which restype is added. Then an <Alt>-element ## with Only-attribute is evaluated if the intersection of ## options.useAlt and the types given in the attribute is not empty. ## In case of a Not-attribute the element is evaluated if this ## intersection is empty.

        ## ## If restype is "BibTeX" then the string fields in the ## result will be recoded with and target ## "LaTeX". If options.hasLaTeXmarkup is bound and set to ## true (for example, because the data are originally read from ## &BibTeX; files), then the target "LaTeXleavemarkup" will be ## used.

        ## ## We use again the file shown in the example for . ## ## gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; ## gap> e := bib.entries[1];; strs := bib.strings;; ## gap> Print(RecBibXMLEntry(e, "BibTeX", strs), "\n"); ## rec( ## From := rec( ## BibXML := true, ## options := rec( ## ), ## type := "BibTeX" ), ## Label := "AB2000", ## Type := "article", ## author := "First, F. A. and Sec{\\H o}nd, X. Y.", ## authorAsList := ## [ [ "First", "F. A.", "Fritz A." ], ## [ "Sec\305\221nd", "X. Y.", "X. Y." ] ], ## journal := "Important Journal", ## mycomment := "very useful", ## note := ## "Online data at \\href {http://www.publish.com/~ImpJ/123#data} {Bla\ ## Bla Publisher}", ## number := "13", ## pages := "13{\\textendash}25", ## printedkey := "FS00", ## title := ## "The {F}ritz package for the \n formula $x^y - l_{{i+1}} \ ## \\rightarrow \\mathbb{R}$", ## year := "2000" ) ## gap> Print(RecBibXMLEntry(e, "HTML", strs).note, "\n"); ## Online data at <a href="http://www.publish.com/~ImpJ/123#data">Bla Bla\ ## Publisher</a> ## ## ## ## <#/GAPDoc> ## <#GAPDoc Label="AddHandlerBuildRecBibXMLEntry"> ## ## ## nothing ## ## The argument elementname must be the name of an entry field ## supported by the BibXMLext format, the name of one of the special ## elements "C", "M", "Math", "URL" or of the ## form "Wrap:myname" or any string "mytype" (which then ## corresponds to entry fields <other type="mytype">). The string ## "Finish" has an exceptional meaning, see below.

        ## ## restype is a string describing the result type for which the ## handler is installed, see .

        ## ## For both arguments, elementname and restype, it is also ## possible to give lists of the described ones for installing several ## handler at once.

        ## ## The argument handler must be a function with five ## arguments of the form handler(entry, r, restype, strings, ## options). Here entry is a parse tree of a BibXMLext ## <entry>-element, r is a node in this tree for an ## element elementname, and restype, strings and ## options are as explained in . ## The function should return a string representing the content ## of the node r. If elementname is of the form ## "Wrap:myname" the handler is used for elements of form ## <Wrap Name="myname">...</Wrap>.

        ## ## If elementname is "Finish" the handler should look like ## above except that now r is the record generated by just before it is returned. Here the handler ## should return nothing. It can be used to manipulate the record r, ## for example for changing the encoding of the strings or for adding some ## more components.

        ## ## The installed handler is called by ## BuildRecBibXMLEntry(entry, r, restype, ## strings, options). The string for the ## whole content of an element can be generated ## by ContentBuildRecBibXMLEntry(entry, r, ## restype, strings, options).

        ## ## We continue the example from and install a ## handler for the <Wrap Name="Package">-element such that ## &LaTeX; puts its content in a sans serif font. ## ## gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", ## > function(entry, r, restype, strings, options) ## > return Concatenation("\\textsf{", ContentBuildRecBibXMLEntry( ## > entry, r, restype, strings, options), "}"); ## > end); ## gap> ## gap> Print(RecBibXMLEntry(e, "BibTeX", strs).title, "\n"); ## The \textsf{ {F}ritz} package for the ## formula $x^y - l_{{i+1}} \rightarrow \mathbb{R}$ ## gap> Print(RecBibXMLEntry(e, "Text", strs).title, "\n"); ## The Fritz package for the ## formula x^y - l_{i+1} → R ## gap> AddHandlerBuildRecBibXMLEntry("Wrap:Package", "BibTeX", "Ignore"); ## ## ## ## <#/GAPDoc> InstallGlobalFunction(ContentBuildRecBibXMLEntry, function(entry, elt, type, strings, opts) local res, a; res := ""; for a in elt.content do Append(res, BuildRecBibXMLEntry(entry, a, type, strings, opts)); od; return res; end); InstallGlobalFunction(BuildRecBibXMLEntry, function(entry, elt, type, strings, opts) local letters, res, f, nam, nams, key, hdlr, a; # helper to find a key letters := function(str, one) local pos; str := Unicode(str, "UTF-8"); if UChar(' ') in str then pos := Concatenation([1], 1+Positions(str, UChar(' '))); if one then return Encode(str{[pos[Length(pos)]]}, "UTF-8"); else return Encode(str{pos}, "UTF-8"); fi; else if one then pos := Minimum(1, Length(str)); else pos := Minimum(3, Length(str)); fi; return Encode(str{[1..pos]}, "UTF-8"); fi; end; if elt = entry then # upper level, create result record res := rec(From := rec(BibXML := true, type := type, options := opts)); res.Label := entry.attributes.id; f := First(entry.content, a-> IsRecord(a) and a.name in RecFields(BibXMLextStructure)); res.Type := f.name; for a in f.content do if IsRecord(a) and not a.name = "PCDATA" then nam := a.name; if nam in ["author", "editor"] then res.(Concatenation(nam, "AsList")) := BuildRecBibXMLEntry(entry, a, "namesaslists", strings, opts); fi; if nam = "other" then nam := a.attributes.type; fi; res.(nam) := BuildRecBibXMLEntry(entry, a, type, strings, opts); fi; od; # we produce a key if not given if not IsBound(res.key) then if IsBound(res.authorAsList) then nams := res.authorAsList; elif IsBound(res.editorAsList) then nams := res.editorAsList; else nams := 0; fi; if nams = 0 then key := "NOAUTHOROREDITOR_SPECIFYKEY"; else key := ""; if Length(nams) = 1 then Append(key, letters(nams[1][1], false)); else for a in nams do Append(key, letters(a[1], true)); od; fi; if IsBound(res.year) and Length(res.year) >= 2 then Append(key, res.year{[Length(res.year)-1, Length(res.year)]}); fi; fi; res.printedkey := key; fi; # a possibility for some final cleanup/additions, e.g., for handling # some options if IsBound(RECBIBXMLHNDLR.Finish.(type)) then res := RECBIBXMLHNDLR.Finish.(type)(entry, res, type, strings, opts); fi; return res; else # return a string (or something else if you know what you are doing) # call this function recursively if IsString(elt) then # end of recursion return elt; fi; nam := elt.name; if IsBound(RECBIBXMLHNDLR.(nam)) then hdlr := RECBIBXMLHNDLR.(nam); else hdlr := RECBIBXMLHNDLR.default; fi; if IsBound(hdlr.(type)) then hdlr := hdlr.(type); elif IsBound(hdlr.default) then hdlr := hdlr.default; else hdlr := RECBIBXMLHNDLR.default.default; fi; return hdlr(entry, elt, type, strings, opts); fi; end); # eltname can be an elementname or a list of elementnames, in the latter # case fun is installed for all of them, same with type InstallGlobalFunction(AddHandlerBuildRecBibXMLEntry, function(eltname, type, fun) local e; if not IsString(eltname) and IsList(eltname) then for e in eltname do AddHandlerBuildRecBibXMLEntry(e, type, fun); od; return; fi; if not IsString(type) and IsList(type) then for e in type do AddHandlerBuildRecBibXMLEntry(eltname, e, fun); od; return; fi; if not IsBound(RECBIBXMLHNDLR.(eltname)) then RECBIBXMLHNDLR.(eltname) := rec(); fi; if fun = "Ignore" then fun := RECBIBXMLHNDLR.default.default; fi; RECBIBXMLHNDLR.(eltname).(type) := fun; end); # this just collect text recursively AddHandlerBuildRecBibXMLEntry("default", "default", function(entry, elt, type, strings, opts) if IsString(elt.content) then return elt.content; elif elt.content = 0 then return ""; else return ContentBuildRecBibXMLEntry(entry, elt, type, strings, opts); fi; end); # dealing with names in author and editor fields # helper function, find initials from UTF-8 string, keep '-'s RECBIBXMLHNDLR.Initials := function(fnam) local pre, res, i; fnam := NormalizedWhitespace(fnam); fnam := Unicode(fnam, "UTF-8"); pre := Unicode(" -"); res := Unicode(""); for i in [1..Length(fnam)] do if i=1 or fnam[i-1] in pre then Add(res, fnam[i]); Add(res, UChar('.')); elif fnam[i] in pre then Add(res, fnam[i]); fi; od; return Encode(res, "UTF-8"); end; # produce the names as lists (result will be bound to elt.AsList # before 'author' and 'editor' are produced) AddHandlerBuildRecBibXMLEntry("name", "namesaslists", function(entry, elt, type, strings, opts) local res, f; res := []; f := First(elt.content, a-> IsRecord(a) and a.name = "last"); Add(res, BuildRecBibXMLEntry(entry, f, type, strings, opts)); NormalizeWhitespace(res[1]); f := First(elt.content, a-> IsRecord(a) and a.name = "first"); if f <> fail then res[3] := BuildRecBibXMLEntry(entry, f, type, strings, opts); NormalizeWhitespace(res[3]); res[2] := RECBIBXMLHNDLR.Initials(res[3]); fi; return res; end); AddHandlerBuildRecBibXMLEntry(["author", "editor"], "namesaslists", function(entry, elt, namesaslists, strings, opts) local res, a; res := []; RECBIBXMLHNDLR.recode := false; for a in elt.content do if IsRecord(a) and a.name = "name" then Add(res, BuildRecBibXMLEntry(entry, a, namesaslists, strings, opts)); fi; od; RECBIBXMLHNDLR.recode := true; elt.AsList := res; return res; end); # a helper RECBIBXMLHNDLR.namstringlist := function(l, opts) local res, f, a; res := []; for a in l do if Length(a) = 1 then Add(res, a[1]); else if IsBound(opts.fullname) and opts.fullname = true then f := a[3]; else f := a[2]; fi; if IsBound(opts.namefirstlast) and opts.namefirstlast = true then Add(res, Concatenation(f, " ", a[1])); else Add(res, Concatenation(a[1], ", ", f)); fi; fi; od; return res; end; # now the default (BibTeX) version AddHandlerBuildRecBibXMLEntry(["author", "editor"], "default", function(entry, elt, default, strings, opts) local res, a; res := RECBIBXMLHNDLR.namstringlist(elt.AsList, opts); res := JoinStringsWithSeparator(res, " and "); if IsBound(opts.hasLaTeXmarkup) and opts.hasLaTeXmarkup = true then return Encode(Unicode(res), "LaTeXleavemarkup"); else return Encode(Unicode(res), "LaTeX"); fi; end); # and Text and HTML with only one 'and' AddHandlerBuildRecBibXMLEntry(["author", "editor"], ["Text", "HTML"], function(entry, elt, default, strings, opts) local res, f, a; res := RECBIBXMLHNDLR.namstringlist(elt.AsList, opts); if Length(res) > 2 then res := [JoinStringsWithSeparator(res{[1..Length(res)-1]}, ", "), res[Length(res)]]; fi; return JoinStringsWithSeparator(res, " and "); end); # now the special markup elements # AddHandlerBuildRecBibXMLEntry("C", "default", function(entry, elt, default, strings, opts) return Concatenation("{", ContentBuildRecBibXMLEntry(entry, elt, default, strings, opts), "}"); end); AddHandlerBuildRecBibXMLEntry("C", ["Text", "HTML"], "Ignore"); # , AddHandlerBuildRecBibXMLEntry(["M", "Math"], "default", function(entry, elt, default, strings, opts) local res; RECBIBXMLHNDLR.recode := false; res := Concatenation("$", ContentBuildRecBibXMLEntry(entry, elt, default, strings, opts), "$"); RECBIBXMLHNDLR.recode := true; return res; end); AddHandlerBuildRecBibXMLEntry("M", "HTML", function(entry, elt, default, strings, opts) local res; RECBIBXMLHNDLR.recode := false; res := TextM( ContentBuildRecBibXMLEntry(entry, elt, default, strings, opts)); RECBIBXMLHNDLR.recode := true; res := SubstitutionSublist(res, "&", "&"); res := SubstitutionSublist(res, "<", "<"); return res; end); AddHandlerBuildRecBibXMLEntry("M", "Text", function(entry, elt, default, strings, opts) return TextM( ContentBuildRecBibXMLEntry(entry, elt, default, strings, opts)); end); # AddHandlerBuildRecBibXMLEntry("value", "default", function(entry, elt, default, strings, opts) local pos; pos := PositionFirstComponent(strings, elt.attributes.key); if not IsBound(strings[pos]) or strings[pos][1] <> elt.attributes.key then return Concatenation("UNKNOWNVALUE(", elt.attributes.key, ")"); else return BuildRecBibXMLEntry(entry, rec(name := "PCDATA", content := strings[pos][2]), default, strings, opts); fi; end); # AddHandlerBuildRecBibXMLEntry("URL", "default", function(entry, elt, default, strings, opts) local f, txt, res, lopt; f := First(elt.content, a-> a.name = "LinkText"); if f <> fail then txt := ContentBuildRecBibXMLEntry(entry, f, default, strings, opts); f := First(elt.content, a-> a.name = "Link"); if f = fail then Error("#I : either use content and 'Text' attribute of elements ", "\n#I and .\n"); else RECBIBXMLHNDLR.recode := false; res := ContentBuildRecBibXMLEntry(entry, f, default, strings, opts); RECBIBXMLHNDLR.recode := true; fi; else RECBIBXMLHNDLR.recode := false; res := ContentBuildRecBibXMLEntry(entry, elt, default, strings, opts); RECBIBXMLHNDLR.recode := true; NormalizeWhitespace(res); if IsBound(opts.hasLaTeXmarkup) and opts.hasLaTeXmarkup = true then lopt := "LaTeXleavemarkup"; else lopt := "LaTeX"; fi; if IsBound(elt.attributes.Text) then txt := Encode(Unicode(elt.attributes.Text), lopt); else txt := Encode(Unicode(res), lopt); txt := Concatenation("\\texttt{", txt, "}"); # allow hyphenation of long entries without hyphen dash txt := GAPDoc2LaTeXProcs.URLBreaks(txt); fi; fi; if IsBound(opts.href) and opts.href = false then if res <> txt then txt := Concatenation(txt, " (", res, ")"); fi; return txt; fi; return Concatenation("\\href {", res, "} {", txt, "}"); end); AddHandlerBuildRecBibXMLEntry("URL", "HTML", function(entry, elt, html, strings, opts) local f, txt, res; f := First(elt.content, a-> a.name = "LinkText"); if f <> fail then txt := ContentBuildRecBibXMLEntry(entry, f, html, strings, opts); f := First(elt.content, a-> a.name = "Link"); if f = fail then Error("#I : either use content and 'Text' attribute of elements ", "\n#I and .\n"); else RECBIBXMLHNDLR.recode := false; res := ContentBuildRecBibXMLEntry(entry, f, html, strings, opts); RECBIBXMLHNDLR.recode := true; fi; else RECBIBXMLHNDLR.recode := false; res := ContentBuildRecBibXMLEntry(entry, elt, html, strings, opts); RECBIBXMLHNDLR.recode := true; NormalizeWhitespace(res); if IsBound(elt.attributes.Text) then txt := elt.attributes.Text; else txt := res; fi; txt := SubstitutionSublist(txt, "&", "&"); txt := SubstitutionSublist(txt, "<", "<"); fi; return Concatenation("", txt, ""); end); AddHandlerBuildRecBibXMLEntry("URL", "Text", function(entry, elt, text, strings, opts) local f, txt, res; f := First(elt.content, a-> a.name = "LinkText"); if f <> fail then txt := ContentBuildRecBibXMLEntry(entry, f, text, strings, opts); f := First(elt.content, a-> a.name = "Link"); if f = fail then Error("#I : either use content and 'Text' attribute of elements ", "\n#I and .\n"); else res := ContentBuildRecBibXMLEntry(entry, f, text, strings, opts); NormalizeWhitespace(res); fi; else res := ContentBuildRecBibXMLEntry(entry, elt, text, strings, opts); NormalizeWhitespace(res); if IsBound(elt.attributes.Text) then txt := elt.attributes.Text; else txt := res; fi; fi; if txt = res then return res; else return Concatenation(txt, " (", res, ")"); fi; end); AddHandlerBuildRecBibXMLEntry("Alt", "default", function(entry, elt, type, strings, opts) local poss, att, ok, res; poss := [type]; if IsBound(opts.useAlt) then Append(poss, opts.useAlt); fi; att := elt.attributes; if IsBound(att.Only) then ok := SplitString(att.Only, "", ", \n\r\t"); else ok := SplitString(att.Not, "", ", \n\r\t"); fi; if (IsBound(att.Only) and ForAny(poss, a-> a in ok)) then RECBIBXMLHNDLR.recode := false; res := ContentBuildRecBibXMLEntry(entry, elt, type, strings, opts); RECBIBXMLHNDLR.recode := true; return res; elif (IsBound(att.Not) and ForAll(poss, a-> not a in ok)) then return ContentBuildRecBibXMLEntry(entry, elt, type, strings, opts); else return ""; fi; end); AddHandlerBuildRecBibXMLEntry("Wrap", "default", function(entry, elt, type, strings, opts) local n, hdlr, res, a; n := Concatenation("Wrap:", elt.attributes.Name); hdlr := fail; if IsBound(RECBIBXMLHNDLR.(n)) then if IsBound(RECBIBXMLHNDLR.(n).(type)) then hdlr := RECBIBXMLHNDLR.(n).(type); elif IsBound(RECBIBXMLHNDLR.(n).default) then hdlr := RECBIBXMLHNDLR.(n).default; fi; fi; if hdlr = fail then # default is to ignore the markup return ContentBuildRecBibXMLEntry(entry, elt, type, strings, opts); else return hdlr(entry, elt, type, strings, opts); fi; end); RECBIBXMLHNDLR.Finish := rec(); # Finish functions AddHandlerBuildRecBibXMLEntry("Finish", ["BibTeX", "LaTeX"], function(entry, res, type, strings, opts) if IsBound(res.printedkey) then res.printedkey := Encode(Unicode(res.printedkey), "LaTeX"); fi; return res; end); RECBIBXMLHNDLR.recode := true; AddHandlerBuildRecBibXMLEntry("PCDATA", ["BibTeX", "LaTeX"], function(entry, elt, type, strings, opts) local lopt; if RECBIBXMLHNDLR.recode then if IsBound(opts.hasLaTeXmarkup) and opts.hasLaTeXmarkup = true then lopt := "LaTeXleavemarkup"; else lopt := "LaTeX"; fi; return Encode(Unicode(elt.content, "UTF-8"), lopt); else return elt.content; fi; end); AddHandlerBuildRecBibXMLEntry("PCDATA", "HTML", function(entry, elt, type, strings, opts) local res; if RECBIBXMLHNDLR.recode then res := SubstitutionSublist(elt.content, "<", "<"); return SubstitutionSublist(res, "&", "&"); else return elt.content; fi; end); # args: # xml tree of entry[, type][, strings (as list of pairs)][, options record] InstallGlobalFunction(RecBibXMLEntry, function(arg) local entry, type, strings, opts, res, i; entry := arg[1]; RECBIBXMLHNDLR.recode := true; type := fail; strings := fail; opts := fail; for i in [2..Length(arg)] do if IsString(arg[i]) and Length(arg[i]) > 0 then type := arg[i]; elif IsDenseList(arg[i]) and ForAll(arg[i], IsList) then strings := arg[i]; elif IsRecord(arg[i]) then opts := arg[i]; fi; od; if opts = fail then opts := rec(); fi; if type = fail or type = "default" then type := "BibTeX"; if not IsBound(opts.useAlt) then opts.useAlt := ["BibTeX", "LaTeX"]; fi; fi; if strings = fail then strings := []; fi; res := BuildRecBibXMLEntry(entry, entry, type, strings, opts); return res; end); ## <#GAPDoc Label="StringBibXMLEntry"> ## ## ## a string ## ## The arguments of this function have the same meaning as in but the return value is a string representing the ## bibliography entry in a format specified by restype (default is ## "BibTeX"). ##

        ## ## Currently, the following cases for restype are supported: ## ## "BibTeX"A string with &BibTeX; source code ## is generated. ## "Text" ## A text representation of the text is returned. If ## options.ansi is bound it must be a record. The components must have ## names Bib_Label, Bib_author, and so on for all fieldnames. ## The value of each component is a pair of strings which will enclose the ## content of the field in the result or the first of these strings in which ## case the default for the second is TextAttr.reset (see ). If you give an empty record here, some default ANSI color ## markup will be used. ## "HTML" ## An HTML representation of the bibliography entry is returned. The text ## from each field is enclosed in markup (mostly <span>-elements) ## with the class attribute set to the field name. This allows a ## detailed layout of the code via a style sheet file. ## ## ## We use again the file shown in the example for . ## ## gap> bib := ParseBibXMLextFiles("doc/testbib.xml");; ## gap> e := bib.entries[1];; strs := bib.strings;; ## gap> ebib := StringBibXMLEntry(e, "BibTeX", strs);; ## gap> PrintFormattedString(ebib); ## @article{ AB2000, ## author = {First, F. A. and Sec{\H o}nd, X. Y.}, ## title = {The {F}ritz package for the formula $x^y - ## l_{{i+1}} \rightarrow \mathbb{R}$}, ## journal = {Important Journal}, ## number = {13}, ## year = {2000}, ## pages = {13{\textendash}25}, ## note = {Online data at \href ## {http://www.publish.com/~ImpJ/123#data} {Bla ## Bla Publisher}}, ## mycomment = {very useful}, ## printedkey = {FS00} ## } ## gap> etxt := StringBibXMLEntry(e, "Text", strs);; ## gap> etxt := SimplifiedUnicodeString(Unicode(etxt), "latin1", "single");; ## gap> etxt := Encode(etxt, GAPInfo.TermEncoding);; ## gap> PrintFormattedString(etxt); ## [FS00] First, F. A. and Second, X. Y., The Fritz package for the ## formula x^y - l_{i+1} ? R, Important Journal, 13 (2000), 13-25, ## (Online data at Bla Bla Publisher ## (http://www.publish.com/~ImpJ/123#data)). ## ## ## ## ## <#/GAPDoc> InstallGlobalFunction(StringBibXMLEntry, function(arg) local r, type, opts; r := CallFuncList(RecBibXMLEntry, arg); type := r.From.type; opts := r.From.options; if IsBound(STRINGBIBXMLHDLR.(type)) then return STRINGBIBXMLHDLR.(type)(r); else InfoBibTools(1, "#W Don't know how to make a string of type ", type, "\n"); return fail; fi; end); STRINGBIBXMLHDLR.BibTeX := StringBibAsBib; STRINGBIBXMLHDLR.Text := StringBibAsText; STRINGBIBXMLHDLR.HTML := StringBibAsHTML; # Utility for a sort key, can be given as field 'sortkey' or element, respectively: as list of strings separated by ",". # If not given we use list of last names of authors/editors (or the title) # transformed to lower case. InstallGlobalFunction(SortKeyRecBib, function(r) local res; res := []; if IsBound(r.sortkey) then Append(res, List(SplitString(r.sortkey, "", ","), NormalizedWhitespace)); fi; if IsBound(r.authorAsList) then Append(res, List(r.authorAsList, a-> LowerASCIIString(a[1]))); fi; if IsBound(r.editorAsList) then Append(res, List(r.editorAsList, a-> LowerASCIIString(a[1]))); fi; if IsBound(r.year) then Add(res, r.year); fi; if IsBound(r.title) then Add(res, LowerASCIIString(NormalizedWhitespace(r.title))); fi; if Length(res) = 0 then Add(res, "zzzzzzzzzz"); fi; return res; end); GAPDoc-1.5.1/lib/UnicodeTools.gd0000644000175000017500000000477412026346064014711 0ustar billbill############################################################################# ## #W UnicodeTools.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2007, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files UnicodeTools.g{d,i} contain utilities for converting text ## between different encodings. They introduce unicode strings and ## characters as GAP objects. ## # for some recode information and functions for the ISO-8859 character sets BindGlobal("UNICODE_RECODE", rec()); # more a hack, some unicode characters can be translated to LaTeX with # this table: this is a set of pairs [ codepoint, LaTeX text ] DeclareGlobalVariable("LaTeXUnicodeTable"); # similar for simplification to ASCII DeclareGlobalVariable("SimplifiedUnicodeTable"); # and for translation to lower case DeclareGlobalVariable("LowercaseUnicodeTable"); # width of unicode characters on terminal DeclareGlobalVariable("WidthUnicodeTable"); ## declarations of unicode characters and strings as GAP objects DeclareFilter("IsUnicodeString", IsString and IsHomogeneousList and IsConstantTimeAccessList); DeclareFilter("IsUnicodeCharacter", IsInt and IsChar); BindGlobal("UnicodeStringType", NewType(NewFamily("dummy"), IsPositionalObjectRep and IsUnicodeString and IsMutable)); BindGlobal("UnicodeCharacterType", NewType(NewFamily("dummy"), IsComponentObjectRep and IsUnicodeCharacter)); BindGlobal("UNICODECHARCACHE", []); DeclareOperation("UChar", [IsObject]); DeclareOperation("UChar", [IsObject, IsObject]); # create unicode strings, from lists of integers or GAP strings, # optionally with encoding (default UTF-8) DeclareOperation("Unicode", [IsObject]); DeclareOperation("Unicode", [IsObject, IsObject]); DeclareGlobalFunction("IntListUnicodeString"); UNICODE_RECODE.Decoder := rec(); ###### Encoding ######### DeclareOperation("Encode", [IsUnicodeString]); DeclareOperation("Encode", [IsUnicodeString, IsString]); UNICODE_RECODE.Encoder := rec(); DeclareGlobalFunction("SimplifiedUnicodeString"); DeclareGlobalFunction("LowercaseUnicodeString"); DeclareGlobalFunction("UppercaseUnicodeString"); ###### Utilities for different lengths of UTF-8 encoded GAP strings ######## DeclareGlobalFunction("NrCharsUTF8String"); DeclareGlobalFunction("WidthUTF8String"); ###### Simplification for sorting and searching ##### DeclareGlobalFunction("LowerASCIIString"); GAPDoc-1.5.1/lib/PrintUtil.gi0000644000175000017500000001544112026346064014232 0ustar billbill############################################################################# ## #W PrintUtil.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files PrintUtil.gd and PrintUtil.gi contain utilities for printing ## objects or large amounts of data. ## ## a hack: type for objects which only exist to print something InstallValue(DUMMYTBPTYPE, NewType(NewFamily(""), IsObjToBePrinted)); InstallMethod(PrintObj, "IsObjToBePrinted", true, [IsObjToBePrinted], 0, function(obj) obj!.f(); end); ## <#GAPDoc Label="PrintTo1"> ## ## ## ## ## The argument fun must be a function without arguments. ## Everything which is printed by a call fun() is printed into ## the file filename. As with and this overwrites or ## appends to, respectively, a previous content of filename. ##

        ## ## These functions can be particularly efficient when many small pieces ## of text shall be written to a file, because no multiple reopening of ## the file is necessary. ## ## ## gap> f := function() local i; ## > for i in [1..100000] do Print(i, "\n"); od; end;; ## gap> PrintTo1("nonsense", f); # now check the local file `nonsense' ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(PrintTo1, function(file, fun) local obj; obj := rec(f := fun); Objectify(DUMMYTBPTYPE, obj); PrintTo(file, obj); end); InstallGlobalFunction(AppendTo1, function(file, fun) local obj; obj := rec(f := fun); Objectify(DUMMYTBPTYPE, obj); AppendTo(file, obj); end); ## <#GAPDoc Label="StringPrint"> ## ## ## ## ## These functions return a string containing the output of a ## Print or ViewObj call with the same arguments.

        ## ## This should be considered as a (temporary?) hack. It would be ## better to have methods for ## all &GAP; objects and to have a generic -function which just interprets these strings. ## ## ## <#/GAPDoc> ## InstallGlobalFunction(StringPrint, function(obj) local str, out; str := ""; out := OutputTextString(str, false); PrintTo1(out, function() Print(obj); end); CloseStream(out); return str; end); InstallGlobalFunction(StringView, function(obj) local str, out; str := ""; out := OutputTextString(str, false); PrintTo1(out, function() View(obj); end); CloseStream(out); return str; end); ## <#GAPDoc Label="PrintFormattedString"> ## ## ## ## This function prints a string str. The difference to ## Print(str); is that no additional line breaks are ## introduced by &GAP;'s standard printing mechanism. This can ## be used to print lines which are longer than the current ## screen width. In particular one can print text which contains ## escape sequences like those explained in , ## where lines may have more characters than visible ## characters. ## ## ## <#/GAPDoc> ## InstallGlobalFunction(PrintFormattedString, function(str) local n, l, i; Print("\c"); n := QuoInt(SizeScreen()[1], 2)+1; l := Length(str); i := 0; while i+n<=l do Print(str{[i+1..i+n]}, "\c"); i := i+n; od; if i ## ## ## ## ## These functions are similar to and , respectively. The ## difference is that the output is not sent directly to the screen, ## but is piped into the current pager; see . ## ## ## ## gap> Page([1..1421]+0); ## gap> PageDisplay(CharacterTable("Symmetric", 14)); ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(Page, function(arg) local str, out; str := ""; out := OutputTextString(str, true); CallFuncList(PrintTo, Concatenation([out],arg)); CloseStream(out); Pager(rec(lines := str, formatted:=true)); end); InstallGlobalFunction(PageDisplay, function(x) local str, out; # since output to proper string is terribly slow str := [,1]; out := OutputTextString(str, true); PrintTo1(out, function() Display(x);end); CloseStream(out); str := str{[3..Length(str)]}; CONV_STRING(str); Pager(rec(lines := str, formatted:=true)); end); ## <#GAPDoc Label="StringFile"> ## ## ## ## ## The function returns the content of ## file filename as a string. This works efficiently with ## arbitrary (binary or text) files. If something went wrong, this ## function returns fail. ##

        ## ## Conversely the function writes the ## content of a string str into the file filename. If ## the optional third argument append is given and equals ## true then the content of str is appended to the ## file. Otherwise previous content of the file is deleted. This ## function returns the number of bytes written or fail if ## something went wrong.

        ## ## Both functions are quite efficient, even with large files. ## ## ## <#/GAPDoc> ## ## moved into lib/string.g{d,i} # GAP3 tyœe dispatcher for viewing and printing records InstallMethod(ViewObj, [IsRecord], function(r) if IsBound(r.operations) and IsBound(r.operations.ViewObj) then r.operations.ViewObj(r); else TryNextMethod(); fi; end); InstallMethod(PrintObj, [IsRecord], function(r) if IsBound(r.operations) and IsBound(r.operations.PrintObj) then r.operations.PrintObj(r); else TryNextMethod(); fi; end); ## # example: ## r := rec( a := 1, b := 2, operations := rec( ## ViewObj := function(r) Print("view rec"); end, ## PrintObj := function(r) Print("print rec"); end) ); ## View(r, rec( c := 3 )); Print("\n"); ## Print(r, "\n", rec( c := 3 ), "\n"); GAPDoc-1.5.1/lib/Text.gi0000644000175000017500000010412512026346064013222 0ustar billbill############################################################################# ## #W Text.gi GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files Text.g{d,i} contain some utilities for dealing with text ## strings. ## ## ## <#GAPDoc Label="CharsColls"> ## ## ## ## ## ## ## ## ## ## These variables contain sets of characters which are useful for ## text processing. They are defined as follows.

        ## ## WHITESPACE ## " \n\t\r" ## CAPITALLETTERS ## "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ## SMALLLETTERS ## "abcdefghijklmnopqrstuvwxyz" ## LETTERS ## concatenation of CAPITALLETTERS and SMALLLETTERS ## DIGITS"0123456789" ## HEXDIGITS"0123456789ABCDEFabcdef" ## BOXCHARS ## "─│┌┬┐├┼┤└┴┘━┃┏┳┓┣╋┫┗┻┛═║╔╦╗╠╬╣╚╩╝" ## Encode(Unicode(9472 + [ 0, 2, 12, 44, 16, 28, ## 60, 36, 20, 52, 24, 1, 3, 15, 51, 19, 35, 75, 43, 23, 59, 27, 80, 81, ## 84, 102, 87, 96, 108, 99, 90, 105, 93 ]), "UTF-8"), ## these are in UTF-8 encoding, the i-th unicode character is ## BOXCHARS{[3*i-2..3*i]}. ## ## ## ## <#/GAPDoc> ## InstallValue(WHITESPACE, " \n\t\r"); InstallValue(CAPITALLETTERS, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); IsSet(CAPITALLETTERS); InstallValue(SMALLLETTERS, "abcdefghijklmnopqrstuvwxyz"); IsSet(SMALLLETTERS); InstallValue(LETTERS, Concatenation(CAPITALLETTERS, SMALLLETTERS)); IsSet(LETTERS); InstallValue(DIGITS, "0123456789"); InstallValue(HEXDIGITS, "0123456789ABCDEFabcdef"); InstallValue(BOXCHARS, "─│┌┬┐├┼┤└┴┘━┃┏┳┓┣╋┫┗┻┛═║╔╦╗╠╬╣╚╩╝"); # utilities to find lines InstallGlobalFunction(PositionLinenumber, function(str, nr) local pos, i; pos := 0; i := 1; while i < nr and pos <> fail do pos := Position(str, '\n', pos); i := i+1; od; if i = nr and IsInt(pos) then return pos+1; else return fail; fi; end); InstallGlobalFunction(NumberOfLines, function(str) local pos, i; if Length(str) = 0 then return 0; fi; pos := 0; i := 1; while pos <> fail do pos := Position(str, '\n', pos); i := i+1; od; if str[Length(str)] = '\n' then return i-2; else return i-1; fi; end); ## ## <#GAPDoc Label="TextAttr"> ## ## ## ## The record contains strings which can be ## printed to change the terminal attribute for the following ## characters. This only works with terminals which understand basic ## ANSI escape sequences. Try the following example to see if this is ## the case for the terminal you are using. It shows the effect of the ## foreground and background color attributes and of the .bold, ## .blink, .normal, .reverse and .underscore ## which can partly be mixed. ## ##

        ## extra := ["CSI", "reset", "delline", "home"];; ## for t in Difference(RecNames(TextAttr), extra) do ## Print(TextAttr.(t), "TextAttr.", t, TextAttr.reset,"\n"); ## od; ## ## ## The suggested defaults for colors 0..7 are black, red, green, ## brown, blue, magenta, cyan, white. But this may be different for ## your terminal configuration.

        ## ## The escape sequence .delline deletes the content of the ## current line and .home moves the cursor to the beginning of ## the current line. ## ##

        ## for i in [1..5] do ## Print(TextAttr.home, TextAttr.delline, String(i,-6), "\c"); ## Sleep(1); ## od; ## ## ## UseColorsInTerminal ## Whenever you use this in some printing routines you should ## make it optional. Use these attributes only when ## UserPreference("UseColorsInTerminal"); returns true. ##
        ##
        ## ## <#/GAPDoc> ## InstallValue(TextAttr, rec()); TextAttr.CSI := "\033["; TextAttr.reset := Concatenation(TextAttr.CSI, "0m"); TextAttr.normal := Concatenation(TextAttr.CSI, "22m"); TextAttr.bold := Concatenation(TextAttr.CSI, "1m"); TextAttr.underscore := Concatenation(TextAttr.CSI, "4m"); TextAttr.blink := Concatenation(TextAttr.CSI, "5m"); TextAttr.reverse := Concatenation(TextAttr.CSI, "7m"); # foreground colors 0..7 (default: black, red, green, brown, blue, magenta, # cyan, white TextAttr.0 := Concatenation(TextAttr.CSI, "30m"); TextAttr.1 := Concatenation(TextAttr.CSI, "31m"); TextAttr.2 := Concatenation(TextAttr.CSI, "32m"); TextAttr.3 := Concatenation(TextAttr.CSI, "33m"); TextAttr.4 := Concatenation(TextAttr.CSI, "34m"); TextAttr.5 := Concatenation(TextAttr.CSI, "35m"); TextAttr.6 := Concatenation(TextAttr.CSI, "36m"); TextAttr.7 := Concatenation(TextAttr.CSI, "37m"); # background colors 0..7 TextAttr.b0 := Concatenation(TextAttr.CSI, "40m"); TextAttr.b1 := Concatenation(TextAttr.CSI, "41m"); TextAttr.b2 := Concatenation(TextAttr.CSI, "42m"); TextAttr.b3 := Concatenation(TextAttr.CSI, "43m"); TextAttr.b4 := Concatenation(TextAttr.CSI, "44m"); TextAttr.b5 := Concatenation(TextAttr.CSI, "45m"); TextAttr.b6 := Concatenation(TextAttr.CSI, "46m"); TextAttr.b7 := Concatenation(TextAttr.CSI, "47m"); TextAttr.delline := Concatenation(TextAttr.CSI, "2K"); TextAttr.home := Concatenation(TextAttr.CSI, "1G"); ## <#GAPDoc Label="RepeatedString"> ## ## ## ## ## Here c must be either a character or a string and len ## is a non-negative number. Then returns ## a string of length len consisting of copies of c. ##

        ## In the variant the argument c ## is considered as string in UTF-8 encoding, and it can also be specified ## as unicode string or character, see . The result is ## a string in UTF-8 encoding which has visible width len as explained ## in . ## ## gap> RepeatedString('=',51); ## "===================================================" ## gap> RepeatedString("*=",51); ## "*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*" ## gap> s := "bäh";; ## gap> enc := GAPInfo.TermEncoding;; ## gap> if enc <> "UTF-8" then s := Encode(Unicode(s, enc), "UTF-8"); fi; ## gap> l := RepeatedUTF8String(s, 8);; ## gap> u := Unicode(l, "UTF-8");; ## gap> Print(Encode(u, enc), "\n"); ## bähbähbä ## ## ## ## ## <#/GAPDoc> InstallGlobalFunction(RepeatedString, function(s, n) local res, i; res := EmptyString(n+1); if n = 0 then return res; elif IsString(s) and Length(s) > 0 then if Length(s) > n then for i in [1..n] do res[i] := s[i]; od; return s; else Append(res, s); fi; elif IsChar(s) then res[1] := s; else Error("First argument must be character or non-empty string\n"); fi; while 2*Length(res) <= n do Append(res, res); od; Append(res, res{[1..n-Length(res)]}); return res; end); InstallGlobalFunction(RepeatedUTF8String, function(s, n) local res, w, r, u, tail, i; if IsUnicodeCharacter(s) then # need to check this first because s is also in IsChar s := Encode(Unicode([Int(s)]),"utf8"); elif IsChar(s) then res := ""; Add(res,s); s := res; elif IsUnicodeString(s) then s := Encode(s, "utf8"); elif not IsString(s) then Error("RepeatedUTF8String: First argument must be character, string \ or unicode \ncharacter or string.\n"); fi; w := WidthUTF8String(s); if w = 0 then if n = 0 then return ""; else Error("RepeatedUTF8String: First argument has width 0.\n"); fi; fi; r := QuotientRemainder(n, w); if r[2] <> 0 then u := Unicode(s, "utf8"); tail := ""; i := 1; while WidthUTF8String(tail) < r[2] do Append(tail, Encode(u{[i]}, "utf8")); i := i+1; od; else tail := ""; fi; if r[1] = 0 then return tail; fi; r := r[1]*Length(s)+Length(tail); res := EmptyString(r); Append(res, s); while 2*Length(res) <= r do Append(res, res); od; Append(res, res{[1..r-Length(tail)-Length(res)]}); Append(res, tail); return res; end); ## <#GAPDoc Label="PositionMatchingDelimiter"> ## ## ## position as integer or fail ## ## Here str must be a string and delim a string with ## two different characters. This function searches the smallest ## position r of the character delim[2] ## in str such that the number of occurrences of ## delim[2] in str between positions ## pos+1 and r is by one greater than the ## corresponding number of occurrences of delim[1].

        ## ## If such an r exists, it is returned. Otherwise fail ## is returned. ## ## ## gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0); ## fail ## gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1); ## 2 ## gap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6); ## 11 ## ## ## ## <#/GAPDoc> InstallGlobalFunction(PositionMatchingDelimiter, function(str, delim, pos) local b, e, p, l, level; b := delim[1]; e := delim[2]; p := pos+1; l := Length(str); level := 0; while true do if p > l then return fail; elif str[p] = b then level := level+1; elif str[p] = e then if level = 0 then return p; else level := level-1; fi; fi; p := p+1; od; end); ## <#GAPDoc Label="SubstitutionSublist"> ## ## ## the changed list ## ## This function looks for (non-overlapping) occurrences of a sublist ## sublist in a list list (compare ) and returns a list where these are ## substituted with the list new.

        ## ## The optional argument flag can either be "all" ## (this is the default if not given) or "one". In the second ## case only the first occurrence of sublist is substituted. ##

        ## ## If sublist does not occur in list then list ## itself is returned (and not a ShallowCopy(list)). ## ## ## gap> SubstitutionSublist("xababx", "ab", "a"); ## "xaax" ## ## ## ## <#/GAPDoc> InstallGlobalFunction(SubstitutionSublist, function(arg) local str, substr, lss, subs, all, p, s, off; str := arg[1]; substr := arg[2]; lss := Length(substr); subs := arg[3]; if Length(arg)>3 then all := arg[4]="all"; else all := true; fi; p := PositionSublist(str, substr); if p = fail then # return original object in case of no substitution return str; fi; s := str{[]}; off := 1-lss; while p<>fail do Append(s, str{[off+lss..p-1]}); Append(s, subs); ## str := str{[p+lss..Length(str)]}; off := p; if all then p := PositionSublist(str, substr, p+lss-1); else p := fail; fi; if p=fail then Append(s, str{[off+lss..Length(str)]}); fi; od; return s; end); ## <#GAPDoc Label="NumberDigits"> ## ## ## integer ## ## string ## ## The argument str of must be ## a string consisting only of an optional leading '-' ## and characters in 0123456789abcdefABCDEF, describing an ## integer in base base with 2 \leq base \leq ## 16. This function returns the corresponding integer.

        ## ## The function does the reverse. ## ## ## gap> NumberDigits("1A3F",16); ## 6719 ## gap> DigitsNumber(6719, 16); ## "1A3F" ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(NumberDigits, function(str, base) local res, x, nr, sign; res := 0; sign := 1; for x in str do nr := INT_CHAR(x) - 48; if nr = -3 then # '-' sign := -sign; else if nr>48 then nr := nr - 39; elif nr>15 then nr := nr - 7; fi; res := res*base + nr; fi; od; return sign*res; end); InstallGlobalFunction(DigitsNumber, function(n, base) local str, s; s := ""; if n<0 then Add(s, '-'); n := -n; fi; str := ""; while n <> 0 do Add(str, HEXDIGITS[(n mod base) + 1]); n := QuoInt(n, base); od; return Concatenation(s, Reversed(str)); end); ## <#GAPDoc Label="StripBeginEnd"> ## ## ## changed string ## ## Here list and strip must be lists. This function ## returns the sublist of list which does not contain the leading ## and trailing entries which are entries of strip. If the ## result is equal to list then list itself is ## returned. ## ## ## gap> StripBeginEnd(" ,a, b,c, ", ", "); ## "a, b,c" ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(StripBeginEnd, function(str, chars) local pb, l, pe; pb := 1; l := Length(str); while pb <= l and str[pb] in chars do pb := pb + 1; od; pe := l; while pe > 0 and str[pe] in chars do pe := pe - 1; od; if pb > 1 or pe < l then return str{[pb..pe]}; else return str; fi; end); ## <#GAPDoc Label="NormalizedWhitespace"> ## ## ## new string with white space normalized ## ## This function gets a string str and returns a new ## string which is a copy of str with normalized white ## space. Note that the library function works in place and changes its ## argument. ## ## ## <#/GAPDoc> ## # moved into GAP library ## InstallGlobalFunction(NormalizedWhitespace, function(str) ## local res; ## res := ShallowCopy(str); ## NormalizeWhitespace(res); ## return res; ## end); ## <#GAPDoc Label="WrapTextAttribute"> ## ## ## a string with markup ## ## The argument str must be a text as &GAP; string, possibly with ## markup by escape sequences as in . This function ## returns a string which is wrapped by the escape sequences attr ## and TextAttr.reset. It takes care of markup in the given string ## by appending attr also after each given TextAttr.reset in ## str. ## ## gap> str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY"); ## "XXX\033[32mBLUB\033[0mYYY" ## gap> str2 := WrapTextAttribute(str, TextAttr.1); ## "\033[31mXXX\033[32mBLUB\033[0m\033[31m\027YYY\033[0m" ## gap> str3 := WrapTextAttribute(str, TextAttr.underscore); ## "\033[4mXXX\033[32mBLUB\033[0m\033[4m\027YYY\033[0m" ## gap> # use Print(str); and so on to see how it looks like. ## ## ## ## ## <#/GAPDoc> InstallGlobalFunction(WrapTextAttribute, function(str, attr) if IsList(attr) and Length(attr) > 0 and IsString(attr[1]) and Length(attr[1]) > 1 and attr[1]{[1,2]} = TextAttr.CSI and attr[2] = TextAttr.reset then attr := attr[1]; fi; if IsString(attr) and Length(attr) > 1 and attr{[1,2]} = TextAttr.CSI then # we mark inner attribute starters by appending a char 23 str := SubstitutionSublist(str, TextAttr.reset, Concatenation( TextAttr.reset, attr, "\027")); str := Concatenation(attr, str, TextAttr.reset); elif IsString(attr) then str := Concatenation(attr,str,attr); elif IsList(attr) and Length(attr) = 2 and IsString(attr[1]) and IsString(attr[2]) then str := Concatenation(attr[1], str, attr[2]); else Error("WrapTextAttribute: argument attr must be string or list of two strings.\n"); fi; return str; end); ## <#GAPDoc Label="FormatParagraph"> ## ## ## the formatted paragraph as string ## ## This function formats a text given in the string str as a ## paragraph. The optional arguments have the following meaning: ## ## ## len ## the length of the lines of the formatted text, default is ## 78 (counted without a visible length of the strings ## specified in the attr argument) ## flush ## can be "left", "right", "center" or ## "both", telling that lines should be flushed left, flushed ## right, centered or left-right justified, respectively, default is ## "both" ## attr ## is a list of two strings; the first is prepended and the ## second appended to each line of the result (can for example ## be used for indenting, [" ", ""], or some markup, ## [TextAttr.bold, TextAttr.reset], default is ["", ## ""]) ## widthfun ## must be a function which returns the display width of text in ## str. The default is Length assuming that each byte ## corresponds to a character of width one. If str is given in ## UTF-8 encoding one can use here. ## ## ## ## This function tries to handle markup with the escape sequences ## explained in correctly. ## ## ## gap> str := "One two three four five six seven eight nine ten eleven.";; ## gap> Print(FormatParagraph(str, 25, "left", ["/* ", " */"])); ## /* One two three four five */ ## /* six seven eight nine ten */ ## /* eleven. */ ## ## ## ## <#/GAPDoc> ## BindGlobal("SPACESTRINGS", [" "]); InstallGlobalFunction(FormatParagraph, function(arg) local str, len, flush, attr, width, i, words, esc, l, j, k, lw, lines, s, ss, nsp, res, a, new, qr, b; str := arg[1]; # default line length len := 78; # default flush (flush left and right) flush := "both"; # default attribute (empty) attr := false; # default width function assumes that one byte is one character width := Length; # scan further arg's for i in [2..Length(arg)] do if IsInt(arg[i]) then len := arg[i]; elif arg[i] in ["both", "left", "right", "center"] then flush := arg[i]; elif IsList(arg[i]) then attr := arg[i]; elif IsFunction(arg[i]) then width := arg[i]; else Error("wrong argument", arg[i]); fi; od; for i in [Length(SPACESTRINGS)+1..len] do SPACESTRINGS[i] := Concatenation(SPACESTRINGS[i-1], " "); od; # we scan the string words := []; i := 1; esc := CHAR_INT(27); l := Length(str); while i<=l do if str[i] in WHITESPACE then # delete leading whitespace if Length(words)>0 then Add(words, 1); fi; i := i+1; while i<=l and str[i] in WHITESPACE do i := i+1; od; elif str[i] = esc then # sequences starting with ESC and stopping with the first letter # afterwards are not changed and considered to have length zero j := i+1; while j<=l and not str[j] in SMALLLETTERS and not str[j] in CAPITALLETTERS do j := j+1; od; if j>l then Error("string end inside escape sequence"); else Add(words, [0, [i..j]]); fi; i := j+1; else j := i+1; while j<=l and not (str[j] in WHITESPACE or str[j]=esc) do j := j+1; od; if ForAll([i..j-1], k-> IsChar(str[k])) then Add(words, [width(str{[i..j-1]}), [i..j-1]]); else Add(words, [j-i, [i..j-1]]); fi; i := j; fi; od; # remove trailing white space lw := Length(words); if lw>0 and IsInt(words[lw]) then Unbind(words[lw]); fi; # split into lines lines := []; i := 1; lw := Length(words); while i <= lw do s := words[i][1]; j := i+1; nsp := 0; while j <= lw and s+nsp < len do if IsInt(words[j]) then nsp := nsp+1; j := j+1; else # line breaks only at white space ss := s+nsp; k := j; while k <= lw and IsList(words[k]) do ss := ss+words[k][1]; k := k+1; od; if s=0 or ss <= len then s := ss-nsp; j := k; else break; fi; fi; od; if IsInt(words[j-1]) then Add(lines, [s,nsp-1,[i..j-2]]); i := j; else Add(lines, [s,nsp,[i..j-1]]); i := j+1; fi; od; # format lines res := ""; for i in [1..Length(lines)] do a := lines[i]; new := words{a[3]}; # now fill with spaces nsp := len - a[1] - a[2]; if nsp > 0 then if flush = "right" then new := Concatenation([nsp], new); elif flush = "both" and a[2] > 0 and i < Length(lines) then qr := QuotientRemainder(nsp, a[2]); for j in [1..Length(new)] do if IsInt(new[j]) then if qr[2]>0 then new[j] := new[j]+qr[1]+1; qr[2] := qr[2]-1; else new[j] := new[j]+qr[1]; fi; fi; od; elif flush = "center" and nsp > 1 then new := Concatenation([QuoInt(nsp,2)], new); fi; fi; # add text attribute begin if attr <> false and Length(new)>0 then if IsInt(new[1]) then new := Concatenation([new[1]], [attr[1]], new{[2..Length(new)]}); else Append(res, attr[1]); fi; fi; s := ""; for b in new do if IsInt(b) then Append(s, SPACESTRINGS[b]); elif IsString(b) then Append(s, b); else # range Append(s, str{b[2]}); fi; od; # add text attribute begin after each text attribute reset (if it # is an escape sequence) # and the end attribute if attr <> false then if Length(attr[1])>2 and attr[1]{[1,2]} = TextAttr.CSI then s := SubstitutionSublist(s, TextAttr.reset, attr[1]); fi; Append(s, attr[2]); fi; Add(s, '\n'); Append(res, s); od; ## if PositionSublist(res,"\033[33X")<> fail and PositionSublist(res,"\033[133X")= fail then Error("FP"); fi; ## if PositionSublist(res,"Emph")<> fail then Error("FP"); fi; return res; end); ## <#GAPDoc Label="StripEscapeSequences"> ## ## ## string without escape sequences ## ## This function returns the string one gets from the string ## str by removing all escape sequences which are explained ## in . If str does not contain such a ## sequence then str itself is returned. ## ## ## <#/GAPDoc> ## InstallGlobalFunction(StripEscapeSequences, function(str) local esc, res, i, ls, p; esc := CHAR_INT(27); res := ""; i := 1; ls := Length(str); while i <= ls do if str[i] = esc then i := i+1; while not str[i] in LETTERS do i := i+1; od; # first letter is last character of escape sequence i := i+1; else p := Position(str, esc, i); if p=fail then if i=1 then # don't copy if no escape there return str; else Append(res, str{[i..ls]}); return res; fi; else Append(res, str{[i..p-1]}); i := p; fi; fi; od; return res; end); InstallGlobalFunction(SubstituteEscapeSequences, function(str, subs) local orig, special, hash, esc, res, i, ls, seq, pos, p, b, e, width, cont, nb, ne, flush, pY, indlen, par, j, row, a, l, n, k, widthfun; # maybe we need to simplify some substitution strings because # of the current encoding, we cache the result if GAPInfo.TermEncoding <> "UTF-8" then if IsBound(subs.(GAPInfo.TermEncoding)) then subs := subs.(GAPInfo.TermEncoding); else orig := subs; subs := ShallowCopy(subs); for a in RecFields(subs) do if IsList(subs.(a)) then subs.(a) := [subs.(a)[1], List(subs.(a)[2], x-> Encode( SimplifiedUnicodeString(Unicode(x, "UTF-8"), GAPInfo.TermEncoding), GAPInfo.TermEncoding))]; fi; od; orig.(GAPInfo.TermEncoding) := subs; fi; fi; # we need a special handling of tags to reformat paragraphs and to # fill lines special := []; for a in ["format", "FillString"] do Add(special, Position(subs.hash[1], subs.(a)[1][1])); Add(special, Position(subs.hash[1], subs.(a)[1][2])); od; hash := subs.hash; esc := CHAR_INT(27); res := ""; i := 1; ls := Length(str); while i <= ls do if str[i] = esc and IsBound(str[i+1]) and str[i+1] = '[' then seq := ""; i := i+1; while not str[i] in LETTERS do i := i+1; Add(seq, str[i]); od; # first letter is last character of escape sequence i := i+1; if IsBound(str[i]) and str[i] = '\027' then cont := true; i := i+1; else cont := false; fi; pos := PositionSet(hash[1], seq); if pos <> fail and not pos in special then if cont and (Length(hash[2][pos]) = 0 or hash[2][pos][1] <> esc) then seq := ""; else seq := hash[2][pos]; fi; else Add(res, esc); Add(res, '['); fi; Append(res, seq); else p := Position(str, esc, i); if p=fail then if i=1 then # don't copy if no escape there return str; else Append(res, str{[i..ls]}); i := ls+1; fi; else Append(res, str{[i..p-1]}); i := p; fi; fi; od; # now we reformat paragraphs if GAPInfo.TermEncoding = "UTF-8" then widthfun := WidthUTF8String; else widthfun := Length; fi; str := res; res := ""; pos := 0; b := Concatenation(TextAttr.CSI, subs.format[1][1]); e := Concatenation(TextAttr.CSI, subs.format[1][2]); width := SizeScreen()[1] - 2; while pos <> fail do nb := PositionSublist(str, b, pos); if nb = fail then Append(res, str{[pos+1..Length(str)]}); pos := fail; else ne := PositionSublist(str, e, nb); # find flush mode if str[nb+Length(b)+2] = '0' then flush := subs.flush[2][1]; elif str[nb+Length(b)+2] = '1' then flush := "left"; elif str[nb+Length(b)+2] = '2' then flush := "center"; else flush := "both"; fi; Append(res, str{[pos+1..nb-1]}); # find indent pY := Position(str, 'Y', nb); # the +2 because all help text has additional indentation of 2 indlen := Int(str{[nb+Length(b)+4..pY-1]}) + 2; par := FormatParagraph(str{[pY+1..ne-1]}, width - indlen, flush, [RepeatedString(" ", indlen), ""], widthfun); # remove leading blanks if there is already something on this line # (e.g., initial indentation or a list mark) i := Length(res); while i > 0 and res[i] <> '\n' do i := i-1; od; i := widthfun(StripEscapeSequences(res{[i+1..Length(res)]})); while i > 0 and par[1] = ' ' do Remove(par,1); i := i-1; od; if Length(par) > 1 and par[Length(par)] = '\n' then Unbind(par[Length(par)]); fi; Append(res, par); pos := ne + Length(e) - 1; fi; od; # a finally we expand the fill strings b := Concatenation(TextAttr.CSI, subs.FillString[1][1]); if PositionSublist(res, b) <> fail then str := res; res := ""; pos := 0; nb := PositionSublist(str, b, pos); while nb <> fail do # find row i := nb-1; while i>0 and str[i] <> '\n' do i := i-1; od; j := nb+1; while Length(str) >= j and str[j] <> '\n' do j := j+1; od; Append(res, str{[pos+1..i]}); # split row into pieces to fill row := [str{[i+1..nb-1]}, str{[nb+Length(b)..j-1]}]; nb := PositionSublist(row[Length(row)], b); while nb <> fail do a := row[Length(row)]; row[Length(row)] := a{[1..nb-1]}; Add(row, a{[nb+Length(b)..Length(a)]}); nb := PositionSublist(row[Length(row)], b); od; # lengths of the fillings l := width - Sum(row, a-> widthfun(StripEscapeSequences(a))); n := Length(row)-1; ls := []; for k in [1..n] do Add(ls, QuoInt(l,n)); od; k := n; while Sum(ls) < l do ls[k] := ls[k]+1; k := k-1; od; # cannot do much when line already too long if l < 0 then ls := 0*ls; fi; for i in [1..n] do Append(res, row[i]); Append(res, RepeatedUTF8String(subs.FillString[2][1], ls[i])); od; Append(res, row[n+1]); pos := j-1; nb := PositionSublist(str, b, pos); od; Append(res, str{[pos+1..Length(str)]}); fi; return res; end); ## <#GAPDoc Label="WordsString"> ## ## ## list of strings containing the words ## ## This returns the list of words of a text stored in the string ## str. All non-letters are considered as word boundaries and ## are removed. ## ## gap> WordsString("one_two \n three!?"); ## [ "one", "two", "three" ] ## ## ## ## <#/GAPDoc> ## InstallGlobalFunction(WordsString, function(str) local nonletters, wds; nonletters := Set("0123456789 \n\r\t\b+*~^\\\"#'`'/?-_.:,;<>|=()[]{}&%$§!"); wds := SplitString(str, "", nonletters); return wds; end); # The GAP library will contain a new function CrcString. To make GAPDoc # running with current/older versions of GAP we use the following helper, # if necessary with a simple fallback. if IsBoundGlobal("CrcString") then InstallGlobalFunction(CrcText, CrcString); else InstallGlobalFunction(CrcText, function(s) local n, res; n := "guckCRCXQWYNVOH"; FileString(n, s); res := CrcFile(n); RemoveFile(n); return res; end); fi; ## <#GAPDoc Label="Base64String"> ## ## ## ## a string ## ## The first function translates arbitrary binary data given as a ## GAP string into a base 64 encoded string. This encoded ## string contains only printable ASCII characters and is used in ## various data transfer protocols (MIME encoded emails, weak ## password encryption, ...). We use the specification in http://tools.ietf.org/html/rfc2045.

        ## ## The second function has the reverse functionality. Here we also accept ## the characters -_ instead of +/ as last two ## characters. Whitespace is ignored. ## ## ## gap> b := Base64String("This is a secret!"); ## "VGhpcyBpcyBhIHNlY3JldCEA=" ## gap> StringBase64(b); ## "This is a secret!" ## ## ## ## <#/GAPDoc> BindGlobal("Base64LETTERS", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); BindGlobal("Base64REVERSE", [,,,,,,,,,-1,,,-1,,,,,,,,,,,,,,,,,,,-1,,,,,,,,,,,62,,62,,63,52,53,54,55,56,57,58,59,60,61,,,,-2,,,,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,,,,,63,,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51]); InstallGlobalFunction(Base64String, function(str) local istr, pad, i, res, a, d, c, b; istr := INTLIST_STRING(str, 1); pad := (-Length(istr)) mod 3; for i in [1..pad] do Add(istr,0); od; i := 1; res := []; while i < Length(istr) do if i > 1 and i mod 57 = 1 then Add(res, '\n'); fi; a := (istr[i]*256+istr[i+1])*256+istr[i+2]; d := RemInt(a, 64); a := (a-d)/64; c := RemInt(a, 64); a := (a-c)/64; b := RemInt(a, 64); a := (a-b)/64; Append(res, Base64LETTERS{[a,b,c,d]+1}); i := i+3; od; if i mod 57 = 1 and pad > 0 then Add(res, '\n'); fi; for i in [1..pad] do Add(res, '='); od; return res; end); InstallGlobalFunction(StringBase64, function(bstr) local istr, res, j, n, d, c, a; istr := Base64REVERSE{INTLIST_STRING(bstr, 1)}; res := []; j := 0; n := 0; for a in istr do if a <> -1 then if a = -2 then Unbind(res[Length(res)]); else n := n*64+a; j := j+1; if j = 4 then d := RemInt(n, 256); n := (n-d)/256; c := RemInt(n, 256); n := (n-c)/256; Append(res, [n,c,d]); j := 0; n := 0; fi; fi; fi; od; return STRING_SINTLIST(res); end); GAPDoc-1.5.1/lib/Text.gd0000644000175000017500000000271012026346064013212 0ustar billbill############################################################################# ## #W Text.gd GAPDoc Frank Lübeck ## ## #Y Copyright (C) 2000, Frank Lübeck, Lehrstuhl D für Mathematik, #Y RWTH Aachen ## ## The files Text.g{d,i} contain some utilities for dealing with text ## strings. ## ## some character lists DeclareGlobalVariable("WHITESPACE"); DeclareGlobalVariable("CAPITALLETTERS"); DeclareGlobalVariable("SMALLLETTERS"); DeclareGlobalVariable("LETTERS"); DeclareGlobalVariable("HEXDIGITS"); DeclareGlobalVariable("DIGITS"); DeclareGlobalVariable("BOXCHARS"); ## record containing ANSI terminal text attributes DeclareGlobalVariable("TextAttr"); ## some utility functions for strings DeclareGlobalFunction("PositionLinenumber"); DeclareGlobalFunction("NumberOfLines"); DeclareGlobalFunction("RepeatedString"); DeclareGlobalFunction("RepeatedUTF8String"); DeclareGlobalFunction("PositionMatchingDelimiter"); DeclareGlobalFunction("SubstitutionSublist"); DeclareGlobalFunction("NumberDigits"); DeclareGlobalFunction("DigitsNumber"); DeclareGlobalFunction("Base64String"); DeclareGlobalFunction("StringBase64"); DeclareGlobalFunction("StripBeginEnd"); DeclareGlobalFunction("WrapTextAttribute"); DeclareGlobalFunction("FormatParagraph"); DeclareGlobalFunction("StripEscapeSequences"); DeclareGlobalFunction("SubstituteEscapeSequences"); DeclareGlobalFunction("WordsString"); DeclareGlobalFunction("CrcText"); GAPDoc-1.5.1/gapdoc.dtd0000644000175000017500000004034712026346063013145 0ustar billbill GAP"> GAPDoc"> {\TeX}TeX"> {\LaTeX}LaTeX"> {Bib\TeX}BibTeX"> MeatAxe"> XGAP"> GAPDoc-1.5.1/styles/0000755000175000017500000000000012174444011012522 5ustar billbillGAPDoc-1.5.1/styles/chooser.html0000644000175000017500000000745612026346064015073 0ustar billbill GAPDoc Style Chooser

        Setting preferences for GAPDoc manuals

        Unfold subsections in menus only by mouse clicks: no (default)     yes

        Show GAP examples as in sessions with ColorPrompt(true): yes (default)     no

        Display side of table of contents within chapters: right (default)     left

        Main document font: Helvetica/sans serif (default)     Times/serif

        Paragraph formatting: left-right justified (default)     ragged right

        Apply settings to last page.

        GAPDoc-1.5.1/styles/rainbow.js0000644000175000017500000000533612026346064014535 0ustar billbill function randchar(str) { var i = Math.floor(Math.random() * str.length); while (i == str.length) i = Math.floor(Math.random() * str.length); return str[i]; } hexdigits = "0123456789abcdef"; function randlight() { return randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits)+ randchar("cdef")+randchar(hexdigits) } function randdark() { return randchar("012345789")+randchar(hexdigits)+ randchar("012345789")+randchar(hexdigits)+ randchar("102345789")+randchar(hexdigits) } document.write('\n'); GAPDoc-1.5.1/styles/nocolorprompt.css0000644000175000017500000000031312026346064016153 0ustar billbill /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000000; font-weight: normal; } span.GAPbrkprompt { color: #000000; font-weight: normal; } span.GAPinput { color: #000000; } GAPDoc-1.5.1/styles/manual.js0000644000175000017500000001003412026346064014340 0ustar billbill/* manual.js Frank Lübeck */ /* This file contains a few javascript functions which allow to switch between display styles for GAPDoc HTML manuals. If javascript is switched off in a browser or this file in not available in a manual directory, this is no problem. Users just cannot switch between several styles and don't see the corresponding button. A style with name mystyle can be added by providing two files (or only one of them). mystyle.js: Additional javascript code for the style, it is read in the HTML pages after this current file. The additional code may adjust the preprocessing function jscontent() with is called onload of a file. This is done by appending functions to jscontentfuncs (jscontentfuncs.push(newfunc);). Make sure, that your style is still usable without javascript. mystyle.css: CSS configuration, read after manual.css (so it can just reconfigure a few details, or overwrite everything). Then adjust chooser.html such that users can switch on and off mystyle. A user can change the preferred style permanently by using the [Style] link and choosing one. Or one can append '?GAPDocStyle=mystyle' to the URL when loading any file of the manual (so the style can be configured in the GAP user preferences). */ /* generic helper function */ function deleteCookie(nam) { document.cookie = nam+"=;Path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } /* read a value from a "nam1=val1;nam2=val2;..." string (e.g., the search part of an URL or a cookie */ function valueString(str,nam) { var cs = str.split(";"); for (var i=0; i < cs.length; i++) { var pos = cs[i].search(nam+"="); if (pos > -1) { pos = cs[i].indexOf("="); return cs[i].slice(pos+1); } } return 0; } /* when a non-default style is chosen via URL or a cookie, then the cookie is reset and the styles .js and .css files are read */ function overwriteStyle() { /* style in URL? */ var style = valueString(window.location.search, "GAPDocStyle"); /* otherwise check cookie */ if (style == 0) style = valueString(document.cookie, "GAPDocStyle"); if (style == 0) return; if (style == "default") deleteCookie("GAPDocStyle"); else { /* ok, we set the cookie for path "/" */ var path = "/"; /* or better like this ??? var here = window.location.pathname.split("/"); for (var i=0; i+3 < here.length; i++) path = path+"/"+here[i]; */ document.cookie = "GAPDocStyle="+style+";Path="+path; /* split into names of style files */ var stlist = style.split(","); /* read style's css and js files */ for (var i=0; i < stlist.length; i++) { document.writeln(''); document.writeln(''); } } } /* this adds a "[Style]" link next to the MathJax switcher */ function addStyleLink() { var line = document.getElementById("mathjaxlink"); var el = document.createElement("a"); var oncl = document.createAttribute("href"); var back = window.location.protocol+"//" if (window.location.protocol == "http:") { back = back+window.location.host; if (window.location.port != "") { back = back+":"+window.location.port; } } back = back+window.location.pathname; oncl.nodeValue = "chooser.html?BACK="+back; el.setAttributeNode(oncl); var cont = document.createTextNode(" [Style]"); el.appendChild(cont); line.appendChild(el); } var jscontentfuncs = new Array(); jscontentfuncs.push(addStyleLink); /* the default jscontent() only adds the [Style] link to the page */ function jscontent () { for (var i=0; i < jscontentfuncs.length; i++) jscontentfuncs[i](); } GAPDoc-1.5.1/styles/toggless.css0000644000175000017500000000167212026346064015076 0ustar billbill/* toggless.css Frank Lübeck */ /* Using javascript we change all div.ContSect to div.ContSectOpen or div.ContSectClosed. This way the config for div.ContSect in manual.css is no longer relevant. Here we add the CSS for the new elements. */ /* This layout is based on an idea by Burkhard Höfling. */ div.ContSectClosed { text-align: left; margin-left: 1em; } div.ContSectOpen { text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock { display: block; text-align: left; margin-left: 1em; } div.ContSectOpen div.ContSSBlock a { display: block; width: 100%; margin-left: 1em; } span.tocline a:hover { display: inline; background: #eeeeee; } span.ContSS a:hover { display: inline; background: #eeeeee; } span.toctoggle { font-size: 80%; display: inline-block; width: 1.2em; } span.toctoggle:hover { background-color: #aaaaaa; } GAPDoc-1.5.1/styles/lefttoc.css0000644000175000017500000000047412026346064014706 0ustar billbill/* leftmenu.css Frank Lübeck */ /* Change default CSS to show section menu on left side */ body { padding-left: 28%; } body.chap0 { padding-left: 2%; } div.ChapSects div.ContSect:hover div.ContSSBlock { left: 15%; } div.ChapSects { left: 1%; width: 25%; } GAPDoc-1.5.1/styles/ragged.css0000644000175000017500000000023112026346064014466 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { text-align: left; } GAPDoc-1.5.1/styles/manual.css0000644000175000017500000001575412026346064014532 0ustar billbill/* manual.css Frank Lübeck */ /* This is the default CSS style sheet for GAPDoc HTML manuals. */ /* basic settings, fonts, sizes, colors, ... */ body { position: relative; background: #ffffff; color: #000000; width: 70%; margin: 0pt; padding: 15pt; font-family: Helvetica,Verdana,Arial,sans-serif; text-align: justify; } /* no side toc on title page, bib and index */ body.chap0 { width: 95%; } body.chapBib { width: 95%; } body.chapInd { width: 95%; } h1 { font-size: 200%; } h2 { font-size: 160%; } h3 { font-size: 160%; } h4 { font-size: 130%; } h5 { font-size: 100%; } p.foot { font-size: 60%; font-style: normal; } a:link { color: #00008e; text-decoration: none; } a:visited { color: #00008e; text-decoration: none; } a:active { color: #000000; text-decoration: none; } a:hover { background: #eeeeee; } pre { font-family: "Courier New",Courier,monospace; font-size: 100%; color:#111111; } tt,code { font-family: "Courier New",Courier,monospace; font-size: 110%; color: #000000; } var { } /* general alignment classes */ .pcenter { text-align: center; } .pleft { text-align: left; } .pright { text-align: right; } /* layout for the definitions of functions, variables, ... */ div.func { background: #e0e0e0; margin: 0pt 0pt; } /* general and special table settings */ table { border-collapse: collapse; margin-left: auto; margin-right: auto; } td, th { border-style: none; } table.func { padding: 0pt 1ex; margin-left: 1ex; margin-right: 1ex; background: transparent; /* line-height: 1.1; */ width: 100%; } table.func td.tdright { padding-right: 2ex; } /* Example elements (for old converted manuals, now in div+pre */ table.example { background: #efefef; border-style: none; border-width: 0pt; padding: 0px; width: 100% } table.example td { border-style: none; border-width: 0pt; padding: 0ex 1ex; } /* becomes ... */ div.example { background: #efefef; padding: 0ex 1ex; /* overflow-x: auto; */ overflow: auto; } /* Links to chapters in all files at top and bottom. */ /* If there are too many chapters then use 'display: none' here. */ div.chlinktop { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; } div.chlinktop a { margin: 3px; } div.chlinktop a:hover { background: #ffffff; } div.chlinkbot { background: #dddddd; border-style: solid; border-width: thin; margin: 2px; text-align: center; /* width: 100%; */ } div.chlinkbot a { margin: 3px; } span.chlink1 { } /* and this is for the "Top", "Prev", "Next" links */ div.chlinkprevnexttop { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnexttop a:hover { background: #ffffff; } div.chlinkprevnextbot { background: #dddddd; border-style: solid; border-width: thin; text-align: center; margin: 2px; } div.chlinkprevnextbot a:hover { background: #ffffff; } /* table of contents, initially don't display subsections */ div.ContSSBlock { display: none; } div.ContSSBlock br { display: none; } /* format in separate lines */ span.tocline { display: block; width: 100%; } div.ContSSBlock a { display: block; } /* this is for the main table of contents */ div.ContChap { } div.ContChap div.ContSect:hover div.ContSSBlock { display: block; position: absolute; background: #eeeeee; border-style: solid; border-width: 1px 4px 4px 1px; border-color: #666666; padding-left: 0.5ex; color: #000000; left: 20%; width: 40%; z-index: 10000; } div.ContSSBlock a:hover { background: #ffffff; } /* and here for the side menu of contents in the chapter files */ div.ChapSects { } div.ChapSects a:hover { background: #eeeeee; } div.ChapSects a:hover { display: block; width: 100%; background: #eeeeee; color: #000000; } div.ChapSects div.ContSect:hover div.ContSSBlock { display: block; position: fixed; background: #eeeeee; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #666666; padding-left: 0ex; padding-right: 0.5ex; color: #000000; left: 54%; width: 25%; z-index: 10000; } div.ChapSects div.ContSect:hover div.ContSSBlock a { display: block; margin-left: 3px; } div.ChapSects div.ContSect:hover div.ContSSBlock a:hover { display: block; background: #ffffff; } div.ContSect { text-align: left; margin-left: 1em; } div.ChapSects { position: fixed; left: 75%; font-size: 90%; overflow: auto; top: 10px; bottom: 0px; } /* Table elements */ table.GAPDocTable { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTable td, table.GAPDocTable th { padding: 3pt; border-width: thin; border-style: solid; border-color: #555555; } caption.GAPDocTable { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } table.GAPDocTablenoborder { border-collapse: collapse; border-style: none; border-color: black; } table.GAPDocTablenoborder td, table.GAPDocTable th { padding: 3pt; border-width: 0pt; border-style: solid; border-color: #555555; } caption.GAPDocTablenoborder { caption-side: bottom; width: 70%; margin-top: 1em; margin-left: auto; margin-right: auto; } td.tdleft { text-align: left; } td.tdright { text-align: right; } td.tdcenter { text-align: center; } /* Colors and fonts can be overwritten for some types of elements. */ /* Verb elements */ pre.normal { color: #000000; } /* Func-like elements and Ref to Func-like */ code.func { color: #000000; } /* K elements */ code.keyw { color: #770000; } /* F elements */ code.file { color: #8e4510; } /* C elements */ code.code { } /* Item elements */ code.i { } /* Button elements */ strong.button { } /* Headings */ span.Heading { } /* Arg elements */ var.Arg { color: #006600; } /* Example elements, is in tables, see above */ div.Example { } /* Package elements */ strong.pkg { } /* URL-like elements */ span.URL { } /* Mark elements */ strong.Mark { } /* Ref elements */ b.Ref { } span.Ref { } /* this contains the contents page */ div.contents { } /* this contains the index page */ div.index { } /* ignore some text for non-css layout */ span.nocss { display: none; } /* colors for ColorPrompt like examples */ span.GAPprompt { color: #000097; font-weight: normal; } span.GAPbrkprompt { color: #970000; font-weight: normal; } span.GAPinput { color: #970000; } /* Bib entries */ p.BibEntry { } span.BibKey { color: #005522; } span.BibKeyLink { } b.BibAuthor { } i.BibTitle { } i.BibBookTitle { } span.BibEditor { } span.BibJournal { } span.BibType { } span.BibPublisher { } span.BibSchool { } span.BibEdition { } span.BibVolume { } span.BibSeries { } span.BibNumber { } span.BibPages { } span.BibOrganization { } span.BibAddress { } span.BibYear { } span.BibPublisher { } span.BibNote { } span.BibHowpublished { } GAPDoc-1.5.1/styles/times.css0000644000175000017500000000026112026346064014361 0ustar billbill/* times.css Frank Lübeck */ /* Change default CSS to use Times font. */ body { font-family: Times,Times New Roman,serif; } GAPDoc-1.5.1/styles/toggless.js0000644000175000017500000000420512026346064014715 0ustar billbill/* toggless.js Frank Lübeck */ /* this file contains two functions: mergeSideTOCHooks: this changes div.ContSect elements to the class ContSectClosed and includes a hook to toggle between ContSectClosed and ContSectOpen. openclosetoc: this function does the toggling, the rest is done by CSS */ closedTOCMarker = "▶ "; openTOCMarker = "▼ "; noTOCMarker = " "; /* merge hooks into side toc for opening/closing subsections with openclosetoc */ function mergeSideTOCHooks() { var hlist = document.getElementsByTagName("div"); for (var i = 0; i < hlist.length; i++) { if (hlist[i].className == "ContSect") { var chlds = hlist[i].childNodes; var el = document.createElement("span"); var oncl = document.createAttribute("class"); oncl.nodeValue = "toctoggle"; el.setAttributeNode(oncl); var cont; if (chlds.length > 2) { var oncl = document.createAttribute("onclick"); oncl.nodeValue = "openclosetoc(event)"; el.setAttributeNode(oncl); cont = document.createTextNode(closedTOCMarker); } else { cont = document.createTextNode(noTOCMarker); } el.appendChild(cont); hlist[i].firstChild.insertBefore(el, hlist[i].firstChild.firstChild); hlist[i].className = "ContSectClosed"; } } } function openclosetoc (event) { /* first two steps to make it work in most browsers */ var evt=window.event || event; if (!evt.target) evt.target=evt.srcElement; var markClosed = document.createTextNode(closedTOCMarker); var markOpen = document.createTextNode(openTOCMarker); var par = evt.target.parentNode.parentNode; if (par.className == "ContSectOpen") { par.className = "ContSectClosed"; evt.target.replaceChild(markClosed, evt.target.firstChild); } else if (par.className == "ContSectClosed") { par.className = "ContSectOpen"; evt.target.replaceChild(markOpen, evt.target.firstChild); } } /* adjust jscontent which is called onload */ jscontentfuncs.push(mergeSideTOCHooks); GAPDoc-1.5.1/makedocrel.g0000644000175000017500000000342512026346063013465 0ustar billbill############################################################################# ## #A makedocrel.g GAPDoc Frank Lübeck ## ## ## Rebuild the whole documentation, provided sufficiently good (pdf)LaTeX ## is available. This version produces relative paths to external ## documents, which is ok for the package in standard location. ## #SetInfoLevel(InfoGAPDoc,4); #SetGapDocLaTeXOptions("pdf","color", "latin1"); relpath := "../../.."; # main Print("\n========== converting main documentation for GAPDoc ==============\n"); maintree := MakeGAPDocDoc("doc", "gapdoc", ["../lib/BibTeX.gi", "../lib/BibTeX.gd", "../lib/BibXMLextTools.gi", "../lib/UnicodeTools.gi", "../lib/ComposeXML.gi", "../lib/GAPDoc2HTML.gi", "../lib/GAPDoc.gd", "../lib/GAPDoc.gi", "../lib/GAPDoc2LaTeX.gi", "../lib/GAPDoc2Text.gi", "../lib/PrintUtil.gi", "../lib/Text.gi", "../lib/XMLParser.gi", "../lib/Examples.gi", "../lib/TextThemes.g", "../lib/HelpBookHandler.g", "../lib/XMLParser.gd", "../lib/Make.g" ], "GAPDoc", relpath, "MathJax"); CopyHTMLStyleFiles("doc"); # now load it (for cross reference in example) Print("\n========== converting example document for GAPDoc ================\n"); HELP_ADD_BOOK("GAPDoc", "Package for Preparing GAP Documentation", DirectoriesPackageLibrary("gapdoc","doc")[1]); # example exampletree := MakeGAPDocDoc("example", "example", [], "GAPDocExample", relpath, "MathJax"); CopyHTMLStyleFiles("example"); # from first chapter Print("\n========== converting small example from introduction ============\n"); 3kp1tree := MakeGAPDocDoc("3k+1", "3k+1", [], "ThreeKPlusOne", relpath, "MathJax"); CopyHTMLStyleFiles("3k+1"); # .lab files for references from main manual GAPDocManualLab("GAPDoc"); GAPDoc-1.5.1/CHANGES0000644000175000017500000003472112026346063012205 0ustar billbill CHANGES of the GAPDoc package 1.5 -> 1.5.1 - Adjustments to GAP's new DeclareUserPreference setup. 1.4 -> 1.5 - Substituted the TestManual functions by new ones based on the new 'Test' functionality in the GAP library: ExtractExamples, RunExamples. (Used this to adjust all manual examples.) - Added a copy of GPL text. - Corrected/improved handling of certain external references, and some other small errors (reported by James Mitchell). - Improved detection of UTF-8 input. - Improved/adjusted manual examples. 1.3 -> 1.4 - Made license statement more direct. - Slight change of the dtd: The elements now permit elements in their content. The converters were adjusted accordingly. - Several layout changes in text version: More unicode characters are used, e.g., for fill strings and table borders (see BOXCHARS). Also mathematical symbols from unicode are used more often. Less colors are used in default text theme. - Several text themes are available in the distribution (more by others are welcome). The preferred theme can be configured by the user via SetGAPDocTextTheme and at startup via a user preference SetUserPreference("GAPDoc", "TextTheme", ...). - Improved markup of elements in function definitions in Text and HTML conversion. - The text version of the manuals now contains more hooks (by pseudo escape sequences) for preprocessing before display. Paragraphs are now reformatted to current screen width. Unicode to latinX translation is now done with multi-character substitution. And markup with visible characters becomes possible, e.g. the "old" text theme (tables are not reformatted which can lead to some problems). - Slightly changed layout of the title page in LaTeX/PDF manuals. - The LaTeX/PDF manuals use less colors by default. - The tables of content contain now references and index (not convinced that this is ok, but was often requested). - Preferred style for viewing the HTML manuals can be configured by the user via user preferences: SetUserPreference("GAPDoc", "HTMLStyle", ...) and SetUserPreference("GAPDoc", "UseMathJax", true/false) - The HTML manuals support style switching (via URL and cookie) with javascript and cookie enabled browsers. Several styles (and combinations) are offered in the distribution (more by others are welcome). - The HTML manuals contain now a hook to use javascript and a few more hooks for CSS style sheets. - All output versions contain now markup for coloring GAP examples as with ColorPrompt(true). (Easy to switch off for text and HTML in user config.) - Link from MathJax HTML manuals to central server http://cdn.mathjax.org to get scripts and fonts. - Added a link to the "Contents" on top and bottom of each HTML manual page. - For LaTeX/PDF conversion of manuals we use now the "psnfss" for postscript fonts. - Added more hooks and simplified customization of LaTeX/PDF manuals (see "SetGapDocLaTeXOptions"). - PDF-verison is now by default generated with bookmarks (for acroread and other viewers), but such that they are not opened by default. - Fixed a bug when displaying multiple hits while ANSI_COLORS=false. 1.2 -> 1.3 - Improved the example ./gapdoc.css file (also used for the GAPDoc manuals): when hovering over a link to a section its subsections are now shown in a separate block. - The Arg attribute in and other elements now allows for GAP options. - Added support for HTML output using MathJax (http://www.mathjax.org/). MakeGAPDocDoc and GAPDoc2HTML now allow an optional argument "MathJax". - Better bound for long index entries to be hyphenated (can now also be changed by setting GAPDoc2LaTeXProcs.MaxIndexEntryWidth). - Improved the \description environment in LaTeX output using the enumitem LaTeX packages. Now works with very long labels. - Now a warning is given if ComposedDocument finds several pieces of documentation with the same label. - Fixed a problem which caused ParseError in rare cases to display the wrong line (reported by Laurent Bartholdi). - Tables without | or HorLine are now distinguished in HTML version, such that they can be configured to be displayed without borders. - There is a new attribute Mode="M" for elements, if this is given the formula is processed as in elements. 1.1 -> 1.2 - New utility to access the MathSciNet data base from within GAP (only if your computer has access, of course), see documentation of 'SearchMR'. - Now letters counting appendices are also printed without trailing dot in references. - Slightly changed HorLine's in text-version of output. - Various changes in tools for bibliography data (many suggested by Thomas Breuer): - Avoid some syntax errors caused by 'NormalizedNameAndKey' in case of first names starting with non-ASCII character (but still cannot correctly handle these cases, use BibXMLext instead). - Improved sorting of bib-entries in HTML/Text output. - Better heuristic functions for translating characters in LaTeX code in BibTeX entries to unicode, see 'HeuristicTranslationsLaTeX2XML'. - Handle (rare) short MathReview numbers. - Better formatted output for HTML version of bib-entries. - Fixed the case of an empty 'strings' list in 'RecBibXMLEntry'. - Apply recoding to strings from BibXMLext data. - Use default markup in StringBibAsText (undocumented, internally used by StringBibXMLEntry) when called with one argument. - Added more simplifications and LaTeX translations of unicode characters. - Improved "RepeatedString". - XML parser: - Could show wrong line number for original position of code with error. - Now the ":" is allowed in element and attribute names, this allows to implement utilities for dealing with XML name spaces (http://www.w3.org/TR/2006/REC-xml-names-20060816/). - Corrected bug in normalization of argument lists (if "," was used as separator). Also the layout was changed in case of leading optional arguments (reported by Laurent Bartholdi). 1.0 -> 1.1 - We allow unicode characters which have useful translations to LaTeX and as simplified string (with one character, for the moment) in mathematical formulae. Introduced entities &CC;, &ZZ;, &NN;, &PP;, &QQ;, &HH;, &RR; for \mathbb characters. - Now chapter numbers in references to chapters are without trailing dot in text and HTML converters. - Fixed bug with vertical spacing for in text converter. - GAPDoc can now be used with other languages than English, see 'SetGapDocLanguage' for details. - Various documentation improvements. - New options "utf8" and "nopslatex" for LaTeX converter, see 'SetGapDocLaTeXOptions'. - Introduced "LaTeXUTF8" encoding (uses known translations but leaves other characters as they are). - Removed support of '\N, \Z, ...' for '{\mathbb N}, {\mathbb Z}, ... (was not documented before). But see &NN; above. - Introduced 'WrapTextAttribute' which takes care of existing escape sequences in the text to wrap. Use it for the text converter to handle elements with markup which are contained in each other correctly. 0.99999 -> 1.0 - Changed the status of the package from "deposited" to "accepted". - GAPDoc language (only few changes, all are fully backward compatible): - Made entities for LaTeX special characters ($tamp;, &percent; and so on) unnecessary (but kept them--with simplified definitions--for backward compatibility). Now just write characters in content and attribute values directly, except for math elements which contain LaTeX code. - A does now allow an optional (I would not like if this would be used extensively, but can be sensible for ManSections which explain several commands.) - does now allow an optional element to specify subkeys with further markup (not possible in 'Subkey' attribute). - , , now allow optional elements and to specify text with further markup (not possible in 'Text' attribute). - New element . Can be used everywhere (e.g., for additional data like source code, or to comment non finished parts of the document). - MakeGAPDocDoc: - Now the text converter is called first to produce labels for (sub-)sections which are independent of their number (see 'Text converter:' below). - Now only the PDF manual is compiled from the LaTeX version. - The .log file written by pdflatex is checked for errors, warnings and overfull boxes; these are displayed. - Bibliography data (see '?GAPDoc: Utilities for Bibliographies'): - Defined a 'BibXMLext' format for bibliographies with DTD bibxmlext.dtd (better data format if not used for LaTeX). - Utilities for parsing BibXMLext data and translating them to various formats (BibTeX, Text, HTML). Includes a utility to approximate BibXMLext data from given BibTeX data. - BibXMLext databases can be specified in (and I suggest to use this possibility). - Labels for references in Text and HTML converter are now similar to those produced by BibTeX. - New functions for extracting and checking the code in all elements, see 'ManualExamples', 'TestManualExamples'. - Unicode strings: - Introduced unicode strings and characters as GAP objects, see '?Unicode'. - Translations between unicode strings and GAP strings in various character encodings, see '?Encode'. (Mainly UTF-8, ISO-8859-X, "XML" and "URL" encodings.) - Some non-injective (partial) maps from unicode: a "LaTeX" encoding, simplifications to ASCII or latin1, conversions to lowercase and uppercase characters. - The internal encoding for the XML parsed data is now UTF-8, this is also recommended for input (all GAPDoc files are now in UTF-8 encoding), but all latin? encodings work as well. - LaTeX converter: - Convert long URLs such that LaTeX can hyphenate them after slashes (but without a maybe confusing hyphenation dash). - Documented SetGapDocLaTeXOptions, see ?GAPDoc2LaTeX. (E.g., settings for hyperref, using colors or not.) - The default LaTeX markup for , is now by slanted typewriter font. - Very long identifier names are now hyphenated in the (two-column) index. - The pdf-manuals now know their paper size. - The pdf-manuals contain the robust labels generated by the text converter (see below). E.g., with xpdf one can display a labeled text directly: xpdf manual.pdf +L.