prochitecture / pml

Translator for PML (Prochitecture Markup Language)
2 stars 0 forks source link

"Decorators" for style blocks #15

Open vvoovv opened 1 year ago

vvoovv commented 1 year ago

There is a concept of defName and use in PML.

I'd like mark that syntax visually in a PML text. That could like a decorator in Python. Once that's implemented, the attributes defName and use inside the curly brackets of a style block won't be processed in any special way.

A proposed syntax:

@define: styleBlock1
facade {
    claddingColor: green;
}

@use: styleBlock1
@use: styleBlock2
facade {
}

The current mapping of define and use to the Python syntax should be preserved.

To be continued in the next message.

vvoovv commented 1 year ago

The will be at least one more decorator.

@setup
facade {
    claddingColor: green;
}

It should be mapped to

Facade(setup=True, ...)
vvoovv commented 1 year ago

How straightforward would it be to implement that new syntax?

polarkernel commented 1 year ago

I am sorry, it's too long since I developed PML. I have some questions for my understanding:

There is a concept of defName and use in PML.

I can't remember this concept. Do we have somewhere a thread/issue, where we discussed that?

I'd like mark that syntax visually in a PML text. That could like a decorator in Python. Once that's implemented, the attributes defName and use inside the curly brackets of a style block won't be processed in any special way.

I can't understand this part, maybe it's too short. I know Python's decorator concept, but can't translate it to this case.

vvoovv commented 1 year ago

There is only a visual similarity between this concept and Python's decorator concept, e.g. an additional syntax before the main syntax.

Attributes defined in a style block with the attribute defName are copied to a style block with the attribute use and its value equal to the value of the attribute defName.

Example:

The PML text

facade{
    defName: styleBlock1;
    claddingColor: blue;
}

facade{
    use: styleBlock1;
}

is translated to

styles = [
    Facade(
        defName = "styleBlock1",
        claddingColor = (0.0, 0.0, 1.0, 1.0)
    ),
    Facade(
        use = ("styleBlock1",)
    )
]

The attribute claddingColor will be copied from the upper style block Facade to the lower one.

polarkernel commented 1 year ago

The attribute claddingColor will be copied from the upper style block Facade to the lower one.

OK, got it and found also the correspondence in the grammar. Now applied to your (extended) example:

@define: styleBlock1
facade {
    claddingColor: green;
}

@define: styleBlock2
facade {
    symmetry : middle-of-last;
    symmetryFlip : true;
}

@use: styleBlock1
@use: styleBlock2
facade {
}

I assume, in this case, @define means all the attributes of the element facade. So that the result becomes something like

styles = [
    Facade(
        claddingColor = (0.0, 1.0, 0.0, 1.0),
        symmetry = symmetry.Middle-of-last,
        symmetryFlip = True
    )
]

Is this the meaning of your idea?

vvoovv commented 1 year ago

I assume, in this case, @define means all the attributes of the element facade. So that the result becomes something like

It means: define the style block with the name styleBlock1. The name styleBlock1 can be then referenced by a use clause.

In other words, the attributes defName and use will be moved out of style blocks to the slots just before the style blocks. The word define will be used instead of defName.

All processing (i.e. copying the attributes) is already available in the addon code.

I'd like to know if it will be straightforward to implement.

polarkernel commented 1 year ago

I'd like to know if it will be straightforward to implement.

The simplest way for me to answer this question is an example, where I can see the PML code and the desired resulting Python code. As far as I understand it until now, it should be easy to implement.

vvoovv commented 1 year ago

Input:

@setup
roadway {
    oneway: attr("oneway");
}

@define: styleBlock1
facade {
    claddingColor: green;
}

@define: styleBlock2
facade {
    symmetry : middle-of-last;
    symmetryFlip : true;
}

@use: styleBlock1
facade {
}

@use: styleBlock1
@use: styleBlock2
facade {
}
vvoovv commented 1 year ago

Output:

styles = [
    Roadway(
        setup = True,
        oneway = Value(FromAttr("oneway", FromAttr.String))
    ),
    Facade(
        defName = "styleBlock1",
        claddingColor = (0.0, 0.502, 0.0, 1.0)
    ),
    Facade(
        defName = "styleBlock2",
        symmetry = symmetry.Middle-of-last,
        symmetryFlip = True
    ),
    Facade(
        use = ("styleBlock1",)
    ),
    Facade(
        use = ("styleBlock1","styleBlock2",)
    )
]
vvoovv commented 1 year ago

The output will have only one change and that if the clause @setup is present:

setup = True
polarkernel commented 1 year ago

Input: Output:

Great, now I got it. Should be feasible, not as simple, as I first thought, because the tokens @define, @use and @setup have to be memorized and then triggered, when the process is within the element. But this can be done in any case.

vvoovv commented 1 year ago

I will continue for now with the existing solution. We can return to this task later, once there is a progress with the street generation.

vvoovv commented 1 year ago

Would both syntaxes work?

@setup
roadway {
    oneway: attr("oneway");
}
@setup: some_name
roadway {
    oneway: attr("oneway");
}

I.e. the setup without a value and the setup with a value

polarkernel commented 1 year ago

Would both syntaxes work?

Roadway(
setup = True,
oneway = Value(FromAttr("oneway", FromAttr.String))
),

in the first case, and

    Roadway(
        setup = "some_name",
        oneway = Value(FromAttr("oneway", FromAttr.String))
    ),

in the second?

Yes, that should work.

vvoovv commented 1 year ago

Yes, that should work.

Yes, that what I meant.

vvoovv commented 1 year ago
    Roadway(
        setup = True,
        oneway = Value(FromAttr("oneway", FromAttr.String))
    ),

In the first style block it should be setup = '' (an empty string) for consistency:

    Roadway(
        setup = '',
        oneway = Value(FromAttr("oneway", FromAttr.String))
    ),