To solve the given optimization problem, we first need to translate the natural language description into a symbolic representation. This involves defining variables, an objective function, and constraints based on the problem statement.

Given:
- The bakery produces two types of donuts: regular (x1) and jelly filled (x2).
- Profit per regular donut = $2.
- Profit per jelly filled donut = $4.
- Daily demand for regular donuts ≤ 100.
- Daily demand for jelly filled donuts ≤ 75.
- Total production capacity per day = 120 donuts.

### Symbolic Representation

Let's define the symbolic variables and the objective function, along with the constraints:

- **Variables**: 
  - x1: Number of regular donuts produced per day.
  - x2: Number of jelly filled donuts produced per day.

- **Objective Function**: Maximize profit = 2x1 + 4x2.

- **Constraints**:
  - x1 ≥ 0 (Non-negativity constraint for regular donuts).
  - x2 ≥ 0 (Non-negativity constraint for jelly filled donuts).
  - x1 ≤ 100 (Demand constraint for regular donuts).
  - x2 ≤ 75 (Demand constraint for jelly filled donuts).
  - x1 + x2 ≤ 120 (Total production capacity constraint).

### JSON Representation

```json
{
  'sym_variables': [('x1', 'regular donuts'), ('x2', 'jelly filled donuts')],
  'objective_function': 'Maximize 2*x1 + 4*x2',
  'constraints': [
    'x1 >= 0',
    'x2 >= 0',
    'x1 <= 100',
    'x2 <= 75',
    'x1 + x2 <= 120'
  ]
}
```

### Gurobi Code in Python

To solve this optimization problem using Gurobi, we'll use the following Python code:

```python
from gurobipy import *

# Create a new model
model = Model("Bakery_Optimization")

# Add variables to the model
x1 = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="regular_donuts")
x2 = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="jelly_filled_donuts")

# Set the objective function
model.setObjective(2*x1 + 4*x2, GRB.MAXIMIZE)

# Add constraints
model.addConstr(x1 <= 100, "regular_donut_demand")
model.addConstr(x2 <= 75, "jelly_filled_donut_demand")
model.addConstr(x1 + x2 <= 120, "total_production_capacity")

# Optimize the model
model.optimize()

# Print the solution
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Regular donuts to produce: {x1.x}")
    print(f"Jelly filled donuts to produce: {x2.x}")
    print(f"Maximum profit: ${model.objVal:.2f}")
else:
    print("No optimal solution found.")
```