Skip to content

Contest schema#

contest.rbx.yml#

Contest #

Bases: BaseModel

Parameters:

Name Type Description Default
name str

Name of this contest.

required
problems List[ContestProblem]

List of problems in this contest.

[]
statements List[ContestStatement]

Configure statements in this contest, per language.

None
vars Dict[str, Union[str, int, float, bool]]

Variables to be re-used across the package.

{}
Source code in rbx/box/contest/schema.py
class Contest(BaseModel):
    model_config = ConfigDict(extra='forbid')

    name: str = NameField(description='Name of this contest.')

    problems: List[ContestProblem] = Field(
        default=[], description='List of problems in this contest.'
    )

    statements: Annotated[
        List[ContestStatement],
        AfterValidator(is_unique_by_name),
    ] = Field(
        default=None,
        description='Configure statements in this contest, per language.',
    )

    # Vars to be re-used in the statements.
    #   - It will be available as \VAR{vars} variable in the contest-level box statement.
    vars: Dict[str, Primitive] = Field(
        default={}, description='Variables to be re-used across the package.'
    )

    @property
    def expanded_statements(self) -> List[ContestStatement]:
        return expand_statements(self.statements)

    @property
    def expanded_vars(self) -> Dict[str, Primitive]:
        return {key: expand_var(value) for key, value in self.vars.items()}

ContestProblem #

Bases: BaseModel

Parameters:

Name Type Description Default
short_name str

Short name of the problem. Usually, just an uppercase letter, but can be a sequence of uppercase letters followed by a number.

required
path Path | None

Path to the problem relative to the contest package directory. If not specified, will expect the problem to be in ./{short_name}/ folder.

None
color str | None

Color that represents this problem in the contest.

Can be a hex color (#abcdef or #abc format), or a color name among available X11 colors.

See https://en.wikipedia.org/wiki/X11_color_names for the list of supported color names.

None
colorName str | None

A custom color name for the color provided by this problem.

If not provided, will try to infer a color name from the color provided.

None
Source code in rbx/box/contest/schema.py
class ContestProblem(BaseModel):
    short_name: str = ShortNameField(
        description="""
Short name of the problem. Usually, just an uppercase letter,
but can be a sequence of uppercase letters followed by a number."""
    )
    path: Optional[pathlib.Path] = Field(
        default=None,
        description="""
Path to the problem relative to the contest package directory.
If not specified, will expect the problem to be in ./{short_name}/ folder.""",
    )

    color: Optional[str] = Field(
        default=None,
        description="""
Color that represents this problem in the contest.

Can be a hex color (#abcdef or #abc format), or a color name among available X11 colors.

See https://en.wikipedia.org/wiki/X11_color_names for the list of supported color names.
""",
    )

    colorName: Optional[str] = Field(
        default=None,
        description="""
A custom color name for the color provided by this problem.

If not provided, will try to infer a color name from the color provided.
""",
        pattern=r'^[a-zA-Z]+$',
    )

    @model_validator(mode='after')
    def check_color(self):
        from colour import Color

        if self.color is None:
            return self

        Color(self.color)
        return self

    @property
    def hex_color(self) -> Optional[str]:
        from colour import Color

        if self.color is None:
            return None

        return Color(self.color).hex_l

    @property
    def color_name(self) -> Optional[str]:
        if self.colorName is not None:
            return self.colorName

        if self.color is None:
            return None

        from colour import Color

        color = Color(self.color)
        web_color = color.web
        if web_color.startswith('#'):
            return 'unknown'
        return web_color

    def get_path(self) -> pathlib.Path:
        return self.path or pathlib.Path(self.short_name)

ContestStatement #

Bases: BaseModel

Parameters:

Name Type Description Default
name str

Name of this statement.

required
extends str | None

Name of the statement to inherit from.

None
language str

Language code for this statement (ISO 639-1).

'en'
title str

Title of the contest in this language.

''
location str | None

Location of the contest in this language.

None
date str | None

Date of the contest in this language.

None
path Path

Path to the input statement file.

<dynamic>
type StatementType

Type of the input statement file.

rbxTeX
joiner JoinTexToPDF | None

Joiner to be used to build the statement.

This determines how problem statements will be joined into a single contest statement.

None
steps List[Union[TexToPDF, JinjaTeX, rbxToTeX]]

Describes a sequence of conversion steps that should be applied to the statement file of this contest.

Usually, it is not necessary to specify these, as they can be inferred from the input statement type and the output statement type, but you can use this to force certain conversion steps to happen.

[]
configure List[Union[TexToPDF, JinjaTeX, rbxToTeX]]

Configure how certain conversion steps should happen when applied to the statement file of this contest.

Different from the steps field, this does not force the steps to happen, but rather only configure them in case they are applied.

[]
assets List[str]

Assets relative to the contest directory that should be included while building the statement. Files will be included in the same folder as the statement file. Can be glob pattern as well, such as imgs/*.png.

[]
override ProblemStatementOverride | None

Override configuration for problem statements.

None
match str | None

Name of the problem-level statement to match this statement against.

If not specified, will match against the first statement of the same language.

None
vars Dict[str, Union[str, int, float, bool]]

Variables to be re-used across the package.

{}
Source code in rbx/box/contest/schema.py
class ContestStatement(BaseModel):
    model_config = ConfigDict(extra='forbid')

    name: str = FNameField(description='Name of this statement.')

    extends: Optional[str] = FNameField(
        default=None, description='Name of the statement to inherit from.'
    )

    language: StatementLanguage = Field(
        default='en', description='Language code for this statement (ISO 639-1).'
    )

    title: str = Field(default='', description='Title of the contest in this language.')

    location: Optional[str] = Field(
        default=None, description='Location of the contest in this language.'
    )

    date: Optional[str] = Field(
        default=None, description='Date of the contest in this language.'
    )

    path: pathlib.Path = Field(
        default_factory=pathlib.Path,
        description='Path to the input statement file.',
    )

    type: StatementType = Field(
        default=StatementType.rbxTeX, description='Type of the input statement file.'
    )

    joiner: Optional[Joiner] = Field(
        default=None,
        description="""
Joiner to be used to build the statement.

This determines how problem statements will be joined into a single contest statement.""",
    )

    steps: List[ConversionStep] = Field(
        default=[],
        discriminator='type',
        description="""
Describes a sequence of conversion steps that should be applied to the statement file
of this contest.

Usually, it is not necessary to specify these, as they can be inferred from the
input statement type and the output statement type, but you can use this to force
certain conversion steps to happen.
""",
    )

    configure: List[ConversionStep] = Field(
        default=[],
        discriminator='type',
        description="""
Configure how certain conversion steps should happen when applied to the statement file of
this contest.

Different from the `steps` field, this does not force the steps to happen, but rather only
configure them in case they are applied.
""",
    )

    assets: List[str] = Field(
        default=[],
        description="""
Assets relative to the contest directory that should be included while building
the statement. Files will be included in the same folder as the statement file.
Can be glob pattern as well, such as `imgs/*.png`.
""",
    )

    override: Optional[ProblemStatementOverride] = Field(
        default=None, description='Override configuration for problem statements.'
    )

    match: Optional[str] = FNameField(
        default=None,
        description="""
        Name of the problem-level statement to match this statement against.

        If not specified, will match against the first statement of the same language.
        """,
    )

    # Vars to be re-used in the statement.
    #   - It will be available as \VAR{vars} variable in the contest-level box statement.
    vars: Dict[str, Primitive] = Field(
        default={}, description='Variables to be re-used across the package.'
    )

    @property
    def expanded_vars(self) -> Dict[str, Primitive]:
        return {key: expand_var(value) for key, value in self.vars.items()}

ProblemStatementOverride #

Bases: BaseModel

Parameters:

Name Type Description Default
configure List[Union[TexToPDF, JinjaTeX, rbxToTeX]]

Configure how certain conversion steps should happen when applied to the statement file.

Different from the steps field, this does not force the steps to happen, but rather only configure them in case they are applied.

[]
vars Dict[str, Union[str, int, float, bool]]

Variables to be merged into the problem statement vars.

{}
Source code in rbx/box/contest/schema.py
class ProblemStatementOverride(BaseModel):
    model_config = ConfigDict(extra='forbid')

    configure: List[ConversionStep] = Field(
        default=[],
        discriminator='type',
        description="""
Configure how certain conversion steps should happen when applied to the statement file.

Different from the `steps` field, this does not force the steps to happen, but rather only
configure them in case they are applied.
""",
    )

    vars: Dict[str, Primitive] = Field(
        default={},
        description='Variables to be merged into the problem statement vars.',
    )