Summary: Provide a way to convert arbitrarily structured text to table markup and provide conversion of simple tables to advanced.
Version: 2013-09-23
Prerequisites: PHP 5 (alignment does NOT work in HTML 5)
Status: alpha
Maintainer: Peter Bowers
Users: +2 (View / Edit)
Categories: Editing Tables
Download: text2tbl.phpΔ
Discussion: Text2Tbl-Talk

Questions answered by this recipe

This section is optional; use it to indicate the types of questions (if any) this recipe is intended to answer.

  • How can I create my table in a simpler structure (for instance, just double-space between columns) and then convert it to normal table markup?
  • How can I convert existing text into a table using various separators to divide into columns and etc?
  • How can I convert a simple table into a table with advanced directives and still keep row and column spanning?
  • How can I use text structured in an alternate way to display tables?

NOTE: Since pmwiki.org is running PHP4 and this recipe uses PHP5 feel free to use http://pmwiki.qdk.org/pmwiki.php?n=Text2Tbl.Test as a sandbox to see how this works.


Use structured text to create tables (either converting or directly as markup).


There are 2 "modes" this recipe provides:

  • CONVERSION: a pattern to alter your source to match normal table markup (converting to either simple or advanced table markup)
  • MARKUP: use your structured text directly AS your markup, without the conversion in your source

There are 2 ways of doing conversion (simple and flextables) and the 2nd way (flextables) also works as markup when it is slightly modified.

Conversion type 1 (SIMPLE) -- create tables by typing 2 or more spaces in between columns

There are 2 basic types of table conversion you can use. The 1st is very simple - it simply converts any occurrences of 2 or more consecutive spaces into a column division. Thus you will enter this:

abc  def    ghi
jkl  mnoaa  pqr
stu  vwx    zzz

and after you press "Save and Edit" or "Save" it will be converted to this:

||  border=1
||abc ||def ||ghi ||
||jkl ||mnoaa ||pqr ||
||stu ||vwx ||zzz ||

Note that everything is left-justified. Any text you place on the line after "TABLESTART" will be left as options to the table. No other options are possible. This is just for quickly creating a table.

Flex Tables (option 2) for source conversion OR directly as markup

Option #2 is quite a bit fancier. It allows for converting almost any structured text (i.e., CSV, etc.) into a table. It allows for specifying the alignment of each column, etc.

There are 2 basic patterns you will use to surround your structured text:

  • (:text2tbl ARGUMENTS:)<structured text>(:text2tblend:)
    • This will convert your source (the source itself will be modified to look like normal table markup)
  • (:flextbl ARGUMENTS:)<structured text>(:flextblend:)
    • This will leave your source as it is but will display a table

Note that if you prefer "table" to "tbl" you can use text2table rather than text2tbl or flextable rather than flextbl in each of the above markups interchangeably


and it will be converted to this when you save:

||a ||b ||c ||
||d ||e ||f ||
||ghi ||jkl ||mno ||

However, you have many different options that you can set. Options appear within the (:text2tbl OPTIONS:) pattern and are specified in the usual opt=val method. The can include these options:

  • sep=X (the separator for all columns will be X (can be multiple chars)
  • sep1=X sep2=Y sep3=Z (specify potentially different separators for each column)
  • align=lrc (specify the alignment of each column as left, right, or center the number of chars will equal the number of columns: llc, lrllc,etc)
  • fmt=AXAXAX (specify the alignment (A) and the separator (X) of each col in a single option. Separators must be single-character.)
  • re=1 (treat the separater as a regular expression pattern. This works regardless of whether you have used sep=X or sep1=X or fmt=AXAXA to specify the separator)
    The pattern may be complex. As such, in order to specify multiple separators, one may use: sep="(X|Y|Z)".
    For example, the pattern sep="(\t+|;| {2,})" would use any of these separators: tab (one or more), semicolon, multiple spaces.
  • options="border=1" (specify table options - whatever is in the quotes will be put verbatim in the usual place on the 1st line)
  • quotes=1 (specify that you want double-quoted strings to be hidden from possibly containing separators -- good for CSV and etc.)
  • keepquotes=1 (specify that the quotes should stay in the text rather than being stripped out as would normally happen if quotes=1)
  • input=X (various shortcuts for specifying the format of the input text -- what type of structured text is to be read)
    • input=simple (this means that other options regarding format of the input text will be ignored and the text will be read from a simple table markup style - primarily used for converting to advanced table directives using output= as below)
    • input=csv (this is a shortcut for sep=, quotes=1 and is used for reading CSV data)
    • input=tsv (this is a shortcut for sep=\t re=1 and is used for reading tab'd data)
    • input=spaces (this is a shortcut for sep=" {2,}" re=1 and is used for reading data with multiple spaces as column separators)
  • output=advanced (this means that instead of outputting in the || style tables it will be output in the (:table ...:) style table
  • keeporiginal=1 or keeporiginal=0 (0=don't keep the original structured text at all - further modification will be made in the newly created table, 1=keep the original structured text - further modifications of the table data will be made in the original text)

Any unrecognized options are passed through directly as if you had specified options="...". This makes it legal to specify border=1 and etc. as an option itself.

For converting from simple to advanced, the following are supported:

  • column span (including using ___ as a cell filler as per RowspanInSimpleTables)
  • row span (as per RowspanInSimpleTables and also allowing ^^^ as a cell filler from that same recipe)
  • alignment for each individual cell is preserved as per the simple || tables

Note that specifying sep1,sep2,sep3 is mutually exclusive with specifying sep and is mutually exclusive with specifying fmt. You can specify your separator in exactly one way -- if you choose more than one way then something will be ignored...

"Fake" Headers (using !string as the label in the input side) are obtained by using the

style='text-align:center; font-weight:bold;'

that PM recommends when using output=advanced.

Cell-specific attributes can be specified as long as you are using output=advanced. Simply specify (:t2t OPTION:) at the start of the value of your cell (any format) and it will be converted to (:cell OPTION:) or (:cellnr OPTION:) in the resulting markup.

To convert CSV to a simple table:

(:text2tbl sep=, quotes=1 options="border=1":)
"Smith, John","123 Main St, Smallville, NC 12345",555-1212
John Smith,123 Main St,555-1212
"Smith, Jane","111 Small St, Mainville, NY 11122",(212) 123-4321

When that is saved it would result in this:

|| border=1
||!Name ||!Address ||!Phone ||
||Smith, John ||123 Main St, Smallville, NC 12345 ||555-1212 ||
||John Smith ||123 Main St ||555-1212 ||
||Smith, Jane ||111 Small St, Mainville, NY 11122 ||(212) 123-4321 ||

To show that you don't have to use the same separator (this is helpful when you have data from a different source that you want to put into a table):

(:text2tbl fmt="l;l-c":)
Column A ; Column B - Column C
apple    ; banana   - cherry

Is identical to this:

(:text2tbl sep1=; sep2=- align="llc":)
Column A ; Column B - Column C
apple    ; banana   - cherry

And both result in this when saved:

||Column A  || Column B  ||  Column C ||
||apple     || banana    ||  cherry ||

If you had specified an "output=advanced" directive:

(:text2tbl sep1=; sep2=- align="llc" output=advanced:)
Column A ; Column B - Column C
apple    ; banana   - cherry

it would have ended up like this:

(:table :)
(:cellnr align=left:)Column A 
(:cell align=left:) Column B 
(:cell align=center:) Column C
(:cellnr align=left:)apple    
(:cell align=left:) banana   
(:cell align=center:) cherry

Converting from simple tables to advanced table directives looks like this (also demonstrating the col & row span with various filler cells):

(:text2tbl input=simple output=advanced:)
|| border=1
|| abc ||__||__||__||
|| abc ||def+++||ghi++||zzz||

The above results (after clicking on "save and edit") in this source:

(:table border=1:)
(:cellnr align=center colspan=4:) abc 
(:cellnr align=center:) abc 
(:cell align=left rowspan=3:)def
(:cell align=left rowspan=2:)ghi
(:cell align=left:)zzz
(:cellnr align=left:)xyz
(:cell align=left:)zzz
(:cellnr align=left:)zzz
(:cell align=left:)yyy
(:cell align=left:)zzz

Embedded newlines (by ending a line with \\ or otherwise) are NOT supported.


  • Download text2tbl.phpΔ and place it in your cookbook directory
  • Add a line include_once("$FarmD/cookbook/text2tbl.php"); to your config.php
  • (optional) add a line $t2tKeepOriginal=0; (the default value is 1 to always keep your original data)

Release Notes

If the recipe has multiple releases, then release notes can be placed here. Note that it's often easier for people to work with "release dates" instead of "version numbers".

  • 2013-09-23: Added config option $t2tEnableSuppressDefaultAlign. When set to true the align="left" will not be displayed for cells in advanced table directives.
  • 2010-04-06: Fixed problem related to multiple TABLESTART ... TABLEEND structures
  • 2009-10-05: Added input=tsv shortcut, as suggested by OliverBetz
  • 2009-09-15B: Made it so unrecognized options get automatically appended to the "options" string, obviating the need for the awkward options="border=1" syntax.
  • 2009-09-15: Fixed an error related to headers on centered and right-aligned columns.
  • 2008-08-30B: Fixed various quoting problems and recipe version notification error.
  • 2008-08-30A: Added (:t2t OPTION:) for cell-specific attributes if output=advanced is specified
  • 2008-08-30: Added "input=csv", "input=spaces", "keeporiginal=1" options and flextbl markup
  • 2008-08-28: Added "output=advanced" and "input=simple" directives to allow table conversion, implemented row & col spanning for same
  • 2008-08-26: Renamed from "simpletable" to "text2tbl" to leave room for a markup
  • 2008-08-25: Initial release

See Also



See discussion at Text2Tbl-Talk

User notes +2: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.