I thought, selecting the attributes of
img element in UE/UES, passing them to a batch file for adding or updating the values of attributes
width and
height would be more easier than writing the script code. Well, I was completely wrong. The Windows command processor limitations made this coding task really tricky. It would have been definitely better to use Visual Basic script or a PowerShell script for this task instead of a batch file with pure Windows internal commands. And best would have been to code the UltraEdit script for this task. However, I like tricky coding tasks. Therefore I finished the batch file coding even as I found out that coding a batch file for this task is not a good idea.
The requirements I defined myself for this coding task before starting batch file coding:
- HTML is case-insensitive and therefore processing the attributes of img element must be done also case-insensitive by the batch file.
- Attribute values can be enclosed in double and single quotes and also not enclosed in quotes at all. All 3 quote types should be supported.
- Attributes width and height not existing at all should be supported with appending the missing attribute(s) with correct value(s).
- Attributes width and height existing already with no values should be supported, too.
- Attributes width and height with empty values should be also supported by the batch file.
- The order of the attributes should not matter on processing them by the batch file.
- The whitespaces between the attributes can be any number of spaces or horizontal tabs.
- The batch file does not need to keep the whitespace type (space or tab) and number of whitespaces between the attributes.
- Leading and trailing whitespaces must not be kept by the batch file. The selected text must not start or end with whitespaces.
- The batch file should work also if the passed arguments list starts with image file name without src=.
- Other attributes in arguments lists should be processed without any modification.
- URL encoded file names/paths must not be supported by the batch file.
- Images on a web server referenced with complete URL must not be supported by the batch file.
- Image elements with attributes spread over multiple lines must not be supported by the batch file solution.
The test file I created for testing the batch file:
Code: Select all
<img src="gfx/image.png" alt="Test 1: no attributes width and height">
<img src="gfx/image.png" width= height= alt="Test 2: attributes width and height with no values">
<img src="gfx/image.png" width="" height="" alt="Test 3: attributes width and height with empty values in double quotes">
<img src="gfx/image.png" width='' height='' alt="Test 4: attributes width and height with empty values in single quotes">
<img src="gfx/image.png" width=400 height=50 alt="Test 5: attributes width and height with values without quotes">
<img src="gfx/image.png" width="400" height="50" alt="Test 6: attributes width and height with values in double quotes">
<img src='gfx/image.png' height='50' alt="Test 7: attributes width and height with values in single quotes">
<img src='gfx/image.png' width='400' height='50' alt="Test 8: attributes width and height 2 tabs and 2 spaces between">
<img width=28 src="gfx/image.png" height='30' alt="Test 9: unusual order of the attributes and usual usage of quotes">
<img src='gfx/image.png' alt="Test 10: attributes width and height wrong in % with other attributes between" hspace=5 style="border-style:ridge; border-width:10px; border-color:#A52A2A" width="400%" height="50%">
Note: On line 8 there are two tabs and not multiple spaces as the browser displays left of
width='400'. And there is one more tab character after
width=28 on line 9.
ATTENTION: This solution posted here works only with ANSI encoded HTML files. It does not work with Unicode (UTF-8) encoded HTML files with UE v23.20.0.43.
The commented batch code using
IrfanView as image processor which I stored in a file with name
ImageWidthHeight.bat.
Code: Select all
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Define file name of IrfanView with full path.
set "IrfanView=%ProgramFiles(x86)%\IrfanView\i_view32.exe"
rem Define type of quote to use around added or inserted width and
rem height values. Possible values are " or ' or no quote at all.
set "QuoteAdd=""
rem Is the batch file called without any parameter?
set "ArgsAll=%*"
if "!ArgsAll!" == "" goto EndBatch
rem Define some environment variables used later in batch code.
set "TmpFile=%TEMP%\%~n0.tmp"
set "ImgFile="
set "ArgHeight=0"
set "ArgWidth=0"
set "ArgIndex=1"
set "CharIndex=0"
set "CharTab= "
set "QuoteActive="
set "QuoteDouble=""
set "QuoteSingle='"
goto NextArg
rem Get all the arguments passed to the batch file. Windows command
rem processor interprets space/tab and equal sign as argument delimiters.
rem Therefore the arguments list must be parsed manually by batch code.
:NextArg
set "Argument="
:ParseArg
set "NextChar=!ArgsAll:~%CharIndex%,1!"
set /A CharIndex+=1
if "!NextChar!" == "" goto CheckArg
if "!QuoteActive!" == "" (
if "!NextChar!" == " " goto SkipSpaces
if "!NextChar!" == "!CharTab!" goto SkipSpaces
if !NextChar! == !QuoteDouble! (
set "QuoteActive=!QuoteDouble!"
) else if !NextChar! == !QuoteSingle! (
set "QuoteActive=!QuoteSingle!"
)
) else if !QuoteActive! == !NextChar! (
set "QuoteActive="
)
set "Argument=!Argument!!NextChar!"
goto ParseArg
rem Skip all spaces and tabs between two IMG attributes.
:SkipSpaces
set "NextChar=!ArgsAll:~%CharIndex%,1!"
if "!NextChar!" == "" goto CheckArg
if not "!NextChar!" == " " (
if not "!NextChar!" == "!CharTab!" goto CheckArg
)
set /A CharIndex+=1
goto SkipSpaces
rem Once the argument string - IMG attribute without any value or with
rem an empty value or with a non empty value - is determined by special
rem parser, find out if attributes width and height are present already
rem in arguments list without or with a value and get image file name
rem with its relative path from the attribute src if present in the
rem arguments list at all.
rem If the current argument is the attribute src, it should be with the name
rem of the image file with file extension and without or with a relative path.
rem The image file name without or with path can be enclosed in double quotes
rem or in single quotes which need to be removed from argument string.
:CheckArg
if "!Argument!" == "" goto CheckFile
set "ArgNumber=0%ArgIndex%"
set "ArgNumber=%ArgNumber:~-2%"
if /I "!Argument:~0,6!" == "width=" goto EvalWidth
if /I "!Argument:~0,7!" == "height=" goto EvalHeight
if /I not "!Argument:~0,4!" == "src=" goto StoreArg
set "ImgFile=!Argument:~4!"
call :GetFileName
:StoreArg
set "ImgAttrib_%ArgNumber%=!Argument!"
set /A ArgIndex+=1
goto NextArg
rem This is a subroutine to get image file name without surrounding quotes.
:GetFileName
if "!ImgFile:~0,1!" == "!QuoteDouble!" set "ImgFile=!ImgFile:~1!"
if "!ImgFile:~-1!" == "!QuoteDouble!" set "ImgFile=!ImgFile:~0,-1!"
if "!ImgFile:~0,1!" == "!QuoteSingle!" set "ImgFile=!ImgFile:~1!"
if "!ImgFile:~-1!" == "!QuoteSingle!" set "ImgFile=!ImgFile:~0,-1!"
goto :EOF
rem The current argument is the attribute width. The next argument can be
rem missing in case of just width= is at end of arguments list. In this case
rem it is necessary to add the width value. But it is also possible that just
rem width="" is in arguments list which must be updated by inserting the
rem width value. Or there is just width='' or width= with a value to update.
:EvalWidth
if not "%ArgWidth%" == "0" goto StoreArg
if "!Argument:~6!" == "" set "Argument=!Argument!%QuoteAdd%?%QuoteAdd%"
set "ArgWidth=%ArgNumber%"
goto StoreArg
rem The current argument is the attribute height.
rem It must be evaluated like the attribute width.
:EvalHeight
if not "%ArgHeight%" == "0" goto StoreArg
if "!Argument:~7!" == "" set "Argument=!Argument!%QuoteAdd%?%QuoteAdd%"
set "ArgHeight=%ArgNumber%"
goto StoreArg
rem Interpret first argument as file name if not attribute src with
rem file name found in arguments list and remove surrounding quotes.
:CheckFile
if "!ImgFile!" == "" (
set "ImgFile=!ImgAttrib_01!"
call :GetFileName
)
if "!ImgFile!" == "" goto Output
rem Replace all forward slashes by backslashes and get image
rem file name with absolute path if the file really exists.
set "ImgFile=!ImgFile:/=\!"
if not exist "!ImgFile!" goto Output
for %%I in ("!ImgFile!") do set "ImgFile=%%~fI"
rem Run IrfanView to get information about image file.
del "%TmpFile%" 2>nul
if not exist "%IrfanView%" goto Output
"%IrfanView%" "!ImgFile!" /info="%TmpFile%"
if not exist "%TmpFile%" goto Output
rem Find in image information the line with width and height.
for /F "usebackq tokens=1-6" %%A in ("%TmpFile%") do (
if /I "%%A %%B %%C %%E" == "Image dimensions = x" (
set "ImgWidth=%%D"
set "ImgHeight=%%F"
goto UpdateWidth
)
)
rem IrfanView failed to get image information from file
rem most likely because of file is not an image file.
del "%TmpFile%"
goto Output
rem Keep the first 6 characters of width attribute and update
rem the value with keeping the double or single quotes depending
rem on what type of quotes are used for value of attribute width.
rem The same is next done also for attribute height and image height.
:UpdateWidth
del "%TmpFile%"
if "%ArgWidth%" == "0" goto AddWidth
set "QuoteActive=!ImgAttrib_%ArgWidth%:~6,1!"
if "!QuoteActive!" == "!QuoteDouble!" (
set "ImgAttrib_%ArgWidth%=!ImgAttrib_%ArgWidth%:~0,6!"%ImgWidth%""
) else if "!QuoteActive!" == "!QuoteSingle!" (
set "ImgAttrib_%ArgWidth%=!ImgAttrib_%ArgWidth%:~0,6!'%ImgWidth%'"
) else (
set "ImgAttrib_%ArgWidth%=!ImgAttrib_%ArgWidth%:~0,6!%ImgWidth%"
)
goto UpdateHeight
rem But in case of attribute width was not in arguments list,
rem append one more argument with the attribute width with the
rem image width and quotes as defined at top of the batch file.
:AddWidth
set "ArgNumber=0%ArgIndex%"
set "ArgNumber=%ArgNumber:~-2%"
set "ImgAttrib_%ArgNumber%=width=%QuoteAdd%%ImgWidth%%QuoteAdd%"
set /A ArgIndex+=1
:UpdateHeight
if "%ArgHeight%" == "0" goto AddHeight
set "QuoteActive=!ImgAttrib_%ArgHeight%:~7,1!"
if "!QuoteActive!" == "!QuoteDouble!" (
set "ImgAttrib_%ArgHeight%=!ImgAttrib_%ArgHeight%:~0,7!"%ImgHeight%""
) else if "!QuoteActive!" == "!QuoteSingle!" (
set "ImgAttrib_%ArgHeight%=!ImgAttrib_%ArgHeight%:~0,7!'%ImgHeight%'"
) else (
set "ImgAttrib_%ArgHeight%=!ImgAttrib_%ArgHeight%:~0,7!%ImgHeight%"
)
goto RebuildArgs
:AddHeight
set "ArgNumber=0%ArgIndex%"
set "ArgNumber=%ArgNumber:~-2%"
set "ImgAttrib_%ArgNumber%=height=%QuoteAdd%%ImgHeight%%QuoteAdd%"
:RebuildArgs
set "ArgsAll="
for /F "tokens=1* delims==" %%I in ('set ImgAttrib_') do set "ArgsAll=!ArgsAll! %%J"
set "ArgsAll=!ArgsAll:~1!"
:Output
echo !ArgsAll!
:EndBatch
endlocal
Note 1: After
IrfanView= the path and file name of IrfanView must be defined in the batch file.
Note 2: The type of quote for added
width and
height values can be defined in the batch file after
QuoteAdd=.
Note 3: There must be a horizontal tab character after
CharTab= in the batch file instead of the multiple spaces displayed by the browser according to HTML specification.
The tool configuration for using this batch file is as follows.
First tab
Command:
Menu item name:
ImageWidthHeight
Command line:
"Path to\batch file\ImageWidthHeight.bat" %sel%
Working directory:
%p
Toolbar bitmap/icon:
empty or name of a suitable image file for this tool with full path
Second tab
Options:
Program type:
DOS program
Save active file:
NOT checked
Save all files first:
NOT checked
Third tab
Output:
Command output:
Append to existing
Show DOS box:
NOT checked
Capture output:
checked
Replace selected text width:
Captured output
The user tool is now ready to use.
The user must select the attributes
src,
width and
height before running the user tool.
src= must not be selected if the first string of selection is the image file name with relative path.
As command
echo outputs always a line with line termination, the selected string in file is replaced by updated string captured from batch file output with inserting also a line termination. So it is necessary to press key END and key DEL to delete the inserted line termination after tool execution.
It is possible to run the user tool (batch file) also via an UltraEdit macro which makes the selection automatically and deletes the always inserted line termination.
The code for this UltraEdit macro is:
Code: Select all
InsertMode
ColumnModeOff
HexOff
IfSel
RunTool "ImageWidthHeight"
Key END
Delete
ExitMacro
EndIf
IfCharIs "<"
Else
Find Up "<"
IfFound
Key LEFT ARROW
Else
ExitMacro
EndIf
EndIf
UnixReOff
Find RegExp "img[^t ][~>^r^n]+"
IfFound
RunTool "ImageWidthHeight"
Key END
Delete
EndIf
See the forum topic
How to create a macro from a posted macro code? with a step by step instruction on how to create a new macro with posted macro code.
The macro should have the properties:
Macro name:
ImageWidthHeight
Show cancel dialog for this macro:
NOT checked
Continue if search string not found:
checked
It is advisable on frequent usage to assign a hotkey or chord to this macro for quick execution by key(s).
This macro should be also stored together with other often used macros in a macro file which is configured for being automatically loaded on startup of UltraEdit/UEStudio. This can be done on using
Ribbon Mode by clicking on ribbon
Advanced in group
Macro on small arrow right to item
Configure and clicking in popup menu on
Set macro for auto-load. On using
Toolbar/Menu Mode - Contemporary menus the configuration for automatic loading of a macro file on startup can be opened by clicking in menu
Advanced in submenu
Configure on menu item
Set macro for auto-load. And last on using
Toolbar/Menu Mode - Traditional menus clicking in menu
Macro on
Set Auto Load opens also the configuration for loading a macro file with 1 or more macros on startup of UltraEdit or UEStudio.
This batch file solution with main code in batch file is definitely not the best solution as it turned out during developing the batch file. So I'm planning to write an UltraEdit script which adds/updates
width and
height values of an
img element using
IrfanView called via a batch file executed via a user tool from within the UltraEdit script. The UltraEdit script makes the hard job of identifying image file name with path and the
width and
height attributes.