mirror of
https://github.com/wolfpld/tracy.git
synced 2026-10-23 17:20:48 +00:00
Generate markdown manual at build time.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@ manual/t*.bbl
|
||||
manual/t*.blg
|
||||
manual/t*.fdb_latexmk
|
||||
manual/t*.fls
|
||||
manual/tracy.md
|
||||
profiler/build-appimage
|
||||
.deps/
|
||||
.dirstamp
|
||||
|
||||
@@ -288,7 +288,8 @@ fs.writeFileSync('/tmp/toolbar-zoom.png', buf);
|
||||
| 1012–1036 | 2142681495 | ▶ next frame — focuses the timeline on the next frame (verified: view range 25.82 s → 203.38 ms) |
|
||||
| 1052–1072 | 2961929287 | ▼ frame set selection (switch the active frame set) |
|
||||
|
||||
Button names and functions: the user manual, *Control menu* (`manual/tracy.md`). The
|
||||
Button names and functions: the user manual, *Control menu* (`manual/tracy.md`,
|
||||
generated into the profiler build directory by the build, e.g. `build/profiler/manual/tracy.md`). The
|
||||
web build omits *Connection* (live capture only) and *Tracy Assist* (desktop only).
|
||||
|
||||
## User scale (DPI zoom)
|
||||
|
||||
73
cmake/manual.cmake
Normal file
73
cmake/manual.cmake
Normal file
@@ -0,0 +1,73 @@
|
||||
set(PANDOC_VERSION 3.9.0.2)
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||
|
||||
find_program(TRACY_PANDOC pandoc)
|
||||
if(TRACY_PANDOC)
|
||||
execute_process(
|
||||
COMMAND ${TRACY_PANDOC} --version
|
||||
OUTPUT_VARIABLE _pandoc_version
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE _pandoc_rc
|
||||
ERROR_QUIET)
|
||||
string(REGEX MATCH "pandoc [0-9.]+" _pandoc_version "${_pandoc_version}")
|
||||
if(NOT _pandoc_rc EQUAL 0 OR NOT _pandoc_version STREQUAL "pandoc ${PANDOC_VERSION}")
|
||||
set(TRACY_PANDOC "")
|
||||
endif()
|
||||
endif()
|
||||
if(TRACY_PANDOC)
|
||||
message(STATUS "Using system pandoc ${PANDOC_VERSION}: ${TRACY_PANDOC}")
|
||||
else()
|
||||
if(WIN32)
|
||||
if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$")
|
||||
message(FATAL_ERROR "No pinned pandoc ${PANDOC_VERSION} binary for ${CMAKE_HOST_SYSTEM_PROCESSOR}; install pandoc ${PANDOC_VERSION}")
|
||||
endif()
|
||||
set(_pandoc_asset pandoc-${PANDOC_VERSION}-windows-x86_64.zip)
|
||||
set(_pandoc_hash c97542f2800f446e788d9f74237856d995421ad1bb3cc8324286840c5f272d3a)
|
||||
set(_pandoc_exe pandoc-${PANDOC_VERSION}/pandoc.exe)
|
||||
elseif(APPLE)
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)$")
|
||||
set(_pandoc_asset pandoc-${PANDOC_VERSION}-arm64-macOS.zip)
|
||||
set(_pandoc_hash 6e9eca844076bcbb599bbeebbba78a70f93b5307782b85c2c272872812c88875)
|
||||
set(_pandoc_exe pandoc-${PANDOC_VERSION}-arm64/bin/pandoc)
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$")
|
||||
set(_pandoc_asset pandoc-${PANDOC_VERSION}-x86_64-macOS.zip)
|
||||
set(_pandoc_hash b9fbceabccbc8f34ac021a50483fc32f8160568d0b4b2c22d81bb29e3054fd82)
|
||||
set(_pandoc_exe pandoc-${PANDOC_VERSION}-x86_64/bin/pandoc)
|
||||
else()
|
||||
message(FATAL_ERROR "No pinned pandoc ${PANDOC_VERSION} binary for ${CMAKE_HOST_SYSTEM_PROCESSOR}; install pandoc ${PANDOC_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
|
||||
set(_pandoc_asset pandoc-${PANDOC_VERSION}-linux-arm64.tar.gz)
|
||||
set(_pandoc_hash b6d21e8f9c3b15744f5a7ab40248019157ed7793875dbe0383d4c82ff572b528)
|
||||
set(_pandoc_exe pandoc-${PANDOC_VERSION}/bin/pandoc)
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64|amd64)$")
|
||||
set(_pandoc_asset pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz)
|
||||
set(_pandoc_hash a69abfababda8a56969a254b09f9553a7be89ddec00d4e0fe9fd585d71a67508)
|
||||
set(_pandoc_exe pandoc-${PANDOC_VERSION}/bin/pandoc)
|
||||
else()
|
||||
message(FATAL_ERROR "No pinned pandoc ${PANDOC_VERSION} binary for ${CMAKE_HOST_SYSTEM_PROCESSOR}; install pandoc ${PANDOC_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(TRACY_PANDOC ${CMAKE_BINARY_DIR}/tools/${_pandoc_exe})
|
||||
if(NOT EXISTS ${TRACY_PANDOC})
|
||||
message(STATUS "Downloading pandoc ${PANDOC_VERSION} (${_pandoc_asset})")
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tools)
|
||||
file(DOWNLOAD
|
||||
https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/${_pandoc_asset}
|
||||
${CMAKE_BINARY_DIR}/tools/pandoc.archive
|
||||
EXPECTED_HASH SHA256=${_pandoc_hash}
|
||||
STATUS _pandoc_download)
|
||||
list(GET _pandoc_download 0 _pandoc_download_rc)
|
||||
if(NOT _pandoc_download_rc STREQUAL "0")
|
||||
file(REMOVE ${CMAKE_BINARY_DIR}/tools/pandoc.archive)
|
||||
message(FATAL_ERROR "Failed to download pandoc ${PANDOC_VERSION}: ${_pandoc_download}")
|
||||
endif()
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT ${CMAKE_BINARY_DIR}/tools/pandoc.archive
|
||||
DESTINATION ${CMAKE_BINARY_DIR}/tools)
|
||||
file(REMOVE ${CMAKE_BINARY_DIR}/tools/pandoc.archive)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1 +0,0 @@
|
||||
The LaTeX source file (tracy.tex) and the resulting PDF file (tracy.pdf) are the only authorative version of the user manual. Do NOT modify the Markdown user manual (tracy.md) by hand. It is only meant to be updated via the latex2md.sh script.
|
||||
@@ -1,35 +0,0 @@
|
||||
/\\begin\{bclogo\}\[/ {
|
||||
in_bclogo = 1
|
||||
bclogo_type = ""
|
||||
next
|
||||
}
|
||||
in_bclogo && /logo=/ {
|
||||
if (/\\bcbombe/) bclogo_type = "bcbombe"
|
||||
else if (/\\bcattention/) bclogo_type = "bcattention"
|
||||
else if (/\\bclampe/) bclogo_type = "bclampe"
|
||||
else if (/\\bcquestion/) bclogo_type = "bcquestion"
|
||||
next
|
||||
}
|
||||
in_bclogo && /noborder|couleur/ {
|
||||
next
|
||||
}
|
||||
in_bclogo {
|
||||
line = $0
|
||||
sub(/^[ \t]*\]?\{/, "", line)
|
||||
sub(/\}.*$/, "", line)
|
||||
bclogo_title = line
|
||||
|
||||
if (bclogo_type == "bcbombe") prefix = "IMPORTANT"
|
||||
else if (bclogo_type == "bcattention") prefix = "CAUTION"
|
||||
else if (bclogo_type == "bclampe") prefix = "TIP"
|
||||
else prefix = "NOTE"
|
||||
|
||||
printf "\\begin{quote}\\textbf{%s:%s}\\par\n", prefix, bclogo_title
|
||||
in_bclogo = 0
|
||||
next
|
||||
}
|
||||
/\\end\{bclogo\}/ {
|
||||
printf "\\end{quote}\n"
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
@@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Replace Font Awesome icon macros in LaTeX with Unicode codepoints."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
def pascal_to_snake(name):
|
||||
"""Convert PascalCase to UPPER_SNAKE_CASE."""
|
||||
result = name[0]
|
||||
for i in range(1, len(name)):
|
||||
if name[i].isupper() and name[i - 1].islower():
|
||||
result += '_'
|
||||
result += name[i]
|
||||
return result.upper()
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(f"Usage: {sys.argv[0]} <header_path> <tex_path>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
header_path = sys.argv[1]
|
||||
tex_path = sys.argv[2]
|
||||
|
||||
# Parse header: ICON_FA_SNAKE_CASE -> Unicode char
|
||||
icons = {}
|
||||
with open(header_path) as f:
|
||||
for line in f:
|
||||
m = re.match(
|
||||
r'#define\s+ICON_FA_(\w+)\s+.*?//\s*(U\+([0-9a-fA-F]+))', line
|
||||
)
|
||||
if m:
|
||||
snake = m.group(1)
|
||||
parts = snake.split('_')
|
||||
pascal = ''.join(p.capitalize() for p in parts)
|
||||
codepoint = int(m.group(3), 16)
|
||||
icons[pascal] = chr(codepoint)
|
||||
|
||||
# Read tex file
|
||||
with open(tex_path) as f:
|
||||
text = f.read()
|
||||
|
||||
# Find all \faXxx used in the text (uppercase first letter excludes \fancyhead etc.)
|
||||
used = set()
|
||||
for m in re.finditer(r'\\fa([A-Z][a-zA-Z0-9]*)', text):
|
||||
used.add(m.group(1))
|
||||
|
||||
# Replace each used icon, longest names first to avoid prefix conflicts
|
||||
for name in sorted(used, key=lambda n: (-len(n), n)):
|
||||
if name not in icons:
|
||||
print(f"Warning: \\fa{name} not found in header", file=sys.stderr)
|
||||
continue
|
||||
char = icons[name]
|
||||
# Order matters: more specific patterns first
|
||||
text = text.replace(f'\\fa{name}{{}}~', f'{char} ')
|
||||
text = text.replace(f'\\fa{name}{{}}', char)
|
||||
text = text.replace(f'\\fa{name}~', f'{char} ')
|
||||
text = text.replace(f'\\fa{name}', char)
|
||||
|
||||
# Write back
|
||||
with open(tex_path, 'w') as f:
|
||||
f.write(text)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,77 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Append icon legend blocks to each markdown section containing Font Awesome icons."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def _extract_icons(lines):
|
||||
"""Return deduplicated icon chars from lines, in order of first appearance."""
|
||||
seen = set()
|
||||
icons = []
|
||||
for line in lines:
|
||||
for ch in line:
|
||||
cp = ord(ch)
|
||||
if 0xE000 <= cp <= 0xF8FF and ch not in seen:
|
||||
seen.add(ch)
|
||||
icons.append(ch)
|
||||
return icons
|
||||
|
||||
|
||||
def _append_legend(result_lines, icons, icon_names):
|
||||
"""Append a legend block for the given icons."""
|
||||
result_lines.append('')
|
||||
result_lines.append('-----')
|
||||
result_lines.append('')
|
||||
for ch in icons:
|
||||
name = icon_names.get(ch, f'Unknown(U+{ord(ch):04X})')
|
||||
result_lines.append(f'{ch} - {name} icon')
|
||||
result_lines.append('')
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(f"Usage: {sys.argv[0]} <header_path> <md_path>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
header_path = sys.argv[1]
|
||||
md_path = sys.argv[2]
|
||||
|
||||
# Build char -> name mapping from header
|
||||
icon_names = {}
|
||||
with open(header_path) as f:
|
||||
for line in f:
|
||||
m = re.match(
|
||||
r'#define\s+ICON_FA_(\w+)\s+.*?//\s*(U\+([0-9a-fA-F]+))', line
|
||||
)
|
||||
if m:
|
||||
snake = m.group(1)
|
||||
parts = snake.split('_')
|
||||
pascal = ' '.join(p.capitalize() for p in parts)
|
||||
codepoint = int(m.group(3), 16)
|
||||
icon_names[chr(codepoint)] = pascal
|
||||
|
||||
with open(md_path, encoding='utf-8') as f:
|
||||
lines = f.read().split('\n')
|
||||
|
||||
# Build chunk boundaries: header lines and EOF
|
||||
chunk_starts = [i for i, line in enumerate(lines) if line.startswith('#')]
|
||||
|
||||
# Also add index 0 as a chunk start if there's pre-header content
|
||||
if chunk_starts and chunk_starts[0] > 0:
|
||||
chunk_starts.insert(0, 0)
|
||||
|
||||
result_lines = []
|
||||
for ci, start in enumerate(chunk_starts):
|
||||
end = chunk_starts[ci + 1] if ci + 1 < len(chunk_starts) else len(lines)
|
||||
icons = _extract_icons(lines[start:end])
|
||||
result_lines.extend(lines[start:end])
|
||||
if icons:
|
||||
_append_legend(result_lines, icons, icon_names)
|
||||
|
||||
with open(md_path, 'w', encoding='utf-8') as f:
|
||||
f.write('\n'.join(result_lines))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
232
manual/latex2md.py
Normal file
232
manual/latex2md.py
Normal file
@@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate the Markdown user manual from the LaTeX source.
|
||||
|
||||
Cross-platform replacement for the previous sh/sed/awk pipeline. pandoc is
|
||||
invoked as a subprocess; its Lua filter (filter.lua, next to the .tex file)
|
||||
stays with pandoc.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
PANDOC_MARKDOWN = 'markdown-simple_tables-multiline_tables-grid_tables+pipe_tables'
|
||||
|
||||
NAMES = (
|
||||
('quicklook', 'A quick look at Tracy Profiler'),
|
||||
('firststeps', 'First steps'),
|
||||
('client', 'Client markup'),
|
||||
('capturing', 'Capturing the data'),
|
||||
('analyzingdata', 'Analyzing captured data'),
|
||||
('tracyassist', 'Tracy Assist'),
|
||||
('csvexport', 'Exporting zone statistics to CSV'),
|
||||
('importingdata', 'Importing external profiling data'),
|
||||
('configurationfiles', 'Configuration files'),
|
||||
)
|
||||
|
||||
|
||||
def parse_icon_header(path):
|
||||
"""Return (pascal_name -> char, char -> 'Word Word') maps from the icon header."""
|
||||
fa = {}
|
||||
names = {}
|
||||
with open(path, encoding='utf-8') as f:
|
||||
for line in f:
|
||||
m = re.match(
|
||||
r'#define\s+ICON_FA_(\w+)\s+.*?//\s*(U\+([0-9a-fA-F]+))', line
|
||||
)
|
||||
if m:
|
||||
parts = m.group(1).split('_')
|
||||
ch = chr(int(m.group(3), 16))
|
||||
fa[''.join(p.capitalize() for p in parts)] = ch
|
||||
names[ch] = ' '.join(p.capitalize() for p in parts)
|
||||
return fa, names
|
||||
|
||||
|
||||
def substitute_icons(text, fa):
|
||||
used = set(re.findall(r'\\fa([A-Z][a-zA-Z0-9]*)', text))
|
||||
for name in sorted(used, key=lambda n: (-len(n), n)):
|
||||
if name not in fa:
|
||||
print(f"Warning: \\fa{name} not found in header", file=sys.stderr)
|
||||
continue
|
||||
ch = fa[name]
|
||||
text = text.replace(f'\\fa{name}{{}}~', f'{ch} ')
|
||||
text = text.replace(f'\\fa{name}{{}}', ch)
|
||||
text = text.replace(f'\\fa{name}~', f'{ch} ')
|
||||
text = text.replace(f'\\fa{name}', ch)
|
||||
return text
|
||||
|
||||
|
||||
def pre_sed(text):
|
||||
text = text.replace('\\menu[,]', '')
|
||||
text = text.replace('\\keys', '')
|
||||
text = text.replace('\\ctrl', 'Ctrl')
|
||||
text = text.replace('\\shift', 'Shift')
|
||||
text = text.replace('\\Alt', 'Alt')
|
||||
text = text.replace('\\del', 'Delete')
|
||||
return text
|
||||
|
||||
|
||||
def post_sed(text):
|
||||
for m in ('LMB', 'MMB', 'RMB', 'Scroll'):
|
||||
text = text.replace(f'\\{m}{{}}~', '')
|
||||
text = text.replace('\\textsigma', 'σ')
|
||||
for l in 'abc':
|
||||
text = text.replace(f'@\\circled{{{l}}}@', f'({l})')
|
||||
for l in 'abc':
|
||||
text = text.replace(f'\\circled{{{l}}}', f'({l})')
|
||||
text = text.replace('@\\ldots@', '…')
|
||||
text = re.sub(r',?escapeinside=\{\}\{\}', '', text)
|
||||
for label, name in NAMES:
|
||||
text = text.replace(f'\\nameref{{{label}}}', name)
|
||||
return text
|
||||
|
||||
|
||||
def bclogo2quote(text):
|
||||
"""Convert \\begin{bclogo} admonition blocks to \\begin{quote}\\textbf{PREFIX:...}."""
|
||||
prefix = {'bcbombe': 'IMPORTANT', 'bcattention': 'CAUTION', 'bclampe': 'TIP'}
|
||||
out = []
|
||||
in_bclogo = False
|
||||
bclogo_type = ''
|
||||
for line in text.split('\n'):
|
||||
if not in_bclogo and r'\begin{bclogo}[' in line:
|
||||
in_bclogo = True
|
||||
bclogo_type = ''
|
||||
continue
|
||||
if in_bclogo and 'logo=' in line:
|
||||
if r'\bcbombe' in line:
|
||||
bclogo_type = 'bcbombe'
|
||||
elif r'\bcattention' in line:
|
||||
bclogo_type = 'bcattention'
|
||||
elif r'\bclampe' in line:
|
||||
bclogo_type = 'bclampe'
|
||||
elif r'\bcquestion' in line:
|
||||
bclogo_type = 'bcquestion'
|
||||
continue
|
||||
if in_bclogo and ('noborder' in line or 'couleur' in line):
|
||||
continue
|
||||
if in_bclogo:
|
||||
title = re.sub(r'\}.*$', '', re.sub(r'^[ \t]*\]?\{', '', line))
|
||||
out.append(f"\\begin{{quote}}\\textbf{{{prefix.get(bclogo_type, 'NOTE')}:{title}}}\\par")
|
||||
in_bclogo = False
|
||||
continue
|
||||
if r'\end{bclogo}' in line:
|
||||
out.append('\\end{quote}')
|
||||
continue
|
||||
out.append(line)
|
||||
return '\n'.join(out)
|
||||
|
||||
|
||||
def run_pandoc(pandoc, filter_path, tex):
|
||||
args = [
|
||||
pandoc,
|
||||
'--wrap=none',
|
||||
'--reference-location=block',
|
||||
'--number-sections',
|
||||
'-f', 'latex',
|
||||
'-t', PANDOC_MARKDOWN,
|
||||
'-s',
|
||||
'-L', filter_path,
|
||||
'-',
|
||||
]
|
||||
proc = subprocess.run(args, input=tex.encode('utf-8'), capture_output=True)
|
||||
if proc.returncode != 0:
|
||||
sys.stderr.write(proc.stderr.decode('utf-8', 'replace'))
|
||||
sys.exit(proc.returncode)
|
||||
return proc.stdout.decode('utf-8')
|
||||
|
||||
|
||||
def tablecaption(text):
|
||||
"""Pandoc emits table captions as ": ..." lines; italicize them instead."""
|
||||
out = []
|
||||
incap = False
|
||||
for line in text.split('\n'):
|
||||
if not incap and line.startswith(': '):
|
||||
incap = True
|
||||
line = '_' + line[2:]
|
||||
if incap and not line.endswith('\\'):
|
||||
out.append(line + '_')
|
||||
incap = False
|
||||
continue
|
||||
out.append(line)
|
||||
return '\n'.join(out)
|
||||
|
||||
|
||||
def admonitions(text):
|
||||
for kind in ('IMPORTANT', 'TIP', 'CAUTION', 'NOTE'):
|
||||
text = re.sub(
|
||||
rf'^> \*\*{kind}:([^*]*)\*\*',
|
||||
f'> [!{kind}]\n> **\\1**',
|
||||
text,
|
||||
flags=re.M,
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
def icon_explain(text, names):
|
||||
"""Append an icon legend to each top-level section containing FA icons."""
|
||||
lines = text.split('\n')
|
||||
chunk_starts = [i for i, line in enumerate(lines) if line.startswith('#')]
|
||||
if chunk_starts and chunk_starts[0] > 0:
|
||||
chunk_starts.insert(0, 0)
|
||||
out = []
|
||||
for ci, start in enumerate(chunk_starts):
|
||||
end = chunk_starts[ci + 1] if ci + 1 < len(chunk_starts) else len(lines)
|
||||
chunk = lines[start:end]
|
||||
icons = []
|
||||
seen = set()
|
||||
for line in chunk:
|
||||
for ch in line:
|
||||
cp = ord(ch)
|
||||
if 0xE000 <= cp <= 0xF8FF and ch not in seen:
|
||||
seen.add(ch)
|
||||
icons.append(ch)
|
||||
out.extend(chunk)
|
||||
if icons:
|
||||
out.append('')
|
||||
out.append('-----')
|
||||
out.append('')
|
||||
for ch in icons:
|
||||
out.append(f"{ch} - {names.get(ch, f'Unknown(U+{ord(ch):04X})')} icon")
|
||||
out.append('')
|
||||
return '\n'.join(out)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description='Generate the Markdown user manual')
|
||||
ap.add_argument('--tex', required=True, help='path to tracy.tex')
|
||||
ap.add_argument('--out', required=True, help='path of the generated tracy.md')
|
||||
ap.add_argument('--pandoc', required=True, help='path to the pandoc executable')
|
||||
ap.add_argument('--icons', required=True, help='path to IconsFontAwesome7.h')
|
||||
args = ap.parse_args()
|
||||
|
||||
fa, names = parse_icon_header(args.icons)
|
||||
|
||||
with open(args.tex, encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = pre_sed(text)
|
||||
text = substitute_icons(text, fa)
|
||||
text = post_sed(text)
|
||||
text = bclogo2quote(text)
|
||||
|
||||
md = run_pandoc(
|
||||
args.pandoc,
|
||||
os.path.join(os.path.dirname(os.path.abspath(args.tex)), 'filter.lua'),
|
||||
text,
|
||||
)
|
||||
|
||||
md = tablecaption(md)
|
||||
md = admonitions(md)
|
||||
md = icon_explain(md, names)
|
||||
|
||||
out_dir = os.path.dirname(os.path.abspath(args.out))
|
||||
if out_dir:
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
with open(args.out, 'w', encoding='utf-8', newline='\n') as f:
|
||||
f.write(md)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cp -f tracy.tex _tmp.tex
|
||||
sed -i -e 's@\\menu\[,\]@@g' _tmp.tex
|
||||
sed -i -e 's@\\keys@@g' _tmp.tex
|
||||
sed -i -e 's@\\ctrl@Ctrl@g' _tmp.tex
|
||||
sed -i -e 's@\\shift@Shift@g' _tmp.tex
|
||||
sed -i -e 's@\\Alt@Alt@g' _tmp.tex
|
||||
sed -i -e 's@\\del@Delete@g' _tmp.tex
|
||||
python3 fa-icons.py ../profiler/src/profiler/IconsFontAwesome7.h _tmp.tex
|
||||
sed -i -e 's@\\LMB{}~@@g' _tmp.tex
|
||||
sed -i -e 's@\\MMB{}~@@g' _tmp.tex
|
||||
sed -i -e 's@\\RMB{}~@@g' _tmp.tex
|
||||
sed -i -e 's@\\Scroll{}~@@g' _tmp.tex
|
||||
sed -i -e 's@\\textsigma@σ@g' _tmp.tex
|
||||
|
||||
# Resolve \circled{} markers and lstlisting escapeinside (@...@) snippets, which
|
||||
# pandoc would otherwise emit verbatim or drop, to their Unicode equivalents.
|
||||
sed -i -e 's|@\\circled{a}@|(a)|g' -e 's|@\\circled{b}@|(b)|g' -e 's|@\\circled{c}@|(c)|g' _tmp.tex
|
||||
sed -i -e 's|\\circled{a}|(a)|g' -e 's|\\circled{b}|(b)|g' -e 's|\\circled{c}|(c)|g' _tmp.tex
|
||||
sed -i -e 's|@\\ldots@|…|g' _tmp.tex
|
||||
# pandoc doens't recognize this lstlisting option and emits it verbatim
|
||||
sed -i -e 's|,\?escapeinside={}{}||g' _tmp.tex
|
||||
|
||||
sed -i -e 's@\\nameref{quicklook}@A quick look at Tracy Profiler@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{firststeps}@First steps@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{client}@Client markup@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{capturing}@Capturing the data@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{analyzingdata}@Analyzing captured data@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{tracyassist}@Tracy Assist@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{csvexport}@Exporting zone statistics to CSV@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{importingdata}@Importing external profiling data@g' _tmp.tex
|
||||
sed -i -e 's@\\nameref{configurationfiles}@Configuration files@g' _tmp.tex
|
||||
|
||||
awk -f bclogo2quote.awk _tmp.tex > _tmp_quoted.tex
|
||||
mv _tmp_quoted.tex _tmp.tex
|
||||
|
||||
pandoc --wrap=none --reference-location=block --number-sections -L filter.lua -t 'markdown-simple_tables-multiline_tables-grid_tables+pipe_tables' -s _tmp.tex -o tracy.md
|
||||
|
||||
awk -f tablecaption.awk tracy.md > _tmp_caption.md
|
||||
mv _tmp_caption.md tracy.md
|
||||
|
||||
sed -i -e 's/^> \*\*IMPORTANT:\([^*]*\)\*\*/> [!IMPORTANT]\
|
||||
> **\1**/' tracy.md
|
||||
sed -i -e 's/^> \*\*TIP:\([^*]*\)\*\*/> [!TIP]\
|
||||
> **\1**/' tracy.md
|
||||
sed -i -e 's/^> \*\*CAUTION:\([^*]*\)\*\*/> [!CAUTION]\
|
||||
> **\1**/' tracy.md
|
||||
sed -i -e 's/^> \*\*NOTE:\([^*]*\)\*\*/> [!NOTE]\
|
||||
> **\1**/' tracy.md
|
||||
|
||||
python3 icon-explain.py ../profiler/src/profiler/IconsFontAwesome7.h tracy.md
|
||||
|
||||
rm -f _tmp.tex
|
||||
@@ -1,16 +0,0 @@
|
||||
# Pandoc emits table captions as a line beginning with ": ", which GitHub
|
||||
# renders literally instead of as a caption. Strip the marker and italicize
|
||||
# the caption instead. Captions may span several physical lines when they
|
||||
# contain a hard line break (a trailing backslash). Underscores are used for
|
||||
# the emphasis so captions that already contain "*...*" markup are left intact.
|
||||
!incap && /^: / {
|
||||
incap = 1
|
||||
$0 = "_" substr($0, 3)
|
||||
}
|
||||
incap && !/\\$/ {
|
||||
print $0 "_"
|
||||
incap = 0
|
||||
next
|
||||
}
|
||||
incap { print; next }
|
||||
{ print }
|
||||
5425
manual/tracy.md
5425
manual/tracy.md
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/../cmake/config.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/vendor.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/server.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/GitRef.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/manual.cmake)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(embed
|
||||
@@ -181,8 +182,23 @@ Embed(PROFILER_FILES FontBold src/font/Roboto-Bold.ttf)
|
||||
Embed(PROFILER_FILES FontItalic src/font/Roboto-Italic.ttf)
|
||||
Embed(PROFILER_FILES FontBoldItalic src/font/Roboto-BoldItalic.ttf)
|
||||
Embed(PROFILER_FILES FontEmoji src/font/NotoEmoji-Regular.ttf)
|
||||
set(MANUAL_MD ${CMAKE_CURRENT_BINARY_DIR}/manual/tracy.md)
|
||||
add_custom_command(
|
||||
OUTPUT ${MANUAL_MD}
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/../manual/latex2md.py
|
||||
--tex ${CMAKE_CURRENT_LIST_DIR}/../manual/tracy.tex
|
||||
--out ${MANUAL_MD}
|
||||
--pandoc ${TRACY_PANDOC}
|
||||
--icons ${CMAKE_CURRENT_LIST_DIR}/src/profiler/IconsFontAwesome7.h
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_LIST_DIR}/../manual/tracy.tex
|
||||
${CMAKE_CURRENT_LIST_DIR}/../manual/filter.lua
|
||||
${CMAKE_CURRENT_LIST_DIR}/../manual/latex2md.py
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/profiler/IconsFontAwesome7.h
|
||||
COMMENT "Generating user manual"
|
||||
VERBATIM)
|
||||
|
||||
Embed(PROFILER_FILES Manual ../manual/tracy.md TEXT)
|
||||
Embed(PROFILER_FILES Manual manual/tracy.md TEXT BUILD)
|
||||
|
||||
Embed(PROFILER_FILES Text100Million src/achievements/100Million.md TEXT)
|
||||
Embed(PROFILER_FILES TextConnectToClient src/achievements/ConnectToClient.md TEXT)
|
||||
|
||||
Reference in New Issue
Block a user