MFL · Chuleta de referencia v1

Manual completo Editor MFL

MFL — MuebleLab Furniture Language

Castellano o inglés (mezclables) · indentación significativa · `=` asigna · `..` rango

Estructura

mueble nombre
  # dimensiones, materiales, zócalo, patas...
  distribucion
    # grid + asignaciones
  zona A1..A3 puerta
    # overlay (opcional)
  montaje
    # pendiente

Indentación 2 espacios. Comentarios con #.

Dimensiones (obligatorias)

anchomm — anchura
altomm — altura
fondomm — profundidad
grosormm — tablero (defecto 19)

Materiales

tablero <color/textura>carcasa
frente <color/textura>puertas/cajones
canto fino|grueso0.4mm o 2mm ABS
trasera fino|tablero|ranurartipo de fondo (también acepta ranurado)

Texturas: roble · pino · haya · nogal. Colores hex: #1a1a1a o nombres (blanco, negro...). Los hex #XXXXXX NO se confunden con comentarios.

Patas (sintaxis homogénea)

patas 4
  alto       = 120
  grueso     = 40
  retranqueo = 50
  anclaje    = inserto     # tornillo|inserto|pegado

Anclaje: tornillo (4 tornillos por pata, defecto), inserto (rosca M6 + tornillo M6×40, típico de tarugo), pegado (sin tornillería). Sintaxis vieja sigue funcionando: altura-patas, grosor-patas...

Ruedas, zócalo, coronación

ruedas 4
zocalo 80
  retranqueo = 60
  lateral    = 30
  trasero    = 0
coronacion 60

Cada bloque acepta valor inline (cantidad/altura) y props anidadas. Para desactivar: zocalo no.

Paneles opcionales

sin-lateral-izq siquita el lateral izquierdo
sin-lateral-dcha siquita el lateral derecho
sin-techo sisin tablero superior
sin-suelo sisin tablero inferior

Cornisa decorativa

cornisa
  alto     = 35
  perfil   = escalon
  voladizo = 10

Perfiles: escalon · recto · redondo · curvo · corona · gola. Se cuenta por metros lineales en el despiece. Hardware: clavillos pin 1mm + tornillos ocultos + cola blanca. Forma corta: cornisa 30.

Marco frontal (vitrina/alacena)

# tablero superior + holguras entre puertas y laterales
marco
  superior = 80
  entre    = 4
  lateral  = 4

Fuerza puertas encastradas automáticamente. Tablero superior aparece en despiece + 4 confirmats. Forma corta: marco 80 (solo altura).

Largueros traseros (sin fondo)

# bajo cocina con paso de tubos
trasera = no
largueros
  superior = si
  inferior = si
  alto     = 80

Sin fondo pero con dos travesaños horizontales arriba/abajo. Cada larguero = 4 confirmats (2 por lateral). Aparece en el despiece. Sintaxis vieja larguero-superior / larguero-inferior también funciona.

Consola REPL (terminal flotante)

Atajo: ` (backtick) abre/cierra · Ctrl+Enter o ▶ ejecuta · Esc cierra · arrastra por la barra superior

A1resumen de la celda
A1.bisagravalor de una propiedad
A1.altodimensión real de la celda en mm
muebleresumen del mueble entero
lateral-izq · techo · suelo · tapa · fondo · zocalodescripción de la pieza estructural
<nombre-de-zona>datos de la zona con nombre
?aliases activos
??MFL exportado completo
añadir mueble · nuevo mueblecrea un mueble nuevo en el escenario (no modifica el actual)
posicion = x, ydentro del bloque añadir/nuevo mueble · mm respecto al origen (0,0) dibujado en el lienzo

Crear un mueble nuevo (no modifica el actual; el plano del fondo es común a todos):

añadir mueble armario
  ancho = 1200
  alto  = 2000
  fondo = 400
  posicion = 800, 0      # x,y mm desde el origen — sólo XY, sin Z
  distribucion
    columnas = 2
    filas    = 1
    A1 = puerta
    A2 = puerta

añadir mueble y nuevo mueble son equivalentes. Sin esa palabra inicial, mueble X se sigue interpretando como modificación del mueble actual. Convención Cartesiana: X crece a la derecha, Y crece hacia arriba (altura desde el suelo). El origen (0,0) está dibujado abajo-izquierda del lienzo: eje X rojo, eje Y verde. Un mueble con posicion = 0, 0 apoya en el suelo. Para apilar otro encima, su Y = altura del mueble que le soporta (p.ej. posicion = 0, 720).

Expresiones aritméticas + variables locales:

comoda.ancho                          → 800
comoda.lateral_izq.ancho              → 19
comoda.tapa.voladizo_frente          → 30
comoda.ancho - 2 * comoda.grosor     → 762

_libre = comoda.ancho - 2*comoda.grosor
_libre / 3                                 → 254

Operadores + - * / y paréntesis. Variables con prefijo _ persisten en la sesión. Acceso jerárquico con . sobre objetos: mueble, comoda (nombre), lateral_izq/_dcha, techo, suelo, tapa, fondo, zocalo, armazon, A1...

Piezas, uniones y hardware (REPL)

A1.bordesqué piezas delimitan la celda (4 lados)
A1.borde-arribasolo una cara (techo, divisor_h_N…)
techo · lateral_izq · divisor_h_1info de la pieza · dimensiones · orient.
techo.unionescon qué piezas se une (L-corner, T-joint, cross, butt)
union(a, b)info de la unión + hardware actual
union(...).hardware = allen×2override persistido (pasa a despiece + CNC)
union(...).note = "..."nota libre asociada a la unión
inventariototal de hardware del mueble
cnc · exportresumen del export con operaciones por pieza
<pieza>.operacioneslista de taladros/fresados (con coords y diámetros)
validarwarnings/errores de las uniones
montajesecuencia recomendada de ensamblaje paso a paso

Tipos de hardware: tubillón, minifix, allen, escuadra, cabezal escondido, tornillo madera, grapa. Sintaxis libre: tubillón×4 + minifix×2.

Construcción (caja / armazón)

construccion armazon     # caja|armazon
  poste     = 40
  lateral   = 12
  travesano = 35
  ranura    = 10

En modo armazón los postes son las patas. Trasera encastrada en ranuras de los postes traseros. Sintaxis vieja: armazon-poste, armazon-lateral... también funciona.

Caja / Joyero

caja joyero
  ancho = 300
  fondo = 200
  alto  = 80
  tapa
    alto     = 25
    bisagras = 2
  apartados
    columnas = 3
    filas    = 2
  piso                 # el 1º es el de abajo
    alto    = 50
    cajones = 2
  cierres  = 2
  asa      = frente     # frente | tapa | no
  acabado  = laton

Tapa y pisos soldados; laterales y trasera hasta el suelo. Repite piso para más pisos. tapa = no = bandeja. Ver manual → Caja / Joyero.

Tapa con voladizos

tapa
  izq     = 50
  dcha    = 50
  frente  = 30
  trasero = 0
encimera = si      # piedra/compacto

Defecto: tapa de madera (copia carcasa). Sintaxis vieja voladizo-izq/dcha/frente/trasero sigue funcionando.

Distribución

distribucion
  columnas = 3  A:400  B:400  C:resto
  filas    = 2  1:300  2:resto

  A1      = puerta
  B1..B2  = cajon     # rango: 1 sola pieza con span
    cantidad = 3
  A2.bisagra      = derecha    # excepción
  A1..C1.bisagra  = izquierda  # por rango

Tamaños: número en mm, fracción (1:resto) o ausentes. Rangos A1..A2 = puerta crean UNA puerta alta con rowSpan=2, no dos puertas separadas.

Dividir solo una celda (azúcar)

distribucion
  columnas = 3
  filas    = 1
  A1 = puerta
  B1 = abierto
  B1.dividir-horizontal = 3   # B en 3 pisos
  C1 = puerta

El compilador expande filas a 3 y mantiene A y C enteras. Existe también dividir-vertical análogo para subdividir una fila en columnas.

Bisagras automáticas

El compilador asigna solo:

Primera columna con puerta→ izquierda (sobre lateral)
Última columna con puerta→ derecha (sobre lateral)
Columnas intermedias→ encadenan vecina izq (sin colisiones)

Solo escribe .bisagra si quieres romper la regla. Aviso del compilador si dos puertas adyacentes acaban con bisagras enfrentadas (chocarían al abrir 90°).

Dot paths — alternativa a indentar

mueble armario
  ancho = 1200
  distribucion.columnas = 3
  distribucion.A1 = puerta
  distribucion.A1.bisagra = derecha
  puerta.tirador = pomo     # default global

Prefijos válidos: distribucion, puerta, cajon, balda, barra, carpinteria. Mezclables con la sintaxis indentada clásica.

Tipos de contenido de celda

puertapuerta batiente
cajoncajón o módulo de cajones
baldabalda fija (divide en filas)
barrabarra de colgar
abiertohueco vacío
ciegopanel ciego (sin apertura)
falso-frentepanel decorativo fijo

Propiedades de puerta

bisagra izq|dcha|arriba|abajolado del giro (auto si no se indica)
hojas 1|2una o dos hojas
estilo superpuesta|encastrada|interiorsuperpuesta=overlay (def), encastrada=flush, interior=retranqueada. Sinónimos: solapada/embutida.
cristal si|nopuerta con vidrio
espejo si|no
cierre-suave si|noamortiguador
kit si|nocomprada hecha (no se fabrica)
tiradorver tabla tiradores

Propiedades de cajón

cantidad <n>cajones en la celda
separacion <mm>entre frentes (def 2)
estilo superpuesto|encastradooverlay/flush del frente. Sinónimos: solapado/embutido
espejo si|nofrente con espejo
cierre-suave si|noguía con freno
push si|nosin tirador, push-to-open
kit si|nocuerpo comprado, fabricamos solo frontal
tiradorver tabla tiradores

Propiedades de balda y barra

cantidad <n>balda: nº de baldas
regulable si|nobalda en sistema 32mm
grosor <mm>balda: si difiere
altura <mm>barra: desde el techo
material aluminio|acero|maderabarra

Tiradores (puertas y cajones)

tirador barratirador alargado (defecto)
tirador pomotirador puntual
tirador perfilcanal en el frente
tirador ningunosin tirador (push-to-open)

Bloque zona (overlay)

zona A1..A3 puerta
  nombre  = puerta-columna
  hojas   = 1
  bisagra = izquierda
  tirador = barra
  cristal = no
  mostrar = si
  kit     = si

Rango contiguo H o V. Tipo: puerta (estructural) o ciego.

Alias de rangos (variables)

mueble x
  primera_columna = a1..a3      # declaración global
  fila_top        = a1..c1

  distribucion
    primera_columna = puerta
    primera_columna.bisagra = derecha
    fila_top = balda

  zona primera_columna puerta

Identificador en minúsculas (sin tildes). Visible desde distribucion y zona.

Defaults globales por tipo

mueble x
  puerta                     # defaults para TODAS las puertas
    bisagra = izquierda
    tirador = barra

  cajon
    cierre-suave = si
    kit          = si

  distribucion
    ...

Bloques puerta, cajon, balda, barra a nivel mueble = defaults; las celdas pueden sobrescribir.

Reglas generales

=asignación
..rango (A1..C4)
restoocupa el sobrante
si / nobooleanos en castellano
# ... fin líneacomentario
### ... ###comentario de bloque

El orden importa: lo último gana. Lo más específico (celda) sobrescribe lo heredado (defaults).

Composición — varios muebles

mueble base
  ancho = 1200
  alto  = 800
  ...

mueble alto
  ancho = 1200
  alto  = 700
  ...

Varios bloques mueble en un fichero = varios muebles independientes.

Gap 2026-05-26 — propiedades nuevas

Lote de keywords añadidas al MFL para cubrir propiedades del modelo Furniture / GridCell / Zone que antes no eran expresables. Tests en mfl/tests/mfl-gap-2026.test.js.

Grosores asimétricos (tapa/suelo independientes de carcasa)

grosor-tapa  = 38         # mm — encimera más gruesa que carcasa
grosor-suelo = 25         # mm — suelo más fino

Frente corredero

frente-corredero 2
  fondo = 60              # profundidad TOTAL del paquete (mm)
  profundidad-carril = 80
  hoja 1
    material = glass      # wood | glass | mirror
    filas-cristal    = 3
    columnas-cristal = 2
    junquillo        = 25
  hoja 2
    material = wood
    tirador  = channel     # recessed | channel | none

Base inferior (tablero entre patas/ruedas y cuerpo, estilo escandinavo)

base 30
  color             = #444
  voladizo-frente   = 15
  voladizo-izq      = 10
  voladizo-dcha     = 10

Listones decorativos sobre trasera (slat wall)

listones
  ancho      = 30          # mm
  grosor     = 15
  separacion = 25
  direccion  = vertical    # vertical | horizontal
  color      = #c9a87a

Trasera: cubrir zócalo + dirección de veta

trasera-cubre-zocalo = si
veta-trasera         = horizontal   # auto | horizontal | vertical

Marco frontal extendido

tablero-inferior = 80     # nuevo: marco superior + inferior
retranqueo-tapa  = 10     # mm de retranqueo en la tapa
retranqueo-suelo = 15

Forma y retranqueos de pata por eje

patas 4
  forma-patas           = redonda   # cuadrada | redonda
  retranqueo-patas-trasero = 20
  retranqueo-patas-lateral = 30

Listones cubrejunta + colores por cara

cubrejunta-izq  = 30      # tira que tapa la junta con el mueble vecino
cubrejunta-dcha = 25
color-suelo    = #aaa     # color/textura por cara (override de carcasa)
color-trasera  = #bbb
color-tirador  = #ccc

Estilo, esquina y caras ocultas del zócalo

zocalo 80
  estilo          = solo-frente   # normal | solo-frente | solo-trasero | frente-y-trasero
  esquina         = lados-cubren  # front-cover | sides-cover
  ocultar-izq     = si              # oculta el listón izquierdo del zócalo
  ocultar-dcha    = si

coronacion 60
  estilo          = normal
  esquina         = frontal-cubre

Cornisa: perfil SVG y referencia comercial

cornisa 35
  perfil             = gola
  perfil-svg         = perfiles/cornisa/g1.svg
  ancho              = 40
  referencia         = Maderpan-G1
  longitud-comercial = 2400
  solo-frente        = si

Faldón, aleros, toallero

faldon 120
  frente = si
  izq    = si

aleros 250
  izq = si
  dcha = si
  apoyo-puerta = si

toallero
  lado     = left
  altura   = 600
  diametro = 18

Tapa con bisagra (cofre/baúl) y puerta entre jambas

tapa-bisagra
  cantidad = 3
  alto     = 200
  cierre-cofre = si

puerta-jambas
  modo     = overlay     # between | overlay
  grosor   = 22
  holgura  = 3
  bisagra  = derecha
  apertura = 110

Anclajes (cuando el mueble está vinculado a tapa polig. o sin suelo)

tapa-poligonal = poly-42
anclaje-tapa   = tornillos-tapon
anclaje-suelo  = liston           # cleat | brackets | none

Encimera completa (no solo activación)

encimera
  grosor          = 38
  voladizo-frente = 25
  lazy-susan      = si
  altura          = 0           # mm desde el suelo del mueble

Celda: contenidos especiales (cesta, cajas) + propiedades nuevas

A1 = cesta                  # wire-basket extraíble (kit)
  alto-cesta  = 120
  color-cesta = anthracite     # white | anthracite | beige
  extraible   = si

A2 = cajas                  # cajas organizadoras de fieltro
  cantidad-cajas = 4
  color-cajas    = white
  alto-caja      = 80

A3 = puerta
  hojas                = 2
  anclaje-tirador      = tl   # 1ª hoja: top-left
  anclaje-tirador-dcha = tr   # 2ª hoja: top-right
  textura              = roble  # override del panel global
  falsa                = si    # estética sin bisagras
  apertura             = 110   # grados de apertura (45..180)
  anchos-hoja          = 500,700  # anchos custom de cada hoja (mm)

Zone: cierre suave, espejo, apertura, color/textura

zona A1..A2 puerta
  hojas        = 2
  cierre-suave = si
  espejo       = si
  apertura     = 120
  color        = #112233
  anchos-hoja  = 400,600

Gap 2026-07-06 — propiedades nuevas

Segundo lote tras auditar el quick-panel contra el lenguaje: modo columnas, empotrado, canteado y extras de mueble/celda/zona. Tests en mfl/tests/mfl-gap-2026-07.test.js.

Modo columnas (columnas independientes)

distribucion-columnas     # sustituye a distribucion
  columna 400
    hueco 300 = cajon     # mismas props que una celda
      cantidad = 2
    hueco resto = puerta
      bisagra = derecha
  columna resto
    hueco resto

Empotrado (hueco de obra)

empotrado
  anchos     = 2000, 1995, 2003  # arriba, medio, abajo (1 valor = los 3)
  altos      = 2400              # izq, centro, dcha
  fondos     = 600               # 4 esquinas
  diagonales = 3120, 3118
  pared      = ladrillo          # tabique | ladrillo | piedra
  fijacion   = escuadras         # liston-pared | escuadras | pasante | ninguna
  obstaculo columna              # columna|tubo|viga|enchufe|rodapie|otro
    x = 100  ancho = 120  fondo = 150  hasta = 900

Canteado por pieza y borde

canteado
  tapa        = frente, izq, dcha
  lateral-izq = frente, arriba   # piezas: tapa suelo lateral-izq/dcha zocalo coronacion

Mueble — patas, acabados, cuerpo

forma-patas    = inclinada  # cuadrada | redonda | inclinada (escandinava)
apertura-patas = 30         # % apertura del pie (solo inclinada)
color-patas    = #663300
color-lateral-izq    = #aabbcc   # idem textura-lateral-izq/dcha
veta-tapa      = horizontal # veta-lateral-izq/dcha, veta-suelo, veta-frontal
bastidor       = si         # face frame; ancho-bastidor = 60
anclaje-pared  = no         # quita antivuelco (activo por defecto)
rinconera      = si         # frente-rincon = 300; mano-rincon = derecha
color-canto    = #112233    # idem textura-canto
voladizo-suelo-frente = 30  # idem -izq/-dcha/-trasero
profundidad-ranura = 14     # fondo ranurado
vuelo-superior = 40         # laterales sobre el cuerpo; vuelo-inferior

Celda — abatible, trasera propia, extras

A1 = mesa-abatible          # pivote-abatible = 150
B1 = puerta
  bisagra  = arriba
  abatible = si             # hoja-tablero con patas en U
  rueda-u  = si             # ruedín bajo puertas grandes
  puerta-cuadro = si        # panel central de madera
  tirador  = concha         # tambien: gola
  color    = #ff8800  etiqueta = vajilla  cara = lateral-izq
  organizador-puerta        # bandeja interna; altura + fondo
    altura = 300
A2 = barra
  altura = 250              # mm desde el techo del interior
B2 = frente-fijo            # diametro = 25 (Ø tubo)
A1.trasera-celda   = falso-frente  # panel | abierto | falso-frente
A1.bisagra-trasera = derecha  A1.ruedin-trasero = si

Zona — abatible, alto de hoja, corredera

zona A1..B1 mesa-abatible   # pivote-abatible = 120
zona A2..B2 puerta
  abatible  = si
  alto-hoja = 500
zona A3..B3 puerta
  corredera        = si      # deslizante en vez de batiente
  hojas-correderas = 3       # 2 | 3

Editor — cargar / guardar

📂 Cargar MFLAbre fichero .mfl en el editor
💾 Guardar MFLDescarga el código actual como <mueble>.mfl
📥 Cargar JSON/SVGImporta proyecto JSON o SVG (con metadata) y regenera el MFL
↓ Exportar JSON/SVG/GLBProyecto, proyecto SVG, o modelo 3D real (metros, sin herrajes)
↓ Exportar despiece/presupuestoCSV (piezas+medidas / material+herrajes+total)
↓ Exportar PLANKPaneles con tag+medidas para PLANK Visual (sin posición real)
↗ Abrir visor GLBPestaña nueva, arrastra el .glb exportado

Los SVG exportados por MuebleLab llevan el JSON del proyecto incrustado en <metadata>. Cargar un SVG → reconstruye Furniture → genera MFL automáticamente vía furnitureToMFL().

Directivas @validate / @export

Sentencias de programa, sueltas sin indentar — no van dentro de mueble. No generan piezas.

@validate soft   # off|soft(default)|strict
@export svg armario-negro
@export glb armario-negro   # repetible, un formato por línea
svg / jsonproyecto (recargable en app.php)
glbmodelo 3D real, sin herrajes
cutlistCSV pieza+medidas
presupuestoCSV material+herrajes+total
plankpaneles PLANK, tag+medidas (sin posición real — v1)

Solo dispara la descarga en mfl.html, tras compilar sin errores. Sin comillas ni paréntesis (tokeniza por espacios). Dentro de para cada genera una directiva por vuelta con el nombre ya sustituido — ver "Bucles" más abajo.

Bucles: datos + para cada — 2026-09-09

datos modulos
  - nombre=bajo-40  ancho=400  alto=800  fondo=600
  - nombre=bajo-60  ancho=600  alto=800  fondo=600

para cada m en modulos
  mueble $m.nombre
    ancho = $m.ancho
    alto  = $m.alto
    fondo = $m.fondo
    distribucion
      columnas = 1
      filas    = 1
      A1 = puerta
fin-para

Bucle ACOTADO (sin mientras ni mutación, como for_each de Terraform): el nº de vueltas lo fija el tamaño de la tabla, así que siempre termina. $var.campo se sustituye en CUALQUIER token de la vuelta — nombre del mueble, dimensiones, incluso una directiva @export. fin-para (o fin) es obligatorio — error de compilación si falta.

Condicional: si / sino si / sino — 2026-09-09

si $m.tipo = puerta
  A1 = puerta
  A1.hojas = $m.hojas
sino si $m.tipo = cajon
  A1 = cajon
sino
  A1 = abierto
fin-si

Operadores: = <>/!= < > <= >= (numérico si ambos lados parecen número, si no compara texto). Funciona anidado en cualquier bloque — dentro de distribucion, de mueble, o suelto — no hace falta que esté dentro de un para cada. La rama se decide al expandir el fichero: el mueble final sigue siendo 100% declarativo. fin-si obligatorio.

Usar MFL desde JS (fuera de MuebleLab) — 2026-09-09

import { compileMFL, generateProjectSVG, serializeFurniture }
  from 'https://mueblelab.com/mfl/dist/mfl-compiler.js';

const { cabinets, errors } = compileMFL(textoMFL);
const svg = generateProjectSVG(
  { furnitures: [{ id: 'm0', x: 0, y: 0, furniture: cabinets[0] }], tabletops: [] },
  serializeFurniture, { crop: true }
);

Un solo fichero, sin dependencias externas, funciona igual en Node y en el navegador (<script type="module">) — cero fs/child_process/nada específico de un entorno, con cabecera CORS para importarlo desde cualquier dominio. Solo trae compileMFL + exportar a SVG — nada de 3D/GLB/despiece/herrajes (eso vive en la app principal, no está pensado para usarse suelto todavía).

Errores en el editor

Bajo el editor hay una consola de 3 líneas (con scroll, hasta 200 entradas) que muestra:

🔴 errorespropiedad desconocida, bloque no reconocido, tipo de celda inválido
🟡 warningscolisiones de bisagras, pegado en mueble grande...
🟢 ok"✓ N mueble(s) compilado(s)"

Vista 3D — modo tornillería

Botón 🔩 Ver tornillería hace transparentes los tableros (0.13 op.) y deja visibles:

tornillos & levasaglomerado, minifix, allen
bisagrascazoleta + brazo + plato + tornillos
guías de cajónraíles + bolas de rodamiento (4–10 por guía)
tiradoresbarra, pomo, perfil