A standard help authoring tool such as HelpNDoc is a software where you generally write and organize content in order to produce documentation files for the end-user. As revisions are needed, the content needs to stay organized, and it usually involves a lot of laborious and error-prone tasks such as copying / pasting content all over the project, deleting content, moving and merging topics… Fortunately, HelpNDoc includes a powerful scripting processor which can help automate documentation creation, maintenance, reorganization… Let’s see how we can leverage HelpNDoc’s scripting capabilities to merge multiple children topics into a parent topic.

Using HelpNDoc’s scripting capabilities

HelpNDoc’s bundled script editor can be used to create and run custom scripts to automate various aspects of HelpNDoc.

Merge topics in HelpNDoc

The purpose of this script is to merge the content of children topics into a parent topic. This means that the script needs to:

  1. Check that a topic is currently selected in HelpNDoc’s table of content. This will be the parent topic;
  2. Create a temporary editor where the content of all the topics will be placed
  3. Place the content of the parent topic into the temporary editor and get a list of its children topics
  4. Iterate through all children topics in order, and place the content in the temporary editor
  5. Place the content of the temporary editor into the parent topic
  6. Delete all children of the parent topic

Warning: as some scripting actions are not reversible, we always recommend that you backup your HelpNDoc project before running a script in case of an error forcing you to go back to an earlier version.

1. Retrieve the parent topic

The currently selected topic in HelpNDoc’s user interface is the parent topic. We need to make sure that a topic is selected, and get its ID:

// Get the currently selected topic
aParentTopicId := HndUi.GetCurrentTopic();
// Make sure that we have a valid selection
if aParentTopicId = '' then
  Exit;

2. Create a temporary editor

The temporary editor is a placeholder for the content of all merged topics. Here is how we can create and free that editor:

// We need a temporary editor
oEditor := HndEditor.CreateTemporaryEditor();
try
  // Here we can insert content into oEditor
finally
  oEditor.Free;
end;

3. Insert the parent topic’s content and get its children

We can now place the parent topic’s content in the topic editor and get a list of its direct children, meaning that only first level children are placed in the list.

// Add the parent topic's content
HndEditor.InsertTopicContent(oEditor, aParentTopicId);
// Get a list of direct children
aFirstLevelChildren := HndTopics.GetTopicDirectChildrenList(aParentTopicId);

4. Iterate through all children topics recursively and add their content

A recursive method can be created to handle children, grand-children and so on… in the right order. We can then call this method for the parent topic’s direct children list:

// Recursive method
procedure DoInsertChildrenContent(aList: THndTopicsInfoArray; anEditor: TObject);
var
  nTopic: Integer;
begin
  // Iterate through children
  for nTopic := 0 to High(aList) do
  begin
    // Insert content
    HndEditor.InsertTopicContent(anEditor, aList[nTopic].Id);
    // Handle children
    DoInsertChildrenContent(
      HndTopics.GetTopicDirectChildrenList(aList[nTopic].Id),
      anEditor
    );
  end;
end;

// Add parent topic's children content
DoInsertChildrenContent(aFirstLevelChildren, oEditor);

5. Replace the parent topic’s content with the temporary editor’s content

The merged content is now ready. We can now replace the parent topic’s content.

// Set the final content to the initial topic
HndEditor.SetAsTopicContent(oEditor, aParentTopicId);

6. Delete children topics

The content from the children topics is now merged in the parent topic. We can finally delete all those children topics as they are not needed anymore.

// Delete children topics
for nTopic := 0 to High(aFirstLevelChildren) do
begin
  HndTopics.DeleteTopic(aFirstLevelChildren[nTopic].Id); 
end;

The whole script and going forward

The whole script is available below and will be part of an upcoming release of HelpNDoc.

procedure DoInsertChildrenContent(aList: THndTopicsInfoArray; anEditor: TObject);var
    nTopic:Integer;
  begin
    // Iterate through children
    for nTopic := 0 to High(aList) do
    begin
      // Insert content
      HndEditor.InsertTopicContent(anEditor, aList[nTopic].Id);
      // Handle children
      DoInsertChildrenContent(
	    HndTopics.GetTopicDirectChildrenList(aList[nTopic].Id),
		anEditor
      );
    end;
  end;

var
  aParentTopicId: string;
  aFirstLevelChildren: THndTopicsInfoArray;
  aCurrentTopicId: string;
  oEditor: TObject;
  nTopic: Integer;
begin
  // Get the currently selected topic
  aParentTopicId := HndUi.GetCurrentTopic();
  // Make sure that we have a valid selection
  if aParentTopicId = '' then
   Exit;  
  // We need a temporary editor 
  oEditor := HndEditor.CreateTemporaryEditor();
  try
    // Add the parent topic's content
    HndEditor.InsertTopicContent(oEditor, aParentTopicId);
    // Get a list of direct children
    aFirstLevelChildren := HndTopics.GetTopicDirectChildrenList(aParentTopicId);
    // Handle them
    DoInsertChildrenContent(aFirstLevelChildren, oEditor);
    // Set the final content to the initial topic
    HndEditor.SetAsTopicContent(oEditor, aParentTopicId);
    // Delete children topics
    for nTopic := 0 to High(aFirstLevelChildren) do
    begin
      HndTopics.DeleteTopic(aFirstLevelChildren[nTopic].Id); 
    end;
    // Current topic is not automatically updated: focus the project topic to change the selection
    HndUi.SetCurrentTopic(HndTopics.GetProjectTopic);
  finally
    oEditor.Free;
  end;
end.

More than a straightforward help authoring software, HelpNDoc includes various advanced tools to simplify and speed up the documentation creation process, such as its amazing script editor and the various API it can access to. Feel free to download your free version of HelpNDoc now to check it out and play with the various API methods available.

See also


Categories: articles