function hyperHelp = makehelphyper(actionName, pathname, fcnName, helpStr)
%MAKEHELPHYPER Reformat help output so that the content has hyperlinks

%   Copyright 1984-2004 The MathWorks, Inc.
%   $Revision: 1.1.6.9 $  $Date: 2004/12/20 16:45:18 $

% Isolate the function name in case a full pathname was passed in
[unused fcnName unused unused] = fileparts(fcnName);

% Make "see also" references act as hot links
CR = sprintf('\n');
SPACE = sprintf(' ');
seeAlso = sprintf('See also');
lengthSeeAlso = length(seeAlso);
xrefStart = findstr(helpStr, sprintf('See also'));
if ~isempty(xrefStart)
    seeAlsoIndex = xrefStart(end);
    nameChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_/.';  % Note : '.' is now valid (for MATLAB class syntax)
    delimChars = [ ', ' CR ];
    % Determine start and end of "see also" portion of the help output
    pieceStr = helpStr(seeAlsoIndex+lengthSeeAlso : length(helpStr));
    periodPos = findstr(pieceStr, '.');
    notePos = min([findstr(pieceStr, sprintf('Overloaded')) findstr(lower(pieceStr), sprintf('note:'))]);
    crPos = regexp(pieceStr,'\n\s*\n');  % blank line with a possible space (or more).
    if isempty(notePos) && isempty(crPos)
        xrefEnd = length(helpStr);
        trailerStr = '';
    elseif ~isempty(notePos)
        xrefEnd = seeAlsoIndex+lengthSeeAlso + notePos(1) - 1;
        trailerStr = pieceStr(notePos(1):length(pieceStr));
    else
        xrefEnd = seeAlsoIndex+lengthSeeAlso + crPos(1) - 1;
        trailerStr = pieceStr(crPos(1):length(pieceStr));
    end

    % Parse the "See Also" portion of help output to isolate function names.
    seealsoStr = '';
    word = '';
    for chx = seeAlsoIndex+lengthSeeAlso : xrefEnd
        if length(findstr(nameChars, helpStr(chx))) == 1
            word = [ word helpStr(chx)];
        elseif (length(findstr(delimChars, helpStr(chx))) == 1)
            if length(word) > 0
                % This word appears to be a function name.
                % Make link in corresponding "see also" string.
                fname = word;
                if strcmp(upper(word), word) == 1
                    % only lowercase this if it's all uppercase.
                    fname = lower(word);
                end
                suffix = '';
                if fname(length(fname)) == '.'
                    % Don't hyperlink the last period of the word.
                    fname = fname(1:length(fname)-1);
                    suffix = '.';
                end
                % Make sure the function exists before hyperlinking it.
                makeHyperlink = 0;
                if exist(fname) > 0
                    makeHyperlink = 1;
                else
                    dotpos = findstr(word,'.');
                    if length(dotpos) == 2
                        % might be a UDD method
                        fullname = strrep(fname, '.', '/');
                        fullname = ['@' fullname(1:dotpos(1)) '@' fullname(dotpos(1)+1:end)];
                        if ~isempty(which(fullname))
                            makeHyperlink = 1;
                        end
                    end
                end

                if makeHyperlink
                    seealsoStr = [seealsoStr '<a href="matlab:' actionName ' ' fname '">' fname '</a>' suffix];
                else
                    seealsoStr = [seealsoStr word suffix];
                end
            end

            
            seealsoStr = [seealsoStr helpStr(chx)];
            word = '';
        else
            seealsoStr = [seealsoStr word helpStr(chx)];
            word = '';
        end
    end
    % Replace "See Also" section with modified string (with links)
    helpStr = [helpStr(1:seeAlsoIndex+lengthSeeAlso -1) seealsoStr trailerStr];
end

% If there is a list of overloaded methods, make these act as links.
overloadPos =  findstr(helpStr, xlate('Overloaded'));
if strcmp(actionName,'doc') == 1
    textToFind = ' doc ';
    len = 5;
else
    textToFind = ' help ';
    len = 6;
end

if length(overloadPos) > 0
    pieceStr = helpStr(overloadPos(1) : length(helpStr));
    % Parse the "Overload methods" section to isolate strings of the form "help DIRNAME/METHOD"
    overloadStr = '';
    linebrkPos = find(pieceStr == CR);
    lineStrt = 1;
    for lx = 1 : length(linebrkPos)
        lineEnd = linebrkPos(lx);
        curLine = pieceStr(lineStrt : lineEnd);
        methodStartPos = findstr(curLine, textToFind);
        methodEndPos = [length(curLine) - 2];
        if (length(methodStartPos) > 0 ) && (length(methodEndPos) > 0 )
            linkTag = ['<a href="matlab:' actionName ' ' curLine(methodStartPos(1)+len:methodEndPos(1)+1) '">'];
            overloadStr = [overloadStr curLine(1:methodStartPos(1)) linkTag curLine(methodStartPos(1)+1:methodEndPos(1)+1) '</a>' curLine(methodEndPos(1)+2:length(curLine))];
        else
            overloadStr = [overloadStr curLine];
        end
        lineStrt = lineEnd + 1;
    end
    % Replace "Overloaded methods" section with modified string (with links)
    helpStr = [helpStr(1:overloadPos(1)-1) overloadStr];
end


% If this topic is a Contents.m file, scan it for function lists, and
% modify function names to act as active links.
if (strcmpi(fcnName, 'Contents')) || (length(findstr(helpStr,'is both a directory and a function'))) || (strcmp(fcnName,'simulink')) || (strcmp(fcnName,'debug'))
    fcnPath = '';
    if ~strcmpi(fcnName,'Contents') && ~isempty(fcnName)
        % We need the pathname to be the name of the directory, and the
        % fcnName to be 'Contents'.
        if isempty(pathname)
            pathname = fcnName;
        else
            pathname = [pathname '/' fcnName];
        end
        fcnName = 'Contents';
    end 
    if strcmpi(fcnName, 'Contents') && ~isempty(pathname)
        [fcnPath unused unused] = fileparts(which([pathname filesep fcnName]));
        if strncmp(matlabroot, fcnPath, length(matlabroot)) == 1
            % if under matlabroot, find the toplevel product directory to
            % use for comparison later.
            tbxPath = fullfile(matlabroot, 'toolbox');
            
            % get the portion of the path after "toolbox"
            postTbxPath = fcnPath(length(tbxPath)+2:end);
            
            % final path for comparison is mlroot/toolbox/<dirname>...
            fcnPath = fcnPath(1:length(tbxPath)+findstr(postTbxPath, filesep));
        end
    end
    TAB = sprintf('\t');
    helpStr = strrep(helpStr, TAB, ' ');
    modHelpStr = '';
    linebrkPos = find(helpStr == CR);
    lineStrt = 1;
    for lx = 1 : length(linebrkPos)
        lineEnd = linebrkPos(lx);
        curLine = helpStr(lineStrt : lineEnd);
        hyphPos = findstr(curLine, ' - ');
        if any(hyphPos)
            nonblankPos = find(curLine ~= ' ');
            if curLine(nonblankPos(1)) == '-'
                modHelpStr = [modHelpStr curLine];
            else
                % start with the hyphen position, and walk backwards to the
                % first nonblank position.
                for i = hyphPos(1):-1:nonblankPos(1)
                    if (curLine(i) ~= ' ') && (curLine(i) ~= ','), break, end;
                end
                fname = curLine(nonblankPos(1):i);
                remainder = curLine(i+1:end);
                try
                    % If there is any help for this name, insert a link for it.
                    % However, avoid the expensive call to "help" by using "exist"
                    % to first test for mfiles, builtins, and directories.
                    fnameType = exist(fname);
                    if (fnameType == 2) || (fnameType == 7) || (fnameType == 5) || (fnameType == 8) || (any(builtin('helpfunc',fname)))
                        if ~isempty(fcnPath) && strncmp(fcnPath, which(fname), length(fcnPath)) == 0
                            % this is likely a shadowed function
                            modHelpStr = [modHelpStr curLine];                            
                        elseif strcmp(fname,'Readme')
                            modHelpStr = [modHelpStr curLine(1:nonblankPos(1)-1) '<a href="' 'matlab:' actionName ' ' topic '/Readme">' fname '</a>' remainder];
                        elseif remainder(1) == ','
                            % Sometimes there are two names separated by a comma.
                            [fname2, remainder2] = strtok(remainder(3:end));
                            fnameLink = strrep(fname,'''','''''');
                            fnameLink2 = strrep(fname2,'''','''''');
                            modHelpStr = [modHelpStr curLine(1:nonblankPos(1)-1) '<a href="' 'matlab:' actionName ' ''' fnameLink '''">' fname '</a>, ' '<a href="' 'matlab:' actionName ' ''' fnameLink2 '''">' fname2 '</a>' remainder2];
                        else
                            fnameLink = strrep(fname,'''','''''');
                            modHelpStr = [modHelpStr curLine(1:nonblankPos(1)-1) '<a href="' 'matlab:' actionName ' ''' fnameLink '''">' fname '</a>' remainder];
                        end
                    else
                        modHelpStr = [modHelpStr curLine];
                    end
                catch
                    % Just in case an error occurred during the helpfunc call, don't try to
                    % hyperlink anything.
                    modHelpStr = [modHelpStr curLine];
                end
            end
        else
            modHelpStr = [modHelpStr curLine];
        end
        lineStrt = lineEnd + 1;
    end
    helpStr = modHelpStr;
end

hyperHelp = helpStr;



