Skip to main content

How to Display File Contents with a Syntax Highlighting Concept in Batch Script

Real-time syntax highlighting in a Batch script is a significant challenge because Batch is designed for plain text stream processing. However, with the advent of ANSI Escape Codes in modern Windows terminals, we can simulate the "Concept" of syntax highlighting. By parsing a file line-by-line and using findstr or string substitution to identify keywords, we can apply specific colors to different parts of the output.

In this guide, we will demonstrate how to build a basic Batch "highlighter" that colors specific keywords in a file.

The Strategy: Keyword Substitution

To highlight text, we:

  1. Read each line of the target file.
  2. Search the line for specific keywords (e.g., echo, goto, rem).
  3. Wrap those keywords in ANSI color codes.
  4. Print the modified line.

Implementation Script: A Simple "Batch Code Explorer"

This script reads a .bat file and highlights common commands in Blue and comments in Grey.

@echo off
setlocal DisableDelayedExpansion

:: 1. Setup ANSI Colors
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"

if not defined ESC (
echo [ERROR] Could not generate ANSI escape character.
pause
exit /b 1
)

set "C_CMD=%ESC%[94m"
set "C_COMMENT=%ESC%[90m"
set "C_RESET=%ESC%[0m"

:: 2. Determine the target file
set "target=%~1"
if not defined target set "target=test_script.bat"

if not exist "%target%" (
echo [ERROR] File not found: %target%
pause
exit /b 1
)

echo Highlighting: %target%
echo ------------------------------------------

:: 3. Read file line by line safely
for /F "usebackq delims=" %%L in ("%target%") do (
set "line=%%L"
setlocal EnableDelayedExpansion

:: Trim leading spaces
set "trimmed=!line!"
for /F "tokens=*" %%t in ("!trimmed!") do set "trimmed=%%t"

:: Detect comments
set "isComment="
if defined trimmed (
if "!trimmed:~0,2!"=="::" set "isComment=1"
if /i "!trimmed:~0,4!"=="rem " set "isComment=1"
if /i "!trimmed!"=="rem" set "isComment=1"
)

if defined isComment (
echo !C_COMMENT!!line!!C_RESET!
) else (
:: Keyword highlighting using CALL for delayed expansion
set "line2=!line!"
call set "line2=%%line2: echo =%C_CMD%echo%C_RESET% %%"
call set "line2=%%line2: goto =%C_CMD%goto%C_RESET% %%"
call set "line2=%%line2: call =%C_CMD%call%C_RESET% %%"

echo(!line2!
)

endlocal
)

echo ------------------------------------------
echo %C_COMMENT%End of file.%C_RESET%

endlocal
pause
warning

Important limitations of keyword substitution: Batch string substitution (!line:word=replacement!) replaces ALL occurrences of the substring, not just whole words. For example, highlighting set would also color the set inside reset, offset, or dataset. This approach is best suited for simple visual aids where approximate highlighting is acceptable, not for precise syntax parsing.

Advanced Logic: Using FINDSTR for Line-Level Highlighting

Substitution works for individual words, but sometimes you want to highlight an entire line based on its content, for example, coloring all comment lines or all lines containing "ERROR" in a log file.

@echo off
setlocal DisableDelayedExpansion

:: 1. Setup ANSI Colors
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"

if not defined ESC (
echo [ERROR] Could not generate ANSI escape character.
pause
exit /b 1
)

set "C_ERROR=%ESC%[91m"
set "C_WARN=%ESC%[93m"
set "C_COMMENT=%ESC%[90m"
set "C_RESET=%ESC%[0m"

:: 2. Target file
set "target=%~1"
if not defined target set "target=application.log"
if not exist "%target%" (
echo [ERROR] File not found: %target%
pause
exit /b 1
)

echo Highlighting: %target%
echo ------------------------------------------

:: 3. Read file line by line
for /F "usebackq delims=" %%L in ("%target%") do (
set "line=%%L"
setlocal EnableDelayedExpansion

set "category="

:: Check for ERROR
echo !line! | findstr /i /C:"ERROR" >nul 2>&1
if !errorlevel! equ 0 set "category=error"

:: Check for WARNING
if not defined category (
echo !line! | findstr /i /C:"WARNING" >nul 2>&1
if !errorlevel! equ 0 set "category=warn"
)

:: Check for comment (:: or rem)
if not defined category (
set "trimmed=!line!"
for /F "tokens=*" %%t in ("!trimmed!") do set "trimmed=%%t"
if "!trimmed:~0,2!"=="::" set "category=comment"
if /i "!trimmed:~0,4!"=="rem " set "category=comment"
if /i "!trimmed!"=="rem" set "category=comment"
)

:: Print line with proper color
if "!category!"=="error" (
echo !C_ERROR!!line!!C_RESET!
) else if "!category!"=="warn" (
echo !C_WARN!!line!!C_RESET!
) else if "!category!"=="comment" (
echo !C_COMMENT!!line!!C_RESET!
) else (
echo !line!
)

endlocal
)

echo ------------------------------------------
pause
endlocal

Example of application.log file:

:: Application log for MyApp v1.2
rem Generated on 2026-04-05

[INFO] Application started successfully
[INFO] Loading configuration files
[WARNING] Configuration file "config.ini" not found, using defaults
[INFO] Connecting to database...
[ERROR] Database connection failed: Timeout expired
[INFO] Retrying database connection...
[INFO] Database connected successfully
[WARNING] Disk space is low: 500MB remaining
[INFO] Performing scheduled cleanup
[ERROR] Cleanup failed: File access denied
[INFO] Application shutdown initiated
:: End of log

Limitations of Batch Syntax Highlighting

  1. Performance: Parsing a large file with multiple findstr checks per line is slow in Batch. This concept is best used for small config files, short code snippets, or log excerpts under a few hundred lines.
  2. Accuracy: Batch lacks a tokenizing lexer. Simple string substitution highlights substrings within larger words (e.g., set inside reset), and findstr cannot distinguish between keywords in code versus keywords in comments or string literals.
  3. Special Characters: Characters like !, &, |, <, >, and ^ in the input file can break the echo and substitution logic. The exclamation mark is particularly problematic with enabledelayedexpansion enabled, as it is consumed as a delimiter. Lines containing these characters may display incorrectly or cause errors.

When to Use This Concept

  • Log File Viewers: Highlighting "ERROR" or "WARNING" lines in log files for quick visual scanning.
  • Config Readers: Making a .ini or .cfg file easier to read by coloring section headers differently from values.
  • Script Previews: Providing a simple "pretty-print" view of a Batch script as part of an educational or documentation tool.

Best Practices

  1. Use Bright/High-Contrast Colors: Use standard ANSI "Bright" codes (91–97) to ensure keywords pop against a dark background.
  2. Include a "Raw" Option: Always give the user a way to view the file without highlighting, in case the parsing logic garbles a line that contains special characters.
  3. Pre-Define a Color Map: Create a set of named variables at the start (e.g., C_COMMENT, C_CMD, C_ERROR) so you can easily adjust the color theme of your highlighter.
  4. Prefer Line-Level Highlighting: For log files, coloring entire lines based on their category (error, warning, info) is more reliable and useful than attempting word-level substitution.

Conclusion

While true IDE-level syntax highlighting in Batch is functionally impossible due to speed and parsing constraints, the ANSI Highlighting Concept is a powerful way to add a layer of legibility to your tools. By color-coding keywords and log levels, you make information significantly easier for the human eye to process, proving that even a legacy environment like Batch can support modern, user-centric visual features.