Content in the file dependent on file it's included from

As @Lutz_Hendricks says the preferred method depends on the structure of data.typ, but here are some solutions I can think of:

  1. Define a function in data.typ that returns the desired data:

    data.typ:

    #let get-data(type) = [
      Content for all variants
    
      #if type == 1 [
        Content for variant 1
      ]
    
      #if type == 2 [
        Content for variant 2
      ]
    ]
    

    variant1.typ:

    #import "data.typ": get-data
    #get-data(1)
    

    Advantage: clear and robust. No significant disadvantage in my opinion.

  2. Define structured data in data.typ and import it as a variable:

    data.typ:

    #let data = (
     (type: "all", value: [Content for all variants]),
     (type: 1, value: [Content for variant 1]),
     (type: 2, value: [Content for variant 2]),
    )
    

    variant1.typ:

    #import "data.typ": data
    #{
      data.filter(x => x.type in (1, "all"))
          .map(x => x.value).join(parbreak())
    }
    

    Advantage: data is declarative, you can have different/complicated selection logic in different variant files.

    Disadvantage: heavy syntax in data.typ, more complicated to use in variant files.

  3. Set a state in variant files, and use it in data.typ:

    variant1.typ:

    #state("data-type").update(1)
    
    #include "data.typ"
    

    data.typ:

    #context [
      #let data-type = state("data-type").get()
    
      Content for all variants
    
      #if data-type == 1 [
        Content for variant 1
      ]
    
      #if data-type == 2 [
        Content for variant 2
      ]
    ]
    

    Advantage: might feel familiar if you’re used to global variables, and the state can be accessed from any content in any file without having to import a function or variable definition.

    Disadvantage: makes the content opaque (you cannot see what’s in a context value), and using a global state without explicit import/include can make the code harder to understand. Also, states are a bit tricky and can be surprising sometimes, see for example here: Why doesn't state behave like the documentation says?

  4. Use labels and show rules:

    data.typ:

    Content for all variants
    
    #[Content for variant 1]<only1>
    
    #[Content for variant 2]<only2>
    

    variant1.typ:

    #show <only2>: none
    
    #include "data.typ"
    

    Advantage: lightweight, declarative syntax so the selection logic can be separated from the data.

    Disadvantage: can interfere with other functionality:

    • A piece of content can only have a single label and you might want to use it for something else.
    • Content “discarded” with #show ...: none is only hidden from the output, it’s still there in the document and can show up in query results.
2 Likes