Add initial static-doc to master for proper versioning

This commit is contained in:
Griatch 2020-06-12 22:01:38 +02:00
parent 935c2c6eff
commit f7bde74360
290 changed files with 32391 additions and 0 deletions

View file

@ -0,0 +1,76 @@
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
if [ "x(.vienvdoc) " != x ] ; then
PS1="(.vienvdoc) ${PS1:-}"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi

View file

@ -0,0 +1,37 @@
# This file must be used with "source bin/activate.csh" *from csh*.
# You cannot run it directly.
# Created by Davide Di Blasi <davidedb@gmail.com>.
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate'
# Unset irrelevant variables.
deactivate nondestructive
setenv VIRTUAL_ENV "/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc"
set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
if (".vienvdoc" != "") then
set env_name = ".vienvdoc"
else
if (`basename "VIRTUAL_ENV"` == "__") then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
else
set env_name = `basename "$VIRTUAL_ENV"`
endif
endif
set prompt = "[$env_name] $prompt"
unset env_name
endif
alias pydoc python -m pydoc
rehash

View file

@ -0,0 +1,75 @@
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
# you cannot run it directly
function deactivate -d "Exit virtualenv and return to normal shell environment"
# reset old environment variables
if test -n "$_OLD_VIRTUAL_PATH"
set -gx PATH $_OLD_VIRTUAL_PATH
set -e _OLD_VIRTUAL_PATH
end
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
set -e _OLD_VIRTUAL_PYTHONHOME
end
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
functions -e fish_prompt
set -e _OLD_FISH_PROMPT_OVERRIDE
functions -c _old_fish_prompt fish_prompt
functions -e _old_fish_prompt
end
set -e VIRTUAL_ENV
if test "$argv[1]" != "nondestructive"
# Self destruct!
functions -e deactivate
end
end
# unset irrelevant variables
deactivate nondestructive
set -gx VIRTUAL_ENV "/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc"
set -gx _OLD_VIRTUAL_PATH $PATH
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
# unset PYTHONHOME if set
if set -q PYTHONHOME
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
set -e PYTHONHOME
end
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
# fish uses a function instead of an env var to generate the prompt.
# save the current fish_prompt function as the function _old_fish_prompt
functions -c fish_prompt _old_fish_prompt
# with the original prompt function renamed, we can override with our own.
function fish_prompt
# Save the return status of the last command
set -l old_status $status
# Prompt override?
if test -n "(.vienvdoc) "
printf "%s%s" "(.vienvdoc) " (set_color normal)
else
# ...Otherwise, prepend env
set -l _checkbase (basename "$VIRTUAL_ENV")
if test $_checkbase = "__"
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
else
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
end
end
# Restore the return status of the previous command.
echo "exit $old_status" | .
_old_fish_prompt
end
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
end

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from automat._visualize import tool
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(tool())

11
docs/.vienvdoc/bin/black Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from black import patched_main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(patched_main())

11
docs/.vienvdoc/bin/blackd Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from blackd import patched_main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(patched_main())

11
docs/.vienvdoc/bin/cftp Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.conch.scripts.cftp import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

11
docs/.vienvdoc/bin/chardetect Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from chardet.cli.chardetect import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/ckeygen Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.conch.scripts.ckeygen import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

12
docs/.vienvdoc/bin/cm2html Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2html'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2html')()
)

12
docs/.vienvdoc/bin/cm2latex Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2latex'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2latex')()
)

12
docs/.vienvdoc/bin/cm2man Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2man'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2man')()
)

12
docs/.vienvdoc/bin/cm2pseudoxml Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2pseudoxml'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2pseudoxml')()
)

12
docs/.vienvdoc/bin/cm2xetex Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2xetex'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2xetex')()
)

12
docs/.vienvdoc/bin/cm2xml Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'recommonmark','console_scripts','cm2xml'
__requires__ = 'recommonmark'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('recommonmark', 'console_scripts', 'cm2xml')()
)

11
docs/.vienvdoc/bin/cmark Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from commonmark.cmark import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/conch Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.conch.scripts.conch import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

11
docs/.vienvdoc/bin/django-admin Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from django.core.management import execute_from_command_line
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(execute_from_command_line())

View file

@ -0,0 +1,5 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
from django.core import management
if __name__ == "__main__":
management.execute_from_command_line()

11
docs/.vienvdoc/bin/easy_install Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from setuptools.command.easy_install import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from setuptools.command.easy_install import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

6
docs/.vienvdoc/bin/evennia Executable file
View file

@ -0,0 +1,6 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-DEV-SCRIPT: 'evennia==0.9.0','evennia'
__requires__ = 'evennia==0.9.0'
__import__('pkg_resources').require('evennia==0.9.0')
__file__ = '/home/griatch/Devel/Home/evennia/evennia/bin/unix/evennia'
exec(compile(open(__file__).read(), __file__, 'exec'))

12
docs/.vienvdoc/bin/futurize Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'future==0.18.2','console_scripts','futurize'
__requires__ = 'future==0.18.2'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('future==0.18.2', 'console_scripts', 'futurize')()
)

11
docs/.vienvdoc/bin/iptest Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from IPython.testing.iptestcontroller import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/iptest3 Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from IPython.testing.iptestcontroller import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/ipython Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())

11
docs/.vienvdoc/bin/ipython3 Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())

11
docs/.vienvdoc/bin/mailmail Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.mail.scripts.mailmail import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

12
docs/.vienvdoc/bin/pasteurize Executable file
View file

@ -0,0 +1,12 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# EASY-INSTALL-ENTRY-SCRIPT: 'future==0.18.2','console_scripts','pasteurize'
__requires__ = 'future==0.18.2'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('future==0.18.2', 'console_scripts', 'pasteurize')()
)

11
docs/.vienvdoc/bin/pip Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from pip import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pip3 Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from pip import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pip3.7 Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from pip import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pudb3 Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from pudb.run import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pybabel Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from babel.messages.frontend import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pygmentize Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from pygments.cmdline import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/pyhtmlizer Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.scripts.htmlizer import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

1
docs/.vienvdoc/bin/python Symbolic link
View file

@ -0,0 +1 @@
python3.7

1
docs/.vienvdoc/bin/python3 Symbolic link
View file

@ -0,0 +1 @@
python3.7

View file

@ -0,0 +1 @@
/usr/bin/python3.7

23
docs/.vienvdoc/bin/rst2html.py Executable file
View file

@ -0,0 +1,23 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing HTML.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates (X)HTML documents from standalone reStructuredText '
'sources. ' + default_description)
publish_cmdline(writer_name='html', description=description)

26
docs/.vienvdoc/bin/rst2html4.py Executable file
View file

@ -0,0 +1,26 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2html4.py 7994 2016-12-10 17:41:45Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing (X)HTML.
The output conforms to XHTML 1.0 transitional
and almost to HTML 4.01 transitional (except for closing empty tags).
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates (X)HTML documents from standalone reStructuredText '
'sources. ' + default_description)
publish_cmdline(writer_name='html4', description=description)

35
docs/.vienvdoc/bin/rst2html5.py Executable file
View file

@ -0,0 +1,35 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf8 -*-
# :Copyright: © 2015 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause
#
# Revision: $Revision: 8410 $
# Date: $Date: 2019-11-04 22:14:43 +0100 (Mo, 04. Nov 2019) $
"""
A minimal front end to the Docutils Publisher, producing HTML 5 documents.
The output also conforms to XHTML 1.0 transitional
(except for the doctype declaration).
"""
try:
import locale # module missing in Jython
locale.setlocale(locale.LC_ALL, '')
except locale.Error:
pass
from docutils.core import publish_cmdline, default_description
description = (u'Generates HTML 5 documents from standalone '
u'reStructuredText sources '
+ default_description)
publish_cmdline(writer_name='html5', description=description)

26
docs/.vienvdoc/bin/rst2latex.py Executable file
View file

@ -0,0 +1,26 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2latex.py 5905 2009-04-16 12:04:49Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing LaTeX.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline
description = ('Generates LaTeX documents from standalone reStructuredText '
'sources. '
'Reads from <source> (default is stdin) and writes to '
'<destination> (default is stdout). See '
'<http://docutils.sourceforge.net/docs/user/latex.html> for '
'the full reference.')
publish_cmdline(writer_name='latex', description=description)

26
docs/.vienvdoc/bin/rst2man.py Executable file
View file

@ -0,0 +1,26 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# Author:
# Contact: grubert@users.sf.net
# Copyright: This module has been placed in the public domain.
"""
man.py
======
This module provides a simple command line interface that uses the
man page writer to output from ReStructuredText source.
"""
import locale
try:
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
from docutils.writers import manpage
description = ("Generates plain unix manual documents. " + default_description)
publish_cmdline(writer=manpage.Writer(), description=description)

30
docs/.vienvdoc/bin/rst2odt.py Executable file
View file

@ -0,0 +1,30 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2odt.py 5839 2009-01-07 19:09:28Z dkuhlman $
# Author: Dave Kuhlman <dkuhlman@rexx.com>
# Copyright: This module has been placed in the public domain.
"""
A front end to the Docutils Publisher, producing OpenOffice documents.
"""
import sys
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline_to_binary, default_description
from docutils.writers.odf_odt import Writer, Reader
description = ('Generates OpenDocument/OpenOffice/ODF documents from '
'standalone reStructuredText sources. ' + default_description)
writer = Writer()
reader = Reader()
output = publish_cmdline_to_binary(reader=reader, writer=writer,
description=description)

View file

@ -0,0 +1,67 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2odt_prepstyles.py 8346 2019-08-26 12:11:32Z milde $
# Author: Dave Kuhlman <dkuhlman@rexx.com>
# Copyright: This module has been placed in the public domain.
"""
Fix a word-processor-generated styles.odt for odtwriter use: Drop page size
specifications from styles.xml in STYLE_FILE.odt.
"""
# Author: Michael Schutte <michi@uiae.at>
from __future__ import print_function
from lxml import etree
import sys
import zipfile
from tempfile import mkstemp
import shutil
import os
NAMESPACES = {
"style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
"fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
}
def prepstyle(filename):
zin = zipfile.ZipFile(filename)
styles = zin.read("styles.xml")
root = etree.fromstring(styles)
for el in root.xpath("//style:page-layout-properties",
namespaces=NAMESPACES):
for attr in el.attrib:
if attr.startswith("{%s}" % NAMESPACES["fo"]):
del el.attrib[attr]
tempname = mkstemp()
zout = zipfile.ZipFile(os.fdopen(tempname[0], "w"), "w",
zipfile.ZIP_DEFLATED)
for item in zin.infolist():
if item.filename == "styles.xml":
zout.writestr(item, etree.tostring(root))
else:
zout.writestr(item, zin.read(item.filename))
zout.close()
zin.close()
shutil.move(tempname[1], filename)
def main():
args = sys.argv[1:]
if len(args) != 1:
print(__doc__, file=sys.stderr)
print("Usage: %s STYLE_FILE.odt\n" % sys.argv[0], file=sys.stderr)
sys.exit(1)
filename = args[0]
prepstyle(filename)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,23 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2pseudoxml.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing pseudo-XML.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates pseudo-XML from standalone reStructuredText '
'sources (for testing purposes). ' + default_description)
publish_cmdline(description=description)

24
docs/.vienvdoc/bin/rst2s5.py Executable file
View file

@ -0,0 +1,24 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2s5.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: Chris Liechti <cliechti@gmx.net>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing HTML slides using
the S5 template system.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates S5 (X)HTML slideshow documents from standalone '
'reStructuredText sources. ' + default_description)
publish_cmdline(writer_name='s5', description=description)

27
docs/.vienvdoc/bin/rst2xetex.py Executable file
View file

@ -0,0 +1,27 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2xetex.py 7847 2015-03-17 17:30:47Z milde $
# Author: Guenter Milde
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing Lua/XeLaTeX code.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline
description = ('Generates LaTeX documents from standalone reStructuredText '
'sources for compilation with the Unicode-aware TeX variants '
'XeLaTeX or LuaLaTeX. '
'Reads from <source> (default is stdin) and writes to '
'<destination> (default is stdout). See '
'<http://docutils.sourceforge.net/docs/user/latex.html> for '
'the full reference.')
publish_cmdline(writer_name='xetex', description=description)

23
docs/.vienvdoc/bin/rst2xml.py Executable file
View file

@ -0,0 +1,23 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rst2xml.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing Docutils XML.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates Docutils-native XML from standalone '
'reStructuredText sources. ' + default_description)
publish_cmdline(writer_name='xml', description=description)

View file

@ -0,0 +1,25 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# $Id: rstpep2html.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
A minimal front end to the Docutils Publisher, producing HTML from PEP
(Python Enhancement Proposal) documents.
"""
try:
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_cmdline, default_description
description = ('Generates (X)HTML from reStructuredText-format PEP files. '
+ default_description)
publish_cmdline(reader_name='pep', writer_name='pep_html',
description=description)

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sphinx.ext.apidoc import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sphinx.ext.autosummary.generate import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/sphinx-build Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sphinx.cmd.build import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sphinx_multiversion import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sphinx.cmd.quickstart import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/sqlformat Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from sqlparse.__main__ import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/tkconch Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.conch.scripts.tkconch import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

11
docs/.vienvdoc/bin/trial Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.scripts.trial import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

11
docs/.vienvdoc/bin/twist Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.application.twist._twist import Twist
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(Twist.main())

11
docs/.vienvdoc/bin/twistd Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from twisted.scripts.twistd import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(run())

11
docs/.vienvdoc/bin/wamp Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from autobahn.__main__ import _main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(_main())

11
docs/.vienvdoc/bin/wheel Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from wheel.cli import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

11
docs/.vienvdoc/bin/xbrnetwork Executable file
View file

@ -0,0 +1,11 @@
#!/home/griatch/Devel/Home/evennia/evennia/docs/.vienvdoc/bin/python3.7
# -*- coding: utf-8 -*-
import re
import sys
from autobahn.xbr._cli import _main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(_main())

View file

@ -0,0 +1,3 @@
home = /usr/bin
include-system-site-packages = false
version = 3.7.5

Binary file not shown.

120
docs/Makefile Normal file
View file

@ -0,0 +1,120 @@
# Makefile to control Evennia documentation building.
# Most common commands are `make help`, `make quick` and `make local`.
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SPHINXMULTIVERSION ?= sphinx-multiversion
SPHINXAPIDOC ?= sphinx-apidoc
SPHINXAPIDOCOPTS = --tocfile evennia-api --module-first --force
SPHINXAPIDOCENV = members,undoc-members,show-inheritance
SPHINXAPIDOCEXCLUDE = */migrations/*
SOURCEDIR = source
BUILDDIR = build
AUTODOCDIR = $(SOURCEDIR)/api
EVDIR ?= $(realpath ../evennia)
EVGAMEDIR ?= $(realpath ../../gamedir)
cblue = $(shell echo "\033[1m\033[34m")
cnorm = $(shell echo "\033[0m")
QUICKFILES=$(SOURCEDIR)/*.md
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@echo "Evennia-specific: "
@echo " $(cblue)install$(cnorm) to get build requirements"
@echo " $(cblue)clean$(cnorm) to remove remnants of a previous build"
@echo " $(cblue)local$(cnorm) to build local html docs of the current branch (no multiversion)."
@echo " $(cblue)mv-local$(cnorm) to build multiversion html docs, without deploying (req. local git commit)"
@echo " $(cblue)release$(cnorm) to build and deploy multiversion docs online (req. commit and github push access)"
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Evennia - custom commands
# helper targets
_check-env:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) bash -e checkenv.sh
_multiversion-check-env:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) bash -e checkenv.sh multiversion
_clean_api_index:
rm source/api/*
_autodoc-index:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTS) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE)
_multiversion-autodoc-index:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) SPHINX_APIDOC_OPTIONS=$(SPHINXAPIDOCENV) $(SPHINXAPIDOC) $(SPHINXAPIDOCOPTS) -o $(SOURCEDIR)/api/ $(EVDIR) $(SPHINXAPIDOCEXCLUDE)
git diff-index --quiet HEAD || git commit -a -m "Updated API autodoc index."
_build:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) $(SPHINXBUILD) $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
_quick-build:
@NOAUTODOC=1 EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) $(SPHINXBUILD) $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html" $(QUICKFILES)
_multiversion-build:
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) $(SPHINXMULTIVERSION) $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS)
_multiversion-deploy:
@bash -e deploy.sh
# main targets
install:
@pip install -r requirements.txt
clean:
@rm -Rf $(BUILDDIR)
@git clean -f -d docs/
@echo "Cleaned old build dir and leftover files."
# TODO remove once done with migration
copy:
@cd pylib && python copy_from_wiki.py && cd ..
make quick
quick:
make _check-env
make _quick-build $(FILES)
@echo ""
@echo "Documentation built (no autodocs). \nTo see result, open evennia/docs/build/html/index.html in a browser."
local:
make _check-env
make clean
make _autodoc-index
make _build
@echo ""
@echo "Documentation built. \nTo see result, open evennia/docs/build/html/index.html in a browser."
mv-local:
make _multiversion-check-env
make clean
make _multiversion-autodoc-index
make _multiversion-build
@echo "Documentation built. \nTo see result, open evennia/docs/build/html/versions/<version>/index.html in a browser."
deploy:
make _multiversion-deploy
# build and prepare the docs for release
release:
make mv-local
# make _mv-deploy
@echo ""
@echo "Deployment complete."

247
docs/README.md Normal file
View file

@ -0,0 +1,247 @@
# evennia-docs
Documentation for the Evennia MUD creation system.
> WARNING: This system is still WIP and many things are bound to change!
> Contributing is still primarily to be done in the wiki.
The live documentation is (will in the future be) available at `https://evennia.github.io/evennia/`.
# Editing the docs
The documentation source files are `*.md` (Markdown) files found in `evennia/docs/source/`.
Markdown files are simple text files that can be edited with a normal text editor. They use
the [Markdown][commonmark] syntax.
Don't edit the files in `source/api/`. These are auto-generated and your changes
will be lost.
See also later in this doc for [Help with editing syntax](#Help-with-editing-syntax).
## Contributing
Contributing to the docs is is like [contributing to the rest of Evennia][contributing]:
Check out the branch of Evennia you want to edit the documentation for. Create your
own work-branch, make your changes and make a PR for it!
# Building the docs
The sources in `evennia/docs/source/` are built into a pretty documentation using
the [Sphinx][sphinx] static generator system. To do so locally you need to either
use a system with `make` (Linux/Unix/Mac/Windows-WSL) or run sphinx-commands manually
(read the `Makefile` to see which commands are run by `make`).
You don't necessarily _have_ to build the docs locally to contribute. But
building them allows you to check for yourself that syntax is correct and that
your change comes out looking as you expected.
## Building only the main documentation
If you only want to build the main documentation pages (not the API autodocs),
you don't need to install Evennia itself, only the documentation resources.
All is done in your terminal/console.
- (Optional, but recommended): Activate a virtualenv with Python 3.7.
- `cd` to into the `evennia/docs` folder (where this README is).
- Install the documentation-build requirements:
```
make install
or
pip install -r requirements.txt
```
- Next, build the html-based documentation.
```
make quick
```
- The html-based documentation will appear in the new
folder `evennia/docs/build/html/`. Note any errors from files you have edited.
- Use a web browser to open `evennia/docs/build/html/index.html` and view the docs.
Note that you will get errors if clicking a link to the auto-docs, because you didn't build them!
## Building the main documentation and API docs
The full documentation includes both the doc pages and the API documentation
generated from the Evennia source. For this you must install Evennia and
initialize a new game with a default database (you don't need to have it
running)
- Follow the normal [Evennia Getting-Started instructions][getting-started]
to install Evennia. Use a virtualenv.
- Make sure you `cd` to the folder _containing_ your `evennia/` repo (so two levels up from `docs/`).
- Create a new game folder called `gamedir` at the same level as your `evennia`
repo with
```
evennia --init gamedir
```
- Then `cd` into it and create a new, empty database. You don't need to start the game
or do any further changes.
```
evennia migrate
```
- This is how the structure should look at this point:
```
(top)
|
----- evennia/ (the top-level folder, containing docs/)
|
----- gamedir/
```
- Make sure you are still in your virtualenv, then go to `evennia/docs/` and
install the doc-building requirements:
```
make install
or
pip install -r requirements.txt
```
- Finally, build the full documentation, including the auto-docs:
```
make local
```
- The rendered files will appear in a new folder `evennia/docs/build/html`.
Note any errors from files you have edited.
- Point your web browser to `evennia/docs/build/html/index.html` to view the full docs.
### Building with another gamedir
If you for some reason want to use another location of your `gamedir/`, or want it
named something else (maybe you already use the name 'gamedir' for your development ...),
you can do so by setting the `EVGAMEDIR` environment variable to the absolute path
of your alternative game dir. For example:
```
EVGAMEDIR=/my/path/to/mygamedir make local
```
## Building for release
The full Evennia documentation also tracks documentation from older Evennia
versions. This is done by pulling documentation from Evennia's old release
branches and building them all so readers can choose which one to view. Only
specific official Evennia branches will be built, so you can't use this to
build your own testing branch.
- All local changes must have been committed to git first, since the versioned
docs are built by looking at the git tree.
- To build for local checking, run (`mv` stands for "multi-version"):
```
make mv-local
```
- The different versions will be found under `evennia/docs/build/versions/`.
- If you have git-push access to the Evennia `gh-pages` branch on `github`, you
can now deploy.
```
make deploy
```
- If you know what you are doing you can also do build + deploy in one step:
```
make release
```
- After deployment finishes, the updated live documentation will be
available at `https://evennia.github.io/evennia/`.
# Help with editing syntax
> This needs expanding in the future.
## Referring to a heading in the same file
You can self-reference by pointing to a header/label elsewhere in the
same document by using `#` and replacing any spaces in the name with `-`.
```
This is a [link to the heading](#My-Heading-Name).
# My Heading Name
```
## Referring to titles in another file
> WIP: Most of these special structures need more work and checking.
If file1 looks like this:
```
# Header title
```
You can refer to it from another file as
```
Read more about it [here](path.to.file1.md:Header title)
```
> This is not actually working at this time (WIP)
To refer to code in the Evennia repository, you can use a relative reference from the docs/ folder:
```
You can find this code [here](../evennia/objects/objects.py).
```
This will be automatically translated to the matching github link so the reader can click and jump to that code directly.
> This is not currently working. (WIP)
## Making toc-tree indices
To make a Table-of-Contents listing (what Sphinx refers to as a "Toc Tree"), one
must make new heading named either `Contents` or `Index`, followed by a bullet-list of
links:
```
# Index
- [Title1](doc1)
- [Title2](doc2)
```
This will create a toc-tree structure behind the scenes.
We may expand on this later. For now, check out existing docs and refer to the
[Markdown][commonmark] (CommonMark) specification.
# Technical
Evennia leverages [Sphinx][sphinx] with the [recommonmark][recommonmark] extension, which allows us to write our
docs in light-weight Markdown (more specifically [CommonMark][commonmark], like on github) rather than ReST.
The recommonmark extension however also allows us to use ReST selectively in the places were it is more
expressive than the simpler (but much easier) Markdown.
For [autodoc-generation][sphinx-autodoc] generation, we use the sphinx-[napoleon][sphinx-napoleon] extension
to understand our friendly Google-style docstrings used in classes and functions etc.
[sphinx]: https://www.sphinx-doc.org/en/master/
[recommonmark]: https://recommonmark.readthedocs.io/en/latest/index.html
[commonmark]: https://spec.commonmark.org/current/
[sphinx-autodoc]: http://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#module-sphinx.ext.autodoc
[sphinx-napoleon]: http://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html
[getting-started]: https://github.com/evennia/evennia/wiki/Getting-Started
[contributing]: https://github.com/evennia/evennia/wiki/Contributing

30
docs/checkenv.sh Normal file
View file

@ -0,0 +1,30 @@
# check environment
# common checks
if [ ! -d "$EVDIR" ]; then
echo "The evennia dir is not found at $EVDIR.";
exit 1
fi
if [ ! -d "$EVGAMEDIR" ]; then
echo "The gamedir is not found at $EVGAMEDIR";
exit 1
fi
if [ $# -ne 0 ]
# a multi-version build
then
if [ -n "$(git status --untracked-files=no --porcelain)" ]; then
echo "There are uncommitted changes. Make sure to commit everything in your current branch before doing a multiversion build."
exit 1
fi
fi

26
docs/deploy.sh Normal file
View file

@ -0,0 +1,26 @@
#
# deploy to github
#
# This copies the recently built files from build/html into the github-gh branch. Note that
# it's important that build/ must not be committed to git!
#
if [ -n "$(git status --untracked-files=no --porcelain)" ]; then
echo "There are uncommitted changes. Make sure to commit everything in your current branch first."
exit 1
fi
git checkout gh-pages
rm -Rf versions
mv build/html/versions .
git add versions
git commit -a -m "Updated HTML docs"
git push origin gh-pages
# get back to previous branch
git checkout -
echo "Deployed to https://evennia.github.io/evennia-docs."

35
docs/make.bat Normal file
View file

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View file

@ -0,0 +1,93 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Builds a lunr static search index for optimized search
"""
import os
import json
import glob
from argparse import ArgumentParser
from os.path import sep, abspath, dirname, join as joinpath
from lunr import lunr
_DOCS_PATH = dirname(dirname(abspath(__file__)))
_DEFAULT_BUILD_DIR = joinpath(_DOCS_PATH, "build", "html")
_DEFAULT_URL_BASE = f"file://{_DEFAULT_BUILD_DIR}"
_INDEX_PATH = joinpath("_static", "js", "lunr", "search_index.json")
DEFAULT_SOURCE_DIR = joinpath(_DOCS_PATH, "source")
DEFAULT_OUTFILE = joinpath(DEFAULT_SOURCE_DIR, _INDEX_PATH)
URL_BASE = os.environ.get("SEARCH_URL_BASE", _DEFAULT_URL_BASE)
def create_search_index(sourcedir, outfile):
"""
Create the index.
Args:
sourcedir (str): Path to the source directory. This will be searched
for both .md and .rst files.
outfile (str): Path to the index file to create.
"""
markdown_files = glob.glob(f"{sourcedir}{sep}*.md")
markdown_files.extend(glob.glob(f"{sourcedir}{sep}*{sep}*.md"))
rest_files = glob.glob(f"{sourcedir}{sep}*.rst")
rest_files.extend(glob.glob(f"{sourcedir}{sep}*{sep}*.rst"))
filepaths = markdown_files + rest_files
outlist = []
print(f"Building Search index from {len(filepaths)} files ... ", end="")
for filepath in filepaths:
with open(filepath, 'r') as fil:
filename = filepath.rsplit(sep, 1)[1].split(".", 1)[0]
url = f"{URL_BASE}{sep}{filename}.html".strip()
title = filename.replace("-", " ").strip()
body = fil.read()
data = {
"url": url,
"title": title,
"text": body,
}
outlist.append(data)
idx = lunr(
ref="url",
documents=outlist,
fields=[
{
"field_name": "title",
"boost": 10
},
{
"field_name": "text",
"boost": 1
}
],
)
with open(outfile, "w") as fil:
fil.write(json.dumps(idx.serialize()))
print(f"wrote to source{sep}{_INDEX_PATH}.")
if __name__ == "__main__":
parser = ArgumentParser(description="Build a static search index.")
parser.add_argument("-i", dest="sourcedir", default=DEFAULT_SOURCE_DIR,
help="Absolute path to the documentation source dir")
parser.add_argument("-o", dest="outfile", default=DEFAULT_OUTFILE,
help="Absolute path to the index file to output.")
args = parser.parse_args()
create_search_index(args.sourcedir, args.outfile)

View file

@ -0,0 +1,254 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Copy data from old Evennia github Wiki to static files.
Prepare files for mkdoc. This assumes evennia.wiki is cloned
to a folder at the same level as the evennia repo.
Just run this to update everything.
We also need to build the toc-tree and should do so automatically for now.
"""
import glob
import re
import datetime
_RE_MD_LINK = re.compile(r"\[(?P<txt>[\w -\[\]]+?)\]\((?P<url>.+?)\)", re.I + re.S + re.U)
_RE_REF_LINK = re.compile(r"\[[\w -\[\]]+?\]\(.+?\)", re.I + re.S + re.U)
_RE_CLEAN = re.compile(r"\|-+?|-+\|", re.I + re.S + re.U)
_IGNORE_FILES = (
"_Sidebar.md",
"Wiki-Index.md"
)
_INDEX_PREFIX = f"""
# VERSION WARNING
> This is the experimental static v0.9 documentation of Evennia, _automatically_ generated from the
> [evennia wiki](https://github.com/evennia/evennia/wiki/) at {datetime.datetime.now()}.
> There are known conversion issues which will _not_ be addressed in this version - refer to
> the original wiki if you have trouble.
>
> Manual conversion and cleanup will instead happen during development of the upcoming v1.0
> version of this static documentation.
"""
_WIKI_DIR = "../../../evennia.wiki/"
_INFILES = [path for path in sorted(glob.glob(_WIKI_DIR + "/*.md"))
if path.rsplit('/', 1)[-1] not in _IGNORE_FILES]
_FILENAMES = [path.rsplit("/", 1)[-1] for path in _INFILES]
_FILENAMES = [path.split(".", 1)[0] for path in _FILENAMES]
_FILENAMESLOW = [path.lower() for path in _FILENAMES]
_OUTDIR = "../source/"
_OLD_WIKI_URL = "https://github.com/evennia/evennia/wiki/"
_OLD_WIKI_URL_LEN = len(_OLD_WIKI_URL)
_CODE_PREFIX = "github:"
_API_PREFIX = "api:"
_CUSTOM_LINK_REMAP = {
"CmdSets": "Command-Sets",
"CmdSet": "Command-Sets",
"Cmdsets": "Command-Sets",
"CommandSet": "Command-Sets",
"batch-code-processor": "Batch-Code-Processor",
"Batch-code-processor": "Batch-Code-Processor",
"batch-command-processor": "Batch-Command-Processor",
"Batch-command-processor": "Batch-Command-Processor",
"evennia-API": "Evennia-API",
"Channels": "Communications#Channels",
"Comms": "Communications",
"typeclass": "Typeclasses",
"Home": "index",
"Help-system": "Help-System",
"Using-Mux-as-a-Standard": "Using-MUX-as-a-Standard",
"Building-quickstart": "Building-Quickstart",
"Adding-Object-Typeclass-tutorial": "Adding-Object-Typeclass-Tutorial",
"EvTable": _API_PREFIX + "evennia.utils#module-evennia.utils.evtable",
}
# complete reference remaps
_REF_REMAP = {
"[![Getting Started][icon_new]](Getting-Started)": "![Getting Started][icon_new]",
"[![Admin Docs][icon_admin]](Administrative-Docs)": "![Admin Docs][icon_admin]",
"[![Builder Docs][icon_builder]](Builder-Docs)": "![Builder Docs][icon_builder]",
"[![Developer-Central][icon_devel]](Developer-Central)": "![Developer-Central][icon_devel]",
"[![tutorial][icon_tutorial]](Tutorials)": "![Tutorials][icon_tutorial]",
"[![API][icon_api]](evennia)": "![API][icon_api]",
}
# absolute links (mainly github links) that should not be converted. This
# should be given without any #anchor.
_ABSOLUTE_LINK_SKIP = (
# "https://github.com/evennia/evennia/wiki/feature-request",
)
# specific references tokens that should be ignored. Should be given
# without any #anchor.
_REF_SKIP = (
"[5](Win)", "[6](Win)", "[7](Win)", "[10](Win)", "[11](Mac)", "[13](Win)",
"[14](IOS)", "[15](IOS)", "[16](Andr)", "[17](Andr)", "[18](Unix)",
"[21](Chrome)",
# these should be checked
"[EvTable](EvTable)",
"[styled](OptionStyles)",
"[Inputfunc](Inputfunc)",
"[online documentation wiki](index)",
"[online documentation](index)",
"[Accounts](Account)",
"[Session](Session)",
"[Inputfuncs](Inputfunc)",
)
_CURRENT_TITLE = ""
def _sub_remap(match):
"""Total remaps"""
ref = match.group(0)
if ref in _REF_REMAP:
new_ref = _REF_REMAP[ref]
print(f" Replacing reference {ref} -> {new_ref}")
return new_ref
return ref
def _sub_link(match):
mdict = match.groupdict()
txt, url_orig = mdict['txt'], mdict['url']
url = url_orig
# if not txt:
# # the 'comment' is not supported by Mkdocs
# return ""
print(f" [{txt}]({url})")
url = _CUSTOM_LINK_REMAP.get(url, url)
url, *anchor = url.rsplit("#", 1)
if url in _ABSOLUTE_LINK_SKIP:
url += (("#" + anchor[0]) if anchor else "")
return f"[{txt}]({url})"
if url.startswith("evennia"):
print(f" Convert evennia url {url} -> {_CODE_PREFIX + url}")
url = _API_PREFIX + url
if url.startswith(_OLD_WIKI_URL):
# old wiki is an url on the form https://<wikiurl>/wiki/TextTags#header
# we don't refer to the old wiki but use internal mapping.
url_conv = url[_OLD_WIKI_URL_LEN:]
url_conv = re.sub(r"%20", "-", url_conv)
if url_conv.endswith("/_edit"):
# this is actually a bug in the wiki format
url_conv = url_conv[:-6]
if url_conv.startswith("evennia"):
# this is an api link
url_conv = _CODE_PREFIX + url_conv
print(f" Converting wiki-url: {url} -> {url_conv}")
url = url_conv
if not url and anchor:
# this happens on same-file #labels in wiki
url = _CURRENT_TITLE
if (url not in _FILENAMES and
not url.startswith("http") and not url.startswith(_CODE_PREFIX)):
url_cap = url.capitalize()
url_plur = url[:-3] + 's' + ".md"
url_cap_plur = url_plur.capitalize()
link = f"[{txt}]({url})"
if link in _REF_SKIP:
url = link
elif url_cap in _FILENAMES:
print(f" Replacing (capitalized): {url.capitalize()}")
url = url_cap
elif url_plur in _FILENAMES:
print(f" Replacing (pluralized): {url + 's'}")
url = url_plur
elif url_cap_plur in _FILENAMES:
print(f" Replacing (capitalized, pluralized): {url.capitalize() + 's'}")
url = url_cap_plur
elif url.lower() in _FILENAMESLOW:
ind = _FILENAMESLOW.index(url.lower())
alt = _FILENAMES[ind]
print(f" Replacing {url} with different cap: {alt}")
url = alt
# print(f"\nlink {link} (orig: [{txt}]({url_orig})) found no file match")
# inp = input("Enter alternate url (return to keep old): ")
# if inp.strip():
# url = inp.strip()
if anchor:
url += "#" + anchor[0]
return f"[{txt}]({url})"
def create_toctree(files):
with open("../source/toc.md", "w") as fil:
fil.write("# Toc\n")
for path in files:
filename = path.rsplit("/", 1)[-1]
ref = filename.rsplit(".", 1)[0]
linkname = ref.replace("-", " ")
if ref == "Home":
ref = "index"
fil.write(f"\n* [{linkname}]({ref}.md)")
def convert_links(files, outdir):
global _CURRENT_TITLE
for inpath in files:
is_index = False
outfile = inpath.rsplit('/', 1)[-1]
if outfile == "Home.md":
outfile = "index.md"
is_index = True
outfile = _OUTDIR + outfile
title = inpath.rsplit("/", 1)[-1].split(".", 1)[0].replace("-", " ")
print(f"Converting links in {inpath} -> {outfile} ...")
with open(inpath) as fil:
text = fil.read()
if is_index:
text = _INDEX_PREFIX + text
_CURRENT_TITLE = title.replace(" ", "-")
text = _RE_CLEAN.sub("", text)
text = _RE_REF_LINK.sub(_sub_remap, text)
text = _RE_MD_LINK.sub(_sub_link, text)
text = text.split('\n')[1:] if text.split('\n')[0].strip().startswith('[]') else text.split('\n')
text = "\n".join(text)
if not is_index:
text = f"# {title}\n\n{text}"
with open(outfile, 'w') as fil:
fil.write(text)
if __name__ == "__main__":
create_toctree(_INFILES)
convert_links(_INFILES, _OUTDIR)

11
docs/requirements.txt Normal file
View file

@ -0,0 +1,11 @@
# requirements for building the docs
sphinx==2.4.4
sphinx-multiversion==0.1.1
lunr==0.5.8
# recommonmark custom branch with evennia-specific fixes
git+https://github.com/evennia/recommonmark.git@evennia-mods#egg=recommonmark
# sphinxcontrib-lunrsearch custom branch with evennia-specific fixes
git+https://github.com/evennia/sphinxcontrib-lunrsearch.git@evennia-mods#egg=sphinxcontrib-lunrsearch

View file

@ -0,0 +1,327 @@
# A voice operated elevator using events
- Previous tutorial: [Adding dialogues in events](Dialogues-in-events)
This tutorial will walk you through the steps to create a voice-operated elevator, using the [in-game Python system](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md). This tutorial assumes the in-game Python system is installed in your game. If it isn't, you can follow the installation steps given in [the documentation on in-game Python](https://github.com/evennia/evennia/blob/master/evennia/contrib/ingame_python/README.md), and come back on this tutorial once the system is installed. **You do not need to read** the entire documentation, it's a good reference, but not the easiest way to learn about it. Hence these tutorials.
The in-game Python system allows to run code on individual objects in some situations. You don't have to modify the source code to add these features, past the installation. The entire system makes it easy to add specific features to some objects, but not all.
> What will we try to do?
In this tutorial, we are going to create a simple voice-operated elevator. In terms of features, we will:
- Explore events with parameters.
- Work on more interesting callbacks.
- Learn about chained events.
- Play with variable modification in callbacks.
## Our study case
Let's summarize what we want to achieve first. We would like to create a room that will represent the inside of our elevator. In this room, a character could just say "1", "2" or "3", and the elevator will start moving. The doors will close and open on the new floor (the exits leading in and out of the elevator will be modified).
We will work on basic features first, and then will adjust some, showing you how easy and powerfully independent actions can be configured through the in-game Python system.
## Creating the rooms and exits we need
We'll create an elevator right in our room (generally called "Limbo", of ID 2). You could easily adapt the following instructions if you already have some rooms and exits, of course, just remember to check the IDs.
> Note: the in-game Python system uses IDs for a lot of things. While it is not mandatory, it is good practice to know the IDs you have for your callbacks, because it will make manipulation much quicker. There are other ways to identify objects, but as they depend on many factors, IDs are usually the safest path in our callbacks.
Let's go into limbo (`#2`) to add our elevator. We'll add it to the north. To create this room, in-game you could type:
tunnel n = Inside of an elevator
The game should respond by telling you:
Created room Inside of an elevator(#3) of type typeclasses.rooms.Room.
Created Exit from Limbo to Inside of an elevator: north(#4) (n).
Created Exit back from Inside of an elevator to Limbo: south(#5) (s).
Note the given IDs:
- `#2` is limbo, the first room the system created.
- `#3` is our room inside of an elevator.
- `#4` is the north exit from Limbo to our elevator.
- `#5` is the south exit from an elevator to Limbo.
Keep these IDs somewhere for the demonstration. You will shortly see why they are important.
> Why have we created exits to our elevator and back to Limbo? Isn't the elevator supposed to move?
It is. But we need to have exits that will represent the way inside the elevator and out. What we will do, at every floor, will be to change these exits so they become connected to the right room. You'll see this process a bit later.
We have two more rooms to create: our floor 2 and 3. This time, we'll use `dig`, because we don't need exits leading there, not yet anyway.
dig The second floor
dig The third floor
Evennia should answer with:
Created room The second floor(#6) of type typeclasses.rooms.Room.
Created room The third floor(#7) of type typeclasses.rooms.Room.
Add these IDs to your list, we will use them too.
## Our first callback in the elevator
Let's go to the elevator (you could use `tel #3` if you have the same IDs I have).
This is our elevator room. It looks a bit empty, feel free to add a prettier description or other things to decorate it a bit.
But what we want now is to be able to say "1", "2" or "3" and have the elevator move in that direction.
If you have read [the previous tutorial about adding dialogues in events](Dialogues-in-events), you may remember what we need to do. If not, here's a summary: we need to run some code when somebody speaks in the room. So we need to create a callback (the callback will contain our lines of code). We just need to know on which event this should be set. You can enter `call here` to see the possible events in this room.
In the table, you should see the "say" event, which is called when somebody says something in the room. So we'll need to add a callback to this event. Don't worry if you're a bit lost, just follow the following steps, the way they connect together will become more obvious.
call/add here = say 1, 2, 3
1. We need to add a callback. A callback contains the code that will be executed at a given time. So we use the `call/add` command and switch.
2. `here` is our object, the room in which we are.
3. An equal sign.
4. The name of the event to which the callback should be connected. Here, the event is "say". Meaning this callback will be executed every time somebody says something in the room.
5. But we add an event parameter to indicate the keywords said in the room that should execute our callback. Otherwise, our callback would be called every time somebody speaks, no matter what. Here we limit, indicating our callback should be executed only if the spoken message contains "1", "2" or "3".
An editor should open, inviting you to enter the Python code that should be executed. The first thing to remember is to read the text provided (it can contain important information) and, most of all, the list of variables that are available in this callback:
```
Variables you can use in this event:
character: the character having spoken in this room.
room: the room connected to this event.
message: the text having been spoken by the character.
----------Line Editor [Callback say of Inside of an elevator]---------------------
01|
----------[l:01 w:000 c:0000]------------(:h for help)----------------------------
```
This is important, in order to know what variables we can use in our callback out-of-the-box. Let's write a single line to be sure our callback is called when we expect it to:
```python
character.msg("You just said {}.".format(message))
```
You can paste this line in-game, then type the `:wq` command to exit the editor and save your modifications.
Let's check. Try to say "hello" in the room. You should see the standard message, but nothing more. Now try to say "1". Below the standard message, you should see:
You just said 1.
You can try it. Our callback is only called when we say "1", "2" or "3". Which is just what we want.
Let's go back in our code editor and add something more useful.
call/edit here = say
> Notice that we used the "edit" switch this time, since the callback exists, we just want to edit it.
The editor opens again. Let's empty it first:
:DD
And turn off automatic indentation, which will help us:
:=
> Auto-indentation is an interesting feature of the code editor, but we'd better not use it at this point, it will make copy/pasting more complicated.
## Our entire callback in the elevator
So here's the time to truly code our callback in-game. Here's a little reminder:
1. We have all the IDs of our three rooms and two exits.
2. When we say "1", "2" or "3", the elevator should move to the right room, that is change the exits. Remember, we already have the exits, we just need to change their location and destination.
It's a good idea to try to write this callback yourself, but don't feel bad about checking the solution right now. Here's a possible code that you could paste in the code editor:
```python
# First let's have some constants
ELEVATOR = get(id=3)
FLOORS = {
"1": get(id=2),
"2": get(id=6),
"3": get(id=7),
}
TO_EXIT = get(id=4)
BACK_EXIT = get(id=5)
# Now we check that the elevator isn't already at this floor
floor = FLOORS.get(message)
if floor is None:
character.msg("Which floor do you want?")
elif TO_EXIT.location is floor:
character.msg("The elevator already is at this floor.")
else:
# 'floor' contains the new room where the elevator should be
room.msg_contents("The doors of the elevator close with a clank.")
TO_EXIT.location = floor
BACK_EXIT.destination = floor
room.msg_contents("The doors of the elevator open to {floor}.",
mapping=dict(floor=floor))
```
Let's review this longer callback:
1. We first obtain the objects of both exits and our three floors. We use the `get()` eventfunc, which is a shortcut to obtaining objects. We usually use it to retrieve specific objects with an ID. We put the floors in a dictionary. The keys of the dictionary are the floor number (as str), the values are room objects.
2. Remember, the `message` variable contains the message spoken in the room. So either "1", "2", or "3". We still need to check it, however, because if the character says something like "1 2" in the room, our callback will be executed. Let's be sure what she says is a floor number.
3. We then check if the elevator is already at this floor. Notice that we use `TO_EXIT.location`. `TO_EXIT` contains our "north" exit, leading inside of our elevator. Therefore, its `location` will be the room where the elevator currently is.
4. If the floor is a different one, have the elevator "move", changing just the location and destination of both exits.
- The `BACK_EXIT` (that is "north") should change its location. The elevator shouldn't be accessible through our old floor.
- The `TO_EXIT` (that is "south", the exit leading out of the elevator) should have a different destination. When we go out of the elevator, we should find ourselves in the new floor, not the old one.
Feel free to expand on this example, changing messages, making further checks. Usage and practice are keys.
You can quit the editor as usual with `:wq` and test it out.
## Adding a pause in our callback
Let's improve our callback. One thing that's worth adding would be a pause: for the time being, when we say the floor number in the elevator, the doors close and open right away. It would be better to have a pause of several seconds. More logical.
This is a great opportunity to learn about chained events. Chained events are very useful to create pauses. Contrary to the events we have seen so far, chained events aren't called automatically. They must be called by you, and can be called after some time.
- Chained events always have the name "chain_X". Usually, X is a number, but you can give the chained event a more explicit name.
- In our original callback, we will call our chained events in, say, 15 seconds.
- We'll also have to make sure the elevator isn't already moving.
Other than that, a chained event can be connected to a callback as usual. We'll create a chained event in our elevator, that will only contain the code necessary to open the doors to the new floor.
call/add here = chain_1
The callback is added to the "chain_1" event, an event that will not be automatically called by the system when something happens. Inside this event, you can paste the code to open the doors at the new floor. You can notice a few differences:
```python
TO_EXIT.location = floor
TO_EXIT.destination = ELEVATOR
BACK_EXIT.location = ELEVATOR
BACK_EXIT.destination = floor
room.msg_contents("The doors of the elevator open to {floor}.",
mapping=dict(floor=floor))
```
Paste this code into the editor, then use `:wq` to save and quit the editor.
Now let's edit our callback in the "say" event. We'll have to change it a bit:
- The callback will have to check the elevator isn't already moving.
- It must change the exits when the elevator move.
- It has to call the "chain_1" event we have defined. It should call it 15 seconds later.
Let's see the code in our callback.
call/edit here = say
Remove the current code and disable auto-indentation again:
:DD
:=
And you can paste instead the following code. Notice the differences with our first attempt:
```python
# First let's have some constants
ELEVATOR = get(id=3)
FLOORS = {
"1": get(id=2),
"2": get(id=6),
"3": get(id=7),
}
TO_EXIT = get(id=4)
BACK_EXIT = get(id=5)
# Now we check that the elevator isn't already at this floor
floor = FLOORS.get(message)
if floor is None:
character.msg("Which floor do you want?")
elif BACK_EXIT.location is None:
character.msg("The elevator is between floors.")
elif TO_EXIT.location is floor:
character.msg("The elevator already is at this floor.")
else:
# 'floor' contains the new room where the elevator should be
room.msg_contents("The doors of the elevator close with a clank.")
TO_EXIT.location = None
BACK_EXIT.location = None
call_event(room, "chain_1", 15)
```
What changed?
1. We added a little test to make sure the elevator wasn't already moving. If it is, the `BACK_EXIT.location` (the "south" exit leading out of the elevator) should be `None`. We'll remove the exit while the elevator is moving.
2. When the doors close, we set both exits' `location` to `None`. Which "removes" them from their room but doesn't destroy them. The exits still exist but they don't connect anything. If you say "2" in the elevator and look around while the elevator is moving, you won't see any exits.
3. Instead of opening the doors immediately, we call `call_event`. We give it the object containing the event to be called (here, our elevator), the name of the event to be called (here, "chain_1") and the number of seconds from now when the event should be called (here, `15`).
4. The `chain_1` callback we have created contains the code to "re-open" the elevator doors. That is, besides displaying a message, it reset the exits' `location` and `destination`.
If you try to say "3" in the elevator, you should see the doors closing. Look around you and you won't see any exit. Then, 15 seconds later, the doors should open, and you can leave the elevator to go to the third floor. While the elevator is moving, the exit leading to it will be inaccessible.
> Note: we don't define the variables again in our chained event, we just call them. When we execute `call_event`, a copy of our current variables is placed in the database. These variables will be restored and accessible again when the chained event is called.
You can use the `call/tasks` command to see the tasks waiting to be executed. For instance, say "2" in the room, notice the doors closing, and then type the `call/tasks` command. You will see a task in the elevator, waiting to call the `chain_1` event.
## Changing exit messages
Here's another nice little feature of events: you can modify the message of a single exit without altering the others. In this case, when someone goes north into our elevator, we'd like to see something like: "someone walks into the elevator." Something similar for the back exit would be great too.
Inside of the elevator, you can look at the available events on the exit leading outside (south).
call south
You should see two interesting rows in this table:
```
| msg_arrive | 0 (0) | Customize the message when a character |
| | | arrives through this exit. |
| msg_leave | 0 (0) | Customize the message when a character leaves |
| | | through this exit. |
```
So we can change the message others see when a character leaves, by editing the "msg_leave" event. Let's do that:
call/add south = msg_leave
Take the time to read the help. It gives you all the information you should need. We'll need to change the "message" variable, and use custom mapping (between braces) to alter the message. We're given an example, let's use it. In the code editor, you can paste the following line:
```python
message = "{character} walks out of the elevator."
```
Again, save and quit the editor by entering `:wq`. You can create a new character to see it leave.
charcreate A beggar
tel #8 = here
(Obviously, adapt the ID if necessary.)
py self.search("beggar").move_to(self.search("south"))
This is a crude way to force our beggar out of the elevator, but it allows us to test. You should see:
A beggar(#8) walks out of the elevator.
Great! Let's do the same thing for the exit leading inside of the elevator. Follow the beggar, then edit "msg_leave" of "north":
call/add north = msg_leave
```python
message = "{character} walks into the elevator."
```
Again, you can force our beggar to move and see the message we have just set. This modification applies to these two exits, obviously: the custom message won't be used for other exits. Since we use the same exits for every floor, this will be available no matter at what floor the elevator is, which is pretty neat!
## Tutorial F.A.Q.
- **Q:** what happens if the game reloads or shuts down while a task is waiting to happen?
- **A:** if your game reloads while a task is in pause (like our elevator between floors), when the game is accessible again, the task will be called (if necessary, with a new time difference to take into account the reload). If the server shuts down, obviously, the task will not be called, but will be stored and executed when the server is up again.
- **Q:** can I use all kinds of variables in my callback? Whether chained or not?
- **A:** you can use every variable type you like in your original callback. However, if you execute `call_event`, since your variables are stored in the database, they will need to respect the constraints on persistent attributes. A callback will not be stored in this way, for instance. This variable will not be available in your chained event.
- **Q:** when you say I can call my chained events something else than "chain_1", "chain_2" and such, what is the naming convention?
- **A:** chained events have names beginning by "chain_". This is useful for you and for the system. But after the underscore, you can give a more useful name, like "chain_open_doors" in our case.
- **Q:** do I have to pause several seconds to call a chained event?
- **A:** no, you can call it right away. Just leave the third parameter of `call_event` out (it will default to 0, meaning the chained event will be called right away). This will not create a task.
- **Q:** can I have chained events calling themselves?
- **A:** you can. There's no limitation. Just be careful, a callback that calls itself, particularly without delay, might be a good recipe for an infinite loop. However, in some cases, it is useful to have chained events calling themselves, to do the same repeated action every X seconds for instance.
- **Q:** what if I need several elevators, do I need to copy/paste these callbacks each time?
- **A:** not advisable. There are definitely better ways to handle this situation. One of them is to consider adding the code in the source itself. Another possibility is to call chained events with the expected behavior, which makes porting code very easy. This side of chained events will be shown in the next tutorial.
- Previous tutorial: [Adding dialogues in events](Dialogues-in-events)

View file

@ -0,0 +1,30 @@
# API refactoring
Building up to Evennia 1.0 and beyond, it's time to comb through the Evennia API for old cruft. This whitepage is for anyone interested to contribute with their views on what part of the API needs refactoring, cleanup or clarification (or extension!)
Note that this is not a forum. To keep things clean, each opinion text should ideally present a clear argument or lay out a suggestion. Asking for clarification and any side-discussions should be held in chat or forum.
---
### Griatch (Aug 13, 2019)
This is how to enter an opinion. Use any markdown needed but stay within your section. Also remember to copy your text to the clipboard before saving since if someone else edited the wiki in the meantime you'll have to start over.
### Griatch (Sept 2, 2019)
I don't agree with removing explicit keywords as suggested by [Johnny on Aug 29 below](API-refactoring#reduce-usage-of-optionalpositional-arguments-aug-29-2019). Overriding such a method can still be done by `get(self, **kwargs)` if so desired, making the kwargs explicit helps IMO readability of the API. If just giving a generic `**kwargs`, one must read the docstring or even the code to see which keywords are valid.
On the other hand, I think it makes sense to as a standard offer an extra `**kwargs` at the end of arg-lists for common methods that are expected to be over-ridden. This make the API more flexible by hinting to the dev that they could expand their own over-ridden implementation with their own keyword arguments if so desired.
---
### Johnny
#### Reduce usage of optional/positional arguments (Aug 29, 2019)
```
# AttributeHandler
def get(self, key=None, default=None, category=None, return_obj=False,
strattr=False, raise_exception=False, accessing_obj=None,
default_access=True, return_list=False):
```
Many classes have methods requiring lengthy positional argument lists, which are tedious and error-prone to extend and override especially in cases where not all arguments are even required. It would be useful if arguments were reserved for required inputs and anything else relegated to kwargs for easier passthrough on extension.

105
docs/source/Accounts.md Normal file
View file

@ -0,0 +1,105 @@
# Accounts
All *users* (real people) that starts a game [Session](Sessions) on Evennia are doing so through an
object called *Account*. The Account object has no in-game representation, it represents a unique
game account. In order to actually get on the game the Account must *puppet* an [Object](Objects)
(normally a [Character](Objects#Character)).
Exactly how many Sessions can interact with an Account and its Puppets at once is determined by
Evennia's [MULTISESSION_MODE](Sessions#Multisession-mode) setting.
Apart from storing login information and other account-specific data, the Account object is what is
chatting on [Channels](Communications). It is also a good place to store [Permissions](Locks) to be
consistent between different in-game characters as well as configuration options. The Account
object also has its own [CmdSet](Command-Sets), the `AccountCmdSet`.
Logged into default evennia, you can use the `ooc` command to leave your current
[character](Objects) and go into OOC mode. You are quite limited in this mode, basically it works
like a simple chat program. It acts as a staging area for switching between Characters (if your
game supports that) or as a safety mode if your Character gets deleted. Use `ic` to attempt to
(re)puppet a Character.
Note that the Account object can have, and often does have, a different set of
[Permissions](Locks#Permissions) from the Character they control. Normally you should put your
permissions on the Account level - this will overrule permissions set on the Character level. For
the permissions of the Character to come into play the default `quell` command can be used. This
allows for exploring the game using a different permission set (but you can't escalate your
permissions this way - for hierarchical permissions like `Builder`, `Admin` etc, the *lower* of the
permissions on the Character/Account will always be used).
## How to create your own Account types
You will usually not want more than one Account typeclass for all new accounts (but you could in
principle create a system that changes an account's typeclass dynamically).
An Evennia Account is, per definition, a Python class that includes `evennia.DefaultAccount` among
its parents. In `mygame/typeclasses/accounts.py` there is an empty class ready for you to modify.
Evennia defaults to using this (it inherits directly from `DefaultAccount`).
Here's an example of modifying the default Account class in code:
```python
# in mygame/typeclasses/accounts.py
from evennia import DefaultAccount
class Account(DefaultAccount): # [...]
at_account_creation(self): "this is called only once, when account is first created"
self.db.real_name = None # this is set later self.db.real_address = None # "
self.db.config_1 = True # default config self.db.config_2 = False # "
self.db.config_3 = 1 # "
# ... whatever else our game needs to know ``` Reload the server with `reload`.
```
... However, if you use `examine *self` (the asterisk makes you examine your Account object rather
than your Character), you won't see your new Attributes yet. This is because `at_account_creation`
is only called the very *first* time the Account is called and your Account object already exists
(any new Accounts that connect will see them though). To update yourself you need to make sure to
re-fire the hook on all the Accounts you have already created. Here is an example of how to do this
using `py`:
``` py [account.at_account_creation() for account in evennia.managers.accounts.all()] ```
You should now see the Attributes on yourself.
> If you wanted Evennia to default to a completely *different* Account class located elsewhere, you
> must point Evennia to it. Add `BASE_ACCOUNT_TYPECLASS` to your settings file, and give the python
> path to your custom class as its value. By default this points to `typeclasses.accounts.Account`,
> the empty template we used above.
## Properties on Accounts
Beyond those properties assigned to all typeclassed objects (see [Typeclasses](Typeclasses)), the
Account also has the following custom properties:
- `user` - a unique link to a `User` Django object, representing the logged-in user.
- `obj` - an alias for `character`.
- `name` - an alias for `user.username`
- `sessions` - an instance of
[ObjectSessionHandler](github:evennia.objects.objects#objectsessionhandler)
managing all connected Sessions (physical connections) this object listens to (Note: In older
versions of Evennia, this was a list). The so-called `session-id` (used in many places) is found as
a property `sessid` on each Session instance.
- `is_superuser` (bool: True/False) - if this account is a superuser.
Special handlers:
- `cmdset` - This holds all the current [Commands](Commands) of this Account. By default these are
the commands found in the cmdset defined by `settings.CMDSET_ACCOUNT`.
- `nicks` - This stores and handles [Nicks](Nicks), in the same way as nicks it works on Objects.
For Accounts, nicks are primarily used to store custom aliases for [Channels](Communications#Channels).
Selection of special methods (see `evennia.DefaultAccount` for details):
- `get_puppet` - get a currently puppeted object connected to the Account and a given session id, if
any.
- `puppet_object` - connect a session to a puppetable Object.
- `unpuppet_object` - disconnect a session from a puppetable Object.
- `msg` - send text to the Account
- `execute_cmd` - runs a command as if this Account did it.
- `search` - search for Accounts.

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