View Issue Details

IDProjectCategoryView StatusLast Update
0000661Cinelerra-GGFeaturepublic2024-06-12 15:33
Reportersge Assigned ToPhyllisSmith  
PrioritynormalSeveritytweakReproducibilityalways
Status acknowledgedResolutionopen 
Summary0000661: New latex2html option '-unicase_titles' checks duplication of filenames for HTML pages in case insensitive manner
DescriptionTo produce CGG HTML manual, we execute latex2html with the option -long_titles 5. Latex2html, up to now, examines generated filenames for HTML pages on duplication and, if necessary, adds an incremented number to each detected duplicated name. However, latex2html compares filenames in case sensitive manner. If several files appear whose names differ in letter case only, latex2html will treat them as different, and if that files later will be copied to some case insensitive filesystem, such as NTFS or FAT, that files will conflict. Moreover, usually latex2html creates the auto-linked file 'index.html' which under case insensitive filesystems can conflict with the Index page, 'Index.html' which exist in many big document, including CGG manual.

To overcome this, I have added the new option to latex2html: -unicase_titles. With this option latex2html will check filenames for duplication in case insensitive manner (and add incremented digit to the name when necessary). To get this option, either apply the patch latex2html-2024-unicasetitles.diff.gz to some recent latex2html sources and then reinstall them, or perform build of latex2html from its git master tree (Dan Gildea already committed my unicasetitles patch to the git tree).

When having applied this unicasetitles patch, one can translate HTML manual using this new option in addition to all the others, like in the attached 'translate_manual' script (residing under 'manual' git tree). Then, when using the new option, the file 'Index.html' with the Index will be renamed to 'Index2.html' but otherwise work as before.

When the -unicase_titles option will be used, we will need also updated ContextManual.pl script (residing under 'cinelerra5' git tree), because ContextManual.pl used Index.html to search for some keyphrases. The new ContextManual.pl script finds the actual filename for the Index (Index.html, Index2.html, or whatever) automatically from the 'Contents.html' file.

To easily check for existence of filenames which differ only in case, the following shell command can be used:
ls | sort -f | uniq -di
TagsNo tags attached.
Attached Files
translate_manual (1,949 bytes)   
#!/bin/sh

# First build PDF version, 3 times to be completely sure.
# The various auxiliary files will be needed later.

pdflatex CinelerraGG_Manual.tex
makeindex CinelerraGG_Manual.idx
makeindex CinelerraGG_Manual.nlo -s nomencl.ist -o CinelerraGG_Manual.nls
pdflatex CinelerraGG_Manual.tex
makeindex CinelerraGG_Manual.idx
pdflatex CinelerraGG_Manual.tex

# Now build HTML version, using auxiliary files created by pdflatex.

# Clean the future HTML directory
rm -rf CinelerraGG_Manual

# Ensure creating the important settings file
if [ ! -f .latex2html-init ]
then
    cp latex2html-init .latex2html-init
fi

# When translating manual for context help, don't use -show_section_numbers !
# And do use -split +3 -link 3 -nofootnode and -local_icons.
# -use_dvipng, -image_type and -bottom_navigation can be used
# according to your preferences.

# translate document (GIF images generated via gs, good for debugging)
#latex2html -html_version 4.0,math -use_pdftex -nouse_dvipng -image_type gif -nofootnode -show_section_numbers -split +3 -link 3 -bottom_navigation -local_icons -t 'Cinelerra-GG Infinity' CinelerraGG_Manual.tex

# another alternative options combination (PNG images, nicer look)
#latex2html -html_version 4.0,math -use_pdftex -use_dvipng -image_type png -nofootnode -show_section_numbers -split +3 -link 3 -bottom_navigation -local_icons -t 'Cinelerra-GG Infinity' CinelerraGG_Manual.tex

# Alternative currently used on the cinelerra-gg.org website / created on a Fedora system
latex2html -html_version 4.0,math -use_pdftex -nouse_dvipng -long_titles 5 -unicase_titles -image_type gif -nofootnode -split +3 -link 3 -bottom_navigation -local_icons -t 'CinelerraGG_Manual' CinelerraGG_Manual.tex

# This single image has to be copied explicitly
cp images/cin-big.png CinelerraGG_Manual

# Clean temporary files in the HTML directory
rm -f CinelerraGG_Manual/WARNINGS
rm -f CinelerraGG_Manual/*.pl
rm -f CinelerraGG_Manual/images*
translate_manual (1,949 bytes)   
ContextManual.pl (9,191 bytes)   
#!/usr/bin/perl

# Helper script for context help in Cinelerra
# Calling: ContextManual.pl "<help keyphrase>"
# Searches the requested key in the following order:
# 1) manual Contents
# 2) manual Index
# 3) all manual pages via grep
# 4) FFmpeg or Ladspa plugins
# The first item found is shown via the default web browser
# If nothing found, the Contents itself is shown
# On empty keyphrase do nothing
# The special keyphrase "TOC" shows Contents, "IDX" shows Index
# The keyphrase starting with "FILE:" shows the file named after colon
# The special keyphrase "API" shows the numeric version of the script itself

# Several important definitions

# ContextManual.pl script API version. Must not be changed !
$cin_cm_api = 2;

# Web browser executable, can be redefined on user's demand
$cin_browser = $ENV{'CIN_BROWSER'};
# a likely default browser
$cin_browser = 'firefox' if $cin_browser eq '';
# another possible browser
#$cin_browser = 'xdg-open' if $cin_browser eq '';
# a fake browser for debugging
#$cin_browser = 'echo';

# The following definitions depend on the HTML manual structure
# There is nothing to change below this line

# The node with the manual contents
$contents_node = 'Contents.html';

# The node with the actual index if needed will be found after parsing contents
$index_node = '';
$index = '';

# Several special plugin names necessary to rewrite
%rewrite = (
  # Rendered effects and transitions are not segmented in the Contents
  "CD Ripper"           => "Rendered Audio Effects",
  "Normalize"           => "Rendered Audio Effects",
  "Resample"            => "Rendered Audio Effects",
  "Time stretch"        => "Rendered Audio Effects",

  "720 to 480"          => "Rendered Video Effects",
  "Reframe"             => "Rendered Video Effects",

  # Audio transitions are segmented in the Index
#  "Crossfade"           => "Audio Transitions",

  # Video transitions are segmented in the Index
#  "BandSlide"           => "Video Transitions",
#  "BandWipe"            => "Video Transitions",
#  "Dissolve"            => "Video Transitions",
#  "Flash"               => "Video Transitions",
#  "IrisSquare"          => "Video Transitions",
#  "Shape Wipe"          => "Video Transitions",
#  "Slide"               => "Video Transitions",
#  "Wipe"                => "Video Transitions",
#  "Zoom"                => "Video Transitions",

  # Several not properly matched names
  "AgingTV"             => "Aging TV",
  "Brightness/Contrast" => "Brightness\\/Contrast",
  "Chroma key (HSV)"    => "Chroma Key \\(HSV\\)",
  "Crop & Position"     => "Crop &amp; Position",
  "FindObj"             => "Find Object",
  "RGB - 601"           => "RGB-601",
  "ShiftInterlace"      => "Shift Interlace",
  "Cinelerra: Scopes"   => "Videoscope"
  );

# Cinelerra installation path
$cin_dat = $ENV{'CIN_DAT'};
$cin_dat = '.' if $cin_dat eq '';

# Cinelerra HTML manual must reside here
$cin_man = "$cin_dat/doc/CinelerraGG_Manual";
$contents = $cin_man.'/'.$contents_node;
#print "ContextManual: using contents $contents\n";

# Cinelerra user's config directory
$cin_config = $ENV{'CIN_CONFIG'};
$cin_config = $ENV{'HOME'}.'/.bcast5'
  if $cin_config eq '' && $ENV{'HOME'} ne '';
$cin_config = '.' if $cin_config eq '';
$me_config = "$cin_config/ContextManual.pl";
#print "ContextManual: user script=$me_config\n";

# 1st argument is the requested key
$help_key = $ARGV[0];
#print "ContextManual: request=$help_key\n";
# Do nothing if no key requested
exit 0 if $help_key eq '';

# A special internal request: output own API version
if ($help_key eq 'API')
{
  print "$cin_cm_api\n";
  exit 0;
}

# If a system (not user's) script instance is executed, and the API versions
# of both scripts do not match, then copy the system script to the user's one
# (making a backup copy of the latter). Then execute it with the same key.
if ($0 ne $me_config)
{
  $me_api = 0;
  $me_api = `\"$me_config\" API` if -x $me_config;
  if ($me_api != $cin_cm_api)
  {
    print "ContextManual: copying \"$0\" to \"$me_config\"\n";
    unlink "$me_config.bak" if -f "$me_config.bak";
    rename "$me_config", "$me_config.bak" if -f $me_config;
    system "cp \"$0\" \"$me_config\"";
    system "chmod +x \"$me_config\"";
  }
  exec "\"$me_config\" \"$help_key\"" if -x $me_config;
}

# If a user's script instance is executed, do everything by myself
#print "ContextManual: executing \"$0\" \"$help_key\"\n";

# Show contents on this special request
if ($help_key eq 'TOC')
{
  system "$cin_browser \"file://$contents\" &";
  exit 0;
}
# Show index on this special request
if ($help_key eq 'IDX')
{
  # Index node will be needed now, find it
  if ($index_node eq '')
  {
    $node = '';
    open CONTENTS, $contents or die "Cannot open $contents: $!";
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
    }
    close CONTENTS;
    $index_node = $node if $node ne '';
    $index_node = 'Index.html' if $index_node eq '';
    $index = $cin_man.'/'.$index_node;
  }
  system "$cin_browser \"file://$index\" &";
  exit 0;
}
# Show the named file on this special request
if ($help_key =~ /^FILE:/)
{
  $help_key =~ s/^FILE://;
  $help_key = $cin_man.'/'.$help_key;
  system "$cin_browser \"file://$help_key\" &";
  exit 0;
}

$help_key = $rewrite{$help_key} if exists $rewrite{$help_key};
# Do nothing if no key requested
exit 0 if $help_key eq '';
# Show contents on this special request
if ($help_key eq 'TOC')
{
  system "$cin_browser \"file://$contents\" &";
  exit 0;
}
# Show index on this special request
if ($help_key eq 'IDX')
{
  # Index node will be needed now, find it
  if ($index_node eq '')
  {
    $node = '';
    open CONTENTS, $contents or die "Cannot open $contents: $!";
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
    }
    close CONTENTS;
    $index_node = $node if $node ne '';
    $index_node = 'Index.html' if $index_node eq '';
    $index = $cin_man.'/'.$index_node;
  }
  system "$cin_browser \"file://$index\" &";
  exit 0;
}
# Show the named file on this special request
if ($help_key =~ /^FILE:/)
{
  $help_key =~ s/^FILE://;
  $help_key = $cin_man.'/'.$help_key;
  system "$cin_browser \"file://$help_key\" &";
  exit 0;
}

# Now try searching...
open CONTENTS, $contents or die "Cannot open $contents: $!";
$node = '';
# First search contents for the exact key
while (<CONTENTS>)
{
  chomp;
  last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
}
# If not found, search contents for an approximate key
if ($node eq '')
{
  seek CONTENTS, 0, 0;
  while (<CONTENTS>)
  {
    chomp;
    last if ($node) = /^\s*HREF=\"(.+?\.html)\">.*?$help_key.*?<\/A>$/i;
  }
}

# Index node will be needed now, find it
if ($node eq '' && $index_node eq '')
{
  seek CONTENTS, 0, 0;
  while (<CONTENTS>)
  {
    chomp;
    last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
  }
  $index_node = $node if $node ne '';
  $index_node = 'Index.html' if $index_node eq '';
  $index = $cin_man.'/'.$index_node;
  $node = '';
}

# If not found, search index for the exact key
if ($node eq '')
{
  open INDEX, $index or die "Cannot open $index: $!";
  while (<INDEX>)
  {
    chomp;
    # Cut off anchor: xdg-open does not like it
    last if ($node) = /<A\s+HREF=\"(.+?\.html)(?:#\d+)?\">\s*$help_key\s*<\/A>$/;
    # Retain anchor
#    last if ($node) = /<A\s+HREF=\"(.+?\.html(?:#\d+)?)\">\s*$help_key\s*<\/A>$/;
  }
  close INDEX;
}
# If not found, search index for an approximate key
if ($node eq '')
{
  open INDEX, $index or die "Cannot open $index: $!";
  while (<INDEX>)
  {
    chomp;
    # Cut off anchor: xdg-open does not like it
    last if ($node) = /<A\s+HREF=\"(.+?\.html)(?:#\d+)?\">.*?$help_key.*?<\/A>$/i;
    # Retain anchor
#    last if ($node) = /<A\s+HREF=\"(.+?\.html(?:#\d+)?)\">.*?$help_key.*?<\/A>$/i;
  }
  close INDEX;
}

# If not found, grep manual for exact key instance
if ($node eq '')
{
  $_ = `grep -l \"$help_key\" \"$cin_dat\"/doc/CinelerraGG_Manual/*.html`;
  ($node) = split;
}
# If not found, grep manual for case insensitive key instance
if ($node eq '')
{
  $_ = `grep -il \"$help_key\" \"$cin_dat\"/doc/CinelerraGG_Manual/*.html`;
  ($node) = split;
}

if ($node eq '')
{
  if ($help_key =~ /^F_/)
  { # If not found, search contents for FFmpeg plugins
    $help_key = 'FFmpeg Audio and Video Plugins';
    seek CONTENTS, 0, 0;
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
    }
  }
  elsif ($help_key =~ /^L_/)
  { # If not found, search contents for LADSPA plugins
    $help_key = 'Audio Ladspa Effects';
    seek CONTENTS, 0, 0;
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
    }
  }
}

close CONTENTS;

# If still nothing found, show contents
$node = $contents_node if $node eq '';
$node = $cin_man.'/'.$node unless $node =~ /\//;
#print "ContextManual: found $node\n";

# Call browser to show the proposed HTML file
system "$cin_browser \"file://$node\" &";

# And immediately return to the caller
exit 0;
ContextManual.pl (9,191 bytes)   

Activities

PhyllisSmith

2024-05-31 20:18

manager   ~0005646

@sge
Will check this later today. With the new release today, the duplicate lower/upper case problem that still existed on the website since February 29 should be ameliorated. Although I had fixed this on my local computer, it was not propagated to the website in order to maintain synchronization of the release Manual/files/source and binary images to Feb. 29.

sge

2024-06-01 07:12

reporter   ~0005647

Just to remember, ContextManual.pl, when invoked first time, copies itself into ~/.bcast5 to allow user's customizations. On upgrading, newer versions of ContextManual.pl compare their API version number ($cin_cm_api in the very beginning of the script) with that copied earlier into ~/.bcast5 and make update there if this version number gets incremented (the older copy, possibly modified by the user, gets renamed with the .bak suffix).

As the updated ContextManual.pl version suggested here expects that Index.html can be named differently now, this is the reason to induce its update in ~/.bcast5. Therefore the API version number has been incremented in the updated script, $cin_cm_api = 2; - just for information.

PhyllisSmith

2024-06-11 23:47

manager   ~0005657

@sge
@Andrea_Paz
ContextManual.pl also was checked into GIT yesterday. Just FYI, because I am trying to implement the latest latex2html files and all of the scripts/tex files on a different laptop with Fedora 39 so I have an alternate/backup spot, I have not successfully tested the "unicase" option yet. Will mark as resolved after I get it working (missing installed packages or other stuff).

sge

2024-06-12 15:33

reporter   ~0005661

@PhyllisSmith
@Andrea_Paz
Updated ContextManual.pl will work with older versions of the manual and/or translated with older versions of latex2html equally well. It is completely backwards compatible. There is no problem to commit the script into git early.

Issue History

Date Modified Username Field Change
2024-05-31 18:12 sge New Issue
2024-05-31 18:12 sge File Added: latex2html-2024-unicasetitles.diff.gz
2024-05-31 18:12 sge File Added: translate_manual
2024-05-31 18:12 sge File Added: ContextManual.pl
2024-05-31 20:18 PhyllisSmith Assigned To => PhyllisSmith
2024-05-31 20:18 PhyllisSmith Status new => acknowledged
2024-05-31 20:18 PhyllisSmith Note Added: 0005646
2024-06-01 07:12 sge Note Added: 0005647
2024-06-11 23:47 PhyllisSmith Note Added: 0005657
2024-06-12 15:33 sge Note Added: 0005661