Prevent conflict with lower and upper case for outlier cases
[goodguy/cin-manual-latex.git] / parts / Developer.tex
index 6fc9f00149c32916575a3036a19a2fb20b1a146b..34d355f38c0ba780867b0f6c97199225379028be 100644 (file)
@@ -20,7 +20,7 @@ So, an example of what happens in 4 steps for a single-user build would be as fo
 
 \begin{enumerate}[nosep]
        \item unpack/patch source code: \\
-       \texttt{git clone --depth 1 ``git:/{\dots}/target'' cinelerra5} \\
+       \texttt{git clone -{}-depth 1 ``git:/{\dots}/target'' cinelerra5} \\
        \texttt{./autogen.sh}
        \item configure build:\\
        \texttt{./configure --with-single-user}
@@ -98,18 +98,35 @@ FFmpeg is a \textit{strongly connected} component in the build linkage and widel
        \item \texttt{./configure} {\dots}
 \end{itemize}
 
-Specific information on using the current ffmpeg GIT repository follows.  You have to supply the actual URL location of the ffmpeg git as you can see in this example \texttt{?bld.sh?} script:
+\section{Experimental Builds}
+\label{sec:experimental_builds}
+\index{build!experimental}
+
+The main compilation we have seen leads to building \CGG{} with its own internal ffmpeg, which includes its stability and feature patches. Normally ffmpeg is updated to version x.1 of each release. The reasons why it is best to use thirdparty with their static versions of the libraries and ffmpeg are explained in detail in \nameref{sec:latest_libraries} and in \nameref{sub:unbundled_builds}.
+
+You can still compile \CGG{} with ffmpeg-git to enjoy the latest version. This build may lead to feature variation and less stability, but in most cases will work perfectly fine.
+You have to supply the actual URL location of the ffmpeg git as you can see in this example \texttt{bld.sh} script:
+
+\begin{lstlisting}[numbers=none]
+       #!/bin/bash
+       ./autogen.sh
+       ./configure --with-single-user --with-booby --with-git-ffmpeg=https://git.ffmpeg.org/ffmpeg.git
+       make && make install ) 2>1 | tee log
+       mv Makefile Makefile.cfg
+       cp Makefile.devel Makefile
+\end{lstlisting}
+
+Since the procedure for obtaining the latest ffmpeg version is not always kept up-to-date and the line numbers will always change, you may have to create some patch first. Generally those line numbers are only updated by a developer when a new stable version with worthwhile features is actually included in the \CGG{} build. FFmpeg is constantly changing and many times the git version is not as stable as desired.
+
+Finally, it is possible to compile \CGG{} so that it uses ffmpeg which is already installed on the system. This build takes less time to compile and may increase performance in both rendering and timeline manipulation. Again, there may be variations in functionality and less stability.
+Getting a build to work in a system environment is not easy. If you have already installed libraries which are normally in the thirdparty build, getting them to be recognized means you have to install the devel version
+so the header files which match the library interfaces exist. If you want to build using only the thirdparty libraries installed in your system, just include \texttt{-–without-thirdparty} to your configure script. For example:
 
 \begin{lstlisting}[numbers=none]
-#!/bin/bash\newline
-() ./autogen.sh\newline
-./configure --with-single-user --with-booby --with-git-ffmpeg=https://git.ffmpeg.org/ffmpeg.git
-make && make install ) 2>1 | tee log
-mv Makefile Makefile.cfg
-cp Makefile.devel Makefile
+./confgure --with-single-user --disable-static-build --without-thirdparty --without-libdpx
 \end{lstlisting}
 
-Since the procedure for obtaining the latest ffmpeg version is not always kept up-to-date and the line numbers will always change, you may have to create that patch first. Generally those line numbers are only updated by a developer when a new stable version with worthwhile features is actually included in the \CGG{} build. FFmpeg is constantly changing and many times the git version is not as stable as desired.
+The library, libdpx, is just such an example of lost functionality: this build of \CGG{} will not be able to use the DPX format.
 
 \section{Configuration Features}
 \label{sec:configuration_features}
@@ -210,6 +227,7 @@ Optional Features:
   --enable-openjpeg       build openjpeg (auto)
   --enable-libogg         build libogg (auto)
   --enable-libsndfile     build libsndfile (auto)
+  --enable-libsvtav1      build libsvtav1 (no)
   --enable-libtheora      build libtheora (auto)
   --enable-libuuid        build libuuid (yes)
   --enable-libvorbis      build libvorbis (auto)
@@ -317,12 +335,13 @@ Individual package libraries can be rebuilt, via:
 
 The rule targets create the set of thirdparty packages which are built from local source archive copies of thirdparty source code and patches, if needed.  The build rule set of dependencies allows for compiling multiple thirdparty programs simultaneously using maximum computer resources.  This parallel build speeds up the process considerably.  For example, these are full static build timings on the production build machine (full build includes building all thirdparty programs as well as all of \CGG{}):
 
-\hspace{2em}
-\begin{tabular}{@{}rcr}
-       1 cpu & = & 61 mins\\
-       12 cpus & = & 7.5 mins\\
-       24 cpus & = & 2 mins\\
-\end{tabular}
+\begin{center}
+       \begin{tabular}{@{}lcr}
+               1 cpu & = & 61 mins\\
+               12 cpus & = & 7.5 mins\\
+               24 cpus & = & 2 mins\\
+       \end{tabular}
+\end{center}
 
 \section{Using the very latest Libraries}
 \label{sec:latest_libraries}
@@ -351,7 +370,7 @@ developer's feedback and experimentation.
 \begin{description}[noitemsep]
      \item Status - currently \CGG{} is staying at 0.5.  This is disappointing because there
 may be speed gains in version 0.6 that would be beneficial. However, it is usable for decoding
-whereas libaom is just too slow.  Unfortunately, it has no effective encoder.
+whereas libaom is a lot slower.  Unfortunately, it has no effective encoder.
      \item Problem - 0.6 dav1d requires NASM 2.14 and uses instructions like vgf2p8affineqb,
 not exactly an "add" instruction. It also uses meson which is not widely available on all
 distros.  The only distros that are built for \CGG{} that are at 2.14 are the latest version
@@ -388,20 +407,12 @@ compile; and use binaries that you do not know what they contain since no source
 Look into opencv4/opencv2/core/types.hpp:711;27
 \end{description}
 
-\textbf{webp}
-\begin{description}[noitemsep]
-     \item Status - currently at version 1.1.0
-     \item Problem - requires cmake 3.5 
-     \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7
-     \item Your workaround - upgrade on those systems to cmake 3.5
-\end{description}
-
 \textbf{libaom}
 \begin{description}[noitemsep]
-     \item Status - currently at version 1.0.0 
-     \item Problem - requires cmake 3.5 
+     \item Status - currently at version 3.0.0 for older O/S and 3.1.1 for newer O/S
+     \item Problem - requires cmake 3.5 at 3.0.0 and 3.6 for 3.1.1
      \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7
-     \item Your workaround - upgrade on those systems to cmake 3.5
+     \item Your workaround - upgrade on those systems to cmake 3.6
 \end{description}
 
 \textbf{x10tv}
@@ -470,7 +481,10 @@ It comes back with the routine as:
 \label{sec:valgrind_support_level}
 \index{build!valgrind}
 
-Valgrind is a memory mis-management detector.  It shows you memory leaks, deallocation errors, mismanaged threads, rogue reads/writes, etc.  \CGG{} memory management is designed to work with Valgrind detection methods.  This assists in developing reliable code.  Use of Valgrind points out problems so that they can be fixed.  For example, when this version of \CGG{} shuts down, it deallocates memory instead of just stopping, thus making memory leak detection possible.
+Valgrind is a memory mis-management detector.  It shows you memory leaks, deallocation errors, mismanaged threads, rogue reads/writes, etc.  \CGG{} memory management is designed to work with Valgrind detection methods.  This assists in developing reliable code.  Use of Valgrind points out problems so that they can be fixed.  For example, when this version of \CGG{} shuts down, it deallocates memory instead of just stopping, thus making memory leak detection possible.  An alternative to Valgrind is
+\textit{heaptrack} which has good documentation and for large programs can run
+faster.  You can find the source and information about it at {\small\url{https://github.com/KDE/heaptrack}}.
+\index{valgrind!heaptrack}
 
 The best way to compile and run valgrind is to run the developer static build. This takes 2 steps and you must already have gdb and valgrind installed:
 
@@ -483,6 +497,10 @@ The best way to compile and run valgrind is to run the developer static build. T
                \texttt{CFLAGS=-ggdb make -j8 rebuild\_all}
 \end{enumerate}
 
+If you frequently make mods and changes in \CGG{} or the thirdparty libraries, do not depend on those
+compiled versions to have the headers updated; so be sure to fully rebuild as shown in the previous 2
+steps before running valgrind or you will get false errors.
+
 Now your \CGG{} obj has all of the debug stuff. Next run valgrind as root for the most useful results:
 
 \hspace{2em}\texttt{cd /path/cinelerra-5.1/cinelerra}
@@ -496,6 +514,10 @@ It is impossible to test everything with valgrind because some things are just t
 deadly. The listing of the memory leaks can be quite voluminous so locating the \textit{LEAK SUMMARY} section
 towards the end of the report is most useful.
 
+Another very useful valgrind run to locate unitialized variables while executing is:
+
+\hspace{2em}\texttt{valgrind -{}-log-file=/tmp/log -{}-tool=memcheck\\
+       -{}-num-callers=32 ./ci}
 
 \section{CFLAGS has -Wall}
 \label{sec:cflags_has_-wall}
@@ -653,6 +675,134 @@ The summary line above in Bold represents the User time, System time, Real time
 
 So why use a Profiler? Because it is the ``ls'' for executable functions!!
 
+\section{Working on AppImage}
+\label{sec:working_on_appimage}
+
+You can work on the appimage file to make changes and fix errors, or you can create a new appimage from scratch containing customizations. For example, you can add new rendering presets, update the Context-Help, change libraries that are no longer supported by the current distro, or make other modifications.
+
+\subsection{Managing AppImage}
+\label{sub:managing_appimage}
+\index{appimage!management}
+
+A limitation of using AppImage instead of installing the binary or compiling from git, is that there is only a single file without the ability to browse the directory structure or to look for files to edit or check. So if using \CGG{} leads to some errors, it is not possible to investigate and fix the problem. Which means if you want to add the most up-to-date Context-Help or want to introduce some custom presets, that can not be done.
+
+Because the appimage file is nothing more than a compressed file containing the same structure as the installed program plus other libraries that allow the program to run independently from the system, the content can be extracted so that you can work on it as you would have on the normally installed program.  To do this you will need the appimage management program.
+Many Linux distros come with this managment program by default, but others may not. For instance in the case of Arch Linux the \texttt{appimagetool-bin} package from AUR needs to be installed. 
+
+To work on the appimage, first unpack it using the command\protect\footnote{Example provided by Glitterball3} (note that you do not have to be root to do any of the following):
+
+\begin{lstlisting}[numbers=none]
+       /{path to appimage}/CinGG-yyyymmdd.AppImage --appimage-extract
+\end{lstlisting}
+
+You will now have a \texttt{squashfs-root} folder in your current directory containing \texttt{/usr/bin/} as well as other files and directories such as \texttt{/usr/lib} and \texttt{/usr/share}. \texttt{Bin} is the folder similar to the one installed with \CGG{} and contains the files that you can work on. Now it is possible to make changes like adding a custom preset in \texttt{/ffmpeg/video} or replacing a library that no longer works with a more recent version by working in \texttt{/squashfs-root/usr/lib}.
+
+To start the unpacked program from the bin folder use the command:
+
+\begin{lstlisting}[numbers=none]
+       /{path to appimage}/squashfs-root/usr/bin/./cin
+\end{lstlisting}
+
+After making your changes, to get back to having an appimage file instead of having to run the program from the bin folder, you can take the extra step of recompressing the squashfs-root folder.
+To do so use linuxdeploy's appimage, a program that can also be useful for creating appimages from scratch (\url{https://github.com/linuxdeploy/linuxdeploy/releases/continuous}).
+
+The steps to recreate the appimage are:
+
+\begin{enumerate}
+       \item Copy the linuxdeploy appimage to \texttt{/\{path to appimage\}} and make sure it is executable.
+       \item Then use the command:
+       \begin{lstlisting}[numbers=none]
+               ./linuxdeploy-x86_64.AppImage --appdir squashfs-root --output appimage
+       \end{lstlisting}
+\end{enumerate}
+
+A new appimage will be created like the original but containing the changes.
+
+Alternatively, download the \texttt{appimagetool} version from \url{https://github.com/AppImage/AppImageKit/releases} if available for your distro and use the command:
+
+\begin{lstlisting}[numbers=none]
+       ./appimagetool --comp /{path to appimage}/squashfs-root /tmpCinGG-yyyymmdd.AppImage
+\end{lstlisting}
+
+Now there will be an appimage called \textit{CinGG-yyyymmdd.AppImage} with the changes that were made.
+
+NOTE: for the \textbf{bdwrite} program which is used to create the udfs image to burn Blu-ray
+media (or any other standalone program), you will find it in the squashfs-root/usr/bin
+subdirectory. You only need to do the initial unpacking extract step and then just copy
+bdwrite and the entire squashfs-root/usr/lib directory to a convenient permanent place for
+usage.  Then when running bdwrite, you will have to first export the libary path by typing
+this command in the window first:
+\begin{lstlisting}[numbers=none]
+export LD_LIBRARY_PATH=/{put your copied usr/lib path here}:$LD_LIBRARY_PATH
+\end{lstlisting}
+
+\subsection{Build the CinGG.AppImage from scratch}
+\label{sub:built_appimage_scratch}
+\index{appimage!creating}
+
+If a developer wants to create an appimage from git, follow these next few steps. An existing automated script is available, \texttt{bld\_appimage.sh}, in the directory \texttt{/\{path to cinelerra-5.1\}}.
+
+This follows four steps:
+
+\begin{itemize}
+       \item Build static version of \CGG{}.
+       \item If desired and needed, build the HTML manual for context-sensitive help.
+       \item Organize code and if present, the manual, in a AppImage specific format \textit{AppDir}. Do this with tool makeappimage, which is built if needed.
+       \item Call an external tool to make the AppDir into an AppImage
+\end{itemize}
+
+Start by downloading the \CGG{} source from Cinelerra's git. The last parameter is a directory name of your choice, the directory must not exist. As example, the name \textit{cinelerra5} is used.
+
+\begin{lstlisting}[numbers=none]
+       git clone --depth 1 "git://git.cinelerra-gg.org/goodguy/cinelerra.git" cinelerra5
+\end{lstlisting}
+
+The source will be in a subdirectory \texttt{cinelerra-5.1} of the directory created by the \textit{git clone} operation.
+
+If context-sensitive help is needed, download the manual sources too, with a different destination directory.
+
+\begin{lstlisting}[numbers=none]
+       git clone --depth 1 "git://git.cinelerra-gg.org/goodguy/cin-manual-latex.git" cin-manual-latex
+\end{lstlisting}
+
+Then move to the \texttt{/\{path to cinelerra-5.1}/\} directory.
+
+
+There are two preliminaries to do before running the script:
+
+1- If context sensitive help in the appimage version is required, the source of the manual and the tools (packages) to build it must be on the system. In the bld\_appimage.sh script, set the variable \texttt{MANUAL\_DIRECTORY=\$(pwd)/../../ cin-manual-latex} to the path of the source of the manual. If the variable is empty, or the specified directory does not exist, \CGG{} will be built without built-in help. The path to the manual source can be an absolute or relative one.
+
+2- The script bld\_appimage.sh uses a platform specific version of appimagetool so that it can create appimages for \textit{x86\_64}, \textit{i686}, \textit{aarch64}, or \textit{armv7l} architecture. We need to add appimagetool-(platform).AppImage to the \texttt{/\{path to cinelerra- 5.1\}/tools} directory, or somewhere in your path. You can download the tool for your system (e.g. appimagetool-x86\_64.AppImage) from git: {\small\url{https://github.com/AppImage/AppImageKit/releases}}
+
+Always remember to make it executable. The four supported platforms are:
+
+\begin{itemize}
+       \item appimagetool-aarch64.AppImage
+       \item appimagetool-armhf.AppImage
+       \item appimagetool-i686.AppImage
+       \item appimagetool-x86\_64.AppImage
+\end{itemize}
+
+With the preparations done, let's go back to the bld\_appimage.sh script.
+
+Make the script executable if it isn't already:
+
+\begin{lstlisting}[numbers=none]
+chmod x+u bld_appimage.sh
+\end{lstlisting}
+
+Start the script with:
+
+\begin{lstlisting}[numbers=none]
+./bld_appimage.sh
+\end{lstlisting}
+
+The first part of the script customizes \texttt{configure}, depending on the architecture of our system. The next step compiles and installs \CGG{} in the \texttt{bin} subdirectory. The third part creates the manual in HTML; It will be the basis for the context help (see \nameref{sec:help_context_help}). The fourth part creates the directory \texttt{/AppDir/usr}, which is the basic structure of an appimage, and then populates it with the contents of \texttt{/\{path to cinelerra-5.1\}/bin}. Finally, the fifth step starts a script, called \texttt{makeappimage}, which points to \textit{bld.sh} contained in \texttt{/tools/makeappimagetool/}.
+
+The script specifies all executables that are part of \CGG{}, so makeappimage can pick up dependencies. Any executable code in other places is not picked up. makeappimage will populate the AppDir directory, and then call the platform dependent appimagetool found in \texttt{/\{path to cinelerra-5.1\}/tools}.
+
+At the end of the compilation there will be an appimage in the \texttt{cinelerra-5.1} directory, which we can move and use.
+
 \section{How to Create a new Theme}
 \label{sec:how_create_theme}
 \index{theme!create new theme}
@@ -727,3 +877,180 @@ example, the SUV theme has over 800 lines in the initialize function, and has ov
 500 png images in the data directory.  Most of these images and data values are
 required to be initialized by the custom theme constructor; very tedious and
 time consuming work.  Creating a new theme is usually a lot of work.
+
+\section{How Context Help works in the Program Code}
+\label{sec:context_help_coding}
+\index{context help}
+
+All class methods related to context help start with the common pattern \texttt{context \_help} in their names. It is easy to get all occurences in the code with the following command (example):
+
+\begin{lstlisting}[style=sh]
+        grep -F context_help `find . -name '*.[Ch]' -print`
+\end{lstlisting}
+
+The base functionality is defined in several \textit{BC\_WindowBase} class methods in \\ \texttt{guicast/bcwindowbase.C} (search on \texttt{context\_help}). All BC\_Window's and BC\_SubWindow's inherit these methods.
+
+For the simplest case of context help definition, it is sufficient to add the call to \texttt{context\_help\_set\_keyword()} in the most inclusive widget constructor. If \texttt{Alt/h} is pressed with the mouse over this widget's window, its \texttt{keypress\_event()} method (inherited from BC\_WindowBase) will catch this hotkey, fetch the keyphrase defined by \texttt{context\_help\_set\_keyword()} and call the \texttt{doc/ContextManual.pl} script with this keyphrase. Then ContextManual.pl script does the whole processing of the keyphrase given and calls web browser to display the found HTML manual page. The browser is called in the background to prevent from blocking the calling \CGG{} thread.
+
+An example from \textit{cinelerra/zoombar.C}:
+
+\begin{lstlisting}[style=sh]
+        ZoomBar::ZoomBar(MWindow *mwindow, MWindowGUI *gui)
+        : BC_SubWindow(...)
+        {
+                this->gui = gui;
+                this->mwindow = mwindow;
+               context_help_set_keyword("Zoom Panel");
+       }                                                        
+\end{lstlisting}
+
+If \texttt{Alt/h} is pressed with the mouse over some subwindow (arbitrary depth) of the \texttt{context\_help\_set\_keyword()} caller, the \texttt{keypress\_event()} method of that subwindow catches the hotkey. Its own context help keyword, probably, will be empty. In this case the whole widget hierarchy is traced up to \textit{top\_level} widget, their context help keywords are checked, and the first nonempty keyword is used for context help.
+
+This approach allows us to define the help keyword common to the whole dialog window with a bunch of diverse buttons with a single call to \texttt{context\_help\_set \_keyword()}, without placing such a call into each button constructor. And at the same time, this approach allows to assign different help keywords to GUI elements belonging to the same window but documented in different manual pages.
+
+\subsubsection{An example with several different help keywords from cinelerra/mwindowgui.C:}%
+\label{ssub:exemple_different_help_keywords}
+
+\begin{lstlisting}[style=sh]
+        MWindowGUI::MWindowGUI(MWindow *mwindow)
+        : BC_Window(_(PROGRAM_NAME ": Program"), ...)
+        {
+                this->mwindow = mwindow;
+                ...
+                context_help_set_keyword("Program Window");
+        }
+        ...
+        FFMpegToggle::FFMpegToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
+        : BC_Toggle(...)
+        {
+                this->mwindow = mwindow;
+                this->mbuttons = mbuttons;
+                set_tooltip(get_value() ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
+                context_help_set_keyword("FFmpeg Early Probe Explanation");
+        }
+        ...
+        StackButton::StackButton(MWindow *mwindow, int x, int y)
+        : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
+        {
+                this->mwindow = mwindow;
+                set_tooltip(_("Close EDL"));
+                context_help_set_keyword("OpenEDL");
+        }
+        ...
+        ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
+        : BC_Toggle(...)
+        {
+                this->mwindow = mwindow;
+                this->mbuttons = mbuttons;
+                ...
+                context_help_set_keyword("Proxy");
+        }
+        \end{lstlisting}
+If the widget we wish to add context help to, overloads keypress\_event() of the base class with its own method, then it is necessary to introduce a small addition to its keypress\_event() handler: the call to \texttt{context\_help\_check\_and\_show()} has to be added in a suitable place in the handler.
+
+An example with \texttt{context\_help\_check\_and\_show()} from \textit{cinelerra/mbuttons.C}:
+\begin{lstlisting}[style=sh]
+       int MButtons::keypress_event()
+       {
+           int result = 0;
+           if(!result) {
+               result = transport->keypress_event();
+           }
+           if(!result) {
+               result = context_help_check_and_show();
+            }
+           return result;
+       }
+\end{lstlisting}
+
+All the keypress handlers are not equal, therefore we provide different variants of the methods context\_help\_check\_and\_show() and context\_help\_show() (the latter for explicit checking on hotkey).
+
+An example with context\_help\_show() from cinelerra/editpanel.C:
+\begin{lstlisting}[style=sh]
+        int EditPanelTcInt::keypress_event()
+        {
+                if( get_keypress() == 'h' && alt_down() ) {
+                        context_help_show("Align Timecodes");
+                        return 1;
+                }
+                ...further processing...
+                return 1;
+        }
+\end{lstlisting}
+
+A single example of much more sophisticated keypress\_event() handler can be found in \texttt{cinelerra/trackcanvas.C} (search on context\_help). The problem here was to track the particular object drawn on the canvas to figure out whose context help is to be requested. Another rare example of difficulty may appear when context help is desired for some GUI object which is not subclassed from BC\_WindowBase.
+
+\textit{ContextManual.pl} looks for occurence of keyphrases in the following order:
+
+\begin{enumerate}
+        \item In \textit{Contents.html}
+        \item In \textit{Index.html}
+        \item In all the \textit{CinelerraGG\_Manual/*.html} files via grep
+\end{enumerate}
+
+Keyphrase matching is tried first exact and case sensitive, then partially and case insensitive. The special keyword \texttt{TOC} shows Contents, \texttt{IDX} shows Index. If the keyword starts with \texttt{FILE:}, the filename after \textit{FILE:} is extracted and that file is shown. You can look in the ContextManual.pl script text.
+
+For debugging purposes the script can be called from command line. For this to work, the environment variable \texttt{\$CIN\_DAT} has to be set to the parent directory of doc.
+
+
+\subsubsection{Providing context help for plugins}%
+\label{ssub:providing_context_help_plugins}
+
+In the simplest case, nothing has to be done at all. The plugin context help functionality introduced in \texttt{cinelerra/pluginclient.C} automatically assigns context help keyword from the plugin's title for all plugins subclassed from \textit{PluginClient}. For this to work, the manual page documenting the plugin must be entitled identically to the programmatic title of the plugin. A special treatment can be necessary in the following cases:
+
+\begin{enumerate}
+        \item \textit{Rendered effects} are not subclasses of PluginClient and require an explicit context help definition via \texttt{context\_help\_set\_keyword().}
+        \item Only the main plugin dialog inherits context help functionality from the parent class. If a plugin opens additional dialog windows, they probably require explicit context help definitions.
+        \item If the plugin title differs from its subsection title in the documentation, either its help keyword or the corresponding title in the manual should be renamed. Another possibility can be an addition to the \textit{\%rewrite table} in \texttt{doc/ContextManual.pl}.
+        \item If the plugin title contains some characters special for HTML and/or Perl regular expression syntax, the special characters have to be escaped. For example, the keyphrase corresponding to the title \textit{Crop \& Position (X/Y)} should be converted to:
+
+        \begin{lstlisting}[style=sh]
+                Crop & Position \\(X\\/Y\\)
+        \end{lstlisting}
+
+        Such a rewriting can be done either in the C++ code or in ContextManual.pl.
+\end{enumerate}
+
+One additional explanation about previous user information when plugin tooltips are off. Help for the \textit {selected plugin} is shown because in this case it would be difficult to figure out, without a visual feedback, which particular item is currently under the mouse.
+
+\subsection{Manual Maintenance is now Tightly Coupled with the Program Code}
+\label{sub:manmaintain}
+
+If some section of the \CGG{} manual gets renamed and is used for Context Help, the corresponding help keywords should be adjusted too. All the keywords used can be listed via the following example command:
+
+\begin{lstlisting}[style=sh]
+       grep -F context_help `find . -name '*.C' -print` | grep -F '"'
+\end{lstlisting}
+----------------
+
+Note that the keyword does not have to exactly match the section title; it can also be a case insensitive substring of the section title.
+
+If some new \CGG{} window or dialog is created and documented, the inclusion of context\_help\_set\_keyword() calls and/or adaptation of keypress\_event() handler (if any) should be included in the program code.
+
+If some new \CGG{} plugin is created, it is best to document it in the section entitled exactly equal to that plugin's title. Then probably its context help will work out of the box. Otherwise, some adaptation to its keypress\_event() (if any) or to the %rewrite table in ContextManual.pl may be necessary.
+
+Why the local copy of \CGG{} manual should be used?
+
+\begin{enumerate}
+       \item For context help keyphrases matching, the local copy of \textit{Contents.html} and \textit{Index.html} is necessary anyway.
+       \item Grepping \textit{CinelerraGG\_Manual/*.html} files of the remote manual from the website cannot work per definition.
+       \item The local copy usage ensures exact matching of the version of the manual to the version of \CGG{}. Otherwise, if one uses for some reason an older version of \CGG{} with the help fetched from the newer version of the website manual, various incompatibilities can be expected.
+       \item Packing the manual into AppImage, the current method of \CGG{} packaging, should be much easier than merging two different git branches when building from source packages, as was done earlier.
+\end{enumerate}
+
+What about Localization?
+
+For now, \CGG{} context help is not localized at all. There is no complete \CGG{} manual in any language except English. But even should the manual be translated to other languages, the context help keywords must remain unlocalized literal string constants. First, because the set of languages known to \CGG{} itself is not the same as the set of languages the manual will be translated to. If some "translated keyword" is fed to the help system, while the manual in this language does not exist, keyword matching cannot succeed. Second, such a help localization with the translation of all keywords can be done and then maintained much easier and much more reliably inside the ContextManual.pl script rather than in the \CGG{} binary.
+
+More about ContextManual.pl file?
+
+The bin/doc/ContextManual.pl script can be configured further. Look in the script text. You can define your preferable web browser, or redefine it to 'echo' for debug purposes. There are also some predefined HTML pages for Contents and Index, and several explicitly rewritten keyphrases. 
+
+After the first invocation of context help the system-wide script, bin/doc/ContextManual.pl, copies itself into
+the user's config directory, \$HOME/.bcast5. If the user needs to modify ContextManual.pl, it should be done
+on that copy from .bcast5 rather than the system-wide one. On all subsequent context help requests this
+(possibly modified) .bcast5 version of the script will be called.  If later the \CGG{} package gets
+upgraded containing a newer, not 100\% compatible version of ContextManual.pl script, and/or not compatible
+structure of the HTML manual itself, the new system-wide version of the script will be copied into .bcast5
+again to ensure context help functionality. The older version of the script will be backed up (with the .bak
+suffix) as a reference of the modifications done by the user.