javascript MD terminé (sauf italique)

pull/1/head
Nicolas Sanchez 3 years ago
parent d9495f6afb
commit 33fedc9f35

2
Cargo.lock generated

@ -838,7 +838,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "mdwiki" name = "mdnotes"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-files", "actix-files",

@ -1,5 +1,5 @@
[package] [package]
name = "mdwiki" name = "mdnotes"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

@ -1,7 +1,7 @@
mdwiki mdnotes
====== ======
Wiki utilisant la syntaxe MarkDown pour être rapide et facile à modifier. Notes utilisant la syntaxe MarkDown pour être rapide et facile à modifier.
Idéal pour la prise de notes. Idéal pour la prise de notes.
Création dynamique de pages en créant un lien dans une page. Création dynamique de pages en créant un lien dans une page.

@ -1,6 +1,5 @@
use clap::Parser; use clap::Parser;
#[derive(Parser)] #[derive(Parser)]
pub struct Arguments { pub struct Arguments {
/// IP address /// IP address

@ -1,8 +1,8 @@
use actix_web::{post, web, App, HttpResponse, HttpServer, Responder}; use actix_web::{post, web, App, HttpResponse, HttpServer, Responder};
use actix_files; use actix_files;
use mdwiki::commons::{Arguments, AppData}; use mdnotes::commons::{Arguments, AppData};
use mdwiki::index; use mdnotes::index;
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
@ -21,6 +21,7 @@ async fn main() -> std::io::Result<()> {
.app_data(web::Data::new(appdata.to_owned())) .app_data(web::Data::new(appdata.to_owned()))
.service(index::index) .service(index::index)
.service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static", "./static"))
.service(actix_files::Files::new("/static/modules", "./static/modules"))
}) })
.bind((ip, port))? .bind((ip, port))?
.run() .run()

@ -1,9 +1,13 @@
html { html {
background-color: #f5f5f5; font-family: system-ui;
font-size: 12pt;
}
body {
margin: 0;
} }
div#mdnotes { div#mdnotes {
font-family: sans-serif;
padding-top: 1rem; padding-top: 1rem;
padding-left: 3rem; padding-left: 3rem;
padding-right: 3rem; padding-right: 3rem;
@ -11,29 +15,91 @@ div#mdnotes {
background-color: #ffffff; background-color: #ffffff;
} }
div#mdnotes:focus {
outline: none;
}
div#mdnotes div.h1 { div#mdnotes div.h1 {
font-size: 2rem; font-size: 3rem;
font-weight: bold;
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
border-bottom: 1px solid #666666; border-bottom: 1px solid #666666;
} }
div#mdnotes div.h2 { div#mdnotes div.h2 {
font-size: 1.5rem; font-size: 2.2rem;
font-weight: bold;
margin-top: 0.5rem; margin-top: 0.5rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
div#mdnotes div.h3 { div#mdnotes div.h3 {
font-size: 1rem; font-size: 1.5rem;
font-weight: bold; margin-top: 0.5rem;
margin-top: 0.3rem; margin-bottom: 1rem;
margin-bottom: 0.5rem;
} }
div#mdnotes div.h4 { div#mdnotes div.h4 {
font-style: italic; font-style: italic;
margin-bottom: 0.3rem; margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
div#mdnotes div.bq1 {
font-style: italic;
padding-top: 0.3rem;
padding-bottom: 0.3rem;
padding-left: .9rem;
background-color: #f5f5f5;
border-left: .3rem solid #446699;
}
div#mdnotes div.bq2 {
font-style: italic;
padding-top: 0.3rem;
padding-bottom: 0.3rem;
padding-left: .6rem;
background-color: #f5f5f5;
border-left: .6rem solid #5577aa;
}
div#mdnotes div.bq3 {
font-style: italic;
padding-top: 0.3rem;
padding-bottom: 0.3rem;
padding-left: .3rem;
background-color: #f5f5f5;
border-left: .9rem solid #6688bb;
}
div#mdnotes div.ul {
padding-left: 1rem;
}
div#mdnotes div.mdnotes_line span.token {
font-weight: 1;
color: #88aaff;
overflow: hidden;
}
div#mdnotes div.mdnotes_line span.token {
font-size: 0;
}
div#mdnotes:focus div.mdnotes_line span.token {
font-size: inherit;
}
div#mdnotes div.body {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
div#mdnotes span.bold {
font-weight: bold;
}
div#mdnotes span.mono {
font-family: monospace;
color: #885511;
} }

@ -17,6 +17,11 @@ function change(evt) {
function reId(obj) { function reId(obj) {
let prevId = ''; let prevId = '';
let children = obj.childNodes; let children = obj.childNodes;
if (children.length == 1 && getType(children[0]) == 'TEXT') {
obj.innerHTML = '<div class="mdnotes_line" id="newline">' + obj.innerText + '</div>';
setStartPositionInLine(document.getElementById('newline'), 1);
children = obj.childNodes;
}
for (i = 0; i < children.length; i++) { for (i = 0; i < children.length; i++) {
let child = children[i]; let child = children[i];
if (child.classList.contains('mdnotes_line')) { if (child.classList.contains('mdnotes_line')) {

@ -0,0 +1,65 @@
function load(textarea, div) {
let lines = textarea.value.split('\n');
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
let elem = formatLine(line);
elem.id = 'mdnotes_' + i;
div.append(elem);
}
}
function formatLine(line) {
let normLine = line.trimStart();
let styleClass = null;
let token = null;
if (normLine.match(/####\s/i)) {
token = /^(####\s)/i;
styleClass = 'h4';
} else if (normLine.match(/###\s/i)) {
token = /^(###\s)/i;
styleClass = 'h3';
} else if (normLine.match(/##\s/i)) {
token = /^(##\s)/i;
styleClass = 'h2';
} else if (normLine.match(/#\s/i)) {
token = /^(#\s)/i;
styleClass = 'h1';
} else if (normLine.match(/>>>\s/i)) {
token = /^(>>>\s)/i;
styleClass = 'bq3';
} else if (normLine.match(/>>\s/i)) {
token = /^(>>\s)/i;
styleClass = 'bq2';
} else if (normLine.match(/>\s/i)) {
token = /^(>\s)/i;
styleClass = 'bq1';
} else if (normLine.match(/^[*-]\s/i)) {
styleClass = 'ul';
} else {
styleClass = 'body';
}
let elem = document.createElement('div');
elem.classList.add('mdnotes_line');
elem.classList.add(styleClass);
normLine = addBold(normLine);
normLine = addMono(normLine);
if (token != null) {
elem.classList.add('hastoken');
normLine = normLine.replace(token, '<span class="token">$1</span>');
}
elem.innerHTML = normLine;
return elem;
}
function addMono(line) {
line = line.replace(/`(.*?)`/ig, '<span class="mono"><span class="token">`</span>$1<span class="token">`</span></span>');
return line;
}
function addBold(line) {
line = line.replace(/\*\*([^\s].*?)\*\*/ig, '<span class="bold"><span class="token">**</span>$1<span class="token">**</span></span>');
line = line.replace(/__([^\s].*?)__/ig, '<span class="bold"><span class="token">__</span>$1<span class="token">__</span></span>');
return line;
}
export { load, formatLine };

@ -0,0 +1,28 @@
import { getStartPositionInLine, setStartPositionInLine } from './position.js';
import { formatLine, load } from './md.js';
function onedit(e) {
let ret = getStartPositionInLine();
let line = ret[0];
let position = ret[1];
if (line.innerText == '\n') {
line.className = 'mdnotes_line';
return;
}
let newline = formatLine(line.innerText);
line.parentNode.replaceChild(newline, line);
setStartPositionInLine(newline, position);
}
function init() {
let mdnotesdiv = document.getElementById('mdnotes');
mdnotesdiv.addEventListener('input', onedit);
load(document.getElementById('ta'), mdnotesdiv);
}
export { onedit };
init();

@ -0,0 +1,74 @@
function getStartPositionInLine() {
let selection = window.getSelection();
if (selection.rangeCount == 0) {
return [null, 0];
}
let range = selection.getRangeAt(0).cloneRange();
let obj = range.startContainer;
let position = range.startOffset;
if (obj.nodeName == 'DIV' && obj.classList.contains('mdnotes_line')) {
return [obj, position];
}
let line = null;
while (obj != null) {
if (obj.previousSibling != null) {
obj = obj.previousSibling;
if (obj.innerText != null) {
position += obj.innerText.length;
} else if (obj.length != null) {
position += obj.length;
}
} else if (obj.parentNode != null && obj.parentNode.classList != null && !obj.parentNode.classList.contains('mdnotes_line')) {
obj = obj.parentNode;
} else if (obj.parentNode != null && obj.parentNode.classList != null && obj.parentNode.classList.contains('mdnotes_line')) {
line = obj.parentNode;
obj = null;
} else {
obj = null;
}
}
return [line, position];
}
function setStartPositionInLine(line, position) {
setStartPositionInDiv(line, position)
}
function setStartPositionInDiv(obj, position) {
let temppos = position;
if (temppos > obj.innerText.length) {
return temppos - obj.innerText.length;
}
let children = obj.childNodes;
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (child.nodeType == 3) {
temppos = setStartPositionInText(child, temppos);
} else {
temppos = setStartPositionInDiv(child, temppos);
}
if (temppos == 0) {
return temppos;
}
}
return temppos;
}
function setStartPositionInText(obj, position) {
if (position > obj.length) {
return position - obj.length;
}
let selection = window.getSelection();
selection.removeAllRanges();
let range = document.createRange();
range.setStart(obj, position);
selection.addRange(range);
return 0;
}
export { getStartPositionInLine, setStartPositionInLine };

@ -1,5 +1,12 @@
<html> <html>
<head> <head>
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="fr">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>{{name}}</title> <title>{{name}}</title>
<link rel="stylesheet" href="static/mdnotes.css"> <link rel="stylesheet" href="static/mdnotes.css">
</head> </head>
@ -13,8 +20,11 @@ Encore un joli texte
### Titre 3-2 ### Titre 3-2
T'en as marre ??? T'en as marre ???
#### Titre 4 #### Titre 4
- coucou
- pas vrai
- tant pis
Moi oui !!!</textarea> Moi oui !!!</textarea>
<div id="mdnotes" class="mdnotes" oninput="return change(event)" contenteditable="true"></div> <div id="mdnotes" class="mdnotes" contenteditable="true"></div>
<script type="text/javascript" src="static/mdnotes.js"></script> <script type="module" src="static/modules/mdnotes.js"></script>
</body> </body>
</html> </html>

Loading…
Cancel
Save