This commit is contained in:
yosh 2024-05-08 12:09:09 -04:00
commit cc7260289c
10 changed files with 769 additions and 0 deletions

View file

@ -0,0 +1,9 @@
# THE DATA PARSING PIPELINE
## basic setup
1. download as ods
2. `sh s_setup.sh`
3. `php process_list.php`
## THINGS THAT WILL NEED TO BE FIXED MANUALLY
- `sort_order` for campaigns that exist on both standard and hard list

119
functions.php Normal file
View file

@ -0,0 +1,119 @@
<?php
class Campaign {
public string $url;
public string $name;
public int $author_id;
public string $author_name;
public $maps;
}
class Map {
public string $name;
public bool $is_rejected = false;
public bool $is_archived = false;
public $challenges; // array
};
class Challenge {
public int $obj_id = 1;
public int $diff_id;
public bool $has_fc = false;
public bool $requires_fc = false;
public $submissions;
}
class Submission {
public string $proof_url;
public int $player_id;
public bool $is_fc = false;
}
/* searches the top list for a sheet, row num, and if it's fc or not
* this only works for top list and standard list. other tabs will need special handling
* it will return an integer depending on its tier. -1 means it wasn't found
*/
function search_top_list($goldlist, string $sheet, int $row, bool $fc) : int
{
foreach ($goldlist[2]['table-row'] as $rowcount => &$rowval) {
if ($rowcount < 5) {
continue;
}
$colflag = false;
$colcount = 0;
foreach ($rowval['table-cell'] as $colnum => &$colval) {
if (!$colflag && !isset($colval['p'])) {
$colcount += isset($colval['+@table:number-columns-repeated'])
? intval($colval['+@table:number-columns-repeated']) : 1;
continue;
}
$colflag = true;
if (isset($colval['+@table:formula'])) {
if (preg_match('/^of:=\[\$' . $sheet . '\.\$?' . ($fc ? 'D' : 'C') . '\$?' . $row . '\]/', $colval['+@table:formula'])) {
return intdiv($colcount, 3);
}
}
$colcount += 1;
}
}
return -1;
}
/* search the hard list for a specific campaign->map
* to remove standard list fc entries that are on top list
*/
function search_hard_list($goldlist, string $campurl, string $map, bool $standalone) : bool
{
$flag = false;
$flagtoggle = false;
foreach ($goldlist[3]['table-row'] as &$crowval) {
if (isset($crowval['table-cell'][0]['p']['a']['+@xlink:href'])) {
if ($crowval['table-cell'][0]['p']['a']['+@xlink:href'] === $campurl) {
$numrows = $crowval['table-cell'][0]['+@table:number-rows-spanned'] ?? "1";
$numrows = intval($numrows);
if ($standalone === true) {
return true;
}
$flagtoggle = true;
$flag = true;
}
} else {
$flag = false;
}
if ($flagtoggle && $flag && $crowval['table-cell'][1]['p'] === $map . ' [Full Clear]') {
return true;
}
if ($flagtoggle && !$flag && $crowval['table-cell'][0]['p'] === $map . ' [Full Clear]') {
return true;
}
if (isset($numrows)) {
$numrows -= 1;
if ($numrows === 0) {
break;
}
}
}
return false;
}
/* test if the map exists in a campaign object */
function map_exists_in($camp, $mapname) : int
{
foreach ($camp as $ind => &$val) {
if ($val->name === $mapname) {
return $ind;
}
}
return -1;
}
function readstdin() : string
{
$o = "";
while ($l = fgets(STDIN)) {
$o .= $l;
}
return $o;
}

336
process_list.php Normal file
View file

@ -0,0 +1,336 @@
<?php
error_reporting(E_ALL ^ E_WARNING);
require_once("functions.php");
$str = readstdin();
$goldlist = json_decode($str, true);
// $goldlist is the entire sheet in an assoc array now.
// this will go $url => array(maps)
$arr_camps = array();
// player array
$arr_players = array();
// STANDARD LIST //
$lim = count($goldlist[4]['table-row']) - 3; // -3 to account for "total" and two weird extra rows google docs puts in?
foreach ($goldlist[4]['table-row'] as $rowcount => &$rowval) {
// skip first 2 rows and last row
if ($rowcount < 2 || $rowcount >= $lim) {
continue;
}
$obj_map = new Map();
$obj_chal = new Challenge();
// if first cell is campaign (has link), set url and shift array if it doesn't span 2 columns
// this will align all of the columns no matter what
if (gettype($rowval['table-cell'][0]['p']) === 'array') {
$obj_camp = new Campaign();
$obj_camp->url = $rowval['table-cell'][0]['p']['a']['+@xlink:href'];
$obj_camp->name = preg_replace('/ \(by [^)]+\)/i', '', $rowval['table-cell'][0]['p']['a']['+content']);
$arr_camps[] = $obj_camp;
if ($rowval['table-cell'][0]['+@table:number-columns-spanned'] !== "2") {
array_shift($rowval['table-cell']); // normalize position in array
} else {
$obj_map->name = $obj_camp->name;
}
}
$obj_map->name = $obj_map->name ?? $rowval['table-cell'][0]['p']; // fallback for no link stuff
$obj_camp->name = preg_replace('/ \[Full Clear\]$/i', '', $obj_map->name);
if (preg_match('/ \[Full Clear\]$/i', $obj_map->name)) {
$obj_map->name = preg_replace('/ \[Full Clear\]$/i', '', $obj_map->name);
$obj_chal->requires_fc = true;
}
array_shift($rowval['table-cell']);
// handle the entry numbers which tell us crucial information
// if this if statement fires, then it has an fc, but we first need to check
if ($rowval['table-cell'][0]['+@table:number-columns-spanned'] !== "2") {
if (search_hard_list($goldlist, $obj_camp->url, $obj_map->name, true) === false) {
$obj_chal->has_fc = true;
}
array_shift($rowval['table-cell']);
}
array_shift($rowval['table-cell']);
// we can do this here because $obj_chal is an object so it gets passed by reference I'm so good
$obj_map->challenges[] = $obj_chal;
$obj_camp->maps[] = $obj_map;
// now to iterate over submissions to the map
foreach ($rowval['table-cell'] as $colcount => &$cellval) {
$obj_sub = new Submission();
if (gettype($cellval['p']) !== 'array') {
continue;
}
$obj_sub->proof_url = $cellval['p']['a']['+@xlink:href'];
$tmp_playername = trim($cellval['p']['a']['+content']);
if (preg_match('/ \[FC\]$/', $tmp_playername)) {
// handles separate chals on same row
if ($obj_chal->has_fc === false) {
continue;
}
$tmp_playername = preg_replace('/ \[FC\]$/', '', $tmp_playername);
$obj_sub->is_fc = true;
}
// check if player exists already and set id accordingly
// N.B.: player id is offset one from array keys
if (($tmp_playerid = array_search($tmp_playername, $arr_players, true)) === false) {
$arr_players[] = $tmp_playername;
$obj_sub->player_id = count($arr_players);
} else {
$obj_sub->player_id = $tmp_playerid + 1;
}
$obj_chal->submissions[] = $obj_sub;
}
}
// HARD LIST
// can literally copy the camp/map/submission stuff, but num parsing will need help
$lim = count($goldlist[3]['table-row']) - 3;
foreach ($goldlist[3]['table-row'] as $rowcount => &$rowval) {
// skip first 2 rows and last row
if ($rowcount < 2 || $rowcount >= $lim) {
continue;
}
$obj_map = new Map();
$obj_chal = new Challenge();
$obj_chal_fc = new Challenge(); // this wasn't needed before but is needed now
$fc_chal_flag = false; // flag for determining if map has a separate fc challenge
$obj_chal_fc->requires_fc = true;
// if first cell is campaign (has link), set url and shift array if it doesn't span 2 columns
// this will align all of the columns no matter what
if (gettype($rowval['table-cell'][0]['p']) === 'array') {
$obj_camp = new Campaign();
$obj_camp->url = $rowval['table-cell'][0]['p']['a']['+@xlink:href'];
$obj_camp->name = preg_replace('/ \(by [^)]+\)/i', '', $rowval['table-cell'][0]['p']['a']['+content']);
$arr_camps[] = $obj_camp;
if ($rowval['table-cell'][0]['+@table:number-columns-spanned'] !== "2") {
array_shift($rowval['table-cell']);
} else {
$obj_map->name = $obj_camp->name;
}
}
$obj_map->name = $obj_map->name ?? $rowval['table-cell'][0]['p'];
$obj_camp->name = preg_replace('/ \[Full Clear\]$/i', '', $obj_map->name);
if (preg_match('/ \[Full Clear\]$/i', $obj_map->name)) {
$obj_map->name = preg_replace('/ \[Full Clear\]$/i', '', $obj_map->name);
$obj_chal->requires_fc = true;
}
array_shift($rowval['table-cell']);
// handle the entry numbers which tell us crucial information
// if this if statement fires, then it has an fc, but we first need to check
if ($rowval['table-cell'][0]['+@table:number-columns-spanned'] !== "2") {
// $rowcount + 1 since arrays start at 0 but sheets start at 1
if (($obj_chal_fc->diff_id = search_top_list($goldlist, "'Hard Golden List'", $rowcount + 1, true)) === -1) {
if ($rowval['table-cell'][1]['p'] !== "0") {
$obj_chal->has_fc = true;
}
} else {
// again passed identifier
$fc_chal_flag = true;
$obj_map->challenges[] = $obj_chal_fc;
}
array_shift($rowval['table-cell']);
}
$obj_chal->diff_id = search_top_list($goldlist, "'Hard Golden List'", $rowcount + 1, false);
array_shift($rowval['table-cell']);
// if map exists, set the obj_map to that so we can update it
// otherwise, create new map!
if (($ind = map_exists_in($obj_camp->maps, $obj_map->name)) !== -1) {
$obj_map = $obj_camp['maps'][$ind];
} else {
$obj_camp->maps[] = $obj_map;
}
$obj_map->challenges[] = $obj_chal;
foreach ($rowval['table-cell'] as $colcount => &$cellval) {
$obj_sub = new Submission();
if (gettype($cellval['p']) !== 'array') {
continue;
}
$obj_sub->proof_url = $cellval['p']['a']['+@xlink:href'];
$tmp_playername = trim($cellval['p']['a']['+content']);
if (preg_match('/ \[FC\]$/', $tmp_playername)) {
if ($fc_chal_flag === true) {
$obj_chal_fc->submissions[] = $obj_sub;
} else {
$obj_sub->is_fc = true;
$obj_chal->submissions[] = $obj_sub;
}
$tmp_playername = preg_replace('/ \[FC\]$/', '', $tmp_playername);
} else {
$obj_chal->submissions[] = $obj_sub;
}
// check if player exists already and set id accordingly
// N.B.: player id is offset one from array keys
if (($tmp_playerid = array_search($tmp_playername, $arr_players, true)) === false) {
$arr_players[] = $tmp_playername;
$obj_sub->player_id = count($arr_players);
} else {
$obj_sub->player_id = $tmp_playerid + 1;
}
}
}
// STRAWBERRY JAM
$lim = count($goldlist[6]['table-row']) - 3;
$sj_player_array = array(); // used for holding player names for associating proof urls with names
$obj_camp = new Campaign();
$obj_camp->url = "https://gamebanana.com/mods/424541";
$obj_camp->name = "Strawberry Jam Collab";
$arr_camps[] = $obj_camp;
foreach ($goldlist[6]['table-row'] as $rowcount => &$rowval) {
// skip first 2 rows and last row
if ($rowcount >= $lim) {
continue;
}
$obj_map = new Map();
$obj_chal = new Challenge();
$obj_chal_fc = new Challenge();
// special 1st row to get names!
if ($rowcount === 0) {
foreach ($rowval['table-cell'] as $colcount => &$cellval) {
if ($colcount < 3) continue; // doesn't strictly follow sheet, just keep in mind
if ($cellval['p'] === null) break;
$sj_player_array[] = trim($cellval['p']);
}
continue;
}
if ($rowcount === 1 || $rowcount > $lim) continue; // useless rows
// catch if we're at the start of a "difficulty" e.g. BEGINNER or whatnot. if so, normalize position
if (isset($rowval['table-cell'][0]['+@table:number-rows-spanned'])) {
array_shift($rowval['table-cell']);
}
$obj_map->name= $rowval['table-cell'][0]['p'];
array_shift($rowval['table-cell']);
// fc challenge mangling
$obj_map->challenges[] = $obj_chal;
$obj_chal->diff_id = search_top_list($goldlist, "'Strawberry Jam Collab 2021'", $rowcount + 1, false);
if ($rowval['table-cell'][0]['+@table:number-columns-spanned'] !== "2") { // FC PART EXISTS
$obj_chal_fc->diff_id = search_top_list($goldlist, "'Strawberry Jam Collab 2021'", $rowcount + 1, true);
if ($obj_chal_fc->diff_id === -1) { // same difficulty
$obj_chal->has_fc = true;
} else { // separate difficulty, separate challenges
$obj_map->challenges[] = $obj_chal_fc;
$obj_chal_fc->requires_fc = true;
}
array_shift($rowval['table-cell']);
}
array_shift($rowval['table-cell']);
// submissions
$player_index = 0; // this needs to be tracked separately
foreach ($rowval['table-cell'] as &$cellval) {
if (isset($cellval['+@table:number-columns-repeated'])) { // empty
$player_index += $cellval['+@table:number-columns-repeated'];
continue;
}
// NO LINK SET
if (!isset($cellval['p']['a'])) {
// ERROR DETECTION: NO LINK YET CELL CONTENT
if (isset($cellval['p'])) {
// +1 on each of these for 0-indexed arrays, +4 on player index cuz, well
$str = "";
$tmpp = $player_index + 5;
while ($tmpp > 0) {
$tmpp -= 1;
$str = substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tmpp % 26, 1) . $str;
$tmpp = intdiv($tmpp, 26);
}
echo 'NO LINK ERROR: ' . $str . sprintf('%02d', $rowcount + 1) . "\n";
}
$player_index += 1;
continue;
}
// yes link, submission
$obj_sub = new Submission();
$obj_sub->proof_url = $cellval['p']['a']['+@xlink:href'];
// FC submission, I take a lenient approach here in case there's weird shit
// this should never catch yt/bili links... what links are less than 8 characters
if (strlen($cellval['p']['a']['+content']) < 8 && str_contains($cellval['p']['a']['+content'], "FC")) {
// same challenges
if ($obj_chal->has_fc) {
$obj_sub->is_fc = true;
$obj_chal->submissions[] = $obj_sub;
} else { // separate challenges
$obj_chal_fc->submissions[] = $obj_sub;
}
} else { // non fc submission
$obj_chal->submissions[] = $obj_sub;
}
// check if player exists already and set id accordingly
// N.B.: player id is offset +1 from array keys
$tmp_playername = $sj_player_array[$player_index];
if (($tmp_playerid = array_search($tmp_playername, $arr_players, true)) === false) {
$arr_players[] = $tmp_playername;
$obj_sub->player_id = count($arr_players);
} else {
$obj_sub->player_id = $tmp_playerid + 1;
}
$player_index += 1;
}
$obj_camp->maps[] = $obj_map;
}
file_put_contents('generated_camps.json',
json_encode($arr_camps, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
);
/*
$arr_camps_real = array();
foreach ($arr_camps as $url => &$maps) {
$obj_camp = new Campaign();
}
*/
exit;
/* ONLY RUN PAST THIS POINT FOR GETTING TRUE DATA FROM GAMEBANANA API, TO RUN OVERNIGHT OR SOMETHING */
// printing everything out (to to be done after *everything*, but we currently don't have other tabs rn)
$arr_camps_real = array();
foreach ($arr_camps as $url => &$maps) {
$obj_camp = new Campaign();
$obj_camp->url = $url;
if (str_contains($url, '/mods/')) {
$gb_id = preg_replace('/.+\/(\d+)$/', '$1', $url);
$json = json_decode(shell_exec('curl -s "https://api.gamebanana.com/Core/Item/Data?itemtype=Mod&itemid=' . $gb_id . '&fields=name,Owner().name,userid"'));
if (isset($json[0])) {
$obj_camp->name = $json[0];
$obj_camp->author_name = $json[1];
$obj_camp->author_id = $json[2];
} else {
$obj_camp->name = 'GB_MOD_REMOVED_NAME';
$obj_camp->author_name = 'GB_MOD_REMOVED_AUTHOR_NAME';
$obj_camp->author_id = -1;
}
sleep(15);
} else {
$obj_camp->name = 'NOTGB_MOD_NAME';
$obj_camp->author_name = 'NOTGB_MOD_AUTHOR_NAME';
$obj_camp->author_id = -2;
}
$obj_camp->maps = $maps;
$arr_camps_real[] = $obj_camp;
}
echo json_encode($arr_camps_real, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
echo json_encode($arr_players, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);

View file

@ -0,0 +1,75 @@
<?php
// map a challenge's difficulty (human readable) to database difficulty id
function map_diff_id($chal) : int
{
// standard
if (!isset($chal->diff_id)) {
return 18;
}
switch ($chal->diff_id) {
case 0:
return 2; break;
case 1:
return 5; break;
case 2:
return 8; break;
case 3:
return 11; break;
case 4:
return 14; break;
case 5:
return 15; break;
case 6:
return 16; break;
case 7:
return 17; break;
default:
return 19; break;
}
}
$obj_camps = json_decode(file_get_contents('generated_camps.json'));
$obj_players = json_decode(file_get_contents('generated_players.json'));
$id_camp = 1;
$id_map = 1;
$id_chal = 1;
foreach ($obj_camps as $camp_ind => &$camp) {
/*
file_put_contents('sql_campaign.sql',
"('" . str_replace("'", "''", $camp->name) . "', '" . $camp->url . "', '" .
str_replace("'", "''", $camp->author_name) . "', " . $camp->author_id . "),\n",
FILE_APPEND);
*/
foreach ($camp->maps as $map_ind => &$map) {
file_put_contents('sql_maps.sql',
"('" . str_replace("'", "''", $map->name) . "', " . $id_camp . "),\n",
FILE_APPEND);
foreach ($map->challenges as $chal_ind => &$chal) {
if (isset($chal->submissions) === false) {
continue;
}
file_put_contents('sql_chals.sql',
"(" . $id_map . ", 1, " . map_diff_id($chal) . ", " . json_encode($chal->requires_fc) .
", " . json_encode($chal->has_fc) . ", false),\n",
FILE_APPEND);
foreach ($chal->submissions as $sub_ind => &$sub) {
file_put_contents('sql_subs.sql',
"(" . $id_chal . ", " . $sub->player_id . ", '" . $sub->proof_url .
"', " . json_encode($sub->is_fc) . ")\n",
FILE_APPEND);
}
$id_chal += 1;
}
$id_map += 1;
}
$id_camp += 1;
}
foreach ($obj_players as $player_ind => &$player) {
file_put_contents('sql_player.sql',
"('" . str_replace("'", "''", $player) . "'),\n",
FILE_APPEND);
}

9
s_check_blanks.sh Normal file
View file

@ -0,0 +1,9 @@
#!/bin/sh
while read -r l; do
case "$l" in
*'"p"'*) p=1 ;;
*'"a"'*) p="" && continue ;;
*) [ -n "$p" ] && echo "$l" ;;
esac
done

7
s_check_pa.sh Normal file
View file

@ -0,0 +1,7 @@
#!/bin/sh
while read -r l; do
case "$l" in
*'"p": "'*) echo "$l" ;;
esac
done

28
s_fix_maps_links.sh Normal file
View file

@ -0,0 +1,28 @@
#!/bin/sh
set -euf
# bring content.json into this
old() {
while read -r line; do
case "$line" in
*/maps/*)
id=$(tr -Cd '[:digit:]' <<-EOF
$line
EOF
)
newurl=$(curl -Ls -o /dev/null -w %{url_effective} "https://gamebanana.com/maps/$id")
echo '"+@xlink:href": "'"$newurl"'",'
;;
*) echo "$line" ;;
esac
done
}
while read -r line; do
case "$line" in
*/maps/*) echo "$content" ;;
*+content*) content=$line ;;
*) ;;
esac
done

104
s_get_info.bash Normal file
View file

@ -0,0 +1,104 @@
#!/bin/bash
set -euf
# [ $# -lt 3 ] && echo "too little args. first is camp, 2nd map, 3rd challenge, 4th players, 5th submissions" && exit
tmp=$(mktemp)
trap 'rm "$tmp"' INT HUP QUIT TERM EXIT
subflag=""
campid=0
playerid=0
mapid=1
chalid=1
subid=0
SUBMISSION_FC=""
SUBMISSION_ANNOTATION=""
MAP_NAME=""
need_check() {
CAMP_NAME="CHECK_ME_PLEASE"
CAMP_UPLOADER="CHECK_ME_PLEASE"
CAMP_UPLOADER_ID="-1"
}
while read -r l; do
case "$l" in
CAMP_LINK*)
campid=$((campid + 1))
case "$l" in
*gamebanana.com*)
id=$(curl -Ls -o /dev/null -w %{url_effective} "${l#*=}" | tr -Cd '[:digit:]')
curl -s "https://api.gamebanana.com/Core/Item/Data?itemtype=Mod&itemid=${id}&fields=name,Owner().name,userid" > "$tmp"
echo "curl'd gamebanana, sleeping for 15"
sleep 15
CAMP_NAME=$(jq -r '.[0]' < "$tmp") && \
CAMP_UPLOADER=$(jq -r '.[1]' < "$tmp") && \
CAMP_UPLOADER_ID=$(jq -r '.[2]' < "$tmp") || \
need_check
# if author id doesn't exist in the author database, make it exist
if ! grep -qF -e "($CAMP_UPLOADER_ID," authors 2>/dev/null; then
printf "(%s, '%s'),\n" "$CAMP_UPLOADER_ID" "${CAMP_UPLOADER//\'/\'\'}" >> a_authors
fi
;;
*) need_check ;;
esac
# id, name, link, uploader_id
printf "(%s, '%s', '%s', %s),\n" \
"$campid" "${CAMP_NAME//\'/\'\'}" "${l#*=}" "${CAMP_UPLOADER_ID//\'/\'\'}" >> a_camps
;;
MAP_NAME*)
MAP_NAME=${l#*=}
;;
SUBMISSION_LINK*)
subid=$((subid+1))
SUBMISSION_LINK=${l#*=}
# if player doesn't exist, make player with new id that's 1 + highest id
if ! tmpid=$(grep -F -e ", '${SUBMISSION_NAME//\'/\'\'}')" a_players 2>/dev/null); then
if [ "$playerid" -gt 0 ]; then
playerid=$(tail -n 1 < a_players)
playerid=${playerid%%,*}
playerid=${playerid#"("}
playerid=$((playerid + 1))
else
playerid=1
fi
printf "(%s, '%s'),\n" \
"$playerid" "${SUBMISSION_NAME//\'/\'\'}" >> a_players
else
playerid=${tmpid%%,*}
playerid=${playerid#"("}
fi
# id, url, verified, fc, challenge id, player id
printf "(%s, '%s', %s, %s, %s, %s),\n" \
"$subid" "$SUBMISSION_LINK" TRUE "${SUBMISSION_FC:-FALSE}" \
"$chalid" "$playerid" >> a_submissions
SUBMISSION_FC=""
SUBMISSION_ANNOTATION=""
;;
SUBMISSION*|MAP_HAS*|MAP_REQUIRES*)
eval "${l%%=*}"'=${l#*=}'
;;
"")
[ -z "$MAP_NAME" ] && MAP_NAME=$CAMP_NAME
# id, name, campaign_id
printf "(%s, '%s', %s),\n" \
"$mapid" "${MAP_NAME//\'/\'\'}" "$campid" >> a_maps
# id, req_fc, has_fc, camp_id, map_id, obj_id, diff_id
printf "(%s, %s, %s, %s, %s, %s, %s),\n" \
"$chalid" "${MAP_REQUIRES_FC:-FALSE}" "${MAP_HAS_FC:-FALSE}" \
"$campid" "$mapid" 1 18 >> a_chals
echo "$CAMP_NAME - $MAP_NAME (by $CAMP_UPLOADER)"
MAP_HAS_FC=""
MAP_REQUIRES_FC=""
MAP_NAME=""
chalid=$((chalid+1))
mapid=$((mapid + 1))
;;
esac
done

77
s_map_get_people.bash Normal file
View file

@ -0,0 +1,77 @@
#!/bin/bash
while read -r l; do
l2="$l"
l="${l#*: \"}"
l="${l%\"*}"
l="${l//\\\"/\"}"
case "$l2" in
'"+@table:style-name": "ro'[0-9]*)
nextissub=""
nextismap=1
echo
;;
'"covered-table-cell"'*)
nextismap=""
nextissub=1
;;
'"+@xlink:href"'*)
if [ -n "$nextismap" ]; then
nextismap=""
nextissub=1
case "$oldl" in
*" [Full Clear]")
printf 'MAP_REQUIRES_FC=TRUE\n'
oldl=${oldl%" [Full Clear]"}
;;
esac
printf 'CAMP_NAME=%s\n' "$oldl"
printf 'CAMP_LINK=%s\n' "$l"
else
case "$oldl" in
*" [FC]")
printf 'SUBMISSION_FC=TRUE\n'
oldl=${oldl%" [FC]"}
;;
esac
printf 'SUBMISSION_NAME=%s\n' "$oldl"
printf 'SUBMISSION_LINK=%s\n' "$l"
fi
l2=${l}
;;
'"+content"'*)
if [ -n "$annotation" ]; then
if [ -n "$nextismap" ]; then
printf 'MAP_ANNOTATION=%s\n' "$l"
elif [ -n "$nextissub" ]; then
printf 'MAP_ANNOTATION=%s\n' "$l"
else
printf 'SUBMISSION_ANNOTATION=%s\n' "$l"
fi
annotation=""
fi
;;
'"p": "'*)
if [ -n "$nextissub" ]; then
case "$l" in
*" [Full Clear]")
printf 'MAP_REQUIRES_FC=TRUE\n'
l=${l%" [Full Clear]"}
;;
esac
printf 'MAP_NAME=%s\n' "$l"
nextissub=""
fi
;;
'"+@table:formula": '*)
nextissub=""
case "$l2" in
*'*[FC]*'*) printf 'MAP_HAS_FC=TRUE\n' ;;
*) : ;;
esac
;;
'"annotation"'*) annotation=1 ;;
'"a": {') nextissub="" ;;
esac
oldl="$l"
done

5
s_setup.sh Normal file
View file

@ -0,0 +1,5 @@
#!/bin/sh
unzip -d 'the' 'Custom Map Golden Strawberry List.ods'
cd the
yq-go -px -oj '.document-content.body.spreadsheet.table' < content.xml > content.json