How to add a new target to txt2tags It's easy! %!includeconf: inc/config.t2t %!postproc: '(?i)(\1 % Trick to color the diff output %!postproc: ^(\+.*) \1 %!postproc: ^(-.*) \1 %!include: inc/menu.t2t == Yes, YOU can make it == So you like txt2tags very much but your favorite format is not yet supported? How about adding it yourself? You don't need to be a Python programmer to do it. You'll just define variables, no algorithm is needed. In fact, if text editors and the command line don't scare you, **you don't even need to be a programmer** to do it. Just read this document carefully :) On the following guidelines we'll add the imaginary "foo" target to txt2tags. %%TOC + Get the most recent txt2tags source code + IMPORTANT! Before you start, make sure you have the newest txt2tags code, available at https://github.com/txt2tags/txt2tags Open this file on your favorite text editor. % + Add the target identifier in TARGETS + % % % This step can be removed by TARGET = TARGET_NAMES.keys() % % But the ordering of TARGET is important to the --help and Tk interface menus % % Think about it -- DONE in 2010-12-01 % % At the beginning of the txt2tags source code, right after the long heading comments, you'll find the declaration of all the available targets: % % ``` TARGETS = 'html xhtml sgml tex lout man mgp wiki gwiki doku moin pm6 txt'.split() % % Just add your new target identifier. Choose a short name (5 letters or less). % % ``` TARGETS = 'html xhtml sgml tex lout man mgp wiki gwiki doku moin pm6 txt @@@foo@@@'.split() % % Note: This identifier will also be the filename extension used by txt2tags when saving the result to a file. % % You can already run ``./txt2tags --help`` and see your new target listed on the --target option! % + Add the target identifier and description in TARGET_NAMES + At the beginning of the txt2tags source code, right after the long heading comments, you'll find the declaration of all the available targets: ``` TARGET_NAMES = { 'html' : _('HTML page'), 'xhtml': _('XHTML page'), 'sgml' : _('SGML document'), 'tex' : _('LaTeX document'), 'lout' : _('Lout document'), 'man' : _('UNIX Manual page'), 'mgp' : _('MagicPoint presentation'), 'wiki' : _('Wikipedia page'), 'gwiki': _('Google Wiki page'), 'doku' : _('DokuWiki page'), 'moin' : _('MoinMoin page'), 'pm6' : _('PageMaker document'), 'txt' : _('Plain Text'), @@@'foo' : _('FOO Document'),@@@ } ``` Add a new item to the dictionary, choosing an identifier and a textual description for your new target. Notes: - Copy & paste instead writing from zero to make sure you won't forgot the _(...) format. - Choose a short name for the identifier (5 letters or less). - The identifier will also be the filename extension used by txt2tags when saving the result to a file. - You can already run ``./txt2tags --targets`` and see your new target listed! + Add the header template in HEADER_TEMPLATE + The headers are the first three lines of a txt2tags document. Some targets as LaTeX have a specific place for them (the Preamble), others don't. Make a decision on how to format the header lines. You have three tokens available: - **%(HEADER1)s** - The first source line (Document title) - **%(HEADER2)s** - The second source line (Document author) - **%(HEADER3)s** - The third source line (Document date) - The title/author/date contents are just suggestions. The user can put whatever he/she wants at those lines. And remember that while the first line (title) is required, the other two are optional. Their lines at this template will be removed if not present. ``` '@@@foo@@@': """\ @@@@@@%(HEADER1)s@@@@@@ @@@@@@%(HEADER2)s@@@@@@ @@@@@@%(HEADER3)s@@@@@@ """, ``` Tip: Once again, copy & paste instead writing from zero. Tip: To show a literal "%" use "%%". + Add the target's tags in getTags() + This is the most tricky step. Some targets are easy, some are more exotic. First, find the definition of the getTags() function. ``` def getTags(config): The **keys** variable stores all the valid tokens you can use to describe your target's tags. The **alltags** dictionary stores the tags for each target. This is where you'll add your new target. ``` '@@@foo@@@': { 'title1' : '@@@@@@\a@@@@@@' , 'title2' : '@@@@@@\a@@@@@@' , 'title3' : '@@@@@@\a@@@@@@' , ... }, ``` **IMPORTANT:** The easiest is to find an already added target that is similar to yours, copy & paste the code and modify it. **Don't start from zero.** Note the ``\a`` on the tags. It represents the text the user typed inside that mark. So ``=My Title=`` will be converted to ``My Title``. You can also put a ``\n`` character to represent a line break. It's useful if your tag spans in multiple lines. A Tab can be inserted using ``\t``. At this point you can already run a ``txt2tags -t foo sample.t2t`` command and it will work! The results will be saved to sample.foo. Check it out. Tip: Keep editing and running to adjust and improve your target support. + Add the target's rules in getRules() + This is the final step. Besides the tags already added, now you can also specify some rules to fine-tune your target code. Search for the function definition: ``` def getRules(config): Then read carefully the **allrules** comments to learn which options are available. Once again, copy & paste the entry of an already added target to make your life easier. Put there all the rules you need, always using 1 as the value. You don't need to turn off a rule with zero. Just don't mention it and it will be disabled by default. In other words, just add the rules you want to be ON. ``` '@@@foo@@@' : { 'indentverbblock':1, 'spacedlistitem':1, 'parainsidelist':1, 'keeplistindent':1, 'barinsidequote':1, 'autotocwithbars':1, 'blankendmotherlist':1, }, ``` And that's it! Now your target is fully added to the txt2tags program! Tips: - If in your target the ``urlMark`` order is reversed (label comes before the link) use the following rule: ``'labelbeforelink':1``. See how this change was made in [f8d7e9 https://github.com/txt2tags/txt2tags/commit/f8d7e9826ec5d80185418209c0e9c2522c5ea1f9]. - If in your target the nested lists are defined by the number of ``*``, for example ``**`` for sublists and ``***`` for subsublists, use ``listItemLine`` instead ``listItemOpen``, remove the ``keeplistindent`` setting and turn on ``spacedlistitemopen``. See how this change was made in [f936c6 https://github.com/txt2tags/txt2tags/commit/f936c603790dfc3dbdf4fddf3ce90463b5b96a71]. Example: ``` # getTags 'listItemOpen': '* ', * mother list ====> * sub list # getRules * sub sub list 'keeplistindent':1, -------------------------------------------------------------- # getTags 'listItemLine': '*', * mother list ====> ** sub list # getRules *** sub sub list 'spacedlistitemopen':1, ``` - + Submit your work! + Once you're done, [open a Pull Request in GitHub https://github.com/txt2tags/txt2tags] so we can include your work in the official txt2tags source and everybody can use your target. You will also be included on the [Team page team/] and your karma will increase in 2,715 points :) **Have a good programming time!** = A real-world example = See how easy it was to add the DokuWiki target to txt2tags. This file is in the diff format, where red lines are OLD and green lines are NEW: %!include: ``inc/doku-adding.diff`` = Another real-world example = Directly from GitHub, see how easy the BBCode target was added: https://github.com/txt2tags/txt2tags/commit/2146a32ea7416c3ccc0c6ca8b4a8f30248c5d6f0 Click in "expand all" to see the code. The green part is the new code. %!include: inc/footer.t2t