' Gambas module file '************************************************************************************** ' ' THIS VERSION IS DEPRECATED! THE CURRENT VERSION IS LOCATED IN THE GAMBAS 3 SOURCES ' '************************************************************************************** PUBLIC InfoFilePath AS String PRIVATE CONST DEFAULT_LANG AS String = "en" PRIVATE CONST TYPE_COMMON AS Integer = 0 PRIVATE CONST TYPE_COMPONENT AS Integer = 1 PRIVATE CONST TYPE_CLASS AS Integer = 2 PRIVATE CONST TYPE_SYMBOL AS Integer = 3 PRIVATE CONST BULLET AS String = "" 'PRIVATE CONST BRK AS String = "

" PRIVATE $hConn AS NEW Connection PRIVATE $aLang AS String[] PRIVATE $sUser AS String PRIVATE $bWget AS Boolean PRIVATE $bHelp AS Boolean PRIVATE $bShow AS Boolean PRIVATE $bEdit AS Boolean PRIVATE $bRename AS Boolean PRIVATE $bAdmin AS Boolean PRIVATE $bHistory AS Boolean PRIVATE $bComment AS Boolean PRIVATE $bLogin AS Boolean PRIVATE $bFind AS Boolean PRIVATE $bView AS Boolean PRIVATE $bNew AS Boolean PRIVATE $sLang AS String PRIVATE $sLangSuff AS String PRIVATE $sShowSuff AS String PRIVATE $sPath AS String PRIVATE $sRoot AS String PRIVATE $aPath AS String[] PRIVATE $sUri AS String PRIVATE $bExample AS Boolean PRIVATE $iType AS Integer PRIVATE $cGotSpecial AS Collection PRIVATE $bHeader AS Boolean PRIVATE $hComp AS CComponent PRIVATE $hClass AS CClassInfo PRIVATE $hSym AS CSymbolInfo PRIVATE $sSection AS String PRIVATE $aSection AS String[] PRIVATE $bVerbatim AS Boolean PRIVATE $bNoWiki AS Boolean PRIVATE $sRes AS String PRIVATE $sList AS String PRIVATE $iPos AS Integer PRIVATE $bWhite AS Boolean PRIVATE $bRefresh AS Boolean PRIVATE $bUndo AS Boolean PRIVATE $bImage AS Boolean PRIVATE $bDispImage AS Boolean PRIVATE $cCompRedirect AS Collection PRIVATE $eTime AS Float PRIVATE PARA AS String PRIVATE SUB AddParam(sReq AS String, sParam AS String) AS String IF NOT sParam THEN RETURN sReq IF InStr(sReq, "?") = 0 THEN RETURN sReq & "?" & sParam ELSE RETURN sReq & "&" & sParam ENDIF END PRIVATE SUB DeleteTempFile() SHELL "rm -rf " & File.Dir(Temp$()) & " > /dev/null 2>&1" WAIT END PUBLIC SUB Main() DIM rPage AS Result DIM sPath AS String DIM bPost AS Boolean DIM sDir AS String DIM sErr AS String 'File.In.EndOfLine = gb.Windows 'File.Out.EndOfLine = gb.Windows $eTime = Timer $aLang = [DEFAULT_LANG, "fr", "de", "es", "it", "nl", "pl", "pt", "pt_BR", "ca", "ar", "fa", "vi", "ja", "ru", "zh", "zh_TW", "eo"] $sRoot = File.Dir(File.Dir(Application.Path)) 'Application.Env["DOCUMENT_ROOT"] IF NOT Exist($sRoot &/ ".htaccess") THEN $sRoot = User.Home &/ "www/help" $sUser = Application.Env["REMOTE_USER"] OpenDatabase System.Language = $sLang IF $sLang <> DEFAULT_LANG THEN $sLangSuff = $sLang ELSE IF $bWget THEN $sLangSuff = $sLang ENDIF IF $sLangSuff THEN $sLangSuff = "?" & $sLangSuff bPost = Application.Env["REQUEST_METHOD"] = "POST" IF $bAdmin THEN IF bPost THEN DoAdminPage ELSE AdminPage ENDIF ELSE IF $bEdit THEN IF bPost THEN UpdatePage ELSE IF $bUndo THEN UndoPage ELSE EditPage ENDIF ELSE IF $bRename THEN IF bPost THEN DoRenamePage ELSE RenamePage ENDIF ELSE IF $bHistory THEN HistoryPage ELSE IF $bLogin THEN LoginPage ELSE IF $bDispImage THEN DisplayImage ELSE IF $bFind THEN IF bPost THEN DoSearchPage ELSE SearchPage ENDIF ELSE DisplayPage ENDIF CComponent.Exit DeleteTempFile CATCH sErr = Error.Where & ": " & Error.Text DEBUG sErr OUTPUT TO DEFAULT IF NOT $bHeader THEN PRINT "Content-type: text/html" PRINT ENDIF PRINT "

Unexpected error while displaying this page.

" PRINT "
"; Error.Text
  PRINT ""; Error.Where; "
" DeleteTempFile END PRIVATE SUB ReadConfiguration() DIM hFile AS File OPEN $sRoot &/ ".conf" FOR READ AS #hFile LINE INPUT #hFile, $hConn.Type LINE INPUT #hFile, $hConn.Login LINE INPUT #hFile, $hConn.Password LINE INPUT #hFile, $hConn.Name CLOSE #hFile InfoFilePath = $sRoot &/ "info" CATCH PRINT $sRoot;; Error.Where;; Error.Text END PRIVATE SUB OpenDatabase() $hConn.Type = "mysql" $hConn.Login = "root" $hConn.Name = "gambas" ReadConfiguration $hConn.Open $sUri = Application.Env["REQUEST_URI"] IF NOT $sUri THEN $sUri = "/edit/comp/gb/pointer[]/_put" $sPath = "/comp/gb/pointer[]/_put" $sLang = DEFAULT_LANG 'DB.Debug = TRUE '$sRoot = "/var/www/html" ELSE $sPath = Application.Env["PATH_INFO"] IF Right$($sPath) = "/" THEN $sPath = Left$($sPath, -1) IF NOT $sPath THEN $sPath = "/" $sLang = Application.Env["QUERY_STRING"] IF Right($sLang, 7) = "refresh" THEN $bRefresh = TRUE $sLang = Left$($sLang, -7) IF Right($sLang) = "&" THEN $sLang = Left$($sLang, -1) ELSE IF Right($sLang, 4) = "undo" THEN $bUndo = TRUE $sLang = Left$($sLang, -4) IF Right($sLang) = "&" THEN $sLang = Left$($sLang, -1) ELSE IF Right($sLang, 4) = "view" THEN $bView = TRUE $bShow = TRUE $sLang = Left$($sLang, -4) IF Right($sLang) = "&" THEN $sLang = Left$($sLang, -1) ELSE IF Right($sLang, 4) = "show" THEN $bShow = TRUE $sLang = Left$($sLang, -4) IF Right($sLang) = "&" THEN $sLang = Left$($sLang, -1) ENDIF IF $aLang.Find($sLang) < 0 THEN $sLang = DEFAULT_LANG ENDIF $bWget = Application.Env["HTTP_USER_AGENT"] LIKE "WGet*" '$bComment = IsCommentPath($sPath) $bImage = Left(File.Name($sPath)) = ":" $bDispImage = $sUri LIKE "/image*" IF NOT $bShow THEN $bShow = $bWget OR $sUri LIKE "/show*" $bHelp = $bShow OR $sUri LIKE "/help*" $bEdit = $sUri LIKE "/edit*" $bRename = $sUri LIKE "/rename*" $bFind = $sUri LIKE "/help/search*" IF $bFind THEN $bHelp = FALSE $bAdmin = $sUri LIKE "/admin*" $bHistory = $sUri LIKE "/hist*" $sUri = $sPath IF $sLang <> DEFAULT_LANG THEN $sUri = AddParam($sUri, $sLang) IF $bShow THEN $sUri = AddParam($sUri, "show") $sShowSuff = "show" ENDIF $aPath = Split($sPath, "/") IF $sPath LIKE "/comp/*" THEN $iType = $aPath.Count - 2 IF $aPath.Count > 2 THEN CComponent.Init $hComp = CComponent.All[$aPath[2]] IF $hComp THEN $hComp.Load IF $aPath.Count > 3 THEN $hClass = CComponent.All[$aPath[2]][$aPath[3]] IF $hClass THEN IF $aPath.Count > 4 THEN $hSym = $hClass.Symbols[Replace($aPath[4], ".", ":")] ENDIF ENDIF ENDIF ENDIF ENDIF IF $bWget THEN $bRefresh = TRUE END PRIVATE FUNCTION IsCommentPath(sPath AS String) AS Boolean RETURN Right(sPath, 8) = ".comment" END PRIVATE FUNCTION GetCommentPath(sPath AS String) AS String IF Right(sPath, 8) = ".comment" THEN RETURN sPath ELSE RETURN sPath & ".comment" ENDIF END PRIVATE FUNCTION GetUncommentPath(sPath AS String) AS String IF Right(sPath, 8) = ".comment" THEN RETURN Left$(sPath, -8) ELSE RETURN sPath ENDIF END PRIVATE FUNCTION GetAbsolutePath(sRoot AS String, sPath AS String) AS String DIM sElt AS String DIM sRes AS String IF Left(sPath, 2) <> "./" AND Left(sPath, 3) <> "../" THEN IF Left(sPath) <> "/" THEN sPath = "/" & sPath RETURN sPath ENDIF sRes = sRoot IF Right(sRes) = "/" AND Len(sRes) > 1 THEN sRes = Left(sRes, -1) FOR EACH sElt IN Split(sPath, "/") IF sElt = "." THEN CONTINUE IF sElt = ".." THEN 'IF sRes = sRoot THEN CONTINUE sRes = File.Dir(sRes) CONTINUE ENDIF sRes &/= sElt NEXT RETURN sRes END PRIVATE SUB GetLinkClass(sClass AS String, bLTR AS Boolean, sTitle AS String) AS String IF System.RightToLeft AND IF NOT bLTR AND IF IsAscii(sTitle) THEN sClass &= "lang=\"en\" " bLTR = TRUE ENDIF IF bLTR THEN sClass &= "dir=\"ltr\" " RETURN sClass END PRIVATE FUNCTION GetLink(sPath AS String, OPTIONAL sMyTitle AS String, OPTIONAL bNoImage AS Boolean, OPTIONAL sClass AS String, OPTIONAL bLTR AS Boolean) AS String DIM sTitle AS String DIM sRelPath AS String IF sClass THEN sClass = "class=\"" & sClass & "\" " IF sPath LIKE "http://*" OR IF sPath LIKE "mailto:*" THEN IF NOT sMyTitle THEN sMyTitle = sPath RETURN "" & EncodeHTML(sMyTitle) & "" ELSE IF sPath LIKE ($sPath &/ "*") THEN sRelPath = "." &/ Mid$(sPath, Len($sPath) + 1) ELSE sRelPath = sPath ENDIF sPath = LCase(GetAbsolutePath($sPath, sRelPath)) sTitle = GetTitle(sPath) IF sTitle THEN IF Left(File.Name(sPath)) = ":" AND NOT bNoImage THEN IF sMyTitle THEN sTitle = sMyTitle RETURN "\""" ELSE IF sMyTitle THEN sTitle = sMyTitle RETURN "" & EncodeHTML(sTitle) & "" ENDIF ELSE IF $bWget THEN IF sMyTitle THEN RETURN "" & EncodeHTML(sMyTitle) & "" ELSE RETURN "" & EncodeHTML(sPath) & "" ENDIF ELSE IF sMyTitle THEN RETURN "" & EncodeHTML(sMyTitle) & "" ELSE RETURN "" & EncodeHTML(sRelPath) & "" ENDIF ENDIF ENDIF ENDIF END PRIVATE FUNCTION GetImage(sImg AS String, OPTIONAL sAdd AS String) AS String IF sAdd THEN sAdd = " " & sAdd RETURN "" END PRIVATE FUNCTION EncodeHTML(sStr AS String) AS String DIM iPos AS Integer DIM sRes AS String DIM sCar AS String FOR iPos = 1 TO Len(sStr) sCar = Mid$(sStr, iPos, 1) IF sCar = "<" THEN sCar = "<" ELSE IF sCar = ">" THEN sCar = ">" ELSE IF sCar = "&" THEN sCar = "&" ELSE IF sCar = "\"" THEN sCar = """ 'ELSE IF Asc(sCar) > 127 THEN 'sCar = "&#" & Asc(sCar) & ";" ENDIF sRes = sRes & sCar NEXT RETURN sRes END PRIVATE SUB FinishList() IF $sList THEN $sRes = $sRes & $sList & "\n" $sList = "" ENDIF END PRIVATE SUB AddPara() IF Right($sRes, 4) <> "

\n" THEN IF Right$($sRes) = "\n" THEN $sRes &= "

" ELSE $sRes &= "\n" ENDIF ENDIF END PRIVATE SUB RemovePara() IF Right($sRes, 4) = "

\n" THEN $sRes = Left$($sRes, -4) & "\n" ENDIF END PRIVATE SUB EnterSection(sSection AS String, OPTIONAL sArg AS String) DIM aSection AS String[] DIM sParam AS String DIM iPos AS Integer 'IF $sSection <> "example" AND IF $sSection <> "syntax" AND IF $sSection <> "title" THEN ' AddPara ' ENDIF IF sSection THEN iPos = InStr(sSection, " ") IF iPos THEN sParam = Mid$(sSection, iPos + 1) sSection = Left$(sSection, iPos - 1) ENDIF ENDIF sSection = LCase(sSection) FinishList 'LeaveSection() $aSection.Push($sSection) $sSection = sSection $bVerbatim = FALSE $sList = "" SELECT CASE $sSection CASE "syntax" IF NOT sParam THEN sParam = ("Syntax") $sRes &= "

" & sParam & "
\n" $sRes &= "
"

    CASE "example"
      'IF NOT $bExample THEN
      '  $bExample = TRUE
      '  $sRes &= "

" & ("Example") & "

\n" 'ENDIF IF NOT sParam THEN sParam = ("Example") $sRes &= "
" & sParam & "
\n" $sRes &= "
"
      '$bVerbatim = TRUE
      $bNoWiki = TRUE

    CASE "code"
      $sRes &= "
"

    CASE "seealso"
      '$sRes &= "

\n" '$sRes &= "
" & ("See also") & "
\n" $sRes &= "
\n" $sRes &= "

" & ("See also") & "

\n" $iPos = Len($sRes) CASE "error" '$sRes &= "

" & ("Errors") & "

\n" $sRes &= "
" & ("Errors") & "
\n" $sRes &= "\n" $sRes &= "\n" '$sRes &= "
" & ("Message") & "" & ("Description") & "
\n" $bWhite = TRUE CASE "warning", "info", "vb", "critical", "tip" $sRes &= "
\n" $sRes &= "
" & GetImage($sSection) & "\n" CASE "title" IF NOT sParam THEN sParam = "gray" $sRes &= "
" CASE "box" IF sParam THEN $sRes &= "
" & EncodeHTML(sParam) & "
" $sRes &= "
\n" END SELECT END PRIVATE SUB LeaveSection() DIM sList AS String FinishList RemovePara SELECT CASE $sSection CASE "syntax" $sRes = RTrim($sRes) & "

\n" CASE "example" $sRes = RTrim($sRes) & "\n" '$bVerbatim = FALSE $bNoWiki = FALSE CASE "code" $sRes = RTrim($sRes) & "

\n" CASE "error" $sRes &= "
\n" CASE "seealso" $sRes = Left$($sRes, $iPos) & Replace(Mid$($sRes, $iPos + 1), "", " ") '$sRes &= "
\n" $sRes &= "
\n" CASE "warning", "info", "vb", "critical", "tip" $sRes &= "
\n" CASE "title" $sRes &= "" ' no '\n' to prevent an '

' to be added CASE "box" $sRes &= "\n" END SELECT TRY $sSection = $aSection.Pop() END PRIVATE FUNCTION Encode(sStr AS String) AS String DIM iPos AS Integer DIM iPos2 AS Integer DIM sCar AS String DIM bBold AS Boolean DIM bItalic AS Boolean DIM bUnderline AS Boolean DIM bTT AS Boolean DIM sTitle AS String DIM sLink AS String DIM sLinkTitle AS String DIM bLinkTitle AS String DIM sLine AS String DIM bLastVoid AS Boolean DIM bHeader AS Boolean DIM sArg AS String DIM iLevel AS Integer DIM iLevelLen AS Integer DIM bList AS Boolean $sRes = "" $aSection = NEW String[] EnterSection("") FOR EACH sStr IN Split(RTrim(sStr), "\n") IF Left$(sStr) = "{" AND IF Len(sStr) >= 2 THEN EnterSection(Trim(Mid$(sStr, 2))) CONTINUE ELSE IF RTrim(sStr) = "}" THEN LeaveSection() CONTINUE ENDIF IF $bVerbatim THEN IF sStr = "==" THEN $bVerbatim = FALSE $sRes = $sRes & "

" CONTINUE ELSE $sRes = $sRes & sStr & "\n" CONTINUE ENDIF ENDIF IF NOT $bNoWiki THEN sStr = RTrim(sStr) sTitle = "" IF NOT sStr THEN ' IF bLastVoid THEN ' $sRes = $sRes & "
\n" ' ELSE ' bLastVoid = TRUE ' $sRes = $sRes & "\n" ' ENDIF IF Right($sRes, 4) <> "

\n" THEN $sRes = $sRes & "

\n" ELSE $sRes = $sRes & "\n" ENDIF CONTINUE ENDIF WHILE Left(sStr) = " " sStr = Mid$(sStr, 2) $sRes &= " " WEND bLastVoid = FALSE bList = FALSE iPos = InStr(sStr, " ") IF iPos >= 2 THEN IF Left$(sStr, iPos - 1) = String(iPos - 1, "*") THEN iLevel = iPos - 1 iLevelLen = iLevel * 6 IF Len($sList) > iLevelLen THEN sCar = Mid$($sList, 1 + iLevelLen) $sList = Left($sList, iLevelLen) ELSE IF Len($sList) < iLevelLen THEN sCar = String$((iLevelLen - Len($sList)) \ 6, "

    \n") $sList &= String$((iLevelLen - Len($sList)) \ 6, "
\n") ELSE sCar = "" ENDIF $sRes &= sCar & "
  • " sStr = Trim(Mid$(sStr, iPos + 1)) bList = TRUE ELSE IF Left$(sStr, iPos - 1) = String(iPos - 1, "#") THEN iLevel = iPos - 1 iLevelLen = iLevel * 6 IF Len($sList) > iLevelLen THEN sCar = Mid$($sList, 1 + iLevelLen) $sList = Left($sList, iLevelLen) ELSE IF Len($sList) < iLevelLen THEN sCar = String$((iLevelLen - Len($sList)) \ 6, "
      \n") $sList &= String$((iLevelLen - Len($sList)) \ 6, "
    \n") ELSE sCar = "" ENDIF $sRes &= sCar & "
  • " sStr = Trim(Mid$(sStr, iPos + 1)) bList = TRUE ENDIF ENDIF IF NOT bList THEN FinishList IF Left$(sStr) = "@" THEN iPos = InStr(sStr, " ") IF iPos THEN sArg = Trim(Mid$(sStr, iPos + 1)) sStr = Left$(sStr, iPos - 1) ENDIF sStr = Mid$(sStr, 2) TRY $cGotSpecial[sStr] = TRUE SELECT CASE sStr CASE "classes" $sRes = $sRes & GetClasses() CONTINUE CASE "no-classes" TRY $cGotSpecial["classes"] = FALSE CONTINUE CASE "symbols" $sRes = $sRes & GetSymbols() CONTINUE CASE "components" $sRes = $sRes & GetComponents() CONTINUE CASE "redirect" iPos = InStr(sArg, " ") IF iPos THEN IF NOT $cCompRedirect THEN $cCompRedirect = NEW Collection $cCompRedirect[Trim(Left(sArg, iPos - 1))] = Trim(Mid$(sArg, iPos + 1)) ENDIF CONTINUE ' @index /path prefix CASE "index" $sRes = $sRes & GetIndex2(sArg) CONTINUE ' @list /path +-number CASE "list" '$sRes = $sRes & GetList(sArg) CONTINUE ' @header /path +-number CASE "header" '$sRes = $sRes & GetList(sArg) CONTINUE CASE "syntax" IF $hSym THEN EnterSection("syntax") $sRes = $sRes & GetSyntax() LeaveSection() ENDIF CONTINUE CASE "version" $sRes = $sRes & GetVersion() CONTINUE CASE "changes" $sRes &= GetLastChanges() CONTINUE CASE "translate" $sRes &= GetTranslate() CONTINUE CASE "class-stat" $sRes &= GetClassStat() CONTINUE CASE "no-autolink" CONTINUE CASE ELSE $sRes &= "
    " & sStr & " ?
    " CONTINUE END SELECT ELSE IF Left$(sStr) = "+" THEN iPos = 1 WHILE Mid$(sStr, iPos, 1) = "+" INC iPos WEND sStr = LTrim(Mid$(sStr, iPos)) IF Len(sStr) THEN 'DEC iPos $sRes = $sRes & "" sTitle = "" ENDIF ENDIF IF Left(sStr, 2) = "[[" THEN $sRes = $sRes & "\n" bHeader = TRUE $sRes = $sRes & "\n" bHeader = FALSE ELSE $sRes = $sRes & "\n" ENDIF $sRes = $sRes & "
    \n" $bWhite = FALSE CONTINUE ELSE IF Len(sStr) <= 2 THEN IF sStr = "]]" THEN IF bHeader THEN $sRes = $sRes & "
    \n" CONTINUE ELSE IF sStr = "[]" THEN bHeader = FALSE CONTINUE ELSE IF sStr = "--" THEN $sRes = $sRes & "
    \n" CONTINUE ELSE IF sStr = "==" THEN $bVerbatim = TRUE $sRes = $sRes & "
    "
              CONTINUE
      '       ELSE IF sStr = "[" THEN
      '         IF bHeader THEN
      '           $sRes = $sRes & "\n"
      '         ELSE
      '           $sRes = $sRes & "\n"
      '         ENDIF
      '         CONTINUE
      '       ELSE IF sStr = "]" THEN
      '         IF bHeader THEN
      '           $sRes = $sRes & "\n"
      '           bHeader = FALSE
      '         ELSE
      '           $sRes = $sRes & "\n"
      '         ENDIF
      '         CONTINUE
            ELSE IF sStr = "][" THEN
              $bWhite = NOT $bWhite
              IF bHeader THEN
                IF Right($sRes, 9) = "\n" THEN
                  IF $bWhite THEN
                    $sRes = Left$($sRes, -9) & "\n"
                  ELSE
                    $sRes = Left$($sRes, -9) & "\n"
                  ENDIF
                ELSE
                  IF $bWhite THEN
                    $sRes = $sRes & "\n\n"
                  ELSE
                    $sRes = $sRes & "\n\n"
                  ENDIF
                ENDIF
                bHeader = FALSE
              ELSE
                IF $bWhite THEN
                  $sRes = $sRes & "\n\n"
                ELSE
                  $sRes = $sRes & "\n\n"
                ENDIF
              ENDIF
              CONTINUE
            ELSE IF sStr = "-" THEN
              IF bHeader THEN
                $sRes = $sRes & "\n"
              ELSE
                $sRes = $sRes & "\n"
              ENDIF
              CONTINUE
            'ELSE IF sStr = "_" THEN
            '  $sRes = $sRes & "

    " ' CONTINUE ENDIF ENDIF ENDIF FOR iPos = 1 TO Len(sStr) sCar = Mid$(sStr, iPos, 1) IF sCar = "\\" THEN INC iPos sCar = Mid$(sStr, iPos, 1) IF sCar = "<" THEN sCar = "<" ELSE IF sCar = ">" THEN sCar = ">" ELSE IF sCar = "&" THEN sCar = "&" ENDIF ELSE IF sCar = "\"" THEN sCar = """ ELSE IF sCar = "<" THEN iPos2 = InStr(sStr, ">", iPos) IF iPos2 = 0 THEN iPos2 = Len(sStr) + 1 sCar = Mid$(sStr, iPos, iPos2 - iPos + 1) iPos = iPos2 ELSE IF $bNoWiki THEN ELSE IF sCar = "*" THEN bBold = NOT bBold sCar = If(bBold, "", "") ELSE IF sCar = "/" THEN IF bItalic OR Asc(Mid$(sStr, iPos + 1, 1)) > 32 THEN bItalic = NOT bItalic sCar = If(bItalic, "", "") ENDIF ELSE IF sCar = "_" THEN IF iPos = Len(sStr) AND NOT bUnderline THEN sCar = "
    " ELSE bUnderline = NOT bUnderline sCar = If(bUnderline, "", "") ENDIF ELSE IF sCar = "=" THEN IF bTT OR Asc(Mid$(sStr, iPos + 1, 1)) > 32 THEN bTT = NOT bTT sCar = If(bTT, "", "") ENDIF ELSE IF sCar = "[" THEN IF Mid$(sStr, iPos + 1, 1) <> " " THEN sLink = "" sLinkTitle = "" bLinkTitle = FALSE iPos2 = iPos + 1 WHILE iPos2 <= Len(sStr) sCar = Mid$(sStr, iPos2, 1) IF sCar = "]" THEN BREAK IF sCar = "|" THEN bLinkTitle = TRUE ELSE IF sCar = "\\" THEN INC iPos2 sCar = Mid$(sStr, iPos2, 1) ENDIF IF bLinkTitle THEN sLinkTitle &= sCar ELSE sLink &= sCar ENDIF ENDIF INC iPos2 WEND sCar = "[" IF iPos2 <= Len(sStr) AND IF Len(Trim(sLink)) THEN sCar = GetLink(Trim(sLink), Trim(sLinkTitle)) iPos = iPos2 ENDIF ENDIF ELSE IF sCar = "%" THEN IF Mid$(sStr, iPos + 1, 1) <> " " THEN iPos2 = InStr(sStr, "%", iPos + 1) IF iPos2 THEN sLink = Mid$(sStr, iPos + 1, iPos2 - iPos - 1) sCar = GetImage(sLink) iPos = iPos2 ENDIF ENDIF 'ELSE IF Asc(sCar) > 127 THEN 'sCar = "&#" & Asc(sCar) & ";" ENDIF $sRes = $sRes & sCar NEXT $sRes = $sRes & sTitle & "\n" NEXT WHILE $aSection.Count LeaveSection() WEND WHILE Right$($sRes) = "\n" $sRes = Left$($sRes, -1) WEND RETURN $sRes END PRIVATE FUNCTION DecodeURL(sUrl AS String) AS String DIM sRes AS String DIM iPos AS Integer DIM sCar AS String FOR iPos = 1 TO Len(sUrl) sCar = Mid$(sUrl, iPos, 1) IF sCar = "+" THEN sCar = " " ELSE IF sCar = "%" THEN sCar = Chr$(Val("&H" & Mid$(sUrl, iPos + 1, 2))) iPos = iPos + 2 ENDIF sRes = sRes & sCar NEXT sRes = Replace(sRes, "\r", "") RETURN sRes END PRIVATE SUB EncodeURL(URL AS String) AS String DIM iInd AS Integer DIM sRes AS String DIM sCar AS String FOR iInd = 1 TO Len(URL) sCar = Mid$(URL, iInd, 1) IF sCar = " " THEN sCar = "+" ELSE IF IsLetter(sCar) OR IF IsDigit(sCar) OR IF InStr("*-._", sCar) THEN ELSE sCar = "%" & Hex$(Asc(sCar), 2) ENDIF sRes &= sCar NEXT RETURN sRes END PRIVATE FUNCTION GetForm() AS Collection DIM sLine AS String DIM iPos AS Integer DIM sVal AS String DIM sName AS String DIM cForm AS NEW Collection DIM sForm AS String READ #File.In, sForm, Val(Application.Env["CONTENT_LENGTH"]) FOR EACH sLine IN Split(sForm, "&") iPos = InStr(sLine, "=") IF iPos = 0 THEN CONTINUE sVal = DecodeURL(Mid$(sLine, iPos + 1)) sName = Left$(sLine, iPos - 1) cForm[sName] = sVal NEXT RETURN cForm END PRIVATE SUB PrintTitle(sTitle AS String) IF sTitle THEN IF $hSym THEN IF NOT $hSym.IsHidden() THEN PRINT $hClass.Name; "."; ENDIF PRINT EncodeHTML(sTitle) IF $hClass THEN PRINT " ("; $hComp.Key; ")"; ENDIF ELSE PRINT $sPath ENDIF END PRIVATE SUB MakeTitle(sTitle AS String) PRINT "" PRINT ("Gambas Documentation"); " - "; PrintTitle(sTitle) PRINT "" END PRIVATE SUB PrintTab(sText AS String, bOn AS Boolean, sClass AS String, sPath AS String, OPTIONAL sLink AS String) IF bOn THEN PRINT ""; sText; "" ELSE PRINT "
    " PRINT "
    "; IF sPath THEN PRINT ""; GetLink(sPath, sText, TRUE); "" ELSE PRINT ""; sText; "" ENDIF PRINT "
    " PRINT "" ENDIF END PRIVATE SUB PrintPath() DIM sElt AS String DIM sPath AS String DIM aElt AS String[] IF $bView THEN RETURN IF System.RightToLeft THEN PRINT "
    "; ELSE PRINT "
    "; ENDIF PRINT " "; 'PRINT "\"""; PRINT GetImage("lang/" & $sLang, "class=\"flag\" alt=\"" & ("Home") & "\""); PRINT ""; IF $sPath AND IF $sPath <> "/" THEN PRINT " / "; sPath = "/" aElt = Split(File.Dir($sPath), "/") FOR EACH sElt IN aElt IF NOT sElt THEN CONTINUE sPath &/= sElt IF $bHelp THEN PRINT GetLink(sPath, sElt); ELSE PRINT sElt; ENDIF PRINT " / "; NEXT PRINT File.Name($sPath); ENDIF PRINT " 
    " END PRIVATE SUB MakeHeader(OPTIONAL sTitle AS String, OPTIONAL sWarn AS String) DIM iPos AS Integer DIM sLang AS String DIM rPage AS Result PRINT "Content-type: text/html;charset=UTF-8" PRINT "Content-language: "; Replace(System.Language, "_", "-") PRINT PRINT "" PRINT "" ELSE PRINT " dir=\"ltr\">" ENDIF PRINT "" PRINT "" PRINT "" MakeTitle(sTitle) PRINT "" 'IF System.RightToLeft THEN ' PRINT "" 'ELSE ' PRINT "" 'ENDIF $bHeader = TRUE 'PRINT "

     

     

    " 'IF NOT $bWget THEN PRINT "

    " IF NOT $bShow THEN PRINT "" IF System.RightToLeft THEN PRINT "" IF System.RightToLeft THEN PRINT "
    " ELSE PRINT "
    " ENDIF 'PRINT "" PrintPath IF $bHelp THEN rPage = DB.Exec("SELECT sPath FROM page WHERE sPath < &1 ORDER BY sPath DESC LIMIT 2", $sPath) IF rPage.Available AND IF IsCommentPath(rPage!sPath) THEN rPage.MoveNext IF rPage.Available THEN PRINT "" & ("Previous") & " " ELSE PRINT ("Previous") & " " ENDIF rPage = DB.Exec("SELECT sPath FROM page WHERE sPath > &1 ORDER BY sPath LIMIT 2", $sPath) IF rPage.Available AND IF IsCommentPath(rPage!sPath) THEN rPage.MoveNext IF rPage.Available THEN PRINT "" & ("Next") & " " ELSE PRINT ("Next") & " " ENDIF ENDIF IF NOT $bWget THEN IF TRUE THEN '$sUser IF $bAdmin OR $bFind THEN ELSE IF $bEdit OR $bRename THEN IF $bNew THEN PRINT "" ELSE PRINT "" ENDIF PRINT ("Cancel") PRINT " " ELSE PRINT ""; IF sTitle THEN PRINT ("Edit"); ELSE PRINT ("Create"); ENDIF PRINT " " IF sTitle AND $sPath <> "/" AND NOT $bComment THEN PRINT ""; PRINT ("Rename"); PRINT " " ENDIF IF sTitle AND NOT $bImage THEN PRINT ""; PRINT ("Undo"); PRINT " " ENDIF IF NOT ($bComment OR $bNew) THEN PRINT ""; PRINT ("Refresh"); PRINT " " ENDIF ENDIF IF $bHelp THEN PRINT ""; ("Search"); " " PRINT ""; ("Administration"); " " ENDIF ELSE IF NOT ($bComment OR $bNew) THEN PRINT ""; PRINT ("Refresh"); PRINT " " ENDIF ENDIF ' PRINT "" PRINT " " ELSE PRINT "" ENDIF FOR EACH sLang IN $aLang IF sLang = $sLang THEN CONTINUE IF $bAdmin THEN PRINT ""; GetImage("lang/" & sLang, "class=\"flag\" alt=\"" & sLang & "\""); PRINT " " '"\"""; "  " NEXT 'IF $sUser THEN ' PRINT $sUser 'ELSE ' PRINT ""; ("Login"); "" 'ENDIF ENDIF PRINT "
    " ELSE PrintPath ENDIF IF NOT $bShow AND ($bHelp OR $bEdit OR $bHistory) THEN PRINT "" PrintTab(("Documentation"), NOT ($bComment OR $bHistory), "taboffl", GetUncommentPath($sPath)) IF (NOT $bNew OR $bComment) AND NOT $bImage THEN IF GetTitle(GetUncommentPath($sPath)) THEN 'PrintTab(("Comments"), $bComment, If($bHistory, "taboffl", "taboffr"), GetCommentPath($sPath)) PrintTab(("History"), $bHistory, "taboffr", "", "/hist" &/ GetUncommentPath($sPath) & $sLangSuff) ENDIF ENDIF PRINT "" PRINT "
     
    " PRINT "
    " ELSE IF $bShow THEN PRINT "
    " ELSE PRINT "
    " ENDIF ENDIF IF sWarn THEN PRINT "
    " PRINT ""; ("Warning!"); " "; sWarn; " " IF NOT $bWget THEN PRINT "" & ("See english version") & " " ENDIF PRINT "
    " ENDIF IF NOT $bEdit THEN IF $bComment THEN PRINT "

    "; Subst(("Comments on &1"), GetTitle(GetUncommentPath($sPath))); "

    " ELSE PRINT "
    " 'PrintTitle(String.UCase(String.Left(sTitle)) & String.Mid(sTitle, 2)) PrintTitle(sTitle) PRINT "
    " ENDIF ENDIF END PRIVATE SUB MakeFooter(OPTIONAL dDate AS Date) DIM sEnv AS String PRINT "

    " ' IF NOT $bWGet THEN ' ' PRINT "
    " ' ' PRINT ""; ' ' IF dDate THEN ' ' PRINT ""; ' ' ENDIF ' ' PRINT "" ' ' PRINT "
    "; ' ' PRINT ""; Subst(("Documentation generated in &1 s. by a CGI script written in Gambas :-)"), Format$(Timer - $eTime, "0.###")); "" ' ' PRINT ""; ' ' PRINT ("Last modified:");; dDate; ' ' PRINT "
    " ' ' ' IF Right(Application.Env["REQUEST_URI"]) = "/" THEN ' ' ' ' PRINT "

    " ' ' FOR EACH sEnv IN Application.Env ' ' PRINT "" ' ' NEXT ' ' PRINT "
    "; EncodeHTML(sEnv); ""; EncodeHTML(Application.Env[sEnv]); " 
    " ' ' ' ' ENDIF ' ELSE ' PRINT "


    " ' ENDIF PRINT "" PRINT "" PRINT END PRIVATE FUNCTION GetRealPath(sPath AS String) AS String DIM rPage AS Result RETRY: rPage = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, DEFAULT_LANG) IF rPage.Available AND IF Left$(rPage!sTitle) = "@" THEN sPath = GetAbsolutePath(sPath, Mid$(rPage!sTitle, 2)) GOTO RETRY ENDIF RETURN sPath END PRIVATE FUNCTION FindPage(sPath AS String, OPTIONAL bNoLink AS Boolean) AS Result DIM rPage AS Result IF NOT bNoLink THEN sPath = GetRealPath(sPath) rPage = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, $sLang) IF NOT rPage.Available THEN rPage = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, DEFAULT_LANG) ENDIF RETURN rPage END PRIVATE FUNCTION GetTitle(sPath AS String) AS String DIM rPage AS Result rPage = FindPage(sPath) IF rPage.Available THEN 'IF sPath LIKE "/comp/*/*/*" THEN ' RETURN GetTitle(File.Dir(sPath)) & "." & rPage!sTitle 'ELSE RETURN rPage!sTitle 'ENDIF ENDIF END PRIVATE SUB PrintExample(sExample AS String) IF NOT sExample THEN RETURN IF NOT $bExample THEN $bExample = TRUE PRINT "

    " & ("Example") & "

    " ENDIF PRINT "
    "; RTrim(sExample); "

    " END ' PRIVATE SUB PrintSection(sCode AS String) ' ' sCode = Encode(sCode) ' IF NOT sCode THEN RETURN ' ' PRINT sCode ' PRINT "

    " ' ' END PRIVATE SUB DisplayImage() DIM rPage AS Result DIM rPageDef AS Result DIM bWarn AS Boolean DIM sWarn AS String DIM sPath AS String DIM sPage AS String sPath = GetRealPath($sPath) rPage = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, $sLang) rPageDef = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, DEFAULT_LANG) IF rPageDef.Available THEN IF NOT rPage.Available THEN ' IF sPath = $sPath THEN ' sWarn = ("This page is not translated.") ' $bNew = TRUE ' ENDIF rPage = rPageDef ELSE ' IF rPageDef!dDate > rPage!dDate THEN ' IF sPath = $sPath THEN sWarn = ("This page is not up to date.") ' ENDIF ENDIF ENDIF 'DEBUG DB.Tables["page"].Fields["sdata"].Type 'PRINT #File.Err, rPage.Fields["sData"].Type; "/"; Len(rPage["sData"].Data) 'DEBUG rPage!sData.Length PRINT rPage!sHtml PRINT "Content-Length: "; rPage["sData"].Length PRINT PRINT rPage!sData.Data; END PRIVATE SUB DisplayPage() DIM rPage AS Result DIM rPageDef AS Result DIM bWarn AS Boolean DIM sWarn AS String DIM sPath AS String DIM sPage AS String sPath = GetRealPath($sPath) IF $bRefresh THEN rPage = DB.Edit("page", "sPath = &1 AND sLang = &2", sPath, $sLang) rPageDef = DB.Edit("page", "sPath = &1 AND sLang = &2", sPath, DEFAULT_LANG) ELSE rPage = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, $sLang) rPageDef = DB.Find("page", "sPath = &1 AND sLang = &2", sPath, DEFAULT_LANG) ENDIF IF rPageDef.Available THEN IF NOT rPage.Available THEN IF sPath = $sPath THEN sWarn = ("This page is not translated.") $bNew = TRUE ENDIF rPage = rPageDef $bRefresh = FALSE ELSE IF rPageDef!dDate > rPage!dDate THEN IF sPath = $sPath THEN sWarn = ("This page is not up to date.") ENDIF ENDIF ENDIF IF NOT rPage.Available THEN MakeHeader() IF $bComment THEN PRINT "

    " & ("There is no comment on this page yet.") & "

    " ELSE PRINT "

    " & ("This documentation page is not available.") & "

    " ENDIF MakeFooter RETURN ENDIF MakeHeader(rPage!sTitle, sWarn) IF $bImage THEN PRINT "" ELSE IF $bShow THEN PRINT MakePageWithoutHeader(rPage) MakeFooter ELSE IF $bRefresh AND NOT $bNew THEN sPage = MakePageWithoutHeader(rPage) IF $cGotSpecial.Count = 0 THEN rPage!sHTML = sPage rPage.Update ENDIF ENDIF IF rPage!sHTML THEN PRINT rPage!sHTML MakeFooter(rPage!dDate) ELSE IF NOT sPage THEN sPage = MakePageWithoutHeader(rPage) PRINT sPage MakeFooter ENDIF ENDIF END PRIVATE FUNCTION MakePageWithoutHeader(rPage AS Result) AS String DIM bExample AS Boolean DIM bPrint AS Boolean DIM hFile AS File DIM sFile AS String DIM sResult AS String sFile = Temp$() TRY KILL sFile TRY OPEN sFile FOR CREATE AS #hFile IF ERROR THEN OPEN sFile FOR CREATE AS #hFile ENDIF OUTPUT TO #hFile $cGotSpecial = NEW Collection bPrint = FALSE IF $iType = TYPE_SYMBOL AND IF $hSym THEN PRINT Encode("@syntax") ENDIF PRINT Encode(rPage!sDesc) IF $iType = TYPE_COMPONENT AND IF NOT $cGotSpecial.Exist("classes") THEN PRINT "

    " PRINT Encode("@classes") ELSE IF $iType = TYPE_CLASS AND IF NOT $cGotSpecial.Exist("symbols") THEN PRINT "

    " PRINT Encode("@symbols") ENDIF OUTPUT TO DEFAULT CLOSE #hFile sResult = File.Load(sFile) KILL sFile RETURN sResult END PRIVATE FUNCTION QuoteSpecial(sName AS String) AS String sName = Replace(sName, "[", "\\[") sName = Replace(sName, "_", "\\_") RETURN sName END PRIVATE FUNCTION GetOld(sPath AS String, OPTIONAL bSyntax AS Boolean) AS String DIM sData AS String DIM iPos AS Integer DIM iPos2 AS Integer DIM sRes AS String DIM sCar AS String sData = File.Load(sPath) iPos = InStr(sData, "") IF iPos THEN sData = Mid$(sData, iPos + 5) IF bSyntax THEN iPos = InStr(sData, "") IF iPos THEN sData = Mid$(sData, iPos + 8) ENDIF iPos = 1 DO iPos = InStr(sData, "<", iPos) IF iPos = 0 THEN BREAK IF InStr(" =>", Mid$(sData, iPos + 1, 1)) THEN INC iPos CONTINUE ENDIF iPos2 = InStr(sData, ">", iPos + 1) IF iPos2 = 0 THEN BREAK sData = Left$(sData, iPos - 1) & Mid$(sData, iPos2 + 1) LOOP sData = Trim(sData) IF LCase(sData) = "not documented" THEN sData = "" RETURN sData END PRIVATE FUNCTION GetOldComponentName(sComp AS String) AS String DIM sRes AS String DIM iPos AS Integer DIM sCar AS String SELECT CASE sComp CASE "gb.xml" RETURN "GbXmlLibxml" CASE "gb.xml.rpc" RETURN "GbXmlLibxmlRpc" CASE "gb.xml.xslt" RETURN "GbXmlLibxmlXslt" CASE "gb.sdl.sound" RETURN "GbSdl" CASE "gb.settings" RETURN "Gb" DEFAULT sComp = "." & sComp FOR iPos = 1 TO Len(sComp) sCar = Mid$(sComp, iPos, 1) IF sCar = "." THEN INC iPos sCar = UCase(Mid$(sComp, iPos, 1)) ENDIF sRes = sRes & sCar NEXT RETURN sRes END SELECT END PRIVATE FUNCTION GetOldName(sName AS String) AS String sName = Replace(sName, "$", "") sName = Replace(sName, "[", "") sName = Replace(sName, "]", "") sName = Replace(sName, "_", "") sName = Replace(sName, ".", "") RETURN sName END PRIVATE FUNCTION GetOldClassName(sName AS String) AS String sName = Replace(sName, "[]", "Array") sName = Replace(sName, ".", "") RETURN sName END PRIVATE SUB RemoveMarkup(sStr AS String) AS String DIM iInd AS Integer DIM aWait AS NEW String[] DIM sWait AS String DIM sCar AS String DIM sRes AS String FOR iInd = 1 TO Len(sStr) sCar = Mid$(sStr, iInd, 1) IF sCar = sWait THEN sWait = aWait.Pop() CONTINUE ENDIF IF sCar = "<" THEN aWait.Push(sWait) sWait = ">" CONTINUE ENDIF IF sCar = Chr$(34) THEN IF sWait THEN aWait.Push(sWait) sWait = Chr$(34) CONTINUE ENDIF ENDIF IF NOT sWait THEN sRes &= sCar NEXT RETURN sRes END PRIVATE SUB EditPage() DIM rPage AS Result DIM sSave AS String DIM aFile AS String[] DIM sName AS String DIM iPos AS Integer DIM sDir AS String DIM sPath AS String DIM sKind AS String rPage = FindPage($sPath, TRUE) IF NOT rPage.Available THEN rPage = DB.Create("page") IF $bComment THEN rPage!sTitle = Subst(("Comments on &1"), GetTitle(GetUncommentPath($sPath))) ELSE sDir = $sRoot &/ "old" 'System.Path &/ "share/gambas2/help/" IF Exist(sDir) THEN SELECT CASE $iType CASE TYPE_COMPONENT IF $hComp THEN rPage!sTitle = $hComp.Key sPath = sDir &/ GetOldComponentName($hComp.Key) & ".html" IF Exist(sPath) THEN rPage!sDesc = GetOld(sPath) ENDIF ENDIF CASE TYPE_CLASS IF $hClass THEN rPage!sTitle = QuoteSpecial($hClass.Name) sPath = sDir &/ GetOldComponentName($hComp.Key) & GetOldClassName($hClass.Name) & ".html" IF Exist(sPath) THEN rPage!sDesc = GetOld(sPath) ENDIF ENDIF CASE TYPE_SYMBOL IF $hSym THEN IF Left$($hSym.Name) = "_" THEN SELECT CASE $hSym.Name CASE "_new" rPage!sTitle = "NEW " & $hClass.Name CASE "_put" rPage!sTitle = $hClass.Name & "[] = ..." CASE "_get" rPage!sTitle = $hClass.Name & "[]" CASE "_call" rPage!sTitle = $hClass.Name & "()" CASE "_next" rPage!sTitle = "FOR EACH " & $hClass.Name DEFAULT rPage!sTitle = $hSym.Name END SELECT ELSE rPage!sTitle = $hSym.Name ENDIF IF Left$(rPage!sTitle) = ":" THEN rPage!sTitle = Mid$(rPage!sTitle, 2) sName = UCase($hSym.Kind) IF sName = ":" THEN sName = "E" & Mid$($hSym.Name, 2) ELSE sName = sName & $hSym.Name ENDIF sName = Replace(sName, "_", "") sPath = sDir &/ GetOldComponentName($hComp.Key) & GetOldClassName($hClass.Name) & sName & ".html" IF Exist(sPath) THEN rPage!sDesc = GetOld(sPath, TRUE) ELSE rPage!sDesc = "\n" ENDIF ENDIF CASE ELSE IF $sPath LIKE "/lang/*" THEN sName = Mid$($sPath, 7) sName = UCase(Left$(sName)) & Mid$(sName, 2) aFile = Dir(sDir, "Lang" & sName & ".html") IF aFile.Count = 0 THEN aFile = Dir(sDir, "Lang" & UCase(sName) & ".html") IF aFile.Count = 0 THEN aFile = Dir(sDir, "Lang" & sName & "*.html") IF aFile.Count THEN rPage!sDesc = GetOld(sDir &/ aFile[0]) rPage!sTitle = Mid$(File.BaseName(aFile[0]), 5) ENDIF ELSE IF $sPath LIKE "/api/name/*" THEN sName = LCase(Mid$($sPath, 11)) aFile = Dir(sDir, "Api*.html") iPos = aFile.Find("api" & GetOldName(sName) & ".html", gb.Text) IF iPos >= 0 THEN rPage!sDesc = GetOld(sDir &/ aFile[iPos]) rPage!sTitle = Mid$(File.BaseName(aFile[iPos]), 4) ENDIF 'ELSE IF InStr(Mid$($sPath, 2), "/") = 0 THEN ELSE sName = Mid$(File.Name($sPath), 2) aFile = Dir(sDir, "*.html") iPos = aFile.Find(GetOldName(sName) & ".html", gb.Text) IF iPos >= 0 THEN rPage!sDesc = GetOld(sDir &/ aFile[iPos]) rPage!sTitle = File.BaseName(aFile[iPos]) ENDIF ENDIF END SELECT ENDIF IF $hComp THEN IF $hComp.Key = "gb.gtk" OR $hComp.Key = "gb.gui" THEN rPage!sTitle = "@" & Replace($sPath, "/" & $hComp.Key, "/gb.qt") 'rPage!sDesc = NULL ENDIF ENDIF ENDIF IF IsNull(rPage!sTitle) THEN sName = File.Name($sPath) IF Left(sName) = ":" THEN sName = Mid$(sName, 2) rPage!sTitle = sName ENDIF ENDIF $bNew = rPage!sLang <> $sLang MakeHeader(rPage!sTitle) sSave = "\n" & "  " IF $bImage THEN PRINT "

    " PRINT "

      " & sSave & "

    " PRINT "

    " PRINT "
    " ELSE PRINT "
    " PRINT "

      " & sSave & "

    " PRINT "

    " PRINT "
    " ENDIF MakeFooter() END PRIVATE FUNCTION MakeRelative(sLink AS String) AS String DIM aPath AS String[] DIM aLink AS String[] DIM iInd AS Integer DIM iMax AS Integer aPath = Split($sPath, "/") aLink = Split(sLink, "/") iMax = Min(aPath.Max, aLink.Max) FOR iInd = 0 TO iMax IF aPath[iInd] <> aLink[iInd] THEN BREAK NEXT IF iInd <= iMax AND (aPath.Count - iInd <= 2) THEN sLink = String$(aPath.Count - iInd, "../") WHILE iInd < aLink.Count sLink = sLink &/ aLink[iInd] INC iInd WEND ENDIF RETURN sLink END PRIVATE FUNCTION AutoLink(sStr AS String) AS String DIM cCache AS NEW Collection DIM sRes AS String DIM iInd AS Integer DIM rPage AS Result DIM rComp AS Result DIM sCar AS String DIM iWord AS Integer DIM sWait AS String DIM sWord AS String DIM sOrig AS String DIM nSpace AS Integer DIM aWord AS String[] DIM nWord AS Integer DIM iPos AS Integer 'DIM bSkip AS Boolean DIM iLevelBrace AS Integer DIM sClass AS String DIM sSymbol AS String DIM sTitle AS String FOR EACH sStr IN Split(sStr, "\n") sStr = RTrim(sStr) IF sWait THEN IF sStr = sWait THEN IF sWait = "}" THEN DEC iLevelBrace IF iLevelBrace = 0 THEN sWait = "" ENDIF ELSE sWait = "" ENDIF ENDIF sRes &= sStr & "\n" CONTINUE ELSE IF sStr = "==" THEN sWait = sStr sRes &= sStr & "\n" CONTINUE ELSE IF Left(sStr) = "{" THEN IF LCase(Mid$(sStr, 2)) = "example" OR IF LCase(Mid$(sStr, 2)) = "syntax" THEN INC iLevelBrace sWait = "}" ENDIF sRes &= sStr & "\n" CONTINUE ELSE IF Left(sStr) = "@" THEN sRes &= sStr & "\n" CONTINUE ELSE IF Left(sStr) = "+" THEN cCache.Clear sRes &= sStr & "\n" CONTINUE ENDIF 'bSkip = FALSE sWait = "" iWord = 0 sStr &= " " FOR iInd = 1 TO Len(sStr) sCar = Mid$(sStr, iInd, 1) IF sWait = " " THEN IF IsPunct(sCar) OR IF IsSpace(sCar) THEN sWait = "" ENDIF ELSE IF sWait THEN IF sCar = sWait THEN sWait = "" ENDIF ELSE IF iWord = 0 THEN IF LCase(sCar) >= "a" AND LCase(sCar) <= "z" THEN iWord = iInd CONTINUE ELSE IF sCar = "[" THEN sWait = "]" ELSE IF sCar = "{" THEN sWait = "}" ELSE IF sCar = "%" THEN sWait = "%" ELSE IF sCar = "\\" THEN sWait = " " 'sCar = "" 'INC iInd 'sCar &= Mid$(sStr, iInd, 1) ENDIF ELSE IF LCase(sCar) >= "a" AND LCase(sCar) <= "z" THEN CONTINUE IF sCar >= "0" AND sCar <= "9" THEN CONTINUE IF sCar = "$" OR sCar = "-" OR sCar = "_" OR sCar = "\\" THEN CONTINUE IF sCar = "." THEN IF IsLetter(Mid$(sStr, iInd + 1, 1)) THEN CONTINUE ENDIF 'IF sCar = " " AND nSpace < 2 THEN ' INC nSpace ' CONTINUE 'ENDIF sOrig = Mid$(sStr, iWord, iInd - iWord) sWord = Replace(sOrig, "\\_", "_") sTitle = "" IF NOT cCache.Exist(sWord) THEN cCache[sWord] = TRUE IF Len(sWord) > 1 THEN aWord = Split(sWord, ".", "", TRUE) IF aWord.Count = 1 THEN rPage = DB.Find("page", "sTitle = &1 AND sLang = &2", sWord, DEFAULT_LANG) IF $hComp THEN FOR EACH rPage IF rPage!sPath LIKE "/lang/*" OR IF (rPage!sPath LIKE ("/comp/" &/ $hComp.Key & "/*") AND NOT (rPage!sPath LIKE "/comp/*/*/*")) THEN IF rPage!sTitle = sWord THEN GOTO FOUND ENDIF ENDIF NEXT ENDIF FOR EACH rPage IF rPage!sPath LIKE "/lang/*" OR IF (rPage!sPath LIKE "/comp/*/*" AND NOT (rPage!sPath LIKE "/comp/*/*/*")) THEN IF rPage!sTitle = sWord THEN BREAK ENDIF ELSE IF rPage!sPath LIKE "/def/*" THEN BREAK ENDIF NEXT ELSE IF aWord[0] = "gb" THEN rPage = DB.Find("page", "sPath = &1 AND sLang = &2", "/comp" &/ LCase(sWord), DEFAULT_LANG) IF rPage.Available THEN GOTO FOUND ENDIF IF aWord.Count = 2 THEN rPage = DB.Find("page", "sTitle = &1 AND sLang = &2 AND sPath LIKE &3", aWord[1], DEFAULT_LANG, "/comp/gb.qt" &/ LCase(aWord[0]) &/ "%") IF NOT rPage.Available THEN rPage = DB.Find("page", "sTitle = &1 AND sLang = &2 AND sPath LIKE &3", aWord[1], DEFAULT_LANG, "/comp/gb%" &/ LCase(aWord[0]) &/ "%") ENDIF sTitle = sWord ENDIF ENDIF FOUND: IF rPage.Available THEN IF rPage!sPath <> $sPath THEN IF sTitle THEN sRes &= "[" & MakeRelative(rPage!sPath) & "|" & sTitle & "]" & sCar ELSE sRes &= "[" & MakeRelative(rPage!sPath) & "]" & sCar ENDIF iInd = iWord + Len(sOrig) iWord = 0 nSpace = 0 'sTitle = "" ENDIF CONTINUE ENDIF ENDIF sRes &= sOrig & sCar 'aWord[0] iInd = iWord + Len(sOrig) 'Len(aWord[0]) iWord = 0 nSpace = 0 'bSkip = FALSE CONTINUE ELSE sCar = sOrig & sCar ENDIF iWord = 0 ENDIF sRes &= sCar NEXT IF Right(sRes) = " " THEN sRes = Left(sRes, -1) sRes &= "\n" sWait = "" NEXT RETURN Trim(sRes) & "\n" END PRIVATE SUB UndoPage() DIM rPage AS Result DIM rArch AS Result rPage = DB.Edit("page", "sPath = &1 AND sLang = &2", $sPath, $sLang) IF rPage.Available THEN rArch = DB.Limit(2).Find("archive", "sPath = &1 AND sLang = &2 ORDER BY dDate DESC", $sPath, $sLang) IF rArch.Count >= 2 THEN rArch.MoveNext rPage!sTitle = rArch!sTitle rPage!dDate = rArch!dDate rPage!sDesc = rArch!sDesc rPage!sHTML = "" rPage!sUser = rArch!sUser rPage.Update DB.Delete("archive", "sPath = &1 AND sLang = &2 AND dDate > &3", $sPath, $sLang, rArch!dDate) ELSE DB.Delete("page", "sPath = &1 AND sLang = &2", $sPath, $sLang) DB.Delete("archive", "sPath = &1 AND sLang = &2", $sPath, $sLang) ENDIF ENDIF PRINT "Content-type: text/html" PRINT "Location: http://" & Application.Env["HTTP_HOST"] &/ "help" &/ $sUri PRINT END PRIVATE SUB UpdatePage() DIM sForm AS String DIM sLine AS String DIM iPos AS Integer DIM iPos2 AS Integer DIM rPage AS Result DIM sVal AS String DIM bCreate AS Boolean 'DIM bOK AS Boolean DIM bDelete AS Boolean DIM rArch AS Result DIM hField AS ResultField DIM sBoundary AS String DIM sName AS String DIM sField AS String DIM bStop AS Boolean rPage = DB.Create("page") rPage!sPath = $sPath rPage!sLang = $sLang rPage!dDate = Now TRY rPage.Update rPage = DB.Edit("page", "sPath = &1 AND sLang = &2", $sPath, $sLang) IF NOT rPage.Available THEN Error.Raise("Unable to edit the page") ENDIF 'rPage!bDoNotCache = FALSE rPage!sPath = $sPath rPage!sLang = $sLang rPage!dDate = Now rPage!sUser = $sUser IF $bImage THEN ' PRINT "Content-type: application/octet-stream" ' PRINT ' WHILE NOT Eof ' LINE INPUT sLine ' PRINT sLine; "\r" ' WEND ' RETURN ' PRINT #File.Err, rPage!sData.Length File.In.EndOfLine = gb.Windows LINE INPUT sBoundary 'DEBUG sBoundary DO DO LINE INPUT sLine 'DEBUG sLine IF NOT sLine THEN BREAK IF sLine LIKE "Content-Disposition: *" THEN 'sField = Scan(sLine, "*name=\"*\"*")[1] iPos = InStr(sLine, "name=\"") iPos2 = InStr(sLine, "\"", iPos + 6) sField = Mid$(sLine, iPos + 6, iPos2 - iPos - 6) ELSE IF sLine LIKE "Content-Type: *" THEN rPage!sHtml = sLine ENDIF LOOP sForm = "" DO LINE INPUT sLine 'DEBUG Left$(sLine, 32) IF sLine = sBoundary THEN BREAK IF sLine = (sBoundary & "--") THEN bStop = TRUE BREAK ENDIF IF sForm THEN sForm &= "\r\n" sForm &= sLine LOOP 'PRINT #File.Err, sField; "->"; rPage.Fields[sField].Type IF sField = "command" THEN bDelete = sForm = ("Delete") ELSE IF Trim(sForm) THEN rPage[sField] = sForm ENDIF 'PRINT #File.Err, sField; "<-"; Len(sForm) LOOP UNTIL bStop 'PRINT #File.Err, "-> "; rPage!sData.Length File.In.EndOfLine = gb.Unix ELSE READ sForm, Val(Application.Env["CONTENT_LENGTH"]) FOR EACH sLine IN Split(sForm, "&") iPos = InStr(sLine, "=") IF iPos = 0 THEN CONTINUE sVal = DecodeURL(Mid$(sLine, iPos + 1)) 'IF sVal THEN bOK = TRUE sField = Left$(sLine, iPos - 1) IF sField = "command" THEN bDelete = sVal = ("Delete") ELSE rPage[sField] = sVal ENDIF NEXT IF NOT (rPage!sDesc LIKE "@no-autolink\n*") THEN rPage!sDesc = AutoLink(rPage!sDesc) ENDIF rPage!sHTML = MakePageWithoutHeader(rPage) IF $cGotSpecial.Count THEN rPage!sHTML = "" ENDIF ENDIF IF bDelete THEN rPage.Delete ELSE IF NOT $bImage THEN rArch = DB.Create("archive") FOR EACH hField IN rArch.Fields 'PRINT "
    "; hField.Name; " = "; rPage[hField.Name]; "
    " rArch[hField.Name] = rPage[hField.Name] NEXT ENDIF 'db.Debug = TRUE DB.Begin 'DEBUG "rArch.Update" IF NOT $bImage THEN TRY rArch.Update ENDIF 'DEBUG "rPage.Update" rPage.Update 'DEBUG "Commit" DB.Commit 'db.Debug = FALSE ENDIF PRINT "Content-type: text/html" PRINT "Location: http://" & Application.Env["HTTP_HOST"] &/ "help" &/ $sUri; 'IF $bImage AND IF Right($sUri, 8) <> "?refresh" THEN PRINT "?refresh"; PRINT PRINT END PRIVATE SUB RenamePage() DIM rPage AS Result DIM sSave AS String DIM aFile AS String[] DIM sName AS String DIM iPos AS Integer DIM sDir AS String DIM sPath AS String DIM sKind AS String rPage = FindPage($sPath) IF NOT rPage.Available THEN MakeHeader() PRINT "

    " & ("This documentation page is not available.") & "

    " MakeFooter RETURN ENDIF MakeHeader(rPage!sTitle) sSave = "  " PRINT "
    " PRINT "" & ("New path") & "  " PRINT "" PRINT "

    " & ("Rename children") & "" PRINT "

    " PRINT "" PRINT "

    " MakeFooter() END PRIVATE SUB RenameOnePage(sPath AS String, sNewPath AS String) DIM rPage AS Result DIM sOld AS String rPage = DB.Edit("page") WHILE rPage.Available IF Left$(File.Name(rPage!sPath)) <> ":" THEN IF rPage!sPath = sPath THEN rPage!sPath = sNewPath rPage!dDate = Now rPage!sUser = Application.Env["REMOTE_USER"] ENDIF sOld = sPath rPage!sDesc = Replace(rPage!sDesc, "[" & sOld & "]", "[" & sNewPath & "]") rPage!sDesc = Replace(rPage!sDesc, "[" & sOld &/ "]", "[" & sNewPath & "]") IF Left(sOld) = "/" THEN sOld = Mid$(sOld, 2) rPage!sDesc = Replace(rPage!sDesc, "[" & sOld & "]", "[" & sNewPath & "]") rPage!sDesc = Replace(rPage!sDesc, "[" & sOld &/ "]", "[" & sNewPath & "]") ENDIF rPage.Update ENDIF rPage.MoveNext WEND END PRIVATE SUB DoRenamePage() DIM sNewPath AS String DIM rPage AS Result DIM bUpdate AS Boolean DIM cForm AS Collection DIM bChild AS Boolean cForm = GetForm() sNewPath = cForm!sNewPath bChild = cForm.Exist("bChild") IF Left$(sNewPath) <> "/" THEN sNewPath = "/" & sNewPath IF Right$(sNewPath) = "/" THEN sNewPath = Right(sNewPath, -1) IF FindPage(sNewPath).Available THEN MakeHeader PRINT "

    " & ("This documentation page already exists.") & "

    " MakeFooter RETURN ENDIF DB.Begin IF NOT bChild THEN RenameOnePage($sPath, sNewPath) ELSE rPage = DB.Edit("page") WHILE rPage.Available IF Left$(File.Name(rPage!sPath)) <> ":" THEN IF rPage!sPath LIKE ($sPath & "*") THEN RenameOnePage(rPage!sPath, sNewPath & Mid$(rPage!sPath, Len($sPath) + 1)) ENDIF ENDIF rPage.MoveNext WEND ENDIF DB.Commit PRINT "Content-type: text/html" PRINT "Location: http://" & Application.Env["HTTP_HOST"] &/ "help" &/ sNewPath & $sLangSuff PRINT END PRIVATE SUB HistoryPage() DIM rPage AS Result DIM sBefore AS String DIM sNext AS String DIM sDiff AS String DIM sLig AS String DIM sLeft AS String DIM sRight AS String DIM sSym AS String DIM sDesc AS String DIM dDate AS Date DIM sUser AS String DIM aSplit AS String[] DIM aPrint AS Byte[] DIM iWidth AS Integer DIM sRes AS String DIM bGotSym AS Boolean DIM iInd AS Integer DIM iSet AS Integer DIM bPrint AS Boolean MakeHeader(Subst(("&1 - History"), GetTitle($sPath))) sBefore = Temp$() sNext = Temp$() iWidth = 80 rPage = DB.Find("archive", "sPath = &1 AND sLang = &2 ORDER BY dDate DESC", $sPath, $sLang) IF NOT rPage.Available THEN rPage = DB.Find("page", "sPath = &1 AND sLang = &2", $sPath, $sLang) FOR EACH rPage IF sUser THEN PRINT "
    "; PRINT dDate; " - "; sUser; PRINT "
    " File.Save(sNext, sDesc) File.Save(sBefore, rPage!sDesc) EXEC ["diff", "-bByt", "-W", 2 * iWidth, sBefore, sNext] TO sDiff aSplit = Split(sDiff, "\n") aPrint = NEW Byte[aSplit.Count] bGotSym = FALSE sRes = "
    "
    
          FOR iInd = 0 TO aSplit.Max
    
            IF Trim(Mid$(aSplit[iInd], iWidth - 1, 3)) THEN
              FOR iSet = Max(0, iInd - 3) TO Min(aSplit.Max, iInd + 3)
                aPrint[iSet] = 1
              NEXT
            ENDIF
    
          NEXT
    
          bPrint = TRUE
    
          FOR iInd = 0 TO aSplit.Max
    
            IF aPrint[iInd] = 0 THEN
              IF bPrint THEN
                bPrint = FALSE
                sRes &= String$(iWidth - 2, ".") & "   " & String$(iWidth - 2, ".") & "\n"
              ENDIF
              CONTINUE
            ENDIF
    
            bPrint = TRUE
    
            sLig = aSplit[iInd]
    
            sLeft = Left$(sLig, iWidth - 2)
            sLeft &= Space$(Max(0, iWidth - 2 - String.Len(sLeft)))
            sLeft = EncodeHTML(sLeft)
            IF Left(sLeft) = " " THEN sLeft = " " & Mid$(sLeft, 2)
    
            sRight = Mid$(sLig, iWidth + 3)
            sRight &= Space$(Max(0, iWidth - 2 - String.Len(sRight)))
            sRight = EncodeHTML(sRight)
            IF Left(sRight) = " " THEN sRight = " " & Mid$(sRight, 2)
    
            sSym = Trim(Mid$(sLig, iWidth - 1, 3))
    
            IF sSym THEN bGotSym = TRUE
    
            IF InStr("|<(", sSym) THEN
              sRes &= "" & sLeft & ""
            ELSE
              sRes &= sLeft
            ENDIF
    
            sRes &= "   "
    
            IF InStr("|>)", sSym) THEN
              sRes &= "" & sRight & " "
            ELSE
              sRes &= sRight
            ENDIF
    
            sRes &= "\n"
    
          NEXT
    
          sRes &= "
    " IF bGotSym THEN PRINT sRes ELSE PRINT "
    "; ("No change"); "
    " ENDIF ENDIF sDesc = rPage!sDesc sUser = rPage!sUser dDate = rPage!dDate NEXT IF sUser THEN PRINT "
    "; PRINT dDate; " - "; sUser; PRINT "
    " PRINT "
    "; ("Creation"); "
    " ENDIF MakeFooter END PRIVATE SUB LoginPage() MakeHeader("Welcome") PRINT "

    "; Subst(("Welcome back &1!"), $sUser); "

    " MakeFooter END PRIVATE FUNCTION GetUserPath() AS String RETURN $sRoot &/ ".htaccess" END PRIVATE FUNCTION GetUser() AS String[] DIM aUser AS NEW String[] DIM sLine AS String DIM sPath AS String DIM iPos AS Integer FOR EACH sLine IN Split(File.Load(GetUserPath()), "\n") sLine = Trim(sLine) IF NOT sLine THEN CONTINUE iPos = InStr(sLine, ":") IF iPos = 0 THEN CONTINUE aUser.Add(Left$(sLine, iPos - 1)) NEXT 'RETURN aUser.Sort() aUser.Sort RETURN aUser END PRIVATE SUB AdminPage() DIM aUser AS String[] DIM sUser AS String aUser = GetUser() MakeHeader(("Administration")) PRINT "

    "; ("User management"); "

    " 'PRINT "
    ";
      'FOR EACH sUser IN aUser
      '  PRINT EncodeHTML(sUser); " ";
      'NEXT
      'PRINT "

    " PRINT "" PRINT "" PRINT "" PRINT "
    " PRINT ("Create user") PRINT "" PRINT ("Edit user") PRINT "" PRINT ("Delete user") PRINT "
    " PRINT "
    " PRINT "" PRINT "" PRINT "" PRINT "" PRINT "
    "; ("Name"); "
    "; ("Password"); "
    "; ("Confirm"); "
    " PRINT "

    " PRINT "

    " PRINT "
    " PRINT "
    " PRINT "" PRINT "" PRINT "" PRINT "" PRINT "
    "; ("Name"); "" PRINT "" PRINT "
    "; ("Password"); "
    "; ("Confirm"); "
    " PRINT "

    " PRINT "

    " PRINT "
    " PRINT "
    " PRINT "" PRINT "" PRINT "
    "; ("Name"); "" PRINT "" PRINT "
    " PRINT "

    " PRINT "

    " PRINT "
    " PRINT "

    "; ("Database management"); "

    " PRINT "
    " PRINT "" PRINT "
    " PRINT "
    " PRINT "" PRINT "
    " MakeFooter END PRIVATE SUB DoAdminPage() DIM cForm AS Collection DIM hProcess AS Process DIM sSave AS String cForm = GetForm() IF $sPath = "/create" THEN MakeHeader(("Create user")) IF NOT Trim(cForm!sName) THEN PRINT ("Please enter a user name.") ELSE IF cForm!sPassword <> cForm!sPasswordAgain THEN PRINT ("Passwords do not match.") ELSE IF NOT Trim(cForm!sPassword) THEN PRINT ("Please enter a password.") ELSE IF GetUser().Find(cForm!sName) >= 0 THEN PRINT ("User already exists.") ELSE hProcess = SHELL "/usr/sbin/htpasswd -b \"" & GetUserPath() & "\" \"" & cForm!sName & "\" \"" & cForm!sPassword & "\"" WAIT IF hProcess.Value = 0 THEN PRINT Subst(("User '&1' created."), cForm!sName) ELSE PRINT Subst(("Cannot create user '&1'. Error code #&2."), cForm!sName, hProcess.Value) ENDIF ENDIF ELSE IF $sPath = "/edit" THEN MakeHeader(("Edit user")) IF cForm!sPassword <> cForm!sPasswordAgain THEN PRINT ("Passwords do not match.") ELSE IF NOT Trim(cForm!sPassword) THEN PRINT ("Please enter a password.") ELSE hProcess = SHELL "/usr/sbin/htpasswd -b \"" & GetUserPath() & "\" \"" & cForm!sName & "\" \"" & cForm!sPassword & "\"" WAIT IF hProcess.Value = 0 THEN PRINT Subst(("User '&1' modified."), cForm!sName) ELSE PRINT Subst(("Cannot edit user '&1'. Error code #&2."), cForm!sName, hProcess.Value) ENDIF ENDIF ELSE IF $sPath = "/delete" THEN MakeHeader(("Delete user")) IF cForm!sName = "gambas" THEN PRINT ("Cannot delete user 'gambas'. This user is reserved.") ELSE hProcess = SHELL "/usr/sbin/htpasswd -D \"" & GetUserPath() & "\" \"" & cForm!sName & "\"" WAIT IF hProcess.Value = 0 THEN PRINT Subst(("User '&1' deleted."), cForm!sName) ELSE PRINT Subst(("Cannot delete user '&1'. Error code #&2."), cForm!sName, hProcess.Value) ENDIF ENDIF ELSE IF $sPath = "/save.sql.bz2" THEN PRINT "Content-Type: application/x-bzip2" PRINT 'hProcess = EXEC ["mysqldump", "-e", "--compatible=mysql40", "--user=" & $hConn.Login, $hConn.Name] FOR READ hProcess = SHELL "mysqldump --default-character-set=latin1 -e --compatible=mysql40 --user=" & $hConn.Login & " " & $hConn.Name & " | bzip2" FOR READ REPEAT WAIT 0.2 UNTIL hProcess.State <> Process.Running RETURN ELSE IF $sPath = "/purge" THEN SHELL "rm -rf " & File.Dir(File.Dir(Temp$())) WAIT ENDIF PRINT "

    "; ("Return to administration page"); "" MakeFooter() 'PRINT "Content-type: text/html" ' PRINT "Location: http://" & Application.Env["HTTP_HOST"] &/ "admin" END PRIVATE SUB SearchPage() MakeHeader(("Search")) PRINT "

    "; ("Search with Google"); "

    " PRINT "
    " PRINT "" PRINT "" PRINT "" PRINT "
    " MakeFooter END PRIVATE SUB DoSearchPage() DIM cForm AS Collection cForm = GetForm() PRINT "Content-type: text/html;charset=UTF-8" 'PRINT "Refresh: 0;http://www.google.com/search?hl="; EncodeURL(cForm["hl"]); "&q="; EncodeURL(cForm["q"] & " +site:gambasdoc.org") PRINT "Location: http://www.google.com/search?hl="; EncodeURL(cForm["hl"]); "&q="; EncodeURL(cForm["q"] & " +site:gambasdoc.org") PRINT END PRIVATE FUNCTION GetComponents() AS String DIM hComp AS CComponent DIM sPath AS String DIM sRes AS String CComponent.Init sRes = "
      \n" FOR EACH hComp IN CComponent.All sRes = sRes & "
    • " & GetLink("/comp" &/ hComp.Key,,, "arrow") & "\n" NEXT sRes = sRes & "
    \n" RETURN sRes END PRIVATE FUNCTION GetClasses() AS String 'DIM sComp AS String DIM sClass AS String DIM sRes AS String DIM iInd AS Integer DIM iPos AS Integer DIM aClass AS NEW String[] 'CComponent.Init 'sComp = $aPath[1] 'hComp = CComponent.All[sComp] 'hComp.Load() sRes = "
    " & ("Classes") & "
    \n" sRes &= "
    " sRes &= "\n" sRes &= "\n" FOR EACH sClass IN $hComp.ClassList IF Left(sClass) = "." OR IF Left(sClass) = "_" THEN CONTINUE aClass.Add(sClass) NEXT FOR iInd = 0 TO aClass.Max STEP 16 IF iInd > 0 THEN sRes = sRes & "\n" sRes = sRes & "\n" NEXT sRes = sRes & "\n
    \n" FOR iPos = iInd TO Min(iInd + 15, aClass.Max) sClass = aClass[iPos] 'sRes = sRes & "" & sClass & "
    \n" sRes = sRes & GetLink("/comp" &/ LCase($hComp.Key &/ sClass),,, "arrow") & "
    \n" NEXT sRes = sRes & "
    \n

    \n" RETURN sRes CATCH RETURN "

    " & Error.Where & ": " & Error.Text & "
    \n" END PRIVATE FUNCTION GetIndex(sRoot AS String) AS String DIM rPage AS Result DIM sLetter AS String DIM sPath AS String DIM sTitle AS String DIM sRes AS String DIM aPath AS NEW String[] DIM aSplit AS String[] IF NOT sRoot THEN Error.Raise("@index needs an argument") rPage = DB.Find("page", "sLang = &1 AND sPath LIKE &2", DEFAULT_LANG, sRoot &/ "%") ' $Lang FOR EACH rPage sPath = GetRealPath(rPage!sPath) sTitle = GetTitle(sPath) aPath.Add(sTitle & "\n" & rPage!sPath) NEXT FOR EACH sPath IN aPath.Sort(gb.Text) aSplit = Split(sPath, "\n") sTitle = aSplit[0] sPath = aSplit[1] IF UCase(Left(sTitle)) <> sLetter THEN sLetter = UCase(Left(sTitle)) sRes &= "

    " & sLetter & "

    \n" & GetLink(sPath,, TRUE, "arrow") & "\n" ELSE sRes &= " •  " & GetLink(sPath,, TRUE, "arrow") & "\n" ENDIF NEXT RETURN sRes END PRIVATE FUNCTION AddIndexEntry(aPath AS String[], iInd AS Integer) AS String DIM sRes AS String DIM aSplit AS String[] DIM sPath AS String DIM sTitle AS String DIM sOldTitle AS String aSplit = Split(aPath[iInd], "\n") sTitle = aSplit[0] sPath = aSplit[1] IF iInd THEN aSplit = Split(aPath[iInd - 1], "\n") sOldTitle = asPlit[0] ENDIF IF String.UCase(String.Left(sTitle)) <> String.UCase(String.Left(sOldTitle)) THEN IF System.RightToLeft THEN sRes = "" & String.UCase(String.Left(sTitle)) & "\n" ELSE sRes = "\n" ENDIF sRes &= "" & GetLink(sPath,, TRUE, "arrow") & "\n" RETURN sRes END PRIVATE FUNCTION GetIndex2(sRoot AS String) AS String DIM rPage AS Result DIM sRes AS String DIM aPath AS NEW String[] DIM iInd AS Integer DIM iInd2 AS Integer DIM sPath AS String DIM sTitle AS String DIM iPos AS Integer DIM sPrefix AS String IF NOT sRoot THEN Error.Raise("@index needs an argument") iPos = InStr(sRoot, " ") IF iPos THEN sPrefix = Trim(Mid$(sRoot, iPos + 1)) & "*" sRoot = Left$(sRoot, iPos - 1) ENDIF rPage = DB.Find("page", "sLang = &1 AND sPath LIKE &2", DEFAULT_LANG, sRoot &/ "%") ' $Lang FOR EACH rPage IF InStr(Mid$(rPage!sPath, Len(sRoot) + 2), "/") THEN CONTINUE IF IsCommentPath(rPage!sPath) THEN CONTINUE sPath = GetRealPath(rPage!sPath) IF Left(rPage!sTitle) = "@" THEN IF sPath LIKE (sRoot &/ "*") THEN CONTINUE ENDIF sTitle = GetTitle(sPath) IF sTitle LIKE sPrefix THEN sTitle = LTrim(Mid$(sTitle, Len(sPrefix))) ENDIF aPath.Add(sTitle & "\n" & rPage!sPath) NEXT aPath.Sort(gb.Text) sRes = "\n" FOR iInd = 0 TO aPath.Count \ 4 sRes &= "\n" iInd2 = iInd WHILE iInd2 < aPath.Count sRes &= AddIndexEntry(aPath, iInd2) iInd2 += 1 + aPath.Count \ 4 WEND sRes &= "\n" NEXT sRes &= "
    \n" RETURN sRes END PRIVATE FUNCTION GetLastChanges() AS String DIM rPage AS Result DIM sRes AS String DIM bOdd AS Boolean rPage = DB.Find("page", "sLang = &1 ORDER BY dDate DESC LIMIT 100", $sLang) sRes = "\n" sRes &= "\n" FOR EACH rPage IF bOdd THEN sRes &= "\n" ELSE sRes &= "\n" ENDIF sRes &= "\n" sRes &= "\n" sRes &= "\n" sRes &= "\n" bOdd = NOT bOdd NEXT sRes &= "
    " & ("Date") & "" & ("User") & "" & ("Page") & "
    " & rPage!dDate & "" & rPage!sUser & "" & GetLink(rPage!sPath,, TRUE, "arrow") & "
    \n" RETURN sRes END PRIVATE FUNCTION GetTranslate() AS String DIM rPage AS Result DIM rPageDef AS Result DIM sRes AS String DIM bOdd AS Boolean rPageDef = DB.Find("page", "sLang = &1 ORDER BY dDate DESC", DEFAULT_LANG) sRes = "\n" sRes &= "\n" FOR EACH rPageDef rPage = DB.Find("page", "sLang = &1 AND sPath = &2", $sLang, rPageDef!sPath) IF rPage.Available AND IF rPage!dDate >= rPageDef!dDate THEN CONTINUE IF bOdd THEN sRes &= "\n" ELSE sRes &= "\n" ENDIF IF rPage.Available THEN sRes &= "" ELSE sRes &= "" ENDIF IF rPage.Available THEN sRes &= "\n" sRes &= "\n" ELSE sRes &= "\n" sRes &= "\n" ENDIF sRes &= "\n" sRes &= "\n" bOdd = NOT bOdd NEXT sRes &= "
    " & ("State") & "" & ("Date") & "" & ("User") & "" & ("Page") & "
    " & GetImage("refresh") & "" & GetImage("new") & "" & rPage!dDate & "" & rPage!sUser & "" & rPageDef!dDate & "" & rPageDef!sUser & "" & GetLink(rPageDef!sPath,, TRUE, "arrow") & "
    \n" RETURN sRes END PRIVATE FUNCTION GetSymbolLink(hSym AS CSymbolInfo, OPTIONAL sMyTitle AS String) AS String DIM sRes AS String DIM sComp AS String IF $cCompRedirect THEN sComp = $cCompRedirect[hSym.Component] IF NOT sComp THEN sComp = hSym.Component IF hSym.IsStatic() THEN sRes = sRes & "" sRes = sRes & GetLink("/comp" &/ LCase(sComp &/ hSym.Class &/ Replace(hSym.Name, ":", ".")), sMyTitle,, "none") IF hSym.IsStatic() THEN sRes = sRes & "" RETURN sRes END PRIVATE FUNCTION GetSymbolType(hComp AS CComponent, hClass AS CClassInfo, aSym AS String[]) AS String DIM sRes AS String DIM hSym AS CSymbolInfo DIM sName AS String IF aSym.Count = 0 THEN RETURN sRes = sRes & "\n" FOR EACH sName IN aSym hSym = hClass.Symbols[sName] IF System.RightToLeft THEN sRes &= "  " & GetSymbolLink(hSym) ELSE sRes &= GetSymbolLink(hSym) & "  " ENDIF NEXT sRes = sRes & " \n" RETURN sRes END PRIVATE FUNCTION GetSymbols() AS String DIM sSymbol AS String DIM sRes AS String DIM iInd AS Integer DIM iPos AS Integer DIM cSymbol AS NEW Collection DIM hSym AS CSymbolInfo DIM bSymbol AS Boolean DIM bDynamic AS Boolean DIM sBreak AS String DIM bStatic AS Boolean DIM sSpace AS String IF NOT $hClass THEN RETURN "

    No symbols." IF $hClass.Symbols.Count THEN cSymbol["P"] = NEW String[] cSymbol["C"] = NEW String[] cSymbol["M"] = NEW String[] cSymbol["p"] = NEW String[] cSymbol["e"] = NEW String[] cSymbol["m"] = NEW String[] FOR EACH hSym IN $hClass.Symbols IF hSym.IsHidden() THEN CONTINUE IF Right$(hSym.Name) = "$" THEN CONTINUE bSymbol = TRUE SELECT CASE hSym.Kind CASE "r", "p" cSymbol["p"].Add(hSym.Name) CASE "R", "P" cSymbol["P"].Add(hSym.Name) CASE "C" cSymbol["C"].Add(hSym.Name) CASE ":", "e", "E" hSym.Kind = "e" cSymbol["e"].Add(hSym.Name) CASE "m" cSymbol["m"].Add(hSym.Name) CASE "M" cSymbol["M"].Add(hSym.Name) DEFAULT PRINT hSym.Kind; " ?" END SELECT 'IF InStr("rpm", hSym.Kind) THEN bDynamic = TRUE IF hSym.IsStatic() THEN bStatic = TRUE ELSE bDynamic = TRUE ENDIF NEXT cSymbol["p"].Sort cSymbol["e"].Sort cSymbol["m"].Sort cSymbol["P"].Sort cSymbol["C"].Sort cSymbol["M"].Sort ENDIF sRes = "

    " & ("Symbols") & "
    \n" sRes &= "
    \n" sBreak = "
    \n" IF $hClass.Parent THEN 'PRINT #$hFile, "
    " IF $hClass.Parent = $hClass.Name THEN sRes = sRes & ("This class reimplements") ELSE sRes = sRes & ("This class inherits") ENDIF sRes = sRes & " " & GetLink("/comp" &/ $hClass.ParentComponent &/ $hClass.Parent,,, "arrow") IF $hClass.ParentComponent <> $hClass.Component THEN sRes = sRes & " " & ("in") & " " & GetLink("/comp" &/ $hClass.ParentComponent,,, "arrow") ENDIF sRes = sRes & ".
    \n" 'PRINT #$hFile, "
    " ENDIF IF $hClass.IsVirtual() THEN sRes = sRes & BULLET & Subst(("This class is &1."), GetLink("/def/virtual")) & sBreak ELSE IF $hClass.AutoCreatable THEN sRes = sRes & BULLET & ("This class can be used like an object by creating an hidden instance on demand.") & sBreak ENDIF IF $hClass.Symbols.Exist("_new") AND $hClass.Creatable THEN sRes = sRes & BULLET & Subst(("This class is &1."), GetSymbolLink($hClass.Symbols["_new"], ("creatable"))) & sBreak ELSE IF NOT bDynamic THEN sRes = sRes & BULLET & ("This class is static.") & sBreak ELSE sRes = sRes & BULLET & ("This class is not creatable.") & sBreak ENDIF ENDIF IF $hClass.Symbols.Exist("_get") THEN IF $hClass.Symbols.Exist("_put") THEN sRes = sRes & BULLET & Subst(("This class acts like a &1 / &2 array."), GetSymbolLink($hClass.Symbols["_get"], ("read")), GetSymbolLink($hClass.Symbols["_put"], ("write"))) ELSE sRes = sRes & BULLET & Subst(("This class acts like a &1 array."), GetSymbolLink($hClass.Symbols["_get"], ("read-only"))) ENDIF sRes = sRes & sBreak ENDIF IF $hClass.Symbols.Exist("_next") THEN sRes = sRes & BULLET & Subst(("This class is &1 with the &2 keyword."), GetSymbolLink($hClass.Symbols["_next"], ("enumerable")), GetLink("/lang/foreach")) & sBreak ENDIF IF $hClass.Symbols.Exist("_call") THEN sRes = sRes & BULLET & Subst(("This class can be used as a &1."), GetSymbolLink($hClass.Symbols["_call"], ("function"))) & sBreak ENDIF IF bSymbol THEN sSpace = " " IF bStatic THEN sRes = sRes & "
    " sRes = sRes & "\n" sRes = sRes & "\n" IF cSymbol["P"].Count THEN sRes = sRes & "" & sSpace & "\n" IF cSymbol["M"].Count THEN sRes = sRes & "" & sSpace & "\n" 'IF cSymbol["E"].Count THEN sRes = sRes & "" & sSpace & "\n" IF cSymbol["C"].Count THEN sRes = sRes & "" & sSpace & "\n" sRes = sRes & "\n" sRes = sRes & "\n" sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["P"]) sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["M"]) 'sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["E"]) sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["C"]) sRes = sRes & "\n" sRes = sRes & "
    " & ("Static properties") & "" & ("Static methods") & "" & ("Events") & "" & ("Constants") & "
    \n" ENDIF IF bDynamic THEN sRes = sRes & "
    " sRes = sRes & "\n" sRes = sRes & "\n" IF cSymbol["p"].Count THEN sRes = sRes & "" & sSpace & "\n" IF cSymbol["m"].Count THEN sRes = sRes & "" & sSpace & "\n" IF cSymbol["e"].Count THEN sRes = sRes & "" & sSpace & "\n" 'IF cSymbol["C"].Count THEN sRes = sRes & "" & sSpace & "\n" sRes = sRes & "\n" sRes = sRes & "\n" sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["p"]) sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["m"]) sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["e"]) 'sRes = sRes & GetSymbolType($hComp, $hClass, cSymbol["C"]) sRes = sRes & "\n" sRes = sRes & "
    " & ("Properties") & "" & ("Methods") & "" & ("Events") & "" & ("Constants") & "
    \n" ENDIF ENDIF sRes = sRes & "

    \n" RETURN sRes CATCH RETURN "

    " & Error.Where & ": " & Error.Text & "
    \n" END PRIVATE FUNCTION GetSyntax() AS String IF $hSym THEN RETURN GetSymbolSyntax($hSym) END PRIVATE FUNCTION GetSymbolSyntax(hSym AS CSymbolInfo) AS String DIM sSyntax AS String DIM sName AS String DIM sValue AS String SELECT CASE hSym.Name CASE "_get" IF hSym.IsStatic() THEN sName = hSym.Class ELSE sName = GetClassVariableName(hSym.Class) sSyntax = sSyntax & Keyword("DIM") & " " & sName & " " & Keyword("AS") & " " & GetType(hSym.Class) & "\n" ENDIF sValue = GetClassVariableName(hSym.Type) sSyntax = sSyntax & Keyword("DIM") & " " & sValue & " " & Keyword("AS") & " " & GetType(hSym.Type) & "\n\n" sSyntax = sSyntax & sValue & " " & Keyword("=") & " " sSyntax = sSyntax & sName & " " & Keyword("[") & GetSignature(hSym.Signature) & Keyword("]") CASE "_put" hSym = CComponent.Classes[hSym.Component &/ hSym.Class].Symbols["_get"] IF hSym.IsStatic() THEN sName = hSym.Class ELSE sName = GetClassVariableName(hSym.Class) sSyntax = sSyntax & Keyword("DIM") & " " & sName & " " & Keyword("AS") & " " & GetType(hSym.Class) & "\n" ENDIF sValue = GetClassVariableName(hSym.Type) sSyntax = sSyntax & Keyword("DIM") & " " & sValue & " " & Keyword("AS") & " " & GetType(hSym.Type) & "\n\n" sSyntax = sSyntax & sName & " " & Keyword("[") & GetSignature(hSym.Signature) & Keyword("]") sSyntax = sSyntax & " " & Keyword("=") & " " & sValue CASE "_next" IF hSym.IsStatic() THEN sName = hSym.Class ELSE sName = GetClassVariableName(hSym.Class) sSyntax = sSyntax & Keyword("DIM") & " " & sName & " " & Keyword("AS") & " " & GetType(hSym.Class) & "\n" ENDIF IF hSym.Type THEN sValue = GetClassVariableName(hSym.Type) sSyntax = sSyntax & Keyword("DIM") & " " & sValue & " " & Keyword("AS") & " " & GetType(hSym.Type) & "\n\n" sSyntax = sSyntax & Keyword("FOR EACH") & " " & sValue & " " & Keyword("IN") & " " & sName & "\n" ELSE sSyntax = sSyntax & Keyword("FOR EACH") & " " & sName & "\n" ENDIF sSyntax = sSyntax & "  ...
    " & Keyword("NEXT") CASE "_new" sName = GetClassVariableName(hSym.Class) sSyntax = sSyntax & Keyword("DIM") & " " & sName & " " & Keyword("AS") & " " & GetType(hSym.Class) & "\n\n" sSyntax = sSyntax & sName & " " & Keyword("=") & " " & Keyword("NEW") & " " & GetType(hSym.Class) sSyntax = sSyntax & " " & Keyword("(") & GetSignature(hSym.Signature) & Keyword(")") CASE ELSE IF hSym.IsStatic() AND hSym.Kind <> "C" THEN sSyntax = Keyword("STATIC") & " " ENDIF SELECT CASE LCase(hSym.Kind) CASE "p" sSyntax = sSyntax & Keyword("PROPERTY") & " " CASE "r" sSyntax = sSyntax & Keyword("PROPERTY READ") & " " CASE "c" sSyntax = sSyntax & Keyword("CONST") & " " CASE ":" sSyntax = sSyntax & Keyword("EVENT") & " " CASE "m" IF hSym.Type THEN sSyntax = sSyntax & Keyword("FUNCTION") & " " ELSE sSyntax = sSyntax & Keyword("SUB") & " " ENDIF END SELECT IF hSym.Name = "_call" THEN sSyntax = sSyntax & "" & GetSymbolName(hSym.Class) & "" ELSE sSyntax = sSyntax & "" & GetSymbolName(hSym.Name) & "" ENDIF IF InStr(":m", LCase(hSym.Kind)) THEN sSyntax = sSyntax & " " & Keyword("(") & GetSignature(hSym.Signature) & Keyword(")") ENDIF IF hSym.Type THEN sSyntax = sSyntax & " " & Keyword("AS") & " " & GetType(hSym.Type) IF hSym.Kind = "C" THEN sSyntax = sSyntax & " " & Keyword("=") & " " SELECT CASE hSym.Type CASE "s" sSyntax = sSyntax & Keyword(Chr$(34)) & hSym.Value & Keyword(Chr$(34)) CASE ELSE sSyntax = sSyntax & hSym.Value END SELECT ENDIF END SELECT RETURN sSyntax END '$$$$$$$$$$$$$$$$$$$$$$$$ PRIVATE FUNCTION GetName(sKey AS String) AS String DIM sName AS String DIM sElt AS String FOR EACH sElt IN Split(sKey, ".") sElt = Replace(sElt, "[]", "Array") sName = sName & UCase(Left$(sElt)) & Mid$(sElt, 2) NEXT RETURN sName END PRIVATE FUNCTION GetOldData(sOld AS String) AS String DIM hFic AS File DIM sData AS String DIM sLig AS String IF Exist(sOld) THEN OPEN sOld FOR READ AS #hFic WHILE NOT Eof(hFic) LINE INPUT #hFic, sLig IF Left(LTrim(sLig)) = "%" THEN CONTINUE IF Trim(sLig) = "" THEN CONTINUE IF Trim(sLig) = "" THEN CONTINUE IF Left$(sLig, 4) = "