From 6b034454f35819999cc26cfe472d537bf1eb3fbf Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 18 Sep 2024 13:40:39 +0200
Subject: fix requirement cross-references

---
 projdoc.cls | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 74 insertions(+), 9 deletions(-)

(limited to 'projdoc.cls')

diff --git a/projdoc.cls b/projdoc.cls
index fe8c8bc..23f3ea9 100644
--- a/projdoc.cls
+++ b/projdoc.cls
@@ -145,13 +145,13 @@
 % \cref{<refname>} is used
 \makeatletter
 \NewDocumentCommand{\customlabel}{omm}{%
-  \begingroup
-  \cref@constructprefix{#1}{\cref@result}%
-  \protected@edef\@currentlabel{#3}%
-  \protected@edef\@currentlabelname{#3}%
-  \protected@edef\cref@currentlabel{[#1][][\cref@result]#3}
-  \label[#1]{#2}%
-  \endgroup
+	\begingroup
+	\cref@constructprefix{#1}{\cref@result}%
+	\protected@edef\@currentlabel{#3}%
+	\protected@edef\@currentlabelname{#3}%
+	\protected@edef\cref@currentlabel{[#1][][\cref@result]#3}
+	\label[#1]{#2}%
+	\endgroup
 }
 \makeatother
 
@@ -215,6 +215,9 @@
 	selection={recorded and deps and see},
 ]
 
+% requirements
+\externaldocument{reqs}[./requirements.pdf]
+
 % default document header/trailer
 \makeatletter
 \def\projdoc@header{
@@ -293,8 +296,8 @@
 	\def\UrlRight{\hbox{\,}}%
 }
 \DefineVerbatimEnvironment{blockcode}{Verbatim}{
-  tabsize=2,
-  obeytabs,
+	tabsize=2,
+	obeytabs,
 }
 
 % scale down image if it exceeds page margins
@@ -321,3 +324,65 @@
 \crefname{test}{test}{tests}
 \Crefname{test}{Test}{Tests}
 
+% fix cleveref showing filename to external cross-reference
+% see <https://tex.stackexchange.com/a/708445/211562>
+% edited from cleveref source
+\makeatletter
+\def\cref@getref#1#2{%
+	\expandafter\let\expandafter#2\csname r@#1@cref\endcsname%
+	\expandafter\expandafter\expandafter\def%
+		\expandafter\expandafter\expandafter#2%
+		\expandafter\expandafter\expandafter{%
+			\expandafter\@firstoffive#2}}%
+\def\cpageref@getref#1#2{%
+	\expandafter\let\expandafter#2\csname r@#1@cref\endcsname%
+	\expandafter\expandafter\expandafter\def%
+		\expandafter\expandafter\expandafter#2%
+		\expandafter\expandafter\expandafter{%
+			\expandafter\@secondoffive#2}}%
+\AtBeginDocument{%
+	\def\label@noarg#1{%
+		\cref@old@label{#1}%
+		\@bsphack%
+		\edef\@tempa{{page}{\the\c@page}}%
+		\setcounter{page}{1}%
+		\edef\@tempb{\thepage}%
+		\expandafter\setcounter\@tempa%
+		\cref@constructprefix{page}{\cref@result}%
+		\protected@write\@auxout{}{%
+			\string\newlabel{#1@cref}{%
+				{\cref@currentlabel}%
+				{[\@tempb][\arabic{page}][\cref@result]\thepage}%
+				{}%
+				{}%
+				{}%
+			}%
+		}%
+		\@esphack%
+	}%
+	\def\label@optarg[#1]#2{%
+		\cref@old@label{#2}%
+		\@bsphack%
+		\edef\@tempa{{page}{\the\c@page}}%
+		\setcounter{page}{1}%
+		\edef\@tempb{\thepage}%
+		\expandafter\setcounter\@tempa%
+		\cref@constructprefix{page}{\cref@result}%
+		\protected@edef\cref@currentlabel{%
+			\expandafter\cref@override@label@type%
+			\cref@currentlabel\@nil{#1}%
+		}%
+		\protected@write\@auxout{}{%
+			\string\newlabel{#2@cref}{%
+				{\cref@currentlabel}%
+				{[\@tempb][\arabic{page}][\cref@result]\thepage}%
+				{}%
+				{}%
+				{}%
+			}%
+		}%
+		\@esphack%
+	}%
+}
+\makeatother
+
-- 
cgit v1.2.3


From f2e1083970107994a031a394198fde039bdf3b77 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 18 Sep 2024 14:10:59 +0200
Subject: cleanup

---
 projdoc.cls         | 2 +-
 scripts/reqs2tex.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'projdoc.cls')

diff --git a/projdoc.cls b/projdoc.cls
index 23f3ea9..7420d38 100644
--- a/projdoc.cls
+++ b/projdoc.cls
@@ -216,7 +216,7 @@
 ]
 
 % requirements
-\externaldocument{reqs}[./requirements.pdf]
+\externaldocument{reqs}[requirements.pdf]
 
 % default document header/trailer
 \makeatletter
diff --git a/scripts/reqs2tex.py b/scripts/reqs2tex.py
index 8a6976a..82b0aae 100755
--- a/scripts/reqs2tex.py
+++ b/scripts/reqs2tex.py
@@ -113,7 +113,7 @@ def fmt_aux(data):
         '[][][]',
         '',
         '',
-        './requirements.pdf',
+        '',
       )),
     ]
   return "\n".join(out)
-- 
cgit v1.2.3


From 0027f5df316892f121bb9f4b5b6b641646273ff0 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 18 Sep 2024 14:54:48 +0200
Subject: add requirements + improve generated reqs.tex

---
 projdoc.cls         |  7 +++++--
 reqs.toml           | 39 ++++++++++++++++++++++++++++++---------
 requirements.tex    |  1 +
 scripts/reqs2tex.py | 15 ++++++++-------
 scripts/tex.py      | 10 ++++++++++
 5 files changed, 54 insertions(+), 18 deletions(-)

(limited to 'projdoc.cls')

diff --git a/projdoc.cls b/projdoc.cls
index 7420d38..fccf8c1 100644
--- a/projdoc.cls
+++ b/projdoc.cls
@@ -215,8 +215,11 @@
 	selection={recorded and deps and see},
 ]
 
-% requirements
-\externaldocument{reqs}[requirements.pdf]
+% allow cross-references to requirements.pdf from all documents except
+% requirements.pdf itself
+\IfEq*{\jobname}{requirements}{}{
+	\externaldocument{reqs}[requirements.pdf]
+}
 
 % default document header/trailer
 \makeatletter
diff --git a/reqs.toml b/reqs.toml
index c05cf71..6645ea4 100644
--- a/reqs.toml
+++ b/reqs.toml
@@ -10,33 +10,46 @@
 # (cross-)referenced from LaTeX by prefixing this ID with `req:` and
 # substituting dots for colons (i.e. this requirement is referenced as
 # \cref{req:audio:async-api}).
-[audio.async-api]
+[audio]
 # Requirement type ('system' | 'user')
-type = 'system'
+type = 'user'
 # MoSCoW priority ('must' | 'should' | 'could' | 'will not')
 priority = 'must'
 # Requirement body. Supports LaTeX formatting. (tip: use single quotes so
 # backslash doesn't act as an escape character)
 description = '''
-The public audio \gls{api} supports starting audio samples asynchronously
-(i.e.~fire and forget).
+The engine allows the game programmer to easily start, pause and stop
+background music, while simultaniously playing sound effects.
 '''
-# Definition of done (user requirements only). If 'done' is a string, it is
-# treated as LaTeX code (like description), if it is a list of strings, each
-# item is treated as the ID of another requirement.
+# Definition of done. If 'done' is a string, it is treated as LaTeX code, if it
+# is a list of strings, each item is treated as the ID of another requirement,
+# and the references are checked before LaTeX runs.
+done = [
+	'audio.async-api',
+	'audio.handle',
+	'audio.stream-mix',
+	'audio.volume',
+]
 #done = 'When I feel like it'
-#done = [ 'audio.handle', 'audio.stream-mix' ]
 # Requirements that are no longer applicable should set `deleted` to `true`.
 # This will make sure the requirements are numbered consistently across
 # different document revisions.
 #deleted = true
 
+[audio.async-api]
+type = 'system'
+priority = 'must'
+description = '''
+The public audio \gls{api} supports starting audio samples asynchronously
+(i.e.~fire and forget).
+'''
+
 [audio.handle]
 type = 'system'
 priority = 'must'
 description = '''
 The public audio \gls{api} allows the game programmer to control (i.e.~play,
-pause and stop) audio samples after they are created/initialized.
+pause, resume and stop) audio samples after they are created/initialized.
 '''
 
 [audio.stream-mix]
@@ -46,6 +59,14 @@ description = '''
 The audio system supports playing multiple audio streams simultaniously.
 '''
 
+[audio.volume]
+type = 'system'
+priority = 'must'
+description = '''
+The public audio \gls{api} allows the game programmer to control the volume of
+audio samples.
+'''
+
 [aux.license]
 type = 'system'
 priority = 'must'
diff --git a/requirements.tex b/requirements.tex
index 2936272..cbaba81 100644
--- a/requirements.tex
+++ b/requirements.tex
@@ -6,6 +6,7 @@
 \projdoc@description@labelindent=0pt
 \projdoc@setdescriptionstyle
 \makeatother
+\setcounter{secnumdepth}{1}
 
 \title{Requirements}
 
diff --git a/scripts/reqs2tex.py b/scripts/reqs2tex.py
index 82b0aae..ff9f3bb 100755
--- a/scripts/reqs2tex.py
+++ b/scripts/reqs2tex.py
@@ -122,7 +122,7 @@ def fmt_tex(data):
   out = ""
   for item in data:
     out += tex.join(
-      tex.cmd('subsection', item[KEY.ID]),
+      tex.cmd('subsection', f"{item[KEY.ID]}: {item[KEY.LABEL]}".upper()),
       tex.withatletter(
         tex.cmd('cref@constructprefix', 'requirement', r'\cref@result'),
         tex.pedef('@currentlabel', item[KEY.ID]),
@@ -130,12 +130,13 @@ def fmt_tex(data):
         tex.pedef('cref@currentlabel', tex.group(['requirement'], [''], [r'\cref@result']) + item[KEY.ID]),
       ),
       tex.cmd('label', ['requirement'], label2ref(item[KEY.LABEL])),
-      tex.cmd('par'),
-      tex.env('description', tex.join(
-        tex.cmd('item', ['Priority']) + item[KEY.PRIORITY].title(),
-        tex.cmd('item', ['Requirement']) + item[KEY.DESCRIPTION],
-        (tex.cmd('item', ['Definition of done']) + item[KEY.DONE] if item[KEY.DONE] is not None else ""),
-      ))
+      tex.cmd('parbox', tex.cmd('linewidth'),
+        tex.env('description', tex.join(
+          tex.cmd('item', ['Priority']) + item[KEY.PRIORITY].title(),
+          tex.cmd('item', ['Requirement']) + item[KEY.DESCRIPTION],
+          (tex.cmd('item', ['Definition of done']) + item[KEY.DONE] if item[KEY.DONE] is not None else ""),
+        )),
+      )
     )
   return out
 
diff --git a/scripts/tex.py b/scripts/tex.py
index e8fc65b..07d275a 100644
--- a/scripts/tex.py
+++ b/scripts/tex.py
@@ -69,3 +69,13 @@ def explist(*items):
       out += explist(*item)
   return out
 
+def sec(level, heading):
+  level = max(min(3, level), 0)
+  section = [
+    'section',
+    'subsection',
+    'subsubsection',
+    'paragraph',
+  ][level]
+  return cmd(section, heading)
+
-- 
cgit v1.2.3

