Mapeate/Public/construir.php

163 lines
7.7 KiB
PHP

<?php
class MapeateConstructorWeb{
const PARRAFO = 1 << 0;
const LINK = 1 << 1;
public function __construct(){
$html = file_get_contents(__DIR__ . "/../HTML/index.html");
$modulos = [];
$modulos_html = file_get_contents(__DIR__ . "/../HTML/modulos.html");
$this->pseudomarkdown_patrones = [
"cabecera" => ['/^(\#{1,6})([^\r\n]+)$/m', fn($campos) => '<h' . ($l = strlen($campos[1][0])) . '>' . $this->montar_pseudomarkdown($campos[2][0], self::PARRAFO) . '</h' . $l . '>'],
"negrilla" => ['/\*{2}(([^\*]+|\*[^\*]|[\n\r]+)+)\*{2}/', fn($campos) => '<b>' . $this->montar_pseudomarkdown($campos[1][0], self::PARRAFO) . '</b>'],
"cursiva" => ['/\*(([^\*]+|[\r\n]+)+)\*/', fn($campos) => '<i>' . $this->montar_pseudomarkdown($campos[1][0], self::PARRAFO) . '</i>'],
"lista" => ['/^(\s*(\-|[0-9]+\.)[^\r\n]+(\r\n|\n|\r))+/m', fn($campos) => $this->montar_lista($campos[0][0])],
"markdown_link" => ['/\[([^\[\]]+)\]\(([^\(\)]+)\)/', fn($campos) => '<a href="' . $campos[1][0] . '" target="_blank" title="' . ($texto = $this->montar_pseudomarkdown($campos[2][0], self::PARRAFO | self::LINK)) . '">' . $texto . '</a>'],
"link" => ['/\[{2}link\s+([^\]\s]+)(\s+([^\]]+))?\]{2}?/', fn($campos) => '<a href="' . $campos[1][0] . '" target="_blank" title="' . ($texto = $campos[count($campos) > 2 && $campos[2] ? 2 : 1][0]) . '">' . $texto . '</a>'],
"link_crudo" => ['/https?\:\/{2}[^\s]+/', fn($campos) => '<a href="' . $campos[0][0] . '" target="_blank" title="' . $campos[0][0] . '">' . $campos[0][0] . '</a>'],
"parrafo" => ['/^(([^\r\n]+)(\r\n|\n|\r)?)+/m', fn($campos) => '<p>' . $this->montar_pseudomarkdown($campos[0][0], self::PARRAFO) . '</p>']
];
while(preg_match('/<\!\-{2}\s*\[{2}([^\[\]]+)\]{2}(\s*\-{2}>)?/', $modulos_html, $matches, \PREG_OFFSET_CAPTURE)){
$clave = trim($matches[1][0]);
if(preg_match('/<\!\-{2}\s*\[{2}\s*' . $clave . '\s*\]{2}(\s*\-{2}>)?/', $modulos_html = substr($modulos_html, $matches[0][1] + strlen($matches[0][0])), $matches, \PREG_OFFSET_CAPTURE)){
$modulos[$clave] = substr($modulos_html, 0, $matches[0][1]);
$modulos_html = substr($modulos_html, $matches[0][1] + strlen($matches[0][0]));
};
};
echo self::string_variables($html, [
"menu" => implode("", array_map(fn($campos) => self::string_variables($modulos["elemento_menu_principal"], [
"i18n" => $campos[0],
"texto" => $campos[1],
"link" => $campos[2],
"target" => $campos[3],
"icono" => $campos[4]
]), [
["mapeate_oficial", "Mapeate - Web oficial", "https://mapeate.k3y.pw/", "_self", "mapeate"],
["web_app_oficial", "Mapeate - Aplicación Web oficial", "https://mapeate.k3y.pw/app.html", "_self", "mapeate"],
["mapeate_git", "Mapeate - Git", "https://git.k3y.pw/CaritasSantaCruz/Mapeate", "_blank", "git"],
["caritas_santa_cruz_facebook", "Cáritas Santa Cruz - Facebook", "https://www.facebook.com/santacruzcaritas/", "_blank", "facebook"],
["caritas_santa_cruz_wix", "Cáritas Santa Cruz - Wix", "https://santacruzdecanido.wixsite.com/caritas", "_blank", "wix"],
["caritas_santa_cruz_twitter", "Cáritas Santa Cruz - Twitter", "https://twitter.com/CanidoSantaCruz", "_blank", "twitter"],
["caritas_santa_cruz_fan_web", "Cáritas Santa Cruz - Fan Web", "https://fanwebcaritassantacruz.k3y.pw/", "_blank", "fan_web"]
])),
"contenido" => $this->montar_pseudomarkdown(file_get_contents(__DIR__ . "/../HTML/contenido.md"))
]);
}
public static function string_variables($string, $variables){
return preg_replace_callback('/\{([^\{\}]+)\}/', function($valor) use($variables){
if(isset($variables[$valor[1]]))
return $variables[$valor[1]];
return $valor[0];
}, $string);
}
private function montar_lista($campos){
$lineas = preg_split('/[\r\n]+/', $campos);
$html = '';
$niveles = [[0, "ul"]];
$l = 0;
foreach($lineas as $linea){
if(!preg_match('/^(\s*)?(\-|[0-9]+\.)?(.*)$/', $linea, $matches))
continue;
$separador = strlen($matches[1]);
$tipo = $matches[2];
$entrada = $this->montar_pseudomarkdown(trim($matches[3]), self::PARRAFO);
if($tipo){
if($niveles[$l][0] == $separador)
$html .= ($html ? '</li>' : '<' . ($niveles[$l][1] = $tipo == "-" ? "ul" : "ol") . '>') . '<li>' . $entrada;
elseif($niveles[$l][0] < $separador){
$niveles[++ $l] = [$separador, $tipo == "-" ? "ul" : "ol"];
$html .= '<' . $niveles[$l][1] . '><li>' . $entrada;
}else{
while($niveles[$l][0] > $separador && $l --)
$html .= '</li></' . array_pop($niveles)[1] . '>';
$html .= '</li><li>' . $entrada;
};
}elseif($entrada)
$html .= " " . $entrada;
};
while(count($niveles))
$html .= '</li></' . array_pop($niveles)[1] . '>';
return $html;
}
public function montar_pseudomarkdown($pseudomarkdown, $modo = 0){
$punteros = [];
$html = '';
$es_parrafo = $modo & self::PARRAFO;
foreach(array_keys($this->pseudomarkdown_patrones) as $clave)
if(!$es_parrafo || $clave != "parrafo")
$punteros[$clave] = [["", -1]];
while(true){
$eliminar = [];
$posicion = 2 << 28;
$elemento = null;
foreach($punteros as $clave => $valor){
if($punteros[$clave] === null)
continue;
if($punteros[$clave][0][1] < 0)
if(!preg_match($this->pseudomarkdown_patrones[$clave][0], $pseudomarkdown, $punteros[$clave], PREG_OFFSET_CAPTURE)){
$eliminar[] = $clave;
continue;
};
if($punteros[$clave][0][1] < $posicion){
$posicion = $punteros[$clave][0][1];
$elemento = $clave;
};
};
foreach($eliminar as $clave)
unset($punteros[$clave]);
if(!count($punteros))
break;
$i = $punteros[$elemento][0][1];
$html .= (
substr($pseudomarkdown, 0, $i) .
((
((!$punteros[$elemento][0][0] || $modo & self::PARRAFO) && $elemento == "parrafo") ||
($modo & self::LINK && $elemento == "link_crudo")
) ? $punteros[$elemento][0][0] : $this->pseudomarkdown_patrones[$elemento][1]($punteros[$elemento]))
);
$i += strlen($punteros[$elemento][0][0]);
foreach(array_keys($punteros) as $clave)
$punteros[$clave][0][1] -= $i;
$pseudomarkdown = substr($pseudomarkdown, $i);
};
return $html . $pseudomarkdown;
}
};
$mcw = new MapeateConstructorWeb();