OXT Lite Moving Forward

A place to discuss and plan OpenSource xTalk (not exclusively LCC based)
and Community Builds of LCC ...Ask NOT what xTalk can do for you...
Get involved you DO have something to contribute, no matter your skillset!

Forum rules
A place to discuss and plan OpenSource xTalk (not exclusively LCC based) and Community Builds of LCC
Ask NOT what xTalk can do for you... get involved you DO have something to contribute, no matter your skillset!
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

A little further up the page, https://www.openxtalk.org/forum/viewtop ... 4902#p4902
I found a bug where the grid setting wasn't being remembered between launches. (Now I think of it, I think this is a longstanding bug in LC), but I've now fixed it.

I added an additional setting next to the grid size buttons in the preferences:
grid-setting.png
grid-setting.png (100.64 KiB) Viewed 9228 times
This now remembers the setting between launches. (all of this will be part of 0.96 when it's released sometime)
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

Here you go Richmond, - this is what I was going on about, but probably didn't explain it very well.
I've added your idea - You can now have custom alert icons in the Ask and Answer dialogs. You just need to have an image called 'appicon.png" in card 1 of your stack, and the Answer and Ask dialogs will now find it if it's there:

custom-alert-icons.png
custom-alert-icons.png (66.42 KiB) Viewed 9223 times
For standalones, it'll probably still use gRevAppIcon (What's set in standalone settings as the alert icon)
User avatar
richmond62
Posts: 2771
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: OXT Lite Moving Forward

Post by richmond62 »

That is totally well groovy! Wonderful.
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

tperry2x wrote: Sat Dec 02, 2023 2:59 pm Here you go Richmond, - this is what I was going on about, but probably didn't explain it very well.
I've added your idea - You can now have custom alert icons in the Ask and Answer dialogs. You just need to have an image called 'appicon.png" in card 1 of your stack, and the Answer and Ask dialogs will now find it if it's there:


custom-alert-icons.png

---- SNIP ---

otherwise, use the gRevAppIcon from the standalone / IDE.
I like this idea as well...to hell with Apple's UI guidelines, xTalk script should have maximum control over the look of dialogs at all times. Although, I had thought that it was already the case that if you set the image in the global variable gRevAppIcon ( (image ID number) from a script like:

Code: Select all

on preOpenStack
 global gRevAppIcon
 put "123457" into gRevAppIcon --- replace 123457 with the image ID number of an image in stack file in memory.
end preOpenStack
...from then on the the icons specified would be anywhere the default ones are normally used.
Is that not the case?
Is it only used in the Answer/Ask dialogs? I'm not sure if the Standalone Builder use whatever number is in gRevAppIcon by default (and can't check right now)

Either way I think it's a really cool idea to have default App Icon(s) (there are 2 Normal/Small ) be an IDE user customizable preference. And we could change the behavior or the Standalone Builder if SB doesn't currently use gRevAppIcon/gRevSmallAppIcon as a default (like if it's hardcoded as a number instead). We could take that even further and have it be loadable from a file in the users OpenXTalk directory and load them at IDE startup. Then you can set it to your own default icon and forget about it, if you wanted most/all of your app builds to have your same custom icons. The files would be in subfolder: ~/OpenXTalk/AppIcons/AppIcon.png ""/AppSmallIcon.png and then be auto-imported into a in-memory "AppIcons" Stack and auto-loaded into gRevAppIcon and gRevSmallAppIcon from that....
But there's a few ways one could go with it...

Nice work fixing Grid Size not saving bug, I'm glad you made start-up-initializing that be optional, because I think some may not want layout tools like grid spacing or 'smart guides' to be remembered between launches.
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

OpenXTalkPaul wrote: Mon Dec 04, 2023 9:57 pm ...I'm glad you made that be optional, because I think some may not want layout tools like grid spacing or 'smart guides' to be remembered between launches.
I know what you mean. I think I've inadvertently ruffled a few feathers in the past with changes (even though I never meant to). My future aim is to have everything newly added to be a preference toggle (where at all possible).
User avatar
richmond62
Posts: 2771
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: OXT Lite Moving Forward

Post by richmond62 »

Just bear in mind that you won't keep everybody happy however hard you try, and you are already doing such a lot my response to anyone who complains would be, "You do it then!"
https://richmondmathewson.owlstown.net/
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

:lol:
It had crossed my mind a couple of times, as I'm sure it does Paul's too.
However, I do try and keep a lid on my default response when I receive 'constructive criticism'. Unfortunately it's not possible to please everyone, so having the IDE set up in a way people can pick-and-choose may nullify some of those responses.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

tperry2x wrote: Tue Dec 05, 2023 7:18 am :lol:
It had crossed my mind a couple of times, as I'm sure it does Paul's too.
However, I do try and keep a lid on my default response when I receive 'constructive criticism'. Unfortunately it's not possible to please everyone, so having the IDE set up in a way people can pick-and-choose may nullify some of those responses.
My default response to 'You should do..." is sarcasm, it runs in my family, sorry if that offends anyone.

But THIS IS what really is great about FOSS and user modifiable software, isn't it?
I agree that we should make as much of the IDE be as user customizable as possible. That way you peoples that need to deal with the youngsters can easily make it into a slimmed down student/teacher editions, preloaded with tutorials and quiz-makers tool stacks or whatever, and I can have my total noise maker edition (or 'Beep-Bop-Boop' edition, as my wife calls it when she teases me about coding for sound/music stuff) with MIDI, USB Joystick support, etc. etc. built in, and then everybody will be happy! Right? :lol:
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

In theory, yes - I certainly don't have an issue with either approach.
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

OpenXTalkPaul wrote: Tue Dec 05, 2023 11:54 pm But THIS IS what really is great about FOSS and user modifiable software, isn't it?
Actually, kind of related this... I'm a bit stuck.
Okay, very stuck.

I'm trying to get the user guides to appear properly, so I began by testing it on a Mac (OXT Lite 0.95). I wonder? has it been broken all this time - I couldn't get anything to appear. It didn't give me a window, an error.... nothing.

I have "open dictionary in external browser" turned off, so it should be generating by the api method.

So I clicked the dictionary... that rendered, but:
Screenshot 2023-12-06 at 20.42.29.png
Screenshot 2023-12-06 at 20.42.29.png (582.98 KiB) Viewed 9068 times
I have a feeling this is wrong, as the api only gives me Livecode and Livecode builder.
So, I thought I'd click the User Guide tab, and see what that loads:

Screenshot 2023-12-06 at 20.42.51.png
Screenshot 2023-12-06 at 20.42.51.png (596.97 KiB) Viewed 9068 times
It loads, but again is only Livecode.

So, quit OXT Lite 0.95 and went to "show package contents" in your RC4, and copied the entire documentation folder (api and all) from the RC4 into the OXT Lite 0.95 one.
Opened it back up, and went to dictionary:
Screenshot 2023-12-06 at 17.53.11.png
Screenshot 2023-12-06 at 17.53.11.png (523.93 KiB) Viewed 9068 times
Now I get nothing here.
Clicked on the Guides tab:
Screenshot 2023-12-06 at 17.53.43.png
Screenshot 2023-12-06 at 17.53.43.png (593 KiB) Viewed 9068 times
The guides display correctly and seem to be using the right api that relates to OXT.

I'm now at a point where I absolutely cannot get the dictionary to generate via the api method.
What files do I need to copy from the RC4 version to the OXT Lite 0.95 version to be able to make this work?
Screenshot 2023-12-06 at 21.28.10.png
Screenshot 2023-12-06 at 21.28.10.png (766.41 KiB) Viewed 9068 times
I'm getting into a right old muddle with this.
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

Is there a better way of getting this to work? If I can't get it to work, I'm on the verge of substituting the normal dictionary with the one called "OpenXTalk Dictionary.oxtstack" that I found inside your RC4 build.
Screenshot 2023-12-06 at 21.58.43.png
Screenshot 2023-12-06 at 21.58.43.png (205.71 KiB) Viewed 9069 times
This is currently holding me up getting any further though.

Edit: There's quite a few interesting attempts at a (replacement?) dictionary inside that RC4 version.
I've currently changed the dictionary button to use this one as it works better. I may well do some visual tidying up of it though, but it'll work as a replacement I think.
Screenshot 2023-12-06 at 22.40.30.png
Screenshot 2023-12-06 at 22.40.30.png (159.52 KiB) Viewed 9057 times
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

That last one is based on Bernd's 'Tiny Dictionary' IIRC. The problem with that one is it rebuilds a sqlite db for all the extensions too, every time it launches, which makes for a long delay opening.
Elsewhere in the repo there may be slightly newer versions of that other one, which was based on 'Fast Dictionary" posted by that Italian dude from http://livecodeitalia.blogspot.com

However, I think I know what's going on here...
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).

It's like I've said, the IDE is a bit of 'Spaghetti" code, and it's fragile, if you change one little thing, it can break something somewhere else, even seemingly unrelated things.

You are correct that the other 'API's like DataGrid do not show up in that popup menu, for some reason (may have been intentional?), I believe this was result of changes after version 8, not sure exactly when, but I am sure that LC CE 9.6.3 only shows those two items in that menu (which is kinda lame).
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

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 "&lt;" in pString
   //replace ">" with "&gt;" 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
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

This works.
I've set it to load a modified "tiny_dictionary". In doing so;
  • it keeps it as a stack(so no bizarre browser object / widget behaviour).
  • it remains dynamically generated
  • it uses the up-to-date api found in your RCx versions
  • It will work the same across all 3 platforms
It still loads the "all guides" fine (automatically passes to a browser on Linux), but should be in a new window with a browser 'widget'(?) on MacOS / Windows).

I'll worry about the appearance of it after I release 0.96, as it'll take me a while to fine-tune the 'tiny dictionary' to get it looking on-par and more modern. That will be happening though, (my apologies for this change as it may not be popular), but I will continue to tweak it.

Screenshot at 2023-12-07 14-06-43.png
Screenshot at 2023-12-07 14-06-43.png (197.55 KiB) Viewed 8956 times
Screenshot 2023-12-07 at 14.37.54.png
Screenshot 2023-12-07 at 14.37.54.png (534.16 KiB) Viewed 8951 times
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

tperry2x wrote: Thu Dec 07, 2023 2:21 pm This works.
I've set it to load a modified "tiny_dictionary". In doing so;
  • it keeps it as a stack(so no bizarre browser object / widget behaviour).
  • it remains dynamically generated
  • it uses the up-to-date api found in your RCx versions
  • It will work the same across all 3 platforms
It still loads the "all guides" fine (automatically passes to a browser on Linux), but should be in a new window with a browser 'widget'(?) on MacOS / Windows).

I'll worry about the appearance of it after I release 0.96, as it'll take me a while to fine-tune the 'tiny dictionary' to get it looking on-par and more modern. That will be happening though, (my apologies for this change as it may not be popular), but I will continue to tweak it.


Screenshot at 2023-12-07 14-06-43.png
Screenshot 2023-12-07 at 14.37.54.png
Nice!
I agree (which is why those stacks were in the repo). It looks OK as web pages and I'd much rather have a Linux Browser Widget that worked on all Linux distros, but l think that the Dictionary Stack did become overly complicated when they changed it to be SQL DB + HTML + JS + xTalk, converting and caching and all of that. I also liked how the old Dictionary was somewhat community extensible (not sure how we could do that).

I think the issue with the 'Tiny Dictionary' version rebuilding the DB for extensions could be ironed out, perhaps the IDE changed set to rebuild the 'extensions' db only when it needs to update (upon installing a new extension), I just haven't had the time or inclination to work on that part of it lately.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

tperry2x wrote: Thu Dec 07, 2023 6:44 am
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?
Not really, I mean I do have some record of all the changes in the form of GitHub push logs, but I'd have to go searching through that to find the exact changes, and I probably made those changes two years ago.
I will if you want me to, but it seems kind of pointless if you're set on working up a non-HTML version.
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

OpenXTalkPaul wrote: Fri Dec 08, 2023 12:39 am ...finding the exact changes, I probably made those changes two years ago.
I will if you want me to, but it seems kind of pointless if you're set on working up a non-HTML version.
You are absolutely right. Not to worry on that front, I'm focusing on making non-web versions. Working my way through the 'All Guides' section at the moment. I didn't realise just how much information is in there, but this too will be a stack eventuallu.

With the dictionary, I only picked the tiny dictionary as it seemed the most complete. It's a bit of a pain to unpick (and I've somehow managed to corrupt a copy of it more than once).
Just trying to simplify it all down is proving a headache, but I'm sure I'll get there.
It's all in aid of unpicking parts of the IDE, so that it's not so easy to break something so easily in future. That's what's taking my time at the moment, but rest assured, I am actively working on quite a bit of changes for 0.96 when I feel it's ready for feedback and a release.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: OXT Lite Moving Forward

Post by OpenXTalkPaul »

tperry2x wrote: Fri Dec 08, 2023 8:51 pm I'm focusing on making non-web versions. Working my way through the 'All Guides' section at the moment. I didn't realise just how much information is in there, but this too will be a stack eventuallu.
For the 'guides' it might be best to work up some sort of functional converter from .md (GitHub style markdown) to grouped flds Text + Images/objects, if you want to support dynamic loading of guides that is. Like when loading a new Extension Module which may contain its own guide that gets added to the Dictionary Guides tab 'on-the-fly'.
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: OXT Lite Moving Forward

Post by tperry2x »

I had considered using some kind of conversion process, but I spotted the guides are full of inaccuracies which needed correcting anyway *(more on this further down), so thought it would be best to use the source material of the generated 'all guides' and correct it as I go.

I do have some rationale for doing it this way. (but let me get a few things out of the way first).
* none of the following is meant in an abrasive / obtuse way
* no offence meant to whoever has produced the previous 'all guides' - they obviously put a lot of work in
* my opinions are just that, my opinions. People may agree or disagree, and that's fine. No offence taken.

Right, with all that out of the way
(why do my posts need a disclaimer: I wish people wouldn't read offence into it. Perhaps it is my writing style, but that's not how I intend it. If I have a problem with something that someone writes, I'll tell you! :lol: )

Anyway, back on topic: first thing to mention is that this will be an 'experimental feature' that people can turn on if they see fit. If this is off, it'll continue to use the traditional 'all guides' api version (if it works for you = if you are on mac or windows).
Screenshot at 2023-12-10 15-19-08.png
Screenshot at 2023-12-10 15-19-08.png (5.31 KiB) Viewed 868 times
I'm very much mirroring the layout of the 'all guides' web interface anyway, although with a few differences.
Screenshot at 2023-12-10 15-20-06.png
Screenshot at 2023-12-10 15-20-06.png (154.24 KiB) Viewed 868 times
I should also mention that the colour scheme is not hard-coded in dark mode. It just shows that way as that's what my system theme is on Linux. In light mode on Linux, or on the mac and windows - it looks very much the same as the 'All Guides' web version
Screenshot at 2023-12-10 15-21-23.png
Screenshot at 2023-12-10 15-21-23.png (304.31 KiB) Viewed 868 times
Screenshot at 2023-12-10 15-22-20.png
Screenshot at 2023-12-10 15-22-20.png (210.29 KiB) Viewed 868 times
So why do it then? I'll get onto that in a moment. Aside from some bits being out of date (Windows bits still reference windows XP as the target system, and the Windows interface guidelines point to somewhere that no longer exists), how does anyone realistically edit this api version of the 'all guides'?
Yes - you can mess about with it in a something like libreoffice, or (database editor app of your own preference), but it's not as easy as editing a stack. With my version, it also has a built in editor:
Screenshot at 2023-12-10 15-24-00.png
Screenshot at 2023-12-10 15-24-00.png (141.88 KiB) Viewed 868 times
Making a new entry is just as simple as making a new card, giving it a name and begin editing. The navigation pane is shared and automatically updates across all cards. There is no database to edit or worry about.
This is to put the ability of editing this type of guides back in the hands of the entire OpenXTalk community:
Screenshot at 2023-12-10 15-24-41.png
Screenshot at 2023-12-10 15-24-41.png (23.75 KiB) Viewed 868 times
* innacuracies.
This is my main reason for doing this. I've spotted a lot of typos, spelling mistakes and information that is incorrect:
Screenshot at 2023-12-10 15-28-29.png
Screenshot at 2023-12-10 15-28-29.png (233.82 KiB) Viewed 868 times
Example: the information for cascading menus does not work in the 'All Guides' api version, needed correcting to my version on the left.

Apart from updating links, I also think several items would be better divided into their own sub-section, as half the information is buried deep, not easily navigatable. In my version, this will be easier to find from the left-hand menu.

Yeah - but your colours suck.
I kind of thought of that (I hope). Imagine this in light mode, that's the default for Mac and Windows.
The purple colour on the left is whatever your tooltip colour is set in the main preferences window. Likewise, at the end of each section, there's a next and previous nav link. This link uses whatever the 'Documentation Color' swatch is set to in the main preferences window too. My aim is to have nothing hard-coded so that anyone can adjust anything.

I should also mention, the title for these guides shown at the top left - that's not hard coded either. So if you change the name of your OXT fork, it gets this from whatever the title of the main revMenubar stack is.
Likewise, the icon is fetched from revGeneralIcons, so if you change it there in your fork, this will also update.

edit: added screenshot of it in light mode.
Screenshot at 2023-12-10 16-49-47.png
Screenshot at 2023-12-10 16-49-47.png (173.83 KiB) Viewed 854 times
User avatar
richmond62
Posts: 2771
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: OXT Lite Moving Forward

Post by richmond62 »

none of the following is meant in an abrasive / obtuse way
Ha, Ha, Ha . . . that did me a lot of good on a gloomy December day. 8-)
why do my posts need a disclaimer: I wish people wouldn't read offence into it.
Probably because, nowadays, people are extremely prickly about everything that might, possibly, stretched to the ultra, cause offence.
-
fence.jpg
fence.jpg (9.51 KiB) Viewed 923 times
-
Let's cause a fence together. :D
-
I've spotted a lot of typos, spelling mistakes and information that is incorrect
All too quick and too careless: I always feel that the documentation was doled out to some 'junior pip' in Edinburgh, while the "hairy-chested ones" (who, quite obviously felt that documentation was below them) got on with building Jerusalem.
Windows bits still reference windows XP as the target system
LC 10 DP-6 references Ubuntu 16.something as the Linux target system, so we should not be surprised really.
but your colours suck.
Well, I don't particularly "go for" your colours either, but to be fair (rare with me), as you are doing 98% of the work, and I am just making the odd snarky comment, it does NOT really "do" for me, or any of the other armchair critics, to criticise your choice of colours.

If you sort out the documentation and deliver it in flashing neon, whether we like flashing neon or not, we'll already be significantly in advance of the 'mess of pottage' we inherited, so we will have no right whatsoever to write stuff like "your colours suck".

And 'that' yellow-on-black has the big benefit of being able to read without funny filters on ones glasses:
-
Screenshot 2023-12-10 at 18.48.29.png
Screenshot 2023-12-10 at 18.48.29.png (54.09 KiB) Viewed 920 times
-
and it is a bloody sight better than this, which burns into one's skull and helps one develop cluster headaches after a longish programming session:
-
Screenshot 2023-12-10 at 19.00.11.png
Screenshot 2023-12-10 at 19.00.11.png (70.46 KiB) Viewed 917 times
https://richmondmathewson.owlstown.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 9 guests