Publishing Engine Programmer's Guide > PTC Arbortext Publishing > The Publishing Framework > The Inner Layer of the Publishing Framework
  
The Inner Layer of the Publishing Framework
The inner layer of the publishing framework is operation-independent, which means that it doesn’t care what kind of output the operation is producing. Conceptually, its operation is intended to run the content pipeline, with calls to outer layer callbacks that provide type-specific processing before and after the content pipeline runs. In practice, this simple picture is complicated in a number of ways, some arising from the needs of various publishing types, and some from the requirements imposed by using Arbortext PE server.
The inner framework is invoked when the outer framework calls:
compose::compose_for_type(doc, comp_type, interactive, params[], preproc_cb, dialog_cb, fixup_cb, postproc_cb)
doc
is the document being published
comp_type
is the name of the content pipeline to run
interactive
is set to 1 if the operation was invoked from the Arbortext Editor user interface
params
is the parameter array
preproc_cb, dialog_cb, fixup_cb, postproc_cb
are each strings containing the names of the four outer layer callback routines. An empty string bypasses the callback.
The callback can return:
-1
if the user aborts the operation, such as by choosing Cancel from the dialog box
0
if the operation fails
1
if the operation succeeds
compose_for_type logs its operation in the event log, a separate document that can be displayed after the operation. It reports any warnings, errors, or a fatal error, and Arbortext Editor can display the event log.
The compose_for_type function starts a new publishing job in the event log to collect messages, calls compose_for_type_int to gather the messages, and then terminate the event log job afterward.
* 
The function compose_for_type_int has the same parameters as compose_for_type, and it returns the same results. Future discussion will refer to compose_for_type for brevity.
Processing divides at this point. If Arbortext PE server is enabled, compose_for_type follows one code path. If Arbortext PE server is not enabled, processing follows another.
compose_for_type Processing
* 
In every operation performed by compose_for_type, a failure writes an error to the event log and returns 0.
1. The compose_for_type operation begins by determining whether the request is being sent to Arbortext PE server. If set peservices is on and the parameter compose.suppress-e3-composition is not present in the parameter array, then the Arbortext PE server will perform the publishing operation.
2. Then compose_for_type checks to make sure that information about the Arbortext PE server is available, and that the Arbortext PE server supports the version of Arbortext Editor that is running.
3. Next, compose_for_type calls the pre-processing callback, if one was provided.
If the callback returns -2, compose_for_type returns 0.
If the callback returns -1, compose_for_type logs a generic failure message, and returns 0.
If the callback returns 1 or 2, compose_for_type continues processing.
4. Next, compose_for_type either creates the content pipeline or initializes for Arbortext PE server publishing. Both operations load the default parameters for the operation type into the parameter array. Then compose_for_type calls get_composer to create the content pipeline, passing its comp_type parameter as the name of the .ccf file to load. If the Arbortext PE server is performing the publishing, compose_for_type calls compose::initialize_e3_composition to retrieve the default Arbortext PE server publishing parameters, again passing comp_type as the pipeline name.
For example, if the output type is pdf, both routines look for a file named pdf.ccf in the composer path on the client or server machine.
If the pre-processing callback returned 2 (meaning processing should continue, but compose_for_type should skip loading the default content pipeline parameters), then the call to get_composer or initialize_e3_composition is omitted, and no default parameters are loaded.
5. compose_for_type determines if the publishing operation is interactive and a dialog callback was passed. When compose_for_type calls the dialog callback, a return value of -1 causes compose_for_type to return 0. If the callback returns 0, compose_for_type logs an error message and returns. Otherwise processing continues. If the parameter array contains values controlling profiling, the values are modified to work with the profiling filters in the content pipeline.
6. If the document being published contains Arbortext data merge queries, compose_for_type calls the data merge facility to update the document with the query results.
7. If the publishing parameters specify profiling, compose_for_type makes sure that the values in the publishing parameter array are properly initialized.
8. If the document being published is a DITA topic, compose_for_type sets up some parameters to either set up some extra parameters to publish the topic as is or sets parameters to wrap the topic in a temporary DITA map.
9. compose_for_type calls the parameter fixup callback, if one was specified. If the callback returns -1, compose_for_type returns 0. If the fixup callback returns 0, compose_for_type logs a message and then returns. The fixup callback can return 1 for success or 2 for success but suppress the content pipeline run. If 2 is returned, that value is saved for later. (In the second step of Processing if not using Arbortext PE server later in this section, if the fixup callback returns 2, compose_for_type skips running the content pipeline.)
10. compose_for_type calls the publishing preprocessor hook to see if there is custom code that was registered using the ACL add_hook function. The hook function code can modify the parameter array as needed. If it returns a value less than zero, the publishing process terminates. If not, operation continues. The custom code must follow this signature:
hook_function(doc, type, interactive, params[])
doc
is the document being published
type
is the name of the composer
interactive
is set to 1 if the operation was invoked from the Arbortext Editor user interface
params
is the parameter array
11. compose_for_type checks to see whether the document being published is a DITA map. If so, it recursively calls an outer-framework routine, compose_for_createprds, to transform the DITA map into a preliminary resolved data set, which is a document that includes the topics and other content referenced by the DITA map. Publishing continues with the PRDS in place of the original document.
Processing divides at this point. If Arbortext PE server is enabled, copose_for_type follows one code path. If Arbortext PE server is not enabled, processing follows another.
Processing if using Arbortext PE server
1. First, compose_for_type sets some additional parameters that control execution of the Arbortext Publishing Engine Client Composer.
2. compose_for_type calls the Arbortext Publishing Engine Client Composer, then returns to its caller. The Arbortext Publishing Engine Client Composer handles communication with the Arbortext PE server and calls the post-process callback when the Arbortext PE server responds.
3. If the publishing operation is queued on the Arbortext PE server, then the post-process callback does not run. Instead, when the user retrieves the result of the queued publishing operation from the Arbortext PE server, Arbortext Editor runs the post-process process as if the operation had just completed.
Processing if not using Arbortext PE server
1. compose_for_type runs the content pipeline. It skips the pipeline run if instructed to by the fixup callback and the document being published is not a DITA map. If the pipeline run succeeds and compose_for_type called the DITA preprocessor, it now calls compose::postprocessForDITA to delete the temporary DITA PRDS document. If the pipeline returns an error, processing terminates.
2. compose_for_type calls the post-process callback function, then returns to its caller.