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.

1. 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.

2. 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:

You can already run ./txt2tags --targets and see your new target listed!

3. 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:

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': """\
<title-tag>%(HEADER1)s</title-tag>

<author-tag>%(HEADER2)s</author-tag>

<date-tag>%(HEADER3)s<date-tag>
""",
Tip: Once again, copy & paste instead writing from zero.
Tip: To show a literal "%" use "%%".

4. 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'              : '<title-tag-1>\a</title-tag-1>' ,
   'title2'              : '<title-tag-2>\a</title-tag-2>' ,
   'title3'              : '<title-tag-3>\a</title-tag-3>' ,
   ...
},

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 <title-tag-1>My Title</title-tag-1>.

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.

5. 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:

6. Submit your work!

Once you're done, open a Pull Request in GitHub 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 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:

--- txt2tags	2007-11-08 15:10:58.000000000 -0200
+++ txt2tags-doku	2007-11-11 23:09:11.000000000 -0200
@@ -175,6 +175,7 @@
   'mgp'  : _('MagicPoint presentation'),
   'wiki' : _('Wikipedia page'),
   'gwiki': _('Google Wiki page'),
+  'doku' : _('DokuWiki page'),
   'moin' : _('MoinMoin page'),
   'pm6'  : _('PageMaker document'),
   'txt'  : _('Plain Text'),
@@ -438,6 +439,14 @@
 
 """,
 
+  'doku': """\
+===== %(HEADER1)s =====
+
+**//%(HEADER2)s//**
+
+//%(HEADER3)s//
+""",
+
   'wiki': """\
 '''%(HEADER1)s'''
 
@@ -895,6 +905,52 @@
 	   'tableCellSep'        : ' || '          ,
 	},
 
+	# http://wiki.splitbrain.org/wiki:syntax
+	# Hint: <br> is \\ $
+	# Hint: You can add footnotes ((This is a footnote))
+	'doku': {
+	   'title1'              : '===== \a =====',
+	   'title2'              : '==== \a ===='  ,
+	   'title3'              : '=== \a ==='    ,
+	   'title4'              : '== \a =='      ,
+	   'title5'              : '= \a ='        ,
+	   # DokuWiki uses '  ' identation to mark verb blocks (see indentverbblock)
+	   'blockQuoteLine'      : '>'             ,
+	   'fontMonoOpen'        : "''"            ,
+	   'fontMonoClose'       : "''"            ,
+	   'fontBoldOpen'        : "**"            ,
+	   'fontBoldClose'       : "**"            ,
+	   'fontItalicOpen'      : "//"            ,
+	   'fontItalicClose'     : "//"            ,
+	   'fontUnderlineOpen'   : "__"            ,
+	   'fontUnderlineClose'  : "__"            ,
+	   'fontStrikeOpen'      : '<del>'         ,
+	   'fontStrikeClose'     : '</del>'        ,
+	   'listItemOpen'        : '  * '          ,
+	   'numlistItemOpen'     : '  - '          ,
+	   'bar1'                : '----'          ,
+	   'url'                 : '[[\a]]'        ,
+	   'urlMark'             : '[[\a|\a]]'     ,
+	   'email'               : '[[\a]]'        ,
+	   'emailMark'           : '[[\a|\a]]'     ,
+	   'img'                 : '{{\a}}'        ,
+	   'imgAlignLeft'        : '{{\a }}'       ,
+	   'imgAlignRight'       : '{{ \a}}'       ,
+	   'imgAlignCenter'      : '{{ \a }}'      ,
+	   'tableTitleRowOpen'   : '^ '            ,
+	   'tableTitleRowClose'  : ' ^'            ,
+	   'tableTitleCellSep'   : ' ^ '           ,
+	   'tableRowOpen'        : '| '            ,
+	   'tableRowClose'       : ' |'            ,
+	   'tableCellSep'        : ' | '           ,
+# DokuWiki has no attributes. The content must be aligned!
+#	   '_tableCellAlignRight' : '<)>'           , # ??
+#	   '_tableCellAlignCenter': '<:>'           , # ??
+# DokuWiki colspan is the same as txt2tags' with multiple |||
+	   # 'comment'             : '## \a'         , # ??
+	   # TOC is automatic
+	},
+	
 	# http://en.wikipedia.org/wiki/Help:Editing
 	'wiki': {
 	   'title1'              : '== \a =='        ,
@@ -1266,8 +1323,23 @@
	    'autonumberlist':1,
 	    'breaktitleopen':1,
 	    },
+	  'doku': {
+	    'indentverbblock':1,           # DokuWiki uses '  ' to mark verb blocks
+	    'spacedlistitem':1,
+	    'linkable':1,
+	    'blankendmotherlist':1,
+	    'keeplistindent':1,
+	    'tableable':1,
+	    'barinsidequote':1,
+	    'blankendtable':1,
+	    'tablecellstrip':1,
+	    'autotocwithbars':1,
+	    'autonumberlist':1,
+	    'imgalignable':1,
+	    'tablecellaligntype':'cell',
+	    },	
 	  'wiki': {
 	    'linkable':1,
 	    'blankendmotherlist':1,

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.