Skip to content

Commit

Permalink
PR #13502 from AviaAv: python script to create html from lrs_options
Browse files Browse the repository at this point in the history
  • Loading branch information
Nir-Az authored Nov 12, 2024
2 parents 960edef + eba3fd8 commit 31f3252
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/static_analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,15 @@ jobs:
echo "Error - The minimal CMake version required for LibRS is ${EXPECTED_CMAKE_MAJOR_VER}.${EXPECTED_CMAKE_MINOR_VER} but on this build the minimal CMake version that works is $CURRENT_CMAKE_MAJOR_VER.$CURRENT_CMAKE_MINOR_VER"
exit 1
fi
build_flags_docs:
name: "Generate build-flags.html"
timeout-minutes: 10
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3

- name: Build docs
run: |
python3 scripts/lrs_options-to-html.py
6 changes: 6 additions & 0 deletions CMake/lrs_options.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## This file is also being used to generate our build flags document at https://intelrealsense.github.io/librealsense/build-flags-docs/build-flags.html
## Formatting notes for this file:
## Options are listed as: <name> | <description> [comment] | <value>
## regular comments should be ABOVE their relevent option
## use double # for comments that should not show in the options doc

option(ENABLE_CCACHE "Build with ccache." ON)
option(BUILD_WITH_CUDA "Enable CUDA" OFF)
option(BUILD_GLSL_EXTENSIONS "Build GLSL extensions API" ON)
Expand Down
91 changes: 91 additions & 0 deletions doc/build-flags.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* This file is used in lrs_options-to-html, creating the html build-flags.html file we use to keep
the flags updated */
body {
font-family: 'Roboto', Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
}

.container {
width: 80%;
margin: 0 auto;
padding: 30px;
}

h1 {
text-align: center;
margin-bottom: 20px;
}

h2 {
text-align: center;
margin-bottom: 30px;
}

table {
width: 100%;
border-collapse: collapse;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: visible;
}

th, td {
padding: 16px;
text-align: left;
border: 1px solid #ddd;
}

th {
background-color: #5873e0;
color: white;
}

tr:hover {
background-color: #f0f0f0;
}

code {
padding: 2px 4px;
border-radius: 4px;
font-family: 'Roboto Mono', monospace;
}
/* --- Tooltip --- */
.tooltip {
position: relative;
display: block;
}

.tooltip .tooltip-text {
visibility: hidden;
/*width: 120px;*/
background-color: #555;
color: #fff;
text-align: center;
padding: 5%;
border-radius: 6px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
}

.tooltip .tooltip-text::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}

.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
Binary file added doc/build-flags.ico
Binary file not shown.
146 changes: 146 additions & 0 deletions scripts/lrs_options-to-html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import sys


def add_style(option, val):
# colorize ON and OFF keywords
val = val.replace('ON', '<span style="color: #4CAF50;">ON</span>')
val = val.replace('OFF', '<span style="color: #E74C3C;">OFF</span>')

# if more complicated conditions are being used, this can be disabled -
# if we see an option more than once at add_row, just set its value to be 'Environment dependant'
# this should handle if/elseif/else structures of cmake
if in_cond:
# text will say Environment dependant, and if hovered will show the condition
val = f'<span class="tooltip">Environment dependant<span class="tooltip-text">{val}<br/></span></span>'
elif in_elseif:
# append condition to tooltip
val = table_rows[option][2].replace("<br/></span></span>", f',<br/> {val}<br/></span></span>')

elif in_else:
# append otherwise to tooltip
val = table_rows[option][2].replace("<br/></span></span>", f',<br/>{val} otherwise</span></span>')

return val


def add_row(option, description, value):
if option in table_rows:
# update value if option exists
table_rows[option][2] = value
else:
# add to table new option
table_rows[option] = [option, description, value]


with open('CMake/lrs_options.cmake', 'r') as file:
lines = file.readlines()

table_rows = {}
in_cond = False
in_elseif = False
in_else = False
current_condition = None
current_comment = ""

for i, line in enumerate(lines):
if line.strip().startswith(('option(', 'set(')):
line = ' '.join(line.split()) # remove consecutive spaces
parts = line.strip().split(' ')
if line.strip().startswith('option('):
option = parts[0].strip('option(')
value = parts[-1].strip(")") # the last word in line is the value (ON/OFF by default)

# concatenate rest of the line - expected to be just the description in quotes
description = ' '.join(parts[1:-1]).strip('"')
else:
option = parts[0].strip('set(')
value = parts[1]
value = f'<code><span style="color: #2fcfc9;">{value}</span></code>'
# parts[2] is expected to be 'CACHE'
vartype = parts[3] # INT, STRING ...

# concatenate rest of the line - expected to be just the description in quotes
description = ' '.join(parts[4:-1]).strip('"') + f" (type {vartype})"

if current_comment:
description += " <span style='font-style: italic; color: #666;'>" + current_comment + "</span>"
current_comment = ""

if in_cond or in_elseif:
value = f'{value} if <b><code>{current_condition}</code></b>'

value = add_style(option, value)
add_row(option, description, value)
elif line.startswith('if'):
parts = line.strip().split('(', 1)
condition = parts[1][:-1] # remove last ")" - part of the 'if'
current_condition = condition
in_cond = True
elif line.startswith('elseif'):
parts = line.strip().split('(', 1)
condition = parts[1][:-1] # remove last ")" - part of the 'if'
current_condition = condition
in_cond = False
in_elseif = True
elif line.startswith('else'):
in_cond = False
in_elseif = False
in_else = True
elif line.startswith('endif'):
current_condition = None
in_cond = False
in_else = False
elif line.startswith('##'):
continue # ignore internal comments
elif line.startswith('#'):
current_comment += line.strip('# \n')
elif line.strip():
# if we reach a line that doesn't match the pattern, throw an error as it's not handled (shouldn't happen)
raise Exception(f"{i, line} not handled")


def format_dict_values():
return ''.join(
f'\n <tr>'
f'\n\t<td>\n\t <b><code>{option}</code></b>'f'\n\t</td>'
f'\n\t<td>\n\t {description}\n\t</td>'
f'\n\t<td>\n\t {value}\n\t</td>'
f'\n </tr>'
for option, description, value in table_rows.values())

def get_sdk_version():
if len(sys.argv) > 1:
# the script can get the version number as a parameter
version = sys.argv[1]
return f'Version {version}'
else:
# if no parameter provided - no version number will be included
return ""


html = f'''<!DOCTYPE html>
<html>
<head>
<title>Build Customization Flags</title>
<link rel="icon" href="build-flags.ico" type="image/icon type">
<link rel="stylesheet" href="build-flags.css">
</head>
<body>
<div class="container">
<h1>Intel RealSense™ SDK Build Customization Flags</h1>
<h2>{get_sdk_version()}</h2>
<table>
<tr>
<th style="width: 30%">Option</th>
<th style="width: 55%">Description</th>
<th style="width: 15%">Default</th>
</tr>{format_dict_values()}
</table>
</div>
</body>
</html>
'''

with open('doc/build-flags.html', 'w') as file:
file.write(html)
print("build-flags.html generated")

0 comments on commit 31f3252

Please sign in to comment.