From: otta8634 Date: Mon, 9 Dec 2024 14:31:53 +0000 (+0800) Subject: Add cvar-standardize.sh script to qcsrc/tools/ X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=2aa7ef847236f2299695a9fa03b46b5ab1b0f725;p=xonotic%2Fxonotic-data.pk3dir.git Add cvar-standardize.sh script to qcsrc/tools/ 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". --- diff --git a/qcsrc/tools/cvar-standardize.sh b/qcsrc/tools/cvar-standardize.sh new file mode 100644 index 000000000..460de9868 --- /dev/null +++ b/qcsrc/tools/cvar-standardize.sh @@ -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 . +