Parcourir la source

Merge branch 'main' into autoreload

Martijn Laan il y a 1 semaine
Parent
commit
f819e60ce7

+ 2 - 2
ISHelp/ISHelpGen/ISHelpGen.dpr

@@ -15,7 +15,7 @@ uses
   PathFunc in '..\..\Components\PathFunc.pas';
 
 const
-  Version = '1.18';
+  Version = '1.19';
 
   XMLFileVersion = '1';
 
@@ -398,7 +398,7 @@ begin
           if Pos('ms-its:', S) = 1 then
             Result := Result + Format('<a href="%s">%s</a>', [S, ParseFormattedText(Node)])
           else
-            Result := Result + Format('<a href="%s" target="_blank" title="%s">%s</a><img src="images/extlink.svg" alt=" [external link]" />',
+            Result := Result + Format('<a href="%s" target="_blank" title="%s">%s</a><img src="images/extlink.png" srcset="images/extlink.svg" alt=" [external link]" />',
               [S, S, ParseFormattedText(Node)]);
         end;
       elHeading:

+ 0 - 1
ISHelp/Staging-dark/images/.gitignore

@@ -1 +0,0 @@
-extlink.svg

BIN
ISHelp/Staging-dark/images/extlink.png


+ 1 - 1
ISHelp/Staging-dark/styles.css

@@ -105,7 +105,7 @@ LI.compact {
 }
 
 TT, .examplebox {
-	background-color: #403E41;
+	background-color: #353135;
 	color: inherit;
 }
 TT {

+ 7 - 5
ISHelp/Staging/contents-template.htm

@@ -8,16 +8,18 @@
 </head>
 <body onload="init_contents(0);">
 
-<div id="tabbar">
-<a id="tab-contents" class="selectedtab" href="javascript:select_tab('contents');">Contents</a>
-<a id="tab-index" class="unselectedtab" href="javascript:select_tab('index');">Index</a>
+<div role="tablist" id="tabbar">
+<a role="tab" id="tab-contents" aria-selected="true" aria-controls="tabbody-contents"
+   href="javascript:select_tab('contents');">Contents</a>
+<a role="tab" id="tab-index" aria-selected="false" aria-controls="tabbody-index"
+   href="javascript:select_tab('index');">Index</a>
 </div>
 
-<div id="tabbody-contents">
+<div role="tabpanel" id="tabbody-contents" tabindex="0" aria-labelledby="tab-contents">
 %CONTENTSTABLES%
 </div>
 
-<div id="tabbody-index" style="display: none">
+<div role="tabpanel" id="tabbody-index" tabindex="0" aria-labelledby="tab-index" hidden="hidden">
 <div style="margin-top: 1em; text-align: center; color: GrayText">Loading...</div>
 </div>
 

+ 5 - 7
ISHelp/Staging/contents.css

@@ -14,7 +14,7 @@
 	--link-fg-color: light-dark(hsl(206, 100%, 37%), hsl(206, 100%, 50%));
 	--link-hover-fg-color: light-dark(hsl(206, 100%, 27%), hsl(206, 100%, 43%));
 	--header-bg-color: light-dark(#e0e0e0, #403e41);
-	--code-bg-color: light-dark(#f0f0f0, #403e41);
+	--code-bg-color: light-dark(#f0f0f0, #353135);
 	--selected-bg-color: var(--header-bg-color);
 }
 BODY {
@@ -36,26 +36,24 @@ INPUT {
 	padding-block-start: 8px;
 	padding-inline-start: 8px;
 	display: flex;
-	align-items: end;
 	overflow-x: hidden;
 
 	& > A {
 		/* Height of tabs should match topic heading */
 		line-height: calc((20rem/16) * 1.5 - 2px);
 		font-size: calc(14rem/16);
-		font-weight: bold;
 		color: inherit;
 		background-color: transparent;
 		text-decoration: none;
 		padding-inline: calc(10rem/16);
 		user-select: none;
 
-		&.selectedtab {
-			background-color: var(--main-bg-color);
-			border-block-start: 2px solid var(--link-fg-color);
+		&[aria-selected="true"] {
+			font-weight: 600;  /* semibold */
+			border-block-end: 2px solid var(--link-fg-color);
 			cursor: default;
 		}
-		&.unselectedtab:hover {
+		&:not([aria-selected="true"]):hover {
 			color: var(--link-fg-color);
 		}
 	}

+ 6 - 7
ISHelp/Staging/contents.js

@@ -206,18 +206,17 @@ function sync_contents()
 
 function select_tab(newTab)
 {
-	var tabs = ["contents", "index"];
+	const tabs = ["contents", "index"];
 
-	var i;
-	for (i = 0; i < tabs.length; i++) {
+	for (let i = 0; i < tabs.length; i++) {
 		if (tabs[i] != newTab) {
-			document.getElementById("tab-" + tabs[i]).className = "unselectedtab";
-			document.getElementById("tabbody-" + tabs[i]).style.display = "none";
+			document.getElementById("tab-" + tabs[i]).setAttribute("aria-selected", false);
+			document.getElementById("tabbody-" + tabs[i]).hidden = true;
 		}
 	}
 
-	document.getElementById("tab-" + newTab).className = "selectedtab";
-	document.getElementById("tabbody-" + newTab).style.display = "";
+	document.getElementById("tab-" + newTab).setAttribute("aria-selected", true);
+	document.getElementById("tabbody-" + newTab).hidden = false;
 
 	if (newTab == "index") init_index_tab();
 }

BIN
ISHelp/Staging/images/extlink.png


+ 1 - 1
ISHelp/Staging/styles.css

@@ -14,7 +14,7 @@
 	--link-fg-color: light-dark(hsl(206, 100%, 37%), hsl(206, 100%, 50%));
 	--link-hover-fg-color: light-dark(hsl(206, 100%, 27%), hsl(206, 100%, 43%));
 	--header-bg-color: light-dark(#e0e0e0, #403e41);
-	--code-bg-color: light-dark(#f0f0f0, #403e41);
+	--code-bg-color: light-dark(#f0f0f0, #353135);
 }
 HTML {
 	/* Ensure that anchor targets don't get hidden underneath the sticky header.

+ 7 - 10
ISHelp/isetup.xml

@@ -111,11 +111,9 @@
 <extlink href="https://jrsoftware.org/">Inno Setup home page</extlink>
 </p>
 
-<p><br/>
-Inno Setup is a <i>free</i> installer for Windows programs by Jordan Russell and Martijn Laan. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.</p>
+<p>Inno Setup is a <i>free</i> installer for Windows programs by Jordan Russell and Martijn Laan. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.</p>
 
-<p><br/>
-<b><i>Key features:</i></b></p>
+<p><b><i>Key features:</i></b></p>
 
 <ul>
 
@@ -166,8 +164,7 @@ Includes integrated support for "deflate", bzip2, and 7-Zip LZMA/LZMA2 file <lin
 
 </ul>
 
-<p><br/>
-<b><i>Is it really free of charge, even for commercial use?</i></b></p>
+<p><b><i>Is it really free of charge, even for commercial use?</i></b></p>
 
 <p>Yes, it may be used completely free of charge, even when deploying commercial applications.</p>
 
@@ -190,7 +187,7 @@ Includes integrated support for "deflate", bzip2, and 7-Zip LZMA/LZMA2 file <lin
 
 <p>To give you an idea of how this all works, start the Compiler IDE, click <i>File | Open</i>, and select one of the script files in the Examples subdirectory located under the Inno Setup directory. (It may be helpful to use the sample scripts as a template for your own scripts.)</p>
 
-<p><br/><b>See also:</b><br/>
+<p><b>See also:</b><br/>
 <link topic="scriptformatoverview">Script Format Overview</link>
 </p>
 
@@ -248,7 +245,7 @@ Source: "MyProg.exe"; DestDir: "{app}"
 
 <p>If an Unicode file is used, it must be UTF-8 encoded.</p>
 
-<p><br/><b>See also:</b><br/>
+<p><b>See also:</b><br/>
 <link topic="params">Parameters in Sections</link><br/>
 <link topic="consts">Constants</link><br/>
 <link topic="commonparams">Common Parameters</link><br/>
@@ -977,7 +974,7 @@ DefaultGroupName=My Program
 
 <p>By default, any leading or trailing whitespace in a directive's value will be stripped. It is possible to avoid this by surrounding the directive's value in double quotes (<tt>"</tt>).</p>
 
-<p><br/>The following directives can be placed in the <tt>[Setup]</tt> section:</p>
+<p>The following directives can be placed in the <tt>[Setup]</tt> section:</p>
 
 <p>(<b>bold</b> = required)</p>
 
@@ -3539,7 +3536,7 @@ Filename: "{win}\MYPROG.INI"; Section: "InstallSettings"; Key: "InstallPath"; St
   <td>Select tab</td><td>Ctrl+1 through Ctrl+9</td>
 </tr>
 <tr>
-  <td>Switch between the active memo and the active bottom pane</td><td>F6</td>
+  <td>Switch between the active memo, the active bottom pane, and the active banner</td><td>F6</td>
 </tr>
 </table>
 

+ 0 - 1
ISHelp/synch-darkfiles.bat

@@ -7,7 +7,6 @@ echo - Synching files from Staging to Staging-dark
 copy Staging\hh_project.hhp Staging-dark
 copy Staging\stoplist.stp Staging-dark
 copy Staging\topic.js Staging-dark
-copy Staging\images\extlink.svg Staging-dark\images\extlink.svg
 
 echo - Synching files done
 

+ 1 - 0
Projects/Res/SetupLdr.offsettable.rc

@@ -0,0 +1 @@
+11111 RCDATA SetupLdr.offsettable.txt

BIN
Projects/Res/SetupLdr.offsettable.res


+ 1 - 0
Projects/Res/SetupLdr.offsettable.txt

@@ -0,0 +1 @@
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

+ 1 - 1
Projects/SetupLdr.dpr

@@ -495,7 +495,7 @@ begin
 
         { Now execute Setup. Use the exit code it returns as our exit code. }
         ExecAndWait(TempFile, Format('/SL5="$%x,%d,%d,',
-          [SetupLdrWnd, OffsetTable.Offset0, OffsetTable.Offset1]) +
+          [UInt32(SetupLdrWnd), OffsetTable.Offset0, OffsetTable.Offset1]) +
           SelfFilename + '" ' + GetCmdTail, SetupLdrExitCode);
 
         { Synchronize our active language with Setup's, in case we need to

+ 6 - 7
Projects/Src/Compiler.SetupCompiler.pas

@@ -6867,10 +6867,9 @@ var
   WizardImages, WizardSmallImages: TObjectList<TCustomMemoryStream>;
   DecompressorDLL, SevenZipDLL: TMemoryStream;
 
-  SetupLdrOffsetTable: TSetupLdrOffsetTable;
-  SizeOfExe, SizeOfHeaders: Longint;
+  SizeOfExe, SizeOfHeaders: Int64;
 
-  function WriteSetup0(const F: TFile): Longint;
+  function WriteSetup0(const F: TFile): Int64;
 
     procedure WriteStream(Stream: TCustomMemoryStream; W: TCompressedBlockWriter);
     var
@@ -7000,7 +6999,7 @@ var
     Result := F.Position - StartPosition;
   end;
 
-  function CreateSetup0File: Longint;
+  function CreateSetup0File: Int64;
   var
     F: TFile;
   begin
@@ -7013,7 +7012,7 @@ var
     end;
   end;
 
-  function RoundToNearestClusterSize(const L: Longint): Longint;
+  function RoundToNearestClusterSize(const L: Int64): Int64;
   begin
     Result := (L div DiskClusterSize) * DiskClusterSize;
     if L mod DiskClusterSize <> 0 then
@@ -7021,7 +7020,7 @@ var
   end;
 
   procedure CompressFiles(const FirstDestFile: String;
-    const BytesToReserveOnFirstDisk: Longint);
+    const BytesToReserveOnFirstDisk: Int64);
   var
     CurrentTime: TSystemTime;
 
@@ -8316,7 +8315,7 @@ begin
 
             { Move the data from Setup.e?? into the Setup.exe, and write
               header data }
-            FillChar(SetupLdrOffsetTable, SizeOf(SetupLdrOffsetTable), 0);
+            var SetupLdrOffsetTable := Default(TSetupLdrOffsetTable);
             SetupLdrOffsetTable.ID := SetupLdrOffsetTableID;
             SetupLdrOffsetTable.Version := SetupLdrOffsetTableVersion;
             SetupLdrOffsetTable.Offset0 := ExeFile.Position;

+ 51 - 14
Projects/Src/IDE.MainForm.pas

@@ -84,7 +84,8 @@ type
     Msg, ConfigIdent: String;
     ConfigValue: Integer;
     Color: TColor;
-    constructor Create(const AMsg, AConfigIdent: String; const AConfigValue: Integer; const AColor: TColor);
+    HasLink: Boolean;
+    constructor Create(const AMsg, AConfigIdent: String; const AConfigValue: Integer; const AColor: TColor; const AHasLink: Boolean);
   end;
 
   TUpdatePanelMessages = TObjectList<TUpdatePanelMessage>;
@@ -722,12 +723,13 @@ const
 { TUpdatePanelMessage }
 
 constructor TUpdatePanelMessage.Create(const AMsg, AConfigIdent: String;
-  const AConfigValue: Integer; const AColor: TColor);
+  const AConfigValue: Integer; const AColor: TColor; const AHasLink: Boolean);
 begin
   Msg := AMsg;
   ConfigIdent := AConfigIdent;
   ConfigValue := AConfigValue;
   Color := AColor;
+  HasLink := AHasLink;
 end;
 
 { TMainFormPopupMenu }
@@ -822,11 +824,13 @@ end;
 constructor TMainForm.Create(AOwner: TComponent);
 
   procedure CheckUpdatePanelMessage(const Ini: TConfigIniFile; const ConfigIdent: String;
-    const ConfigValueDefault, ConfigValueMinimum: Integer; const Msg: String; const Color: TColor);
+    const ConfigValueDefault, ConfigValueMinimum: Integer; const Msg: String; const Color: TColor;
+    const HasLink: Boolean);
   begin
     var ConfigValue := Ini.ReadInteger('UpdatePanel', ConfigIdent, ConfigValueDefault);
     if ConfigValue < ConfigValueMinimum then
-      FUpdatePanelMessages.Add(TUpdatePanelMessage.Create(Msg, ConfigIdent, ConfigValueMinimum, Color));
+      FUpdatePanelMessages.Add(TUpdatePanelMessage.Create(Msg, ConfigIdent, ConfigValueMinimum, Color,
+        HasLink));
   end;
 
   procedure ReadConfig;
@@ -893,10 +897,10 @@ constructor TMainForm.Create(AOwner: TComponent);
       { UpdatePanel visibility }
       CheckUpdatePanelMessage(Ini, 'KnownVersion', 0, Integer(FCompilerVersion.BinVersion),
         'Your version of Inno Setup has been updated! <a id="hwhatsnew">See what''s new</a>.',
-        $ABE3AB); //MGreen with HSL lightness changed from 40% to 78%
+        $ABE3AB, True); //MGreen with HSL lightness changed from 40% to 78%
       CheckUpdatePanelMessage(Ini, 'VSCodeMemoKeyMap', 0, 1,
         'VS Code-style editor shortcuts added! Use the <a id="toptions-vscode">Editor Keys option</a> in Options dialog.',
-        $FFD399); //MBlue with HSL lightness changed from 42% to 80%
+        $FFD399, True); //MBlue with HSL lightness changed from 42% to 80%
       UpdateUpdatePanel;
 
       { Debug options }
@@ -1266,6 +1270,15 @@ end;
 
 procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
   Shift: TShiftState);
+
+  procedure AddControlToArray(const ControlToAdd: TWinControl; var Controls: TArray<TWinControl>;
+    var NControls: Integer);
+  begin
+    Inc(NControls);
+    SetLength(Controls, NControls);
+    Controls[NControls-1] := ControlToAdd;
+  end;
+
 begin
   var AShortCut := ShortCut(Key, Shift);
   if (AShortCut = VK_ESCAPE) and BStopCompile.Enabled then begin
@@ -1296,18 +1309,42 @@ begin
     if BCompile.Enabled then
       BCompileClick(Self);
   end else if (Key = VK_F6) and not (ssAlt in Shift) then begin
-    { Toggle focus between the active memo and the active bottom pane }
+    { Move focus between the active memo, the active bottom pane, and the active banner }
     Key := 0;
-    if ActiveControl <> FActiveMemo then
-      ActiveControl := FActiveMemo
-    else if StatusPanel.Visible then begin
+
+    { First get the list of controls to toggle between }
+    var Controls: TArray<TWinControl> := [FActiveMemo];
+    var NControls := Length(Controls);
+    if StatusPanel.Visible then begin
+      var ControlToAdd: TWinControl := nil;
       case OutputTabSet.TabIndex of
-        tiCompilerOutput: ActiveControl := CompilerOutputList;
-        tiDebugOutput: ActiveControl := DebugOutputList;
-        tiDebugCallStack: ActiveControl := DebugCallStackList;
-        tiFindResults: ActiveControl := FindResultsList;
+        tiCompilerOutput: ControlToAdd := CompilerOutputList;
+        tiDebugOutput: ControlToAdd := DebugOutputList;
+        tiDebugCallStack: ControlToAdd := DebugCallStackList;
+        tiFindResults: ControlToAdd := FindResultsList;
+      end;
+      if ControlToAdd <> nil then
+        AddControlToArray(ControlToAdd, Controls, NControls);
+    end;
+    if UpdatePanel.Visible and FUpdatePanelMessages[UpdateLinkLabel.Tag].HasLink then
+      AddControlToArray(UpdateLinkLabel, Controls, NControls);
+
+    { Now move focus to next }
+    if NControls > 1 then begin
+      for var I := 0 to NControls-1 do begin
+        if ActiveControl = Controls[I] then begin
+          if I = NControls-1 then
+            ActiveControl := Controls[0]
+          else
+            ActiveControl := Controls[I+1];
+          Exit;
+        end;
       end;
     end;
+
+    { Didn't move }
+    if ActiveControl <> FActiveMemo then
+      ActiveControl := FActiveMemo;
   end;
 end;
 

+ 10 - 10
Projects/Src/Setup.MainFunc.pas

@@ -68,7 +68,7 @@ var
   { Variables for command line parameters }
   SetupLdrMode: Boolean;
   SetupLdrOriginalFilename: String;
-  SetupLdrOffset0, SetupLdrOffset1: Longint;
+  SetupLdrOffset0, SetupLdrOffset1: Int64;
   SetupNotifyWndPresent: Boolean;
   SetupNotifyWnd: HWND;
   InitLang: String;
@@ -2592,14 +2592,14 @@ procedure InitializeSetup;
 var
   DecompressorDLL, SevenZipDLL: TMemoryStream;
 
-  function ExtractLongWord(var S: String): LongWord;
-  var
-    P: Integer;
+  function ExtractInt64(var S: String): Int64;
   begin
-    P := PathPos(',', S);
+    const P = Pos(',', S);
     if P = 0 then
-      raise Exception.Create('ExtractLongWord: Missing comma');
-    Result := LongWord(StrToInt(Copy(S, 1, P-1)));
+      raise Exception.Create('Error parsing command line: Missing comma');
+    Result := StrToInt64Def(Copy(S, 1, P-1), -1);
+    if Result < 0 then
+      raise Exception.Create('Error parsing command line: Invalid value');
     Delete(S, 1, P);
   end;
 
@@ -2981,10 +2981,10 @@ begin
   if CompareText(ParamName, '/SL5=') = 0 then begin
     StartParam := 2;
     SetupLdrMode := True;
-    SetupNotifyWnd := ExtractLongWord(ParamValue);
+    SetupNotifyWnd := UInt32(ExtractInt64(ParamValue));
     SetupNotifyWndPresent := True;
-    SetupLdrOffset0 := ExtractLongWord(ParamValue);
-    SetupLdrOffset1 := ExtractLongWord(ParamValue);
+    SetupLdrOffset0 := ExtractInt64(ParamValue);
+    SetupLdrOffset1 := ExtractInt64(ParamValue);
     SetupLdrOriginalFilename := ParamValue;
   end
   else begin

+ 11 - 10
Projects/Src/Shared.Struct.pas

@@ -387,17 +387,18 @@ type
   { TSetupLdrOffsetTable is stored inside SetupLdr's SetupLdrOffsetTableResID
     RCDATA resource }
   PSetupLdrOffsetTable = ^TSetupLdrOffsetTable;
-  TSetupLdrOffsetTable = packed record
+  TSetupLdrOffsetTable = record
     ID: array[1..12] of AnsiChar;   { = SetupLdrOffsetTableID }
-    Version: LongWord;              { = SetupLdrOffsetTableVersion }
-    TotalSize: LongWord;            { Minimum expected size of setup.exe }
-    OffsetEXE: LongWord;            { Offset of compressed setup.e32 }
-    UncompressedSizeEXE: LongWord;  { Size of setup.e32 before compression }
-    CRCEXE: Longint;                { CRC of setup.e32 before compression }
-    Offset0: LongWord;              { Offset of embedded setup-0.bin data }
-    Offset1: LongWord;              { Offset of embedded setup-1.bin data,
+    Version: UInt32;                { = SetupLdrOffsetTableVersion }
+    TotalSize: Int64;               { Minimum expected size of setup.exe }
+    OffsetEXE: Int64;               { Offset of compressed setup.e32 }
+    UncompressedSizeEXE: UInt32;    { Size of setup.e32 before compression }
+    CRCEXE: Int32;                  { CRC of setup.e32 before compression }
+    Offset0: Int64;                 { Offset of embedded setup-0.bin data }
+    Offset1: Int64;                 { Offset of embedded setup-1.bin data,
                                       or 0 when DiskSpanning=yes }
-    TableCRC: Longint;              { CRC of all prior fields in this record }
+    ReservedPadding: UInt32;        { Not set (just provides padding) }
+    TableCRC: Int32;                { CRC of all prior fields in this record }
   end;
 
   { TMessagesLangOptions is a simplified version of TSetupLanguageEntry that
@@ -416,7 +417,7 @@ type
 const
   SetupLdrOffsetTableResID = 11111;
   SetupLdrOffsetTableID = 'rDlPtS'#$CD#$E6#$D7#$7B#$0B#$2A;
-  SetupLdrOffsetTableVersion = 1;
+  SetupLdrOffsetTableVersion = 2;
   SetupExeModeOffset = $30;
   SetupExeModeUninstaller = $6E556E49;
   SetupExeModeRegSvr = $53526E49;

+ 45 - 37
whatsnew.htm

@@ -11,20 +11,24 @@
       --main-bg-color: light-dark(white, #1f1f1f);
       --link-fg-color: light-dark(hsl(206, 100%, 37%), hsl(206, 100%, 50%));
       --link-hover-fg-color: light-dark(hsl(206, 100%, 27%), hsl(206, 100%, 43%));
-      --code-bg-color: light-dark(#f0f0f0, #403e41);
+      --code-bg-color: light-dark(#f0f0f0, #353135);
     }
     body         { font: calc(14rem/16)/1.5 "Segoe UI", sans-serif; color: var(--main-fg-color); background-color: var(--main-bg-color) }
     a:link, a:visited { color: var(--link-fg-color); background-color: transparent; text-decoration: none }
     a[href]:hover { color: var(--link-hover-fg-color); text-decoration: underline }
     tt, pre      { font: calc(13rem/16)/calc(21rem/16) monospace; color: inherit; background-color: var(--code-bg-color) }
     tt           { padding: 2px 4px; border-radius: 4px }
-    pre          { line-height: normal; padding: 10px; border-radius: 6px }
+    pre          { line-height: normal; padding: 10px; border-radius: 6px; overflow-x: auto }
     li, div.limargins { margin-block: calc(5rem/16) }
     div.bluehead { text-align: center; color: white; background-color: hsl(206, 100%, 30%); padding: 5px; font-weight: bold; line-height: normal }
     .date        { font-size: calc(11rem/16); font-weight: bold }
     .head1       { font-size: calc(32rem/16) }
     .head2       { font-size: calc(20rem/16) }
     .ver         { font-size: calc(20rem/16); font-weight: bold }
+    code.innosetup .sec { font-weight: bold }
+    code.innosetup .key { color: #0078d4 }
+    code.innosetup .com { color: #339933 }
+    code.innosetup .con { color: #9262a8 }
 </style>
 </head>
 <body>
@@ -62,12 +66,12 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
         <li>Using a solid archive is not recommended; extraction performance may degrade depending on the solid block size.</li>
         <li>Archive extraction otherwise behaves the same as external file copying. For example, it supports automatic uninstallation of extracted files and can be combined with same other flags and parameters.</li>
         <li>Example script:
-          <pre>[Setup]
-ArchiveExtraction=enhanced/nopassword
+          <pre><code class="innosetup"><span class="sec">[Setup]</span>
+<span class="key">ArchiveExtraction</span>=enhanced/nopassword
 
-[Files]
-Source: "{tmp}\MyProg-ExtraReadmes.7z"; DestDir: "{app}"; \
-  Flags: external extractarchive recursesubdirs createallsubdirs ignoreversion</pre>
+<span class="sec">[Files]</span>
+<span class="key">Source</span>: "<span class="con">{tmp}</span>\MyProg-ExtraReadmes.7z"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"</span>; \
+  <span class="key">Flags</span>: external extractarchive recursesubdirs createallsubdirs ignoreversion</code></pre>
         </li>
       </ul>
     </li>
@@ -97,11 +101,13 @@ Source: "{tmp}\MyProg-ExtraReadmes.7z"; DestDir: "{app}"; \
     <li>When combined with the new <tt>extractarchive</tt> flag (see above), the archive will be downloaded and, if the <tt>issigverify</tt> flag is also used, verified at the start of the <i>Preparing to Install</i> step. The archive is then extracted normally during the actual installation process.<br/>
         In this case, the value of <tt>DestName</tt> is used to determine the archive format and for display and logging purposes.</li>
     <li>Example script:
-      <pre>[Files]
-Source: "https://jrsoftware.org/download.php/is.exe?dontcount=1"; DestName: "innosetup-latest.exe"; DestDir: "{app}"; \
-  ExternalSize: 7_000_000; Flags: external download ignoreversion
-Source: "https://jrsoftware.org/download.php/myprog-extrareadmes.7z"; DestName: "MyProg.ExtraReadmes.7z"; DestDir: "{app}"; \
-  ExternalSize: 275; Flags: external download extractarchive ignoreversion</pre>
+      <pre><code class="innosetup"><span class="sec">[Files]</span>
+<span class="key">Source</span>: "https://jrsoftware.org/download.php/is.exe?dontcount=1"; \
+  <span class="key">DestName</span>: "innosetup-latest.exe"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ExternalSize</span>: 7_000_000; <span class="key">Flags</span>: external download ignoreversion
+<span class="key">Source</span>: "https://jrsoftware.org/download.php/myprog-extrareadmes.7z"; \
+  <span class="key">DestName</span>: "MyProg.ExtraReadmes.7z"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ExternalSize</span>: 275; <span class="key">Flags</span>: external download extractarchive ignoreversion</code></pre>
     </li>
     <li>Added example script <i>DownloadFiles.iss</i> to demonstrate how to use a single <tt>[Files]</tt> entry to download a file, or to download and extract an archive, with verification.</li>
   </ul>
@@ -119,14 +125,14 @@ Source: "https://jrsoftware.org/download.php/myprog-extrareadmes.7z"; DestName:
     <li>Supports parameters <tt>Name</tt> (required) and <tt>Group</tt> to identify keys, parameters <tt>KeyFile</tt>, <tt>PublicX</tt>, and <tt>PublicY</tt> to specify the key values, parameter <tt>KeyID</tt> to double-check the key values, and parameter <tt>RuntimeID</tt> for runtime identification of the key.</li>
     <li>Key files are human-readable and can be created using Inno Setup Signature Tool (see below).</li>
     <li>Example section:
-      <pre>[ISSigKeys]
-Name: anna: KeyFile: "anna.ispublickey"; Group: exesigner
-Name: ryan; KeyFile: "ryan.ispublickey"; Group: exesigner
-Name: ivan; KeyFile: "ivan.ispublickey"; Group: docsigner
-; max is trusted for both exe and doc signing
-Name: max; KeyFile: "max.ispublickey"; Group: exesigner docsigner
-; the boss also has a key
-Name: bosskey; KeyFile: "boss.ispublickey"</pre>
+      <pre><code class="innosetup"><span class="sec">[ISSigKeys]</span>
+<span class="key">Name</span>: anna; <span class="key">KeyFile</span>: "anna.ispublickey"; <span class="key">Group</span>: exesigner
+<span class="key">Name</span>: ryan; <span class="key">KeyFile</span>: "ryan.ispublickey"; <span class="key">Group</span>: exesigner
+<span class="key">Name</span>: ivan; <span class="key">KeyFile</span>: "ivan.ispublickey"; <span class="key">Group</span>: docsigner
+<span class="com">; max is trusted for both exe and doc signing</span>
+<span class="key">Name</span>: max; <span class="key">KeyFile</span>: "max.ispublickey"; <span class="key">Group</span>: exesigner docsigner
+<span class="com">; the boss also has a key</span>
+<span class="key">Name</span>: bosskey; <span class="key">KeyFile</span>: "boss.ispublickey"</code></pre>
     </li>
   </ul>
   </li>
@@ -141,17 +147,18 @@ Name: bosskey; KeyFile: "boss.ispublickey"</pre>
     <li>Added a new and optional <tt>ISSigAllowedKeys</tt> parameter to restrict which keys or groups of keys from the <tt>[ISSigKeys]</tt> section are permitted for signature verification using the <tt>issigverify</tt> flag.</li>
     <li>Note: The <tt>issigverify</tt> flag cannot be combined with the <tt>sign</tt> or <tt>signonce</tt> flags. Use <tt>signcheck</tt> instead.</li>
     <li>Example section:
-      <pre>[Files]
-Source: "MyProg.exe"; DestDir: "{app}"; \
-  ISSigAllowedKeys: "exesigner bosskey"; Flags: issigverify 
-Source: "MyProg.chm"; DestDir: "{app}"; \
-  ISSigAllowedKeys: "docsigner bosskey"; Flags: issigverify
-Source: "{src}\Extra\*.chm"; DestDir: "{app}"; \
-  ISSigAllowedKeys: "docsigner bosskey"; Flags: issigverify external; \
-  Excludes: "*.issig"
-Source: "https://jrsoftware.org/download.php/is.exe?dontcount=1"; DestDir: "{app}"; \
-  ISSigAllowedKeys: "exesigner bosskey"; Flags: issigverify external download ignoreversion; \
-  DestName: "innosetup-latest.exe"; ExternalSize: 7_000_000</pre>
+      <pre><code class="innosetup"><span class="sec">[Files]</span>
+<span class="key">Source</span>: "MyProg.exe"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ISSigAllowedKeys</span>: "exesigner bosskey"; <span class="key">Flags</span>: issigverify 
+<span class="key">Source</span>: "MyProg.chm"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ISSigAllowedKeys</span>: "docsigner bosskey"; <span class="key">Flags</span>: issigverify
+<span class="key">Source</span>: "<span class="con">{src}</span>\Extra\*.chm"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ISSigAllowedKeys</span>: "docsigner bosskey"; <span class="key">Flags</span>: issigverify external; \
+  <span class="key">Excludes</span>: "*.issig"
+<span class="key">Source</span>: "https://jrsoftware.org/download.php/is.exe?dontcount=1"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">ISSigAllowedKeys</span>: "exesigner bosskey"; \
+  <span class="key">Flags</span>: issigverify external download ignoreversion; \
+  <span class="key">DestName</span>: "innosetup-latest.exe"; <span class="key">ExternalSize</span>: 7_000_000</code></pre>
     </li>
   </ul>
   </li>
@@ -160,10 +167,10 @@ Source: "https://jrsoftware.org/download.php/is.exe?dontcount=1"; DestDir: "{app
     <li>Added <tt>ISSigTool.exe</tt>, a new command-line utility designed to sign files using ECDSA P-256 cryptographic signatures.</li>
     <li>Offers commands to sign and verify files, to export public keys and to generate private keys.</li>
     <li>Example commands:
-      <pre>issigtool --key-file="MyKey.isprivatekey" generate-private-key
+      <pre><code>issigtool --key-file="MyKey.isprivatekey" generate-private-key
 issigtool --key-file="MyKey.isprivatekey" sign "MyProg.dll"
 issigtool --key-file="MyKey.isprivatekey" export-public-key "MyKey.ispublickey"
-issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</pre>
+issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</code></pre>
     </li>
   </ul>
   </li>
@@ -180,10 +187,11 @@ issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</pre>
     <li>The compiler now verifies additional precompiled files, such as <i>Setup.e32</i> and <i>SetupLdr.e32</i>, to ensure they remain unchanged before using them. Can be disabled using new [Setup] section directive <tt>DisablePrecompiledFileVerifications</tt>, though doing so is <i>not</i> recommended.</li>
     <li>Added new <tt>[Files]</tt> section parameter <tt>Hash</tt>. Instructs the compiler or Setup to do a simple SHA-256 hash check instead of a full signature verification, as an alternative to using the <tt>issigverify</tt> flag.<br/>
         Example script:
-      <pre>[Files]
-Source: "https://jrsoftware.org/download.php/iscrypt.dll?dontcount=1"; DestName: "ISCrypt.dll"; DestDir: "{app}"; \
-  Hash: "2f6294f9aa09f59a574b5dcd33be54e16b39377984f3d5658cda44950fa0f8fc"; \
-  ExternalSize: 2560; Flags: external download ignoreversion</pre>
+      <pre><code class="innosetup"><span class="sec">[Files]</span>
+<span class="key">Source</span>: "https://jrsoftware.org/download.php/iscrypt.dll?dontcount=1"; \
+  <span class="key">DestName</span>: "ISCrypt.dll"; <span class="key">DestDir</span>: "<span class="con">{app}</span>"; \
+  <span class="key">Hash</span>: "2f6294f9aa09f59a574b5dcd33be54e16b39377984f3d5658cda44950fa0f8fc"; \
+  <span class="key">ExternalSize</span>: 2560; <span class="key">Flags</span>: external download ignoreversion</code></pre>
     </li>
     <li>Pascal Scripting:
       <ul>