638 lines
31 KiB
Plaintext
638 lines
31 KiB
Plaintext
|
python early:
|
||
|
|
||
|
# This maps from example name to the text of a fragment.
|
||
|
examples = { }
|
||
|
|
||
|
# The size of the example - large or small.
|
||
|
example_size = "small"
|
||
|
|
||
|
# The location of the example - top or bottom.
|
||
|
example_location = "top"
|
||
|
|
||
|
# The screen in the last example.
|
||
|
example_screen = None
|
||
|
|
||
|
# A transition used with examples
|
||
|
example_transition = None
|
||
|
|
||
|
def reset_example():
|
||
|
"""
|
||
|
Called to reset the example code to the defaults.
|
||
|
"""
|
||
|
|
||
|
global example_size
|
||
|
global example_location
|
||
|
global example_screen
|
||
|
|
||
|
example_size = "small"
|
||
|
example_location = "top"
|
||
|
example_screen = None
|
||
|
|
||
|
def show_example_screen(name):
|
||
|
global example_screen
|
||
|
example_screen = name
|
||
|
renpy.show_screen(name)
|
||
|
|
||
|
def hide_example_screen():
|
||
|
global example_screen
|
||
|
|
||
|
if example_screen is not None:
|
||
|
renpy.hide_screen(example_screen)
|
||
|
|
||
|
example_screen = None
|
||
|
|
||
|
|
||
|
# Keywords that, at the start of an example block, cause it to be
|
||
|
# outdented
|
||
|
OUTDENT_KEYWORDS = { "define", "default", "image", "screen", "init", "transform", "label", "style" }
|
||
|
|
||
|
|
||
|
# This defines the example statement.
|
||
|
#
|
||
|
# The example statement takes:
|
||
|
# * An optional name for the example.
|
||
|
# * An optional hide flag.
|
||
|
# * Optional size flags, large or small.
|
||
|
# * Optional position flags, top or bottom.
|
||
|
#
|
||
|
# The statement defines an example with the name, or an anyonymous name if no
|
||
|
# name is given. When run, the example is displayed if the hide flag is not
|
||
|
# given.
|
||
|
|
||
|
|
||
|
def read_example(name, fn, line, outdent):
|
||
|
"""
|
||
|
This reads an example from an example statement, and places it into
|
||
|
the examples dictionary.
|
||
|
"""
|
||
|
|
||
|
fn = fn.replace("game/", "")
|
||
|
|
||
|
with renpy.notl_file(fn) as f:
|
||
|
data = f.read().decode("utf-8")
|
||
|
|
||
|
rawlines = [ i.rstrip() for i in data.split("\n") ]
|
||
|
|
||
|
lines = [ ]
|
||
|
|
||
|
base_indent = 0
|
||
|
|
||
|
while True:
|
||
|
|
||
|
if line >= len(rawlines):
|
||
|
raise Exception("Example open at end of {}.".format(fn))
|
||
|
|
||
|
l = rawlines[line]
|
||
|
line += 1
|
||
|
|
||
|
if not l:
|
||
|
lines.append(l)
|
||
|
continue
|
||
|
|
||
|
indent = len(l) - len(l.lstrip())
|
||
|
|
||
|
if base_indent == 0:
|
||
|
base_indent = indent
|
||
|
lines.append(l[4:])
|
||
|
elif indent >= base_indent:
|
||
|
lines.append(l[4:])
|
||
|
else:
|
||
|
break
|
||
|
|
||
|
# Determine if the line should be indented.
|
||
|
if outdent == "auto":
|
||
|
|
||
|
for i in lines:
|
||
|
l = i.strip().split()
|
||
|
if not l:
|
||
|
continue
|
||
|
|
||
|
if l[0] in OUTDENT_KEYWORDS:
|
||
|
outdent = True
|
||
|
else:
|
||
|
outdent = False
|
||
|
|
||
|
break
|
||
|
|
||
|
# Strip indentation.
|
||
|
if outdent:
|
||
|
lines = [ i[base_indent - 4:] for i in lines ]
|
||
|
|
||
|
if name in examples:
|
||
|
examples[name].append('')
|
||
|
examples[name].extend(lines)
|
||
|
else:
|
||
|
examples[name] = lines
|
||
|
|
||
|
def parse_example(l):
|
||
|
"""
|
||
|
This parses the example statement.
|
||
|
"""
|
||
|
|
||
|
# The name of the example. A string, or None if we don't know yet.
|
||
|
name = None
|
||
|
|
||
|
# Hide, bottom, and small flags.
|
||
|
hide = False
|
||
|
bottom = False
|
||
|
small = False
|
||
|
top = False
|
||
|
large = False
|
||
|
outdent = "auto"
|
||
|
show_screen = True
|
||
|
hide_screen = True
|
||
|
showtrans = False
|
||
|
|
||
|
while True:
|
||
|
|
||
|
if l.match(':'):
|
||
|
break
|
||
|
|
||
|
elif l.keyword('hide'):
|
||
|
hide = True
|
||
|
|
||
|
elif l.keyword('bottom'):
|
||
|
bottom = True
|
||
|
|
||
|
elif l.keyword('small'):
|
||
|
small = True
|
||
|
|
||
|
elif l.keyword('top'):
|
||
|
top = True
|
||
|
|
||
|
elif l.keyword('large'):
|
||
|
large = True
|
||
|
|
||
|
elif l.keyword('outdent'):
|
||
|
outdent = True
|
||
|
|
||
|
elif l.keyword('nooutindent'):
|
||
|
outdent = False
|
||
|
|
||
|
elif l.keyword("noshow"):
|
||
|
show_screen = False
|
||
|
|
||
|
elif l.keyword("nohide"):
|
||
|
hide_screen = False
|
||
|
|
||
|
elif l.keyword("showtrans"):
|
||
|
showtrans = True
|
||
|
|
||
|
else:
|
||
|
|
||
|
if name:
|
||
|
l.error('an example may have at most one name')
|
||
|
|
||
|
name = l.require(l.name)
|
||
|
|
||
|
l.expect_eol()
|
||
|
|
||
|
if name is None:
|
||
|
name = "example_{}_{}".format(l.filename, l.number)
|
||
|
|
||
|
ll = l.subblock_lexer()
|
||
|
ll.advance()
|
||
|
|
||
|
if ll.keyword('screen'):
|
||
|
screen_name = ll.name()
|
||
|
else:
|
||
|
screen_name = None
|
||
|
|
||
|
return {
|
||
|
"name" : name,
|
||
|
"names" : [ name ],
|
||
|
"hide" : hide,
|
||
|
"bottom" : bottom,
|
||
|
"small" : small,
|
||
|
"filename" : l.filename,
|
||
|
"number" : l.number,
|
||
|
"top" : top,
|
||
|
"large" : large,
|
||
|
"outdent" : outdent,
|
||
|
"screen_name" : screen_name,
|
||
|
"show_screen" : show_screen,
|
||
|
"hide_screen" : hide_screen,
|
||
|
"showtrans" : showtrans,
|
||
|
}
|
||
|
|
||
|
def next_example(data, first):
|
||
|
return first
|
||
|
|
||
|
def execute_example(data):
|
||
|
names = data.get("names", [ ])
|
||
|
hide = data.get("hide", False)
|
||
|
bottom = data.get("bottom", False)
|
||
|
small = data.get("small", False)
|
||
|
top = data.get("top", False)
|
||
|
large = data.get("large", False)
|
||
|
showtrans = data.get("showtrans", False)
|
||
|
|
||
|
global example_location
|
||
|
global example_size
|
||
|
|
||
|
|
||
|
if bottom:
|
||
|
example_location = "bottom"
|
||
|
elif top:
|
||
|
example_location = "top"
|
||
|
|
||
|
if small:
|
||
|
example_size = "small"
|
||
|
elif large:
|
||
|
example_size = "large"
|
||
|
|
||
|
if not hide:
|
||
|
renpy.show_screen("example", names, example_size == "small", example_location == "bottom", showtrans=showtrans)
|
||
|
|
||
|
screen_name = data.get("screen_name", None)
|
||
|
|
||
|
if screen_name is not None:
|
||
|
if data.get("hide_screen", True):
|
||
|
hide_example_screen()
|
||
|
|
||
|
if data.get("show_screen", True):
|
||
|
show_example_screen(screen_name)
|
||
|
renpy.with_statement(example_transition)
|
||
|
|
||
|
def execute_init_example(data):
|
||
|
read_example(data["name"], data["filename"], data["number"], data.get("outdent", "auto"))
|
||
|
|
||
|
renpy.register_statement("example", parse=parse_example, execute=execute_example, execute_init=execute_init_example, next=next_example, block="script")
|
||
|
|
||
|
|
||
|
# The show example statement.
|
||
|
|
||
|
def parse_show_example(l):
|
||
|
|
||
|
names = [ ]
|
||
|
|
||
|
bottom = False
|
||
|
small = False
|
||
|
top = False
|
||
|
large = False
|
||
|
showtrans = False
|
||
|
|
||
|
while not l.eol():
|
||
|
|
||
|
if l.keyword('bottom'):
|
||
|
bottom = True
|
||
|
|
||
|
elif l.keyword('small'):
|
||
|
small = True
|
||
|
|
||
|
elif l.keyword('top'):
|
||
|
top = True
|
||
|
|
||
|
elif l.keyword('large'):
|
||
|
large = True
|
||
|
|
||
|
elif l.keyword('showtrans'):
|
||
|
showtrans = True
|
||
|
|
||
|
else:
|
||
|
|
||
|
names.append(l.require(l.name))
|
||
|
|
||
|
return {
|
||
|
"names" : names,
|
||
|
"hide" : False,
|
||
|
"bottom" : bottom,
|
||
|
"small" : small,
|
||
|
"top" : top,
|
||
|
"large" : large,
|
||
|
"showtrans" : showtrans,
|
||
|
}
|
||
|
|
||
|
renpy.register_statement("show example", parse=parse_show_example, execute=execute_example)
|
||
|
|
||
|
|
||
|
# The hide example statement.
|
||
|
|
||
|
def parse_hide_example(l):
|
||
|
|
||
|
hide_screen = True
|
||
|
|
||
|
while not l.eol():
|
||
|
if l.keyword('nohide'):
|
||
|
hide_screen = False
|
||
|
else:
|
||
|
break
|
||
|
|
||
|
l.expect_eol()
|
||
|
|
||
|
return {
|
||
|
"hide_screen" : hide_screen,
|
||
|
}
|
||
|
|
||
|
def execute_hide_example(data):
|
||
|
renpy.hide_screen("example")
|
||
|
|
||
|
if example_screen and data.get("hide_screen", True) and renpy.get_screen(example_screen):
|
||
|
hide_example_screen()
|
||
|
renpy.with_statement(example_transition)
|
||
|
|
||
|
renpy.register_statement("hide example", parse=parse_hide_example, execute=execute_hide_example)
|
||
|
|
||
|
|
||
|
# A preference that controls if translations are shown.
|
||
|
default persistent.show_translation_marker = False
|
||
|
|
||
|
init python:
|
||
|
|
||
|
dialogue_map = { }
|
||
|
|
||
|
for i in renpy.known_languages():
|
||
|
dialogue_map[i] = renpy.translation.dialogue.create_dialogue_map(i)
|
||
|
|
||
|
|
||
|
import re
|
||
|
import keywords
|
||
|
|
||
|
KEYWORDS = set(keywords.keywords)
|
||
|
PROPERTIES = set(keywords.properties)
|
||
|
|
||
|
regex = r"(?P<word>\b(\$|[_a-zA-Z0-9]+)\b)" + \
|
||
|
r"|(?P<string>\"([^\"]|\\.)*(?<!\\)\")" + \
|
||
|
r"|(?P<comment>#.*)"
|
||
|
|
||
|
regex = re.compile(regex)
|
||
|
|
||
|
def quote(s):
|
||
|
s = s.replace("{", "{{")
|
||
|
s = s.replace("[", "[[")
|
||
|
|
||
|
return s
|
||
|
|
||
|
def translate(m):
|
||
|
if m.group("string"):
|
||
|
s = eval(m.group(0))
|
||
|
|
||
|
if __(s) != s:
|
||
|
s = __(s)
|
||
|
elif _preferences.language:
|
||
|
|
||
|
dm = dialogue_map[_preferences.language]
|
||
|
|
||
|
if s in dm:
|
||
|
s = dm[s]
|
||
|
|
||
|
quote = m.group(0)[0]
|
||
|
s = s.replace("\\", "\\\\")
|
||
|
s = s.replace(quote, "\\" + quote)
|
||
|
s = s.replace("\n", "\\n")
|
||
|
s = quote + s + quote
|
||
|
|
||
|
return s
|
||
|
|
||
|
return m.group(0)
|
||
|
|
||
|
def colorize(m):
|
||
|
if m.group("string"):
|
||
|
return "{color=#060}" + m.group(0) + "{/color}"
|
||
|
|
||
|
word = m.group("word")
|
||
|
if word:
|
||
|
if word in KEYWORDS:
|
||
|
return "{color=#840}" + m.group(0) + "{/color}"
|
||
|
elif word in PROPERTIES:
|
||
|
return "{color=#048}" + m.group(0) + "{/color}"
|
||
|
else:
|
||
|
return m.group(0)
|
||
|
|
||
|
if m.group("comment"):
|
||
|
return "{color=#600}" + m.group(0) + "{/color}"
|
||
|
|
||
|
return m.group(0)
|
||
|
|
||
|
def clean_example(lines):
|
||
|
rv = list(lines)
|
||
|
|
||
|
while rv and not rv[0]:
|
||
|
rv.pop(0)
|
||
|
|
||
|
while rv and not rv[-1]:
|
||
|
rv.pop(-1)
|
||
|
|
||
|
return rv
|
||
|
|
||
|
def example_code(blocks, raw=False, showtrans=False):
|
||
|
|
||
|
if not isinstance(blocks, list):
|
||
|
blocks = [ blocks ]
|
||
|
|
||
|
|
||
|
# Collect the examples we use.
|
||
|
lines1 = [ ]
|
||
|
|
||
|
for i in blocks:
|
||
|
if i not in examples:
|
||
|
lines1.append('Example {} not found.'.format(i))
|
||
|
else:
|
||
|
lines1.extend(clean_example(examples[i]))
|
||
|
|
||
|
lines1.append('')
|
||
|
|
||
|
|
||
|
# Strip off doubled blank lines.
|
||
|
last_blank = False
|
||
|
lines = [ ]
|
||
|
|
||
|
for i in lines1:
|
||
|
|
||
|
if not i and last_blank:
|
||
|
continue
|
||
|
|
||
|
last_blank = not i
|
||
|
|
||
|
i = regex.sub(translate, i)
|
||
|
|
||
|
if not (persistent.show_translation_marker or showtrans):
|
||
|
i = re.sub(r'__?\((".*?")\)', r'\1', i)
|
||
|
i = re.sub(r"__?\(('.*?')\)", r'\1', i)
|
||
|
i = i.replace("!t]", "]")
|
||
|
|
||
|
if not raw:
|
||
|
i = quote(i)
|
||
|
i = regex.sub(colorize, i)
|
||
|
|
||
|
lines.append(i)
|
||
|
|
||
|
while not lines[-1]:
|
||
|
lines.pop()
|
||
|
|
||
|
# Join them into a single string.
|
||
|
return "\n".join(lines) + "\n "
|
||
|
|
||
|
class CopyCode(Action):
|
||
|
def __init__(self, s):
|
||
|
self.s = s
|
||
|
|
||
|
def __call__(self):
|
||
|
import pygame.scrap
|
||
|
pygame.scrap.put(pygame.SCRAP_TEXT, self.s.encode("utf-8"))
|
||
|
renpy.notify(_("Copied the example to the clipboard."))
|
||
|
|
||
|
example_transition = dissolve
|
||
|
|
||
|
import os
|
||
|
SHOW_EXAMPLES = ("RENPY_LESS_EXAMPLES" not in os.environ)
|
||
|
|
||
|
|
||
|
transform example_transform(height, ypos):
|
||
|
ypos ypos
|
||
|
yanchor 1.0
|
||
|
xalign 0.5
|
||
|
|
||
|
on replace:
|
||
|
crop (0, 0, 1280, height)
|
||
|
|
||
|
on show:
|
||
|
crop (0, 0, 1280, 0)
|
||
|
linear .5 crop (0, 0, 1280, height)
|
||
|
|
||
|
on hide:
|
||
|
linear .5 crop (0, 0, 1280, 0)
|
||
|
|
||
|
|
||
|
screen example(blocks, small=False, bottom=False, showtrans=False):
|
||
|
|
||
|
zorder 10
|
||
|
|
||
|
default raw_code = example_code(blocks, raw=True, showtrans=showtrans)
|
||
|
default code = example_code(blocks, showtrans=showtrans)
|
||
|
|
||
|
if small:
|
||
|
$ height = 80
|
||
|
else:
|
||
|
$ height = 160
|
||
|
|
||
|
if bottom:
|
||
|
$ ypos = 720
|
||
|
else:
|
||
|
$ ypos = 540
|
||
|
|
||
|
|
||
|
if SHOW_EXAMPLES:
|
||
|
|
||
|
frame:
|
||
|
style "empty"
|
||
|
background "#fffc"
|
||
|
foreground Solid("#aaac", xsize=1, xpos=178)
|
||
|
|
||
|
xfill True
|
||
|
yfill True
|
||
|
ymaximum height
|
||
|
|
||
|
at example_transform(height, ypos)
|
||
|
|
||
|
viewport:
|
||
|
side_xmaximum 1098
|
||
|
side_xpos 180
|
||
|
child_size (2000, 2000)
|
||
|
ymaximum height
|
||
|
draggable True
|
||
|
mousewheel True
|
||
|
scrollbars "vertical"
|
||
|
|
||
|
vscrollbar_xsize 5
|
||
|
vscrollbar_base_bar "#aaac"
|
||
|
vscrollbar_unscrollable "hide"
|
||
|
|
||
|
text code:
|
||
|
alt ""
|
||
|
size 16
|
||
|
color "#000"
|
||
|
|
||
|
textbutton _("copy"):
|
||
|
style "empty"
|
||
|
text_style "quick_button_text"
|
||
|
text_text_align 0.5
|
||
|
text_minwidth 180
|
||
|
|
||
|
text_size 16
|
||
|
|
||
|
action CopyCode(raw_code)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
init python hide:
|
||
|
|
||
|
import os.path
|
||
|
import re
|
||
|
|
||
|
# A list of files we will be scanning.
|
||
|
files = [ ]
|
||
|
|
||
|
for i in renpy.list_files():
|
||
|
if i.endswith(".rpy"):
|
||
|
files.append(i)
|
||
|
|
||
|
for fn in files:
|
||
|
|
||
|
try:
|
||
|
with open(os.path.join(renpy.config.gamedir, fn), "r") as f:
|
||
|
lines = f.readlines()
|
||
|
except:
|
||
|
lines = [ ]
|
||
|
|
||
|
open_examples = set()
|
||
|
|
||
|
for l in lines:
|
||
|
|
||
|
l = l.rstrip()
|
||
|
|
||
|
m = re.match("\s*#begin (\w+)", l)
|
||
|
if m:
|
||
|
example = m.group(1)
|
||
|
|
||
|
if example in examples:
|
||
|
raise Exception("Example %r is defined in two places.", example)
|
||
|
|
||
|
open_examples.add(example)
|
||
|
examples[example] = [ ]
|
||
|
|
||
|
continue
|
||
|
|
||
|
m = re.match("\s*#end (\w+)", l)
|
||
|
if m:
|
||
|
example = m.group(1)
|
||
|
|
||
|
if example not in open_examples:
|
||
|
raise Exception("Example %r is not open.", example)
|
||
|
|
||
|
open_examples.remove(example)
|
||
|
continue
|
||
|
|
||
|
for i in open_examples:
|
||
|
examples[i].append(l)
|
||
|
|
||
|
if open_examples:
|
||
|
raise Exception("Examples %r remain open at the end of %r" % (open_examples, fn))
|
||
|
|
||
|
|
||
|
|
||
|
init python:
|
||
|
|
||
|
def lint_stats_callback():
|
||
|
print("The game contains {} examples.".format(len(examples)))
|
||
|
|
||
|
config.lint_stats_callbacks.append(lint_stats_callback)
|
||
|
|
||
|
import base64
|
||
|
|
||
|
image _finaleimage = im.Data(base64.b64decode("""
|
||
|
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
|
||
|
"""), "finale.png")
|
||
|
|
||
|
|
||
|
image _finale:
|
||
|
"_finaleimage"
|
||
|
yalign 0.3
|
||
|
xanchor 1.0 xpos 0.0
|
||
|
pause 90.0
|
||
|
easein 1.5 xanchor 0.0 xpos .25
|
||
|
pause 3.0
|
||
|
easeout 1.5 xanchor 1.0 xpos 0.0
|
||
|
repeat
|