Skip to content

Commit

Permalink
Internal: Introduce ViewCommand
Browse files Browse the repository at this point in the history
ViewCommand reconfigures SearchViewCommand.
  • Loading branch information
kohler committed Oct 6, 2024
1 parent 184ae6c commit c88e4af
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 274 deletions.
2 changes: 1 addition & 1 deletion batch/makedist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@ src/searchoperatorset.php
src/searchparser.php
src/searchselection.php
src/searchterm.php
src/searchviewcommand.php
src/searchword.php
src/sessionlist.php
src/settinginfoset.php
Expand Down Expand Up @@ -537,6 +536,7 @@ src/useractions.php
src/userinfo/u_developer.php
src/userinfo/u_security.php
src/userstatus.php
src/viewcommand.php
src/xtparams.php
devel/hotcrp.vim
Expand Down
8 changes: 4 additions & 4 deletions lib/scoreinfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ class ScoreInfo {
static private $score_sorts = [
"counts", "average", "median", "variance", "maxmin", "my"
];
static private $score_sort_parser = "0 C 0 M 0 count 0 counts 1 A 1 average 1 avg 1 av 1 ave 2 E 2 median 2 med 3 V 3 variance 3 var 4 D 4 maxmin 4 max-min 5 Y 5 my 5 myscore ";
static private $score_sort_parser = "0 C,0 M,0 count,0 counts,1 A,1 average,1 avg,1 av,1 ave,2 E,2 median,2 med,3 V,3 variance,3 var,4 D,4 maxmin,4 max-min,5 Y,5 my,5 myscore,";

/** @param string $x
/** @param ?string $x
* @return null|'count'|'average'|'median'|'variance'|'maxmin'|'my' */
static function parse_score_sort($x) {
if (in_array($x, self::$score_sorts)) {
if ($x === null || in_array($x, self::$score_sorts)) {
return $x;
} else if (($p = strpos(self::$score_sort_parser, " {$x} ")) !== false
} else if (($p = strpos(self::$score_sort_parser, " {$x},")) !== false
&& strpos($x, " ") === false) {
return self::$score_sorts[(int) self::$score_sort_parser[$p - 1]];
} else {
Expand Down
93 changes: 43 additions & 50 deletions src/paperlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ function __construct(string $report, PaperSearch $search, $args = [], $qreq = nu
$this->_highlight_map = $this->search->highlights_by_paper_id();
}
foreach ($this->search->view_commands() as $svc) {
if (($show_action = $svc->show_action())) {
$this->set_view($svc->keyword, $show_action, self::VIEWORIGIN_SEARCH, $svc->decorations);
if (!$svc->is_sort()) {
$this->set_view($svc->keyword, $svc->is_show(), self::VIEWORIGIN_SEARCH, $svc->decorations);
}
}

Expand Down Expand Up @@ -698,21 +698,17 @@ private function _append_sortcol($col, $origin) {
array_splice($this->_sort_origin, $i, 0, [$origin]);
}

/** @param string $k
* @param 0|1|2|3|4|5 $origin
* @param ?list<string> $decorations
* @param ?list<int> $sort_subset
* @param ?int $pos1
* @param ?int $pos2 */
private function _add_sorter($k, $origin, $decorations,
$sort_subset, $pos1, $pos2) {
// `sort:score` is a special case.
if ($k === "score") {
$flags = &$this->_viewf[$k];
/** @param ViewCommand $svc
* @param ?list<int> $sort_subset */
private function _add_sorter($svc, $sort_subset) {
$origin = $svc->flags >> ViewCommand::ORIGIN_SHIFT;

// `sort:score` is a special case
if ($svc->keyword === "score") {
$flags = &$this->_viewf[$svc->keyword];
$flags = $flags ?? 0;
if (($flags & self::VIEW_ORIGINMASK) <= $origin
&& !empty($decorations)
&& ($x = ScoreInfo::parse_score_sort($decorations[0])) !== null) {
&& ($x = ScoreInfo::parse_score_sort($svc->decoration(0))) !== null) {
$flags = ($flags & ~self::VIEW_ORIGINMASK) | $origin;
$this->_score_sort = $x;
}
Expand All @@ -722,48 +718,45 @@ private function _add_sorter($k, $origin, $decorations,
assert($this->_sortcol_fixed < 2);
// Do not use ensure_columns_by_name(), because decorations for sorters
// might differ.
$fs = $this->conf->paper_columns($k, $this->xtp);
$mi = null;
$fs = $this->conf->paper_columns($svc->keyword, $this->xtp);
if (count($fs) === 1) {
$col = PaperColumn::make($this->conf, $fs[0])->add_decorations($decorations);
$col = PaperColumn::make($this->conf, $fs[0])->add_decorations($svc->decorations);
if ($col->prepare($this, PaperColumn::PREP_SORT)
&& $col->sort) {
$col->sort_subset = $sort_subset;
$this->_append_sortcol($col, $origin);
} else {
$mi = $this->search->warning("<0>‘{$k}’ cannot be sorted");
return;
}
} else if (empty($fs)) {
}

// Warn on failure
$warning = "<0>‘{$svc->keyword}’ cannot be sorted";
if (empty($fs)) {
if ($this->user->can_view_tags(null)
&& ($tagger = new Tagger($this->user))
&& ($tag = $tagger->check($k))
&& ($tag = $tagger->check($svc->keyword))
&& ($ps = new PaperSearch($this->user, ["q" => "#{$tag}", "t" => "vis"]))
&& $ps->paper_ids()) {
$mi = $this->search->warning("<0>‘{$k}’ cannot be sorted; did you mean “sort:#{$k}”?");
} else {
$mi = $this->search->warning("<0>‘{$k}’ cannot be sorted");
$warning = "<0>‘{$svc->keyword}’ cannot be sorted; did you mean “sort:#{$tag}”?";
}
} else {
$mi = $this->search->warning("<0>Sort ‘{$k}’ is ambiguous");
} else if (count($fs) > 1) {
$warning = "<0>Sort ‘{$svc->keyword}’ is ambiguous";
}
if ($mi) {
$mi->pos1 = $pos1;
$mi->pos2 = $pos2;
$mi->context = $this->search->q;
if ($svc->sword) {
$this->search->lwarning($svc->sword, $warning);
} else {
$this->search->warning($warning);
}
}

/** @param ?string $str
* @param 0|1|2|3|4|5 $origin */
function parse_view($str, $origin) {
$groups = SearchParser::split_balanced_parens($str ?? "");
foreach (SearchViewCommand::analyze($groups) as $sve) {
if (($show_action = $sve->show_action())) {
$this->set_view($sve->keyword, $show_action, $origin, $sve->decorations);
}
if ($sve->sort_action()) {
$this->_add_sorter($sve->keyword, $origin, $sve->decorations,
null, $sve->pos1, $sve->pos2);
foreach (ViewCommand::split_parse($str ?? "", $origin << ViewCommand::ORIGIN_SHIFT) as $svc) {
if ($svc->is_sort()) {
$this->_add_sorter($svc, null);
} else {
$this->set_view($svc->keyword, $svc->is_show(), $origin, $svc->decorations);
}
}
}
Expand Down Expand Up @@ -831,8 +824,8 @@ function unparse_view($base_origin = self::VIEWORIGIN_NONE, $include_sort = true
}
}
$key = "{$pos} {$name}";
$kw = $v >= self::VIEW_SHOW ? "show" : "hide";
$res[$key] = PaperSearch::unparse_view($kw, $name, $this->_view_decorations[$name] ?? null);
$flags = $v >= self::VIEW_SHOW ? ViewCommand::F_SHOW : ViewCommand::F_HIDE;
$res[$key] = (new ViewCommand($flags, $name, $this->_view_decorations[$name] ?? null))->unparse();
}
if (((($this->_viewf["anonau"] ?? 0) >= self::VIEW_SHOW && $this->conf->submission_blindness() == Conf::BLIND_OPTIONAL)
|| ($this->_viewf["aufull"] ?? 0) >= self::VIEW_SHOW)
Expand All @@ -848,7 +841,7 @@ function unparse_view($base_origin = self::VIEWORIGIN_NONE, $include_sort = true
if ($this->_sort_origin[$i] <= $base_origin) {
break;
}
$res[] = PaperSearch::unparse_view("sort", $s->name, $s->decorations());
$res[] = (new ViewCommand(ViewCommand::F_SORT, $s->name, $s->decorations()))->unparse();
if ($s->name === "id") {
break;
}
Expand All @@ -861,7 +854,7 @@ function unparse_view($base_origin = self::VIEWORIGIN_NONE, $include_sort = true
// score sort
if ($this->_score_sort
&& ($base_origin < 0 || $this->_score_sort !== self::default_score_sort($this->conf))) {
$res[] = PaperSearch::unparse_view("sort", "score", [$this->_score_sort]);
$res[] = (new ViewCommand(ViewCommand::F_SORT, "score", [$this->_score_sort]))->unparse();
}

return $res;
Expand Down Expand Up @@ -916,10 +909,9 @@ function _then_sort_compare($a, $b) {
/** @param ?list<int> $sort_subset */
private function _add_search_sorters(SearchTerm $qe, $sort_subset) {
$nsortcol = count($this->_sortcol);
foreach ($qe->view_commands() as $sve) {
if ($sve->sort_action()) {
$this->_add_sorter($sve->keyword, PaperList::VIEWORIGIN_SEARCH, $sve->decorations, $sort_subset, $sve->pos1, $sve->pos2);
}
foreach ($qe->view_commands() as $svc) {
if ($svc->is_sort())
$this->_add_sorter($svc, $sort_subset);
}
if (count($this->_sortcol) === $nsortcol
&& ($dspc = $qe->default_sort_column(true, $this))
Expand Down Expand Up @@ -1230,11 +1222,12 @@ function column_error($message) {
$mi = $message;
}
if (($sve = $this->search->main_term()->find_view_command($name))
&& $sve->sword
&& ($mi->status !== MessageSet::INFORM || empty($this->_finding_column_errors))) {
if ($mi->pos1 !== null) {
$mis = $this->search->expand_message_context($mi, $mi->pos1 + $sve->pos1, $mi->pos2 + $sve->pos1, $sve->string_context);
$mis = $this->search->expand_message_context($mi, $mi->pos1 + $sve->sword->pos1, $mi->pos2 + $sve->sword->pos1, $sve->sword->string_context);
} else {
$mis = $this->search->expand_message_context($mi, $sve->kwpos1, $sve->pos2, $sve->string_context);
$mis = $this->search->expand_message_context($mi, $sve->sword->kwpos1, $sve->sword->pos2, $sve->sword->string_context);
}
} else {
$mis = [$mi];
Expand Down Expand Up @@ -2153,7 +2146,7 @@ private function _table_render() {
$this->table_attr["data-search-params"] = $this->encoded_search_params();
$views = [];
foreach ($this->search->view_commands() as $svc) {
$views[] = $svc->command;
$views[] = $svc->unparse();
}
if (!empty($views)) {
$this->table_attr["data-search-view"] = join(" ", $views);
Expand Down
32 changes: 3 additions & 29 deletions src/papersearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -1277,33 +1277,7 @@ function highlights_by_paper_id() {
return $this->_highlight_map;
}

/** @param iterable<string>|iterable<array{string,?int,?int,?int,?SearchStringContext}> $words
* @return list<SearchViewCommand>
* @deprecated */
static function view_generator($words) {
return SearchViewCommand::analyze($words);
}

/** @param string|bool $action
* @param string $keyword
* @param ?list<string> $decorations
* @return string */
static function unparse_view($action, $keyword, $decorations) {
if (is_bool($action)) {
$action = $action ? "show" : "hide";
}
if (!ctype_alnum($keyword)
&& SearchParser::span_balanced_parens($keyword) !== strlen($keyword)) {
$keyword = "\"" . $keyword . "\"";
}
if ($decorations) {
return "{$action}:{$keyword}[" . join(" ", $decorations) . "]";
} else {
return "{$action}:{$keyword}";
}
}

/** @return list<SearchViewCommand> */
/** @return list<ViewCommand> */
function view_commands() {
return $this->main_term()->view_commands();
}
Expand All @@ -1312,7 +1286,7 @@ function view_commands() {
private function sort_field_list() {
$r = [];
foreach ($this->main_term()->view_commands() as $svc) {
if ($svc->sort_action())
if ($svc->is_sort())
$r[] = $svc->keyword;
}
return $r;
Expand Down Expand Up @@ -1518,7 +1492,7 @@ function highlight_tags() {
$ht = $this->main_term()->get_float("tags") ?? [];
$tagger = null;
foreach ($this->sort_field_list() as $s) {
if (preg_match('/\A(?:#|tag:\s*|tagval:\s*)(\S+)\z/', $s, $m)) {
if (preg_match('/\A(?:\#|tag:\s*|tagval:\s*)(\S+)\z/', $s, $m)) {
$tagger = $tagger ?? new Tagger($this->user);
if (($tag = $tagger->check($m[1]))) {
$ht[] = $tag;
Expand Down
6 changes: 3 additions & 3 deletions src/reviewform.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ function highlighted_main_scores() {
return $f ? [$f] : [];
}
$fs = [];
foreach (SearchViewCommand::analyze(SearchParser::split_balanced_parens($s)) as $sve) {
if ($sve->show_action() === "show"
&& ($x = $this->conf->find_all_fields($sve->keyword))
foreach (ViewCommand::split_parse($s, 0) as $svc) {
if ($svc->is_show()
&& ($x = $this->conf->find_all_fields($svc->keyword))
&& count($x) === 1
&& $x[0] instanceof Score_ReviewField
&& $x[0]->view_score >= VIEWSCORE_PC
Expand Down
16 changes: 7 additions & 9 deletions src/searchterm.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,19 @@ final function negate_if($negate) {
* @param SearchWord $sword
* @return $this */
final function add_view_anno($command, $sword) {
$this->float["view"][] = new SearchViewCommand($command, $sword);
foreach (ViewCommand::parse($command, ViewCommand::ORIGIN_SEARCH, $sword) as $svc) {
$this->float["view"][] = $svc;
}
return $this;
}

/** @return list<SearchViewCommand> */
/** @return list<ViewCommand> */
final function view_commands() {
$v = $this->float["view"] ?? [];
if (!empty($v)) {
$v = SearchViewCommand::analyze($v);
}
return $v;
return $this->float["view"] ?? [];
}

/** @param string $field
* @return ?SearchViewCommand */
* @return ?ViewCommand */
final function find_view_command($field) {
foreach ($this->view_commands() as $svc) {
if ($svc->keyword === $field)
Expand Down Expand Up @@ -386,7 +384,7 @@ protected function append_in($term, $context) {
foreach ($term->float as $k => $v) {
if ($k === "view") {
if ($this->type === "then") {
$v = SearchViewCommand::strip_sorts($v);
$v = ViewCommand::strip_sorts($v);
}
$this->float[$k] = array_merge($this->float[$k] ?? [], $v);
} else if ($k === "tags") {
Expand Down
Loading

0 comments on commit c88e4af

Please sign in to comment.