Overview
The HotDocs® (HD) converter released with Version 11 of XpressDox will attempt as far as possible to prepare a set of XpressDox templates which, ideally, the user will be able to run as-is after the conversion is complete.
Firstly, there are quite a few terminological and usage differences. Here are some of them:
- A dialog becomes a Tab in XpressDox
- In XpressDox, a data element is an item of information that typically is captured by the user in the interview, but may also originate in a database or other source of data. A variable in XpressDox is something that the template author defines, and is only available when the template is being assembled. Both of these are called variables in HD.
- XpressDox has what many HD users call a “multiple choice” feature, but is probably what XpressDox calls a “Set All Group”. In XpressDox, this can be a set of check boxes or radio buttons. In the latter case, each choice can have more than two options.
- The XpressDox command CaptureInGrid achieves something similar to what the “spreadsheetOnParent” option in HD is used for.
- XpressDox is basically an XML engine. The data are all in XML, which does not have the concept of a data type – every element value is a string. So where HD has the concept of a field being a number, or a date, etc., XpressDox has the Rule command which the template author can employ to ensure that users enter data in the correct format. Some of these Rules (like IsNumber and IsDate) are applied automatically if XpressDox can infer from usage that this is appropriate. The converter will apply those rules where necessary.
A look at the converted documents
There are three types of documents that the conversion produces: the templates themselves, and then an “Interview” template and a “Scripts” template. The latter two are generated from one or more of the component (.cmp) files.
Typically a set of templates would have a few “main” templates – i.e. those that the user will actually ask to be run. These main templates then include (HotDocs INSERT) sub-templates. Most XpressDox authors will create a “code template” with all of the XpressDox commands which control the interview, and another template with all the scripts. These would then be included in the main templates, usually at the start. If you have a look at any of the templates which the converter produced, you will see that there are one or two Include commands at the top which refer to the generated Interview template and/or the Scripts template. The converter might have surrounded the Includes with Comments, because when there are multiple templates in a suite, it is not easy to determine whether a template is a main template or an included template. Only the main templates should have the Interview and Scripts templates included by them.
It may be that some HD fields cannot be handled by the converter. These are copied as-is into the converted template, but will be surrounded in a function call to a function called “Unconverted”. The fillpoints containing this function call are highlighted in yellow. Some examples of HD fields that will not be converted are:
-
- There is a HD variable which has not been defined in the component file.
- The format specification “a, b, and c” is accomplished in such different ways in XpressDox that a direct conversion from HD is not possible.
- Setting a repeating instance of a variable (e.g SET ABC[counter] TO “Something”) is achievable in XpressDox using Arrays, but is probably not what an XpressDox template author would do.
- The HD FILTER concept – again this is achievable in such a different way in XpressDox that a direct translation is not really possible.
- A format specification that refers either to a computation or a HD variable.
- None of the HD commands related to interview construction will be converted. Most are ignored and won’t even appear as Unconverted.
Quirks
XpressDox requires that placement of “block” commands conform to some rules. A block command is any XpressDox command whose scope is terminated by an «End()
» command. In other words, If, ForEach and RepeatWhile. The rule is that if the starting command and ending command are in separate paragraphs in the document, then the start (e.g. If()) and End() must each be in their own paragraph.
This is one situation where the first time a converted template is run will probably result in some XpressDox messages asking you to put fillpoints into their own paragraphs. It is a situation that will be addressed in a future version of XpressDox.
If there are any Unconverted instances that don’t conform to the above, or you have any other suggestions to make, please let us know at support@xpressdox.com.
The Interview Template
In the Beginning
The first 3 commands in the Interview template are generated automatically regardless of the contents of the HD component file. They are:
«InterviewIsWizard(Yes)
»: The actual interview generated by this will (in the Desktop at least) look more like what HD users are used to than the default XpressDox interview.
«ExpectXSLTFormatNumbers(Yes)
»: It is good practice to have this command active in every template. It is rather complicated, and so it would be best to have a look at Arithmetic in XpressDox for more information. For the moment, just leave this command here, it will do a lot of useful work for you, even if you don’t understand why.
«AlignCaptions(Right)
»: It seems that HD authors typically use fairly long captions for some of the variables – now data elements. Aligning the captions to the right makes it easier for the eye to follow the shorter captions.
Dialogs and Tabs
After this, the Interview template contains a section for each dialog in the HD component file. Each section contains the name of the HD dialog in a Word Heading style, so that the entire document can be easily navigated via the Word navigation pane. The reason that this kind of documentation can be provided in the Interview template is that it will be included with the IncludeCodeTemplate command. This command will ignore any line (paragraph) which has no XpressDox fillpoints in it.
For non-repeating data elements, an XpressDox Tab command is created, with the name (or Title) of the HD dialog, followed by the data elements which will be in that Tab. This is the time to note that XpressDox data elements, since they are really XML element names, cannot (unlike HD variable names) contain spaces or other punctuation. The converter will translate these non-XML characters to underscores. There is a mechanism by which you can instruct the converter to change the HD variable names to what might be totally different XpressDox data element names. This will be discussed later.
Sequence of data elements in the interview
The Tab commands have been produced in the Interview template in the sequence in which the dialogs were found in the component file – which is alphabetical. This is probably not the sequence in which you would like them to appear in the interview. The way to get the Tabs into the sequence that you would like them in the interview, is to move them to the top of the Interview template, and then put them in the sequence in which you would like them to appear in the template.
The general rule for positioning of data elements in the interview is that they will be sequenced in the order in which they are first encountered in the template – in this case the Included templates are also taken into account. Hence if your Interview template is the first to be Included in any template, then the sequence of the data elements in the interview will be dictated by the Interview template. (Even then you can modify the sequence for any particular template by using The CaptureLater Command)
Escaping special characters
You will probably notice that in some places there is an exclamation mark (point) in front of certain characters, such as in
«Caption(Amount,Enter the amount !(without a dollar sign!))
»
This is called “escaping” the character after the !, and is required when that character is to appear in the Caption and not be regarded as the closing parenthesis of the command.
Characters which should be escaped in this way are:
,
(
)
"
'
:
ChooseFromFile
There are some places where the converter can recognize that a list of items should rather be sourced from a file as against hard coding the list in the template. Typically this will be when the user needs to choose from a list of states. Then you would usually like either the name of the state, or the abbreviation to appear in the document.
In addition, there are often many parties for which a choice of states must be made. This situation as well as the above can both be achieved by having one file with a list of all the state names and abbreviations, and have the same list be presented for each party where a state is required.
The converter will generate both the file and the ChooseFromFile command. Unfortunately, it will produce one file for each different multiple choice variable in HD, but it should be fairly straightforward to change these ChooseFromFile commands to refer to only one file. Have a look at The ChooseFromFile Command.
ChooseFromSamples
Where a multiple choice list in HD presents a list of options, but also allows an “other” or “none of the above” option, then the interview generator will produce the XpressDox ChooseFromSamples command. This command, by definition, allows the user to type in a value which is not in the drop down list. The interview generator will explicitly exclude the option “other”. In the templates, or scripts, the HD OTHER function is translated in a way that, if the user did actually type in a value not in the drop down list (i.e. an OTHER value), then the value that the user typed is returned, but if they DID choose one of the samples, the translation of the OTHER function returns an empty string (because it is not an OTHER value). It might be that this is not what you want, but an edit of the template, or the interview, would be easy to achieve.
The Interview CSV file
If the option to generate XpressDox Define commands in the interview is chosen, then the converter will also generate a Comma Separated Values (CSV) file containing all the interview commands, as well as other useful columns, such as the sequence in the original HD dialog of the fields. This file can be opened in MS Excel. In the case of very large interviews, it becomes easier to manipulate the Excel file than it is to modify the XpressDox interview template. The columns in the spreadsheet are self-explanatory, and the main point is that the columns are organised in such a way that the Define commands can be created from the spreadsheet by easy to construct Excel functions.
The Scripts Template
Each HD computation is translated into an XpressDox Script, with the name being a straight forward translation from the non-XML HD format to an acceptable XML format. The converter understands HD parameters, and creates a Script with parameters. There are also at least two standard Scripts that are generated, and used internally by the converter. They are the Scripts named OrdinalValue and ShowOrDefault. More may be added with time.
There are two Script files that are produced – one where, for each HD computation/script, each of the lines in the computation is converted into an XpressDox fillpoint. The second Scripts file has SingleFillpoints in the name. It is recommended that you start off with the default Scripts file – i.e. the one for which the converter will put an IncludeTemplate command at the top of the converted template. It will probably be that as you start to run the converted templates, XpressDox will issue a message saying something like: “In order the use a script as a function, the script body must consist of exactly one fillpoint”. If this happens, then locate the script in question, and copy it from the “SingleFillpoints” Scripts template. You could decide to just use the SingleFillpoints Scripts template in its entirety, but then you might bump into some of the issues highlighted in the Advanced Usage section below.
Advanced Usage
Although the fairly simple templates in both systems will be similar to each other, as soon as the more complex features of HD have been used, then there will be more and more striking differences between how things are done in the two systems. In order to achieve the aim of making a set of templates which can be run with as little modification as possible, some features of the converted templates are not what an experienced XpressDox author would use to achieve the same objective. This is particularly true of the converted computations, and especially those reduced to single fillpoints. In fact, a few new functions have been introduced into XpressDox with the sole purpose of achieving a runnable result from the conversion.
These new functions are RepeatForEach, While, and IIfSet. They can be used by anyone, but are not included in the XpressDox Command Editor because there are much better ways to achieve the same objectives taking into account that XpressDox is basically an XML engine, and each fillpoint is an XPATH expression. XPATH is a syntax for navigating an XML dataset. You can read about it here: XML and XPATH. If you are a serious document assembly template author (and if your are reading this far, then you probably qualify for that description) then understanding XPATH will be indispensable for advanced template authoring in XpressDox.
The converter is not an artificial intelligence engine, but, in order to come as close as possible to the aim of having a runnable solution with as few changes as possible, the converter needs to perform the conversion in an almost literal fashion. A little like taking the the works of Shakespeare one sentence at a time and passing each sentence through Google Translate – you will get a passable translation but nothing like what a human translator can achieve.
Some Examples of Rewrites
RepeatForEach
An example of where a script would benefit from a total re-write using XpressDox features would be the following typical computation conversion. The HD computation is called “ABC in Community CO”, and has a script which looks like:
FALSE
REPEAT ABC
IF ABC Option MC = "c"
TRUE
END IF
END REPEAT
The converter will produce the following XpressDox Script:
«
Script(ABC_in_Community_CO)
»
«IsTrue(Execute(
»
SetV('RESULT',IsTrue('FALSE')),
RepeatForEach(ABC,
IIf((ABC_Option_MC = 'c'),
SetV('RESULT',IsTrue('TRUE'))
,'')),IsTrue(GetV('RESULT'))))
«ScriptEnd(ABC in Community CO)
»
The above XpressDox script would work, but, if written by an experienced XpressDox template author, would become:
«
count(ABC[ABC_Option_MC = 'c']) > 0
»
In fact, so simple that the author might even decide not to put it into a Script but to write it directly into the template wherever necessary.
IIfSet
The IIfSet function is very similar to the IIf function, but in the context of a single fillpoint script, it is needed instead of an IIf where a variable will be set in either the “then” or “else” branch of the IIf. (IIf is short for InlineIf.)
Firstly, just about any Script containing an IIfSet would benefit from a re-write, if for no other reason than to make it more readable. Here is a Script that will work as-is, and its re-write:
«
Script(Final_decree_or_pp_CO)
»
«Execute(IIfSet((Case_type_MC = 'Custody'),'SetV(<RESULT>,<final decree>)','SetV(<RESULT>,<final parenting plan>)'),GetV('RESULT'))
»
«ScriptEnd(Final decree or pp CO)
»
The re-write:
«
Script(Final_decree_or_pp_CO)
»
«Execute(SetV('RESULT',IIf((Case_type_MC = 'Custody'),'final decree','final parenting plan')),GetV('RESULT'))
»
«ScriptEnd(Final decree or pp CO)
»
Or, even better:
«
Script(Final_decree_or_pp_CO)
»
«IIf((Case_type_MC = 'Custody'),'final decree','final parenting plan'))
»
«ScriptEnd(Final decree or pp CO)
»
Here are two related Scripts, produced by the converter, which will not work as-is:
«
Script(ABC_account_CO)
»
«IsTrue(Execute(SetV('RESULT',IsTrue('FALSE')),RepeatForEach('ABC_account',IIfSet((Filter_ABC_accounts_CO()),'SetV(<RESULT>,IsTrue(<TRUE>))','')),IsTrue(GetV('RESULT'))))
»
«ScriptEnd(ABC account CO)
»
«
Script(Filter_ABC_accounts_CO)
»
«ABC_ch = 'c' and ABC_aw != 'res'
»
«ScriptEnd(Filter ABC accounts CO)
»
When the first script is invoked somewhere in the template (or in another Script) then it would produce a syntax error. A re-write of the first Script would be:
«
Script(ABC_account_CO)
»
«ABC_account[Filter_ABC_accounts_CO()]> 0)
»
«ScriptEnd(ABC account CO)
»