+<hr width="100%" size="2"><br>
+<h2><a name="Support_for_writing_GEDCOM_files"></a>Support for writing GEDCOM files</h2>
+The Gedcom parser library also contains functions to writing GEDCOM files.
+ Similar as for the parsing itself, there are two interfaces: an interface
+which is very basic, and requires you to call a function for each line in
+the GEDCOM file, and an interface which just dumps the Gedcom object model
+to a file in one shot (if you use the Gedcom object model).<br>
+<br>
+Again, this section focuses on the basic interface, the Gedcom object model interface is described <a href="gom.html#Writing_the_object_model_to_file">here</a>.<br>
+<br>
+<h3><a name="Opening_and_closing_files"></a>Opening and closing files</h3>
+The basic functions for opening and closing Gedcom files for writing are the following:<br>
+<code></code>
+<blockquote><code>Gedcom_write_hndl <b>gedcom_write_open</b> (const char* filename);<br>
+int <b>gedcom_write_close</b> (Gedcom_write_hndl hndl, int* total_conv_fails);<br></code></blockquote>
+The function <code>gedcom_write_open</code> takes a parameter the name of
+the file to write, and returns a write handle, which needs to be used in
+subsequent functions. It returns <code>NULL</code> in case of errors.<br>
+<br>
+The function <code>gedcom_write_close</code> takes, next to the write handle,
+an integer pointer as parameter. If you pass an actual pointer for
+this, the function will write in it the total number of conversion failures;
+you can pass <code>NULL</code> if you're not interested. The function returns 0 in case of success, non-zero in case of failure.<br>
+<br>
+<h3><a name="Controlling_some_settings"></a>Controlling some settings<br>
+</h3>
+Note that by default the file is written in ASCII encoding (and hence e.g.
+accented characters will cause a conversion failure). You can change
+this by calling the following function <i>before</i> calling <code>gedcom_write_open</code>, i.e. it affects all files that are opened after it is being called:<code></code><code><br>
+</code>
+<blockquote><code>int <b>gedcom_write_set_encoding</b> (const char* charset, Encoding width, Enc_bom bom);<br></code></blockquote>
+The valid <code>charset</code> values are given in the first column in the file <code>gedcom.enc</code> in the data directory of gedcom-parse (<code>$PREFIX/share/gedcom-parse</code>).
+ The character sets UNICODE, ASCII and ANSEL are always supported (these
+are standard for GEDCOM), as well as ANSI (not standard), but there may be
+others.<br>
+<br>
+The <code>width</code> parameter takes one of the following values:<br>
+<ul>
+</ul>
+<ul>
+ <li><code><b>ONE_BYTE</b></code>: This should be used for all character sets except UNICODE.</li>
+ <li><code><b>TWO_BYTE_HILO</b></code>: High-low encoding for UNICODE (i.e. big-endian)</li>
+ <li><code><b>TWO_BYTE_LOHI</b></code>: Low-high encoding for UNICODE (i.e. little-endian)</li>
+</ul>
+The <code>bom</code> parameter determines whether a byte-order-mark should
+be written in the file in case of UNICODE encoding (usually preferred because
+it then clearly indicates the byte ordering). It takes one of the following
+values:<br>
+<ul>
+ <li><code><b>WITHOUT_BOM</b></code></li>
+ <li><code><b>WITH_BOM</b></code></li>
+</ul> For both these parameters you can pass 0 for non-UNICODE encodings,
+since that corresponds to the correct values (and is ignored anyway). The
+function returns 0 in case of success, non-zero in case of error. Note
+that you still need to pass the correct charset value for the HEAD.CHAR tag,
+otherwise you will get a warning, and the value will be forced to the correct
+value.<br>
+<br>
+Further, it is possible to control the kind of line terminator that is used, via the following function (also to be used before <code>gedcom_write_open</code>):<br>
+<blockquote><code>int <b>gedcom_write_set_line_terminator</b> (Enc_line_end end);<br></code></blockquote>
+The <code>end</code> parameter takes one of the following values:<br>
+<ul>
+ <li><b><code>END_CR</code></b>: only carriage return ("/r") (cf. Macintosh)</li>
+ <li><b><code>END_LF</code></b>: only line feed ("/n") (cf. Unix, Mac OS X)</li>
+ <li><b><code>END_CR_LF</code></b>: first carriage return, then line feed ("/r/n") (cf. DOS, Windows)</li>
+ <li><b><code>END_LF_CR</code></b>: first line feed, then carriage return ("/n/r")</li>
+</ul>
+By default, this is set to the appropriate line terminator on the current
+platform, so it only needs to be changed if there is some special reason
+for it.<br>
+<h3><a name="Writing_data"></a>Writing data<br>
+</h3>
+For actually writing the data, the principle is that every line in the GEDCOM
+file to write corresponds to a call to one of the following functions, except
+that CONT/CONC lines can be automatically taken care of. Note that
+the resulting GEDCOM file should conform to the GEDCOM standard. Several
+checks are built in already, and more will follow, to force this. There
+is (currently) no compatibility mode for writing GEDCOM files.<br>
+<br>
+In general, each of the following functions expect their input in UTF-8 encoding (see also <a href="#Converting_character_sets">here</a>). If this is not the case, errors will be returned.<br>
+<br>
+Note that for examples of using these functions you can look at the sources for the Gedcom object model (e.g. the function <code>write_header</code> in <code>gom/header.c</code>).<br>
+<h4>Records</h4>
+For writing lines corresponding to records (i.e. on level 0), the following function is available:
+<blockquote><code>int <b>gedcom_write_record_str</b> (Gedcom_write_hndl hndl, Gedcom_rec rec, char* xrefstr, char* value);<br></code></blockquote>
+The <code>hndl</code> parameter is the write handle that was returned by <code>gedcom_write_open</code>. The <code>rec</code> parameter is one of the identifiers given in the first column in <a href="interface.html#Record_identifiers">this table</a> (except <code>REC_USER</code>: see below). The <code>xrefstr</code> and <code>val</code> parameters are respectively the cross-reference key of the record (something like '<code>@FAM01@</code>'), and the value of the record line, which should be <code>NULL</code> for some record types, according to the same table.<br>
+<h4>Elements</h4>
+For writing lines corresponding to elements (inside records, i.e. on a level
+bigger than 0), the following functions are available, depending on the data
+type:
+<blockquote><code>int <b>gedcom_write_element_str</b> (Gedcom_write_hndl hndl, Gedcom_elt elt, int parsed_tag, <br>
+
+ int parent_rec_or_elt, char* value);<br>
+i</code><code>nt <b>gedcom_write_element_xref</b> (Gedcom_write_hndl hndl, Gedcom_elt elt, int parsed_tag, <br>
+
+ int parent_rec_or_elt, struct xref_value*
+value);</code><br>
+ <code>int <b>gedcom_write_element_date</b> (Gedcom_write_hndl hndl, Gedcom_elt elt, int parsed_tag, <br>
+
+ int parent_rec_or_elt, struct date_value*
+value);</code><br>
+ <code>i</code><code>nt <b>gedcom_write_element_age </b> (Gedcom_write_hndl hndl, Gedcom_elt elt, int parsed_tag, <br>
+
+ int parent_rec_or_elt, struct age_value*
+value);</code><br>
+</blockquote>
+<blockquote><code></code></blockquote>
+These functions only differ in the type of the last argument, which is the value of the element.<br>
+<br>
+The <code>hndl</code> parameter is again the write handle returned by <code>gedcom_write_open</code>. The <code>elt</code> parameter is one of the identifiers given in the first column in <a href="interface.html#Element_identifiers">this table</a> (except <code>ELT_USER</code>: see below). The <code>parent_rec_or_elt</code> is the corresponding <code>rec</code> or <code>elt</code>
+identifier of the logically enclosing statement: this will determine the
+level number written on the line, as the level number of the parent + 1.<br>
+<br>
+Some of the identifiers can actually stand for different tags. For this reason, the <code>parsed_tag</code> has to be passed for some of them. This parsed tag is the same as was returned by the callback functions defined <a href="#Start_and_end_callbacks">above</a>, and is an identifier of the form <code>TAG_<i>name</i></code>. This parameter is needed whenever the second column in <a href="interface.html#Element_identifiers">this table</a> shows several possible tags (this is e.g. the case for <code>ELT_SUB_FAM_EVT</code>).<br>
+<br>
+Note that for writing a date value, the given value should be valid, i.e.
+all its struct fields filled in properly and consistent. This can be
+done by calling <code>gedcom_normalize_date</code> (see <a href="interface.html#date">here</a>).<br>
+<h4>User-defined tags</h4>
+For user-defined tags (tags starting with an underscore), there are separate functions, again depending on the data type:<code></code>
+<blockquote><code>int <b>gedcom_write_user_str</b> (Gedcom_write_hndl hndl, int level, char* tag, char* xrefstr,<br>
+ char* value);<br>
+i</code><code>nt <b>gedcom_write_user_xref</b> (Gedcom_write_hndl hndl, </code><code>int level, char* tag, char* xrefstr,</code><br>
+ <code>
+ struct xref_value* value);</code><br>
+ <code></code></blockquote>
+In the case of user-defined tags, the level and tag string are passed verbatim
+(not controlled by the library). This allows to write any extra data
+that doesn't use a standard tag, but is only allowed for tags starting with
+an underscore.<br>