OpenXTalkPaul wrote: ↑Thu Dec 07, 2023 2:40 am
in my OXT builds the 'APIs' have been renamed in the DB changed from "LiveCode Script" to "Script" and "LiveCode Builder" to "Builder". IIRC , I had to change some of the HTML/JS in the
html template file that's is used to build the dictionary pages, and the 'guides' don't use that template which is probably why they showed up fine while the dictionary didn't. I believe I also had to edit the 'tabs' (it's a widget), which is a card-level control, not part of the dictionary browser widget content. I probably also edited the file revDocsParser (may not be the actual name of that IDE library stack).
Do you have a list of all the edits written down somewhere, so I can apply this to OXT Lite?
OpenXTalkPaul wrote: ↑Thu Dec 07, 2023 2:40 am
LC CE 9.6.3 only shows those two items in that menu (which is kinda lame).
I'll keep 'all guides' rendering as it does. However, with the dictionary: since I've always had to have workarounds (like opening the dictionary in an external browser), I'll use one of these working stacks that is capable of reading the dictionary directly, and capable of displaying it as a normal stack. I'll just redesign it to look closer to the original layout.
regarding delay: not so much of an issue - with it having to open the dictionary each time in an external browser, there's already a delay in showing the dictionary. On Windows and Mac, I found there was always a delay of a few seconds when loading in the dictionary each time I clicked the dictionary button on the revMenubar anyway (not surprising when it's got to do all the checks pasted below!)
I tested this 'tiny dictionary' approach on an old Mac Mini (barely powerful enough to run 10.9), so just scrapes through running OXT Lite. I consider this the lowest spec machine (but handy for seeing what the user experiences is like on low-end-hardware). There was only a perceptable delay of perhaps 0.5 seconds from clicking the button in the toolbar, to having it display. So, perfectly acceptable for the trade off in reliability.
I'll work on redesigning this stack, and go with this approach as it seems less delicate (fragile / prone to breaking than the one I've been having all those issues with). The problem with the original dictionary stack is the insistence on running as browser objects inside the stack. Not too bad for Windows and Mac, but I'm trying to get something reliable that always works identically between all 3 platforms - so I'll not be using anything that makes use of a browser 'widget' / object (whatever it is).
I'll use something that keeps it as a stack.
Normally, I'm quite open to discussion on changes, but the way I'm feeling about this dictionary method - It's going to get changed. End of.
The more I look at this original dictionary script, the more I consider the current method of showing the dictionary a mess:
Code: Select all
##################################################
#
# IDE DOCS FUNCTIONS
#
##################################################
private function escape pString, pConvertLineEndings
replace "\" with "\\" in pString
replace quote with ("\" & quote) in pString
if pConvertLineEndings is true then
replace CRLF with "\n" in pString
replace numToCodepoint(13) with "\n" in pString
end if
replace LF with "\n" in pString
replace numToCodepoint(13) with "\r" in pString
//replace "<" with "<" in pString
//replace ">" with ">" in pString
replace tab with "\t" in pString
return (quote & pString & quote)
end escape
private function __getLCBSourceFile pFolder
revIDEPushDefaultFolder pFolder
# Isolate the source file
local tSource
put the files into tSource
filter tSource with "*.lcb"
revIDEPopDefaultFolder
return tSource
end __getLCBSourceFile
private function revIDEGetBaseDocsData pWhich
local tData
local tAPIPath, tLibs
put revIDESpecialFolderPath("api", pWhich) into tAPIPath
put files(tAPIPath) into tLibs
filter tLibs with "*.js"
local tDoc
repeat for each line tLibraryJS in tLibs
put revIDEUTF8FileContents(tAPIPath & slash & tLibraryJS) into tDoc
if tData is empty then
put tDoc into tData
else
put comma & tDoc after tData
end if
end repeat
return tData
end revIDEGetBaseDocsData
private function revIDEGetExtensionDocsData pAPI
local tExtensionDocsDataA
put revIDEExtensionDocsData(pAPI) into tExtensionDocsDataA
local tFolder, tCachedDataFolder
set the itemdelimiter to slash
local tData
repeat for each element tExtensionData in tExtensionDocsDataA
local tExtensionAPI
put tExtensionData["folder"] into tFolder
local tSource
put tExtensionData["source_file"] into tSource
# Check if the lcdoc file is out of date
put revEnvironmentUserDocsPath() & slash & tExtensionData["name"] into tCachedDataFolder
revIDEEnsurePath tCachedDataFolder
local tInputs
put empty into tInputs
if tSource is not empty then
put tFolder & slash & tSource into tInputs[1]
end if
# If we are running from source, also add the docs parser as an input
# dependency of the docs files
if not revEnvironmentIsInstalled() then
put the effective filename of stack "revDocsParser" into \
tInputs[the number of elements in tInputs + 1]
end if
local tNeedUpdate, tError, tAPIDoc
put tCachedDataFolder & slash & "api.lcdoc" into tAPIDoc
put revIDEIsFilesetStale(tInputs, tAPIDoc, false, tError) \
into tNeedUpdate
# If there is an up-to-date api.lcdoc in the source folder, just copy that across
local tSourceAPI
put tFolder & slash & "api.lcdoc" into tSourceAPI
if there is a file tSourceAPI then
if tSource is empty then
put false into tNeedUpdate
if there is no file tAPIDoc then
revIDESetUTF8FileContents tAPIDoc, revIDEUTF8FileContents(tSourceAPI)
end if
else if tNeedUpdate then
if revIDEIsFilesetStale(tInputs, tSourceAPI, false, tError) \
is false then
revIDESetUTF8FileContents tAPIDoc, revIDEUTF8FileContents(tSourceAPI)
put false into tNeedUpdate
end if
end if
end if
# Regenerate the lcdoc file if required
if tNeedUpdate is true then
# Generate the docs text in lcdoc format
local tDoc
if tExtensionData["source_type"] is "lcb" then
dispatch function "revDocsGenerateDocsFileFromModularFile" to stack "revDocsParser" with \
tFolder & slash & tSource
put the result into tDoc
else if tExtensionData["source_type"] is "lcs" then
local tStack, tPassword
try
put the long id of stack (tFolder & slash & tSource) into tStack
put the password of tStack into tPassword
end try
if tStack is not empty and tPassword is empty then
dispatch function "revDocsGenerateDocsFileFromText" \
to stack "revDocsParser" with \
the script of tStack, tStack
put the result into tDoc
end if
end if
if tDoc is not empty then
# Output the lcdoc file
revIDESetUTF8FileContents tAPIDoc, tDoc
end if
end if
local tAPIJS
put tCachedDataFolder & "/api.js" into tAPIJS
# Check if the .js is out of date
if tNeedUpdate is not true then
put tAPIDoc into tInputs[1]
put revIDEIsFilesetStale(tInputs, tAPIJS , false, tError) \
into tNeedUpdate
end if
if tNeedUpdate is false then
put revIDEUTF8FileContents(tAPIJS) into tExtensionAPI
else if tNeedUpdate is true then
local tLibraryArray, Lcdoc
dispatch function "revDocsParseDocFileToLibraryArray" to stack "revDocsParser" \
with tAPIDoc, tExtensionData["title"], \
tExtensionData["author"]
put the result into tLibraryArray
dispatch function "revDocsFormatLibraryDocArrayAsJSON" to stack "revDocsParser" \
with tLibraryArray
put the result into tExtensionAPI
# Update the dictionary database
ideDocsUpdateDatabase pAPI, tLibraryArray, false
revIDESetUTF8FileContents tAPIJS, tExtensionAPI
end if
if tExtensionAPI is not empty then
if tData is not empty then
put comma & tExtensionAPI after tData
else
put tExtensionAPI into tData
end if
end if
end repeat
return tData
end revIDEGetExtensionDocsData
private function revIDEGetDocsAPIData pWhich
local tData, tExtensions
put revIDEGetBaseDocsData(pWhich) into tData
put revIDEGetExtensionDocsData(pWhich) into tExtensions
if tExtensions is not empty then
put comma & tExtensions after tData
end if
return tData
end revIDEGetDocsAPIData
private function revIDEGetDocsGuideData
local tData
local tGuidePath
put revIDESpecialFolderPath("guide") into tGuidePath
put revIDEUTF8FileContents(tGuidePath & slash & "distributed_guide.js") into tData
local tExtensionDocsDataA
put revIDEExtensionDocsData() into tExtensionDocsDataA
local tFolder, tCachedDataFolder
set the itemdelimiter to slash
repeat for each element tExtensionData in tExtensionDocsDataA
local tExtensionGuide, tGuideFile
put empty into tExtensionGuide
put tExtensionData["folder"] into tFolder
put revEnvironmentUserDocsPath() & slash & \
tExtensionData["name"] into tCachedDataFolder
put tFolder & slash & "guide.md" into tGuideFile
if there is not a file tGuideFile then
-- User widgets have the guide.md in docs/guide/
put "/docs/guide" after tFolder
put tFolder & slash & "guide.md" into tGuideFile
end if
if there is not a file tGuideFile then next repeat
revIDEEnsurePath tCachedDataFolder
# Check if the .js is out of date
local tNeedUpdate, tError, tGuideJS
put tCachedDataFolder & "/guide.js" into tGuideJS
put revIDEIsFilesetStale(tGuideFile, tGuideJS, false, tError) \
into tNeedUpdate
if tNeedUpdate is false then
put revIDEUTF8FileContents(tGuideJS) into tExtensionGuide
else if tNeedUpdate is true then
local tGuide
put revIDEUTF8FileContents(tGuideFile) into tGuide
if tGuide is not empty then
put "{" & CR after tExtensionGuide
put tab & quote & "name" & quote & ":" && quote & tExtensionData["name"] & quote & comma & CR after tExtensionGuide
put tab & quote & "display name" & quote & ":" && quote & tExtensionData["title"] & quote & comma & CR after tExtensionGuide
put tab & quote & "group" & quote & ":" && quote & "Extensions" & quote & comma & CR after tExtensionGuide
put tab & quote & "location" & quote & ":" && quote & tFolder & quote & comma & CR after tExtensionGuide
put quote & "data" & quote & ":" & escape(tGuide, true) & CR after tExtensionGuide
put "}" after tExtensionGuide
revIDESetUTF8FileContents tGuideJS, tExtensionGuide
end if
else
-- FIXME There is some inconsistency in the guide's files that we
-- can't cope with
end if
if tExtensionGuide is not empty then
put comma & tExtensionGuide after tData
end if
end repeat
return tData
end revIDEGetDocsGuideData
on revIDERegenerateBuiltGuides
local tData
# Get the location of the distributed guide
local tGuidePath
put revIDESpecialFolderPath("guide") into tGuidePath
put "var tUserGuideData =" & CR & "{" & CR & tab & quote & "guides" & quote & ":[" into tData
put revIDEGetDocsGuideData() after tData
put CR & tab & "]" & CR & "}" after tData
local tDocsCache
put revIDESpecialFolderPath("documentation cache") into tDocsCache
revIDESetUTF8FileContents tDocsCache & slash & "built_guide.js", tData
end revIDERegenerateBuiltGuides
constant kAPIs = "LiveCode Script,livecode_script|LiveCode Builder,livecode_builder|LiveCode IDE,livecode_ide"
on revIDERegenerateBuiltAPIs
local tData, tAPIData
set the lineDelimiter to "|"
repeat for each line tAPI in kAPIs
-- For now, the IDE API is BFS only
if item 2 of tAPI is "livecode_ide" and revEnvironmentIsInstalled() then
next repeat
end if
put revIDEGetDocsAPIData(item 2 of tAPI) into tAPIData
dispatch function "revDocsCreateAPIJSON" to stack "revDocsParser" \
with item 1 of tAPI, item 2 of tAPI, "", tAPIData
if tData is empty then
put the result into tData
else
put comma & the result after tData
end if
end repeat
local tDictionaryData
put "var dictionary_data =" & return & "{" & return & \
tab & quote & "docs" & quote & ":[" & \
tData & return & tab & "]" & return & "}" \
into tDictionaryData
local tDocsCache
put revIDESpecialFolderPath("documentation cache") into tDocsCache
revIDESetUTF8FileContents tDocsCache & slash & "built_api.js", tDictionaryData
end revIDERegenerateBuiltAPIs
on revIDERegenerateBuiltDictionaryData
revIDERegenerateBuiltAPIs
revIDERegenerateBuiltGuides
end revIDERegenerateBuiltDictionaryData
on revIDEGenerateDistributedDocs
start using stack (revEnvironmentRepositoryPath() & slash & "ide-support" & slash & "revdocsparser.livecodescript")
revIDEGenerateDistributedGuide
revIDEGenerateDistributedAPI
revIDERegenerateBuiltDictionaryData
end revIDEGenerateDistributedDocs
private on revIDEGenerateDistributedGuide
# Set the default folder to where the guide markdown files are stored in the IDE
local tGuideFoldersWithLocationA
put revIDESpecialFolderPath("ide guides") into tGuideFoldersWithLocationA[1]["folder"]
put "ide" into tGuideFoldersWithLocationA[1]["location"]
if not revEnvironmentIsInstalled() then
put revIDESpecialFolderPath("repo guides") into tGuideFoldersWithLocationA[2]["folder"]
put "repo" into tGuideFoldersWithLocationA[2]["location"]
end if
local tGuideJSONFile
put revIDESpecialFolderPath("guide") & slash & "distributed_guide.js" \
into tGuideJSONFile
# Check if the distributed guide is out of date
local tKey, tInputFiles, tNeedUpdate, tError
repeat for each key tKey in tGuideFoldersWithLocationA
put tGuideFoldersWithLocationA[tKey]["folder"] into tInputFiles[tKey]
end repeat
put revIDEIsFilesetStale(tInputFiles, tGuideJSONFile, true, tError) \
into tNeedUpdate
# If we don't need to regenerate, exit
if tNeedUpdate is not true then
exit revIDEGenerateDistributedGuide
end if
local tOrderedGuidesA, tOrderFolder
put revIDESpecialFolderPath("ide guides") into tOrderFolder
put revDocsOrderedGuideData(tGuideFoldersWithLocationA, tOrderFolder) into tOrderedGuidesA
local tGuideData
repeat for each element tGuideA in tOrderedGuidesA
put tab & "{" after tGuideData
put return & revDocsFormatGuideDataAsJSON(tGuideA) after tGuideData
put return & tab & "}," after tGuideData
end repeat
delete the last char of tGuideData
# Write out to apropriate location
revIDESetUTF8FileContents tGuideJSONFile, tGuideData
end revIDEGenerateDistributedGuide
private command revIDEGenerateDistributedAPI
local tRepoPath
put revEnvironmentRepositoryPath() into tRepoPath
local tDocsFolder
put tRepoPath & slash & "docs" into tDocsFolder
if there is not a folder tDocsFolder then
answer "No dictionary data found at" && tDocsFolder
end if
# Check to see if we need to regenerate the script dictionary
local tNeedUpdate, tInputs, tError, tOutput
put the effective filename of stack "revDocsParser" into tInputs[0]
put tDocsFolder & slash & "dictionary" into tInputs[1]
put tDocsFolder & slash & "glossary" into tInputs[2]
put revIDESpecialFolderPath("api", "livecode_script") & slash & "script.js" into tOutput
put revIDEIsFilesetStale(tInputs, tOutput, true, tError) into tNeedUpdate
# Regenerate dictionary if necessary
if tNeedUpdate then
local tScriptA
put "LiveCode Script" into tScriptA["display name"]
put revDocsModifyForUrl(tScriptA["display name"]) into tScriptA["name"]
put "LiveCode" into tScriptA["author"]
put "dictionary" into tScriptA["type"]
# Parse the dictionary files into a structured array
put revDocsParseDictionaryToLibraryArray(tDocsFolder) into tScriptA["doc"]
# Update the database
ideDocsUpdateDatabase "livecode_script", tScriptA, true
local tJSON
put revDocsFormatLibraryDocArrayAsJSON(tScriptA) into tJSON
revIDESetUTF8FileContents revIDESpecialFolderPath("api", "livecode_script") & slash & "script.js", \
tJSON
end if
# Check to see if we need to regenerate the builder dictionary
local tModuleList
put revDocsGetBuiltinModuleList(revEnvironmentBinariesPath() & slash & "modules" & slash & "lci", tRepoPath) into tModuleList
set the itemdelimiter to slash
put empty into tInputs
put revIDESpecialFolderPath("api", "livecode_builder") & slash & "builder.js" into tOutput
put the effective filename of stack "revDocsParser" into tInputs[0]
local tCount
put 1 into tCount
repeat for each line tLine in tModuleList
put tLine into tInputs[tCount]
add 1 to tCount
end repeat
put revIDEIsFilesetStale(tInputs, tOutput, false, tError) into tNeedUpdate
# Regenerate dictionary if necessary
if tNeedUpdate then
local tModularA, tModularCount, tBlocksA, tParsedA
put 1 into tModularCount
set the itemdelimiter to "."
repeat for each line tLine in tModuleList
if item -1 of tLine is "lcdoc" then
get url("file:" & tLine)
else
get revDocsGenerateDocsFileFromModularFile(tLine)
end if
if it is not empty then
put it into tModularA[tModularCount]
add 1 to tModularCount
end if
end repeat
local tBuilderA
put 1 into tModularCount
repeat for each element tElement in tModularA
put revDocsParseDocText(tElement) into tParsedA
repeat for each key tEntry in tParsedA["doc"]
put tParsedA["doc"][tEntry] into tBuilderA["doc"][tModularCount]
add 1 to tModularCount
end repeat
put empty into tParsedA
end repeat
put "LiveCode Builder" into tBuilderA["display name"]
put revDocsModifyForUrl(tBuilderA["display name"]) into tBuilderA["name"]
put "LiveCode" into tBuilderA["author"]
put "dictionary" into tBuilderA["type"]
# Update the database
ideDocsUpdateDatabase "livecode_builder", tBuilderA, true
put revDocsFormatLibraryDocArrayAsJSON(tBuilderA) into tJSON
revIDESetUTF8FileContents revIDESpecialFolderPath("api", "livecode_builder") & slash & "builder.js", \
tJSON
end if
# Check to see if we need to regenerate the datagrid docs
put empty into tInputs
put revIDESpecialFolderPath("api", "livecode_script") & slash & "dg.js" into tOutput
put the effective filename of stack "revDocsParser" into tInputs[0]
local tDatagridDoc, tFolder
put revIDESpecialFolderPath("Documentation") &"/dictionary" into tFolder
put tFolder & slash & "datagrid.lcdoc" into tInputs[1]
put revIDEIsFilesetStale(tInputs, tOutput, false, tError) into tNeedUpdate
# Regenerate if necessary
if tNeedUpdate then
local tLibA
put revDocsParseDocFileToLibraryArray(tFolder & slash & "datagrid.lcdoc", "DataGrid", "LiveCode") into tLibA
# Update the database
ideDocsUpdateDatabase "livecode_script", tLibA, true
put revDocsFormatLibraryDocArrayAsJSON(tLibA) into tJSON
revIDESetUTF8FileContents revIDESpecialFolderPath("api", "livecode_script") & slash & "dg.js", \
tJSON
end if
local tIDELibsFolder, tIdeSupportFolder
put tRepoPath & "/ide-support" into tIdeSupportFolder
put tRepoPath & "/ide/Toolset/libraries" into tIDELibsFolder
# Check to see if we need to regenerate the ide dictionary
put empty into tInputs
put the effective filename of stack "revDocsParser" into tInputs[0]
put tIdeSupportFolder into tInputs[1]
put tIDELibsFolder into tInputs[2]
put revIDESpecialFolderPath("api", "livecode_ide") & slash & "ide.js" into tOutput
put revIDEIsFilesetStale(tInputs, tOutput, true, tError) into tNeedUpdate
# Regenerate dictionary if necessary
if tNeedUpdate then
local tIDELibs, tIDEA, tIDECount, tIDEParsedA
put 1 into tIDECount
put the stackfiles of stack "home" into tIDELibs
split tIDELibs by return and comma
repeat for each key tStackName in tIDELibs
local tStack, tPassword, tDoc
try
put the long id of stack tStackName into tStack
put the password of tStack into tPassword
end try
if tStack is not empty and tPassword is empty then
put revDocsGenerateDocsFileFromText(the script of tStack, \
tStack) into tDoc
end if
if tDoc is not empty then
put tDoc into tIDEA[tIDECount]
add 1 to tIDECount
end if
end repeat
local tIDELibraryA
put 1 into tIDECount
repeat for each element tElement in tIDEA
put revDocsParseDocText(tElement) into tIDEParsedA
repeat for each key tEntry in tIDEParsedA["doc"]
put tIDEParsedA["doc"][tEntry] into tIDELibraryA["doc"][tIDECount]
add 1 to tIDECount
end repeat
put empty into tIDEParsedA
end repeat
put "LiveCode IDE" into tIDELibraryA["display name"]
put revDocsModifyForUrl(tIDELibraryA["display name"]) into tIDELibraryA["name"]
put "LiveCode" into tIDELibraryA["author"]
put "dictionary" into tIDELibraryA["type"]
# Update the database
ideDocsUpdateDatabase "livecode_ide", tIDELibraryA, true
put revDocsFormatLibraryDocArrayAsJSON(tIDELibraryA) into tJSON
revIDESetUTF8FileContents revIDESpecialFolderPath("api", "livecode_ide") & slash & "ide.js", \
tJSON
end if
local tExtractedDocsFolder
put revEnvironmentBinariesPath() & slash & "extracted_docs" into tExtractedDocsFolder
local tFiles
put files(tExtractedDocsFolder) into tFiles
filter tFiles with "*.lcdoc"
set the itemDelimiter to "."
local tFile
repeat for each line tFile in tFiles
# Check to see if we need to regenerate the docs
put empty into tInputs
put revIDESpecialFolderPath("api", "livecode_script") & slash & toLower(item 1 to -2 of tFile) & ".js" into tOutput
put the effective filename of stack "revDocsParser" into tInputs[0]
put tExtractedDocsFolder & slash & tFile into tInputs[1]
put revIDEIsFilesetStale(tInputs, tOutput, false, tError) into tNeedUpdate
# Regenerate if necessary
if tNeedUpdate then
put revDocsParseDocFileToLibraryArray(tExtractedDocsFolder & slash & tFile, item -2 of tFile, "LiveCode") into tLibA
# Update the database
ideDocsUpdateDatabase "livecode_script", tLibA, true
put revDocsFormatLibraryDocArrayAsJSON(tLibA) into tJSON
revIDESetUTF8FileContents tOutput, tJSON
end if
end repeat
end revIDEGenerateDistributedAPI
on revIDEEnsureDictionaryUrl pWhich
local tInput, tOutput
put revIDEGetDictionaryHTMLTemplate(pWhich) into tInput
put revIDEGetDictionaryUrl(pWhich) into tOutput
local tNeedUpdate, tError
put revIDEIsFilesetStale(revIDEGetDictionaryHTMLTemplate(pWhich), \
revIDEGetDictionaryUrl(pWhich), false, tError) into tNeedUpdate
if tNeedUpdate is true then
revIDEGenerateDictionaryHTML pWhich
end if
end revIDEEnsureDictionaryUrl
function revIDEGetDictionaryUrl pWhich
return revEnvironmentUserDocsPath() & slash & pWhich & ".html"
end revIDEGetDictionaryUrl
function revIDEGetDictionaryHTMLTemplate pWhich
return revIDESpecialFolderPath("documentation") & slash & "html_viewer" & slash & pWhich & ".html.template"
end revIDEGetDictionaryHTMLTemplate
on revIDEGenerateDictionaryHTML pWhich, pInitialLibrary, pInitialEntryName, pInitialEntryType
local tGeneratedHTMLFile
put revIDEGetDictionaryUrl(pWhich) into tGeneratedHTMLFile
local tLibraryName, tEntryName, tEntryType
put pInitialLibrary into tLibraryName
put pInitialEntryName into tEntryName
put pInitialEntryType into tEntryType
local tDocsBase
put revIDESpecialFolderPath("documentation") & slash & "html_viewer" into tDocsBase
local tDocsCSSFolder, tDocsJSFolder, tDataPath
put tDocsBase & slash & "css" into tDocsCSSFolder
put tDocsBase & slash & "js" into tDocsJSFolder
put revIDESpecialFolderPath("documentation cache") & slash & "built_" & pWhich & ".js" into tDataPath
local tIDEGuidesFolder, tRepoGuidesFolder
put revIDESpecialFolderPath("ide guides") into tIDEGuidesFolder
put revIDESpecialFolderPath("repo guides") into tRepoGuidesFolder
local tTemplate
put revIDEUTF8FileContents(revIDEGetDictionaryHTMLTemplate(pWhich)) into tTemplate
put merge(tTemplate) into tTemplate
revIDESetUTF8FileContents tGeneratedHTMLFile, tTemplate
end revIDEGenerateDictionaryHTML