]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add cvar-standardize.sh script to qcsrc/tools/
authorotta8634 <k9wolf@pm.me>
Mon, 9 Dec 2024 14:31:53 +0000 (22:31 +0800)
committerotta8634 <k9wolf@pm.me>
Mon, 9 Dec 2024 14:31:53 +0000 (22:31 +0800)
Added a bash script to somewhat-standardize cvar descriptions so that they're no longer a huge mess.
Will run the script in the following commit.
Rules this applies are outlined by L114-L122:
- remove_ending_period "${file}"
- change_colons_to_equals "${file}"
- quote_options "${file}"
- uppercase_notes "${file}"
- lowercase_after_notes "${file}"
- lowercase_option_first_letter "${file}"
- lowercase_first_letter "${file}"
- lowercase_after_sentences "${file}"
- # Americanizing spelling will have to be done manually
Since it's not perfect, cvar lines can be "opted out" from the script by appending "// script-ignore".

qcsrc/tools/cvar-standardize.sh [new file with mode: 0644]

diff --git a/qcsrc/tools/cvar-standardize.sh b/qcsrc/tools/cvar-standardize.sh
new file mode 100644 (file)
index 0000000..460de98
--- /dev/null
@@ -0,0 +1,133 @@
+#!/usr/bin/env bash
+
+set -eu
+cd "${0%/*}" # move to qcsrc/tools
+cd ../..
+
+CONFIG_EXT=".cfg"
+SCRIPT_IGNORE='\bscript-ignore[[:space:]]*$'
+# can add `// script-ignore` to the end of lines to ignore
+# e.g. g_ca 0 "Clan Arena: played in rounds, once you're dead you're out! The team with survivors wins the round" // script-ignore
+# the script would otherwise change "Clan" -> "clan", and other changes
+START='^(([[:space:]]*\/\/)?[[:space:]]*\bseta?[[:space:]]+(\w+|"\w+")[[:space:]]+([^"[:space:]]+|"[^"]*")[[:space:]]+")'
+END='("[[:space:]]*(\/\/.*)?)$'
+# selects all properly formatted set/seta lines, including commented out ones, excluding the script-ignore ones
+LINE_SELECTOR="/${SCRIPT_IGNORE}/!"
+# combined regex: /^((\s*\/\/)?\s*\bseta?\s+(\w+|"\w+")\s+([^"\s]+|"[^"]*")\s+").*("\s*(\/\/.*)?)$/, ignoring /\bscript-ignore\s*$/
+#                   +~~~~~~~~~--------------~~~~~~~~~~~---~~~~~~~~~~~~~~~~~----+  +-------------+
+#                    +-------+              +-------  \1  +---------------+           \digit
+#                       \2                      \4               \3
+# replacements should start with \1, skip \2, \3, and \4, and end with \digit
+
+# this script shouldn't be run on the user's .cfgs, or else it can alter cvars like _cl_name
+
+function hash() {
+       git hash-object "$1"
+}
+
+function remove_ending_period() {
+       #- seta cl_test_cvar "1" "some test cvar."
+       #+ seta cl_test_cvar "1" "some test cvar"
+       sed -i -E "${LINE_SELECTOR}s/${START}"'(.+)\.'"${END}"'/\1\5\6/' "$1"
+       # regex: /(.+)\./
+       #         +--+
+       #     \1   \5     \6
+}
+function change_colons_to_equals() {
+       #- seta cl_test_cvar "1" "some test cvar; 0: do nothing, 1: do something"
+       #+ seta cl_test_cvar "1" "some test cvar; 0 = do nothing, 1 = do something"
+       # using label jumping instead of global since all matches overlap
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.*[[:space:]])?([^([:space:]][^:[:space:]]*):[[:space:]]+(.*)'"${END}"'/\1\5\6 = \7\8/; ta' "$1"
+       # regex: /(.*\s)?([^(\s][^:\s]*):\s+(.*)/
+       #         +----+ +-------------+    +--+
+       #     \1    \5         \6            \7   \8
+}
+function quote_options() {
+       #- seta cl_test_cvar "1" "some test cvar (0 = do nothing, 1 = do something)"
+       #+ seta cl_test_cvar "1" "some test cvar (\"0\" = do nothing, \"1\" = do something)"
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.*[[:space:]])?(\()?([^"[:space:]]+)[[:space:]]+=[[:space:]]+(.*)'"${END}"'/\1\5\6\\"\7\\" = \8\9/; ta' "$1"
+       # regex: /(.*\s)?(\()?([^"\s]+)\s+=\s+(.*)/
+       #         +----+ +--+ +-------+       +--+
+       #     \1    \5    \6     \7            \8   \9
+}
+function uppercase_notes() {
+       #- seta cl_test_cvar "1" "some test cvar (warning: does nothing)"
+       #+ seta cl_test_cvar "1" "some test cvar (WARNING: does nothing)"
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.*[[:space:]])?(\([a-zA-Z\-]*[a-z][a-zA-Z\-]*:)[[:space:]]+([^)]*\).*)'"${END}"'/\1\5\U\6\E \7\8/; ta' "$1"
+       # regex: /(.*\s)?(\([a-zA-Z\-]*[a-z][a-zA-Z\-]*:)\s+([^)]*\).*)/
+       #         +----+ +------------------------------+   +---------+
+       #     \1    \5                  \6                      \7       \8
+}
+function lowercase_after_notes() {
+       #- seta cl_test_cvar "1" "some test cvar (WARNING: Does nothing)"
+       #+ seta cl_test_cvar "1" "some test cvar (WARNING: does nothing)"
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.*[[:space:]])?(\([A-Z][A-Z\-]*:)[[:space:]]+([A-Z][a-z\-]*[a-z]\b[^)]*\).*)'"${END}"'/\1\5\6 \l\7\8/; ta' "$1"
+       # regex: /(.*\s)?(\([A-Z][A-Z\-]*:)\s+([A-Z][a-z\-]*[a-z]\b[^)]*\).*)/
+       #         +----+ +----------------+   +-----------------------------+
+       #     \1    \5           \6                         \7                 \8
+}
+function lowercase_option_first_letter() {
+       #- seta cl_test_cvar "1" "some test cvar; \"0\" = Do nothing, \"1\" = Do something"
+       #+ seta cl_test_cvar "1" "some test cvar; \"0\" = do nothing, \"1\" = do something"
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.*[[:space:]])?(\\"[^\\]*\\")[[:space:]]+=[[:space:]]+([A-Z][a-z\-]*[a-z]\b.*)'"${END}"'/\1\5\6 = \l\7\8/; ta' "$1"
+       # regex: /(.*\s)?(\\"[^\\]*\\")\s+=\s+([A-Z][a-z\-]*[a-z]\b.*)/
+       #         +----+ +------------+       +----------------------+
+       #     \1    \5         \6                        \7             \8
+}
+function lowercase_first_letter() {
+       #- seta cl_test_cvar "1" "Some test CVAR"
+       #+ seta cl_test_cvar "1" "some test CVAR"
+       # only affects words that start with a capital letter and have no other capital letters
+       # ... otherwise we assume the capitalization is intentional (e.g. StrafeHUD)
+       # also doesn't affect one-letter words (e.g. description that starts with "R G B")
+       sed -i -E "${LINE_SELECTOR}s/${START}"'([A-Z][a-z\-]*[a-z]\b.*)'"${END}"'/\1\l\5\6/' "$1"
+       # regex: /([A-Z][a-z\-]*[a-z]\b.*)/
+       #         +----------------------+
+       #     \1             \5             \6
+}
+function lowercase_after_sentences() {
+       #- seta cl_test_cvar "1" "some test cvar; Does nothing"
+       #+ seta cl_test_cvar "1" "some test cvar; does nothing"
+       # same condition as in lowercase_first_letter()
+       sed -i -E ":a; ${LINE_SELECTOR}s/${START}"'(.+[;.?!])[[:space:]]+([A-Z][a-z\-]*[a-z]\b.*)'"${END}"'/\1\5 \l\6\7/; ta' "$1"
+       # regex: /(.+[;.?!])\s+([A-Z][a-z\-]*[a-z]\b.*)/
+       #         +--------+   +----------------------+
+       #     \1      \5                  \6             \7
+}
+
+function check() {
+       find "$1" -maxdepth 1 -type f -name "*${CONFIG_EXT}" -print0 \
+       | sort -z \
+       | while read -r -d '' file
+       do
+               if [[ "$file" == "./notifications${CONFIG_EXT}" ]]
+               then
+                       echo "Skipped ${file}"
+                       continue
+               else
+                       echo "${file}"
+               fi
+
+               oldHash="$(hash "${file}")"
+               oldTime="$(stat -c "%Y" "${file}")"
+
+               remove_ending_period "${file}"
+               change_colons_to_equals "${file}"
+               quote_options "${file}"
+               uppercase_notes "${file}"
+               lowercase_after_notes "${file}"
+               lowercase_option_first_letter "${file}"
+               lowercase_first_letter "${file}"
+               lowercase_after_sentences "${file}"
+               # Americanizing spelling will have to be done manually
+
+               newHash="$(hash "${file}")"
+               if [[ "$newHash" == "$oldHash" ]]
+               then
+                       touch -d @"$oldTime" "${file}"
+               fi
+       done
+}
+
+check .
+