Refactor for new page structure
This commit is contained in:
parent
25a674121f
commit
df22907a41
|
@ -153,7 +153,7 @@ class LexiconArticle:
|
|||
article_by_title[target].citedby.add(article.title)
|
||||
return list(article_by_title.values())
|
||||
|
||||
def build_default_content(self):
|
||||
def build_default_contentblock(self):
|
||||
"""
|
||||
Formats citations into the article content as normal HTML links
|
||||
and returns the result.
|
||||
|
@ -164,23 +164,29 @@ class LexiconArticle:
|
|||
"" if cite_tuple[1] in self.wcites else " class=\"phantom\"")
|
||||
for format_id, cite_tuple in self.citations.items()
|
||||
}
|
||||
return self.content.format(**format_map)
|
||||
article_content = self.content.format(**format_map)
|
||||
return "<div class=\"contentblock\">\n<h1>{}</h1>\n{}</div>\n".format(
|
||||
self.title,
|
||||
article_content)
|
||||
|
||||
def build_default_citeblock(self, prev_article, next_article):
|
||||
"""
|
||||
Builds the citeblock content HTML for use in regular article pages.
|
||||
For each defined target, links the target page as Previous or Next.
|
||||
"""
|
||||
citeblock = "<div class=\"content citeblock\">\n"
|
||||
# Prev/next links
|
||||
if next_article is not None:
|
||||
citeblock += "<p style=\"float:right\"><a href=\"{}.html\"{}>Next →</a></p>\n".format(
|
||||
next_article.title_filesafe, " class=\"phantom\"" if next_article.player is None else "")
|
||||
if prev_article is not None:
|
||||
citeblock += "<p><a href=\"{}.html\"{}>← Previous</a></p>\n".format(
|
||||
prev_article.title_filesafe, " class=\"phantom\"" if prev_article.player is None else "")
|
||||
if next_article is None and prev_article is None:
|
||||
citeblock += "<p> </p>\n"
|
||||
citeblock = "<div class=\"contentblock citeblock\">\n"
|
||||
# Prev/next links:
|
||||
if next_article is not None or prev_article is not None:
|
||||
prev_link = ("<a href=\"{}.html\"{}>← Previous</a>".format(
|
||||
prev_article.title_filesafe,
|
||||
" class=\"phantom\"" if prev_article.player is None else "")
|
||||
if prev_article is not None else "")
|
||||
next_link = ("<a href=\"{}.html\"{}>Next →</a>".format(
|
||||
next_article.title_filesafe,
|
||||
" class=\"phantom\"" if next_article.player is None else "")
|
||||
if next_article is not None else "")
|
||||
citeblock += "<table><tr>\n<td>{}</td>\n<td>{}</td>\n</table></tr>\n".format(
|
||||
prev_link, next_link)
|
||||
# Citations
|
||||
cites_links = [
|
||||
"<a href=\"{1}.html\"{2}>{0}</a>".format(
|
||||
|
@ -189,7 +195,7 @@ class LexiconArticle:
|
|||
for title in sorted(
|
||||
self.wcites | self.pcites,
|
||||
key=lambda t: utils.titlesort(t))]
|
||||
cites_str = " | ".join(cites_links)
|
||||
cites_str = " / ".join(cites_links)
|
||||
if len(cites_str) < 1: cites_str = "—"
|
||||
citeblock += "<p>Citations: {}</p>\n".format(cites_str)
|
||||
# Citedby
|
||||
|
@ -199,7 +205,7 @@ class LexiconArticle:
|
|||
for title in sorted(
|
||||
self.citedby,
|
||||
key=lambda t: utils.titlesort(t))]
|
||||
citedby_str = " | ".join(citedby_links)
|
||||
citedby_str = " / ".join(citedby_links)
|
||||
if len(citedby_str) < 1: citedby_str = "—"
|
||||
citeblock += "<p>Cited by: {}</p>\n</div>\n".format(citedby_str)
|
||||
return citeblock
|
||||
|
|
188
src/build.py
188
src/build.py
|
@ -8,17 +8,37 @@ from collections import defaultdict # For rank inversion in statistics
|
|||
from src import utils
|
||||
from src.article import LexiconArticle
|
||||
|
||||
def build_contents_page(articles, config):
|
||||
class LexiconPage:
|
||||
"""
|
||||
An abstraction layer around formatting a Lexicon page skeleton with kwargs
|
||||
so that kwargs that are constant across pages aren't repeated.
|
||||
"""
|
||||
|
||||
def __init__(self, skeleton=None, page=None):
|
||||
self.kwargs = {}
|
||||
self.skeleton = skeleton
|
||||
if page is not None:
|
||||
self.skeleton = page.skeleton
|
||||
self.kwargs = dict(page.kwargs)
|
||||
|
||||
def add_kwargs(self, **kwargs):
|
||||
self.kwargs.update(kwargs)
|
||||
|
||||
def format(self, **kwargs):
|
||||
total_kwargs = {**self.kwargs, **kwargs}
|
||||
return self.skeleton.format(**total_kwargs)
|
||||
|
||||
def build_contents_page(page, articles, index_list):
|
||||
"""
|
||||
Builds the full HTML of the contents page.
|
||||
"""
|
||||
content = ""
|
||||
content = "<div class=\"contentblock\">"
|
||||
# Head the contents page with counts of written and phantom articles
|
||||
phantom_count = len([article for article in articles if article.player is None])
|
||||
if phantom_count == 0:
|
||||
content = "<p>There are <b>{0}</b> entries in this lexicon.</p>\n".format(len(articles))
|
||||
content += "<p>There are <b>{0}</b> entries in this lexicon.</p>\n".format(len(articles))
|
||||
else:
|
||||
content = "<p>There are <b>{0}</b> entries, <b>{1}</b> written and <b>{2}</b> phantom.</p>\n".format(
|
||||
content += "<p>There are <b>{0}</b> entries, <b>{1}</b> written and <b>{2}</b> phantom.</p>\n".format(
|
||||
len(articles), len(articles) - phantom_count, phantom_count)
|
||||
# Prepare article links
|
||||
link_by_title = {article.title : "<a href=\"../article/{1}.html\"{2}>{0}</a>".format(
|
||||
|
@ -28,7 +48,7 @@ def build_contents_page(articles, config):
|
|||
# Write the articles in alphabetical order
|
||||
content += utils.load_resource("contents.html")
|
||||
content += "<div id=\"index-order\" style=\"display:none\">\n<ul>\n"
|
||||
indices = config["INDEX_LIST"].split("\n")
|
||||
indices = index_list.split("\n")
|
||||
alphabetical_order = sorted(
|
||||
articles,
|
||||
key=lambda a: utils.titlesort(a.title))
|
||||
|
@ -64,70 +84,31 @@ def build_contents_page(articles, config):
|
|||
content += "<li>{}</li>\n".format(link_by_title[article.title])
|
||||
content += "</ul>\n</div>\n"
|
||||
# Fill in the page skeleton
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
return entry_skeleton.format(
|
||||
title="Index of " + config["LEXICON_TITLE"],
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
css=css,
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"],
|
||||
content=content,
|
||||
citeblock="")
|
||||
return page.format(title="Index", content=content)
|
||||
|
||||
def build_rules_page(config):
|
||||
def build_rules_page(page):
|
||||
"""
|
||||
Builds the full HTML of the rules page.
|
||||
"""
|
||||
content = utils.load_resource("rules.html")
|
||||
# Fill in the entry skeleton
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
return entry_skeleton.format(
|
||||
title="Rules",
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
css=css,
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"],
|
||||
content=content,
|
||||
citeblock="")
|
||||
return page.format(title="Rules", content=content)
|
||||
|
||||
def build_formatting_page(config):
|
||||
def build_formatting_page(page):
|
||||
"""
|
||||
Builds the full HTML of the formatting page.
|
||||
"""
|
||||
content = utils.load_resource("formatting.html")
|
||||
# Fill in the entry skeleton
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
return entry_skeleton.format(
|
||||
title="Formatting",
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
css=css,
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"],
|
||||
content=content,
|
||||
citeblock="")
|
||||
return page.format(title="Formatting", content=content)
|
||||
|
||||
def build_session_page(config):
|
||||
def build_session_page(page, session_content):
|
||||
"""
|
||||
Builds the full HTML of the session page.
|
||||
"""
|
||||
# Fill in the entry skeleton
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
return entry_skeleton.format(
|
||||
title=config["LEXICON_TITLE"],
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
css=css,
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"],
|
||||
content=config["SESSION_PAGE"],
|
||||
citeblock="")
|
||||
content = "<div class=\"contentblock\">{}</div>".format(session_content)
|
||||
return page.format(title="Session", content=content)
|
||||
|
||||
def reverse_statistics_dict(stats, reverse=True):
|
||||
"""
|
||||
|
@ -147,7 +128,7 @@ def reverse_statistics_dict(stats, reverse=True):
|
|||
def itemize(stats_list):
|
||||
return map(lambda x: "{0} – {1}".format(x[0], "; ".join(x[1])), stats_list)
|
||||
|
||||
def build_statistics_page(articles, config):
|
||||
def build_statistics_page(page, articles):
|
||||
"""
|
||||
Builds the full HTML of the statistics page.
|
||||
"""
|
||||
|
@ -174,19 +155,19 @@ def build_statistics_page(articles, config):
|
|||
# Format the ranks into strings
|
||||
top_ranked_items = itemize(top_ranked)
|
||||
# Write the statistics to the page
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Top 10 pages by page rank:</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Top 10 pages by page rank:</u><br>\n"
|
||||
content += "<br>\n".join(top_ranked_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Top number of citations made
|
||||
citations_made = { title : len(cites) for title, cites in cite_map.items() }
|
||||
top_citations = reverse_statistics_dict(citations_made)[:3]
|
||||
top_citations_items = itemize(top_citations)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Most citations made from:</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Most citations made from:</u><br>\n"
|
||||
content += "<br>\n".join(top_citations_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Top number of times cited
|
||||
# Build a map of what cites each article
|
||||
|
@ -201,10 +182,10 @@ def build_statistics_page(articles, config):
|
|||
citations_to = { title : len(cites) for title, cites in cited_by_map.items() }
|
||||
top_cited = reverse_statistics_dict(citations_to)[:3]
|
||||
top_cited_items = itemize(top_cited)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Most citations made to:</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Most citations made to:</u><br>\n"
|
||||
content += "<br>\n".join(top_cited_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Top article length, roughly by words
|
||||
article_length = {}
|
||||
|
@ -218,16 +199,16 @@ def build_statistics_page(articles, config):
|
|||
article_length[article.title] = wordcount
|
||||
top_length = reverse_statistics_dict(article_length)[:3]
|
||||
top_length_items = itemize(top_length)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Longest article:</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Longest article:</u><br>\n"
|
||||
content += "<br>\n".join(top_length_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Total word count
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Total word count:</u><br>\n"
|
||||
content += str(sum(article_length.values())) + "</p>"
|
||||
content += "</p>\n</div>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Total word count:</u><br>\n"
|
||||
content += str(sum(article_length.values()))
|
||||
content += "</div>\n"
|
||||
|
||||
# Player pageranks
|
||||
players = sorted(set([article.player for article in articles if article.player is not None]))
|
||||
|
@ -247,10 +228,10 @@ def build_statistics_page(articles, config):
|
|||
in articles_by_player.items()}
|
||||
player_rank = reverse_statistics_dict(pagerank_by_player)
|
||||
player_rank_items = itemize(player_rank)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Player total page rank:</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Player total page rank:</u><br>\n"
|
||||
content += "<br>\n".join(player_rank_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Player citations made
|
||||
player_cite_count = {
|
||||
|
@ -258,10 +239,10 @@ def build_statistics_page(articles, config):
|
|||
for player, articles in articles_by_player.items()}
|
||||
player_cites_made_ranks = reverse_statistics_dict(player_cite_count)
|
||||
player_cites_made_items = itemize(player_cites_made_ranks)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Citations made by player</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Citations made by player</u><br>\n"
|
||||
content += "<br>\n".join(player_cites_made_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Player cited count
|
||||
cited_times = {player : 0 for player in players}
|
||||
|
@ -270,23 +251,13 @@ def build_statistics_page(articles, config):
|
|||
cited_times[article.player] += len(article.citedby)
|
||||
cited_times_ranked = reverse_statistics_dict(cited_times)
|
||||
cited_times_items = itemize(cited_times_ranked)
|
||||
content += "<div class=\"moveable\">\n"
|
||||
content += "<p><u>Citations made to player</u><br>\n"
|
||||
content += "<div class=\"contentblock\">\n"
|
||||
content += "<u>Citations made to player</u><br>\n"
|
||||
content += "<br>\n".join(cited_times_items)
|
||||
content += "</p>\n</div>\n"
|
||||
content += "</div>\n"
|
||||
|
||||
# Fill in the entry skeleton
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
return entry_skeleton.format(
|
||||
title="Statistics",
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
css=css,
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"],
|
||||
content=content,
|
||||
citeblock="")
|
||||
return page.format(title="Statistics", content=content)
|
||||
|
||||
def build_graphviz_file(cite_map):
|
||||
"""
|
||||
|
@ -367,26 +338,29 @@ def build_all(path_prefix, lexicon_name):
|
|||
lex_path = os.path.join(path_prefix, lexicon_name)
|
||||
# Load the Lexicon's peripherals
|
||||
config = utils.load_config(lexicon_name)
|
||||
entry_skeleton = utils.load_resource("entry-page.html")
|
||||
css = utils.load_resource("lexicon.css")
|
||||
page_skeleton = utils.load_resource("page-skeleton.html")
|
||||
page = LexiconPage(skeleton=page_skeleton)
|
||||
page.add_kwargs(
|
||||
lexicon=config["LEXICON_TITLE"],
|
||||
logo=config["LOGO_FILENAME"],
|
||||
prompt=config["PROMPT"],
|
||||
sort=config["DEFAULT_SORT"])
|
||||
# Parse the written articles
|
||||
articles = LexiconArticle.parse_from_directory(os.path.join(lex_path, "src"))
|
||||
# At this point, the articles haven't been cross-populated,
|
||||
# so we can derive the written titles from this list
|
||||
#written_titles = [article.title for article in articles]
|
||||
# Once they've been populated, the articles list has the titles of all articles
|
||||
# Sort this by turn before title so prev/next links run in turn order
|
||||
articles = sorted(
|
||||
LexiconArticle.populate(articles),
|
||||
key=lambda a: (a.turn, utils.titlesort(a.title)))
|
||||
#phantom_titles = [article.title for article in articles if article.title not in written_titles]
|
||||
|
||||
def pathto(*els):
|
||||
return os.path.join(lex_path, *els)
|
||||
|
||||
# Write the redirect page
|
||||
print("Writing redirect page...")
|
||||
with open(pathto("index.html"), "w", encoding="utf8") as f:
|
||||
f.write(utils.load_resource("redirect.html").format(lexicon=config["LEXICON_TITLE"], sort=config["DEFAULT_SORT"]))
|
||||
f.write(utils.load_resource("redirect.html").format(
|
||||
lexicon=config["LEXICON_TITLE"], sort=config["DEFAULT_SORT"]))
|
||||
|
||||
# Write the article pages
|
||||
print("Deleting old article pages...")
|
||||
|
@ -398,38 +372,32 @@ def build_all(path_prefix, lexicon_name):
|
|||
for idx in range(l):
|
||||
article = articles[idx]
|
||||
with open(pathto("article", article.title_filesafe + ".html"), "w", encoding="utf-8") as f:
|
||||
content = article.build_default_content()
|
||||
contentblock = article.build_default_contentblock()
|
||||
citeblock = article.build_default_citeblock(
|
||||
None if idx == 0 else articles[idx - 1],
|
||||
None if idx == l-1 else articles[idx + 1])
|
||||
article_html = entry_skeleton.format(
|
||||
article_html = page.format(
|
||||
title = article.title,
|
||||
lexicon = config["LEXICON_TITLE"],
|
||||
css = css,
|
||||
logo = config["LOGO_FILENAME"],
|
||||
prompt = config["PROMPT"],
|
||||
sort = config["DEFAULT_SORT"],
|
||||
content = content,
|
||||
citeblock = citeblock)
|
||||
content = contentblock + citeblock)
|
||||
f.write(article_html)
|
||||
print(" Wrote " + article.title)
|
||||
|
||||
# Write default pages
|
||||
print("Writing default pages...")
|
||||
with open(pathto("contents", "index.html"), "w", encoding="utf-8") as f:
|
||||
f.write(build_contents_page(articles, config))
|
||||
f.write(build_contents_page(page, articles, config["INDEX_LIST"]))
|
||||
print(" Wrote Contents")
|
||||
with open(pathto("rules", "index.html"), "w", encoding="utf-8") as f:
|
||||
f.write(build_rules_page(config))
|
||||
f.write(build_rules_page(page))
|
||||
print(" Wrote Rules")
|
||||
with open(pathto("formatting", "index.html"), "w", encoding="utf-8") as f:
|
||||
f.write(build_formatting_page(config))
|
||||
f.write(build_formatting_page(page))
|
||||
print(" Wrote Formatting")
|
||||
with open(pathto("session", "index.html"), "w", encoding="utf-8") as f:
|
||||
f.write(build_session_page(config))
|
||||
f.write(build_session_page(page, config["SESSION_PAGE"]))
|
||||
print(" Wrote Session")
|
||||
with open(pathto("statistics", "index.html"), "w", encoding="utf-8") as f:
|
||||
f.write(build_statistics_page(articles, config))
|
||||
f.write(build_statistics_page(page, articles))
|
||||
print(" Wrote Statistics")
|
||||
|
||||
# Write auxiliary pages
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<div class="contentblock">
|
||||
<p>Lexipython provides support for a limited amount of Markdown-esque formatting.</p>
|
||||
<pre style="background:#eeeeee">
|
||||
# Player: PN
|
||||
|
@ -7,17 +8,50 @@
|
|||
This is an example page.
|
||||
Some words are //italicized//,
|
||||
and some words are **bolded**.
|
||||
All of these sentences are part of the same paragraph.
|
||||
All of these sentences are part of the same
|
||||
paragraph.
|
||||
|
||||
This is a new paragraph.\\
|
||||
Unlike the last paragraph, this line will be after a line break within the paragraph.
|
||||
Unlike the last paragraph, this line will be after a
|
||||
line break within the paragraph.
|
||||
|
||||
This is an [[example citation|Phantom page]]. You can also cite a [[phantom page]] with just the title.
|
||||
This is an [[example citation|Phantom page]]. You can
|
||||
also cite a [[phantom page]] with just the title.
|
||||
|
||||
~Dr. X. Amplepage
|
||||
</pre>
|
||||
<p>Each turn, fill out the header with your player information, the current turn, and the title of your entry. The <i>Player</i> field can be anything as long as it's the same for all articles you write (even when they're by different characters). Using your initials is recommended.</p>
|
||||
<p>Two line breaks begins a new paragraph. A single line break does nothing, unless the line is ended by a double backslash (\\).</p>
|
||||
<p>Text bounded by ** will be bolded: **bold** produces <b>bold</b>. Text bounded by // will be italicized: //italics// produces <i>italics</i>.</p>
|
||||
<p>To cite another Lexicon entry, use double brackets. Text in double brackets will cite and link to the entry of the same name: [[Example page]] produces <a href="Example_page.html" class="phantom">Example page</a>. Text in double brackets split with a | will alias the link as the left text and link to the entry with the name of the right text: [[this text|Example page]] produces <a href="Example_page.html" class="phantom">this text</a>. <b>You must be precise in the entry title you cite to.</b> Citations to "Example" vs. "The Example" will point to different entries and create different phantoms, and your GM will probably have to clean up after you.</p>
|
||||
<p>Beginning a paragraph with ~ will right-align it and place a horizontal line above it. Use this for signing your entry with your scholar's name.</p>
|
||||
<p>Each turn, fill out the header with your player information, the current
|
||||
turn, and the title of your entry. The <i>Player</i> field can be anything
|
||||
as long as it's the same for all articles you write (even when they're by
|
||||
different characters). Using your initials is recommended.</p>
|
||||
<p>Two line breaks begins a new paragraph. A single line break does nothing,
|
||||
unless the line is ended by a double backslash (\\).</p>
|
||||
<p>Text bounded by ** will be bolded: **bold** produces <b>bold</b>. Text
|
||||
bounded by // will be italicized: //italics// produces <i>italics</i>.</p>
|
||||
<p>To cite another Lexicon entry, use double brackets. Text in double brackets
|
||||
will cite and link to the entry of the same name: [[Example page]] produces
|
||||
<a href="Example_page.html" class="phantom">Example page</a>. Text in
|
||||
double brackets split with a | will alias the link as the left text and
|
||||
link to the entry with the name of the right text: [[this text|Example page]]
|
||||
produces <a href="Example_page.html" class="phantom">this text</a>. <b>You
|
||||
must be precise in the entry title you cite to.</b> Citations to
|
||||
"Example" vs. "The Example" will point to different entries and create
|
||||
different phantoms, and your GM will probably have to clean up after
|
||||
you.</p>
|
||||
<p>Beginning a paragraph with ~ will right-align it and place a horizontal line
|
||||
above it. Use this for signing your entry with your scholar's name.</p>
|
||||
</div>
|
||||
<div class="contentblock">
|
||||
<h1>Example page</h1>
|
||||
<p>This is an example page.
|
||||
Some words are <i>italicized</i>,
|
||||
and some words are <b>bolded</b>.
|
||||
All of these sentences are part of the same
|
||||
paragraph.</p>
|
||||
<p>This is a new paragraph.<br>
|
||||
Unlike the last paragraph, this line will be after a
|
||||
line break within the paragraph.</p>
|
||||
<p>This is an <a href="Phantom_page.html" class="phantom">example citation</a>. You can
|
||||
also cite a <a href="Phantom_page.html" class="phantom">phantom page</a> with just the title.</p>
|
||||
<hr><span class="signature"><p>Dr. X. Amplepage</p></span>
|
||||
</div>
|
|
@ -1,18 +1,67 @@
|
|||
<div class="contentblock">
|
||||
<ol>
|
||||
<li>At the beginning of the game, you will be provided with a <i>topic statement</i> that sets the tone for the game. Use it for inspiration and a stepping-stone into shaping the world of the Lexicon.</li>
|
||||
<li>Each round, you will be assigned an <i>index</i>, a grouping of letters. Your entry must alphabetize under that index.<ol>
|
||||
<li>Each index has a number of open slots equal to the number of players, which are taken up by article titles when an article is written in that index or a citation is made to an unwritten article, or <i>phantom</i>. If there are no open slots in your index, you must write the article for a phantom in that index.</li>
|
||||
<li>"The" and "A" aren't counted in indexing.</li></ol></li>
|
||||
<li>Once you've picked an article title, write your article on that subject.<ol>
|
||||
<li>There are no hard and fast rules about style. Try to sound like an encyclopedia entry or the overview section at the top of a wiki article.</li>
|
||||
<li>You must respect and not contradict any factual content of any posted articles. You may introduce new facts that place things in a new light, provide alternative interpretations, or flesh out unexplained details in unexpected ways; but you must not <i>contradict</i> what has been previously established as fact.</li>
|
||||
<li>Aim for around 200-300 words. Going over is okay, but be reasonable.</li></ol></li>
|
||||
<li>Your article must cite other articles in the Lexicon. Sometimes these citations will be to phantoms, articles that have not been written yet.<ol>
|
||||
<li>On the first turn, your article must cite <i>exactly two</i> phantom articles.</li>
|
||||
<li>On subsequent turns, your article must cite <i>exactly two</i> phantom articles, either already-cited phantoms or new ones. Your article must also cite <i>at least one</i> written article.</li>
|
||||
<li>On the penultimate turn, you must cite <i>exactly one</i> phantom article and <i>at least two</i> written articles.</li>
|
||||
<li>On the final turn, you must cite <i>at least three</i> written articles.</li>
|
||||
<li>You may not cite an entry you wrote. You may cite phantoms you have cited before.</li>
|
||||
<li>Once you cite a phantom, you cannot choose to write it if you write an article for that index later.</li></ol></li>
|
||||
|
||||
<p><b>Ersatz Scrivener.</b> In the course of the game, it may come to pass that a scholar is assigned an index in which no slots are available to them, because they have cited all the available phantoms in their previous articles. When this happens, the player instead writes their article as Ersatz Scrivener, radical skeptic. Ersatz does not believe in the existence of whatever he is writing about, no matter how obvious it seems to others or how central it is in the developing history of the world. All references, testimony, etc. with regard to its existence are tragic delusion at best or malicious lies at worst. Unlike the other scholars, Ersatz does not treat the research of his peers as fact, because he does not believe he has peers. Players writing articles as Ersatz are encouraged to name and shame the work of the misguided amateurs collaborating with him.</p>
|
||||
<li>Each Lexicon has a <i>topic statement</i> that sets the tone for the game.
|
||||
It provides a starting point for shaping the developing world of the
|
||||
Lexicon. As it is a starting point, don't feel contrained to write only
|
||||
about the topics mentioned directly in it.</li>
|
||||
<li>Articles are sorted under an <i>index</i>, a grouping of letters. An article is
|
||||
in an index if its first letter is in that group of letters. "The", "A",
|
||||
and "An" aren't counted in indexing. <i>Example: One of the indices is JKL.
|
||||
An article titled 'The Jabberwock' would index under JKL, not T's index.</i></li><ol>
|
||||
<li>Until the game is over, some of the articles will have been cited, but not
|
||||
yet written. These are called <i>phantom</i> articles. A phantom article has a
|
||||
title, which is defined by the first citation to it, but no content.</li>
|
||||
<li>Generally, an index has a number of "slots" equal to the number of players.
|
||||
When an article is first written or cited, it takes up one slot in its
|
||||
corresponding index.</li></ol>
|
||||
<li>Each turn, you will be assigned to write in an index.</li><ol>
|
||||
<li>Your articles should be written from the perspective of your character.
|
||||
Your character should be a scholar collaborating with the other
|
||||
scholars on the production of the Lexicon. You should play the same
|
||||
character for the duration of the game.</li>
|
||||
<li>If the index has open slots, you may come up with a new article title
|
||||
and write an article under that title. If all unwritten slots in your
|
||||
index are filled by phantom articles, you must choose one of them and
|
||||
write it.</li>
|
||||
<li>There are no hard and fast rules about style, but it is recommended
|
||||
that players imitate an encyclopedic style to stay true to the game's
|
||||
conceit.</li>
|
||||
<li>There are no hard and fast rules about length, but it is recommended
|
||||
that the Editor enforce a maximum word limit. In general, aiming for
|
||||
200-300 words is ideal.</li>
|
||||
<li>You must respect and not contradict the factual content of all written
|
||||
articles. You may introduce new facts that put things in a new light,
|
||||
provide alternative interpretations, or flesh out unexplained details
|
||||
in unexpected ways; but you must not <i>contradict</i> what has been
|
||||
previously established as fact. Use the "yes, and" rule from improv
|
||||
acting: accept what your fellow scholars have written and add to it in
|
||||
new ways, rather than trying to undo their work. This rule includes
|
||||
facts that have been established in written articles about the topics
|
||||
of phantom articles.</li></ol>
|
||||
<li>Each article will cite other articles in the Lexicon.</li><ol>
|
||||
<li>You may not cite an entry that you have written. When you write an
|
||||
article, you may not cite it in later articles.</li>
|
||||
<li>As a corollary, you may not write phantom articles that you have cited.
|
||||
If you cite an article and then write it later, your former article
|
||||
now cites you, which is forbidden per the above.</li>
|
||||
<li>On the first turn, there are no written articles. Your first article
|
||||
must cite <i>exactly two</i> phantom articles.</li>
|
||||
<li>On subsequent turns, your article must cite <i>exactly two</i> phantoms,
|
||||
but you can cite phantoms that already exist. Your article must also
|
||||
cite <i>at least one</i> written article. You can cite more than one.</li>
|
||||
<li>On the penultimate turn, you must cite <i>exactly one</i> phantom
|
||||
article and <i>at least two</i> written articles.</li>
|
||||
<li>On the final turn, you must cite <i>at least three</i> written articles.</li></ol>
|
||||
<li>As the game goes on, it may come to pass that a player must write an
|
||||
article in an index, but that index is full, and that player has already
|
||||
cited all the phantoms in it. When this happens, the player instead writes
|
||||
their article as **Ersatz Scrivener**, radical skeptic. Ersatz does not
|
||||
believe in the existence of whatever he is writing about, no matter how
|
||||
obvious it seems to others or how central it is in the developing history
|
||||
of the world. For Ersatz, all references, testimony, etc. with regard to
|
||||
its existence are tragic delusion at best or malicious lies at worst.
|
||||
Unlike the other scholars, Ersatz does not treat the research of his peers
|
||||
as fact, because he does not believe he has peers. Players writing articles
|
||||
as Ersatz are encouraged to lambast the amateur work of his misguided
|
||||
"collaborators".</li>
|
||||
</div>
|
Loading…
Reference in New Issue