#-----------------------------------------------------------------
to_state( $FMT );
$_ = substr( $_, 4 );
text_target_tt();
$size = length( $_ );
#-------------------------------------------------
# Going to wrap titles with lines as long as title
#-------------------------------------------------
for( $size = length( $_ ); $size > 0; $size-- )
{
$line="$line$lc";
}
print CONVERT "$line\n$_\n$line\n";
}
sub text_underline_tt { replace_underlines( $underline_tt ) }
#-------------------------------------------------------------------------------
# setext to HTML conversion call-back routines.
# ( in alphabetical order )
#-------------------------------------------------------------------------------
sub html_bold_tt
{
#---------------------------------------
# Turn all "**text**" into "text"
#---------------------------------------
s#$bold_tt#${lt}B${gt}$1${lt}/B${gt}$2#g;
}
#-------------------------------------------------------------------------------
sub html_bullet_tt
{
s/$bullet_tt(.*)/ ${lt}li${gt}$1$2${lt}\/li${gt}/;
}
#-------------------------------------------------------------------------------
sub html_emit_footer
{
print CONVERT "\n$htmlFooter";
$closePgf = "";
}
#-------------------------------------------------------------------------------
sub html_emit_header
{
my $htitle = shift;
my $header = $htmlHeader;
$header =~ s/\$HTML_TITLE/$htitle/o;
print CONVERT $header;
}
#-------------------------------------------------------------------------------
sub html_emit_line
{
print CONVERT "" if $atListStart == 1 and not /${lt}LI${gt}/o;
$atListStart = 0;
if( /$passthru_tt/ )
{
s/$passthru_tt//o; # remove typotag and pass line out as is.
reclaim_escapes();
print CONVERT "$_\n"
}
else
{
print CONVERT &html_finishing( $_ ), "\n";
}
}
#-------------------------------------------------------------------------------
sub html_enter_list { print CONVERT "\n" } # state change activities
sub html_leave_list { print CONVERT "
\n" }
sub html_enter_pre { print CONVERT "\n"; $insideNoFormatArea = 1 }
sub html_leave_pre { print CONVERT "
\n"; $insideNoFormatArea = 0 }
sub html_enter_quote { print CONVERT "\n"; $insideNoFormatArea = 1 }
sub html_leave_quote { print CONVERT "
\n"; $insideNoFormatArea = 0 }
#-------------------------------------------------------------------------------
sub html_final
{
&to_state( $FMT );
html_emit_footer();
#----------------------------------------------------
# Report on all internal name references not used up.
#----------------------------------------------------
if( scalar( @nm_ref ) > 0 )
{
print STDERR "\nMissing reference (target-tt) to the following:\n\n";
for( $i=0; $i < scalar( @nm_ref ); $i++ )
{
print STDERR " $nm_ref[ $i ]\n";
}
}
}
#-------------------------------------------------------------------------------
sub html_finishing {
local($_) = @_;
my $unt;
s/\&/\&\#38\;/go; s/\\&\#60\;/go; s/\>/\&\#62\;/go;
s/$lt//go; s/$amp/\&/go; # convert markers to real symbols
#-----------------------------------------------
# This fixes the case where an untouchable
# string includes these special html characters.
#-----------------------------------------------
foreach $element ( @untouchable )
{
$element =~ s/\&/\&\#38\;/go;
$element =~ s/\\&\#60\;/go;
$element =~ s/\>/\&\#62\;/go;
}
recover_extractions();
$_;
}
#-------------------------------------------------------------------------------
sub html_hot_tt
{
#----------------------------------------------------
# After finding a hot-tt, substitute all underlines
# with spaces and check to see if the hot-tt had
# a corresponding hypertext reference. Flag it in
# bright, bold red when no hypertext record found.
# Allow user to define the variable HTML_DIR as the
# destination directory for the HTML code.
# Note, the files may have to actually be placed
# in such directory by hand after they are generated.
#----------------------------------------------------
s#$hot_tt#
$h = $href{$1}; ($text = $1) =~ s,_, ,go;
$h ? qq'${lt}A HREF="$variables{HTML_DIR}$h"${gt}$text${lt}/A${gt}'
: "${lt}B${gt}${lt}font color=red${gt}--> $text <-- NO HREF!!${lt}/font${gt}${lt}/B${gt}"; #eg;
}
#-------------------------------------------------------------------------------
sub html_indent { s/$indent_tt/$1/ } # get rid of indent-tt characters
#-------------------------------------------------------------------------------
sub html_init
{
local $title, $aTitle;
my $target;
%state_change = (
enter_list => "html_enter_list",
leave_list => "html_leave_list",
enter_pre => "html_enter_pre",
leave_pre => "html_leave_pre",
enter_quote => "html_enter_quote",
leave_quote => "html_leave_quote",
);
$veryFirstTime = 1; # used to force table of content header out
#------------------------------------------
# Make a first pass over the data, looking
# for hypertext linking information.
#------------------------------------------
for ($i = 0; $i <= $#data; $i++)
{
$_ = $data[$i]; # $_ is default for searches
#---------------------------------------------------------
# This will pick out targets found in the setext not
# hidden by a suppress-tt, that is, the href-tt below.
# With this check, it is unnecessary to have to include
# the href-tt which uses identical text for internal
# document references. External references need href-tt.
# Have to make sure the match does not pick up elements
# inside a notouch-tt ( eg. `_do_not_want_this_as_target`)
#---------------------------------------------------------
if( /$target_tt/ && substr($`,length($`)-1,1) ne "`" &&
(not /$suppress_tt/) )
{
$href{ $4 } = "$intHrefMrk$4";
push @nm_ref, $4;
}
#-------------------------------------------------
# Locate HREF's and save. When no target is given,
# assume the target is internal, with same name.
#-------------------------------------------------
if( /$href_tt/ )
{
$hrefID = $1;
$target = ($2) ? $2 : "$intHrefMrk$hrefID"; # assume internal href.
$href{$hrefID} = $2;
#------------------------------
# Remember internal HREF's not
# already seen for target-tt.
#------------------------------
if( $target =~ /$internal_href/ ) {
if( not is_member( substr( $target, 1), \@nm_ref ) ) {
push @nm_ref, $1;
}
}
next;
}
#---------------------------------------------------------
# The first title-tt or subhead-tt gets ...
#---------------------------------------------------------
/$title_tt/ && do { $htmlTitle = html_init_title("H1", $i); next; };
/$subtitle_tt/ && do { $htmlTitle = html_init_title("H2", $i); next; };
}
html_emit_header( $htmlTitle );
#----------------------------------------------------
# NOTE: changing original title-tt search pattern
# to match what was done in html_init_title.
#----------------------------------------------------
$title_tt = "^\\.\\.\\s+()(.*)(<\\/H.>)";
}
#-------------------------------------------------------------------------------
sub html_init_title
{
local($head, $i) = @_;
my $hyper_ref;
$data[$i--] = ".."; # suppress title indicator ( --- or === )
$data[$i] =~ s/^\s*//; # get rid of any leading space in actual title
$this_title = $data[$i];
# Have to fix title if it also happens to be a target-tt.
$this_title =~ /$target_tt/ && do { ($tmp = $4) =~ s,_, ,go; $this_title = $tmp };
#---------------------------------------------------
# Are all titles automatically considered target-tt?
#---------------------------------------------------
if( $make_title_href )
{
$hyper_ref = $this_title;
$hyper_ref =~ s/ /_/go;
$externalReference =
($separate_html_files) ? substr("$MenuNames{ $hyper_ref }.$htmlExt", 1) : "";
$href{ $hyper_ref } ="$externalReference$intHrefMrk$hyper_ref";
#------------------------------
# Remember internal HREF's not
# already seen for target-tt.
#------------------------------
if( not is_member( $hyper_ref, \@nm_ref ) ) {
push @nm_ref, $hyper_ref;
}
}
#-----------------------------------------------------------------
# Put out the HTML title and then suppress it for later processing
#-----------------------------------------------------------------
$aTitle = "$this_title" unless $title++;
$data[$i] = ".. <$head> " . $data[$i] . " $head>";
return $aTitle;
}
#-------------------------------------------------------------------------------
sub html_italic_tt
{
#---------------------------------------
# Turn all "~text~" into "text"
#---------------------------------------
s#$italic_tt#${lt}I${gt}$1${lt}/I${gt}#g;
}
#-------------------------------------------------------------------------------
sub html_line_break
{
my $fold = shift;
print CONVERT "$closePgf\n" unless $fold++;
$closePgf = "
";
return $fold;
}
#-------------------------------------------------------------------------------
sub html_line_tt
{
if( not $insideNoFormatArea )
{
s/$line_tt/${lt}P${gt}${lt}HR${gt}/;
print CONVERT html_finishing( $_ ), "\n";
}
}
#-------------------------------------------------------------------------------
sub html_list_tt
{
if( /$list_tt/o )
{
if ( $1 eq '(' ) # open list level
{
$list_level++;
s/$list_tt/${lt}UL${gt}${lt}LI${gt}/;
}
else # close list level
{
$list_level--;
s,$list_tt,${lt}/LI${gt}${lt}/UL${gt},;
$atListStart = 2 if $list_level;
$terminatedList = 1;
}
}
#-----------------------------------------------------
# An empty line terminates a multiple line list entry.
#-----------------------------------------------------
elsif( /$empty_line/o )
{
print CONVERT "\n" unless $terminatedList;
print CONVERT "\n";
$atListStart = 1 if $list_level;
$terminatedList = 0;
}
}
#-------------------------------------------------------------------------------
sub html_quote_tt
{
s/$quote_tt\s*//;
}
#-------------------------------------------------------------------------------
sub html_section_tt
{
my $hdr_level = shift;
print CONVERT "\n";
}
#-------------------------------------------------------------------------------
sub html_target_tt
{
check_target_reference( $_ );
/$target_tt/ && do { ($a = $4) =~ s,_, ,go; s/$target_tt/ $a/; };
}
#-------------------------------------------------------------------------------
sub html_title
{
my $titleHolder = $_;
to_state( $FMT );
/$target_tt/ && do { ($a = $4) =~ s,_, ,go; s/$target_tt/$a/; };
if( /$title_tt/i ) # this is the new title-tt from html_init
{
$frontMrk = $1; $thisTitle = $2; $backMrk = $3;
if( not $separate_html_files or $veryFirstTime )
{
check_target_reference( $titleHolder );
print CONVERT $frontMrk, &html_finishing($thisTitle), $backMrk, "\n";
$veryFirstTime = 0;
}
elsif( $frontMrk eq "" )
{
$savedTitle = $thisTitle;
$savedTitleHolder = $titleHolder;
}
else
{
#--------------------------
# Create another HTML file?
#--------------------------
$hyper_ref = $thisTitle;
$hyper_ref =~ s/$trim_spaces/$2/o;
$hyper_ref =~ s/ /_/go;
$association = $MenuNames{ $hyper_ref };
if( $association ne "" )
{
$assocLevel = substr( $association, 0, 1 );
$association = substr( $association, 1 );
$newFile = "$outputDirectory$association.$htmlExt";
if( $converted_file ne $newFile )
{
#-----------------------------
# Finish off the current file.
#-----------------------------
html_emit_footer();
close CONVERT;
#-----------------------------------------------------
# This realigns title after nested sublevels complete.
#-----------------------------------------------------
if ( $assocLevel == 0 ) {
$savedTitle = $thisTitle;
}
$converted_file = $newFile;
open CONVERT, ">$converted_file" or die "Can't create $converted_file, $OS_ERROR";
html_emit_header( $savedTitle );
#--------------------------------------------
# This puts target reference in correct file.
#--------------------------------------------
if( $savedTitleHolder )
{
check_target_reference( $savedTitleHolder );
if( $savedTitleHolder =~ /$title_tt/i )
{
print CONVERT $1, &html_finishing($2), $3, "\n";
}
$savedTitleHolder = "";
}
}
}
check_target_reference( $titleHolder );
print CONVERT $frontMrk, &html_finishing($thisTitle), $backMrk, "\n";
}
}
}
#-------------------------------------------------------------------------------
sub html_underline_tt
{
#--------------------------------------------
# Turn all "_text_" into "text"
# Remembering to substitute intervening
# underlines with spaces.
#--------------------------------------------
s#$underline_tt#
($text = $1) =~ s,_, ,go;
"${lt}I${gt}${lt}U${gt}$text${lt}/U${gt}${lt}/I${gt}"; #eg;
}
#-------------------------------------------------------------------------------
# setext to NEdit HELP conversion call-back routines.
# ( in alphabetical order )
#-------------------------------------------------------------------------------
sub help_bold_tt
{
#----------------------------------------------------
# Turn all "**text**" into "text"
#----------------------------------------------------
s#$bold_tt#${stlMrk}$TKN_BOLD$1${stlMrk}$TKN_BOLD$2#g;
}
#-------------------------------------------------------------------------------
sub help_bullet_tt { s/$bullet_tt/ * $1/ }
#-------------------------------------------------------------------------------
sub help_emit_line
{
#------------------------------------------------------
# The following is here to help us generate conditional
# compilation elements for the 'C' compiler.
#------------------------------------------------------
if( /$passthru_tt/ )
{
s/$passthru_tt//o; # remove typotag and pass line out as is.
reclaim_escapes();
print HELP "$_\n"
}
else
{
#-------------------------------------------------
# This seems to be the only good place to take
# care of style changes that have occurred between
# usage of proportional and fixed font styles.
#-------------------------------------------------
if( $styleChanged )
{
$_ = $styleMark . get_style_name( $crntStyle ) . $_;
$styleChanged = "";
}
my $finishedLine = help_finishing( $_ );
print HELP "\"", $finishedLine, "\",\n";
#----------------------------------------------------------------
# To minimize newline output for the empty line elements,
# the algorithm remembers if its last line had a newline emitted.
#----------------------------------------------------------------
$newLinePresentInLastLine = $finishedLine =~ /\\n$/;
}
}
#-------------------------------------------------------------------------------
sub help_final {}
#-------------------------------------------------------------------------------
sub help_finishing
{
local($_) = @_;
#----------------------------
# When finishing a heading...
#----------------------------
if( $headingLevel )
{
#--------------------------------------------------
# ... destroy any styles inadvertantly placed there
#--------------------------------------------------
if( /$stlMrk/o )
{
my @line = split $stlMrk;
$_ = join '', @line;
}
#------------------------------------
# ... because only one style allowed.
#------------------------------------
$stlFront = $styleMark . get_style_name( "" );
$headingLevel = 0;
$stlEnd = $styleMark . get_style_name( $initialStyle );
$stlFront = "" if /^$styleToken/ ; # remove redundancy when present
$_ = $stlFront . $_ .$stlEnd;
}
#---------------------------------------------
# Any style markers found in the current line?
#---------------------------------------------
elsif( /$stlMrk/ )
{
#----------------------------------------
# Break line up into style word elements.
#----------------------------------------
my $line = "";
my @line = split $stlMrk;
foreach $element ( @line )
{
#--------------------------------------------------
# Extract word emphasis token and associated words.
# Embed style marker into text line.
#--------------------------------------------------
$element =~ /^($aStyleToken)?(.*)$/o && do {
$token = ($1) ? $1 : $TKN_TEXT; # $TKN_xxx
$words = $2;
my $nextStyle = get_style( $crntStyle, $token );
if( $crntStyle eq $nextStyle )
{
$line .= $words;
}
else
{
$stlNm = get_style_name( $nextStyle );
$line .= "$styleMark$stlNm$words";
$crntStyle = $nextStyle;
}
};
}
$_ = $line;
}
recover_extractions();
fix_target_tt();
#-------------------------------------------
# Apply any initial style change introduced.
#-------------------------------------------
$_ = $newLeadStyle . $_;
$newLeadStyle = "";
#----------------------------------------------------------------
# Add newline element to all lines which are not being currently
# formatted into a flowing paragraph. It is done here because the
# character also has to get included in the character counts.
#----------------------------------------------------------------
$_ .= get_newline( 1 ) if $crnt_state ne $FMT;
#----------------------------------------------------------------------
# Since 2 characters (\ and n) are occupying the space of one newline,
# we need to subract out the number of new lines from the total offset.
#----------------------------------------------------------------------
my $styleCount = count( $styleToken, $_ );
my $newLineCount = count( "\\\\n", $_ );
my $quoteCount = count( '"', $_ );
my $backslashCount = count( "\\\\", $_ ) - $styleCount -
$newLineCount - $quoteCount;
my $adjustment = ($styleCount * $styleTokenSize) +
($backslashCount / 2) + $newLineCount + $quoteCount;
#-----------------------------------------------------------
# Now keep a running total of how many characters to emit.
# (Keep 2 forms, total number for compiler string length
# considerations, and another for target-tt section offsets.
#-----------------------------------------------------------
$sectionCharacterCnt += length( $_ );
$targetOffset += length( $_ ) - $adjustment;
$_;
}
#-------------------------------------------------------------------------------
sub help_fixed_styles
{
#----------------------------------------------------------------
# All proportional styles in the style state transition table
# begin with the "_" character. If we are already in the
# proportional styles arena, a link, or header, no change occurs.
#----------------------------------------------------------------
if( $crntStyle =~ /^_/ )
{
$crntStyle =~ s/^_//o;
$styleChanged = $crntStyle unless $styleChanged;
}
}
#-------------------------------------------------------------------------------
sub help_hot_tt
{
my ( $text, $stlNm, $h );
#--------------------------------------------------
# After finding a hot-tt, substitute all underlines
# with spaces and check to see if the hot-tt had
# a corresponding hypertext reference. Make it
# unadorned text when no reference found.
#--------------------------------------------------
s#$hot_tt#
($text = $1) =~ s,_, ,go;
$h = is_known_link( $text );
$stlNm = get_style_name( $crntStyle );
$h ? "$stlMrk$TKN_LINK$text$stlMrk$TKN_LINK"
: $text;
#eg;
}
#-------------------------------------------------------------------------------
sub help_indent
{
if( /$indent_tt/ )
{
s/$indent_tt/$1/; # get rid of indent-tt characters
/\S$/ && do { $_ .= ' ' }; # make sure space available for remaining
} # text in this kind of paragraph
}
#-------------------------------------------------------------------------------
sub help_init
{
%state_change = (
enter_pre => "help_fixed_styles",
leave_pre => "help_proportional_styles",
enter_quote => "help_fixed_styles",
leave_quote => "help_proportional_styles",
);
#--------------------------------------------
# Global elements needed for making menu code
#--------------------------------------------
%href = ();
$copy_right_holder = "Mark Edel";
$hlptxt = "help_data$helpSuffix.h"; # name of file holding help data structures
$hlphdr = "help_topic$helpSuffix.h"; # name of file holding help definitions
$stlMrk = "\01"; # this is the character code
$styleMark = '\01'; # this is the text string
$styleToken = "\\$styleMark"; # this for splitting strings on styleMark
$styleTokenSize = length( $styleToken ); # accounts for '\01A'
$illegal_help = "HELP_none";
$menu_record = "(.),(.*),(.*),(\\d)";
$tgtIndx = 0; # target-tt index for hypertext reference array (@href)
#-------------------------------------------------------------------
# The following data is used to embed style data into the help text.
#-------------------------------------------------------------------
# TOKENS => text bold italic underline
%styles_stt = (
# fixed font styles
plain => { style => "A", states => [ "plain", "bold", "italic", "u_plain" ] },
bold => { style => "B", states => [ "bold", "plain", "b_ital", "u_bold" ] },
italic => { style => "C", states => [ "italic", "b_ital", "plain", "u_italic" ] },
b_ital => { style => "D", states => [ "b_ital", "italic", "bold", "u_b_ital" ] },
u_plain => { style => "E", states => [ "u_plain", "u_bold", "u_italic", "plain" ] },
u_bold => { style => "F", states => [ "u_bold", "u_plain", "u_b_ital", "bold" ] },
u_italic => { style => "G", states => [ "u_italic", "u_b_ital", "u_plain", "italic" ] },
u_b_ital => { style => "H", states => [ "u_b_ital", "u_italic", "u_bold", "bold_ital" ] },
# proportional font styles
_plain => { style => "I", states => [ "_plain", "_bold", "_italic", "_u_plain" ] },
_bold => { style => "J", states => [ "_bold", "_plain", "_b_ital", "_u_bold" ] },
_italic => { style => "K", states => [ "_italic", "_b_ital", "_plain", "_u_italic" ] },
_b_ital => { style => "L", states => [ "_b_ital", "_italic", "_bold", "_u_b_ital" ] },
_u_plain => { style => "M", states => [ "_u_plain", "_u_bold", "_u_italic", "_plain" ] },
_u_bold => { style => "N", states => [ "_u_bold", "_u_plain", "_u_b_ital", "_bold" ] },
_u_italic => { style => "O", states => [ "_u_italic", "_u_b_ital", "_u_plain", "_italic" ] },
_u_b_ital => { style => "P", states => [ "_u_b_ital", "_u_italic", "_u_bold", "_bold_ital" ] },
# hyperLink style => "Q",
# header1 style => "R", --
# header2 style => "S", |_ MAX_HEADER
# header3 style => "T", --
);
#-----------------------------------------------------------
# The link index is the position in a font style table
# where the linking font will reside. It appears immediately
# after the styles from the table above.
#-----------------------------------------------------------
$linkIndex = scalar( keys %styles_stt );
$maxTokens = scalar( @{ $styles_stt{plain}{states} } );
$STYLE_PLAIN = $styles_stt{plain}{style};
$STYLE_LINK = "Q"; # link style marker, a continuation from style table
$STYLE_HDR = "R"; # beginning of header style markers
$MAX_HEADER = 3; # the maximum number of header styles in use
$TKN_TEXT = 0; # used in style state transition, order important
$TKN_BOLD = 1; # used in style state transition, order important
$TKN_ITALIC = 2; # used in style state transition, order important
$TKN_ULINE = 3; # used in style state transition, order important
$TKN_LINK = 4;
$aStyleToken = "[$TKN_TEXT$TKN_BOLD$TKN_ITALIC$TKN_ULINE$TKN_LINK]";
$initialStyle = "_plain"; # the initial style for help text.
$crntStyle = $initialStyle;
$headingLevel = 0;
print_menu( $crntMenu, "" ) if $print_menu; # sort of debug info
#----------------------------------
# Create help header (help_topic.h)
#----------------------------------
open HLPHDR, ">$hlphdr" or die "Can't create $hlphdr, $OS_ERROR";
emit_help_header( HLPHDR, $crntMenu );
close HLPHDR;
#-------------------------------------------
# Create help text data header (help_data.h)
#-------------------------------------------
open HELP, ">$hlptxt" or die "Can't create $hlptxt, $OS_ERROR";
emit_helpTitles( HELP, $crntMenu );
collect_internal_hypertext_references( \@data );
$whence = 0;
emit_helpText( HELP, $crntMenu, \@data );
}
#-------------------------------------------------------------------------------
sub help_italic_tt
{
s/$italic_tt/${stlMrk}$TKN_ITALIC$1${stlMrk}$TKN_ITALIC/g
}
#-------------------------------------------------------------------------------
sub help_line_break
{
my $fold = shift;
$_ .= get_newline( 2 );
help_emit_line() unless $fold++;
return $fold;
}
#-------------------------------------------------------------------------------
sub help_line_tt {}
sub help_list_tt { text_list_tt() }
sub help_quote_tt {}
#-------------------------------------------------------------------------------
sub help_proportional_styles
{
#----------------------------------------------------------------
# All proportional styles in the style state transition table
# begin with the "_" character. If we are already in the
# proportional styles arena, a link, or header, no change occurs.
#----------------------------------------------------------------
unless( $crntStyle =~ /^_/ or
$crntStyle eq "link" or
$crntStyle eq "header" ) {
$crntStyle = "_$crntStyle";
$newLeadStyle = $styleMark . get_style_name( $crntStyle );
}
}
#-------------------------------------------------------------------------------
sub help_section_tt
{
$headingLevel = shift;
#----------------------------------------------------------
# Heading levels for sectioning are being required to start
# at level 3 (considered the first level). This keeps the
# X-resources down inside NEdit. So here is the mapping.
# 1> level-1
# 2> level-1
# 3> level-1
# 4> level-2
# 5> level-3
#----------------------------------------------------------
$headingLevel = ($headingLevel > 2 ) ? $headingLevel - 2 : 1;
$headingLevel = $MAX_HEADER if $headingLevel > $MAX_HEADER; #
s/$section_tt//;
&help_emit_line;
$crntStyle = $initialStyle;
}
#-------------------------------------------------------------------------------
sub help_target_tt { } # cannot process target-tt at this time because
# calculation of the hypertext offset requires
# a fully expanded text line (see help_finishing).
sub fix_target_tt
{
if( /$target_tt/ and exists $href{ $4 } )
{
my ( $text, $tgtOffset, $originalLine );
#---------------------------------------------------
# Have to compute target's offset into help section.
# Need actual text sans styling information. Assuming
# all other text replacement has already occurred.
#---------------------------------------------------
$originalLine = $_;
s/$styleToken.//g; # remove all styling markers
#--------------------------------------------------------
# Inside this special substitution, a computation of the
# target's offset from the beginning of the section is
# being computed and applied to the hyper-reference array
# element which will be emitted after all text sections
# have been processed.
#--------------------------------------------------------
s#$target_tt#
($text = $4) =~ s,_, ,go;
$tgtOffset = index( $_, $text ) + $targetOffset -1;
$tgtOffset = sprintf( "%6d", $tgtOffset );
$href[ $tgtIndx++ ] =~ s /^0/$tgtOffset/o;
" $text";
#eg;
#-------------------------------------------------------
# Now fix hyper-references in actual line to be emitted.
#-------------------------------------------------------
$_ = $originalLine;
s#$target_tt#
($text = $4) =~ s,_, ,go;
" $text";
#eg;
}
}
#-------------------------------------------------------------------------------
sub help_title {&help_emit_line}
#-------------------------------------------------------------------------------
sub help_underline_tt
{
#--------------------------------------------------
# Turn all "_text_" into "text"
# Remembering to substitute intervening
# underlines with spaces.
#--------------------------------------------------
s#$underline_tt#
($text = $1) =~ s,_, ,go;
"${stlMrk}$TKN_ULINE$text${stlMrk}$TKN_ULINE";
#eg;
}
#-------------------------------------------------------------------------------
sub get_newline
{
$howMany = shift;
$howMany-- if $newLinePresentInLastLine && $howMany > 1;
return '\n' x $howMany;
}
#-------------------------------------------------------------------------------
sub is_known_link
{
my $linkName = shift;
for( $index = 0; $index < scalar( @hot_tt_links ); $index++ )
{
$element = $hot_tt_links[ $index ];
return 1 if( $hot_tt_links[ $index ] eq $linkName );
}
return 0;
}
#-------------------------------------------------------------------------------
sub get_style
{
my $crntStyle = shift; # plain, bold, italic, etc.
my $token = shift; # $TKN_xxx
my $style = "header"; # assume working on header
if( $headingLevel == 0 )
{
if( $token == $TKN_LINK )
{
if( $crntStyle eq "link" )
{
$style = $prevStyle;
}
else
{
$prevStyle = $crntStyle;
$style = "link";
}
}
else
{
@transitions = @{ $styles_stt{$crntStyle}{states} };
$style = $transitions[ $token ];
}
}
return $style;
}
#-------------------------------------------------------------------------------
sub get_style_name
{
my $crntStyle = shift; # plain, bold, italic, etc.
my $styleName;
if( $headingLevel )
{
$styleName = chr(ord( $STYLE_HDR )+$headingLevel-1);
}
elsif( $crntStyle eq "link" )
{
$styleName = $STYLE_LINK;
}
else
{
$styleName = $styles_stt{$crntStyle}{style};
}
return $styleName;
}
#-------------------------------------------------------------------------------
sub get_menu_item
{
my $setext = shift;
my $line = shift;
while( $$line < scalar( @$setext ) )
{
$_ = $$setext[ $$line++ ];
return $_ if s/$menu_element//o;
return "$_, $help_code" if s/$help_element//o;
}
return "";
}
#-------------------------------------------------------------------------------
sub print_menu
{
my $crnt_menu = shift;
my $indent = shift;
my ( $menuTitle, $mneumonic, $helpName, $hideit, $type );
foreach $menuItem ( @$crnt_menu )
{
if ( $menuItem =~ /$menu_record/o )
{ $mneumonic=$1; $menuTitle=$2; $helpName=$3; $hideit=($4) ? $4 : "" }
if( $hideit eq $help_code ) {
$hideit = "";
$type = "Help"
}
else {
$hideit = ", ($hideit)" if $hideit;
$type = "Menu"
}
print "$type: $indent$mneumonic, $menuTitle [$helpName]$hideit\n";
if( $menuItem =~ /$subMenuIndicator/o )
{
($menu = $menuTitle) =~ s/ /_/og;
print_menu( \@$menu, "$indent " );
}
}
}
#-------------------------------------------------------------------------------
sub collect_internal_hypertext_references
{
my $setext = shift;
my $line = 0;
my ($source, $destination );
while( $line < scalar( @$setext ) )
{
$_ = $$setext[ $line++ ];
if( /$href_tt/o )
{
$source = $1;
$destination = $2;
if( $destination =~ /$internal_href/ )
{
$href{ $1 } = $source;
}
}
}
}
#-------------------------------------------------------------------------------
sub emit_helpText
{
my $stream = shift;
my $crnt_menu = shift;
my $setext = shift;
my $line = 0;
my $index = 1;
$helpNameList = "";
emit_help_menu_text( $setext, $stream, $crnt_menu, \$line );
print $stream "static char **HelpText[] = {\n$helpNameList\n};\n\n";
print $stream "HelpMenu H_M [] =\n{\n";
emit_help_menu( $stream, $crnt_menu, 0, 1 );
print $stream "\n};\n";
#------------------------------------
# Emit internal hypertext references.
#------------------------------------
print $stream "\nHref H_R [] =\n{\n";
$sep = "";
for ($index = 0; $index < scalar(@href); $index++)
{
$element = $href[$index];
$nextone = ($index == $#href) ? "NULL, " : "&H_R[%2d],";
printf $stream "$sep {$nextone$element}", $index+1;
$sep = ",\n"
}
print $stream "\n};\n";
#-----------------------------
# Emit program version string.
#-----------------------------
$pgmVersion = $variables{ version };
$pgmVersion .= '\n' . date() if $pgmVersion !~ /$neditDefaultMarker/ and $pgmVersion !~ /XNEdit rev /;
print $stream "\nstatic const char * NEditVersion = \"$pgmVersion\\n\";\n";
}
#-------------------------------------------------------------------------------
sub emit_help_menu_text
{
my $setext = shift;
my $stream = shift;
my $crnt_menu = shift;
my $line = shift;
my ( $menuTitle, $mneumonic, $helpName, $prevLine );
#----------------------------------------
# For every node of the menu tree...
#----------------------------------------
foreach $menuItem ( @$crnt_menu )
{
if ( $menuItem =~ /$menu_record/ )
{ $mneumonic=$1; $helpName=$3; ($menuTitle=$2) =~ s/_//; }
#---------------------------------
# ... recursively expand sub-menus
#---------------------------------
if( $menuItem =~ /$subMenuIndicator/ )
{
($menu = $menuTitle) =~ s/ /_/g;
emit_help_menu_text( $setext, $stream, \@$menu, $line );
}
elsif( $mneumonic ne $separator ) # ... and not a menu separator
{
locate_menu_text( $setext, $menuTitle, $line )
or die "Unable to find \"$menuTitle\" text!";
$remainder = "";
my @section = ();
my $lineNbr = 0;
$s_e_p = ($helpNameList) ? ",\n" : "";
$helpNameList .= $s_e_p . " htxt_$helpName";
$sectionCharacterCnt = 0;
$targetOffset = 0;
#------------------------
# ... emit help menu text
#------------------------
while( 1 )
{
($_,$remainder) = get_menu_text( $setext, $remainder, $line );
last if $_ eq "";
$lineNbr++;
next if /$empty_line/ and $lineNbr == 1;
chomp;
#--------------------------------------------------
# Save all hypertext targets found in current topic
#--------------------------------------------------
if( /$target_tt/ and exists $href{ $4 } )
{
$target = $4;
$href = $href{$target};
$href =~ s/_/ /go;
$target =~ s/_/ /go;
$topic = "HELP_\U$helpName,";
$nl1 = $name_length; # for HELP_ and comma
push @href, sprintf("0, %-${nl1}.${nl1}s \"$href\"", $topic);
push @hot_tt_links, $href; # collect for later verification.
}
s/\\/\\\\/go; # escape backslash any where in text
s/"/\\"/go; # escape embedded double quotes
s/^\s*$//; # redefine whitespace as empty line
push @section, $_ ;
}
print $stream "static char * htxt_$helpName [] = {\n";
$styleChanged = $initialStyle; # This forces initial style out
$crntStyle = $initialStyle;
parse_setext( \@section );
print $stream "NULL\n};\n\n";
}
}
}
#-------------------------------------------------------------------------------
sub locate_menu_text
{
my $setext = shift;
my $menuTitle = shift;
my $line = shift;
$menuTitle =~ s/_//go; # removing drop key character markers
$menuTitle =~ s/ /./go; # spaces could be underlines in titles
$menuTitle =~ s/\(/./go; # parens are special in regex searches...
$menuTitle =~ s/\)/./go; # ... here they should be ignored
#-----------------------------------------------------
# When the whence value is set to zero, the search
# for the text that belongs with the given menu title
# is started at the beginning of the file. This allows
# the menu text to be in an order other than that
# specified by the menu itself. This gives freedom
# to the writer; inefficiency to the text processing.
#-----------------------------------------------------
$$line = 0 if ( $whence != 1 );
while( $$line < scalar( @$setext ) )
{
if( $$setext[ $$line++ ] =~ /$menuTitle/ )
{
if ( $$setext[ $$line ] =~ /$subtitle_tt/ or
$$setext[ $$line ] =~ /$title_tt/ )
{
$$line++;
return 1; # the first line after the setext title marker
}
}
}
return 0;
}
#-------------------------------------------------------------------------------
sub get_menu_text
{
my $setext = shift;
my $crnt_line = shift;
my $line = shift;
#-------------------------------------
# Skip any setext comment lines found.
#-------------------------------------
while( $$setext[ $$line ] =~ /$suppress_tt/ ) { $$line ++ };
$crnt_line = $$setext[ $$line++ ] if $crnt_line eq "";
if( $crnt_line =~ /$twobuck_tt/ ) # end of setext document?
{
return ("", "");
}
else
{
#--------------------------------------------
# Have to read ahead by one line to catch the
# title of the next section, or the end of
# the setext document.(Eat horizontal rulers)
#--------------------------------------------
do { $_ = $$setext[ $$line++ ] } until not /^ --/;
#--------------------------------
# Look ahead again, so that an
# empty last line is not emitted.
#--------------------------------
if( $crnt_line =~ /^\s*$/ and
($$setext[ $$line ] =~ /$subtitle_tt/o or
$$setext[ $$line ] =~ /$title_tt/o or
$$setext[ $$line ] =~ /$twobuck_tt/o))
{
return ("", "");
}
if( /$subtitle_tt/o or /$twobuck_tt/o )
{
$$line = $$line - 2;
return ("", "");
}
}
return ( $crnt_line, $_ );
}
#-------------------------------------------------------------------------------
sub emit_help_menu
{
my $stream = shift;
my $crnt_menu = shift;
my $level = shift;
my $index = shift;
my ( $menuTitle, $mneumonic, $helpName, $hideIt );
if( $level == 0 )
{
$sep = "";
$end_index = scalar( @$crnt_menu );
}
$level++;
$nl1 = $name_length+6; # for HELP_ and comma
$nl2 = $name_length+3; # for 2 double quotes and comma
#----------------------------------------
# For every node of the menu tree...
#----------------------------------------
foreach $menuItem ( @$crnt_menu )
{
if ( $menuItem =~ /$menu_record/ )
{
$mneumonic = $1;
$helpName = $3;
$hideIt = $4;
($menuTitle=$2) =~ s/_//;
}
#---------------------------------
# ... recursively expand sub-menus
#---------------------------------
if( $menuItem =~ /$subMenuIndicator/ )
{
($menu = $menuTitle) =~ s/ /_/g;
printf $stream "$sep { &H_M[%2d], $level, %-${nl1}.${nl1}s %-${nl2}.${nl2}s $hideIt, '$mneumonic', \"$menuTitle\" }",
$index, "$illegal_help,", "\"$helpName\",";
$index = emit_help_menu( $stream, \@$menu, $level, $index+1 );
}
else
{
$topic = ( $mneumonic eq $separator ) ? "$illegal_help," : "HELP_\U$helpName,";
$helpName = "\"$helpName\",";
$nptr = ( $end_index == 1 && $level == 1 ) ? "NULL" : "&H_M[%2d]";
#---------------------------
# are we at end of the menu?
#---------------------------
if( $end_index == 1 && $level == 1 ) {
print $stream "$sep { NULL, ";
}
else {
printf $stream "$sep { &H_M[%2d], ", $index;
}
printf $stream "$level, %-${nl1}.${nl1}s %-${nl2}.${nl2}s $hideIt, '$mneumonic', NULL }", $topic, $helpName;
$sep = ",\n";
$index++;
}
$end_index-- if $level == 1;
}
return $index;
}
#-------------------------------------------------------------------------------
sub emit_helpTitles
{
my $stream = shift;
my $crnt_menu = shift;
emit_copyright( $stream, "$hlptxt -- Nirvana Editor help module data" );
print $stream "char *HelpTitles[] = {\n";
emit_help_label( $stream, $crnt_menu );
print $stream " NULL\n};\n\n";
}
#-------------------------------------------------------------------------------
sub emit_help_label
{
my $stream = shift;
my $crnt_menu = shift;
my ( $menuTitle, $mneumonic, $helpName );
#-----------------------------------------------------------------
# Emit help title/labels for only the leaf nodes of the menu tree.
#-----------------------------------------------------------------
foreach $menuItem ( @$crnt_menu )
{
if ( $menuItem =~ /$menu_record/ )
{
$mneumonic = $1;
$helpName = $3;
($menuTitle = $2) =~ s/_//go;
}
if( $menuItem =~ /$subMenuIndicator/ )
{
($menu = $menuTitle) =~ s/ /_/go;
emit_help_label( $stream, \@$menu );
}
elsif( $mneumonic ne $separator ) # ... and not a menu separator
{
print $stream " \"$menuTitle\",\n";
push @hot_tt_links, $menuTitle; # collect for later verification.
}
}
}
#-------------------------------------------------------------------------------
sub emit_help_header # populates NEdit's help_topic.h
{
my $stream = shift;
my $crnt_menu = shift;
emit_copyright( $stream, "$hlphdr -- Nirvana Editor help display" );
print $stream "#define MAX_HEADING $MAX_HEADER\n";
print $stream "#define STL_HD $linkIndex+1\n";
print $stream "#define STL_LINK $linkIndex\n";
print $stream "#define STL_NM_HEADER '$STYLE_HDR'\n";
print $stream "#define STL_NM_LINK '$STYLE_LINK'\n";
print $stream "#define STYLE_MARKER '$styleMark'\n";
print $stream "#define STYLE_PLAIN '$STYLE_PLAIN'\n";
print $stream "#define TKN_LIST_SIZE $maxTokens\n";
print $stream "\n";
print $stream "enum HelpTopic {\n";
emit_help_topic( $stream, $crnt_menu );
print $stream " HELP_LAST_ENTRY,\n";
print $stream " $illegal_help = 0x7fffffff /* Illegal topic */ \n";
print $stream "};\n";
print $stream "\n";
print $stream "#define NUM_TOPICS HELP_LAST_ENTRY\n";
print $stream "\n";
}
#-------------------------------------------------------------------------------
sub emit_help_topic
{
my $stream = shift;
my $crnt_menu = shift;
my ( $menuTitle, $mneumonic, $helpName );
#-----------------------------------------------------------------
# Emit help topic name for only the leaf nodes of the menu tree.
#-----------------------------------------------------------------
foreach $menuItem ( @$crnt_menu )
{
if ( $menuItem =~ /$menu_record/ )
{
$mneumonic = $1;
$helpName = $3;
($menuTitle = $2) =~ s/_//go;
}
if( $menuItem =~ /$subMenuIndicator/ )
{
($menu = $menuTitle) =~ s/ /_/go;
emit_help_topic( $stream, \@$menu );
}
elsif( $mneumonic ne $separator ) # ... and not a menu separator
{
print $stream " HELP_\U$helpName,\n";
}
}
}
#-------------------------------------------------------------------------------
sub emit_copyright
{
my $stream = shift;
my $filename = shift;
my $year = date("y");
my $padlen1 = 76 - length( $filename );
my $padlen2 = 52 - length( $copy_right_holder );
my $blanks = " ";
my $pad1 = substr( $blanks, 0, $padlen1 );
my $pad2 = substr( $blanks, 0, $padlen2 );
print $stream "/*******************************************************************************\n";
print $stream "* *\n";
print $stream "* $filename$pad1 *\n";
print $stream "* *\n";
print $stream " Generated on " . date() . " (Do NOT edit!)\n";
print $stream " Source of content from file $setext_file\n";
print $stream "* *\n";
print $stream "* Copyright (c) 1999-$year $copy_right_holder$pad2 *\n";
print $stream "* *\n";
print $stream "* This is free software; you can redistribute it and/or modify it under the *\n";
print $stream "* terms of the GNU General Public License as published by the Free Software *\n";
print $stream "* Foundation; either version 2 of the License, or (at your option) any later *\n";
print $stream "* version. *\n";
print $stream "* *\n";
print $stream "* This software is distributed in the hope that it will be useful, but WITHOUT *\n";
print $stream "* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *\n";
print $stream "* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *\n";
print $stream "* for more details. *\n";
print $stream "* *\n";
print $stream "* In addition, as a special exception to the GNU GPL, the copyright holders *\n";
print $stream "* give permission to link the code of this program with the Motif and Open *\n";
print $stream "* Motif libraries (or with modified versions of these that use the same *\n";
print $stream "* license), and distribute linked combinations including the two. You must *\n";
print $stream "* obey the GNU General Public License in all respects for all of the code used *\n";
print $stream "* other than linking with Motif/Open Motif. If you modify this file, you may *\n";
print $stream "* extend this exception to your version of the file, but you are not obligated *\n";
print $stream "* to do so. If you do not wish to do so, delete this exception statement from *\n";
print $stream "* your version. *\n";
print $stream "* *\n";
print $stream "* You should have received a copy of the GNU General Public License along with *\n";
print $stream "* software; if not, write to the Free Software Foundation, Inc., 59 Temple *\n";
print $stream "* Place, Suite 330, Boston, MA 02111-1307 USA *\n";
print $stream "* *\n";
print $stream "* Nirvana Text Editor *\n";
print $stream "* September 10, 1991 *\n";
print $stream "* *\n";
print $stream "* Written by $copy_right_holder *\n";
print $stream "* *\n";
print $stream "*******************************************************************************/\n";
print $stream "\n";
}
#-------------------------------------------------------------------------------
__END__
=head1 NAME
Setext - convert Structured Enhanced TEXT into HTML or plain text.
=head1 SYNOPSIS
Usage: setext [ -dhtTVw ][-D directory][-H [hfile]][-S [htmlExt]] \
[-c conditional][-v name=value][setext_file [converted_file]]
setext {-mp} [-c conditional][-M menuSuffix][-v name=value] setext_file
The first form of setext is used to convert Structure Enhanced TEXT
documents into HTML or simple text documents.
The second form is specific to generating NEdit help menu code
from a setext document with Menu and Help directives.
-c conditional text definitions, separated by commas.
-d do not automatically make titles hypertext references (HTML only)
-D specify destination directory for separate HTML files. This also sets
the value for the variable HTML_DIR.
-h show this usage clause.
-H convert setext_file to HyperText Markup Language (HTML).
Optional file parameter specifies file containing HTML header
and footer definition overrides. The current defaults are:
$htmlHeader =
$HTML_TITLE
$htmlFooter =
where $HTML_TITLE is replaced with an appropriate title.
-m generate NEdit help menu code files.
-M name NEdit help code files with this suffix.
-p do option -m and print out NEdit help elements.
-S convert setext_file into separate HTML files.
(the default name extension is 'html', but it can be
changed by specifying it as an argument to this option)
-t convert setext_file to simple text (default).
-T emit setext typotag definitions in use.
-v defines variable name and assigns it the given value.
(more than one occurrence of -v can be made) The variables
are made available for use within the setext document parsing.
-V display the version of this setext script.
-w do not emit warnings about missing variables.
When the converted_file argument is missing, STDOUT is used.
When the setext_file argument is missing, STDIN is used.
To get conditional text within a setext document to be displayed,
supply a definition tag through the -c option. For example,
setext -c NEDITDOC help.etx nedit.doc
would generate a plain text document, nedit.doc, from the source
help.etx, including/excluding text marked with 'NEDITDOC'
conditional text markers, also known as 'maybe' typotags.
=head1 DESCRIPTION
This Structured Enhanced TEXT converter produces either HTML or plain
text files from a given setext source. The HTML files produced can
include hypertext references to within itself, or to external
destinations. The setext converter also has the capability of providing
different content in the resulting output files through a conditional
text mechanism, and variable data definitions. All this allows a
publisher to maintain a single, very readable, source while producing
varying content for different output formats and audiences.
When the converted_file argument is missing, STDOUT is used.
When the setext_file argument is missing, STDIN is used. This gives
setext the capability of being a filter to other programs.
To get conditional text within a setext document to be displayed,
supply a definition tag through the -c option. For example,
setext -c NEDITDOC help.etx nedit.doc
would generate a plain text document, nedit.doc, from the source
help.etx, including/excluding text marked with 'NEDITDOC'
conditional text markers, also known as 'maybe' typotags.
Use the -T option to see the set of typotags supported by this
converter. Further explanations of typotags occurs there.
=head2 HTML Generation Examples
The simplest form of HTML generation is:
setext help.etx nedit.html
setext -H help.etx nedit.html
The results will be stored in the current directory in the nedit.html
file.
When the user wants to break up the resulting html file into multiple
files, with cross references between the files, the -S option should
be used.
setext -S help.etx nedit.html
The resulting files are broken up according to titled sections and
are placed into the current directory, along with the nedit.html file.
To change the destination of the resulting files, two options are
supplied, the -D and -S options. For instance,
setext -S shtml -D help/nedit help.etx nedit.shtml
The -S option allows the name of the file extension to be altered.
The -D option specifies where the resulting files are going to be
stored. Thus, in the example, all the files will be placed in the
help/nedit directory (relative to the current directory) and will
have ".shtml" as the file extension.
A final nuance has been added to help server side HTML capabilities.
The -H option can be used to specify a file which contains the
definitions of $htmlHeader and $htmlFooter. This will be used to
override that which is supplied by the setext script. For example,
setext -S shtml -H NEdit.ssd help.etx nedit.html
tells setext to use the file NEdit.ssd (server side definition)
to override the HTML header and footer generation. An example of
the contents of this file follows.
$htmlHeader =
'' . "\n" .
'' . "\n";
$htmlFooter =
'' . "\n";
=head2 NEdit Help Menu
When generating the NEdit help menu code, two files will be produced,
help_data.h and help_topic.h (when the -M option is not used).
These two files contain all the programmatic
data needed to implement hypertext menus within the NEdit program.
The following is an example of a setext invocation which assumes that
the variable 'version' is being used within the help.etx file.
setext -m -v "version=6.0" help.etx
If the -M option is used, its value is appended to the root portion
of the two generated files. For example,
setext -m -c VMS -M _VMS help.etx
will generate the files help_topic_VMS.h and help_data_VMS.h. The
conditional portion of the help menu specifically designated for VMS
will be extracted from the help.etx source.
Below is what is used to guide the generation of 'C'-Motif menus.
Indentation is SIGNIFICANT in the "Menu" directive lines below. It
is used to determine under which menu element another item will belong.
The number of spaces indented is not significant, but items to be placed
in the same menu panel MUST line up at the same indent level.
ALL nodes of this menu "tree" should have help name qualifiers.
These are used to produce the internal lists used by NEdit help code.
By default, the first character of the menu element will be used as a
menu mneumonic key. To use another character in the menu element for
this purpose, surround the character with underscores (eg. I w_a_nt 'a').
The menu title MUST match the one found in the actual help text (sans
special mneumonic key character marking). The help text title may include
underlines (for spaces) when it is a hyperlink target.
The Help-name is used to generate various data structure names. For
instance, the 'start' help name will be used to generate the HelpTopic
enumeration value HELP_START and the character array htxt_start which
holds the actual help text used in the menu dialogs. Consequently, these
names need to be unique and contain only the characters that a 'C'
compiler can digest.
Menu separator lines use a dash (-) character for the Menu Title. They
should also have a unique Help-name.
A numerical value following the Help-name (separated from the name by
a comma and/or spaces) is part of a menu element hiding scheme implemented
in buildHelpMenu (found in 'menu.c'). When the number matches the hideIt
value found in the procedure, that element will effectively become invisible.
This mechanism was created for particular menu features that are not
available to all incarnations of NEdit (in this case, the VMS version).
A "Help" directive is used for all other text used as NEdit help, but
does not show up in the Help menu. The following is a sample of
Menu and Help directives.
.. Menu Title # Help-name
.. ------------------------------------------------------------
.. Menu: Getting Started # start
.. Menu: Basic Operation # basicOp
.. Menu: Selecting Text # select
.. Menu: Finding and Replacing Text # search
.. Menu: Cut and Paste # clipboard
.. Menu: Using the Mouse # mouse
.. Menu: Keyboard Shortcuts # keyboard
.. Menu: S_h_ifting and Filling # fill
.. Menu: F_i_le Format # format
.. Menu: Features for Programming # features
.. Menu: Programming with NEdit # programmer
.. Menu: Tabs/Emulated Tabs # tabs
.. Menu: Auto/Smart Indent # indent
.. Menu: Syntax Highlighting # syntax
.. Menu: Finding Declarations (ctags) # tags
.. Menu: Regular Expressions # regex
.. Menu: Basic Syntax # basicSyntax
.. Menu: Metacharacters # escapeSequences
.. Menu: Parenthetical Constructs # parenConstructs
.. Menu: Advanced Topics # advancedTopics
.. Menu: Examples # examples
.. Menu: Macro/Shell Extensions # extensions
.. Menu: Shell Commands and Filters # shell, 1
.. Menu: Learn/Replay # learn
.. Menu: Macro Language # macro_lang
.. Menu: M_a_cro Subroutines # macro_subrs
.. Menu: Action Routines # actions
.. Menu: Customizing # customizing
.. Menu: Customizing NEdit # customize
.. Menu: Preferences # preferences
.. Menu: X Resources # resources
.. Menu: Key Binding # binding
.. Menu: Highlighting Patterns # patterns
.. Menu: Smart Indent Macros # smart_indent
.. Menu: NEdit Command Line # command_line
.. Menu: Client/Server Mode # server
.. Menu: Cr_a_sh Recovery # recovery
.. Menu: ---------------------------------- # separator1
.. Menu: Version # version
.. Menu: Distribution Policy # distribution
.. Menu: Mailing _L_ists # mailing_list
.. Menu: Problems/Defects # defects
.. ------------------------------------------------------------
.. Help: Tabs Dialog # tabs_dialog
=cut