diff --git a/README.md b/README.md index 0bd17a2..59690b6 100644 --- a/README.md +++ b/README.md @@ -245,23 +245,28 @@ scalp -i 330328 -s ![scalp logo](https://algolymp.ru/static/img/scalp.png) ## valeria -*Build valuer + scorer using Polygon API.* +*Build valuer + textable using Polygon API.* ### About 1. Get problem tests and groups; 2. Build and commit `valuer.cfg` (in Ejudge format); -3. Build and print `scoring.tex` (in Moscow summer olympiad school format). +3. Build and print `scoring.tex`. ~~Not very fast now, waiting for `absentInput` parameter in Polygon API.~~ Thanks to Mike, it's been working fast since 30.01.2024. +Valeria supports several textable types. + +- `universal` - Moscow summer olympiad school format. Works both in PDF and HTML. +- `moscow` - Moscow olympiads format. Works both in PDF and HTML if no variables are passed, otherwise works only in PDF. + ### Flags - `-i` - problem id (required) - `-v` - print valuer.cfg in stderr - `-t` - textable type (universal | moscow, default: universal) -- `-c` - depvars count, useful for some textables (default: 0) +- `-c` - variables list, useful for some textables (default: nil) ### Config - `polygon.url` @@ -275,6 +280,7 @@ valeria -i 288808 -v valeria -i 318511 > scoring.tex valeria -i 318882 | bat -l tex valeria -i 285375 -t moscow +valeria -i 285375 -t moscow -c n -c m -c k ``` ![valeria logo](https://algolymp.ru/static/img/valeria.png) diff --git a/cmd/valeria/main.go b/cmd/valeria/main.go index b31656d..fc8a9fa 100644 --- a/cmd/valeria/main.go +++ b/cmd/valeria/main.go @@ -23,7 +23,7 @@ var ( ) func main() { - parser := argparse.NewParser("valeria", "Build valuer + scorer using Polygon API.") + parser := argparse.NewParser("valeria", "Build valuer + textable using Polygon API.") pID := parser.Int("i", "problem_id", &argparse.Options{ Required: true, Help: "Polygon problem ID", @@ -40,10 +40,10 @@ func main() { Default: universalTag, Help: "Textable type", }) - cntVars := parser.Int("c", "count-depvars", &argparse.Options{ + vars := parser.StringList("c", "variable", &argparse.Options{ Required: false, - Default: 0, - Help: "Depvars count (useful for some textables)", + Default: nil, + Help: "Variables list (useful for some textables)", }) if err := parser.Parse(os.Args); err != nil { logrus.WithError(err).Fatal("bad arguments") @@ -53,13 +53,13 @@ func main() { pClient := polygon.NewPolygon(&cfg.Polygon) val := valeria.NewValeria(pClient) - logrus.WithFields(logrus.Fields{"type": *tableTyp, "vars": *cntVars}).Info("select textable") + logrus.WithFields(logrus.Fields{"type": *tableTyp, "vars": *vars}).Info("select textable") var table textables.Table switch *tableTyp { case universalTag: table = new(textables.UniversalTable) case moscowTag: - table = textables.NewMoscowTable(*cntVars) + table = textables.NewMoscowTable(*vars) } if table == nil { logrus.WithError(ErrUnknownTexTable).Fatal("failed to get textable") diff --git a/polygon/valeria/textables/moscow.go b/polygon/valeria/textables/moscow.go index 573b8ca..6a4aac5 100644 --- a/polygon/valeria/textables/moscow.go +++ b/polygon/valeria/textables/moscow.go @@ -5,18 +5,25 @@ import ( "strings" ) -// If cntVars != 0 works only in PDF render. +// If len(vars) != 0 works only in PDF render. // Otherwise works both in HTML and PDF render. type MoscowTable struct { - groups []string - cntVars int + groups []string + vars []string } +const clineDelta = 2 + var _ Table = &MoscowTable{} -func NewMoscowTable(cntVars int) *MoscowTable { +func NewMoscowTable(vars []string) *MoscowTable { + newVars := make([]string, 0, len(vars)) + for _, dv := range vars { + newVars = append(newVars, "$"+dv+"$") + } + return &MoscowTable{ - cntVars: cntVars, + vars: newVars, } } @@ -25,7 +32,12 @@ func (t *MoscowTable) AddGroup(info GroupInfo) { if info.Type == Group0 { comment = "Тесты из условия." } - row := fmt.Sprintf("%s & %d & %s & %s & %s \\\\ \\hline", + if len(t.vars) > 0 { + limits = strings.Repeat(" & ", len(t.vars)) + } else { + limits = " & " + } + row := fmt.Sprintf("%s & %d & %s%s & %s \\\\ \\hline", info.Name, info.Score, limits, @@ -39,16 +51,31 @@ func (t *MoscowTable) String() string { table := []string{ "\\begin{center}", "\\renewcommand{\\arraystretch}{1.5}", - "\\begin{tabular}{|c|c|c|c|c|}", - "\\hline", - "Группа", - "& Баллы", - "& Доп. ограничения", - "& Необх. группы", - "& Комментарий", - "\\\\", - "\\hline", } + if len(t.vars) > 0 { + table = append(table, + fmt.Sprintf("\\begin{tabular}{|c|c|%sc|c|}", strings.Repeat("c|", len(t.vars))), + "\\hline", + fmt.Sprintf("& & \\multicolumn{%d}{c|}{Доп. ограничения} & & \\\\", len(t.vars)), + fmt.Sprintf("\\cline{3-%d}", len(t.vars)+clineDelta), + "\\raisebox{2.25ex}[0cm][0cm]{Группа}", + "& \\raisebox{2.25ex}[0cm][0cm]{Баллы}", + "& "+strings.Join(t.vars, " & "), + "& \\raisebox{2.25ex}[0cm][0cm]{Необх. группы}", + "& \\raisebox{2.25ex}[0cm][0cm]{Комментарий}", + ) + } else { + table = append(table, + "\\begin{tabular}{|c|c|c|c|c|}", + "\\hline", + "Группа", + "& Баллы", + "& Доп. ограничения", + "& Необх. группы", + "& Комментарий", + ) + } + table = append(table, "\\\\", "\\hline") table = append(table, t.groups...) table = append(table, "\\end{tabular}", "\\end{center}")