Document title: File format description for TreePad .hjt files (versions 3.x/4.x/5.x/6.x/7.x) Document version: December 22, 2008 Document author: Freebyte.com Document Web location: http://www.treepad.com/docs/ Contents Introduction File version section Node section Which tags are essential? The object tag Node caption formatting tag Node color tag Article color tag Node checkmark visibility tag Node 'checked' tag Article readonly tag Export tag Template tag Default subtree icon tag Date-time changed tag Username changed tag Date-time created tag Username created tag Bookmarks list TPZ files TreeBooks and Templates Draft Pad Future TreePad file formats Programming example Introduction This document contains technical information on the structure of the TreePad file format. It covers the TreePad file types: .hjt (and .tpz), .htmhjt. The basic .hjt file format is text/ascii. File version section Inside the ascii file, the start of a TreePad file should be the line containing the version number of the TreePad program which last wrote to the file: Example: Example: Node section The TreePad data file consists of a large number of nodes, each representing and article/node combination which is part of the tree. Each node looks like this: (Unique identifier) (Data type indicator) (Node title) (level indicator, 0 meaning at tree level 0, 1 meaning one level up, etc.) the following lines are part of the article text, until the closing line ('end node'), which is: 5P9i0s8y19Z * When 'unique identifier' is not present or is equal to zero, TreePad 3.1 and higher will automatically generate a unique identifier. This tag has been introduced in version 3.1 and will be ignored by earlier versions. This identifier is a natural number and the tag is of the form: id=n where n is the next natural number after the highest number the tree already employs as a 'unique identifier. * In addition to this, TreePad PLUS/SAFE/BIZ 7.x and higher add an extra line, containing a globally unique identifier (or GUID), and is of the form: nodeguid=g If the NodeGUID tag is not present, a GUID will be automatically generated for the node the next time the file is saved (versions 7.x and higher). * When 'data type indicator' is not present, it is assumed that the article is of type 'plain text'. The data type indicator has been introduced by TreePad freeware, version 2.7 and will be ignored by earlier TreePad versions, so that the file format is backwards compatible. Please note: TreePad freeware will not be able to read html and rtf articles correctly. TreePad PLUS files containing only plain text articles are backwards compatible with any previous TreePad version. * A TreePad RTF article should start with the string {\rtf, a TreePad HTML article should start with the line '', a TreePad XML article should start with ' mail from the President 4 Dear sir, I would like to invite all TreePad users into the Oval Office to help me better organize the country. Sincerely, G. Bush, the White House Washington 5P9i0s8y19Z Example 2, an HTML article id=6 dt=HTML mail from the President 4

Dear sir,

I would like to invite all TreePad users into the Oval Office to help me better organize the country. Sincerely,

G. Bush, the White House Washington

Example 3, an RTF article id=6 dt=RTF bush 1 {\rtf1\ansi\deff0\deftab254{\fonttbl{\f0\fnil\fcharset0 arial;}}{\colortbl\red0\green0\blue0;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red255\green255\blue0;\red255\green0\blue255;\red128\green0\blue128;\red128\green0\blue0;\red0\green255\blue0;\red0\green255\blue255;\red0\green128\blue128;\red0\green0\blue128;\red255\green255\blue255;\red192\green192\blue192;\red128\green128\blue128;\red0\green0\blue0;}\wpprheadfoot0\paperw12240\paperh15840\margl1880\margr1880\margt1440\margb1440\margh720\margf720{\*\pnseclvl1\pnucrm\pnstart1\pnhang\pnindent720{\pntxtb}{\pntxta{.}}} {\*\pnseclvl2\pnucltr\pnstart1\pnhang\pnindent720{\pntxtb}{\pntxta{.}}} {\*\pnseclvl3\pndec\pnstart1\pnhang\pnindent720{\pntxtb}{\pntxta{.}}} {\*\pnseclvl4\pnlcltr\pnstart1\pnhang\pnindent720{\pntxtb}{\pntxta{)}}} {\*\pnseclvl5\pndec\pnstart1\pnhang\pnindent720{\pntxtb{(}}{\pntxta{)}}} {\*\pnseclvl6\pnlcltr\pnstart1\pnhang\pnindent720{\pntxtb{(}}{\pntxta{)}}} {\*\pnseclvl7\pnlcrm\pnstart1\pnhang\pnindent720{\pntxtb{(}}{\pntxta{)}}} {\*\pnseclvl8\pnlcltr\pnstart1\pnhang\pnindent720{\pntxtb{(}}{\pntxta{)}}} {\*\pnseclvl9\pndec\pnstart1\pnhang\pnindent720{\pntxtb{(}}{\pntxta{)}}} \endnhere\sectdefaultcl{\pard{\ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 Dear sir,\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 \par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 I would like to invite all TreePad users into the Oval Office\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 to help me better organize the country.\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 Sincerely,\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 \par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 G. Bush,\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 the White House\par \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs24\cf0 Washington}} } 5P9i0s8y19Z Example 4, an XML article, which will be displayed as a form in TreePad PLUS/SAFE/BIZ 6.0. id=6 dt=XML My Yahoo account 1 Yahoo ID Fido Fido MyDog Fido@yahoo.com website.yahoo.com/fido What is the name of my dog? Fido No real data. Only for testing purposes 5P9i0s8y19Z The string 5P9i0s8y19Z is included to make sure that when someone types in the article, the program will not get confused into thinking the node has ended there (in the middle of the article). The chance that someone types 5P9i0s8y19Z by accident into the article area is very much smaller. Not a very beautiful implementation, but it's simple and it works. The order in which the nodes are listed in the TreePad file is determined by the order in which they would appear in a fully expanded tree, beginning at the top, and ending at the bottom. E.g. a sequence of levels (the numbers are indicating the node levels): 1 - 2 - 3 - 3 - 3 - 2 will be corresponding to the tree structure (the numbers are indicating the node levels): 1 ___2 | |___3 | |___3 | |___3 | |____2 Warning: if you store this text in TreePad, do not include any " 5P9i0s8y19Z" as appearing in this text !!!!! Which tags are essential? Of all the .hjt file-format elements discussed in this document, only these are essential for a correct TreePad file: 1 - file version 2 - 3 - Node title 4 - Node level indicator 5 - the lines which are part of the article text 6 - 5P9i0s8y19Z All other tags are optional. The Object tag This tag indicates an object embedded into the article, such as an image. This tag occurs only if the article contains one or more images. This example contains five image files, embedded into the article: id=209 nodeguid=7614DD4938A67FAEFF8388BAA08389A4CBB510F5 dt=RTF obj=11.bmp obj=F7F8E9D8E9EDC2B1C5AB4AE28D5F153BCE436CA2.bmp obj=34.bmp obj=222F80F71F36FC5D4CBB9C4F93B3F4D0E63EE9F9.png obj=B778AC6CD54A27E8542F124B460BCDB2285240AA.png Photos of my house 2 ........... Objects are stored into the accompanying .tpz file. Additionally references to the objects are present inside the article as RTF links to external objects. Node caption formatting tag This tag indicates the formatting of a node (like bold, italic, underline, font name, color). If this tag is not present, the default tree font is used for the node. Example: nft=0F;00000000;000A;01;arial (1) The first two digits in the node format string are a hexadecimal number indicating the font style and which font attributes are used from the global tree font parameters: bit0 = 1 -> bold; bit0 = 0 -> not bold bit1 = 1 -> italic; bit1 = 0 -> not italic bit2 = 1 -> underline; bit2 = 0 -> not underline bit3 = 1 -> strikeout; bit3 = 0 -> not strikeout bit4 = 1 -> use the default tree font size; bit4 = 0 -> use the specified node font size (see below) bit5 = 1 -> use the default tree font name and charset; bit5 = 1 -> use the specified node font name and charset (see below) bit6 = 1 -> use the default tree font color; bit6 = 1 -> use the specified node font color (see below) bit7 = 1 -> use the default tree font style; bit7 = 1 -> use the specified node font style (see above) So a hexadecimal number of '01' means only 'bold', and not italic/underline/stikeout (2) The second number is an eight digit hexadecimal number representing the font color in hexadecimal notation. 00FF0000 represents pure blue, 0000FF00 is pure green, and 000000FF is pure red. $0000000 is black and 00FFFFFF is white. (3) The third number is a four digit hexadecimal number representing the font size. For example, 0A would represent font size 10. (4) The fourth number represents the font character set. ANSI_CHARSET 00 ANSI characters. DEFAULT_CHARSET 01 Font is chosen based solely on Name and Size. If the described font is not available on the system, Windows will substitute another font. SYMBOL_CHARSET 02 Standard symbol set. SHIFTJIS_CHARSET 80 Japanese shift-jis characters. HANGEUL_CHARSET 81 Korean characters (Wansung). JOHAB_CHARSET 82 Korean characters (Johab). GB2312_CHARSET 86 Simplified Chinese characters (mainland china). CHINESEBIG5_CHARSET 88 Traditional Chinese characters (taiwanese). GREEK_CHARSET A1 Greek characters. TURKISH_CHARSET A2 Turkish characters. VIETNAMESE_CHARSET A3 Vietnamese characters. HEBREW_CHARSET B1 Hebrew characters. ARABIC_CHARSET B2 Arabic characters. BALTIC_CHARSET BA Baltic characters. Not available on NT 3.51. RUSSIAN_CHARSET CC Cyrillic characters. Not available on NT 3.51. THAI_CHARSET CE Thai characters. Not available on NT 3.51 EASTEUROPE_CHARSET EE Includes diacritical marks for eastern european countries. Not available on NT 3.51. OEM_CHARSET FF Depends on the codepage of the operating system. (5) the fifth part of the node formatting tag is the name of the font. Node color tag This tag, 'cl', specifies the text background color of an individual node. If this tag is not present, the default tree background color is used. Example for specifying pure red: cl=000000FF This is an eight digit hexadecimal number representing the font color in hexadecimal notation. 00FF0000 represents pure blue, 0000FF00 is pure green, and 000000FF is pure red. $0000000 is black and 00FFFFFF is white. Article color tag The article color tab, 'acl', functions in a similar way to the node color tag. It defines a background color for an individual article color, overriding the global article color setting in the options screen. Example: acl=0040FF00 Node checkmark visibility tag If the the line chkroot=1 occurs, the checkmark is visible for that particular node. In all other cases (including this tag not present), the checkmark is hidden. Node 'checked' tag If the line chk=1 occurs, the node is checked (independent of the fact whether the node is visible or not). In all other cases (including this tag not present), the node is unchecked. Article readonly tag IF the line artreadonly=1 is present, the article of the corresponding node is readonly. In all other cases, the article is writable. Note: the readonly flag only works in TreePad Business Edition and TreePad SAFE. It has no effect in TreePad PLUS and TreePad Lite. Export tag: enableexport=0 means that this node, and all its child nodes will not be included in a single-file html/rtf/txt subtree print or export. Anything else means that this node will be exported and printed. Template tag: istemplate=1 means that this node is a template for all newly created child nodes Default subtree icon tag: dsi=1 means that this node contains the default icon for the subtree, all newly created descendants of this subtree will display this icon. Date-time changed tag: dtch=20030623-235539 means that this node has been changed on June 23, 2003 at time 23.55.39 (hh.mi.ss) Username changed tag: usrch=johndoe means that this node has been changed or created by user johndoe (user name of the user logged on in Windows who changed that node) Date-time created tag: dtcr=20030623-235539 means that this node has been created on June 23, 2003 at time 23.55.39 (hh.mi.ss) Username created tag: usrcr=johndoe means that this node has been changed or created by user johndoe (user name of the user logged on in Windows who created that node) Bookmarks list The bookmark list is a simple flat list of tree node ids, example: id=34 id=119 id=7 5P9i0s8y19Z The number in each line after 'id=' is the ID of the node in the tree. The bookmarks list is placed before the first node tag of the tree inside a TreePad file. _______________________________________________________ TPZ files When storing objects such as images into TreePad PLUS, the program will not keep them into the .hjt file, but into an external file, of extension '.tpz'. TPZ files (TreePad Zipped) are simply zip files! TPZ files can contain images. The .tpz file has the same name as the .hjt file, only the extension is different. Images are stored in a folder inside the .tpz file, called \1\bin . The images have numbered names, like 1.bmp, 2.bmp.....346.bmp....etc or names containing GUIDs. For images these formats are supported: bmp, ico, gif, jpeg, png, wmf, emf Tree icons are stored in the folder \2\bin inside the tpz file. For icons these formats are supported: ico, bmp _________________________________________________________ TreeBooks and Templates A TreeBook is a subtree or tree containing nodes all with a the same structure, like an XML form. A TreeBook node contains the template from which the structure for the descendant nodes is copied. The article of an XML TreeBook root node consists of two sections. The first section is the XML template, this is the model which is applied to new descendant nodes by default. The second section contains the text that is displayed in the TreeBook root node itself, it is not part of the template. The text in the second section can be Rich Text, plain text, XML or HTML. An RTF section should start with the string {\rtf, an HTML section should start with the line '', an XML section should start with 5P9i0s8y19Z Example 5, an XML treebook node (or an XML template node) id=6 dt=XML istemplate=1 Business Addressbook 1
5P9i0s8y19Z {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}} \viewkind4\uc1\pard\b\f0\fs40 Business Addressbook\par \par \b0\fs20 By default, any descendent-node of this node will display the Business Addressbook form.\par Alternatively, you can also insert standard TreePad nodes containing normal article text and images.\par Please note that the text of this article can be altered in any way you like.\par \par } 5P9i0s8y19Z _________________________________________________________ Draft pad The draft pad is an extra editor pane (to be found only in TreePad Business Edition) in the accessory pane, below the article. The contents of the Draft Pad is stored as a block of Rich Text, between tags; example: {\rtf1\ansi\deff0\deftab850{\fonttbl{\f0\fnil\fcharset0 arial;}{\f1\fnil\fcharset2 symbol;}{\f2\fnil\fcharset2 WingDings;}}{\colortbl\red0\green0\blue0;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red255\green255\blue0;\red255\green0\blue255;\red128\green0\blue128;\red128\green0\blue0;\red0\green255\blue0;\red0\green255\blue255;\red0\green128\blue128;\red0\green0\blue128;\red255\green255\blue255;\red192\green192\blue192;\red128\green128\blue128;\red0\green0\blue0;}\wpprheadfoot1\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\margh720\margf720{\*\listtable{\list\listtemplateid19690212{\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc1{\leveltext\'02\'00.;}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc3{\leveltext\'02\'01.;}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'02\'02.;}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc4{\leveltext\'02\'03);}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc2{\leveltext\'02\'04);}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc4{\leveltext\'02\'05);}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'02\'06);}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'02\'07);}{\levelnumbers\'01;}} {\listlevel\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent360\levelnfc0{\leveltext\'02\'08);}{\levelnumbers\'01;}} \listid1194737}}{\*\listoverridetable{\listoverride\listid1194737\listoverridecount0\ls1}}\endnhere\sectdefaultcl{\pard{\tx8480 \ql\li0\fi0\ri0\sb0\sl\sa0 \plain\f0\fs20\cf0 All in one! Multi-featured Tree-structured Organizer, intuitive yet powerful.}} } 5P9i0s8y19Z Future TreePad file formats New tags can be introduced in future .hjt file formats, to support new features, such as node keywords. For any program to be compatible with future TreePad versions, the program needs to ignore any tags it does not know (this is how TreePad functions, so that older versions can read files created by newer versions). Example of a possible new tag which can be introduced in a new TreePad version: id=6 keywords=president, white house, politics, government dt=text mail from the President 4 Dear sir, The new element here is keywords=president, white house, politics, government'.Any current TreePad version will ignore the 'keywords=' tag, because it does not know it. That's what will keep the program compatible with future versions, this is also the way any TreePad compatible program should approach .hjt files. Programming example To help programmers create fully TreePad compatible software (programs which are able to read current and any future .hjt files, and write to .hjt files), an example programming code fragment is presented below. It illustrates how to read and write a node from/to a standard TreePad .hjt file. We do not guarantee that it is totally correct, the fragment below merely is shown as an example. The programming language used is Borland Delphi, see http://www.freebyte.com/programming/delphi/. The TNode.ReadFromfile method below shows how you can read a TreePad node without relying on knowing which tags you will encounter, and in which order. interface type TDataType = (dt_text, dt_rtf, dt_html, dt_xml); TNode = class ID, level: integer; NodeGUID, caption: string; Article: TStringList; DataType: TDataType; procedure Process_ID(line: string); //procedure will put ID found in line in Node.ID procedure Process_GUID(line: string); //procedure will put GUID found in line in Node.GUID procedure Process_DT(line: string); //procedure will put DT if found in Node.DataType procedure ReadFromFile(var f: textfile); //reads the node from a text file procedure WriteToFile(var f: textfile); //writes the node to a text file class function DataTypeTostr(dt: TDataType): string; class function strToDataType(s: string): TDataType; constructor create; destructor destroy; end; ......................... implementation ......................... //auxiliary functions: function LineHasName(line, name: string): boolean; //true only if line starts with: name + '=' begin //make case insensitive, and remove any trailing or leading spaces: line := lowercase(trim(line)); name := lowercase(trim(name)) + '='; //finally, return true only if line starts with: name + '=': result := (pos(name, line) = 1); end; function GetValueFromLine(line: string): string; //returns the 'value' in the 'name=value' pair contained in line begin result := ''; p := pos('=', line); //return last part of line, only if equal sign is present: if p > 0 then begin result := copy(line, p+1, length(line)); end; end; function MakeNameValue(name, value: string): string; begin result := name + '=' + value; end; function GenerateGUID: string; {implementation of this function here} //TNode methods: constructor TNode.create; begin Article := TStringList.create; self.clear; //initialize end; destructor TNode.destroy; begin Article.free; end; procedure TNode.clear; begin ID := 0; level := 0; NodeGUID := ''; caption := ''; Article.clear; DataType := dt_text; end; class function TNode.strToDataType(s: string): TDataType; var strDataType: string; begin strDataType := uppercase(GetValueFromLine(s)); if strDataType = 'RTF then begin result := dt_RTF; end else if strDataType = 'XML' then begin result := dt_XML; end else if strDataType = 'HTML' then begin result := dt_HTML; end else begin //datatype unknown or plain text: result := dt_Text; end; end; class function TNode.DataTypeToStr(dt: TDataType): string; begin case dt of dt_RTF: result := 'RTF'; dt_HTML: result := 'HTML'; dt_XML: result := 'XML'; else result := 'text'; end; end; procedure TNode.ReadFromFile(var f: textfile); var line: string; begin //initialize: self.clear; //read the first part, until the node tag: repeat readln(line, f); if LineHasName(line, 'id') then self.process_ID(line) else if LineHasName(line, 'dt') then self.process_DT(line) else if LineHasName(line, 'nodeguid') then self.process_GUID(line); until line = ''; //read the node caption and the node level: readln(line, f); self.caption := line readln(line, f); self.level := strToIntDef(line, 0) //finally read the article until the end node tag has been found self.article.clear; //initialize the article list of strings repeat readln(line, f); if line = ' 5P9i0s8y19Z' then break //exit from repeat loop else self.article.Add(line); //add one more line to the article until eof(f); end; procedure TNode.WriteToFile(var f: textfile); var idx: longint; begin //these lines are not essential: if self.NodeGUID = '' then self.NodeGUId := GenerateGUID; writeln(f, MakeNamevalue('id', inttostr(self.ID)); writeln(f, MakeNamevalue('nodeguid', self.NodeGUID)); writeln(f, MakeNameValue('dt', self.DataTypeTostr(self.DataType))); //all the following lines are absolutely essential for writing to a TP file: writeln(f, ''); writeln(f, self.caption); writeln(f, inttostr(self.level)); idx := 0; while idx < self.Article.count do begin writeln(f, article[idx]); inc(idx); end; writeln(' 5P9i0s8y19Z'); end; procedure TNode.Process_ID(line: string); //procedure will put ID (as found in line) in self.ID begin self.ID := strToIntDef(GetValueFromLine(line), 0); end; procedure Process_GUID(line: string); //procedure will put GUID (as found in line) in self.GUID var dummy: string; begin self.NodeGUID := GetValueFromLine(line); end; procedure Process_DT(line: string); //procedure will put DT (as found in line) in self.DataType begin self.DataType := self.strToDataType(GetValueFromLine(line)); end; .......................... Freebyte.com Almere, the Netherlands http://www.treepad.com http://www.freebyte.com email: http://www.treepad.com/support