├── .gitignore ├── Makefile ├── README.rst ├── make.bat └── source ├── _static ├── terminal.ico └── terminal.png ├── conf.py ├── contents ├── 01_about.rst ├── 02_features.rst ├── 03_debugging.rst ├── 04_pitfalls.rst ├── 05_cookbook.rst ├── 10_development.rst ├── 11_contributing.rst ├── cookbook │ ├── class-guards.rst │ ├── clear-console.rst │ ├── executing-code-in-all-sessions.rst │ ├── parsing-tables-by-reference.rst │ ├── passing-by-reference.rst │ ├── read-verbose-with-flag.rst │ ├── reload-command-file.rst │ ├── string-get-length.rst │ ├── string-repeat-character.rst │ ├── string-split-by-num-chars.rst │ ├── variable-table-indexes.rst │ └── variable-test-existence.rst └── features │ ├── 01_sessions.rst │ ├── 02_datatypes.rst │ ├── 03_command-files.rst │ ├── 04_loops.rst │ ├── 05_colors.rst │ ├── 06_tab-completion.rst │ ├── 07_shell-integration.rst │ ├── 08_mapper.rst │ ├── 09_autologin.rst │ └── mapper │ ├── 01_getting-started.rst │ ├── 02_editing-maps.rst │ ├── 03_map-display.rst │ └── 04_map-metadata.rst └── index.rst /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Windows ### 4 | # Windows image file caches 5 | Thumbs.db 6 | ehthumbs.db 7 | 8 | # Folder config file 9 | Desktop.ini 10 | 11 | # Recycle Bin used on file shares 12 | $RECYCLE.BIN/ 13 | 14 | # Windows Installer files 15 | *.cab 16 | *.msi 17 | *.msm 18 | *.msp 19 | 20 | # Windows shortcuts 21 | *.lnk 22 | 23 | 24 | ### OSX ### 25 | .DS_Store 26 | .AppleDouble 27 | .LSOverride 28 | 29 | # Icon must end with two \r 30 | Icon 31 | 32 | 33 | # Thumbnails 34 | ._* 35 | 36 | # Files that might appear on external disk 37 | .Spotlight-V100 38 | .Trashes 39 | 40 | # Directories potentially created on remote AFP share 41 | .AppleDB 42 | .AppleDesktop 43 | Network Trash Folder 44 | Temporary Items 45 | .apdisk 46 | 47 | 48 | ### Linux ### 49 | *~ 50 | 51 | # KDE directory preferences 52 | .directory 53 | 54 | 55 | ### SublimeText ### 56 | # cache files for sublime text 57 | *.tmlanguage.cache 58 | *.tmPreferences.cache 59 | *.stTheme.cache 60 | 61 | # workspace files are user-specific 62 | *.sublime-workspace 63 | 64 | # project files should be checked into the repository, unless a significant 65 | # proportion of contributors will probably not be using SublimeText 66 | # *.sublime-project 67 | 68 | # sftp configuration file 69 | sftp-config.json 70 | 71 | 72 | ### Python ### 73 | # Byte-compiled / optimized / DLL files 74 | __pycache__/ 75 | *.py[cod] 76 | 77 | # C extensions 78 | *.so 79 | 80 | # Distribution / packaging 81 | .Python 82 | env/ 83 | build/ 84 | develop-eggs/ 85 | dist/ 86 | downloads/ 87 | eggs/ 88 | lib/ 89 | lib64/ 90 | parts/ 91 | sdist/ 92 | var/ 93 | *.egg-info/ 94 | .installed.cfg 95 | *.egg 96 | 97 | # PyInstaller 98 | # Usually these files are written by a python script from a template 99 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 100 | *.manifest 101 | *.spec 102 | 103 | # Installer logs 104 | pip-log.txt 105 | pip-delete-this-directory.txt 106 | 107 | # Unit test / coverage reports 108 | htmlcov/ 109 | .tox/ 110 | .coverage 111 | .cache 112 | nosetests.xml 113 | coverage.xml 114 | 115 | # Translations 116 | *.mo 117 | *.pot 118 | 119 | # Django stuff: 120 | *.log 121 | 122 | # Sphinx documentation 123 | build/ 124 | 125 | # PyBuilder 126 | target/ 127 | 128 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/TinTinUnofficialDocumentation.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/TinTinUnofficialDocumentation.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/TinTinUnofficialDocumentation" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/TinTinUnofficialDocumentation" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ================================= 2 | TinTin++ Unofficial Documentation 3 | ================================= 4 | Community maintained documentation for the `tintin++ mud client `_. 5 | 6 | - This project is published by the `Unofficial TinTin\+\+ User\'s Group `_ 7 | - The documentation available on `read the docs `_ 8 | 9 | .. image:: https://readthedocs.org/projects/tintinplusplus-unoffical-documentation/badge/?version=latest 10 | 11 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | set I18NSPHINXOPTS=%SPHINXOPTS% source 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\TinTinUnofficialDocumentation.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\TinTinUnofficialDocumentation.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /source/_static/terminal.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tintinplusplus/tintinplusplus-unoffical-documentation/d228e2de576b9a368ee3f03507aa342d8e3bda82/source/_static/terminal.ico -------------------------------------------------------------------------------- /source/_static/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tintinplusplus/tintinplusplus-unoffical-documentation/d228e2de576b9a368ee3f03507aa342d8e3bda82/source/_static/terminal.png -------------------------------------------------------------------------------- /source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # TinTin++ Unofficial Documentation documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Oct 4 11:53:56 2014. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 32 | 'sphinx.ext.todo', 33 | ] 34 | 35 | # Add any paths that contain templates here, relative to this directory. 36 | templates_path = ['_templates'] 37 | 38 | # The suffix of source filenames. 39 | source_suffix = '.rst' 40 | 41 | # The encoding of source files. 42 | #source_encoding = 'utf-8-sig' 43 | 44 | # The master toctree document. 45 | master_doc = 'index' 46 | 47 | # General information about the project. 48 | project = u'TinTin++ Unofficial Documentation' 49 | copyright = u'2014, Nathan Farrar' 50 | 51 | # The version info for the project you're documenting, acts as replacement for 52 | # |version| and |release|, also used in various other places throughout the 53 | # built documents. 54 | # 55 | # The short X.Y version. 56 | version = '0.1' 57 | # The full version, including alpha/beta/rc tags. 58 | release = '0.1' 59 | 60 | # The language for content autogenerated by Sphinx. Refer to documentation 61 | # for a list of supported languages. 62 | #language = None 63 | 64 | # There are two options for replacing |today|: either, you set today to some 65 | # non-false value, then it is used: 66 | #today = '' 67 | # Else, today_fmt is used as the format for a strftime call. 68 | #today_fmt = '%B %d, %Y' 69 | 70 | # List of patterns, relative to source directory, that match files and 71 | # directories to ignore when looking for source files. 72 | exclude_patterns = [] 73 | 74 | # The reST default role (used for this markup: `text`) to use for all 75 | # documents. 76 | #default_role = None 77 | 78 | # If true, '()' will be appended to :func: etc. cross-reference text. 79 | #add_function_parentheses = True 80 | 81 | # If true, the current module name will be prepended to all description 82 | # unit titles (such as .. function::). 83 | #add_module_names = True 84 | 85 | # If true, sectionauthor and moduleauthor directives will be shown in the 86 | # output. They are ignored by default. 87 | #show_authors = False 88 | 89 | # The name of the Pygments (syntax highlighting) style to use. 90 | pygments_style = 'sphinx' 91 | 92 | # A list of ignored prefixes for module index sorting. 93 | #modindex_common_prefix = [] 94 | 95 | # If true, keep warnings as "system message" paragraphs in the built documents. 96 | #keep_warnings = False 97 | 98 | 99 | # -- Options for HTML output ---------------------------------------------- 100 | 101 | # The theme to use for HTML and HTML Help pages. See the documentation for 102 | # a list of builtin themes. 103 | # html_theme = 'default' 104 | 105 | # on_rtd is whether we are on readthedocs.org 106 | import os 107 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True' 108 | 109 | if not on_rtd: # only import and set the theme if we're building docs locally 110 | import sphinx_rtd_theme 111 | html_theme = 'sphinx_rtd_theme' 112 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 113 | 114 | # Theme options are theme-specific and customize the look and feel of a theme 115 | # further. For a list of options available for each theme, see the 116 | # documentation. 117 | #html_theme_options = {} 118 | 119 | # Add any paths that contain custom themes here, relative to this directory. 120 | #html_theme_path = [] 121 | 122 | # The name for this set of Sphinx documents. If None, it defaults to 123 | # " v documentation". 124 | #html_title = None 125 | 126 | # A shorter title for the navigation bar. Default is the same as html_title. 127 | #html_short_title = None 128 | 129 | # The name of an image file (relative to this directory) to place at the top 130 | # of the sidebar. 131 | #html_logo = None 132 | html_logo = '_static/terminal.png' 133 | 134 | # The name of an image file (within the static path) to use as favicon of the 135 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 136 | # pixels large. 137 | #html_favicon = None 138 | html_favicon = '_static/terminal.ico' 139 | 140 | # Add any paths that contain custom static files (such as style sheets) here, 141 | # relative to this directory. They are copied after the builtin static files, 142 | # so a file named "default.css" will overwrite the builtin "default.css". 143 | html_static_path = ['_static'] 144 | 145 | # Add any extra paths that contain custom files (such as robots.txt or 146 | # .htaccess) here, relative to this directory. These files are copied 147 | # directly to the root of the documentation. 148 | #html_extra_path = [] 149 | 150 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 151 | # using the given strftime format. 152 | #html_last_updated_fmt = '%b %d, %Y' 153 | 154 | # If true, SmartyPants will be used to convert quotes and dashes to 155 | # typographically correct entities. 156 | #html_use_smartypants = True 157 | 158 | # Custom sidebar templates, maps document names to template names. 159 | #html_sidebars = {} 160 | 161 | # Additional templates that should be rendered to pages, maps page names to 162 | # template names. 163 | #html_additional_pages = {} 164 | 165 | # If false, no module index is generated. 166 | #html_domain_indices = True 167 | 168 | # If false, no index is generated. 169 | #html_use_index = True 170 | 171 | # If true, the index is split into individual pages for each letter. 172 | #html_split_index = False 173 | 174 | # If true, links to the reST sources are added to the pages. 175 | #html_show_sourcelink = True 176 | 177 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 178 | #html_show_sphinx = True 179 | 180 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 181 | #html_show_copyright = True 182 | 183 | # If true, an OpenSearch description file will be output, and all pages will 184 | # contain a tag referring to it. The value of this option must be the 185 | # base URL from which the finished HTML is served. 186 | #html_use_opensearch = '' 187 | 188 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 189 | #html_file_suffix = None 190 | 191 | # Output file base name for HTML help builder. 192 | htmlhelp_basename = 'TinTinUnofficialDocumentationdoc' 193 | 194 | 195 | # -- Options for LaTeX output --------------------------------------------- 196 | 197 | latex_elements = { 198 | # The paper size ('letterpaper' or 'a4paper'). 199 | #'papersize': 'letterpaper', 200 | 201 | # The font size ('10pt', '11pt' or '12pt'). 202 | #'pointsize': '10pt', 203 | 204 | # Additional stuff for the LaTeX preamble. 205 | #'preamble': '', 206 | } 207 | 208 | # Grouping the document tree into LaTeX files. List of tuples 209 | # (source start file, target name, title, 210 | # author, documentclass [howto, manual, or own class]). 211 | latex_documents = [ 212 | ('index', 'TinTinUnofficialDocumentation.tex', u'TinTin++ Unofficial Documentation Documentation', 213 | u'Nathan Farrar', 'manual'), 214 | ] 215 | 216 | # The name of an image file (relative to this directory) to place at the top of 217 | # the title page. 218 | #latex_logo = None 219 | 220 | # For "manual" documents, if this is true, then toplevel headings are parts, 221 | # not chapters. 222 | #latex_use_parts = False 223 | 224 | # If true, show page references after internal links. 225 | #latex_show_pagerefs = False 226 | 227 | # If true, show URL addresses after external links. 228 | #latex_show_urls = False 229 | 230 | # Documents to append as an appendix to all manuals. 231 | #latex_appendices = [] 232 | 233 | # If false, no module index is generated. 234 | #latex_domain_indices = True 235 | 236 | 237 | # -- Options for manual page output --------------------------------------- 238 | 239 | # One entry per manual page. List of tuples 240 | # (source start file, name, description, authors, manual section). 241 | man_pages = [ 242 | ('index', 'tintinunofficialdocumentation', u'TinTin++ Unofficial Documentation Documentation', 243 | [u'Nathan Farrar'], 1) 244 | ] 245 | 246 | # If true, show URL addresses after external links. 247 | #man_show_urls = False 248 | 249 | 250 | # -- Options for Texinfo output ------------------------------------------- 251 | 252 | # Grouping the document tree into Texinfo files. List of tuples 253 | # (source start file, target name, title, author, 254 | # dir menu entry, description, category) 255 | texinfo_documents = [ 256 | ('index', 'TinTinUnofficialDocumentation', u'TinTin++ Unofficial Documentation Documentation', 257 | u'Nathan Farrar', 'TinTinUnofficialDocumentation', 'One line description of project.', 258 | 'Miscellaneous'), 259 | ] 260 | 261 | # Documents to append as an appendix to all manuals. 262 | #texinfo_appendices = [] 263 | 264 | # If false, no module index is generated. 265 | #texinfo_domain_indices = True 266 | 267 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 268 | #texinfo_show_urls = 'footnote' 269 | 270 | # If true, do not generate a @detailmenu in the "Top" node's menu. 271 | #texinfo_no_detailmenu = False 272 | -------------------------------------------------------------------------------- /source/contents/01_about.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | About 3 | ===== 4 | This is an unofficial documentation resource for the TinTin++ client (hopefully a community effort). The documentation for TinTin++ is not automatically built and is severely out of date. Because user's (including myself) are constantly asking the same questions on the `tintin forums `_, I have attempted to document those features that cause the most issues here and lay the documentation out such that the starting sections begin with the questions and issues encountered by the newest users and the later sections are those encountered by more advanced users. 5 | 6 | The cookbook exists outside of this layout and consists of 'shorter' recipes to perform very specific tasks that are commonly inquired about on the forums. 7 | -------------------------------------------------------------------------------- /source/contents/02_features.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Features 3 | ======== 4 | Supplemental documentation for things that are either not obvious or undocumented. 5 | 6 | .. toctree:: 7 | :glob: 8 | :maxdepth: 2 9 | 10 | features/* 11 | -------------------------------------------------------------------------------- /source/contents/03_debugging.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | Debugging 3 | ========= 4 | Debugging in TinTin is like hitting yourself in the face over, and over, and over. It hurts. And makes you feel dumb. 5 | These are some debugging tricks I've learned along the way that help make it a little less painful. 6 | 7 | 8 | --------------------- 9 | Verbose Configuration 10 | --------------------- 11 | TinTin's verbosity can be increased for debugging purposes with the command:: 12 | 13 | #config {VERBOSE} {ON}; 14 | 15 | However, this will not apply to command files loaded with the read command. These will need to be explicitly loaded with the command:: 16 | 17 | #line verbose #read 18 | 19 | This will also increase the verbosity of the #DEBUG command, however that output always goes to the console and cannot be sent to a logfile. 20 | 21 | ----------------- 22 | Console Debugging 23 | ----------------- 24 | The included #DEBUG features provides some helpful data when needed. By default, debugging information is written the console and is enabled with:: 25 | 26 | #DEBUG {LIST} {ON}; 27 | 28 | To display all the debugging lists, use:: 29 | 30 | #DEBUG 31 | 32 | To enable all the debugging lists, use:: 33 | 34 | #DEBUG {ALL} {ON}; 35 | 36 | The verbosity of the debugging information can be increased by enabling verbose config:: 37 | 38 | #CONFIG {VERBOSE} {ON}; 39 | 40 | Unfortunately, output generated by #CONFIG {VERBOSE} {ON} cannot be sent to log files. 41 | 42 | 43 | ------------- 44 | Debug Logging 45 | ------------- 46 | You can log debugging output to a separate file:: 47 | 48 | #log APPEND debug.log; 49 | #debug {ALL} {LOG}; 50 | 51 | Note: #DEBUG's verbosity is increased by #CONFIG {VERBOSE} {ON} and will be sent to the log, but is also sent to the console. No way around this at present. 52 | 53 | 54 | ----------------------- 55 | Debugging Command Files 56 | ----------------------- 57 | If a command file is not behaving as expected - a useful debugging technique is to write the class out to a temporary file and review it. This very often exposes extremely common syntax errors - chunks of commands may be missing, identifying a position where to look for the source of the bug. 58 | 59 | 60 | ---------------- 61 | Extraneous Input 62 | ---------------- 63 | Sometimes you'll get the following message in your console when loading command files into the startup session:: 64 | 65 | #NO SESSION ACTIVE. USE: #session {name} {host} {port} TO START ONE. 66 | 67 | Essentially, this identifies that some command file loaded some configuration that malfunctioned and attempted to write some data to the session, rather than run as a command. Unfortunately the information is not displayed or logged, so identifying what it was and what caused it can be tricky. 68 | 69 | 70 | The following alias will capture all the extraneous input and write it to the console in bright colors:: 71 | 72 | #alias {%*} { 73 | #showme {MSG:INPUT %0}; 74 | } 75 | 76 | The downside to this technique is that it captures ALL input, that is not not a tintin command - all user defined commands, such as aliases and functions, will be captured and displayed rather than executed. This breaks most of my framework, so it's only useful on demand, and only after I've identified the immediate location of the malfunctioning code. 77 | 78 | 79 | ------------- 80 | ANSI Bleeding 81 | ------------- 82 | If colors are "bleeding", there is an included configuration setting that may resolve the issue:: 83 | 84 | #config {COLOUR PATCH} {ON}; 85 | 86 | 87 | 88 | ---------- 89 | References 90 | ---------- 91 | 92 | - `Adding Scope `_ 93 | - `Scope Tricks `_ 94 | - `Events Reading Closing Files `_ 95 | - `Debug Framework Weird Behavior `_ 96 | - `Verbose Classes `_ 97 | 98 | -------------------------------------------------------------------------------- /source/contents/04_pitfalls.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Pitfalls 3 | ======== 4 | Issues that commonly trip up users. 5 | 6 | 7 | ---------- 8 | Data Types 9 | ---------- 10 | The data type documentation is significantly lacking. The table data type is completely undocumented. I highly recommend making sure you understand them thoroughly first, as the parser is extremely particular about how data is stored and referenced - and will fail silently if anything is out of place. 11 | 12 | 13 | ------------------------- 14 | If Statement Terminations 15 | ------------------------- 16 | When a statement is on a line all by itself, you need to (in most cases) terminate it with a semicolon (;). This is sometimes not required for block statements, such as #IF statements:: 17 | 18 | #if { condition } { 19 | commands 20 | } 21 | 22 | The previous code works fine - most of the time. However, if this code is in an alias and that alias is called from within an #if block somewhere else, the code will break ... for that occurrence only. The practical solution is to terminate all these code blocks explicitly:: 23 | 24 | #if { condition } { 25 | commands 26 | }; 27 | 28 | 29 | --------------- 30 | Silent Failures 31 | --------------- 32 | When issuing #read commands from an alias, all debugging output is silenced, regardless of:: 33 | 34 | #CONIG {VERBOSE} ON; 35 | #DEBUG {ALL} ON; 36 | 37 | You will not see error messages from these files. This present a significant problem for me, as I do all my loading through my module manager. 38 | You can force verbose output by prefixing the #read commands with #line verbose. 39 | 40 | TODO: Test how #line log works with #line verbose. 41 | 42 | 43 | ------------------- 44 | Variable Collisions 45 | ------------------- 46 | There.is.no.scope. Variables using the same name in separate command files will overwrite each other. Beware. 47 | 48 | 49 | --------------- 50 | Quoting Strings 51 | --------------- 52 | When working with strings, quotes matter:: 53 | 54 | #showme "Test"; # yields "Test" 55 | #showme Test; # yields Test 56 | 57 | These values are not equivalent. Typically, strings remain unquoted. 58 | Note: This has tripped me up several times when passing data between the shell and tintin using #script. 59 | Note: In some contexts, for example `switch statements `_, strings MUST be quoted. 60 | 61 | 62 | ----------------- 63 | Switch Statements 64 | ----------------- 65 | Arguments in switch statements must be quoted, otherwise you'll get insane alias argument stack frame behavior. See "Quoted Strings" above. 66 | 67 | 68 | -------- 69 | Comments 70 | -------- 71 | If you don't terminate a #nop statement with a semicolon it will "absorb" the subsequent line:: 72 | 73 | #nop I'm just a comment 74 | #script { 75 | .... 76 | } 77 | 78 | In this example, the script tag will be commented out and silently fail to execute. 79 | 80 | 81 | ------------- 82 | Command Files 83 | ------------- 84 | Command files must start with a #tintin command. If they don't, they'll fail to load. If you're loading the file through an alias it will silently fail to load. 85 | To make sure this never happens, I start every file with: 86 | 87 | #nop VSOF; 88 | 89 | And regardless of how I modify my code, that line is never changed. 90 | Note: The error message displayed when this happens is "Invalid start of file." Hence VSOF (Valid Start of FIile). 91 | -------------------------------------------------------------------------------- /source/contents/05_cookbook.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Cookbook 3 | ======== 4 | How to do different types of things. 5 | 6 | .. toctree:: 7 | :glob: 8 | :maxdepth: 2 9 | 10 | cookbook/* 11 | -------------------------------------------------------------------------------- /source/contents/10_development.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Development 3 | =========== 4 | I'm trying to hack at the sphinx documentation a bit to add related content, integrated discussions via disqus, livereload support, and issue submission links for each page, so that an issue can be submit directly to the github issue tracker for documentation corrections. 5 | 6 | I've got some notes below on adding these features. 7 | 8 | 9 | --------------- 10 | Related Content 11 | --------------- 12 | Add support for page tags and automatic interlinking. This way recipes in the cookbook page could be tagged by "feature" and automatically included in the feature pages. 13 | 14 | - `Finding Related Content with Sphinx `_ 15 | - `Blogging with Sphinx `_ 16 | 17 | 18 | ------ 19 | Disqus 20 | ------ 21 | Add disqus support for integrated discussions on specific documentation pages. 22 | 23 | 24 | ----------- 25 | Live Reload 26 | ----------- 27 | Add livereload support for automatic rebuilding of local wiki while editing. 28 | 29 | - `Adding LiveReload Support to Sphinx `_ 30 | 31 | 32 | ------------- 33 | Github Issues 34 | ------------- 35 | Add links that allow users to directly submit github issues for documentation corrections. 36 | -------------------------------------------------------------------------------- /source/contents/11_contributing.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Contributing 3 | ============ 4 | I've invited all the TinTin++ user's on github that I know about to the organization, which should provide all of you (them) commit privileges. If I missed you, just sent a request to join the group `here `_. 5 | 6 | 7 | ------------- 8 | Documentation 9 | ------------- 10 | The `TinTin Unofficial Documentation `_ is built using sphinx, which uses python. To build a local version of the documentation that you can edit and publish, you'll need to install the necessary python dependencies first. There are lots of ways to do this, personally I like to use virtualenv and virtualenvwrapper to setup an isolated python environment:: 11 | 12 | pip install virtualenv virtualenvwrapper 13 | 14 | Then add the following to your shell initialization (.bashrc, .zshrc, etc) file:: 15 | 16 | if [[ -f '/usr/local/bin/virtualenvwrapper.sh' ]]; then 17 | export WORKON_HOME=$HOME/.virtualenvs 18 | export PROJECT_HOME=$HOME/Documents/Projects 19 | source /usr/local/bin/virtualenvwrapper.sh 20 | fi 21 | 22 | Then create the virtualenv and install the python requirements: 23 | 24 | mkvirtualenv mudfiles 25 | pip install -r requirements.txt 26 | 27 | And finally build your local copy of the documentation (from docs/):: 28 | 29 | make clean && make html && chrome build/html/index.html 30 | 31 | Once you've make your modifications, if you've got commit privileges, just push your updates. Otherwise, submit a `pull request `_. 32 | 33 | --------- 34 | RTD Theme 35 | --------- 36 | The docs use the `sphinx rtd theme `_. I've modified the sphinx config.py to use this theme when building locally as well. To build locally, you'll need to install the them via pip (this is done automatically when you install the requirements). 37 | 38 | I'm not sure yet, but I may need to fork the theme to setup the additional features on the :doc:`10_development` page. 39 | 40 | References: 41 | 42 | - `Read The Docs Theme Documentation `_ 43 | -------------------------------------------------------------------------------- /source/contents/cookbook/class-guards.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Class Guards 3 | ============ 4 | When storing configuration and settings in command files, you can wrap them in "class guards" to ensure that the old code is destroyed each time the is reloaded:: 5 | 6 | #class {MYCLASS} {kill}; 7 | #class {MYCLASS} {open}; 8 | ... 9 | #class {MYCLASS} {close}; 10 | -------------------------------------------------------------------------------- /source/contents/cookbook/clear-console.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Clear Console 3 | ============= 4 | The following alias uses tput to clear the console from within tintin:: 5 | 6 | #alias {clear} { 7 | #system {tput clear}; 8 | }; 9 | -------------------------------------------------------------------------------- /source/contents/cookbook/executing-code-in-all-sessions.rst: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Executing Code in All Sessions 3 | ------------------------------ 4 | Tintin includes the #ALL command for executing code in all sessions (#help all). Simply prefix #ALL to the command you want to execute in all sessions to use it:: 5 | 6 | #all #showme $session[name]; 7 | -------------------------------------------------------------------------------- /source/contents/cookbook/parsing-tables-by-reference.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Parsing Tables by Reference 3 | =========================== 4 | Through "passing by reference" it's possible to parse a table without knowing it's structure beforehand. First, we'll create our example data structure:: 5 | 6 | #var V1.T1 {{T1K1}{T1V1}{T1K2}{T1V2}}; 7 | #var V1.T2 {{T2K1}{T2V1}{T2K2}{T2V2}}; 8 | 9 | Next, we create a variable that contains the name of the variable that contains our tables:: 10 | #var table_index V1; 11 | 12 | Now we get a list of those tables. Note that we are using the "pass by reference" technique to operate on a dynamic variable name:: 13 | 14 | #var tables ${$table_index}[]; 15 | 16 | Now, we need to iterate over the tables. We've successfully abstracted ourselves away from operating on a specific table, so this will parse any set of tables stored in a nested variable:: 17 | 18 | #foreach {$tables} {table} { 19 | #var table {${$table_index}[$table]}; 20 | #foreach {$table[]} {index} { 21 | #showme $index:$table[$index]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /source/contents/cookbook/passing-by-reference.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Passing by Reference 3 | ==================== 4 | Even though we don't have address or dereferencing operators in tintin, we can still emulate some very basic referential operations:: 5 | 6 | #var myvar {mydata}; 7 | #var mypointer {myvar}; 8 | 9 | #showme $mypointer:${$mypointer}; 10 | > myvar:mydata 11 | 12 | #alias myalias { 13 | #showme value of "dereferenced" alias argument: ${%1}; 14 | } 15 | myalias myvar; 16 | > value of "dereferenced" alias argument: mydata 17 | 18 | #function myfunction { 19 | #return $%1 20 | }; 21 | 22 | #showme valued of "dereferenced" function argument: @myfunction{myvar}; 23 | > value of "dereferenced" function argument: mydata 24 | -------------------------------------------------------------------------------- /source/contents/cookbook/read-verbose-with-flag.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Read Verbose with Flag 3 | ====================== 4 | Even with #CONFIG VERBOSE ON and #DEBUG ALL enabled, this output is still suppressed if #read is called from within an alias. 5 | We can get around this by prefixing the #READ command with #LINE VERBOSE. Unfortunately, if you have lots of files being read, 6 | then each time you want to enable this globally, you have to modify it throughout your entire configuration. 7 | 8 | To make this a little more user-friendly, we can wrap the #read command in an alias that issues the command based on a global flag:: 9 | 10 | #var READ_VERBOSE 1; 11 | #alias read { 12 | #if { "$READ_VERBOSE" == "0" } {#read %1}; 13 | #else {#line verbose #read %1}; 14 | } 15 | -------------------------------------------------------------------------------- /source/contents/cookbook/reload-command-file.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Reload Command File 3 | =================== 4 | When testing code, it's desirable to be able to run the same code over and over after making small changes. I add the following alias to my "test" command files when to make this very fast:: 5 | 6 | #alias reload { 7 | #kill {all}; 8 | #showme Reloading ...; 9 | #read thisfile.tin; 10 | } 11 | 12 | NOTE: The reloading is taking place inside of an alias, so verbose output will be disabled. 13 | -------------------------------------------------------------------------------- /source/contents/cookbook/string-get-length.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Find the Length of a String 3 | =========================== 4 | Find the length of a string:: 5 | 6 | #var thestring {something here} 7 | #format resultvar {%L} {$thestring} 8 | #echo {$resultvar} 9 | 10 | References: 11 | - `Finding the length of a string `_ 12 | -------------------------------------------------------------------------------- /source/contents/cookbook/string-repeat-character.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Repeating Characters 3 | ==================== 4 | To repeat a character a dynamic number of times:: 5 | 6 | #var cnt 30; 7 | #format tmp %+${cnt}s; 8 | #replace tmp { } {-}; 9 | 10 | References: 11 | - `Repeat a character `_ 12 | -------------------------------------------------------------------------------- /source/contents/cookbook/string-split-by-num-chars.rst: -------------------------------------------------------------------------------- 1 | ================================================ 2 | Splitting a string by a set number of characters 3 | ================================================ 4 | Split a string into an array based on a set string length:: 5 | 6 | #format {test} {%w} {string} 7 | 8 | Or use #regex to grab 80 or any number of characters at a time and split it. 9 | 10 | References: 11 | - `Split string into an array by width `_ 12 | -------------------------------------------------------------------------------- /source/contents/cookbook/variable-table-indexes.rst: -------------------------------------------------------------------------------- 1 | ======================================== 2 | Retrieving Table Indexes from a Variable 3 | ======================================== 4 | Retrieve a list of indexes from any reference point within a nested variable you must use the table index operator "[]":: 5 | 6 | #var MODULES { 7 | {module} { {loaded} {1} {path} {modules/module/__init__.tin} } 8 | {profile} { {loaded} {1} {path} {modules/profile/__init__.tin} } 9 | {session} { {loaded} {1} {path} {modules/session/__init__.tin} } 10 | }; 11 | 12 | #showme $MODULES[]; 13 | {module}{profile}{session} 14 | 15 | Note: You cannot retrieve this list of indexes and store them in a variable, they will be parsed as a table rather than a brace delimited list. The only place this works is within the context of a #foreach loop input. 16 | -------------------------------------------------------------------------------- /source/contents/cookbook/variable-test-existence.rst: -------------------------------------------------------------------------------- 1 | ======================================= 2 | Testing for the Existence of a Variable 3 | ======================================= 4 | To test for the existence of a variable:: 5 | 6 | #if {&MYVAR} { #showme $$MYVAR EXISTS }; 7 | #else { #showme $$MYVAR DOES NOT EXIST }; 8 | 9 | -------------------------------------------------------------------------------- /source/contents/features/01_sessions.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Sessions 3 | ======== 4 | 5 | 6 | ------------------- 7 | The Startup Session 8 | ------------------- 9 | The startup session is created at default. It's named gts (per #help session) and can be referenced with #gts, just as you would reference a character's session. Any code from command files loaded on startup is executed in this session. 10 | 11 | There are probably other interesting things about #gts, but I don't know them. 12 | 13 | 14 | ------------------- 15 | Session Inheritance 16 | ------------------- 17 | When creating a new session - the entire config from the startup session is copied into the new session. This is important if you play multiple sessions at the same time - you don't want to copy character A's data into a session for character B. 18 | 19 | It is also important to note that the copy of the data does not reference the original session in any way - it's a brand new copy. Once the new session has been established, changing the data in either session will not affect the copy of the data in the other. 20 | 21 | If you use a "session API" (ttlib includes one), then this can be confusing at first. When I load the program, all my session management code is copied into the GTS session. When I create a new session, that code gets copied into the characters session. I can then use the session API from the characters session, however it will contain different variables than those in the #GTS session. 22 | 23 | 24 | ---------- 25 | References 26 | ---------- 27 | 28 | - `The All Command `_ 29 | - `The Session Command `_ 30 | -------------------------------------------------------------------------------- /source/contents/features/02_datatypes.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Data Types 3 | ========== 4 | There are several different data types in tintin, several of which are undocumented. They must be used in specific ways that vary by context, so it can get tricky: 5 | 6 | - Simple variables: The basic building block for all data types. 7 | - String lists: A simple variable, used in the context of a foreach loop that contains semicolon delimited fields. 8 | - Brace lists: A brace delimited type that is only valid in the context of a foreach loop input. 9 | - Nested variables: A variable containing another variable. Try not to think of this as arrays, this will lead you to dark places. 10 | - Lists: A complex data type that uses integers for it's indexes. An API is provided for working with this data type. 11 | - Tables: A complex data type consisting of name/value pairs. 12 | 13 | 14 | ---------------- 15 | Simple Variables 16 | ---------------- 17 | A simple variable:: 18 | 19 | #var SIMPLE_VARIABLE value; 20 | 21 | These are self explanatory, enough said. 22 | 23 | 24 | ------------------ 25 | Removing Variables 26 | ------------------ 27 | To remove a variable, use #unvariable (or #unvar). 28 | When planning out your data storage, keep in mind that you can deeply nest variables & tables in the same "root" variable, then remove the entire thing at once, using #unvar nested_data; 29 | 30 | You cannot remove multiple variables at once, i.e:: 31 | 32 | #unvar var1 var2 var3; 33 | 34 | You must remove them individually:: 35 | 36 | #unvar var1; 37 | #unvar var2; 38 | #unvar var3; 39 | 40 | This is worth considering when you design your data structures. 41 | 42 | 43 | ------------ 44 | String Lists 45 | ------------ 46 | A string list is a simple variable that contains a string with semicolons that can be interpretted in the context of a foreach loop. From #help foreach:: 47 | 48 | #foreach {bob;tim;kim} {name} {tell $name Hello} 49 | 50 | 51 | ----------- 52 | Brace Lists 53 | ----------- 54 | Brace lists confused me pretty bad. They are only valid in the context of a forloop and cannot be stored in a variable. Again, from #help foreach:: 55 | 56 | #foreach {{bob}{tim}{kim}} {name} {tell $name Hello} 57 | 58 | The format for these lists is extremely similar to that of a "table" (more on tables later). 59 | 60 | If you attempt to use the brace list syntax outside of the context of a forloop input, you'll get confusing behavior:: 61 | 62 | #var list {{bob}{tim}{kim}}; 63 | #OK. VARIABLE {list} HAS BEEN SET TO {{bob}{tim}{kim}{}}. 64 | 65 | The parser created the "list" but added an extra {} at the end. This is because the parser is interpreting the input as a table, and tables store key/value pairs. So to recap - you cannot create "brace lists" outside of the scope of a #foreach input. 66 | 67 | ---------------- 68 | Nested Variables 69 | ---------------- 70 | Variables can be nested using either "array" or "dot" syntax. Both of the following forms are syntactically correct:: 71 | 72 | #var {V1.N1.N2} {VALUE}; 73 | > #VARIABLE {V1}={{N1}{{N2}{VALUE}}} 74 | 75 | #var {V2[N1][N2]} {VALUE}; 76 | > #VARIABLE {V2}={{N1}{{N2}{VALUE}}} 77 | 78 | Note the syntax, it's important. The exploded representation:: 79 | 80 | #VAR V1 81 | { 82 | {N1} 83 | { 84 | {N2}{VALUE} 85 | } 86 | } 87 | 88 | Each "nested" variable is encapsulated with an extra set of braces. 89 | Note: I've run into some situations where whitespace in nested variables and tables matter, so don't define them in your code using the exploded form above (no extra whitespace!). 90 | 91 | You can retrieve the values from nested lists using either syntax:: 92 | 93 | #showme $V1.N1.N2; 94 | > VALUE 95 | 96 | #showme $V1[N1][N2]; 97 | > VALUE 98 | 99 | And in some cases (though I don't know why you'd want to) you can mix the "array" and "dot" syntax:: 100 | 101 | #nop This works.; 102 | #showme $V1.N1[N2]; 103 | > VALUE 104 | 105 | #nop This does not work.; 106 | #showme $V1[N1].N2}; 107 | > {N2}{VALUE}.N2}; 108 | 109 | ----- 110 | Lists 111 | ----- 112 | Lists are essentially integer indexed arrays:: 113 | 114 | #list list add item1; 115 | #list list add item2; 116 | #list list add item3; 117 | #list list add item4; 118 | > #VARIABLE {list}={{1}{item1}{2}{item2}{3}{item3}{4}{item4}} 119 | 120 | Note that the order is preserved in a list:: 121 | 122 | #list list add item0; 123 | > #VARIABLE {list}={{1}{item1}{2}{item2}{3}{item3}{4}{item4}{5}{item0}} 124 | 125 | You can add multiple values to a list at once, note that they are whitespace delimited:: 126 | 127 | #list list add item1 item2 item3 item4; 128 | > #VARIABLE {list}={{1}{item1}{2}{item2}{3}{item3}{4}{item4}} 129 | 130 | Like (just about) everything in tintin, you can disable whitespace delimiting by using explicit braces:: 131 | 132 | #list list add {this is a sentance} 133 | > #VARIABLE {list}={{1}{this is a sentance}} 134 | 135 | NOTE: I haven't used these types of lists as much as nested variables and tables, so I'm unsure if forcing whitespace into items will break the API. 136 | For more information about lists, see #help list. 137 | 138 | Tables 139 | ====== 140 | Tables are key/value pairs, stored in variables. They are undocumented, but very powerful:: 141 | 142 | #var {T1} {{K1}{V1}{K2}{V2}}; 143 | > #VARIABLE {T1}={{K1}{V1}{K2}{V2}} 144 | 145 | Notice that the parser writes these differently than it writes nested variables. They are different, and handled differently. They are however stored exactly the same as lists, but with string-based indexes, rather than integers. 146 | 147 | Tables are automagically sorted. If you need to preserve the order, you'll have to use another data type. AFAIK, there's no way around this:: 148 | 149 | #var {T1} {{K2}{V2}{K1}{V1}}; 150 | > #VARIABLE {T1}={{K1}{V1}{K2}{V2}} 151 | 152 | Values can be inserted into tables using either "array" or "dot" notation:: 153 | 154 | #var T1[K1] V1; 155 | > #VARIABLE {T1}={{K1}{V1}} 156 | 157 | #var T1.K1 V1; 158 | > #VARIABLE {T1}={{K1}{V1}} 159 | 160 | This is exactly the same syntax as the "nested" variables referenced above. The only difference is that we can shove multiple key/value pairs into a single variable:: 161 | 162 | #var T1.K1 V1; 163 | #var T1.K2 V2; 164 | > #VARIABLE {T1}={{K1}{V1}{K2}{V2}} 165 | 166 | Note: While the data in the variable looks like a "brace delimited list", it is not. Don't get confused on this, it caused me great trouble. This form is ONLY used for storing key value pairs. 167 | 168 | 169 | When referencing a table stored in a variable, we can pull out a list of the indexes using a special "[]" operator that's only valid for this purpose in this context:: 170 | 171 | #showme $T1[]; 172 | > {K1}{K2} 173 | 174 | We can store tables in any value inside a nested variable:: 175 | 176 | #var V1.N1.T1 {{K1}{V1}{K2}{V2}}; 177 | > #VARIABLE {V1}={{N1}{{T1}{{K1}{V1}{K2}{V2}}}} 178 | 179 | And retrieve it:: 180 | 181 | #showme $V1.N1.T1; 182 | > {K1}{V1}{K2}{V2} 183 | 184 | To iterate over the values, we have to be careful:: 185 | 186 | #foreach {$V1.N1.T1} {table} { 187 | #showme $table; 188 | } 189 | > K1 190 | > V1 191 | > K2 192 | > V2 193 | 194 | Referencing it this way in the #foreach loop input causes the parser to interpret the table as a brace list (remember above?). Not the behavior we want. 195 | 196 | To iterate over the table correctly, we need to use the special "[]" operator mentioned above:: 197 | 198 | #foreach {$V1.N1.T1[]} {table} { 199 | #showme $table; 200 | } 201 | > K1 202 | > K2 203 | 204 | We can store multiple tables in a nested variable:: 205 | 206 | #var V1.N1.T1 {{T1K1}{T1V1}{T1K2}{T1V2}}; 207 | #var V1.N1.T2 {{T2K1}{T2V1}{T2K2}{T2V2}}; 208 | > #VARIABLE {V1}={{N1}{{T1}{{T1K1}{T1V1}{T1K2}{T1V2}}{T2}{{T2K1}{T2V1}{T2K2}{T2V2}}}} 209 | 210 | 211 | To get a list of our tables stored in N1, we can use:: 212 | #showme $V1.N1[]; 213 | > {T1}{T2} 214 | 215 | However, we have to be careful how we attempt to iterate over them. The following gives us the name of each table, a newline, and then the table content:: 216 | 217 | #foreach {$V1.N1} {table} { 218 | #showme $table; 219 | } 220 | > T1 221 | > {T1K1}{T1V1}{T1K2}{T1V2} 222 | > T2 223 | > {T2K1}{T2V1}{T2K2}{T2V2} 224 | 225 | To just get the name, we have to use our "[]" operator:: 226 | 227 | #foreach {$V1.N1[]} {table} { 228 | #showme $table; 229 | } 230 | > T1 231 | > T2 232 | 233 | As far as I know, there is no way to pull the data for each table directly out. This requires a little more effort, though we can use the following syntax to accomplish the task:: 234 | 235 | #foreach {$V1.N1[]} {table} { 236 | #foreach {$V1.N1[$table][]} {key} { 237 | #showme $table:$key:$V1.N1[$table][$key] 238 | } 239 | } 240 | > T1:T1K1:T1V1 241 | > T1:T1K2:T1V2 242 | > T2:T2K1:T2V1 243 | > T2:T2K2:T2V2 244 | 245 | The syntax for the foreach input fields above is extremely picky. I played around with several variations using dots and braces, and this was the one I found that works. 246 | 247 | 248 | ---------- 249 | References 250 | ---------- 251 | - `The Variable Command `_ 252 | - `The List Command `_ 253 | - `Retrieving Keys from an associative lists `_ 254 | - `Working with associative lists `_ 255 | - `Stumped Nested List `_ 256 | - `Forcing Variable Substitution `_ 257 | - `Help with List Issues `_ 258 | 259 | ----- 260 | Notes 261 | ----- 262 | TODO: Add information about checking for variable and index existence (&). 263 | TODO: Add notes on escaping periods in variable names (#var LOGFILE data/log/$ISODATE.log;). 264 | -------------------------------------------------------------------------------- /source/contents/features/03_command-files.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Command Files 3 | ============= 4 | Commands can be placed in files (known as command files). 5 | 6 | 7 | --------------------- 8 | Reading Command Files 9 | --------------------- 10 | Reading and then read into TinTin using two basic methods:: 11 | 12 | #class {} {read} {} 13 | #read {filename} 14 | 15 | The #class {read} {filename} command is basically shorthand for: 16 | 17 | #class {name} {open}; 18 | #read {filename}; 19 | #class {close}; 20 | 21 | Using the #class {read} {filename} method imposes some limitations on us: 22 | 23 | 1. Everything in the file will be part of the class (we can't mix non-class code in a file read in this way). 24 | 2. We don't explicitly remove the existing data before reading it in, therefore unexpected results can occur (if reloading command files on the fly). 25 | 26 | I prefer the more flexible approach (using the #read command with explicit #class commands) as described next. 27 | 28 | 29 | --------------- 30 | Execution Order 31 | --------------- 32 | Command files can load each other. When they do, the command file is immediately read and the commands are immediately executed as soon as #read statement is encountered. The following scripts demonstrate this behavior:: 33 | 34 | #nop init.tin; 35 | 36 | #showme {DEBUG:INIT Start of init.tin.}; 37 | 38 | #alias read { 39 | #showme {DEBUG:INIT:READ Reading %1.}; 40 | #line verbose #read %1; 41 | } 42 | 43 | #showme {DEBUG:INIT Just before read alias commands.}; 44 | 45 | read module1.tin; 46 | read module2.tin; 47 | 48 | #showme {DEBUG:INIT Just after read alias commands.}; 49 | 50 | #showme {DEBUG:INIT Reading module3.tin started.}; 51 | #read module3.tin; 52 | #showme {DEBUG:INIT Reading module3.tin completed.}; 53 | 54 | 55 | #nop module1.tin; 56 | #showme {DEBUG:MODULE1: Inside of module1.tin.}; 57 | 58 | #nop module2.tin; 59 | #showme {DEBUG:MODULE2: Inside of module2.tin.}; 60 | 61 | #nop module3.tin; 62 | #showme {DEBUG:MODULE3: Inside of module3.tin.}; 63 | 64 | When we execute init.tin with:: 65 | 66 | tt++ -v -r init.tin 67 | 68 | We see the following output:: 69 | 70 | #CONFIG {VERBOSE} HAS BEEN SET TO {ON}. 71 | #CONFIG {TINTIN CHAR} HAS BEEN SET TO {#}. 72 | DEBUG:INIT Start of init.tin. 73 | #CONFIG {COMMAND ECHO} HAS BEEN SET TO {ON}. 74 | #CONFIG {VERBOSE} HAS BEEN SET TO {ON}. 75 | #OK. {reload} NOW ALIASES {#system {tput clear};#kill {all};#read init.tin;} @ {5}. 76 | #OK. {read} NOW ALIASES {#showme {DEBUG:INIT:READ Reading %1.};#line verbose #read %1;} @ {5}. 77 | DEBUG:INIT Just before read alias commands. 78 | DEBUG:INIT:READ Reading module1.tin. 79 | #CONFIG {TINTIN CHAR} HAS BEEN SET TO {#}. 80 | DEBUG:MODULE1: Inside of module1.tin. 81 | DEBUG:INIT:READ Reading module2.tin. 82 | #CONFIG {TINTIN CHAR} HAS BEEN SET TO {#}. 83 | DEBUG:MODULE2: Inside of module2.tin. 84 | DEBUG:INIT Just after read alias commands. 85 | DEBUG:INIT Reading module3.tin started. 86 | #CONFIG {TINTIN CHAR} HAS BEEN SET TO {#}. 87 | DEBUG:MODULE3: Inside of module3.tin. 88 | DEBUG:INIT Reading module3.tin completed. 89 | -------------------------------------------------------------------------------- /source/contents/features/04_loops.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | Loops 3 | ===== 4 | There are six commands in tintin for implementing different sorts of "loop" behavior: 5 | 6 | 1. Foreach: For each item in the specified list, retrieve the value and execute some command(s). 7 | 2. Forall: For all items in the specified list, execute some command. This command appears to be identical (except for the "goblin" syntax) to the #foreach command. 8 | 3. Loop: Loop from and to specified indexes (a traditional for loop). 9 | 4. While: Execute a set of command(s) until a specified condition is met. 10 | 5. Parse: Iterate over a string and for each character, execute some command. 11 | 6. Repeat: Execute some command a specified amount of times. 12 | 13 | There are also two flow-control commands that can be used to alter the flow of the loops (though they appear to have identical behavior): 14 | 15 | 1. Break: Stop executing the current loop and resume execution at the end of the loop's control structure. 16 | 2. Continue: Stop executing the current loop and resume execution at the end of the loop's control structure. 17 | 18 | ------- 19 | Goblins 20 | ------- 21 | I honestly can't think of a better name "looping through lists" in TinTin. The syntax is completely nonstandard and doesn't fit into the same context as anything else in TinTin++. 22 | I can never remember the syntax and have to look it up each time I write one. 23 | 24 | From the foreach page of the official manual: 25 | > To loop through all items in a list (or a nested variable) using the foreach command use $[%*]. 26 | 27 | The forall loop uses a special "goblin" syntax for referencing the value of the current item: "&0". 28 | 29 | Examples 30 | ======== 31 | Example syntax:: 32 | 33 | #foreach {$mylist[%*]} {value} { 34 | #showme {$value}; 35 | }; 36 | 37 | #forall {$mylist[%*]} { 38 | #showme &0; 39 | }; 40 | 41 | #loop {1} {5} {i} { 42 | #showme {$mylist[$i]}; 43 | }; 44 | 45 | #var {i} {5}; 46 | #while {$i > 0} { 47 | #showme {$mylist[$i]}; 48 | #math {cnt} {$cnt - 1}; 49 | }; 50 | 51 | #parse {a string of characters} {c} {#showme $c}; 52 | 53 | #10 #showme {repeat}; 54 | 55 | References 56 | ========== 57 | 58 | - `The Break Command `_ 59 | - `The Continue Command `_ 60 | - `The Forall Command `_ 61 | - `The Foreach Command `_ 62 | - `The Loop Command `_ 63 | - `The Parse Command `_ 64 | - `The Repeat Command `_ 65 | - `The While Command `_ 66 | - `Stumped on Nested List `_ 67 | - `Retrieving keys from associative array variables `_ 68 | - `Iterating Lists with foreach `_ 69 | - `how do same thing like ismember `_ 70 | -------------------------------------------------------------------------------- /source/contents/features/05_colors.rst: -------------------------------------------------------------------------------- 1 | ====== 2 | Colors 3 | ====== 4 | NOTE: This page is incomplete. 5 | 6 | 7 | References: 8 | - `RGB Colour Conversion `_ 9 | - `Colour Questions `_ 10 | -------------------------------------------------------------------------------- /source/contents/features/06_tab-completion.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Tab Completion 3 | ============== 4 | Tab completion does not work for commands with whitespace, the following script demonstrates this behavior:: 5 | 6 | #nop Our "nested" tab completions.; 7 | #tab module list; 8 | #tab module load; 9 | #tab module kill; 10 | #tab module reload; 11 | 12 | #nop Our primary API alias. Calls the correct aliases for us based on the ; 13 | #nop initial arguments; 14 | #alias module { 15 | 16 | #showme ALIAS: module; 17 | 18 | #if {"%1" == "list"} {moduleList}; 19 | #elseif {"%1" == "load"} {moduleLoad %2}; 20 | #elseif {"%1" == "kill"} {moduleKill %2}; 21 | #elseif {"%1" == "reload"} {mdouleReload %2}; 22 | #else { 23 | #showme ERROR: Usage: module list | load | kill | reload ; 24 | }; 25 | } 26 | 27 | #nop Some stub aliases.; 28 | #alias moduleList {#showme moduleList}; 29 | #alias moduleLoad {#showme moduleLoad %1}; 30 | #alias moduleKill {#showme moduleKill %1}; 31 | #alias moduleReload {#showme moduleReload %1}; 32 | 33 | This results in the following tab completions:: 34 | 35 | mod 36 | module kill 37 | module mod 38 | module module kill 39 | module module mod 40 | ... etc 41 | -------------------------------------------------------------------------------- /source/contents/features/07_shell-integration.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Shell Integration 3 | ================= 4 | There are several commands provided in TinTin to facilitate shell integration: 5 | 6 | - #script {variable} {shell command} 7 | - #run {session name} {shell command} 8 | - #system {command name} 9 | 10 | ----- 11 | Notes 12 | ----- 13 | NOTE: This page is incomplete. 14 | TODO: Add detailed notes about #script (out of these commands I understand it the best). 15 | -------------------------------------------------------------------------------- /source/contents/features/08_mapper.rst: -------------------------------------------------------------------------------- 1 | ====== 2 | Mapper 3 | ====== 4 | TinTin's mapper is the best available. It's the reason why TinTin is so popular, even after all these years. 5 | 6 | .. toctree:: 7 | :glob: 8 | :maxdepth: 2 9 | 10 | mapper/* 11 | -------------------------------------------------------------------------------- /source/contents/features/09_autologin.rst: -------------------------------------------------------------------------------- 1 | Autologin 2 | ======== 3 | 4 | A typical feature of every config: game autologin. Usually it looks like this: 5 | 6 | :: 7 | 8 | #event {SESSION_CONNECTED} { 9 | #showme {CONNECTED: %0}; 10 | #regex {%0} {^sessionname$} {CONNECT name password} {0}; 11 | } 12 | 13 | * ``sessionname`` is the name of your session you will use in the ``#session`` command 14 | * ``CONNECT name password`` is the autologin command. Some MUDs understand only username and password, so you have to write: ``username\npassword`` instead. 15 | 16 | This snippet activates on session connect. It checks the session name and sends the autologin command. 17 | -------------------------------------------------------------------------------- /source/contents/features/mapper/01_getting-started.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Getting Started 3 | =============== 4 | 5 | 6 | -------------- 7 | Creating a Map 8 | -------------- 9 | To create a map, use:: 10 | 11 | #map create 12 | 13 | The size argument specifies the maximum number of rooms the map can hold (this can be increased later, if necessary). I do not believe the maximum number of rooms affects the map performance (though the actual number of rooms absolutely does), so I typically create my maps with a very large number of maximum rooms (1,000,000). If no size is specified, the default value of 50,000 is used. 14 | 15 | 16 | -------------------------------- 17 | Modifying the Maximum Room Count 18 | -------------------------------- 19 | To modify the maximum number of rooms, use:: 20 | 21 | #map resize 22 | 23 | I haven't ever had to do this, because I always create my maps with a starting size of 1,000,000 rooms (and I haven't gone over this number). As mentioned above, the maximum number of rooms does not affect map performance, so there are no drawbacks to doing this. 24 | 25 | 26 | ---------------- 27 | Destroying a Map 28 | ---------------- 29 | A map that is loaded can be destroyed with the command:: 30 | 31 | #map destroy 32 | 33 | This will remove it from memory and make us leave the map, but it will not affect a map file from which the map was loaded. 34 | 35 | This is useful if you've read a map file into memory, made some mistakes, and want to start fresh. 36 | 37 | 38 | --------------------------- 39 | Temporarily Leaving the Map 40 | --------------------------- 41 | We can exit the map without destroying it (leaving it loaded in memory) with the command:: 42 | 43 | #map leave 44 | 45 | This is useful when entering a maze or another room where the mapper will not work correctly. 46 | 47 | 48 | ------------------------ 49 | Saving the Map to a File 50 | ------------------------ 51 | Once a map has been created in memory it can be saved for later use with:: 52 | 53 | #map write 54 | 55 | Be very careful when saving your map files, this command will overwrite any file without warning. I have done this in the past (after a long session and very tired). I accidentally overwrote my command file rather than updating the map file. 56 | 57 | To ensure this doesn't happen, I recommend creating an alias that always saves the file to the same place:: 58 | 59 | #alias mapsave { 60 | #showme "Map saved."; 61 | #map write mymap.map; 62 | } 63 | 64 | Two other tips when saving map files: 65 | 66 | - You can make your map save alias automatically backup the previous map first using the #script command. 67 | - You can setup automatic map saving using the #ticker command. 68 | 69 | 70 | --------------------------- 71 | Loading the Map from a File 72 | --------------------------- 73 | Maps that have been saved to a file can be loaded with the command:: 74 | 75 | #map read 76 | 77 | Just like the #map create command, this will not automatically insert you into the map. 78 | 79 | 80 | ------------------------------- 81 | Setting Our Position in the Map 82 | ------------------------------- 83 | To set our position in the map, use the command:: 84 | 85 | #map goto 86 | 87 | This will tell the mapper that we are at position in the map. The goto command does not send any commands to the mud and therefore does not actually move us around. This is strictly used for telling the mapper where our position is. 88 | 89 | If our map file is empty, the goto command will create the first room in the map. Once our map is populated, we can set our position to any room in the map using this command. Again, this doesn't actually move our character on the mud - it tells the mapper where our position in the map is. 90 | 91 | This is mostly used when our actual position gets out of sync from where the mapper believes we are. 92 | 93 | A quick note about vnums: 94 | Vnum's are unique integer's that function as an index for each room in our map file. When starting with an empty map (right after #map create, or if using #map read on an empty file), we have no rooms, so this will create the first. 95 | 96 | ------------------ 97 | Displaying the Map 98 | ------------------ 99 | If you've gone through this far, you're probably wondering where the map is. There are an infinite amount of ways to display the map, but we're only going to cover the most basic methods here. 100 | 101 | The most basic way to display the map is through the command:: 102 | 103 | #map map 104 | 105 | This command is used in other ways as well, but for our purposes right now, this will display the map. 106 | Of course, we don't want to have to type a command each time we want to display the map, we'd rather have always be displayed and updated. 107 | 108 | Again, there are lots of ways to do this, and we're just going to cover the most basic here. 109 | TinTin provides a #split command, that allows us to split the screen. This is used for two primary purposes: 110 | 111 | 1. Separating the input field from the buffer 112 | 2. A very simple map display. 113 | 114 | We're going to use it for both:: 115 | 116 | #split 16 1 117 | 118 | You should now have a separate input field and 16 dashed lines at the top of the terminal window. In order to display the maps in the split, we need to use the command:: 119 | 120 | #map flag vtmap on 121 | 122 | The #map flag vtmap on command takes advantage of this split to draw the map, only if the split is created and the flag is enabled. The map it draws is 16 rows high, and I don't believe there is a way to change this. Setting a larger height for the top split results in additional empty rows being displayed, but not a larger map display area. 123 | 124 | After creating the splits, the buffer window is drawn differently than before. If you attempt to scroll up, you're going to see the buffer content you're looking for. Depending on your terminal you may need to use a different combination of keys to scroll correctly. On my OS X system in iTerm2, this is the function and up/down arrows. 125 | 126 | ---------------- 127 | Updating the Map 128 | ---------------- 129 | If you move around, you'll notice that the map is not updated - this is because the #map flag static flag is set and no other rooms exists (assuming you've got a brand new map with only 1 room). 130 | 131 | We can disable this flag with the command:: 132 | 133 | #map flag static off 134 | 135 | Now if you move around, you'll see that new rooms are created. 136 | -------------------------------------------------------------------------------- /source/contents/features/mapper/02_editing-maps.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Editing the Map 3 | =============== 4 | 5 | --------------- 6 | Dynamic Mapping 7 | --------------- 8 | As covered in fundamentals, we need to disable the static flag to allow rooms to be created as navigate around the mud:: 9 | 10 | #map flag static off 11 | 12 | Once this is disabled, the mapper will automatically create rooms in the map as it interprets your movement. 13 | 14 | NOTE: Dynamic mapping requires the #pathdir settings to be configured. The default are good when starting, but more can be done with these. 15 | 16 | -------------- 17 | Manual Mapping 18 | -------------- 19 | While the majority of mapping is typically done via dynamic mapping, there will be situations where you need to manually create or fix parts of the map. 20 | 21 | To create an adjacent room, use the command:: 22 | 23 | #map dig 24 | 25 | This will insert a room in the specified direction, but not move you to it. 26 | 27 | To insert a room between you and an adjacent room, use the command:: 28 | 29 | #map insert 30 | 31 | This will create a room between you and the room in the specified direction. This is used extensively for creating additional spaces to avoid overlap, and hidding entire map branches, covered in the following sections. 32 | 33 | If you need to remove a room between your current room and the room on the other side of an adjacent room, you can use the command:: 34 | 35 | #uninsert 36 | 37 | While the seems trivial, it's very useful because it automatically updates room vnums for both rooms and reconnects them for you automatically. Doing this by hand is very tedious. 38 | 39 | There are also times when you need to move your position around the map, but not on the mud. This is done with the command:: 40 | 41 | #map move 42 | 43 | This command is primarily used when the mapper gets out of sync with your actual location on the mud, especially while manually editing the map. 44 | 45 | 46 | --------------------- 47 | Undoing Room Creation 48 | --------------------- 49 | The mapper (out of the box) cannot tell when movement was prevented. It interprets your input and updates the map accordingly. One of the first things that happens in this situation, is that you'll attempt to move through a closed door or encounter some kind of situation that prevents the movement from occurring, but the mapper will create the room anyway. 50 | 51 | There are several ways to recover from this situation, the first is with:: 52 | 53 | #map undo 54 | 55 | This will unwind the erroneous room creation and move you to your previous location in the map. 56 | The second is to not unwind the room creation, but to move yourself back to your previous location in the map. This can be done with either of the commands:: 57 | 58 | #map goto 59 | #map move 60 | 61 | If desired, you then delete the room that was created with:: 62 | 63 | #map delete 64 | 65 | ----------------- 66 | Overlapping Rooms 67 | ----------------- 68 | Most muds aren't laid out in a perfect grid - there's lots of overlapping. How you design your map is a personal preference, but one of the basic tools is to hide branches from the map. 69 | 70 | Void rooms help to solve spacing issues by creating an additional "space" between two adjacent rooms. 71 | 72 | The most basic way of using this, is with #map insert, and specifying the roomflag void:: 73 | 74 | #map insert void 75 | 76 | This will move the room to over an existing space, creating the space needed to avoid overlapping rooms. 77 | 78 | 79 | ------------------- 80 | Hiding Map Branches 81 | ------------------- 82 | Sometimes, entire areas should be hidden from a view until they are entered. To do this, we use hidden void rooms. As previously covered, we can insert a void room with the command:: 83 | 84 | #map insert void 85 | 86 | Note the vnum of the room that was created, because we will need to set the hide flag on it as well. 87 | 88 | To do this, you create a "void" room (this is basically a place marker in the map) and set it's hidden flag to 1. When you navigate to this room you'll pass over it in whatever direction you were already going. 89 | 90 | There are several ways to create the rooms, the most straight forward is: 91 | 92 | #map insert void 93 | #map goto 94 | #map roomflag hide 95 | #map move 96 | 97 | You should now see the entire branch hidden from your current position. 98 | 99 | NOTE: It does not appear possible to set both the hide and void roomflags at the same time when using the #insert command. 100 | NOTE: THe #map return command does not appear to work to return from the void room to the previous location. 101 | 102 | There are probably more efficient ways of doing this, but I don't know them. 103 | 104 | -------------------------------------------------------------------------------- /source/contents/features/mapper/03_map-display.rst: -------------------------------------------------------------------------------- 1 | ========================================= 2 | Displaying the Map in a Separate Terminal 3 | ========================================= 4 | Rather than displaying in a split, we can get a much more enjoyable experience by displaying the map in a separate window. 5 | 6 | The easiest way to do this is to have the MAP ENTER ROOM event write the map to a separate file, like this:: 7 | 8 | #event {MAP ENTER ROOM} { 9 | #map map 16x16 map.txt {a}; 10 | }; 11 | 12 | Note: The {a} flag appends to the file, rather than overwriting it, so that we can use tail of view it whenever it changes. This can generate very large files. 13 | 14 | And then we can view the file in a separate window with tail -F :: 15 | 16 | tail -n 16 -f map.txt 17 | 18 | I've had mixed results with this approach - depending on the system and implimentation of tail, this may or may not work. 19 | 20 | Rather than use this approach, we can get much better behavior by using the following bash script:: 21 | 22 | #!/usr/bin/env bash 23 | 24 | MAP_FILE='map.txt' 25 | MAP_SIZE='map_size.tin' 26 | REFRESH_RATE=.25 27 | 28 | while [ "true" ]; do 29 | echo \#var MAP_ROWS $(tput cols)\; > $MAP_SIZE 30 | echo \#var MAP_LINES $(tput lines)\; >> $MAP_SIZE 31 | clear 32 | cat $MAP_FILE 33 | sleep $REFRESH_RATE 34 | done 35 | 36 | This redisplays the file every .25 seconds, which on my system seems to be the fastest refresh rate that there is nearly no noticeable lag between my movement in TinTin and the map being updated. Additionally, it writes a small tintin file, which contains two variable definitions - the number of columns and number lines in the window displaying the map. 37 | 38 | In our map event hook, we can then have it write the perfectly sized map, by simply reading this tintin file and using those values to update the size of the map that is displayed:: 39 | 40 | #event {MAP ENTER ROOM} { 41 | #read map_size.tin; 42 | #map map ${MAP_ROWS}x${MAP_LINES} map.txt; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /source/contents/features/mapper/04_map-metadata.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Metadata 3 | ======== 4 | The mapper also has the capabilities for storing metadata about each room that can be used in an infinite amount of ways. The command #map info shows you some of these fields: 5 | 6 | Room area: 7 | Room data: 8 | Room desc: 9 | Room name: 10 | Room note: 11 | Room symbol: 12 | Room terrain: 13 | 14 | But map set shows them all (I believe): 15 | 16 | roomarea: 17 | roomcolor: 18 | roomdata: 19 | roomdesc: 20 | roomflags: 0 21 | roomname: 22 | roomnote: 23 | roomsymbol: 24 | roomterrain: 25 | roomweight: 1.000 26 | 27 | Any of these values can be set with the #map set command, for example: 28 | 29 | #map set roomarea mainland 30 | 31 | These options are tailored to the MSDP protocol, which specifies values like TERRAIN that can be easily parsed and stored. I play on an LPMUD, which does not have terrain, so I don't use this value, but I do use the others. 32 | 33 | -------------------------------------------------------------------------------- /source/index.rst: -------------------------------------------------------------------------------- 1 | ================================= 2 | TinTin++ Unofficial Documentation 3 | ================================= 4 | 5 | .. toctree:: 6 | :glob: 7 | :maxdepth: 2 8 | 9 | contents/* 10 | 11 | ----- 12 | Notes 13 | ----- 14 | 15 | - TODO: Figure out a way to add tags to sphinx pages, so "related" items are shown. 16 | - TODO: Figure out a way to add a "fix me" button, so users can click a link on a sphinx page that redirects them directly to the issue tracker on github, so they can submit a correction. 17 | - TODO: Figure out a way to integrate disqus so conversations can take place on specific pages. 18 | 19 | 20 | Indices and tables 21 | ================== 22 | 23 | * :ref:`genindex` 24 | * :ref:`modindex` 25 | * :ref:`search` 26 | 27 | --------------------------------------------------------------------------------