1
0
Fork 0
Markdown-Maker/README.md

369 lines
13 KiB
Markdown

# Libre-marker Project
con Nginx + JavaScript. Podemos configurar Nginx para que, cuando alguien pida un `.md`, Nginx le sirva una pequeña plantilla HTML "invisible" que contenga la librería
[Marked](https://github.com/markedjs/marked/) y renderice el texto al instante.
## FASE1 - Libre-marke viewer
Aquí tienes cómo montar tu propio "Markdown Viewer" estático en 2 pasos:
### Paso 1: Crear el "Visor Mágico" (visor.html)
Crea un archivo llamado `visor.html` en la raíz de tu sitio web (junto a tus archivos .md). Copia este código exacto.
Este código usa la librería **Marked** (la que mostraste en la imagen) para convertir el texto a HTML en el navegador del visitante.
```HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Visor Markdown</title>
<style>
body { font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; line-height: 1.6; }
img { max-width: 100%; }
pre { background: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; }
/* Puedes añadir aquí CSS para que se vea como GitHub o tu estilo preferido */
</style>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<div id="content">Cargando documento...</div>
<script>
// 1. Detectar qué archivo .md se pidió (viene en la URL)
const urlParams = new URLSearchParams(window.location.search);
const file = urlParams.get('file');
if (file) {
// 2. Descargar el archivo .md
fetch(file)
.then(response => {
if (!response.ok) throw new Error("No se encontró el archivo.");
return response.text();
})
.then(text => {
// 3. Convertir Markdown a HTML y mostrarlo
document.getElementById('content').innerHTML = marked.parse(text);
})
.catch(err => {
document.getElementById('content').innerHTML = "Error: " + err.message;
});
} else {
document.getElementById('content').innerHTML = "No se ha especificado ningún archivo.";
}
</script>
</body>
</html>
```
### Paso 2: El Truco de Nginx (La Redirección)
Ahora configuramos Nginx para que intercepte la petición. Cuando el usuario escriba `misitio.com/manual.md`, Nginx **reescribirá internamente** la petición para cargar el visor, pasándole el nombre del archivo.
Edita tu configuración del sitio (`/etc/nginx/sites-enabled/tustio`):
```Nginx
server {
# ... tu configuración actual ...
root /var/www/tusitio;
index index.html;
# REGLA MÁGICA PARA MARKDOWN
location ~ \.md$ {
# Si el archivo existe, redirige al visor
try_files $uri @markdown_viewer;
}
location @markdown_viewer {
# Reescribe la URL para usar el visor.html
# Ejemplo: manual.md -> /visor.html?file=manual.md
rewrite ^/(.*\.md)$ /visor.html?file=$1 last;
}
# ... resto de la config ...
}
```
### Paso 3: Reiniciar y Probar
1. Reinicia Nginx:
```bash
service nginx restart
```
2. Borra caché del navegador (Ctrl + Shift + R).
Entra a librebits.info/tu-archivo.md.
3. ¿Qué ocurrirá?
La URL en el navegador seguirá diciendo tu-archivo.md (elegante).
Pero lo que verás en pantalla será el HTML generado, con títulos, negritas y enlaces, tal cual querías.
¿Te animas a probar este enfoque? Es muy ligero y no requiere instalar PHP ni bases de datos.
## FASE 2 - Live Editor + Preview
Editor Markdown en tiempo real con split view, inspirado en la demo oficial de Marked.js (ver `Screenshots/markedJS-demo.png`).
### Arquitectura
**100% cliente-side**. Nginx solo sirve el HTML estático, toda la lógica ocurre en el navegador usando JavaScript vanilla + Marked.js.
### Componentes UI
```
┌─────────────────────────────────────────────────────────────┐
│ Barra superior: [Dropdown Views] [Clear] [Version] [Theme] │
├──────────────────────────┬──────────────────────────────────┤
│ │ │
│ PANEL IZQUIERDO │ PANEL DERECHO │
│ (Editor) │ (Preview) │
│ │ │
│ <textarea> │ <div id="preview"> │
│ Markdown crudo │ HTML renderizado │
│ con sintaxis │ en tiempo real │
│ │ │
└──────────────────────────┴──────────────────────────────────┘
```
### Funcionamiento
1. **Textarea con evento `oninput`**:
```javascript
textarea.addEventListener('input', (e) => {
const markdown = e.target.value;
renderPreview(markdown);
});
```
2. **Renderizado instantáneo**:
```javascript
function renderPreview(text) {
const view = currentView; // Preview, HTML Source, Lexer Data
switch(view) {
case 'preview':
preview.innerHTML = marked.parse(text);
break;
case 'html':
preview.textContent = marked.parse(text);
break;
case 'lexer':
preview.textContent = JSON.stringify(marked.lexer(text), null, 2);
break;
}
}
```
3. **Layout CSS Grid/Flexbox**:
- Split 50/50 horizontal
- Responsive: stack vertical en móviles
- Dark mode toggle
### Características a Implementar
- ✅ Split view editor/preview
- ✅ Actualización en tiempo real (oninput)
- ✅ Dropdown con vistas: Preview, HTML Source, Lexer Data, Quick Reference
- ✅ Botón "Clear" para limpiar editor
- ✅ Dark mode
- ⏳ Cargar archivo .md existente para editar
- ⏳ Botón "Download" para guardar cambios localmente
- ⏳ LocalStorage para persistencia temporal
### Sin Backend Necesario
Todo funciona en el cliente con:
- HTML + CSS + JavaScript vanilla (ES6+)
- Marked.js (CDN: `https://cdn.jsdelivr.net/npm/marked/marked.min.js`)
- Nginx sirviendo archivos estáticos
---
## FASE 3 - Control de Versiones con Git
Añadir capacidad de **commit directo desde el navegador** para versionar cambios en archivos Markdown.
### Visión General
Botón "💾 Commit" en la interfaz que guarda el estado actual del archivo con mensaje de commit, creando un historial versionado.
### Desafío: Seguridad del Navegador
JavaScript en el navegador **NO puede ejecutar comandos git** directamente por restricciones de seguridad. Necesitamos un puente mínimo servidor-cliente.
### Opciones de Implementación (Out-of-the-box thinking)
#### Opción A: GitHub API (Sin Backend Custom)
**Pros**: Sin código servidor, usa API REST de GitHub
**Contras**: Requiere repo público/privado en GitHub, token de autenticación
```javascript
// Commit directo vía GitHub API
async function commitToGitHub(filename, content, message) {
const response = await fetch(`https://api.github.com/repos/user/repo/contents/${filename}`, {
method: 'PUT',
headers: {
'Authorization': `token ${GITHUB_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: message,
content: btoa(content), // Base64
sha: currentFileSHA // Obtenido previamente
})
});
return response.json();
}
```
**Flujo**:
1. Usuario edita markdown
2. Click en "Commit" → prompt para mensaje
3. JavaScript hace PUT a GitHub API
4. Archivo actualizado en el repo remoto
5. Historial visible en GitHub
#### Opción B: Endpoint Mínimo PHP/Python + Git Local
**Pros**: Control total, commits locales, no depende de GitHub
**Contras**: Requiere script servidor (rompe filosofía "sin backend")
```php
// save.php (ejecutado vía Nginx FastCGI)
<?php
$file = $_POST['file'];
$content = $_POST['content'];
$message = $_POST['message'];
// Guardar archivo
file_put_contents("/var/www/docs/{$file}", $content);
// Git commit
exec("cd /var/www/docs && git add {$file}");
exec("git commit -m " . escapeshellarg($message));
echo json_encode(['status' => 'ok']);
?>
```
**Configuración Nginx**:
```nginx
location /api/save {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/scripts/save.php;
}
```
#### Opción C: LocalStorage + Historial JSON (Sin Git Real)
**Pros**: 100% cliente, sin servidor, funciona offline
**Contras**: No es git real, historial solo en navegador local
```javascript
// Pseudo-versionado con LocalStorage
function saveVersion(filename, content, message) {
const history = JSON.parse(localStorage.getItem('mdHistory') || '[]');
history.push({
file: filename,
content: content,
message: message,
timestamp: new Date().toISOString(),
sha: simpleHash(content) // Hash simple como "commit ID"
});
localStorage.setItem('mdHistory', JSON.stringify(history));
}
// Exportar historial como .json
function exportHistory() {
const data = localStorage.getItem('mdHistory');
downloadFile('history.json', data);
}
```
#### Opción D: Git via WebAssembly (Experimental)
**Pros**: Git real en el navegador, sin backend
**Contras**: Tecnología emergente, compleja, tamaño de bundle grande
Usar [isomorphic-git](https://isomorphic-git.org/) compilado a WASM para ejecutar operaciones git directamente en el navegador.
### Recomendación por Fases
1. **FASE 3.1** (Más simple): Opción C - LocalStorage + exportar historial
2. **FASE 3.2** (Híbrido): Opción B - Endpoint PHP mínimo para git local
3. **FASE 3.3** (Cloud): Opción A - GitHub API para equipos colaborativos
4. **FASE 3.X** (Futuro): Opción D - Git WASM cuando madure la tecnología
### UI Propuesta
```
┌──────────────────────────────────────────────────────────┐
│ [💾 Commit] [📜 History] [⬇️ Export] [Theme] [Help] │
├─────────────────────────┬────────────────────────────────┤
│ Editor │ Preview │
│ │ │
└─────────────────────────┴────────────────────────────────┘
Al click en "💾 Commit":
┌─────────────────────────────────────┐
│ Commit Message: │
│ ┌───────────────────────────────┐ │
│ │ Updated documentation │ │
│ └───────────────────────────────┘ │
│ │
│ [Cancel] [💾 Save] │
└─────────────────────────────────────┘
```
---
### Reference: Marked - Markdown Parser
========================
[Marked] lets you convert [Markdown] into HTML. Markdown is a simple text format whose goal is to be very easy to read and write, even when not converted to HTML. This demo page will let you type anything you like and see how it gets converted. Live. No more waiting around.
How To Use The Demo
-------------------
1. Type in stuff on the left.
2. See the live updates on the right.
That's it. Pretty simple. There's also a drop-down option above to switch between various views:
- **Preview:** A live display of the generated HTML as it would render in a browser.
- **HTML Source:** The generated HTML before your browser makes it pretty.
- **Lexer Data:** What [marked] uses internally, in case you like gory stuff like this.
- **Quick Reference:** A brief run-down of how to format things using markdown.
Why Markdown?
-------------
It's easy. It's not overly bloated, unlike HTML. Also, as the creator of [markdown] says,
> The overriding design goal for Markdown's
> formatting syntax is to make it as readable
> as possible. The idea is that a
> Markdown-formatted document should be
> publishable as-is, as plain text, without
> looking like it's been marked up with tags
> or formatting instructions.
Ready to start writing? Either start changing stuff on the left or
[clear everything](/demo/?text=) with a simple click.
[Marked]: https://github.com/markedjs/marked/
[Markdown]: http://daringfireball.net/projects/markdown/