Files
harbour-core/extras/hbdoc/_genhtml.prg
Viktor Szakats c1bde05495 2016-10-26 12:50 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
- extras/hbdoc/_tmplate.prg
  - extras/hbdoc/hbdoc.ch
  * extras/hbdoc/_genbase.prg
  * extras/hbdoc/_genhtml.prg
  * extras/hbdoc/_gentxt.prg
  * extras/hbdoc/_genxml.prg
  * extras/hbdoc/hbdoc.hbp
  * extras/hbdoc/hbdoc.prg
    + improve readability by paragraphs spacing in DESCRIPTION sections
    + improve divs in section content for better control via CSS
    + improve readability of tables with borders and
      header hightlights
    * change default output to single-file
    + add support for the old <table>/<fixed> tags in html output until they
      are converted to something better
    + add support for <b>/<b>, <URL:url>, Markdown `inline code`,
      _emphasis_, *bold*, character escaping \*, line separators ===/---,
      and fenced code using triple backticks.
      Very limited and not with standard compliance or completeness
      in mind, just to be able to use some basic formatting.
    ; TODO: Markdown URL and lists, then replace all <b>,<URL>,<fixed>
            markup with Markdown equivalents in docs
    + better localization support
    + add support for one file per component output via -output-component
      cmdline option
    % assemble output in memory and write to disk in a single call
    % integrate external header
    % replace almost all internal arrays with hashes
    % replace self-modifying class and macro expansion with
      regular hashes
    % internal cleanups
    % switch to simpler method for sort weighting
    + merge category/subcategory values into tag list. It
      means they will be now be included in the output
    % cleanup/fix/simplify value expansions for 'compliance',
      'status' and 'platform' fields
    % cleanup the way output engines are handles internally
    + add support for 'TAGS' entry to replace/extend the rigid and
      ambiguous CATEGORY/SUBCATEGORY-based categorization. It is meant
      to be a comma-separated list of freeform tags, possibly with a set
      of standard common tags, with the freedom to use anything else deemed
      useful by component/doc authors.
    + add footer showing the build date of the doc
    + include Git revision the doc is based on, link to the relevant
      source tree version.
    * various code refactoring steps to avoid unnecessary
      classes, arrays, macro evaluation, and using undocumented
      functions
    % various HTML5 tag improvements and optimizations
    + load HBX file contents and lookup each referenced
      symbol. Emit warning in verbose mode, if docs refers
      to non-existing one.
      (this replaces slow and broken logic based on hbextern.ch)
    + use core hbdoc API to load the documentation instead
      of locally rolled logic
    * always show those content problems that are considered
      fatal and the input doc to be skipped
    + filter docs to English language by default
    + add ability to choose language using a command-line option
    ! fix faulty validation logic that resulted in
      erronously skipping certain entries
    + identify docs' 'component' property automatically
    ! fix to not eat empty lines from examples
    + convert "see also" items to links (this works correctly only
      in single file output mode)
    ! fix to not break words (f.e. URLs) when outputting HTML
    % use shorter class names
    ! fix invalid element ID generated
    ! fix RTE when trying to create output by category
    % delete dummy "HTML2" output mode
    * convert more ASCII chars to better Unicode equivalents
    + mark more text as code automatically
    * drop MS-DOS compatibility

  * src/rtl/hbdoc.prg
    ! fix filling '_LANG' property with the correct value
    * switch to use LF instead of CRLF in the field contents

  * contrib/hbct/doc/en/*.txt
  * contrib/hbgd/doc/en/hbgd.txt
  * contrib/hbgt/doc/en/hbgt.txt
  * contrib/hbmisc/doc/en/dates2.txt
  * contrib/hbnf/doc/en/*.txt
  * contrib/rddads/doc/en/adsfuncs.txt
  * doc/en/*.txt
    * cleanups and fixes
    ! casing
    ! fix to always delimit "see also" items with comma (",")
    ! fix various casing issues and old typos
    ! various fixes after detecting them using updated hbdoc
    ! eliminate/fix various rare/unnecessary/invalid field values
    ! move some embedded docs from hbdoc into their respective
      doc sources
    ! fix a typo
    * use backtick
    * replace code copyright with reference to COPYING.txt (=LICENSE.txt)
    + mark tables without a header or with double height header

  ; Above patches come from 3.4 fork commits below:

    2016-10-26 12:43 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-26 12:34 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-26 12:20 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-26 03:21 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-26 02:47 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 15:05 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 14:51 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 14:30 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 13:19 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 12:35 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 11:47 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-25 02:48 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 22:26 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 18:35 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 17:58 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 16:12 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 15:44 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 03:36 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 02:40 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-24 00:23 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-23 23:09 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-23 16:39 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-23 16:10 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
    2016-10-23 13:15 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
2016-10-26 13:07:21 +02:00

601 lines
18 KiB
Plaintext

/*
* Document generator - HTML output
*
* Copyright 2009 April White <bright.tigra gmail.com>
* Copyright 1999-2003 Luiz Rafael Culik <culikr@uol.com.br> (Portions of this project are based on hbdoc)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING.txt. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site https://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
#include "hbclass.ch"
#include "hbver.ch"
#define EXTENSION ".html"
#define STYLEFILE "hbdoc.css"
CREATE CLASS GenerateHTML INHERIT TPLGenerate
HIDDEN:
METHOD RecreateStyleDocument( cStyleFile )
METHOD OpenTagInline( cText, ... )
METHOD OpenTag( cText, ... )
METHOD Tagged( cText, cTag, ... )
METHOD CloseTagInline( cText )
METHOD CloseTag( cText )
METHOD AppendInline( cText, cFormat, lCode )
METHOD Append( cText, cFormat, lCode )
METHOD Space() INLINE ::cFile += ", ", self
METHOD Spacer() INLINE ::cFile += hb_eol(), self
METHOD Newline() INLINE ::cFile += "<br>" + hb_eol(), self
METHOD NewFile()
CLASS VAR lCreateStyleDocument AS LOGICAL INIT .T.
VAR TargetFilename AS STRING INIT ""
EXPORTED:
METHOD NewIndex( cDir, cFilename, cTitle, cLang )
METHOD NewDocument( cDir, cFilename, cTitle, cLang )
METHOD AddEntry( oEntry )
METHOD AddReference( oEntry, cReference, cSubReference )
METHOD BeginSection( cSection, cFilename )
METHOD EndSection( cSection, cFilename )
METHOD Generate()
METHOD WriteEntry( cField, cContent, lPreformatted ) HIDDEN
VAR nStart INIT hb_MilliSeconds()
VAR nIndent INIT 0
ENDCLASS
METHOD NewFile() CLASS GenerateHTML
::cFile += "<!DOCTYPE html>" + hb_eol()
::OpenTag( "html", "lang", StrTran( ::cLang, "_", "-" ) )
::Spacer()
::OpenTag( "meta", "charset", "utf-8" )
::OpenTag( "meta", "name", "referrer", "content", "origin" )
::OpenTag( "meta", "name", "viewport", "content", "initial-scale=1" )
::Spacer()
::OpenTag( "meta", "name", "generator", "content", "hbdoc" )
::OpenTag( "meta", "name", "keywords", "content", ;
"Harbour, Clipper, xBase, database, Free Software, GPL, compiler, cross-platform, 32-bit, 64-bit" )
::Spacer()
IF ::lCreateStyleDocument
::lCreateStyleDocument := .F.
::RecreateStyleDocument( STYLEFILE )
ENDIF
::Append( ::cTitle, "title" )
::Spacer()
::OpenTag( "link", "rel", "stylesheet", "href", STYLEFILE )
::Spacer()
::OpenTag( "body" )
::Spacer()
::OpenTag( "header" )
::Append( ::cTitle, "h1" )
::CloseTag( "header" )
::Spacer()
::OpenTag( "main" )
RETURN self
STATIC FUNCTION GitRev()
LOCAL cStdOut := ""
hb_processRun( "git rev-parse --short HEAD",, @cStdOut )
RETURN hb_StrReplace( cStdOut, Chr( 13 ) + Chr( 10 ) )
METHOD Generate() CLASS GenerateHTML
LOCAL cRevision := GitRev()
::Spacer()
::CloseTag( "main" )
::Spacer()
::OpenTag( "footer" )
::Append( "Generated by hbdoc on " + hb_TToC( hb_DateTime() - ( hb_UTCOffset() / 86400 ), "yyyy-mm-dd", "hh:mm" ) + " UTC", "div" )
::OpenTagInline( "div" )
::AppendInline( "Based on commit " )
#if defined( HB_VERSION_URL_BASE )
::OpenTagInline( "a", "href", hb_Version( HB_VERSION_URL_BASE ) + "tree/" + cRevision )
#endif
::AppendInline( cRevision )
#if defined( HB_VERSION_URL_BASE )
::CloseTagInline( "a" )
#endif
::CloseTag( "div" )
::CloseTag( "footer" )
::super:Generate()
#if 0
? Round( ( hb_MilliSeconds() - ::nStart ) / 1000, 3 )
#endif
RETURN self
METHOD NewDocument( cDir, cFilename, cTitle, cLang ) CLASS GenerateHTML
::super:NewDocument( cDir, cFilename, cTitle, EXTENSION, cLang )
::NewFile()
RETURN self
METHOD NewIndex( cDir, cFilename, cTitle, cLang ) CLASS GenerateHTML
::super:NewIndex( cDir, cFilename, cTitle, EXTENSION, cLang )
::NewFile()
RETURN self
METHOD BeginSection( cSection, cFilename ) CLASS GenerateHTML
cSection := SymbolToHTMLID( cSection )
IF ::IsIndex()
IF cFilename == ::cFilename
::OpenTagInline( "div", "id", cSection ):AppendInline( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" )
ELSE
::OpenTag( "a", "href", cFilename + ::cExtension + "#" + cSection ):Append( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "a" )
ENDIF
ELSE
::OpenTagInline( "div", "id", cSection ):AppendInline( cSection, "h" + hb_ntos( ::Depth + 2 ) ):CloseTag( "div" )
ENDIF
::TargetFilename := cFilename
::Depth++
RETURN self
METHOD EndSection( cSection, cFilename ) CLASS GenerateHTML
HB_SYMBOL_UNUSED( cSection )
HB_SYMBOL_UNUSED( cFilename )
::Depth--
RETURN self
METHOD AddReference( oEntry, cReference, cSubReference ) CLASS GenerateHTML
IF HB_ISOBJECT( oEntry ) .AND. oEntry:ClassName() == "ENTRY"
::OpenTag( "a", "href", ::TargetFilename + ::cExtension + "#" + oEntry:_filename ):Append( oEntry:fld[ "NAME" ] ):CloseTag( "a" ):Append( oEntry:fld[ "ONELINER" ] ):Newline()
ELSE
IF HB_ISSTRING( cSubReference )
::OpenTag( "a", "href", cReference + ::cExtension + "#" + cSubReference ):Append( oEntry ):CloseTag( "a" ):Newline()
ELSE
::OpenTag( "a", "href", cReference + ::cExtension /* + "#" + oEntry:_filename */ ):Append( oEntry ):CloseTag( "a" ):Newline()
ENDIF
ENDIF
RETURN self
METHOD AddEntry( oEntry ) CLASS GenerateHTML
LOCAL item
LOCAL cEntry
::Spacer()
::OpenTag( "section", "id", SymbolToHTMLID( oEntry:_filename ) )
FOR EACH item IN FieldIDList()
IF item == "NAME"
cEntry := oEntry:fld[ "NAME" ]
IF "(" $ cEntry .OR. Upper( cEntry ) == cEntry // guess if it's code
::OpenTagInline( "h4" ):OpenTagInline( "code" ):AppendInline( cEntry ):CloseTagInline( "code" ):CloseTag( "h4" )
ELSE
::OpenTagInline( "h4" ):AppendInline( cEntry ):CloseTag( "h4" )
ENDIF
ELSEIF oEntry:IsField( item ) .AND. oEntry:IsOutput( item ) .AND. Len( oEntry:fld[ item ] ) > 0
::WriteEntry( item, oEntry:fld[ item ], oEntry:IsPreformatted( item ) )
ENDIF
NEXT
::CloseTag( "section" )
RETURN self
METHOD PROCEDURE WriteEntry( cField, cContent, lPreformatted ) CLASS GenerateHTML
STATIC s_class := { ;
"NAME" => "d-na", ;
"ONELINER" => "d-ol", ;
"EXAMPLES" => "d-ex", ;
"TESTS" => "d-te" }
LOCAL cTagClass
LOCAL cCaption
LOCAL lFirst
LOCAL tmp, tmp1
LOCAL cLine
LOCAL lCode, lTable, lTablePrev, cHeaderClass
IF ! Empty( cContent )
cTagClass := hb_HGetDef( s_class, cField, "d-it" )
IF ! HB_ISNULL( cCaption := FieldCaption( cField ) )
::Tagged( cCaption, "div", "class", "d-d" )
ENDIF
DO CASE
CASE lPreformatted /* EXAMPLES, TESTS */
::OpenTag( "pre", "class", cTagClass )
::Append( cContent,, .T. )
::CloseTag( "pre" )
CASE cField == "SEEALSO"
::OpenTagInline( "div", "class", cTagClass )
lFirst := .T.
FOR EACH tmp IN hb_ATokens( cContent, "," )
tmp := AllTrim( tmp )
IF ! HB_ISNULL( tmp )
// TOFIX: for multi-file output
tmp1 := Parse( tmp, "(" )
IF lFirst
lFirst := .F.
ELSE
::Space()
ENDIF
::OpenTagInline( "code" ):OpenTagInline( "a", "href", "#" + SymbolToHTMLID( tmp1 ) ):AppendInline( tmp ):CloseTagInline( "a" ):CloseTagInline( "code" )
ENDIF
NEXT
::CloseTag( "div" )
CASE cField == "SYNTAX"
::OpenTagInline( "div", "class", cTagClass )
DO WHILE ! HB_ISNULL( cContent )
::OpenTagInline( "code" )
::AppendInline( Indent( Parse( @cContent, hb_eol() ), 0, -1,, .T. ),, .F. )
::CloseTagInline( "code" )
ENDDO
::CloseTag( "div" )
OTHERWISE
::OpenTag( "div", "class", cTagClass )
::nIndent++
lTable := .F.
DO WHILE ! HB_ISNULL( cContent )
lCode := .F.
lTablePrev := lTable
tmp1 := ""
DO WHILE ! HB_ISNULL( cContent )
cLine := Parse( @cContent, hb_eol() )
DO CASE
CASE hb_LeftEq( LTrim( cLine ), "```" )
IF lCode
EXIT
ELSE
lCode := .T.
ENDIF
CASE cLine == "<fixed>"
lCode := .T.
CASE cLine == "</fixed>"
IF lCode
EXIT
ENDIF
CASE hb_LeftEq( cLine, "<table" )
lTable := .T.
DO CASE
CASE cLine == "<table-noheader>" ; cHeaderClass := ""
CASE cLine == "<table-doubleheader>" ; cHeaderClass := "d-t1 d-t2"
OTHERWISE ; cHeaderClass := "d-t1"
ENDCASE
CASE cLine == "</table>"
lTable := .F.
OTHERWISE
tmp1 += cLine + hb_eol()
IF ! lCode
EXIT
ENDIF
ENDCASE
ENDDO
IF lTable != lTablePrev
IF lTable
::OpenTag( "div", "class", "d-t" + iif( HB_ISNULL( cHeaderClass ), "", " " + cHeaderClass ) )
ELSE
::CloseTag( "div" )
ENDIF
ENDIF
DO CASE
CASE lCode
::OpenTag( "pre" )
::Append( tmp1,, .T. )
CASE lTable
::OpenTagInline( "div" )
::AppendInline( iif( lTable, StrTran( tmp1, " ", hb_UChar( 160 ) ), tmp1 ),, .T. )
OTHERWISE
::OpenTagInline( "div" )
IF cField $ "DESCRIPTION|"
::OpenTagInline( "p" )
ENDIF
::AppendInline( iif( lTable, StrTran( tmp1, " ", hb_UChar( 160 ) ), tmp1 ),, .F. )
ENDCASE
IF lCode
::CloseTag( "pre" )
ELSE
::CloseTag( "div" )
ENDIF
ENDDO
::nIndent--
::CloseTag( "div" )
ENDCASE
ENDIF
RETURN
METHOD OpenTagInline( cText, ... ) CLASS GenerateHTML
LOCAL aArgs := hb_AParams()
LOCAL idx
FOR idx := 2 TO Len( aArgs ) STEP 2
cText += " " + aArgs[ idx ] + "=" + '"' + aArgs[ idx + 1 ] + '"'
NEXT
IF ! cText $ "pre"
::cFile += Replicate( " ", ::nIndent )
ENDIF
::cFile += "<" + cText + ">"
RETURN self
METHOD OpenTag( cText, ... ) CLASS GenerateHTML
::OpenTagInline( cText, ... )
::cFile += hb_eol()
RETURN self
METHOD Tagged( cText, cTag, ... ) CLASS GenerateHTML
LOCAL aArgs := hb_AParams()
LOCAL cResult := ""
LOCAL idx
FOR idx := 3 TO Len( aArgs ) STEP 2
cResult += " " + aArgs[ idx ] + "=" + '"' + aArgs[ idx + 1 ] + '"'
NEXT
::cFile += "<" + cTag + cResult + ">" + cText + "</" + cTag + ">" + hb_eol()
RETURN self
METHOD CloseTagInline( cText ) CLASS GenerateHTML
::cFile += "</" + cText + ">"
RETURN self
METHOD CloseTag( cText ) CLASS GenerateHTML
::cFile += "</" + cText + ">" + hb_eol()
RETURN self
STATIC FUNCTION StrEsc( cString )
STATIC s_html := { ;
"&" => "&amp;", ;
'"' => "&quot;", ;
"<" => "&lt;", ;
">" => "&gt;" }
RETURN hb_StrReplace( cString, s_html )
METHOD AppendInline( cText, cFormat, lCode ) CLASS GenerateHTML
LOCAL idx
LOCAL cChar, cPrev, cNext, cOut, tmp, tmp1, nLen
LOCAL lEM, lIT, lPR
LOCAL nEM, nIT, nPR
LOCAL cdp
IF ! HB_ISNULL( cText )
hb_default( @lCode, .F. )
IF lCode
cText := StrEsc( cText )
ELSE
cdp := hb_cdpSelect( "EN" ) /* make processing loop much faster */
lEM := lIT := lPR := .F.
cOut := ""
nLen := Len( cText )
FOR tmp := 1 TO nLen
cPrev := iif( tmp > 1, SubStr( cText, tmp - 1, 1 ), "" )
cChar := SubStr( cText, tmp, 1 )
cNext := SubStr( cText, tmp + 1, 1 )
DO CASE
CASE ! lPR .AND. cChar == "\" .AND. tmp < Len( cText )
tmp++
cChar := cNext
CASE ! lPR .AND. cChar == "*" .AND. ! lIT .AND. ;
iif( lEM, ! Empty( cPrev ) .AND. Empty( cNext ), Empty( cPrev ) .AND. ! Empty( cNext ) )
lEM := ! lEM
IF lEM
nEM := Len( cOut ) + 1
ENDIF
cChar := iif( lEM, "<strong>", "</strong>" )
CASE ! lPR .AND. cChar == "_" .AND. ! lEM .AND. ;
( ( ! lIT .AND. Empty( cPrev ) .AND. ! Empty( cNext ) ) .OR. ;
( lIT .AND. ! Empty( cPrev ) .AND. Empty( cNext ) ) )
lIT := ! lIT
IF lIT
nIT := Len( cOut ) + 1
ENDIF
cChar := iif( lIT, "<i>", "</i>" )
CASE cChar == "`" .AND. ;
( ( ! lPR .AND. Empty( cPrev ) .AND. ! Empty( cNext ) ) .OR. ;
( lPR .AND. ! Empty( cPrev ) .AND. Empty( cNext ) ) )
lPR := ! lPR
IF lPR
nPR := Len( cOut ) + 1
ENDIF
cChar := iif( lPR, "<code>", "</code>" )
CASE ! lPR .AND. SubStr( cText, tmp, 3 ) == "<b>"
tmp += 2
cChar := "<strong>"
CASE ! lPR .AND. SubStr( cText, tmp, 4 ) == "</b>"
tmp += 3
cChar := "</strong>"
CASE ! lPR .AND. ;
( SubStr( cText, tmp, 3 ) == "===" .OR. SubStr( cText, tmp, 3 ) == "---" )
DO WHILE tmp < nLen .AND. SubStr( cText, tmp, 1 ) == cChar
tmp++
ENDDO
cChar := "<hr>"
CASE ! lPR .AND. ;
( SubStr( cText, tmp, 5 ) == "<URL:" .AND. ( tmp1 := hb_At( ">", cText, tmp + 6 ) ) > 0 )
tmp1 := SubStr( cText, tmp + 5, tmp1 - tmp - 5 )
tmp += Len( tmp1 ) + 5
cChar := "<a href=" + '"' + tmp1 + '"' + ">" + tmp1 + "</a>"
CASE ! lPR .AND. ;
( SubStr( cText, tmp, 3 ) == "==>" .OR. SubStr( cText, tmp, 3 ) == "-->" )
tmp += 2
cChar := "&rarr;"
CASE ! lPR .AND. ;
( SubStr( cText, tmp, 2 ) == "->" )
tmp += 1
cChar := "&rarr;"
CASE cChar == "&"
cChar := "&amp;"
CASE cChar == '"'
cChar := "&quot;"
CASE cChar == "<"
cChar := "&lt;"
CASE cChar == ">"
cChar := "&gt;"
ENDCASE
cOut += cChar
NEXT
/* Remove these tags if they weren't closed */
IF lPR
cOut := Stuff( cOut, nPR, Len( "<code>" ), "`" )
ENDIF
IF lEM
cOut := Stuff( cOut, nEM, Len( "<strong>" ), "*" )
ENDIF
IF lIT
cOut := Stuff( cOut, nIT, Len( "<i>" ), "_" )
ENDIF
cText := cOut
hb_cdpSelect( cdp )
ENDIF
FOR EACH idx IN hb_ATokens( hb_defaultValue( cFormat, "" ), "," ) DESCEND
IF ! Empty( idx )
cText := "<" + idx + ">" + cText + "</" + idx + ">"
ENDIF
NEXT
DO WHILE Right( cText, Len( hb_eol() ) ) == hb_eol()
cText := hb_StrShrink( cText, Len( hb_eol() ) )
ENDDO
::cFile += cText
ENDIF
RETURN self
METHOD Append( cText, cFormat, lCode ) CLASS GenerateHTML
::AppendInline( cText, cFormat, lCode )
::cFile += hb_eol()
RETURN self
METHOD RecreateStyleDocument( cStyleFile ) CLASS GenerateHTML
LOCAL cString
#pragma __streaminclude "hbdoc.css" | cString := %s
IF ! hb_MemoWrit( ::cDir + hb_ps() + cStyleFile, cString )
/* TODO: raise an error, could not create style file */
ENDIF
RETURN self
STATIC FUNCTION SymbolToHTMLID( cID )
RETURN Lower( hb_StrReplace( cID, { ;
"%" => "pct", ;
"_" => "-", ;
" " => "-" } ) )