This commit is contained in:
ivan 2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

28
.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
# CVS default ignores begin
tags
TAGS
.make.state
.nse_depinfo
*~
#*
.#*
,*
_$*
*$
*.old
*.bak
*.BAK
*.orig
*.rej
.del-*
*.a
*.olb
*.o
*.obj
*.so
*.exe
*.Z
*.elc
*.ln
core
# CVS default ignores end

93
bml/MANIFEST Executable file
View File

@ -0,0 +1,93 @@
bml-tester.pl
doc/bml-notes.txt
doc/docbook/appx.gfdl.xml
doc/docbook/book.ent
doc/docbook/book.xml
doc/docbook/bookinfo.xml
doc/docbook/build.pl
doc/docbook/BUILD.txt
doc/docbook/core.xml
doc/docbook/flags.xml
doc/docbook/index.xml
doc/docbook/preface.xml
doc/docbook/tutorial.xml
lib/Apache/BML.pm
Makefile.PL
MANIFEST
t/00_require.t
t/10_simple.t
t/20_render.t
test/bml-profile.pl
test/brads/_config.bml
test/brads/scheme.look
test/brads/test1.bml
test/brads/test1.correct
test/codeblocks/_config.bml
test/codeblocks/carry-variables.bml
test/codeblocks/carry-variables.correct
test/codeblocks/complex1.bml
test/codeblocks/complex1.correct
test/codeblocks/complex2.bml
test/codeblocks/complex2.correct
test/codeblocks/re-expand.bml
test/codeblocks/re-expand.correct
test/codeblocks/scheme.look
test/codeblocks/simple.bml
test/codeblocks/simple.correct
test/comments/_config.bml
test/comments/basic.bml
test/comments/basic.correct
test/comments/rendered.bml
test/comments/rendered.correct
test/comments/scheme.look
test/escape/_config.bml
test/escape/ea.bml
test/escape/ea.correct
test/escape/eb.bml
test/escape/eb.correct
test/escape/eh.bml
test/escape/eh.correct
test/escape/eu.bml
test/escape/eu.correct
test/escape/scheme.look
test/fake_root/_config.bml
test/fake_root/bluewhite.look
test/fake_root/bml-simple.bml
test/fake_root/bml-simple.correct
test/fake_root/bml-test.bml
test/fake_root/bml-test.correct
test/fake_root/global.look
test/include/_config.bml
test/include/loremipsum.txt
test/include/plain.bml
test/include/scheme.look
test/info/_config.bml
test/info/localblocks.bml
test/info/localblocks.correct
test/info/package.bml
test/info/package.correct
test/info/scheme.look
test/recursion/_config.bml
test/recursion/infinite.bml
test/recursion/infinite.correct
test/recursion/nested.bml
test/recursion/nested.correct
test/recursion/scheme.look
test/syntax-errors/_config.bml
test/syntax-errors/dangling-tagopen.bml
test/syntax-errors/dangling-tagopen.correct
test/syntax-errors/no-close.bml
test/syntax-errors/no-close.correct
test/syntax-errors/onlyopen.bml
test/syntax-errors/onlyopen.correct
test/syntax-errors/scheme.look
test/syntax-errors/spaces.bml
test/syntax-errors/spaces.correct
test/tutorial1/_config.bml
test/tutorial1/index.bml
test/tutorial1/index.correct
test/tutorial1/scheme.look
test/tutorial2/_config.bml
test/tutorial2/index.bml
test/tutorial2/index.correct
test/tutorial2/scheme.look

11
bml/MANIFEST.SKIP Executable file
View File

@ -0,0 +1,11 @@
^#
\bCVS\b
^MANIFEST\.
^Makefile$
~$
\.html$
\.old$
^blib/
_blib$
^MakeMaker-\d
^\.exists

36
bml/Makefile.PL Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/perl
#
# Perl Makefile for BML
# $Id: Makefile.PL,v 1.1 2004/05/26 17:33:51 deveiant Exp $
#
# Invoke with 'perl Makefile.PL'
#
# See ExtUtils::MakeMaker (3) for more information on how to influence
# the contents of the Makefile that is written
#
use ExtUtils::MakeMaker;
my $version = do { my @r = (q$Revision: 1.1 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
my %config = (
NAME => 'BML',
VERSION => "0." . $version,
AUTHOR => 'Brad Fitzpatrick <brad@danga.com>',
ABSTRACT => 'a server-side markup language',
PREREQ_PM => {
Apache => 0,
Apache::URI => 0,
Digest::MD5 => 0,
File::Spec => 0,
},
dist => {
CI => "cvs commit",
RCS_LABEL => 'cvs tag r$(VERSION_SYM)',
SUFFIX => ".bz2",
DIST_DEFAULT => 'all tardist',
COMPRESS => "bzip2",
},
);
WriteMakefile( %config );

61
bml/doc/bml-notes.txt Executable file
View File

@ -0,0 +1,61 @@
TEMPLATE FLAGS
==============
This documents the flags in braces at the beginning of .look
file block template definitions. The flags fall into one
of three classes:
1) Varible definition types:
F: full, mix of multi & single line property definitions:
<?template
<=foo
Multi
line
string
<=foo
bar=>Single line string
template?>
P: pipe delimited, properites are named DATA<n>, where <n> starts at
1 and increases.
<?template DATA1|second arg|DATA3 template?>
D: one proprety, and it's named DATA
<?template I am the DATA template?>
2) Static template definitions:
S: static: output won't have more BML to expand, or properties to fill-in,
so don't try.
R: less static: add pRoperties, but then don't BML expand.
3) Controlling expansion vs. interpolation order:
p: pre-parsed. BML-expand parameters first, then interpolate into
template. by default, parameters are interpolated first, then
everything is expanded. but if you use %%TITLE%% twice in your
PAGE, for example, and your .bml file defines TITLE=> with a
_CODE block, it will be run twice, so it's generally a good idea
to make PAGE definitions pre-parsed. also, then, you avoid
re-running most of your output through the BML expander a second
time.
s: expand embedded parameterless static blocks in definition early.
so when the template file is read, any blocks of the form (=FOO=)
are expanded ahead of time. Useful in conjunction with the {S}
flag. consider:
# Our image server:
IMGPREFIX=>{S}http://www.site.com:8080/
# Some block that has an image:
SPACER=>{Ss}<img src='<?imgprefix?>/spacer.gif' width='1' height='10'>
The SPACER block isn't really static, but because {s} is used and IMGPREFIX
is static, then SPACER can also be static.

5
bml/doc/docbook/BUILD.txt Executable file
View File

@ -0,0 +1,5 @@
To build the BML documentation from these DocBook sources, you'll need
apidoc.pl from wcmtools here, and then run generate.pl.
FIXME: better notes

450
bml/doc/docbook/appx.gfdl.xml Executable file
View File

@ -0,0 +1,450 @@
<appendix id="appx.gfdl">
<title>GNU Free Documentation License</title>
<!-- - GNU Project - Free Software Foundation (FSF) -->
<!-- LINK REV="made" HREF="mailto:webmasters@gnu.org" -->
<!-- sect1>
<title>GNU Free Documentation License</title -->
<para>Version 1.1, March 2000</para>
<blockquote>
<para>Copyright (C) 2000 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.</para>
</blockquote>
<sect1 id="appx.gfdl-0">
<title>PREAMBLE</title>
<para>The purpose of this License is to make a manual, textbook,
or other written document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or
noncommercially. Secondarily, this License preserves for the
author and publisher a way to get credit for their work, while not
being considered responsible for modifications made by
others.</para>
<para>This License is a kind of "copyleft", which means that
derivative works of the document must themselves be free in the
same sense. It complements the GNU General Public License, which
is a copyleft license designed for free software.</para>
<para>We have designed this License in order to use it for manuals
for free software, because free software needs free documentation:
a free program should come with manuals providing the same
freedoms that the software does. But this License is not limited
to software manuals; it can be used for any textual work,
regardless of subject matter or whether it is published as a
printed book. We recommend this License principally for works
whose purpose is instruction or reference.</para>
</sect1>
<sect1 id="appx.gfdl-1">
<title>APPLICABILITY AND DEFINITIONS</title>
<para>This License applies to any manual or other work that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. The "Document",
below, refers to any such manual or work. Any member of the
public is a licensee, and is addressed as "you".</para>
<para>A "Modified Version" of the Document means any work
containing the Document or a portion of it, either copied
verbatim, or with modifications and/or translated into another
language.</para>
<para>A "Secondary Section" is a named appendix or a front-matter
section of the Document that deals exclusively with the
relationship of the publishers or authors of the Document to the
Document's overall subject (or to related matters) and contains
nothing that could fall directly within that overall subject.
(For example, if the Document is in part a textbook of
mathematics, a Secondary Section may not explain any mathematics.)
The relationship could be a matter of historical connection with
the subject or with related matters, or of legal, commercial,
philosophical, ethical or political position regarding
them.</para>
<para>The "Invariant Sections" are certain Secondary Sections
whose titles are designated, as being those of Invariant Sections,
in the notice that says that the Document is released under this
License.</para>
<para>The "Cover Texts" are certain short passages of text that
are listed, as Front-Cover Texts or Back-Cover Texts, in the
notice that says that the Document is released under this
License.</para>
<para>A "Transparent" copy of the Document means a
machine-readable copy, represented in a format whose specification
is available to the general public, whose contents can be viewed
and edited directly and straightforwardly with generic text
editors or (for images composed of pixels) generic paint programs
or (for drawings) some widely available drawing editor, and that
is suitable for input to text formatters or for automatic
translation to a variety of formats suitable for input to text
formatters. A copy made in an otherwise Transparent file format
whose markup has been designed to thwart or discourage subsequent
modification by readers is not Transparent. A copy that is not
"Transparent" is called "Opaque".</para>
<para>Examples of suitable formats for Transparent copies include
plain ASCII without markup, Texinfo input format, LaTeX input
format, SGML or XML using a publicly available DTD, and
standard-conforming simple HTML designed for human modification.
Opaque formats include PostScript, PDF, proprietary formats that
can be read and edited only by proprietary word processors, SGML
or XML for which the DTD and/or processing tools are not generally
available, and the machine-generated HTML produced by some word
processors for output purposes only.</para>
<para>The "Title Page" means, for a printed book, the title page
itself, plus such following pages as are needed to hold, legibly,
the material this License requires to appear in the title page.
For works in formats which do not have any title page as such,
"Title Page" means the text near the most prominent appearance of
the work's title, preceding the beginning of the body of the
text.</para>
</sect1>
<sect1 id="appx.gfdl-2">
<title>VERBATIM COPYING</title>
<para>You may copy and distribute the Document in any medium,
either commercially or noncommercially, provided that this
License, the copyright notices, and the license notice saying this
License applies to the Document are reproduced in all copies, and
that you add no other conditions whatsoever to those of this
License. You may not use technical measures to obstruct or
control the reading or further copying of the copies you make or
distribute. However, you may accept compensation in exchange for
copies. If you distribute a large enough number of copies you
must also follow the conditions in section 3.</para>
<para>You may also lend copies, under the same conditions stated
above, and you may publicly display copies.</para>
</sect1>
<sect1 id="appx.gfdl-3">
<title>COPYING IN QUANTITY</title>
<para>If you publish printed copies of the Document numbering more
than 100, and the Document's license notice requires Cover Texts,
you must enclose the copies in covers that carry, clearly and
legibly, all these Cover Texts: Front-Cover Texts on the front
cover, and Back-Cover Texts on the back cover. Both covers must
also clearly and legibly identify you as the publisher of these
copies. The front cover must present the full title with all
words of the title equally prominent and visible. You may add
other material on the covers in addition. Copying with changes
limited to the covers, as long as they preserve the title of the
Document and satisfy these conditions, can be treated as verbatim
copying in other respects.</para>
<para>If the required texts for either cover are too voluminous to
fit legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto
adjacent pages.</para>
<para>If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a
machine-readable Transparent copy along with each Opaque copy, or
state in or with each Opaque copy a publicly-accessible
computer-network location containing a complete Transparent copy
of the Document, free of added material, which the general
network-using public has access to download anonymously at no
charge using public-standard network protocols. If you use the
latter option, you must take reasonably prudent steps, when you
begin distribution of Opaque copies in quantity, to ensure that
this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you
distribute an Opaque copy (directly or through your agents or
retailers) of that edition to the public.</para>
<para>It is requested, but not required, that you contact the
authors of the Document well before redistributing any large
number of copies, to give them a chance to provide you with an
updated version of the Document.</para>
</sect1>
<sect1 id="appx.gfdl-4">
<title>MODIFICATIONS</title>
<para>You may copy and distribute a Modified Version of the
Document under the conditions of sections 2 and 3 above, provided
that you release the Modified Version under precisely this
License, with the Modified Version filling the role of the
Document, thus licensing distribution and modification of the
Modified Version to whoever possesses a copy of it. In addition,
you must do these things in the Modified Version:</para>
<orderedlist numeration="upperalpha">
<listitem><para>Use in the Title Page
(and on the covers, if any) a title distinct from that of the
Document, and from those of previous versions (which should, if
there were any, be listed in the History section of the
Document). You may use the same title as a previous version if
the original publisher of that version gives permission.</para>
</listitem>
<listitem><para>List on the Title Page,
as authors, one or more persons or entities responsible for
authorship of the modifications in the Modified Version,
together with at least five of the principal authors of the
Document (all of its principal authors, if it has less than
five).</para>
</listitem>
<listitem><para>State on the Title page
the name of the publisher of the Modified Version, as the
publisher.</para>
</listitem>
<listitem><para>Preserve all the
copyright notices of the Document.</para>
</listitem>
<listitem><para>Add an appropriate
copyright notice for your modifications adjacent to the other
copyright notices.</para>
</listitem>
<listitem><para>Include, immediately
after the copyright notices, a license notice giving the public
permission to use the Modified Version under the terms of this
License, in the form shown in the Addendum below.</para>
</listitem>
<listitem><para>Preserve in that license
notice the full lists of Invariant Sections and required Cover
Texts given in the Document's license notice.</para>
</listitem>
<listitem><para>Include an unaltered
copy of this License.</para>
</listitem>
<listitem><para>Preserve the section
entitled "History", and its title, and add to it an item stating
at least the title, year, new authors, and publisher of the
Modified Version as given on the Title Page. If there is no
section entitled "History" in the Document, create one stating
the title, year, authors, and publisher of the Document as given
on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.</para>
</listitem>
<listitem><para>Preserve the network
location, if any, given in the Document for public access to a
Transparent copy of the Document, and likewise the network
locations given in the Document for previous versions it was
based on. These may be placed in the "History" section. You
may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.</para>
</listitem>
<listitem><para>In any section entitled
"Acknowledgements" or "Dedications", preserve the section's
title, and preserve in the section all the substance and tone of
each of the contributor acknowledgements and/or dedications
given therein.</para>
</listitem>
<listitem><para>Preserve all the
Invariant Sections of the Document, unaltered in their text and
in their titles. Section numbers or the equivalent are not
considered part of the section titles.</para>
</listitem>
<listitem><para>Delete any section
entitled "Endorsements". Such a section may not be included in
the Modified Version.</para>
</listitem>
<listitem><para>Do not retitle any
existing section as "Endorsements" or to conflict in title with
any Invariant Section.</para>
</listitem>
</orderedlist>
<para>If the Modified Version includes new front-matter sections
or appendices that qualify as Secondary Sections and contain no
material copied from the Document, you may at your option
designate some or all of these sections as invariant. To do this,
add their titles to the list of Invariant Sections in the Modified
Version's license notice. These titles must be distinct from any
other section titles.</para>
<para>You may add a section entitled "Endorsements", provided it
contains nothing but endorsements of your Modified Version by
various parties--for example, statements of peer review or that
the text has been approved by an organization as the authoritative
definition of a standard.</para>
<para>You may add a passage of up to five words as a Front-Cover
Text, and a passage of up to 25 words as a Back-Cover Text, to the
end of the list of Cover Texts in the Modified Version. Only one
passage of Front-Cover Text and one of Back-Cover Text may be
added by (or through arrangements made by) any one entity. If the
Document already includes a cover text for the same cover,
previously added by you or by arrangement made by the same entity
you are acting on behalf of, you may not add another; but you may
replace the old one, on explicit permission from the previous
publisher that added the old one.</para>
<para>The author(s) and publisher(s) of the Document do not by
this License give permission to use their names for publicity for
or to assert or imply endorsement of any Modified Version.</para>
</sect1>
<sect1 id="appx.gfdl-5">
<title>COMBINING DOCUMENTS</title>
<para>You may combine the Document with other documents released
under this License, under the terms defined in section 4 above for
modified versions, provided that you include in the combination
all of the Invariant Sections of all of the original documents,
unmodified, and list them all as Invariant Sections of your
combined work in its license notice.</para>
<para>The combined work need only contain one copy of this
License, and multiple identical Invariant Sections may be replaced
with a single copy. If there are multiple Invariant Sections with
the same name but different contents, make the title of each such
section unique by adding at the end of it, in parentheses, the
name of the original author or publisher of that section if known,
or else a unique number. Make the same adjustment to the section
titles in the list of Invariant Sections in the license notice of
the combined work.</para>
<para>In the combination, you must combine any sections entitled
"History" in the various original documents, forming one section
entitled "History"; likewise combine any sections entitled
"Acknowledgements", and any sections entitled "Dedications". You
must delete all sections entitled "Endorsements."</para>
</sect1>
<sect1 id="appx.gfdl-6">
<title>COLLECTIONS OF DOCUMENTS</title>
<para>You may make a collection consisting of the Document and
other documents released under this License, and replace the
individual copies of this License in the various documents with a
single copy that is included in the collection, provided that you
follow the rules of this License for verbatim copying of each of
the documents in all other respects.</para>
<para>You may extract a single document from such a collection,
and distribute it individually under this License, provided you
insert a copy of this License into the extracted document, and
follow this License in all other respects regarding verbatim
copying of that document.</para>
</sect1>
<sect1 id="appx.gfdl-7">
<title>AGGREGATION WITH INDEPENDENT WORKS</title>
<para>A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of
a storage or distribution medium, does not as a whole count as a
Modified Version of the Document, provided no compilation
copyright is claimed for the compilation. Such a compilation is
called an "aggregate", and this License does not apply to the
other self-contained works thus compiled with the Document, on
account of their being thus compiled, if they are not themselves
derivative works of the Document.</para>
<para>If the Cover Text requirement of section 3 is applicable to
these copies of the Document, then if the Document is less than
one quarter of the entire aggregate, the Document's Cover Texts
may be placed on covers that surround only the Document within the
aggregate. Otherwise they must appear on covers around the whole
aggregate.</para>
</sect1>
<sect1 id="appx.gfdl-8">
<title>TRANSLATION</title>
<para>Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section
4. Replacing Invariant Sections with translations requires
special permission from their copyright holders, but you may
include translations of some or all Invariant Sections in addition
to the original versions of these Invariant Sections. You may
include a translation of this License provided that you also
include the original English version of this License. In case of
a disagreement between the translation and the original English
version of this License, the original English version will
prevail.</para>
</sect1>
<sect1 id="appx.gfdl-9">
<title>TERMINATION</title>
<para>You may not copy, modify, sublicense, or distribute the
Document except as expressly provided for under this License. Any
other attempt to copy, modify, sublicense or distribute the
Document 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.</para>
</sect1>
<sect1 id="appx.gfdl-10">
<title>FUTURE REVISIONS OF THIS LICENSE</title>
<para>The Free Software Foundation may publish new, revised
versions of the GNU Free Documentation 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. See <ulink
url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.</para>
<para>Each version of the License is given a distinguishing
version number. If the Document specifies that a particular
numbered version of this License "or any later version" applies to
it, you have the option of following the terms and conditions
either of that specified version or of any later version that has
been published (not as a draft) by the Free Software Foundation.
If the Document does not specify a version number of this License,
you may choose any version ever published (not as a draft) by the
Free Software Foundation.</para>
</sect1>
<sect1 id="appx.gfdl-11">
<title>How to use this License for your documents</title>
<para>To use this License in a document you have written, include
a copy of the License in the document and put the following
copyright and license notices just after the title page:</para>
<blockquote><para>
Copyright (c) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
</para></blockquote>
<para>If you have no Invariant Sections, write "with no Invariant
Sections" instead of saying which ones are invariant. If you have
no Front-Cover Texts, write "no Front-Cover Texts" instead of
"Front-Cover Texts being LIST"; likewise for Back-Cover
Texts.</para>
<para>If your document contains nontrivial examples of program
code, we recommend releasing these examples in parallel under your
choice of free software license, such as the GNU General Public
License, to permit their use in free software.</para>
</sect1>
</appendix>

35
bml/doc/docbook/book.ent Executable file
View File

@ -0,0 +1,35 @@
<!ENTITY bml.book SYSTEM "book.xml">
<!ENTITY bml.index SYSTEM "index.xml">
<!ENTITY bml.bookinfo SYSTEM "bookinfo.xml">
<!ENTITY bml.preface SYSTEM "preface.xml">
<!ENTITY bml.api.ref SYSTEM "api.gen.xml">
<!ENTITY bml.flags SYSTEM "flags.xml">
<!ENTITY bml.core SYSTEM "core.xml">
<!ENTITY bml.tutorial SYSTEM "tutorial.xml">
<!ENTITY appx.gfdl SYSTEM "appx.gfdl.xml">
<!ENTITY bml.legalnotice "
<legalnotice>
<para>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version
1.1 or any later version published by the Free Software
Foundation; with no invariant sections, nor Front-Cover/Back-Cover
Texts.
A copy of the license is included in <xref linkend='appx.gfdl'/>
</para>
</legalnotice>
">
<!ENTITY bml.copyright '
<copyright>
<year>1997</year>
<year>1998</year>
<year>1999</year>
<year>2000</year>
<year>2001</year>
<year>2002</year>
<holder><ulink url="http://www.bradfitz.com/">Brad Fitzpatrick</ulink></holder>
</copyright>
'>

15
bml/doc/docbook/book.xml Executable file
View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE book SYSTEM "/usr/share/sgml/docbook/dtd/xml/4.1.2/docbookx.dtd" [
<!ENTITY % book SYSTEM "book.ent">
%book;
<!ENTITY id.prepend "">
]>
<book id="index">
&bml.bookinfo;
&bml.preface;
&bml.tutorial;
&bml.flags;
&bml.core;
&bml.api.ref;
&appx.gfdl;
</book>

35
bml/doc/docbook/bookinfo.xml Executable file
View File

@ -0,0 +1,35 @@
<bookinfo>
<title>The Better Markup Language</title>
<titleabbrev><abbrev>BML</abbrev></titleabbrev>
<edition>BML Manual Version 1.0</edition>
<abstract>
<para>
Anyone's who's ever put together a large website or done a lot of server-side
programming will know how hard and annoying it is to keep a consistent look
through a site, and how painful it is to go back and change something globally
later, once their site is up. In addition, looking at <abbrev>HTML</abbrev>
code is ugly and <abbrev>HTML</abbrev> editors don't always do what you want them to.
</para>
<para>
<abbrev>BML</abbrev> was designed to address a lot of these problems.
<abbrev>BML</abbrev> is a server-side markup language that lets you define your own
<abbrev>BML</abbrev> blocks and use them as templates within your <abbrev>BML</abbrev> pages.
Your templates don't even have to be static. Because <abbrev>BML</abbrev> pages are
converted to <abbrev>HTML</abbrev> on the server when users request them, this also
enables you to embed live code within your <abbrev>BML</abbrev> pages, just like a
<abbrev>CGI</abbrev> script.
</para>
<para>
A lot is possible using <abbrev>BML</abbrev>. Whether you want to make a full blown
database driven website, enable a little dynamic content on your site, or just
make things on your site easier to maintain, <abbrev>BML</abbrev> can really help out.
</para>
<para>
The official website for <abbrev>BML</abbrev> is located at <ulink url="http://www.bradfitz.com/bml" />.
</para>
</abstract>
&bml.copyright;
&bml.legalnotice;
</bookinfo>
<title>The Better Markup Language</title>
<titleabbrev><abbrev>BML</abbrev></titleabbrev>

88
bml/doc/docbook/build.pl Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/perl
#
use strict;
use Getopt::Long;
my $XSL_VERSION_RECOMMENDED = "1.45";
my $opt_clean;
my ($opt_myxsl, $opt_getxsl);
exit 1 unless GetOptions('clean' => \$opt_clean,
'myxsl' => \$opt_myxsl,
'getxsl' => \$opt_getxsl,
);
my $home = $ENV{'LJHOME'};
require "$home/cgi-bin/ljlib.pl";
$ENV{'SGML_CATALOG_FILES'} = $LJ::CATALOG_FILES || "/usr/share/sgml/docbook/dtd/xml/4.1/docbook.cat";
unless (-e $ENV{'SGML_CATALOG_FILES'}) {
die "Catalog files don't exist. Either set \$LJ::CATALOG_FILES, install docbook-xml (on Debian), or symlink $ENV{'SGML_CATALOG_FILES'} to XML DocBook 4.1's docbook.cat.";
}
if ($opt_getxsl) {
chdir "$home/doc/raw/build" or die "Where is build dir?";
unlink "xsl-docbook.tar.gz";
my $fetched = 0;
my $url = "http://www.livejournal.org/misc/xsl-docbook.tar.gz";
my @fetcher = ([ 'wget', "wget $url", ],
[ 'lynx', "lynx -source $url > xsl-docbook.tar.gz", ],
[ 'GET', "GET $url > xsl-docbook.tar.gz", ]);
foreach my $fet (@fetcher) {
next if $fetched;
print "Looking for $fet->[0] ...\n";
next unless `which $fet->[0]`;
print "RUNNING: $fet->[1]\n";
system($fet->[1])
and die "Error running $fet->[0]. Interrupted?\n";
$fetched = 1;
}
unless ($fetched) {
die "Couldn't find a program to download things from the web. I looked for:\n\t".
join(", ", map { $_->[0] } @fetcher) . "\n";
}
system("tar", "zxvf", "xsl-docbook.tar.gz")
and die "Error extracting xsl-doxbook.tar.gz; have GNU tar?\n";
}
my $output_dir = "$home/htdocs/doc/bml";
my $docraw_dir = "$home/doc/raw";
my $XSL = "$docraw_dir/build/xsl-docbook";
my $stylesheet = "$XSL/html/chunk.xsl";
open (F, "$XSL/VERSION");
my $XSL_VERSION;
{
local $/ = undef; my $file = <F>;
$XSL_VERSION = $1 if $file =~ /VERSION.+\>(.+?)\</;
}
close F;
my $download;
if ($XSL_VERSION && $XSL_VERSION ne $XSL_VERSION_RECOMMENDED && ! $opt_myxsl) {
print "\nUntested DocBook XSL found at $XSL.\n";
print " Your version: $XSL_VERSION.\n";
print " Recommended: $XSL_VERSION_RECOMMENDED.\n\n";
print "Options at this point. Re-run with:\n";
print " --myxsl to proceed with yours, or\n";
print " --getxsl to install recommended XSL\n\n";
exit 1;
}
if (! $XSL_VERSION) {
print "\nDocBook XSL not found at $XSL.\n\nEither symlink that dir to the right ";
print "place (preferrably at version $XSL_VERSION_RECOMMENDED),\nor re-run with --getxsl ";
print "for me to do it for you.\n\n";
exit 1;
}
chdir "$docraw_dir/build" or die;
print "Generating API reference\n";
system("api/api2db.pl --include=BML:: --book=bml > $docraw_dir/bml.book/api.gen.xml")
and die "Errror generating BML API reference.\n";
system("xsltproc --nonet --catalogs ".
"--stringparam use.id.as.filename '1' ".
"$stylesheet $docraw_dir/bml.book/book.xml")
and die "Error generating HTML.\n";

115
bml/doc/docbook/core.xml Executable file
View File

@ -0,0 +1,115 @@
<chapter id="bml.core">
<chapterinfo>
<title>Core <abbrev>BML</abbrev> blocks</title>
</chapterinfo>
<title>Core <abbrev>BML</abbrev> blocks</title>
<para>
Core blocks are predefined blocks that are named with a leading underscore.
Most core blocks have a higher purpose than simple template use:
</para>
<variablelist>
<varlistentry>
<term><literal role="core.bml.block">_code</literal></term>
<listitem><para>
<literal>&lt;?_code _code?&gt;</literal> blocks are perhaps the most useful feature of
<abbrev>BML</abbrev> outside of the ability to have global site templates.
These blocks allow template authors to embed pieces of executable Perl code
within the bml page that get executed on the server.
</para><para>
</para><para>
The code you write gets executed in its own package (namespace) called
<computeroutput>BMLCodeBlock::</computeroutput>.
Any variables you declare in one code block on a page without using
<literal>my</literal> are carried on to the next <literal>_code</literal> block.
</para><para>
Because the BML parser must evaluate everything on the page before sending the
<abbrev>HTTP</abbrev> headers, make sure you don't print anything.
Any output printed to <literal>STDOUT</literal> will just be interpreted as
<abbrev>HTTP</abbrev> headers. How the <literal>_code</literal> blocks work is
that you need to return a value at the end.
Whatever value your code fragment returns is what the block evaluates to.
Usually what you end up doing is building a string, concatenating things to it
over and over, and then returning it at the end.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal role="core.bml.block">_c</literal> - <literal role="core.bml.block">_comment</literal></term>
<listitem><para>
Comment blocks are templates that do not get parsed into resultant text later,
and are useful when <abbrev>HTML</abbrev> style comments
(<quote><literal>&lt;!-- --&gt;</literal></quote>) are not desired.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal role="core.bml.block">_info</literal></term>
<listitem><para>
Information blocks can be used to include special information about the particular
<abbrev>BML</abbrev> page the block is contained in.
<variablelist>
<title><literal>_info</literal> directives</title>
<varlistentry>
<term><literal>package</literal></term>
<listitem><para>Specify and load a required package</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>nocache</literal></term>
<listitem><para>Specified page is dynamic, and shouldn't be cached</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>static</literal></term>
<listitem><para>Specified page is static; ok to cache</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>noheaders</literal></term>
<listitem><para>Turn off default <abbrev>BML</abbrev> headers</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>nocontent</literal></term>
<listitem><para>Specify that page has no cacheable content</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>localblocks</literal></term>
<listitem><para>Declare page specific <abbrev>BML</abbrev> blocks.</para></listitem>
</varlistentry>
</variablelist>
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal role="core.bml.block">_include</literal></term>
<listitem><para>
Include blocks can be used to integrate a text file straight into a <abbrev>BML</abbrev>
file. Include files can be written in BML or plain text.
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal role="core.bml.block">_e*</literal></term>
<listitem><para>
<literal>_e*</literal> are a variety of escape blocks, each with a different purpose:
<variablelist>
<varlistentry>
<term><literal>_eh</literal></term>
<listitem><para>Replace certain <abbrev>ASCII</abbrev> characters with their <abbrev>HTML</abbrev> entity counterparts</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>_eb</literal></term>
<listitem><para>Replace certain <abbrev>ASCII</abbrev> characters that can trigger <abbrev>BML</abbrev> blocks (<quote><literal>&lt;?xml?&gt;</literal></quote>) with their <abbrev>HTML</abbrev> entity counterparts</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>_eu</literal></term>
<listitem><para>Escape non-compliant <abbrev>ASCII</abbrev> characters in <acronym>URL</acronym>s</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>_ea</literal></term>
<listitem><para>Escape text by passing through <literal>eh</literal> and then <literal>eb</literal></para></listitem>
</varlistentry>
</variablelist>
</para></listitem>
</varlistentry>
<varlistentry>
<term><literal role="core.bml.block">_ml</literal></term>
<listitem><para>
Multi language blocks are used to interchange certain text blocks with the specified language-domain translation.
</para></listitem>
</varlistentry>
</variablelist>
</chapter>

89
bml/doc/docbook/flags.xml Executable file
View File

@ -0,0 +1,89 @@
<chapter id="bml.flags">
<title>BML Block Types</title>
<para>
This documents the flags in braces at the beginning of <filename>.look</filename> file block template definitions.
The flags fall into one of three classes:
</para>
<para>
<variablelist>
<title>Varible definition types:</title>
<varlistentry>
<term>F</term>
<listitem>
<para>Full, mix of multi &amp; single line property definitions:
<programlisting><![CDATA[<?template
foo<=
Multi
line
string
<=foo
bar=>Single line string
template?>]]></programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>P</term>
<listitem>
<para>Pipe delimited, properites are named DATA&lt;n&gt;, where &lt;n&gt; starts at 1 and increases.
<programlisting>&lt;?template DATA1|second arg|DATA3 template?&gt;</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>D</term>
<listitem>
<para>One property, and it's named DATA
<programlisting>&lt;?template I am the DATA template?&gt;</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<title>Static template definitions:</title>
<varlistentry>
<term>S</term>
<listitem>
<para>Static: output won't have more BML to expand, or properties to fill-in, so don't try.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>R</term>
<listitem>
<para>Less static: add pRoperties, but then don't BML expand.</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<title>Controlling expansion vs. interpolation order:</title>
<varlistentry>
<term>p</term>
<listitem>
<para>
Pre-parsed.
BML-expand parameters first, then interpolate into template.
By default, parameters are interpolated first, then everything is expanded.
But if you use <literal>%%TITLE%%</literal> twice in your <literal>PAGE</literal>, for example, and your <filename>.bml</filename> file defines <literal>TITLE=></literal> with a <literal>_CODE</literal> block, it will be run twice, so it's generally a good idea to make <literal>PAGE</literal> definitions pre-parsed.
Also, then, you avoid re-running most of your output through the BML expander a second time.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>s</term>
<listitem>
<para>
Expand embedded parameterless static blocks in definition early.
When the template file is read, any blocks of the form <literal>&lt;?foo?&gt;</literal> are expanded ahead of time.
Useful in conjunction with the <literal>{S}</literal> flag. consider:
<programlisting><![CDATA[# Our image server:
IMGPREFIX=>{S}http://www.site.com:8080/
# Some block that has an image:
SPACER=>{Ss}<img src='<?imgprefix?>/spacer.gif' width='1' height='10'>]]></programlisting>
The <literal>SPACER</literal> block isn't really static, but because <literal>{s}</literal> is used and <literal>&lt;?IMGPREFIX?&gt;</literal> is static, then <literal>SPACER</literal> can also be static.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</chapter>

8
bml/doc/docbook/index.xml Executable file
View File

@ -0,0 +1,8 @@
<book id="bml.index">
&bml.bookinfo;
&bml.preface;
&bml.tutorial;
&bml.flags;
&bml.core;
&bml.api.ref;
</book>

64
bml/doc/docbook/preface.xml Executable file
View File

@ -0,0 +1,64 @@
<preface id="bml.preface">
<!-- Was going to use <section>s, but we don't need more pages. -->
<!-- Not as clean, but it works -->
<title>Preface</title>
<para>
This is a comprehensive manual aimed towards people wishing to
use <abbrev>BML</abbrev> for their website needs.
Some of the topics covered include setting up <abbrev>BML</abbrev> for
a website, writing a custom <abbrev>BML</abbrev> scheme, and
customization &amp; optimization of a <abbrev>BML</abbrev> installation.
</para>
<formalpara>
<title>Target Audience</title>
<para>
This book was written for anyone interested in installing and using
<abbrev>BML</abbrev> for their own purposes, and for people who are
just generally interested in how <abbrev>BML</abbrev> works.
</para>
</formalpara>
<para>
Readers of this book should be familiar with administering a web
site, and have at least a brief knowledge of <abbrev>HTML</abbrev>.
</para>
<formalpara><title>Organization</title><para>
The Manual is organized into certain chapters:
</para><para>
<variablelist>
<varlistentry>
<term><xref linkend="bml.tutorial" /></term>
<listitem><para>
A tutorial covering the basics of <abbrev>BML</abbrev>, and
explaining how to write a <abbrev>BML</abbrev> document.
</para></listitem>
</varlistentry>
<varlistentry>
<term><xref linkend="bml.flags" /></term>
<listitem><para>
A reference to <abbrev>BML</abbrev> block flags.
</para></listitem>
</varlistentry>
<varlistentry>
<term><xref linkend="bml.core" /></term>
<listitem><para>
A reference to the core <abbrev>BML</abbrev> blocks.
</para></listitem>
</varlistentry>
<varlistentry>
<term><xref linkend="bml.api.ref" /></term>
<listitem><para>
An application programming interface reference.
</para></listitem>
</varlistentry>
</variablelist>
</para></formalpara>
<formalpara>
<title>Versions</title>
<para>
An online version of this book can be found at:
<ulink url="http://www.livejournal.com/doc/server/bml.index.html" />.
To compile these pages for your own, refer to:
<filename>/doc/raw/notes.txt</filename> in <abbrev>CVS</abbrev>.
</para>
</formalpara>
</preface>

552
bml/doc/docbook/tutorial.xml Executable file
View File

@ -0,0 +1,552 @@
<chapter id="bml.tutorial">
<!-- $Id: tutorial.xml,v 1.4 2004/07/03 00:13:27 deveiant Exp $ -->
<chapterinfo>
<title>A Brief Tutorial</title>
</chapterinfo>
<title>A Brief Tutorial</title>
<para>
The goal of using <abbrev>BML</abbrev> is to become a smarter, lazier
webmaster. The qualities that define a <abbrev>BML</abbrev> author should
be the same as a good Perl programmer: <emphasis>laziness, impatience,
and hubris</emphasis>.
</para>
<section id="bml.tutorial.intro">
<title>Introducing <abbrev>BML</abbrev></title>
<!-- Tutorial: Blocks Section -->
<section id="bml.tutorial.intro.blocks">
<title>Blocks</title>
<para>
<abbrev>BML</abbrev> is essentially a simple macro language. Macros are
called <firstterm>blocks</firstterm> in <abbrev>BML</abbrev>. Blocks are
<wordasword>defined</wordasword> in <firstterm>look files</firstterm>
and are <wordasword>invoked</wordasword> in <abbrev>BML</abbrev> files.
Blocks accept <wordasword>parameters</wordasword> and are divided into
several <wordasword>types</wordasword> according to how parameters are
transmitted and how the definition of the block is able to make use of
them. Definitions of blocks are essentially chunks of
<abbrev>HTML</abbrev> with potentially more recursive
<abbrev>BML</abbrev> block invocations inside them.
</para>
<example id="bml.lookup.example1">
<title>BML lookup file</title>
<programlisting linenumbering="numbered"><![CDATA[
project=>The Alabaster Project
greeting<=
<p>Welcome to <?project project?>, a joint effort between the citizens of earth
and Spumco, Inc.</p>
<=greeting
]]></programlisting>
</example>
<para>The "project" and "greeting" constructs in the above example lookup file are
blocks, and can be used to insert their respective content into HTML
output. The "project" block is a single-line block that consists of
everything immediately following the name of the block and the
<literal>=&gt;</literal> up to the end of the line. The "greeting"
block is a multiline block, and contains all the lines immediately
following the <literal>greeting&lt;=</literal> line and preceding
the <literal>&lt;=greeting</literal> one.</para>
</section>
<!-- Tutorial: BML Files Section -->
<section id="bml.tutorial.intro.bmlfiles">
<title>BML Files</title>
<para>
A <abbrev>BML</abbrev> file is simply an <abbrev>HTML</abbrev> file with
some <abbrev>BML</abbrev> block invocations in it. Each such invocation
specifies the name of the block and the parameters, if any, to pass to it.
The ultimate result of a block's invocation at runtime is <abbrev>HTML</abbrev>
which is put in the outgoing stream exactly at the place where the block's
invocation resided in the <abbrev>BML</abbrev> file.
</para>
<example id="bml.file.example1">
<title>BML file</title>
<programlisting linenumbering="numbered"><![CDATA[
<html>
<head><title><?project project?></title>
<body>
<h1><?project project?></h1>
<?greeting greeting?>
</body>
</html>
]]></programlisting>
</example>
<para>Given the lookup file from the previous example, the BML file above
would yield output like:</para>
<example id="bml.output.example1">
<title>Output</title>
<programlisting linenumbering="numbered"><![CDATA[
<html>
<head><title>The Alabaster Project</title>
<body>
<h1>The Alabaster Project</h1>
<p>Welcome to The Alabaster Project, a joint effort between the citizens of earth
and Spumco, Inc.</p>
</body>
</html>
]]></programlisting>
</example>
<para>The block invocations in the <link linkend="bml.lookup.example1">BML
lookup file example</link> above do not contain parameters, but even
so are still a powerful way of building a document out of aggregate
parts. Adding parameters, of course, increases this usefulness.</para>
</section>
</section>
<!-- Tutorial: Parameters Section -->
<section>
<title>Block Parameters</title>
<section id="bml.tutorial.intro.parameters">
<title>The <varname>DATA</varname> Block Parameter</title>
<para>Sometimes the insertion of simple static content into the output
will not suffice for projects of moderate complexity. A designer
frequently wishes to repeat certain elements throughout the page,
keeping a consistent structure and look-and-feel. BML provides this
functionality by allowing you to declare blocks which take parameters,
which can then be used in building the content inserted into the
document.</para>
<para>The simplest parameter-accepting block is one you've seen already in
the above examples. Unless otherwise designated, all blocks accept one
parameter, which is put into a variable called
<varname>DATA</varname>. This parameter can then be interpolated
into the resulting output with a placeholder that looks like:
<literal>%%DATA%%</literal>.</para>
<example id="bml.lookup.example2">
<title>Lookup file with DATA blocks</title>
<programlisting linenumbering="numbered"><![CDATA[
heading=><h1>%%DATA%%</h1>
subheading=><h2>%%DATA%%</h2>
]]></programlisting>
</example>
<para>This lookup file defines two blocks, one called
<literal>heading</literal> which creates level-one heading HTML, and
another called <literal>subhead</literal>, which creates level-two
headings.</para>
<para>These could be used like so:</para>
<example id="bml.file.example2">
<title>BML file using parameterized blocks</title>
<programlisting linenumbering="numbered"><![CDATA[
<html>
<head><title>Hansel and Grendel Go to Finishing School</title>
<body>
]]>
<emphasis><![CDATA[ <?heading Hansel and Grendel Go to Finishing School heading?>]]></emphasis>
<![CDATA[
<p>Our story begins at a point in the Universe not unlike where you are now
sitting, drinking your government-sanctioned stimulant, dreaming of the
day when you, too, will own your own personalized luxury home on 0.3 acres
of land, with a stunning view of, well, the neighbor's personalized luxury
home on 0.3 acres of land. Except this point in the Universe is much more
exciting, fine-smelling, and generally a better place to be than
yours.</p>
]]>
<emphasis><![CDATA[ <?subheading No, Really, It Is Much Finer subheading?>]]></emphasis>
<![CDATA[
<p>So, anyway, at this particular point in the Universe, on a day not
entirely unlike today, two entirely unrelated mythological pantheons
collided, resulting in a fast friendship between a Little Boy Bound to be
Eaten by the Architypal Crone and a Faceless Beast That Waits for the Hero
to Dispatch It. Which, as you might have guessed, was not the intention of
the various storytellers involved, but that's what happens when people
stop reading all the really cool stories and start checking the Financial
Section every 12 minutes. There's only so much space to go around in the
collective consciousness, you know...</p>
</body>
</html>
]]></programlisting>
</example>
<para>which would result in output like:</para>
<example id="bml.output.example2">
<title>Parameterized Output: Named Parameters</title>
<programlisting linenumbering="numbered"><![CDATA[
<html>
<head><title>Hansel and Grendel Go to Finishing School</title>
<body>
]]>
<emphasis><![CDATA[ <h1>Hansel and Grendel Go to Finishing School heading</h1>]]></emphasis>
<![CDATA[
<p>Our story begins at a point in the Universe not unlike where you are now
sitting, drinking your government-sanctioned stimulant, dreaming of the
day when you, too, will own your own personalized luxury home on 0.3 acres
of land, with a stunning view of, well, the neighbor's personalized luxury
home on 0.3 acres of land. Except this point in the Universe is much more
exciting, fine-smelling, and generally a better place to be than
yours.</p>
]]>
<emphasis><![CDATA[ <h2>No, Really, It Is Much Finer</h2>]]></emphasis>
<![CDATA[
<p>So, anyway, at this particular point in the Universe, on a day not
entirely unlike today, two entirely unrelated mythological pantheons
collided, resulting in a fast friendship between a Little Boy Bound to be
Eaten by the Architypal Crone and a Faceless Beast That Waits for the Hero
to Dispatch It. Which, as you might have guessed, was not the intention of
the various storytellers involved, but that's what happens when people
stop reading all the really cool stories and start checking the Financial
Section every 12 minutes. There's only so much space to go around in the
collective consciousness, you know...</p>
</body>
</html>
]]></programlisting>
</example>
<para>By this point, you might be saying, "But wait! I'd much rather type
<literal>'&lt;h1&gt; ... &lt;/h1&gt;'</literal> than
<literal>'&lt;?heading ... heading?&gt;'</literal>!" If you were
absolutely confident that headings would always be expressed with
<literal>&lt;h1&gt;</literal> tags, and subheadings with
<literal>&lt;h2&gt;</literal> tags, it might be more efficent to
leave them as static HTML. If, however, someone wants all headings and
subheadings to change throughout the site, having the definition of them
expressed as a block makes changing them everywhere a simple matter of
changing the block that defines them:</para>
<example id="bml.lookup.example3">
<title>Alternate Heading Block</title>
<programlisting linenumbering="numbered"><![CDATA[
heading=><h1 class="heading"><img src="logo.png"/> %%DATA%%</h1>
subhead<=
<!-- This is a subheading, which naturally requires a chicken above it -->
<img src="chicken.png" /><br />
<h2 class="subheading">%%DATA%%</h2>
<=subhead
]]></programlisting>
</example>
<para>Instead of a fairly complex search-and-replace session over multiple
files, you instead need only change the definition of what a heading means
in one place, and see it reflected throughout your site. Note that
multiline blocks can also use the <varname>DATA</varname>
parameter.</para>
<para>The examples above are admittedly contrived, and could probably be
accomplished using <acronym>CSS</acronym>, but it should serve to
demonstrate a use which is orthogonal to the role played by style
systems.</para>
</section>
<!-- Tutorial: Multiple Parameters Section -->
<section id="bml.tutorial.intro.multipleparams">
<title>Block Flags and Passing Multiple Parameters</title>
<para>Many tasks will not be able to be accomplished with blocks that have
only one parameter, so BML provides another kind of block that can be
passed multiple parameters. Up 'til now, we've been using blocks with an
implied parameter, but we'll need to tell BML that the block we're
defining is different. This is accomplished by specifying one or more
<firstterm>flags</firstterm> when declaring the block. Flags are single
letters that are placed inside curly braces (<literal>{}</literal>) at
the beginning of the block definition. For example, the flag that
corresponds to the full block type (which we'll be using for blocks that
can accept multiple parameters) is designated with an
<literal>{F}</literal> flag:</para>
<example id="bml.lookup.example4">
<title>Block Definitions with Flags</title>
<programlisting linenumbering="numbered"><![CDATA[
smallcaps=>{D}<span style="font-variant: small-caps">%%DATA%%</span>
topiclink=>{F}<a href="/topic.pl?name=%%name%%">%%linktext%%</a>
section<={F}
<div id="section-%%id%%" class="section">
<h3>%%heading%%</h3>
<p>%%body%%</p>
</div>
<=section
]]>
</programlisting>
</example>
<para>As you can see, two of the blocks declared above have an
<literal>{F}</literal> flag, and one has a <literal>{D}</literal>
flag. The <literal>{D}</literal> flag stands for 'data', which is the
default block type we're already familiar with, so the flag part could
have been omitted. There are other block types which specify other
attributes and behaviors, but for now we'll focus on the
<literal>{F}</literal> type.</para>
<para>In the above example, two <literal>{F}</literal> blocks are defined,
a single-line one and a multi-line one. Both expect multiple parameters
which they use to fill in parts of the HTML fragments they are responsible
for creating. They also use placeholders like <literal>{D}</literal>
blocks do, but they have unique names that will serve as the label given
with the parameter that belongs there when calling it from a BML
file.</para>
<para>Calling an <literal>{F}</literal> block necessarily looks a bit
different than the simple references made to <literal>{D}</literal>
blocks. Calls to a block which requires multiple parameters uses the same
syntax as that used for declaring blocks:</para>
<example id="bml.file.example4">
<title>BML File</title>
<programlisting linenumbering="numbered"><![CDATA[
<?section
id=>listrules
heading=>Rules of the Lists
body<=
There are many considerations when engaging in mounted combat at a tourney, not
the least of which is obeying the convoluted and sometimes confusing localized
<em>Rules of the Lists</em>.
<=body
section?>
]]></programlisting>
</example>
<para>In the above example, the <literal>section</literal> block is being
called with three parameters, two of which are single-line parameters
(<varname>id</varname> and <varname>heading</varname>), and a third
multi-line one (<varname>body</varname>). The output rendered by combining
the above BML file with the previous lookup file would look something
like:</para>
<example id="bml.output.example4">
<title>Example output</title>
<programlisting>
<![CDATA[
<div id="section-listrules" class="section">
<h3>Rules of the Lists</h3>
<p>There are many considerations when engaging in mounted combat at a tourney, not
the least of which is obeying the convoluted and sometimes confusing localized
<em>Rules of the Lists</em>.
</p>
</div>
]]>
</programlisting>
</example>
</section>
<section>
<title>Parameterized Output: Positional Parameters</title>
<para>In addition to the named parameters introduced above, BML also
supports positional parameters. Like with named parameters, a block with
positional parameters is designated with the use of a flag, this time the
<literal>{P}</literal> or "pipe-delimited" flag. Parameters in a
<literal>{P}</literal> block are represented with
<varname>%%DATA1%%</varname>, <varname>%%DATA2%%</varname>, etc. This can
be useful when a routine takes a lot of parameters, or when calling the
same block many times with tabular or list data.</para>
<para>An example of this is building a list of links, each of which is an
item in a definition list:</para>
<example id="bml.lookup.example5">
<title>Block Definitions with Positional Parameters</title>
<programlisting linenumbering="numbered">
<![CDATA[
LINKITEM=>{P}<dt><a href="%%data2%%">%%data1%%</a></dt> <dd>%%data3%%</dd>
LINKLIST<=
{F}
<h4>My Current Reading List</h4>
<dl>
%%items%%
</dl>
<p><small>Last updated: %%date%%</small></p>
<=LINKLIST
]]>
</programlisting>
</example>
<example id="bml.file.example5">
<title>BML File using the 'listlist' and 'linkitem' blocks</title>
<programlisting linenumbering="numbered">
<![CDATA[
<?linklist
date=>2004/10/14
items<=
<?linkitem News of Brad|http://brad.livejournal.com/|Brad's daily adventure linkitem?>
<?linkitem BoingBoing|http://boingboing.net/|A directory of wonderful things linkitem?>
<?linkitem WPGtR|http://poignantguide.net/ruby/|Wow, this book comes with an onion! linkitem?>
<=items
linklist?>
]]>
</programlisting>
</example>
<para>Combining the two files above would render output like this:</para>
<example id="bml.output.example5">
<title>Example output</title>
<programlisting>
<![CDATA[
<h4>My Current Reading List</h4>
<dl>
<dt><a href="http://brad.livejournal.com/">News of Brad</a></dt> <dd>Brad's daily adventure</dd>
<dt><a href="http://boingboing.net/">BoingBoing</a></dt> <dd>A directory of wonderful things</dd>
<dt><a href="http://poignantguide.net/ruby/">WPGtR</a></dt> <dd>Wow, this book comes with an onion!</dd>
</dl>
<p><small>Last updated: 2004/10/14</small></p>
]]>
</programlisting>
</example>
</section>
</section>
<section>
<title>Static Blocks</title>
<para>Sometimes the re-expansion of embedded BMl might not be what you
want. In that case, you can designate a block with a flag which will cause
it to stop or limit the re-expansion of embedded calls.</para>
<section>
<title>Fully-Static Blocks</title>
<para>If you add the <literal>{S}</literal> flag to the block you're
defining, the contents of it will not be re-evaluated afterward. This is
mostly useful when you have blocks that you are sure will never contain
BML to be expanded or properties to fill in, and you want to save the
overhead of trying to re-evaluate them.</para>
<example id="bml.lookup.example6">
<title>Look file with <literal>{S}</literal> block</title>
<programlisting linenumbering="numbered">
<![CDATA[
companyname=>{S}Spumco, Inc.
]]>
</programlisting>
</example>
<para>This defines the <literal>companyname</literal> block as
static.</para>
<example id="bml.file.example6">
<title>BML File that calls the static block</title>
<programlisting linenumbering="numbered">
<![CDATA[
<h1>Welcome to <?companyname companyname?></h1>
]]>
</programlisting>
</example>
<para>Combining the two yields:</para>
<example id="bml.output.example6">
<title>Example output</title>
<programlisting>
<![CDATA[
<h1>Welcome to Spumco, Inc.</h1>
]]>
</programlisting>
</example>
</section>
<section>
<title>Semi-static Blocks</title>
<para>Sometimes you want a block which fits somewhere between the
fully-dynamic <literal>{D}</literal> blocks and the completely-static
behavior of <literal>{S}</literal> blocks. Enter the
<literal>{R}</literal> block flag, which expands
p<emphasis>R</emphasis>operties like those passed to a
<literal>{D}</literal>, <literal>{F}</literal>, or <literal>{P}</literal>
block, but doesn't expand BML that might be inserted by one of
those.</para>
<example id="bml.lookup.example7">
<title>Look file with <literal>{R}</literal> block</title>
<programlisting linenumbering="numbered">
<![CDATA[
]]>
</programlisting>
</example>
<para></para>
<example id="bml.file.example7">
<title></title>
<programlisting linenumbering="numbered">
<![CDATA[]]>
</programlisting>
</example>
<para></para>
<example id="bml.output.example7">
<title>Example output</title>
<programlisting>
<![CDATA[]]>
</programlisting>
</example>
</section>
</section>
<section id="bml.tutorial.example">
<title>A Full Example</title>
<para>
</para>
<para>
<programlisting><![CDATA[
<html>
<head>
<title>FooBar Enterprises - Page</title>
</head>
<body>
<h1 class="header">FooBar Enterprises - Page</h1>
<hr />
<div class="header"><strong>Headers - What good are they?</strong></div>
<p class="para" style="text-align: justify">
This is just an introductory text. The normal way to include text like this
is to write it in Latin, but since I don't know Latin, you'll have to settle
with this little paragraph.
</p>
<div class="header"><strong>Templates are for Wimps!</strong></div>
<p class="para">
I'd rather have to edit all of my pages by hand when I decide to change the
unified look of my site!
</p>
</body>
</html>
]]></programlisting>
</para>
<para>
<programlisting><![CDATA[
header=>{D}<div class="header"><strong>%%DATA%%</strong></div>
]]></programlisting>
</para>
<para>
<programlisting><![CDATA[
<?header Headers - What good are they? header?>
]]></programlisting>
</para>
<!-- :WORK: -->
</section>
</chapter>

2065
bml/lib/Apache/BML.pm Executable file

File diff suppressed because it is too large Load Diff

40
bml/t/00_require.t Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/perl
#
# Test script for Apache::BML
# $Id: 00_require.t,v 1.1 2004/05/26 17:33:51 deveiant Exp $
#
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl 00_require.t'
#
# Please do not commit any changes you make to the module without a
# successful 'make test'!
#
package main;
use strict;
BEGIN { $| = 1; }
### Load up the test framework
use Test::SimpleUnit qw{:functions};
my (
$manifest,
@modules,
@testSuite,
);
# Read the manifest and grok the list of modules out of it
$manifest = IO::File->new( "MANIFEST", "r" )
or die "open: MANIFEST: $!";
@modules = map { s{lib/(.+)\.pm$}{$1}; s{/}{::}g; $_ } grep { m{\.pm$} } $manifest->getlines;
chomp @modules;
### Test suite (in the order they're run)
@testSuite = map {
{
name => "require ${_}",
test => eval qq{sub { assertNoException {require $_}; }},
}
} @modules;
runTests( @testSuite );

210
bml/t/10_simple.t Executable file
View File

@ -0,0 +1,210 @@
#!/usr/bin/perl
#
# Test script for Apache::BML -- Simple functions
# $Id: 10_simple.t,v 1.1 2004/05/26 17:33:51 deveiant Exp $
#
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl 00_require.t'
#
# Please do not commit any changes you make to the module without a
# successful 'make test'!
#
package main;
use strict;
BEGIN { $| = 1; }
### Load up the test framework
use Test::SimpleUnit qw{:functions};
use Apache::BML qw{};
use Apache::FakeRequest qw{};
use Fcntl qw{O_CREAT O_TRUNC O_EXCL O_WRONLY};
use File::Spec qw{};
my (
@testSuite,
$Output,
$Errout,
$Pnotes,
$Request,
$DataPath,
$NonExistantFile,
$ForbiddenFile,
$ForbiddenConfigFile,
$EmptyFile,
);
$Pnotes = {};
$Output = '';
$Errout = '';
$DataPath = File::Spec->rel2abs( "test" );
$NonExistantFile = "$DataPath/nonexistant.bml";
$ForbiddenFile = "$DataPath/forbidden.bml";
$ForbiddenConfigFile = "$DataPath/_config.bml";
$EmptyFile = "$DataPath/empty.bml";
# Overload Apache::FakeRequest's print to append output to a variable.
{
no warnings 'redefine';
*Apache::FakeRequest::print = sub {
my $r = shift;
$Output .= join('', @_)
};
*Apache::FakeRequest::log_error = sub {
my $r - shift;
print STDERR @_, "\n"; $Errout .= join('', @_)
};
*Apache::FakeRequest::pnotes = sub {
my ( $r, $key ) = @_;
return $Pnotes if !$key;
$Pnotes->{ $key } = shift if @_;
$Pnotes->{ $key };
};
}
# Define tests
@testSuite = (
{
name => 'setup',
func => sub {
$Output = '';
$Errout = '';
$Pnotes = {};
},
},
# Calling handler() with no args should error
{
name => 'No Args',
test => sub {
assertException {
Apache::BML::handler();
};
},
},
# Calling with a non-existant file should 404
{
name => "Non-existant file",
test => sub {
my $request = new Apache::FakeRequest (
filename => $NonExistantFile,
);
my $res;
assertNoException {
$res = Apache::BML::handler( $request );
};
assertEquals( 404, $res );
assertMatches( /does not exist/, $Errout );
},
},
{
name => 'teardown',
func => sub {
if ( -e $ForbiddenFile ) {
unlink $ForbiddenFile or die "unlink: $ForbiddenFile: $!";
}
},
},
# Calling with a file for which we have no permissions should 403
{
name => "Non-readable file",
test => sub {
# Create an unreadable file
my $fh = new IO::File $ForbiddenFile, O_CREAT|O_WRONLY
or die "open: $ForbiddenFile: $!";
close $fh;
chmod 0220, $ForbiddenFile
or die "chmod: $ForbiddenFile: $!";
my $request = new Apache::FakeRequest (
filename => $ForbiddenFile,
);
my $res;
assertNoException {
$res = Apache::BML::handler( $request );
};
assertEquals( 403, $res );
assertMatches( /File permissions deny access/, $Errout );
},
},
{
name => 'teardown',
func => sub {
if ( -e $ForbiddenConfigFile ) {
unlink $ForbiddenConfigFile or die "unlink: $ForbiddenConfigFile: $!";
}
},
},
# _config files are forbidden
{
name => "Forbidden _config file",
test => sub {
# Create a readable _config file
my $fh = new IO::File $ForbiddenConfigFile, O_CREAT|O_WRONLY
or die "open: $ForbiddenConfigFile: $!";
$fh->print("");
close $fh;
my $request = new Apache::FakeRequest (
filename => $ForbiddenConfigFile,
);
my $res;
assertNoException {
$res = Apache::BML::handler( $request );
};
assertEquals( 403, $res );
},
},
{
name => 'teardown',
func => sub {
if ( -e $EmptyFile ) {
unlink $EmptyFile or die "unlink: $EmptyFile: $!";
}
},
},
# Loading an empty file should be okay
{
name => "Empty file",
test => sub {
# Create an unreadable file
my $fh = new IO::File $EmptyFile, O_CREAT|O_WRONLY
or die "open: $EmptyFile: $!";
$fh->print("");
close $fh;
my $request = new Apache::FakeRequest (
filename => $EmptyFile,
);
my $res;
assertNoException { $res = Apache::BML::handler($request) };
assertEquals 0, $res;
assertEquals '', $Output;
},
}
);
runTests( @testSuite );

185
bml/t/20_render.t Executable file
View File

@ -0,0 +1,185 @@
#!/usr/bin/perl
#
# Test script for Apache::BML -- Simple functions
# $Id: 20_render.t,v 1.3 2004/07/03 00:13:26 deveiant Exp $
#
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl 00_require.t'
#
# Please do not commit any changes you make to the module without a
# successful 'make test'!
#
package main;
use strict;
BEGIN { $| = 1; }
use lib "lib";
### Load up the test framework
use Test::SimpleUnit qw{:functions};
use Apache::BML qw{};
use Apache::FakeRequest qw{};
use Fcntl qw{O_CREAT O_TRUNC O_EXCL O_RDONLY O_WRONLY};
use File::Spec qw{};
use File::Basename qw{dirname basename};
use Text::Diff qw{diff};
#####################################################################
### G L O B A L V A R I A B L E S
#####################################################################
my (
@testSuite,
$Request,
$TestDir,
@TestSubdirs,
);
$TestDir = File::Spec->rel2abs( "test" );
# The list of directories to search for .bml files. This is hard-coded instead
# of automatic so other tests can use the test/ directory for their data, too.
@TestSubdirs = qw[ tutorial1 tutorial2 brads recursion syntax-errors
codeblocks fake_root comments info escape include
tutorial-example*
];
#####################################################################
### C U S T O M A S S E R T I O N F U N C T I O N S
#####################################################################
### FUNCTION: readFile( $file )
### Read the specified I<file> and return its contents as a single scalar.
sub readFile {
my ( $file ) = @_;
my $fh = new IO::File $file, O_RDONLY
or die "open: $file: $!";
return join '', $fh->getlines;
}
### FUNCTION: assertCorrect( $directory, $name, $output )
### Load the "I<name>.correct" file from the specified testing I<directory> and
### check that it is the same as the specified I<output> after stripping off
### trailing whitespace from both.
sub assertCorrect {
my ( $dir, $name, $output ) = @_;
my $path = File::Spec->catfile( $dir, "$name.correct" );
if ( ! -e $path ) {
print "\n>>> WARNING: No .correct file for '$name': Creating one with \n",
">>> the test output. You should verify the correctness of \n",
">>> '$path' before trusting this test.\n\n";
IO::File->new($path, O_WRONLY|O_CREAT)->print( $output );
}
my $correct = readFile( $path );
# Trim trailing whitespace off of both expected and correct
$correct =~ s{\s+$}{}; $correct .= "\n";
$output =~ s{\s+$}{}; $output .= "\n";
my $diff = diff( \$correct, \$output );
assert( $diff eq '', "Expected output from $name.correct, got:\n$diff" );
}
#####################################################################
### A P A C H E : : F A K E R E Q U E S T M U N G I N G
#####################################################################
# Overload Apache::FakeRequest's print to append output to a variable.
{
package Apache::FakeRequest;
use vars qw{%Pnotes $Output $Errout};
no warnings 'redefine';
%Pnotes = ();
$Output = $Errout = '';
sub Reset {
%Pnotes = ();
$Output = $Errout = '';
}
sub print {
my $r = shift;
$Output .= join('', @_)
}
sub log_error {
my $r - shift;
print STDERR @_, "\n"; $Errout .= join('', @_)
}
sub pnotes {
my ( $r, $key ) = @_;
$Pnotes{ $key } = shift if @_;
return $Pnotes{ $key };
}
}
#####################################################################
### T E S T S
#####################################################################
# Define tests
@testSuite = (
{
name => 'setup',
func => sub {
Apache::FakeRequest->Reset;
},
},
);
# Auto-generate tests for each test subdir
foreach my $subdir ( @TestSubdirs ) {
my $testpat = File::Spec->catdir( $TestDir, $subdir );
# Find all the .bml files, skipping those which start with underscores.
foreach my $bmlfile ( glob "$testpat/*.bml" ) {
next if $bmlfile =~ m{/_};
( my $name = $bmlfile ) =~ s{.*/(.*)\.bml$}{$1};
my $testdir = dirname( $bmlfile );
my $testname = basename( $testdir );
# Add a test to the suite for the .bml file
push @testSuite,
{
name => "$testname $name",
test => sub {
#print "Testing dir: $testdir\n";
my $request = new Apache::FakeRequest (
document_root => $TestDir,
uri => "/$name.bml",
filename => "$bmlfile",
);
my $res;
$ENV{testlookroot} = $testdir;
assertNoException {
local $SIG{ALRM} = sub { die "Timeout" };
alarm 10;
$res = Apache::BML::handler($request)
};
alarm 0;
assertEquals 0, $res;
assertCorrect( $testdir, $name, $Apache::FakeRequest::Output );
print STDERR $Apache::Request::Errout, "\n";
},
};
}
}
runTests( @testSuite );

8
bml/test/Pblocks/scheme.look Executable file
View File

@ -0,0 +1,8 @@
oneline=>{P}Arg one: %%DATA1%%; Arg two: %%DATA2%%
multiline<={P}
Arg one: %%DATA1%%
Arg two: %%DATA2%%
<=multiline

9
bml/test/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

52
bml/test/bml-profile.pl Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/perl
#
use strict;
use lib "$ENV{'LJHOME'}/cgi-bin";
use Apache;
use Apache::FakeRequest ();
use Apache::BML;
use Benchmark;
my $benchmark = shift; # times to run new code
my $bold = shift; # times to run old code
$bold = $benchmark unless defined $bold;
my $r = Apache::FakeRequest->new(
'filename' => "$ENV{LJHOME}/fake_root/bml-test.bml",
# 'filename' => "$ENV{LJHOME}/htdocs/foo.bml",
'document_root' => "$ENV{LJHOME}/fake_root",
'method' => "GET",
'args' => "",
'content' => "",
'uri' => '/bml-test.bml',
# 'uri' => '/foo.bml',
'header_only' => $benchmark ? 1 : 0,
);
unless ($benchmark) {
# *Apache::BML::bml_decode = \&Apache::BML::bml_decode_OLD;
# *Apache::BML::load_elements = \&Apache::BML::load_elements_OLD;
my $stat = Apache::BML::handler($r);
die "bad init" unless $stat == 0;
exit 0;
}
print "New code:\n";
timethis($benchmark, sub {
my $stat = Apache::BML::handler($r);
});
if ($bold) {
print "Old code:\n";
*Apache::BML::bml_decode = \&Apache::BML::bml_decode_OLD;
*Apache::BML::load_elements = \&Apache::BML::load_elements_OLD;
timethis($bold, sub {
my $stat = Apache::BML::handler($r);
});
}

9
bml/test/brads/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

9
bml/test/brads/scheme.look Executable file
View File

@ -0,0 +1,9 @@
page<=
{F}<html>
<head><title>%%title%%</title></head>
<body>
%%body%%
</body>
</html>
<=page

16
bml/test/brads/test1.bml Executable file
View File

@ -0,0 +1,16 @@
<?_info
localblocks<=
foo=>[foo]%%DATA%%[/foo]
<=localblocks
_info?><?page
title=>Test1
body<=
Test of local block foo: <?foo?>
Another test of local block foo: <?foo with data this time foo?>
<=body
page?>

12
bml/test/brads/test1.correct Executable file
View File

@ -0,0 +1,12 @@
<html>
<head><title>Test1</title></head>
<body>
Test of local block foo: [foo][/foo]
Another test of local block foo: [foo]with data this time[/foo]
</body>
</html>

View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

View File

@ -0,0 +1,6 @@
<?_code $content = "This should show up twice"; _code?>
<?_code $content _code?>
<?_code my $other = "This should only show up once."; _code?>
<?_code $other _code?>

View File

@ -0,0 +1,6 @@
This should show up twice
This should show up twice
This should only show up once.

View File

@ -0,0 +1,15 @@
<?_code
sub some_function { return "This is from the first codeblock"; }
$package = __PACKAGE__;
return "Returning from the first codeblock.";
_code?>
<?_code
$package->some_function();
_code?>

View File

@ -0,0 +1,4 @@
Returning from the first codeblock.
This is from the first codeblock

View File

@ -0,0 +1,28 @@
<?_code
package Foo;
sub new {
my $class = shift;
my ( $this, $that ) = @_;
bless {
this => $this || "default this",
that => $that || "default that",
}, $class;
}
sub this { my $self = shift; $self->{this} = shift if @_; $self->{this} }
sub that { my $self = shift; $self->{that} = shift if @_; $self->{that} }
sub msg {
my $self = shift;
return "[This: ". $self->this . ", That: ". $self->that . "]";
}
_code?>
<?_code
my $f = new Foo "pony", "not yours";
$f->msg;
_code?>

View File

@ -0,0 +1,6 @@
[This: pony, That: not yours]

View File

@ -0,0 +1,9 @@
Return a BML construct:
<?_code return "<?tag Foo tag?>" _code?>
Inside-out from above:
<?exec return "[This is it.]" exec?>
Recurse:
<?exec return '<?_code return "[Foo.]" _code?>' exec?>

View File

@ -0,0 +1,9 @@
Return a BML construct:
[Tag: Foo]
Inside-out from above:
[This is it.]
Recurse:
[Error: <b>_CODE block failed to execute by permission settings</b>]

View File

@ -0,0 +1,4 @@
tag=>{D}[Tag: %%DATA%%]
exec=>{D}<?_code %%DATA%% _code?>

12
bml/test/codeblocks/simple.bml Executable file
View File

@ -0,0 +1,12 @@
Immediate value/Simple string:
<?_code "Foo" _code?>
Immediate value/List:
<?_code qw{this is some data in a list} _code?>
Returned string:
<?_code return "Bar" _code?>
Returned List:
<?_code return ("some", "stuff", "in", "a", "list") _code?>

View File

@ -0,0 +1,12 @@
Immediate value/Simple string:
Foo
Immediate value/List:
list
Returned string:
Bar
Returned List:
list

9
bml/test/comments/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

22
bml/test/comments/basic.bml Executable file
View File

@ -0,0 +1,22 @@
Comment:
<?_c This shouldn't show up _c?>
Comment full:
<?_comment This shouldn't show up _comment?>
Embedded:
<?_c This shouldn't show up: <?_code something _code?> _c?>
Embedded full:
<?_comment This shouldn't show up: <?_code something _code?> _comment?>
Multiline:
<?_c
This shouldn't show up: <?_code something _code?>
_c?>

18
bml/test/comments/basic.correct Executable file
View File

@ -0,0 +1,18 @@
Comment:
Comment full:
Embedded:
Embedded full:
Multiline:

13
bml/test/comments/rendered.bml Executable file
View File

@ -0,0 +1,13 @@
Single line:
<?user_comment This shouldn't be rendered user_comment?>
Multiline:
<?user_comment
This is a comment, too, so it shouldn't be renderered.
user_comment?>
Indirect:
<?indirect This shouldn't be rendered indirect?>

View File

@ -0,0 +1,11 @@
Single line:
Multiline:
Indirect:
(Indirect)

6
bml/test/comments/scheme.look Executable file
View File

@ -0,0 +1,6 @@
user_comment=><?_c %%DATA%% _c?>
indirect<=
(Indirect)
<?user_comment %%DATA%% user_comment?>
<=indirect

9
bml/test/escape/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

34
bml/test/escape/ea.bml Executable file
View File

@ -0,0 +1,34 @@
Escape HTML tags:
<?_ea In structural HTML, the <b> tag should be replaced with <strong> and the
<i> tag with <em>. _ea?>
Escape a code example:
<pre><code><?_ea
# Overload Apache::FakeRequest's print to append output to a variable.
{
no warnings 'redefine';
*Apache::FakeRequest::print = sub {
my $r = shift;
$Output .= join('', @_)
};
*Apache::FakeRequest::log_error = sub {
my $r - shift;
print STDERR @_, "\n"; $Errout .= join('', @_)
};
*Apache::FakeRequest::pnotes = sub {
my ( $r, $key ) = @_;
$Pnotes->{ $key } = shift if @_;
$Pnotes->{ $key };
};
}
_ea?></code></pre>
Escape old-style syntax:
<?_ea Tags in BML used to be like (=this=), but that format has since been
deprecated. _ea?>
Escape new-style syntax:
<?_ea Now tags in BML look like: <?foo?>. _ea?>

32
bml/test/escape/ea.correct Executable file
View File

@ -0,0 +1,32 @@
Escape HTML tags:
In structural HTML, the &lt;b&gt; tag should be replaced with &lt;strong&gt; and the
&lt;i&gt; tag with &lt;em&gt;.
Escape a code example:
<pre><code># Overload Apache::FakeRequest&#39;s print to append output to a variable.
{
no warnings &#39;redefine&#39;;
*Apache::FakeRequest::print = sub {
my $r = shift;
$Output .= join(&#39;&#39;, @_)
};
*Apache::FakeRequest::log_error = sub {
my $r - shift;
print STDERR @_, &quot;\n&quot;; $Errout .= join(&#39;&#39;, @_)
};
*Apache::FakeRequest::pnotes = sub {
my ( $r, $key ) = @_;
$Pnotes-&gt;{ $key } = shift if @_;
$Pnotes-&gt;{ $key };
};
}</code></pre>
Escape old-style syntax:
Tags in BML used to be like (= this =), but that format has since been
deprecated.
Escape new-style syntax:
Now tags in BML look like: &lt;?foo?&gt;.

7
bml/test/escape/eb.bml Executable file
View File

@ -0,0 +1,7 @@
Escape old-style syntax:
<?_eb Tags in BML used to be like (=this=), but that format has since been
deprecated. _eb?>
Escape new-style syntax:
<?_eb Now tags in BML look like: <?foo?>. _eb?>

7
bml/test/escape/eb.correct Executable file
View File

@ -0,0 +1,7 @@
Escape old-style syntax:
Tags in BML used to be like (= this =), but that format has since been
deprecated.
Escape new-style syntax:
Now tags in BML look like: &lt;?foo?&gt;.

26
bml/test/escape/eh.bml Executable file
View File

@ -0,0 +1,26 @@
Escape HTML tags:
<?_eh In structural HTML, the <b> tag should be replaced with <strong> and the
<i> tag with <em>. _eh?>
Escape a code example:
<pre><code><?_eh
# Overload Apache::FakeRequest's print to append output to a variable.
{
no warnings 'redefine';
*Apache::FakeRequest::print = sub {
my $r = shift;
$Output .= join('', @_)
};
*Apache::FakeRequest::log_error = sub {
my $r - shift;
print STDERR @_, "\n"; $Errout .= join('', @_)
};
*Apache::FakeRequest::pnotes = sub {
my ( $r, $key ) = @_;
$Pnotes->{ $key } = shift if @_;
$Pnotes->{ $key };
};
}
_eh?></code></pre>

24
bml/test/escape/eh.correct Executable file
View File

@ -0,0 +1,24 @@
Escape HTML tags:
In structural HTML, the &lt;b&gt; tag should be replaced with &lt;strong&gt; and the
&lt;i&gt; tag with &lt;em&gt;.
Escape a code example:
<pre><code># Overload Apache::FakeRequest&#39;s print to append output to a variable.
{
no warnings &#39;redefine&#39;;
*Apache::FakeRequest::print = sub {
my $r = shift;
$Output .= join(&#39;&#39;, @_)
};
*Apache::FakeRequest::log_error = sub {
my $r - shift;
print STDERR @_, &quot;\n&quot;; $Errout .= join(&#39;&#39;, @_)
};
*Apache::FakeRequest::pnotes = sub {
my ( $r, $key ) = @_;
$Pnotes-&gt;{ $key } = shift if @_;
$Pnotes-&gt;{ $key };
};
}</code></pre>

3
bml/test/escape/eu.bml Executable file
View File

@ -0,0 +1,3 @@
Escaped URL characters:
http://www.fruit-jar.com/booklist?title=<?_eu 21 Things to do with Excess !%$@#!@#@# Punctuation _eu?>

3
bml/test/escape/eu.correct Executable file
View File

@ -0,0 +1,3 @@
Escaped URL characters:
http://www.fruit-jar.com/booklist?title=21+Things+to+do+with+Excess+%21%25%24%40%23%21%40%23%40%23+Punctuation

1
bml/test/escape/scheme.look Executable file
View File

@ -0,0 +1 @@

9
bml/test/fake_root/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot .
DefaultScheme bluewhite
DefaultLanguage en
AllowCode 1
AllowTemplateCode 1

251
bml/test/fake_root/bluewhite.look Executable file
View File

@ -0,0 +1,251 @@
#
# Welcome to GENERIC.LOOK for the WhiteBlue scheme
#
# by....
# Brad Fitzpatrick
# brad@danga.com
#
######################### little stuff
_parent=>global.look
AL=>{P}<I><A HREF="%%DATA1%%">%%DATA2%%</A></I> <IMG SRC="/img/external_link.gif" WIDTH=16 HEIGHT=11 ALIGN=ABSMIDDLE>
AWAYLINK=>{P}<I><A HREF="%%DATA1%%">%%DATA2%%</A></I> <IMG SRC="/img/external_link.gif" WIDTH=16 HEIGHT=11 ALIGN=ABSMIDDLE>
H1=>{D}<P><FONT FACE="Arial,Helvetica" COLOR="#CC0000"><B>%%DATA%%</B></FONT>
H1/FOLLOW_CHOICES=>{D}<FONT FACE="Arial,Helvetica" COLOR="#CC0000"><B>%%DATA%%</B></FONT>
HEAD1=>{D}<P><FONT FACE="Arial,Helvetica" COLOR="#CC0000"><B>%%DATA%%</B></FONT>
H2=>{D}<P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>%%DATA%%</B></FONT>
HEAD2=>{D}<P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>%%DATA%%</B></FONT>
# Banner Header: search results banner, content desriptor, etc...
BH=>{D}<P ALIGN=CENTER><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>%%DATA%%</B></FONT>
GRIN=>&lt;grin&gt;
HR=><P ALIGN="CENTER"><FONT COLOR=BLUE>*</FONT></P>
NEWLINE=>{D}<BR>&nbsp;&nbsp;&nbsp;&nbsp;
P=>{D}<BR>%%DATA%%
P/FOLLOW_P=>{D}<BR><IMG SRC="/img/dot.gif" WIDTH=1 VSPACE=6 HEIGHT=1><BR>%%DATA%%
STANDOUTO<=
{D}<CENTER><FONT SIZE=1><BR></FONT><TABLE ALIGN=CENTER CELLPADDING=8 BORDER=1 BGCOLOR=#CCCCFF BORDERCOLORLIGHT=#DDDDFF
BORDERCOLORDARK=#BBBBFF><TR><TD VALIGN=CENTER>
%%DATA%%
</TD></TR></TABLE></CENTER>
<=STANDOUTO
STANDOUT<=
{D}<CENTER><FONT SIZE=1><BR></FONT>
<table cellspacing=0 cellpadding=0 border=0 bgcolor="#ccccff">
<tr>
<td width=7 align=left valign=top>
<img width=7 height=7 src="/img/corn_nw.gif" alt=""></td>
<td height=7>
<img height=7 src="/img/dot.gif" alt=""></td>
<td width=7 valign=top align=right>
<img height=7 src="/img/corn_ne.gif" alt=""></td>
</tr><tr>
<td width=7>
<img width=7 height=1 src="/img/dot.gif" alt=""></td>
<td valign=top>
%%DATA%%
</td>
<td width=7>
<img width=7 height=1 src="/img/dot.gif" alt=""></td>
</tr><tr>
<td width=7 align=left valign=top>
<img width=7 height=7 src="/img/corn_sw.gif" alt=""></td>
<td height=7>
<img height=7 src="/img/dot.gif" alt=""></td>
<td width=7 valign=top align=right>
<img height=7 src="/img/corn_se.gif" alt=""></td>
</tr>
</table>
</CENTER>
<=STANDOUT
SOERROR=><div style='background-color:#f3f4fe; color:red; font-weight:bold; text-align:center'>%%data%%</div>
######################### choices stuff
CHOICE=>{P}<DT><A HREF="%%DATA2%%"><FONT FACE="Arial,Helvetica"><B>%%DATA1%%</B></FONT></A><DD><FONT SIZE="2">%%DATA3%%</FONT>
CHOICES<=
{F}<P><DIV CLASS="choice"><TABLE WIDTH="100%" CELLPADDING="2" CELLSPACING="5">
<TR>
<TD VALIGN=TOP WIDTH="50%">
<DL>
%%ITEMS%%
</DL>
</TD>
<TD VALIGN=TOP WIDTH="50%">
<DL>
%%ITEMSB%%
</DL>
</TD>
</TR>
</TABLE></DIV>
<=CHOICES
##################################################################################
################################### MAIN PAGE ####################################
##################################################################################
PAGE<=
{F}<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML><?load_page_info?>
<HEAD>
<TITLE>%%TITLE%%</TITLE>
%%head%%
</HEAD>
<BODY BGCOLOR=#FFFFFF TOPMARGIN="0" LEFTMARGIN="0" MARGINHEIGHT="0" MARGINWIDTH="0" LINK=#0000C0 VLINK=#0000C0 %%bodyopts%%>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0 BACKGROUND="/img/bluewhite/bluefade.jpg">
<TR WIDTH=100%>
<TD VALIGN=BOTTOM ALIGN=LEFT HEIGHT=100>
<TABLE BACKGROUND="" HEIGHT=95 WIDTH=100% BORDER=0>
<TR>
<TD WIDTH=3>&nbsp;</TD>
<TD HEIGHT=53 WIDTH=406 VALIGN=BOTTOM>
<?_code
$is_home = (BML::get_uri() =~ m!^/(index\.bml)?!);
if (0 && $is_home)
{
return '<IMG SRC="/img/bluewhite/title.gif" WIDTH=600 HEIGHT=53><!-- ';
}
return "";
_code?>
<FONT SIZE=6 COLOR="#000a3f" FACE="Arial, Helvetica"><B>%%TITLE%%</B></FONT>
<?_code
if (0 && $is_home)
{
return ' -->';
}
return "";
_code?>
</TD>
<TD VALIGN=TOP ALIGN=RIGHT>
<?_code
unless ($is_home) {
return "<A HREF=\"/\"><IMG SRC=\"/img/bluewhite/home.gif\" WIDTH=35 HEIGHT=36 BORDER=0></A>&nbsp;";
}
return "";
_code?>
</TD>
</TR>
</TABLE>
</TD></TR>
</TABLE>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR VALIGN=TOP>
<TD WIDTH=133 BGCOLOR=#d7d9e8 NOWRAP><IMG SRC="/img/bluewhite/hline.gif" WIDTH=133 HEIGHT=25 ALT="">
<TABLE WIDTH=128 BORDER=0 CELLSPACING=0 CELLPADDING=0>
<TR><TD>
<FONT FACE="Arial,Helvetica" SIZE=-1>
<?_code
$ret = "";
sub dump_entry
{
my ($ret, $listref, $depth) = @_;
foreach my $mi (@$listref)
{
if ($depth==0) {
$$ret .= "<P><IMG SRC=\"/img/bluewhite/bullet.gif\" WIDTH=10 HEIGHT=10 HSPACE=2 ALIGN=ABSMIDDLE>";
} else {
$$ret .= "&nbsp;" x ($depth*3+1);
$$ret .= $mi->{'cont'} ? "&nbsp;&nbsp;" : "- ";
}
my $name = $mi->{'name'};
$name =~ s/ /&nbsp;/g;
if (! defined $mi->{'uri'}) {
if ($depth == 0) {
$$ret .= "<B>$name</B><BR>";
} else {
$$ret .= "$name<BR>";
}
} elsif ($mi->{'match'} ?
(BML::get_uri() =~ /$mi->{'match'}/) :
(BML::get_uri() eq $mi->{'uri'})
){
$$ret .= "<B><SPAN style=\"background-color: #FFFFFF\"><FONT COLOR=#0000D0>$name</FONT></SPAN></B><BR>";
} else {
$$ret .= "<A HREF=\"$mi->{'uri'}\">$name</A><BR>";
}
if ($mi->{'children'} &&
($mi->{'recursematch'} ? BML::get_uri() =~ /$mi->{'recursematch'}/ : 1)) {
&dump_entry($ret, $mi->{'children'}, $depth+1);
}
}
}
&dump_entry(\$ret, \@sidebar, 0);
return $ret;
_code?>
</FONT>
</TD></TR></TABLE>
</TD>
<TD ALIGN=LEFT BACKGROUND="/img/bluewhite/vline.gif" WIDTH=25 NOWRAP>
<IMG SRC="/img/bluewhite/linetop.gif" WIDTH=25 HEIGHT=25 ALT=""><BR>
<IMG SRC="/img/bluewhite/vline.gif" WIDTH=25 HEIGHT=800 ALT="">
</TD>
<TD>
<IMG SRC="/img/dot.gif" WIDTH=1 HEIGHT=3><BR>
%%BODY%%
</TD>
<TD WIDTH=20>&nbsp;</TD>
</TR>
<!-- table closure row -->
<TR>
<TD WIDTH=133 NOWRAP><IMG SRC="/img/bluewhite/sidebarfade.gif" WIDTH=133 HEIGHT=25 ALT=""></TD>
<TD WIDTH=25 NOWRAP><IMG SRC="/img/bluewhite/sidebarfade_line.gif" WIDTH=25 HEIGHT=25 ALT=""></TD></TD>
<TD>
&nbsp;
</TD>
<TD WIDTH=20>&nbsp;</TD>
</TR>
</TABLE>
<!-- /table closure row -->
<TABLE WIDTH=100%>
<TR>
<TD ALIGN=RIGHT>
<FONT FACE="Arial, Helvetica" SIZE="-2">
<A HREF="/privacy.bml">Privacy Policy</A> -
<A HREF="/coppa.bml">COPPA</A><BR>
<A HREF="/disclaimer.bml">Legal Disclaimer</A> -
<A HREF="/sitemap.bml">Site Map</A><BR>
</FONT>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
<=PAGE

View File

@ -0,0 +1,14 @@
<?_info
localblocks<=
h1=>{D}<h1 bml='1'>%%data%%</h1>
<=localblocks
_info?>
Pre.
[<?h1 User Links <?h1 Inner h1?> <?h1?> h1?>]
Mid.
<?h1?>
End.

View File

@ -0,0 +1,10 @@
Pre.
[<h1 bml='1'>User Links <h1 bml='1'>Inner</h1> <h1 bml='1'></h1></h1>]
Mid.
<h1 bml='1'></h1>
End.

265
bml/test/fake_root/bml-test.bml Executable file
View File

@ -0,0 +1,265 @@
<?_info
localblocks<=
pof=>{s}<a href='/paidaccounts/'><img src='<?imgprefix?>/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a>
pef=>{s}<a href='/paidaccounts/'><img src='<?imgprefix?>/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a>
h1=>{D}<h1 bml='1'>%%data%%</h1>
page<=
{F}<html>
<head><title>%%title%%</title></head>
<body>
%%body%%
</body></html>
<=page
<=localblocks
_info?><?page
head<=
<style type="text/css">
<!--
li { font-weight: bold; }
li.header { font-weight: normal; }
-->
</style>
<=head
title=>Site Map
body<=
<?p foo p?>
<?p bar p?>
<?p baz <?p baznest p?> endbaz p?>
<?pof?> = Paid Only Feature<br />
<?pef?> = Enhanced for Paid Users
<?h1 User Links <?h1 Inner h1?> <?h1?> h1?>
<?h1?>
<table style='margin-top: 10px' cellpadding="2" width="100%">
<tr valign="top"><td>
<ul>
<li class="header"><?h2 Your Account: h2?>
<ul>
<li><a href="/create.bml">Create an Account</a></li>
<li><a href="/login.bml">Login to your Account</a></li>
<li><a href="/update.bml">Update your Journal</a></li>
<li><a href="/editjournal.bml">Edit your Journal Entries</a></li>
<li><a href="/lostinfo.bml">Lost Password?</a></li>
<li><a href="/changepassword.bml">Change Account Password</a></li>
<li><a href="/tools/emailmanage.bml">Email Management</a></li>
<li><a href="/accountstatus.bml">Delete/Undelete your Journal</a></li>
<li><a href="/manage/files.bml">File Manager</a></li>
</ul>
</li>
<li class="header"><?h2 Your Settings: h2?>
<ul>
<li><a href="/manage/">Manage all Settings</a></li>
<li><a href="/editinfo.bml">Edit your Information</a> <?pef?></li>
<li><a href="/customize/">Customize your Journal</a> <?pef?></li>
<li><a href="/manage/links.bml">Create Link List</a> <?pef?></li>
<li><a href="/manage/siteopts.bml">Browse Preferences</a></li>
<li><a href="/editpics.bml">Edit and Upload User Picture Icons</a> <?pef?></li>
<li><a href="/manage/emailpost.bml">Email Gateway Settings</a> <?pof?></li>
<li><a href="/manage/phonepost.bml">Post by Phone Settings</a> <?pof?></li>
</ul>
</li>
<li class="header"><?h2 Tools: h2?>
<ul>
<li><a href="/portal/">Portal</a></li>
<li><a href="/invite/">Invite a Friend</a> <?pef?></li>
<li><a href="/misc/whereami.bml">Where am I?</a></li>
<li><a href="/admin/console">Administrative Console</a> - <a href="/admin/console/reference.bml">Reference</a></li>
<li><a href="/tools/textmessage.bml">Text Message Tool</a> <?pof?></li>
<li><a href="/poll/create.bml">Poll Creator</a> <?pof?></li>
<li><a href="/tools/memories.bml">Memorable Posts</a></li>
<li><a href="/todo/">To-Do List</a> <?pef?></li>
<li><a href="/export.bml">Export your Journal</a></li>
</ul>
</li>
<li class="header"><?h2 Friends: h2?>
<ul>
<li><a href="/friends/edit.bml">Edit Your Friends</a></li>
<li><a href="/friends/editgroups.bml">Edit Your Friend Groups</a></li>
<li><a href="/friends/filter.bml">Friends Filter</a></li>
<li><a href="/birthdays.bml">Birthdays</a></li>
<li><a href="/friends/popwithfriends.bml">Popular Users Amongst Your Friends</a> <?pof?></li>
</ul>
</li>
<li class="header"><?h2 Clients: h2?>
<ul>
<li><a href="/download/">Download A Client</a></li>
<li><a href="/update.bml">Web Update Client</a> - <a href="/update.bml?mode=full">(Full Mode)</a></li>
<li><a href="/phonepost/">Post by Phone <?pof?></li>
<li><a href="/support/faqbrowse.bml?faqcat=clients">FAQ Category</a></li>
</ul>
</li>
<li class="header"><?h2 Communities: h2?>
<ul>
<li><a href="/community/">Community Center</a></li>
<li><a href="/community/settings.bml?mode=create">Create a Community</a></li>
<li><a href="/community/manage.bml">Manage Communities</a></li>
<li><?ljcomm community_promo ljcomm?></li>
<li><?ljcomm community_quest ljcomm?></li>
<li><a href="/support/faqbrowse.bml?faqcat=community">FAQ Category</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=comm-manage">Community Management FAQ</a></li>
</ul>
</li>
<li class="header"><?h2 Legal / Abuse: h2?>
<ul>
<li><a href="/legal/tos.bml">Terms Of Service</a></li>
<li><a href="/legal/privacy.bml">Privacy Policy</a></li>
<li><a href="/legal/coppa.bml">COPPA Policy</a></li>
<li><a href="/site/contract.bml">Our Social Contract</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=abuse">FAQ Category</a></li>
<li><a href="/abuse/report.bml">Report Violations</a></li>
</ul>
</li>
</ul>
</td><td>
<ul>
<li class="header"><?h2 New to <?sitename?>? h2?>
<ul>
<li><a href="/site/about.bml">About <?sitename?></a></li>
<li><a href="/doc/tour">Take the LiveJournal Tour</a></li>
<li><a href="http://newbies.livejournal.com/">The Newbies Lounge</a></li>
<li><a href="/create.bml">Create an Account</a></li>
<li><a href="/support/">Have a Question?</a></li>
</ul>
</li>
<li class="header"><?h2 Paid Accounts: h2?>
<ul>
<li><a href="/paidaccounts/">Paid Accounts</a></li>
<li><a href="/site/accounts.bml">Features by Account Type</a></li>
<li><a href="/paidaccounts/status.bml">Paid Account Status</a></li>
<li><a href="/pay/history.bml">Payment History</a> - <a href="/pay/coupons.bml">Current Coupons</a></li>
<li><a href="/rename/">Rename Your Account</a></li>
<li><a href="/paidaccounts/friends.bml">Buy for Friends!</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=paidaccounts">FAQ Category</a></li>
<li><a href="/phonepost/">Post by Phone</a></li>
</ul>
</li>
<li class="header"><?h2 Style System 1: h2?>
<ul>
<li><a href="/developer/styles.bml">Style Reference</a></li>
<li><a href="/styles/create.bml">Create a Style</a> <?pof?></li>
<li><a href="/styles/edit.bml">Edit Styles</a> <?pof?></li>
<li><a href="/modify.bml">Modify your S1 Settings</a> <?pef?></li>
</ul>
</li>
<li class="header"><?h2 Style System 2 h2?>
<ul>
<li><a href="/doc/s2/">S2 Manual</a></li>
<li><a href="/customize/">Customize your Journal</a></li>
<li><a href="/customize/advanced/layerbrowse.bml">Layer Browser</a></li>
<li><a href="/customize/advanced/">Advanced Customization</a> <?pof?></li>
</ul>
</li>
<li class="header"><?h2 Syndication: h2?>
<ul>
<li><a href="/syn/">Syndicated Accounts</a> <?pef?></li>
<li><?ljcomm syn_promo ljcomm?></li>
<li><a href="/syn/raw.bml">Recently Updated Feeds</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=syn">FAQ Category</a></li>
</ul>
</li>
<li class="header"><?h2 Technical Support: h2?>
<ul>
<li><a href="/support/faq.bml">FAQ</a> - <a href="/support/faqpop.bml">Popular FAQs</a></li>
<li><a href="/support/submit.bml">Ask a Question</a></li>
<li><a href="/support/help.bml">Help Someone Out</a></li>
<li><a href="/support/highscores.bml">High Scores</a></li>
<li><a href="/support/changenotify.bml">Change Support Notifications</a></li>
</ul>
</li>
<li class="header"><?h2 International: h2?>
<ul>
<li><a href="/manage/siteopts.bml">Set Language</a></li>
<li><a href="/utf8convert.bml">Conversion Tool</a></li>
<li><a href="/translate/">Tool for Translation Volunteers</a></li>
</ul>
</li>
<li class="header"><?h2 Fun Stuff: h2?>
<ul>
<li><a href="./goat.bml">Frank the Goat!</a></li>
<li><a href="/users/news/50307.html?mode=reply">LiveJournal &hellip; The Song!</a></li>
<li><a href="/singles/">Singles</a> <?pof?></li>
<li><a href="/meme.bml">Meme Tracker</a></li>
<li><a href="/banners.bml">Banners</a></li>
<li><?ljcomm lj_nifty ljcomm?></li>
</ul>
</li>
<li class="header"><?h2 Search/Find Users: h2?>
<ul>
<li><a href="/random.bml">Random User</a></li>
<li><a href="/directory.bml">By Region</a> <?pof?></li>
<li><a href="/interests.bml">By Interest</a> <?pef?></li>
<li><a href="/directorysearch.bml">Directory Search</a> <?pof?></li>
</ul>
</li>
</ul></td>
</tr>
</table>
<?h1 Other Links h1?>
<table style='margin-top: 10px' cellpadding="2" width="100%">
<tr valign="top">
<td>
<ul>
<li class="header"><?h2 Development: h2?>
<ul>
<li><a href="/developer/">Developer Info</a></li>
<li><a href="/site/contributors.bml">Contributors</a></li>
<li><?ljcomm lj_dev ljcomm?></li>
<li><a href="/users/changelog">Changelog</a></li>
<li><a href="http://www.livejournal.org">LiveJournal.org</a></li>
<li><a href="http://test.livejournal.org">Test Site</a> - <?ljcomm lj_test ljcomm?></li>
<li><a href="http://cvs.livejournal.org">CVS</a></li>
<li><a href="/doc/server/">LiveJournal Server Manual</a></li>
</ul>
</li>
<li class="header"><?h2 Service Status: h2?>
<ul>
<li><a href="/news.bml">News Page</a> - <?ljuser news ljuser?></li>
<li><a href="http://status.livejournal.org">The Status of LiveJournal</a></li>
<li><?ljcomm lj_maintenance ljcomm?></li>
</ul>
</li>
<li class="header"><?h2 Offsite Tools: h2?>
<ul>
<li><a href="http://www.petekrawczyk.com/lj_connect/">LiveJournal Connect</a></li>
<li><a href="http://marnanel.org/joule">Friends List Analysis, Past &amp; Present</a></li>
<li><a href="http://livejournal.meetup.com/">Meetup!</a></li>
</ul>
</li>
</ul>
</td><td>
<ul>
<li class="header"><?h2 Feedback: h2?>
<ul>
<li><a href="/suggestions/">Suggestions</a></li>
<li><a href="/support/">Technical Support</a></li>
</ul>
</li>
</ul>
<ul>
<li class="header"><?h2 Press: h2?>
<ul>
<li><a href="/press/">Press Area</a></li>
<li><a href="/press/articles.bml">LiveJournal in the Press</a> - <?ljuser press ljuser?></li>
<li><a href="/press/staff.bml">Senior Staff</a></li>
<li><a href="/stats.bml">Statistics</a></li>
</ul>
</li>
<li class="header"><?h2 Documentation: h2?>
<ul>
<li><a href="/support/faq.bml">FAQ</a></li>
<li><a href="/doc/html/">Guides</a></li>
<li><a href="/doc/server">LiveJournal Server Manual</a></li>
<li><?ljcomm lj_sysdoc ljcomm?></li>
<li><?ljcomm lj_userdoc ljcomm?></li>
</ul>
</li>
</ul>
</td></tr></table>
<?hr?>
Thanks go to <?ljuser pinrad ljuser?> for the initial version of this page.
<=body
page?>

View File

@ -0,0 +1,245 @@
<html>
<head><title>Site Map</title></head>
<body>
<BR>foo
<BR><IMG SRC="/img/dot.gif" WIDTH=1 VSPACE=6 HEIGHT=1><BR>bar
<BR><IMG SRC="/img/dot.gif" WIDTH=1 VSPACE=6 HEIGHT=1><BR>baz <BR>baznest endbaz
<a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a> = Paid Only Feature<br />
<a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a> = Enhanced for Paid Users
<h1 bml='1'>User Links <h1 bml='1'>Inner</h1> <h1 bml='1'></h1></h1>
<h1 bml='1'></h1>
<table style='margin-top: 10px' cellpadding="2" width="100%">
<tr valign="top"><td>
<ul>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Your Account:</B></FONT>
<ul>
<li><a href="/create.bml">Create an Account</a></li>
<li><a href="/login.bml">Login to your Account</a></li>
<li><a href="/update.bml">Update your Journal</a></li>
<li><a href="/editjournal.bml">Edit your Journal Entries</a></li>
<li><a href="/lostinfo.bml">Lost Password?</a></li>
<li><a href="/changepassword.bml">Change Account Password</a></li>
<li><a href="/tools/emailmanage.bml">Email Management</a></li>
<li><a href="/accountstatus.bml">Delete/Undelete your Journal</a></li>
<li><a href="/manage/files.bml">File Manager</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Your Settings:</B></FONT>
<ul>
<li><a href="/manage/">Manage all Settings</a></li>
<li><a href="/editinfo.bml">Edit your Information</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/customize/">Customize your Journal</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/manage/links.bml">Create Link List</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/manage/siteopts.bml">Browse Preferences</a></li>
<li><a href="/editpics.bml">Edit and Upload User Picture Icons</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/manage/emailpost.bml">Email Gateway Settings</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/manage/phonepost.bml">Post by Phone Settings</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Tools:</B></FONT>
<ul>
<li><a href="/portal/">Portal</a></li>
<li><a href="/invite/">Invite a Friend</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/misc/whereami.bml">Where am I?</a></li>
<li><a href="/admin/console">Administrative Console</a> - <a href="/admin/console/reference.bml">Reference</a></li>
<li><a href="/tools/textmessage.bml">Text Message Tool</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/poll/create.bml">Poll Creator</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/tools/memories.bml">Memorable Posts</a></li>
<li><a href="/todo/">To-Do List</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/export.bml">Export your Journal</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Friends:</B></FONT>
<ul>
<li><a href="/friends/edit.bml">Edit Your Friends</a></li>
<li><a href="/friends/editgroups.bml">Edit Your Friend Groups</a></li>
<li><a href="/friends/filter.bml">Friends Filter</a></li>
<li><a href="/birthdays.bml">Birthdays</a></li>
<li><a href="/friends/popwithfriends.bml">Popular Users Amongst Your Friends</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Clients:</B></FONT>
<ul>
<li><a href="/download/">Download A Client</a></li>
<li><a href="/update.bml">Web Update Client</a> - <a href="/update.bml?mode=full">(Full Mode)</a></li>
<li><a href="/phonepost/">Post by Phone <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/support/faqbrowse.bml?faqcat=clients">FAQ Category</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Communities:</B></FONT>
<ul>
<li><a href="/community/">Community Center</a></li>
<li><a href="/community/settings.bml?mode=create">Create a Community</a></li>
<li><a href="/community/manage.bml">Manage Communities</a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=community_promo'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/community_promo/'><b>community_promo</b></a></span></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=community_quest'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/community_quest/'><b>community_quest</b></a></span></li>
<li><a href="/support/faqbrowse.bml?faqcat=community">FAQ Category</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=comm-manage">Community Management FAQ</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Legal / Abuse:</B></FONT>
<ul>
<li><a href="/legal/tos.bml">Terms Of Service</a></li>
<li><a href="/legal/privacy.bml">Privacy Policy</a></li>
<li><a href="/legal/coppa.bml">COPPA Policy</a></li>
<li><a href="/site/contract.bml">Our Social Contract</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=abuse">FAQ Category</a></li>
<li><a href="/abuse/report.bml">Report Violations</a></li>
</ul>
</li>
</ul>
</td><td>
<ul>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>New to Foo.com?</B></FONT>
<ul>
<li><a href="/site/about.bml">About Foo.com</a></li>
<li><a href="/doc/tour">Take the LiveJournal Tour</a></li>
<li><a href="http://newbies.livejournal.com/">The Newbies Lounge</a></li>
<li><a href="/create.bml">Create an Account</a></li>
<li><a href="/support/">Have a Question?</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Paid Accounts:</B></FONT>
<ul>
<li><a href="/paidaccounts/">Paid Accounts</a></li>
<li><a href="/site/accounts.bml">Features by Account Type</a></li>
<li><a href="/paidaccounts/status.bml">Paid Account Status</a></li>
<li><a href="/pay/history.bml">Payment History</a> - <a href="/pay/coupons.bml">Current Coupons</a></li>
<li><a href="/rename/">Rename Your Account</a></li>
<li><a href="/paidaccounts/friends.bml">Buy for Friends!</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=paidaccounts">FAQ Category</a></li>
<li><a href="/phonepost/">Post by Phone</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Style System 1:</B></FONT>
<ul>
<li><a href="/developer/styles.bml">Style Reference</a></li>
<li><a href="/styles/create.bml">Create a Style</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/styles/edit.bml">Edit Styles</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/modify.bml">Modify your S1 Settings</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Style System 2</B></FONT>
<ul>
<li><a href="/doc/s2/">S2 Manual</a></li>
<li><a href="/customize/">Customize your Journal</a></li>
<li><a href="/customize/advanced/layerbrowse.bml">Layer Browser</a></li>
<li><a href="/customize/advanced/">Advanced Customization</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Syndication:</B></FONT>
<ul>
<li><a href="/syn/">Syndicated Accounts</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=syn_promo'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/syn_promo/'><b>syn_promo</b></a></span></li>
<li><a href="/syn/raw.bml">Recently Updated Feeds</a></li>
<li><a href="/support/faqbrowse.bml?faqcat=syn">FAQ Category</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Technical Support:</B></FONT>
<ul>
<li><a href="/support/faq.bml">FAQ</a> - <a href="/support/faqpop.bml">Popular FAQs</a></li>
<li><a href="/support/submit.bml">Ask a Question</a></li>
<li><a href="/support/help.bml">Help Someone Out</a></li>
<li><a href="/support/highscores.bml">High Scores</a></li>
<li><a href="/support/changenotify.bml">Change Support Notifications</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>International:</B></FONT>
<ul>
<li><a href="/manage/siteopts.bml">Set Language</a></li>
<li><a href="/utf8convert.bml">Conversion Tool</a></li>
<li><a href="/translate/">Tool for Translation Volunteers</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Fun Stuff:</B></FONT>
<ul>
<li><a href="./goat.bml">Frank the Goat!</a></li>
<li><a href="/users/news/50307.html?mode=reply">LiveJournal &hellip; The Song!</a></li>
<li><a href="/singles/">Singles</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/meme.bml">Meme Tracker</a></li>
<li><a href="/banners.bml">Banners</a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_nifty'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_nifty/'><b>lj_nifty</b></a></span></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Search/Find Users:</B></FONT>
<ul>
<li><a href="/random.bml">Random User</a></li>
<li><a href="/directory.bml">By Region</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/interests.bml">By Interest</a> <a href='/paidaccounts/'><img src='/img/talk/sm08_star.gif' width='25' height='19' alt='&#9786;' style='vertical-align: middle; border: 0;' /></a></li>
<li><a href="/directorysearch.bml">Directory Search</a> <a href='/paidaccounts/'><img src='/img/talk/md10_thumbup.gif' width='25' height='19' alt='&#10004;' style='vertical-align: middle; border: 0;' /></a></li>
</ul>
</li>
</ul></td>
</tr>
</table>
<h1 bml='1'>Other Links</h1>
<table style='margin-top: 10px' cellpadding="2" width="100%">
<tr valign="top">
<td>
<ul>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Development:</B></FONT>
<ul>
<li><a href="/developer/">Developer Info</a></li>
<li><a href="/site/contributors.bml">Contributors</a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_dev'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_dev/'><b>lj_dev</b></a></span></li>
<li><a href="/users/changelog">Changelog</a></li>
<li><a href="http://www.livejournal.org">LiveJournal.org</a></li>
<li><a href="http://test.livejournal.org">Test Site</a> - <span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_test'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_test/'><b>lj_test</b></a></span></li>
<li><a href="http://cvs.livejournal.org">CVS</a></li>
<li><a href="/doc/server/">LiveJournal Server Manual</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Service Status:</B></FONT>
<ul>
<li><a href="/news.bml">News Page</a> - <span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=news'><img src='/img/userinfo.gif' alt='userinfo' width='17' height='17' style='vertical-align:bottom;border:0;' /></a><a href='/users/news/'><b>news</b></a></span></li>
<li><a href="http://status.livejournal.org">The Status of LiveJournal</a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_maintenance'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_maintenance/'><b>lj_maintenance</b></a></span></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Offsite Tools:</B></FONT>
<ul>
<li><a href="http://www.petekrawczyk.com/lj_connect/">LiveJournal Connect</a></li>
<li><a href="http://marnanel.org/joule">Friends List Analysis, Past &amp; Present</a></li>
<li><a href="http://livejournal.meetup.com/">Meetup!</a></li>
</ul>
</li>
</ul>
</td><td>
<ul>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Feedback:</B></FONT>
<ul>
<li><a href="/suggestions/">Suggestions</a></li>
<li><a href="/support/">Technical Support</a></li>
</ul>
</li>
</ul>
<ul>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Press:</B></FONT>
<ul>
<li><a href="/press/">Press Area</a></li>
<li><a href="/press/articles.bml">LiveJournal in the Press</a> - <span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=press'><img src='/img/userinfo.gif' alt='userinfo' width='17' height='17' style='vertical-align:bottom;border:0;' /></a><a href='/users/press/'><b>press</b></a></span></li>
<li><a href="/press/staff.bml">Senior Staff</a></li>
<li><a href="/stats.bml">Statistics</a></li>
</ul>
</li>
<li class="header"><P><FONT FACE="Arial,Helvetica" COLOR="#CC0000" SIZE=-1><B>Documentation:</B></FONT>
<ul>
<li><a href="/support/faq.bml">FAQ</a></li>
<li><a href="/doc/html/">Guides</a></li>
<li><a href="/doc/server">LiveJournal Server Manual</a></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_sysdoc'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_sysdoc/'><b>lj_sysdoc</b></a></span></li>
<li><span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=lj_userdoc'><img src='/img/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/lj_userdoc/'><b>lj_userdoc</b></a></span></li>
</ul>
</li>
</ul>
</td></tr></table>
<P ALIGN="CENTER"><FONT COLOR=BLUE>*</FONT></P>
Thanks go to <span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=pinrad'><img src='/img/userinfo.gif' alt='userinfo' width='17' height='17' style='vertical-align:bottom;border:0;' /></a><a href='/users/pinrad/'><b>pinrad</b></a></span> for the initial version of this page.
</body></html>

286
bml/test/fake_root/global.look Executable file
View File

@ -0,0 +1,286 @@
IMGPREFIX=>{S}/img
STATPREFIX=>{S}/stc
SITENAME=>{S}Foo.com
SITEROOT=>{S}http://www.lj.com/
SECURITYPRIVATE=>{Ss}<img src="<?imgprefix?>/icon_private.gif" width=16 height=16 align=absmiddle>
SECURITYPROTECTED=>{Ss}<img src="<?imgprefix?>/icon_protected.gif" width=14 height=15 align=absmiddle>
LJUSER=>{DRs}<span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=%%data%%'><img src='<?imgprefix?>/userinfo.gif' alt='userinfo' width='17' height='17' style='vertical-align:bottom;border:0;' /></a><a href='/users/%%data%%/'><b>%%data%%</b></a></span>
LJCOMM=>{DRs}<span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=%%data%%'><img src='<?imgprefix?>/community.gif' alt='userinfo' width='16' height='16' style='vertical-align:bottom;border:0;' /></a><a href='/community/%%data%%/'><b>%%data%%</b></a></span>
LJUSERF=>{DRs}<span class='ljuser' style='white-space:nowrap;'><a href='/userinfo.bml?user=%%data%%&amp;mode=full'><img src='<?imgprefix?>/userinfo.gif' alt='userinfo' width='17' height='17' style='vertical-align:bottom;border:0;' /></a><a href='/users/%%data%%/'><b>%%data%%</b></a></span>
HELP=>{DR}(<a href="%%data%%"><i>help</i></a>)
INERR=>{DR}<font color="#ff0000"><b>%%data%%</b></font>
SOERROR=>{DR}<div><b>%%data%%</b></div>
NEEDLOGIN<=
<?h1 Login Required h1?>
<?p
To view this page you must first <a href="/login.bml?ret=1">go login</a>.
p?>
<=NEEDLOGIN
BADINPUT<=
<?h1 Bad Unicode input h1?>
<?p
Your browser sent some text which is not recognised as valid text in the
UTF-8 encoding, as it should be. This might happen if you forced your browser
to view the previous page in some other encoding rather than UTF-8. It may
also indicate a bug in the browser. If you cannot get around this error,
contact us.
p?>
<=BADINPUT
REQUIREPOST<=
{S}As a security precaution, the page you're viewing requires a POST request,
not a GET. If you're trying to submit this form legitimately, please
contact us.
<=REQUIREPOST
LOAD_PAGE_INFO<=
<?_code
#line 3
@sidebar = ({ 'name' => 'Home',
'uri' => '/',
'match' => "^/(index\\.bml)?(\\?.*)?\$",
'children' => [
{ 'name' => 'Create Journal',
'uri' => '/create.bml', },
{ 'name' => 'Update',
'uri' => '/update.bml',
'extra' => '/update.bml?mode=full',
# 'children' => [
# { 'name' => 'Full Update',
# 'uri' => '/update.bml?mode=full', }
# ],
},
{ 'name' => 'Download',
'uri' => '/download/', },
],
},
{ 'name' => 'LiveJournal',
'children' => [
{ 'name' => 'News',
'match' => '^/news\\.bml\$',
'uri' => '/news.bml', },
{ 'name' => 'Paid Accounts',
'uri' => '/paidaccounts/',
'recursematch' => '^/paidaccounts/',
'children' => [
{ 'name' => 'Is this safe?',
'uri' => '/paidaccounts/whysafe.bml', },
{ 'name' => 'Progress',
'uri' => '/paidaccounts/progress.bml', },
],
},
# { 'name' => 'To-Do list',
# 'uri' => '/todo.bml', },
{ 'name' => 'Contributors',
'uri' => '/contributors.bml', },
],
},
{ 'name' => 'Customize',
'children' => [
{ 'name' => 'Modify Journal',
'uri' => '/modify.bml', },
{ 'name' => 'Create Style',
'uri' => '/createstyle.bml', },
{ 'name' => 'Edit Style',
'uri' => '/editstyle.bml', },
],
},
{ 'name' => 'Find Users',
'children' => [
{ 'name' => 'Random!',
'uri' => '/random.bml', },
{ 'name' => 'By Region',
'uri' => '/directory.bml', },
{ 'name' => 'By Interest',
'uri' => '/interests.bml', },
{ 'name' => 'Search',
'uri' => '/directorysearch.bml', }
], },
{ 'name' => 'Edit ...',
'children' => [
{ 'name' => 'Personal Info &',
'uri' => '/editinfo.bml', },
{ 'name' => 'Settings', cont => 1,
'uri' => '/editinfo.bml', },
{ 'name' => 'Your Friends',
'uri' => '/editfriends.bml', },
{ 'name' => 'Old Entries',
'uri' => '/editjournal.bml', },
{ 'name' => 'Your Pictures',
'uri' => '/editpics.bml', },
{ 'name' => 'Your Password',
'uri' => '/changepassword.bml', },
],
},
{ 'name' => 'Developer Area',
'uri' => '/developer/',
'match' => "^/developer/\$",
'recursematch' => "^/developer/",
'children' => [
{ 'name' => 'Style System',
'uri' => '/developer/styles.bml',
'children' => [
{ 'name' => 'View Types',
'uri' => '/developer/views.bml', },
{ 'name' => 'Variable List',
'uri' => '/developer/varlist.bml', },
],
},
{ 'name' => 'Embedding',
'uri' => '/developer/embedding.bml', },
{ 'name' => 'Protocol',
'uri' => '/developer/protocol.bml',
'children' => [
{ 'name' => 'Mode List',
'uri' => '/developer/modelist.bml', }
],
},
],
},
{ 'name' => 'Need Help?',
'children' => [
{ 'name' => 'Lost Password?',
'uri' => '/lostinfo.bml', },
{ 'name' => 'Freq. Asked',
'uri' => '/support/faq.bml', },
{ 'name' => 'Questions',
'uri' => '/support/faq.bml', cont => 1, },
{ 'name' => 'Support Area',
'uri' => '/support/', },
],
},
);
my $remote = LJ::get_remote();
my $remuser = $remote ? $remote->{'user'} : "";
my $uri = BML::get_uri();
if ($remuser ne "" && $uri ne "/logout.bml")
{
my $subdomain = $remuser;
$subdomain =~ s/_/-/g;
unshift @sidebar, { 'name' => "Hello, $remuser!",
'children' => [
{ 'name' => 'Your Journal',
'children' => [
{ 'name' => 'Recent',
'uri' => "/users/$remuser/", },
{ 'name' => 'Calendar',
'uri' => "/users/$remuser/calendar", },
{ 'name' => 'Friends',
'uri' => "/users/$remuser/friends",
'extra' => "/friendsfilter.bml",
},
],
},
{ 'name' => 'User Info',
'uri' => "/userinfo.bml?user=$remuser", },
{ 'name' => 'Memories',
'uri' => "/memories.bml?user=$remuser", },
{ 'name' => 'Logout',
'uri' => '/logout.bml', },
]
};
} elsif ($uri ne "/login.bml") {
unshift @sidebar, { 'name' => "Log In",
'uri' => '/login.bml', }
}
return "";
_code?>
<=LOAD_PAGE_INFO
AL=>{P}<i><a href="%%data1%%">%%data2%%</a></i> <img src="/img/external_link.gif" width='16' height='11' align='absmiddle' />
AWAYLINK=>{P}<i><a href="%%data1%%">%%data2%%</a></i> <img src="/img/external_link.gif" width='16' height='11' align='absmiddle' />
H1=>{D}<h1>%%data%%</h1>
H2=>{D}<h2>%%data%%</h2>
# Banner Header: search results banner, content desriptor, etc...
BH=>{D}<p align='center'><font face="Arial,Helvetica" color="#CC0000" size='-1'><b>%%data%%</b></font>
GRIN=>{S}&lt;grin&gt;
HR=>{S}<hr />
NEWLINE=>{S}<BR>&nbsp;&nbsp;&nbsp;&nbsp;
P=>{D}<P>%%data%%</P>
STANDOUT<=
{D}<blockquote>
<hr />
%%data%%
<hr />
</blockquote>
<=STANDOUT
BADCONTENT<=
<?h1 Error h1?>
<?p
One or more errors occured processing your request. Please go back, correct the
necessary information, and submit your data again.
p?>
<=BADCONTENT
DE<=
%%data%%
<=DE
EMCOLOR=>{S}#c0c0c0
HOTCOLOR=>{S}#ff0000
EMCOLORLITE=>{S}#e2e2e2
screenedbarcolor=>{S}#d0d0d0
CHOICE=>{P}<dt><a href="%%data2%%"><font size="+1"><tt><b>%%data1%%</b></tt></font></a><dd><font size="2">%%data3%%</font>
CHOICES<=
{F}<table width="100%" cellpadding="2" cellspacing="5">
<tr>
<td valign='top' width="50%">
<dl>
%%items%%
</dl>
</td>
<td valign='top' width="50%">
<dl>
%%itemsb%%
</dl>
</td>
</tr>
</table>
<=CHOICES
PAGE<=
{Fp}<html>
<head><title>%%title%%</title>%%head%%</head>
<body %%bodyopts%%>
%%body%%
</body>
</html>
<=PAGE
CHALRESPJS<=
<script type="text/javascript" src="/js/md5.js"></script>
<script language="JavaScript">
<!--
function sendForm ()
{
if (! document.getElementById) return true;
var loginform = document.getElementById('login');
if (! loginform) return true;
var pass_ele = document.getElementById('xc_password');
var chal_ele = document.getElementById('login_chal');
var resp_ele = document.getElementById('login_response');
if (! pass_ele || ! chal_ele || ! resp_ele) return true;
var pass = pass_ele.value;
var chal = chal_ele.value;
var res = MD5(chal + MD5(pass));
resp_ele.value = res;
pass_ele.value = ""; // dont send clear-text password!
loginform.submit();
return false; // cancel browser submit
}
// -->
</script>
<=CHALRESPJS

9
bml/test/include/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

31
bml/test/include/loremipsum.txt Executable file
View File

@ -0,0 +1,31 @@
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque convallis
lacus vel dui. Nam nec augue in massa bibendum consectetuer. In porttitor
nulla. Integer volutpat placerat justo. Etiam interdum pulvinar risus. Sed ut mi
sit amet nulla euismod pulvinar. Phasellus sed turpis. Aliquam in leo in wisi
auctor feugiat. Quisque consequat ante id orci. Sed condimentum pede id
elit. Proin vitae nunc nec arcu ornare tincidunt. Ut mollis interdum
augue. Integer id felis. Nulla facilisis faucibus sapien. Praesent vehicula
luctus wisi. Sed volutpat augue nec lacus vulputate pretium. Suspendisse
potenti. Sed blandit semper tellus.
Ut tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos hymenaeos. Phasellus id metus. Phasellus interdum lacinia
leo. Pellentesque a massa. Aliquam non justo. Proin enim metus, nonummy sit
amet, ornare eu, convallis vel, arcu. Pellentesque tempor rhoncus
mauris. Praesent malesuada pulvinar turpis. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus nunc. Mauris
imperdiet mi nec libero. Maecenas purus velit, fringilla id, mattis sed,
pulvinar id, ligula. Vivamus vel erat vel diam cursus eleifend.
Donec massa est, mollis ac, placerat iaculis, vehicula id, dolor. Quisque
malesuada diam vel pede. Suspendisse egestas. Sed imperdiet tellus non
magna. Etiam luctus, wisi ut fringilla pharetra, tortor lorem suscipit libero,
nec imperdiet ante dolor mollis wisi. Nulla feugiat, erat non viverra mattis,
massa dui molestie orci, vitae bibendum dolor orci id ligula. Quisque
lorem. Donec fringilla vehicula ante. Nam convallis, sapien vitae interdum
mattis, nisl diam egestas enim, ac posuere nisl elit ut purus. Nullam
nonummy. Nulla felis. Fusce cursus lorem quis enim. Suspendisse mattis luctus
magna. Morbi ligula lectus, bibendum ac, tempus ac, scelerisque ac,
pede. Praesent lobortis lectus a libero. Sed luctus, dui a porttitor congue,
neque metus facilisis orci, sit amet congue lorem ligula ut magna. Vivamus non
orci.

6
bml/test/include/plain.bml Executable file
View File

@ -0,0 +1,6 @@
Some Plain Text:
<?_include
bml=>1
code=>0
file=>loremipsum.txt
_include?>

2
bml/test/include/plain.correct Executable file
View File

@ -0,0 +1,2 @@
Some Plain Text:
[Error: <b>Could not open include file.</b>]

1
bml/test/include/scheme.look Executable file
View File

@ -0,0 +1 @@

9
bml/test/info/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

9
bml/test/info/localblocks.bml Executable file
View File

@ -0,0 +1,9 @@
<?_info
localblocks<=
bracketed=>[ %%DATA%% ]
braced=>{ %%DATA%% }
grouped=>( %%DATA%% )
<=localblocks
_info?>
<?bracketed <?braced <?bracketed <?grouped fish grouped?> bracketed?> braced?> bracketed?>

View File

@ -0,0 +1,3 @@
[ { [ ( fish ) ] } ]

9
bml/test/info/package.bml Executable file
View File

@ -0,0 +1,9 @@
<?_c
What the hell does package do?
_c?>
<?_info
package=>Foo
_info?>

2
bml/test/info/package.correct Executable file
View File

@ -0,0 +1,2 @@

0
bml/test/info/scheme.look Executable file
View File

82
bml/test/newtest.pl Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/perl -w
package newtest;
use strict;
use warnings qw{all};
BEGIN {
use Term::Prompter qw{};
use FindBin qw{$Bin};
use Cwd qw{getcwd};
use IO::File qw{};
use Fcntl qw{O_WRONLY O_CREAT O_EXCL};
}
my (
$prompter,
$olddir,
$testname,
$firstfile,
$ofh,
);
$olddir = getcwd();
chdir $Bin;
$prompter = new Term::Prompter;
$prompter->promptColor( 'cyan' );
# Prompt for the information about this test
$prompter->message( "This will create a new test subdirectory and create the \n",
"necessary files and links.\n" );
$testname = $prompter->prompt( "Name of the test subdirectory:" )
or exit 1;
$firstfile = $prompter->promptWithDefault( 'index.bml', "Name of the first BML test file" );
$firstfile .= ".bml" unless $firstfile =~ m{\.bml$};
# Make the test directory, symlink the config, and add the new files to it
$prompter->message( "Creating '$testname' directory..." );
mkdir $testname or die "mkdir: $testname: $!";
symlink "../_config.bml", "$testname/_config.bml"
or die "symlink: _config.bml -> $testname/_config.bml: $!";
$prompter->message( "Creating BML file '$testname/$firstfile'..." );
$ofh = new IO::File "$testname/$firstfile", O_WRONLY|O_CREAT|O_EXCL
or die "open: $testname/$firstfile: $!";
$ofh->print( <<"EOF" );
<!-- You should, of course, replace this with your own stuff... -->
<?example This is an example call to a block. example?>
EOF
$ofh->close;
$prompter->message( "Creating lookfile '$testname/scheme.look'..." );
$ofh = new IO::File "$testname/scheme.look", O_WRONLY|O_CREAT|O_EXCL
or die "open: $testname/scheme.look: $!";
$ofh->print( <<"EOF" );
example=>{D}<example>%%DATA%%</example>
EOF
$ofh->close;
chdir( $olddir );
# Give instructions to the user
( my $correct = $firstfile ) =~ s{\.bml$}{.correct};
$prompter->message( <<"EOF" );
Now you need to do three things to finish setting up the test:
1. Edit $testname/scheme.look and add the blocks you're testing.
2. Edit $testname/$firstfile and add your test content.
3. When you're done, add '$testname' to the list of tests to run in the
\@TestSubdirs var in t/20_render.t.
Then when you run the new test for the first time, it'll generate a comparison
test output file in $testname/$correct which you should verify for
correctness.
EOF

9
bml/test/recursion/_config.bml Executable file
View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

11
bml/test/recursion/infinite.bml Executable file
View File

@ -0,0 +1,11 @@
Simple infinite recursion:
<?rtag Foo rtag?>
Complex infinite recursion:
<?1tag
From there to here,
from here to there,
funny things
are everywhere.
1tag?>

View File

@ -0,0 +1,6 @@
Simple infinite recursion:
<b>[Error: Too deep recursion: RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG -> RTAG]</b>
Complex infinite recursion:
<b>[Error: Too deep recursion: 1TAG -> 2TAG -> REDTAG -> BLUETAG -> 1TAG -> 2TAG -> REDTAG -> BLUETAG -> 1TAG -> 2TAG -> REDTAG]</b>

1
bml/test/recursion/nested.bml Executable file
View File

@ -0,0 +1 @@
<?outer Foo outer?>

View File

@ -0,0 +1 @@
[outer: [inner: Foo]]

7
bml/test/recursion/scheme.look Executable file
View File

@ -0,0 +1,7 @@
rtag=>{D}<?rtag %%DATA%% rtag?>
outer=>{D}[outer: <?inner %%DATA%% inner?>]
inner=>{D}[inner: %%DATA%%]
1tag=>{D}<?2tag %%DATA%% 2tag?>
2tag=>{D}<?redtag %%DATA%% redtag?>
redtag=>{D}<?bluetag %%DATA%% bluetag?>
bluetag=>{D}<?1tag %%DATA%% 1tag?>

View File

@ -0,0 +1,9 @@
LookRoot $testlookroot
DefaultScheme scheme
DefaultLanguage en
AllowOldSyntax 0
AllowCode 1
AllowTemplateCode 1

View File

@ -0,0 +1 @@
<? Some stuff

View File

@ -0,0 +1 @@
<? Some stuff

View File

@ -0,0 +1,2 @@
Tag vs Tga:
<?tag Foo tga?>

View File

@ -0,0 +1,2 @@
Tag vs Tga:
[Error: <b>BML block 'TAG' has no close</b>]

View File

@ -0,0 +1,7 @@
<?tag
Some stuff
?>

View File

@ -0,0 +1 @@
[Error: <b>BML block 'TAG' has no close</b>]

View File

@ -0,0 +1,2 @@
tag=>{D}[Tag: %%DATA%%]

View File

@ -0,0 +1,12 @@
Tag with spurious space:
<?tag Foo t ag?>
Tag with leading padding:
<? tag Foo tag?>
Tag with padding on both sides:
<? tag Foo tag ?>
Tag with trailing padding:
<?tag Foo tag ?>

View File

@ -0,0 +1,11 @@
Tag with spurious space:
[Tag: Foo t ag?>
Tag with leading padding:
<? tag Foo]
Tag with padding on both sides:
<? tag Foo tag ?>
Tag with trailing padding:
[Error: <b>BML block 'TAG' has no close</b>]

View File

@ -0,0 +1,8 @@
<html>
<head><title><?project project?></title>
<body>
<h1><?project project?></h1>
<?greeting greeting?>
</body>
</html>

View File

@ -0,0 +1,10 @@
<html>
<head><title>The Alabaster Project</title>
<body>
<h1>The Alabaster Project</h1>
<p>Welcome to The Alabaster Project, a joint effort between the citizens of earth
and Spumco, Inc.</p>
</body>
</html>

View File

@ -0,0 +1,6 @@
project=>The Alabaster Project
greeting<=
<p>Welcome to <?project project?>, a joint effort between the citizens of earth
and Spumco, Inc.</p>
<=greeting

View File

@ -0,0 +1,27 @@
<html>
<head><title>Hansel and Grendel Go to Finishing School</title>
<body>
<?heading Hansel and Grendel Go to Finishing School heading?>
<p>Our story begins at a point in the Universe not unlike where you are now
sitting, drinking your government-sanctioned stimulant, dreaming of the
day when you, too, will own your own personalized luxury home on 0.3 acres
of land, with a stunning view of, well, the neighbor's personalized luxury
home on 0.3 acres of land. Except this point in the Universe is much more
exciting, fine-smelling, and generally a better place to be than
yours.</p>
<?subheading No, Really, It Is Much Finer subheading?>
<p>So, anyway, at this particular point in the Universe, on a day not
entirely unlike today, two entirely unrelated mythological pantheons
collided, resulting in a fast friendship between a Little Boy Bound to be
Eaten by the Architypal Crone and a Faceless Beast That Waits for the Hero
to Dispatch It. Which, as you might have guessed, was not the intention of
the various storytellers involved, but that's what happens when people
stop reading all the really cool stories and start checking the Financial
Section every 12 minutes. There's only so much space to go around in the
collective consciousness, you know...</p>
</body>
</html>

View File

@ -0,0 +1,27 @@
<html>
<head><title>Hansel and Grendel Go to Finishing School</title>
<body>
<h1>Hansel and Grendel Go to Finishing School</h1>
<p>Our story begins at a point in the Universe not unlike where you are now
sitting, drinking your government-sanctioned stimulant, dreaming of the
day when you, too, will own your own personalized luxury home on 0.3 acres
of land, with a stunning view of, well, the neighbor's personalized luxury
home on 0.3 acres of land. Except this point in the Universe is much more
exciting, fine-smelling, and generally a better place to be than
yours.</p>
<h2>No, Really, It Is Much Finer</h2>
<p>So, anyway, at this particular point in the Universe, on a day not
entirely unlike today, two entirely unrelated mythological pantheons
collided, resulting in a fast friendship between a Little Boy Bound to be
Eaten by the Architypal Crone and a Faceless Beast That Waits for the Hero
to Dispatch It. Which, as you might have guessed, was not the intention of
the various storytellers involved, but that's what happens when people
stop reading all the really cool stories and start checking the Financial
Section every 12 minutes. There's only so much space to go around in the
collective consciousness, you know...</p>
</body>
</html>

View File

@ -0,0 +1,2 @@
heading=><h1>%%DATA%%</h1>
subheading=><h2>%%DATA%%</h2>

View File

@ -0,0 +1,3 @@
<?heading Lava Lamps heading?>
<?subhead Oil-based Lava Lamps (and Chickens) subhead?>

View File

@ -0,0 +1,6 @@
<h1 class="heading"><img src="logo.png"/> Lava Lamps</h1>
<!-- This is a subheading, which naturally requires a chicken above it -->
<img src="chicken.png" /><br />
<h2 class="subheading">Oil-based Lava Lamps (and Chickens)</h2>

View File

@ -0,0 +1,6 @@
heading=><h1 class="heading"><img src="logo.png"/> %%DATA%%</h1>
subhead<=
<!-- This is a subheading, which naturally requires a chicken above it -->
<img src="chicken.png" /><br />
<h2 class="subheading">%%DATA%%</h2>
<=subhead

View File

@ -0,0 +1,9 @@
<?section
id=>listrules
heading=>Rules of the Lists
body<=
There are many considerations when engaging in mounted combat at a tourney, not
the least of which is obeying the convoluted and sometimes confusing localized
<em>Rules of the Lists</em>.
<=body
section?>

Some files were not shown because too many files have changed in this diff Show More