From 426a96394fad1427ddb0ace2daf0c17a33995d09 Mon Sep 17 00:00:00 2001 From: gabriele-cusato Date: Thu, 19 Mar 2026 15:29:03 +0100 Subject: [PATCH] eliminata la cartella C, era un bug --- .../plugins/handwriting-to-markdown/main.js | 16 ++ .../handwriting-to-markdown/manifest.json | 9 + .../plugins/handwriting-to-markdown/styles.css | 259 ++++++++++++++++++ .../Projects/handwriting-to-markdown/main.js | 16 ++ .../handwriting-to-markdown/manifest.json | 9 + .../Projects/handwriting-to-markdown/styles.css | 259 ++++++++++++++++++ 6 files changed, 568 insertions(+) create mode 100644 HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/main.js create mode 100644 HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/manifest.json create mode 100644 HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/styles.css create mode 100644 HandTranscriptMd/C/Users/gabri/Il mio Drive (gabrielecusato@gmail.com)/Projects/handwriting-to-markdown/main.js create mode 100644 HandTranscriptMd/C/Users/gabri/Il mio Drive (gabrielecusato@gmail.com)/Projects/handwriting-to-markdown/manifest.json create mode 100644 HandTranscriptMd/C/Users/gabri/Il mio Drive (gabrielecusato@gmail.com)/Projects/handwriting-to-markdown/styles.css diff --git a/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/main.js b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/main.js new file mode 100644 index 0000000..c99c0ba --- /dev/null +++ b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/main.js @@ -0,0 +1,16 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var I=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var mt=Object.prototype.hasOwnProperty;var vt=(i,t)=>{for(var e in t)I(i,e,{get:t[e],enumerable:!0})},wt=(i,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of pt(t))!mt.call(i,s)&&s!==e&&I(i,s,{get:()=>t[s],enumerable:!(n=ut(t,s))||n.enumerable});return i};var ft=i=>wt(I({},"__esModule",{value:!0}),i);var $t={};vt($t,{default:()=>H});module.exports=ft($t);var st=require("obsidian");var v=require("obsidian"),bt={light:"#ffffff",dark:"#1e1e1e",custom:"#ffffff"},kt={light:"#e0e0e0",dark:"#3a3a3a",custom:"#cccccc"};function q(i){return i.bgMode==="custom"?i.bgCustomColor:bt[i.bgMode]}function Y(i){return i.bgMode==="custom"?yt(i.bgCustomColor):kt[i.bgMode]}function yt(i){let t=parseInt(i.slice(1,3),16),e=parseInt(i.slice(3,5),16),n=parseInt(i.slice(5,7),16),o=t*.299+e*.587+n*.114>128?-30:30,r=a=>Math.max(0,Math.min(255,a+o));return`#${r(t).toString(16).padStart(2,"0")}${r(e).toString(16).padStart(2,"0")}${r(n).toString(16).padStart(2,"0")}`}var W=["#000000","#1e40af","#dc2626","#16a34a"],X=["#ffffff","#60a5fa","#f87171","#4ade80"];function J(i,t){let e=i.toLowerCase();if(t==="dark"){let n=W.indexOf(e);if(n>=0)return X[n]}else if(t==="light"){let n=X.indexOf(e);if(n>=0)return W[n]}return i}var K={svgFolder:"_handwriting",canvasWidth:800,canvasHeight:300,bgMode:"light",bgCustomColor:"#ffffff",ocrLanguages:["it","en"],geminiApiKey:"",debugMode:!1},L=class extends v.PluginSettingTab{constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),t.createEl("h2",{text:"Handwriting to Markdown"}),new v.Setting(t).setName("Cartella SVG").setDesc("Cartella nel vault dove vengono salvati i file SVG dei disegni").addText(e=>e.setPlaceholder("_handwriting").setValue(this.plugin.settings.svgFolder).onChange(async n=>{this.plugin.settings.svgFolder=n||"_handwriting",await this.plugin.saveSettings()})),new v.Setting(t).setName("Larghezza canvas").setDesc("Risoluzione orizzontale del canvas in pixel").addText(e=>e.setValue(String(this.plugin.settings.canvasWidth)).onChange(async n=>{let s=parseInt(n);!isNaN(s)&&s>100&&(this.plugin.settings.canvasWidth=s,await this.plugin.saveSettings())})),new v.Setting(t).setName("Altezza canvas").setDesc("Risoluzione verticale del canvas in pixel").addText(e=>e.setValue(String(this.plugin.settings.canvasHeight)).onChange(async n=>{let s=parseInt(n);!isNaN(s)&&s>50&&(this.plugin.settings.canvasHeight=s,await this.plugin.saveSettings())})),new v.Setting(t).setName("Sfondo canvas").setDesc("Colore di sfondo del riquadro di disegno").addDropdown(e=>e.addOption("light","Chiaro (bianco)").addOption("dark","Scuro (grigio scuro)").addOption("custom","Personalizzato").setValue(this.plugin.settings.bgMode).onChange(async n=>{this.plugin.settings.bgMode=n,await this.plugin.saveSettings(),this.display()})),this.plugin.settings.bgMode==="custom"&&new v.Setting(t).setName("Colore sfondo personalizzato").setDesc("Scegli il colore hex dello sfondo").addColorPicker(e=>e.setValue(this.plugin.settings.bgCustomColor).onChange(async n=>{this.plugin.settings.bgCustomColor=n,await this.plugin.saveSettings()})),new v.Setting(t).setName("Chiave API Gemini").setDesc("Necessaria per il riconoscimento OCR della scrittura a mano. Ottienila da Google AI Studio (aistudio.google.com).").addText(e=>{e.setPlaceholder("AIza...").setValue(this.plugin.settings.geminiApiKey).onChange(async n=>{this.plugin.settings.geminiApiKey=n.trim(),await this.plugin.saveSettings()}),e.inputEl.type="password"}),new v.Setting(t).setName("Lingue OCR").setDesc('Codici lingua BCP-47 separati da virgola (es. "it, en, fr"). Usati dal riconoscitore di scrittura su Android.').addText(e=>e.setValue(this.plugin.settings.ocrLanguages.join(", ")).setPlaceholder("it, en").onChange(async n=>{let s=n.split(",").map(o=>o.trim()).filter(o=>o.length>0);this.plugin.settings.ocrLanguages=s.length>0?s:["it","en"],await this.plugin.saveSettings()})),new v.Setting(t).setName("Modalit\xE0 debug").setDesc("Mostra notifiche in tempo reale per eventi IME/touch (utile per diagnosticare problemi su Android).").addToggle(e=>e.setValue(this.plugin.settings.debugMode).onChange(async n=>{this.plugin.settings.debugMode=n,await this.plugin.saveSettings()}))}};var h=require("obsidian");function P(i){return i.map(t=>({points:t.points.map(e=>({...e})),color:t.color,width:t.width}))}var E=class{constructor(t,e,n,s,o=!1,r=null){this.strokes=[];this.currentStroke=null;this.mode="pen";this.color="#000000";this.lineWidth=2;this.isDrawing=!1;this.changeCb=null;this.mobileMode=!1;this.history=[];this.historyIdx=-1;this.eraserChanged=!1;this.LINE_SPACING=32;this.bgColor="#ffffff";this.lineColor="#e0e0e0";this.EXPAND_MARGIN=40;this.EXPAND_AMOUNT=150;this.animFrameId=null;this.boundBeforeInput=null;this.container=null;this.debugFn=null;this.canvas=document.createElement("canvas"),this.canvas.width=e,this.canvas.height=n,this.defaultHeight=s,this.mobileMode=o,this.container=t,this.debugFn=r,o&&(this.boundBeforeInput=a=>{var c;this.isDrawing&&((c=this.debugFn)==null||c.call(this,"\u{1F6AB} beforeinput bloccato"),a.preventDefault())},document.addEventListener("beforeinput",this.boundBeforeInput,!0)),this.canvas.classList.add("hwm_canvas"),this.canvas.style.setProperty("touch-action","none","important"),t.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.clearBackground(),this.pushHistory(),this.boundDown=this.onPointerDown.bind(this),this.boundMove=this.onPointerMove.bind(this),this.boundUp=this.onPointerUp.bind(this),this.canvas.addEventListener("pointerdown",this.boundDown),this.canvas.addEventListener("pointermove",this.boundMove),this.canvas.addEventListener("pointerup",this.boundUp),this.canvas.addEventListener("pointerleave",this.boundUp)}onChange(t){this.changeCb=t}setMode(t){this.mode=t}getMode(){return this.mode}setColor(t){this.color=t}setLineWidth(t){this.lineWidth=t}getStrokes(){return[...this.strokes]}getWidth(){return this.canvas.width}getHeight(){return this.canvas.height}setBackground(t,e){this.bgColor=t,this.lineColor=e,this.redraw()}getBgColor(){return this.bgColor}getLineColor(){return this.lineColor}loadStrokes(t){this.strokes=P(t),this.history=[],this.historyIdx=-1,this.pushHistory(),this.redraw()}undo(){var t;return this.historyIdx<=0?!1:(this.historyIdx--,this.strokes=P(this.history[this.historyIdx]),this.redraw(),(t=this.changeCb)==null||t.call(this),!0)}redo(){var t;return this.historyIdx>=this.history.length-1?!1:(this.historyIdx++,this.strokes=P(this.history[this.historyIdx]),this.redraw(),(t=this.changeCb)==null||t.call(this),!0)}clear(){var t;this.strokes=[],this.pushHistory(),this.redraw(),this.animateHeight(this.defaultHeight),(t=this.changeCb)==null||t.call(this)}resizeHeight(t){t<100||(this.canvas.height=t,this.redraw())}destroy(){this.animFrameId!==null&&cancelAnimationFrame(this.animFrameId),this.canvas.removeEventListener("pointerdown",this.boundDown),this.canvas.removeEventListener("pointermove",this.boundMove),this.canvas.removeEventListener("pointerup",this.boundUp),this.canvas.removeEventListener("pointerleave",this.boundUp),this.boundBeforeInput&&(document.removeEventListener("beforeinput",this.boundBeforeInput,!0),this.boundBeforeInput=null)}pushHistory(){this.history=this.history.slice(0,this.historyIdx+1),this.history.push(P(this.strokes)),this.historyIdx=this.history.length-1}onPointerDown(t){var s,o;let e=t.pointerType||"pen";if(this.mobileMode&&e==="touch"){(s=this.debugFn)==null||s.call(this,"\u{1F446} Dito sul canvas"),t.stopPropagation();return}t.preventDefault(),this.mobileMode&&((o=this.debugFn)==null||o.call(this,`\u{1F58A} pointerdown tipo="${t.pointerType}" \u2192 "${e}"`),t.stopPropagation()),this.canvas.setPointerCapture(t.pointerId),this.isDrawing=!0;let n=this.eventToPoint(t);this.mode==="pen"?this.currentStroke={points:[n],color:this.color,width:this.lineWidth}:(this.eraserChanged=!1,this.eraseAt(n))}onPointerMove(t){if(this.mobileMode&&(t.pointerType||"pen")==="touch"||!this.isDrawing)return;t.preventDefault();let e=this.eventToPoint(t);this.mode==="pen"&&this.currentStroke?(this.currentStroke.points.push(e),this.drawSegment(this.currentStroke),this.checkAutoExpand(e)):this.mode==="eraser"&&this.eraseAt(e)}onPointerUp(t){var e,n;this.mobileMode&&(t.pointerType||"pen")==="touch"||this.isDrawing&&(this.isDrawing=!1,this.mode==="pen"&&this.currentStroke?(this.currentStroke.points.length>=2&&(this.strokes.push(this.currentStroke),this.pushHistory(),(e=this.changeCb)==null||e.call(this)),this.currentStroke=null):this.mode==="eraser"&&this.eraserChanged&&(this.pushHistory(),(n=this.changeCb)==null||n.call(this)))}checkAutoExpand(t){if(this.animFrameId===null&&t.y>this.canvas.height-this.EXPAND_MARGIN){let e=this.canvas.height+this.EXPAND_AMOUNT;this.animateHeight(e)}}animateHeight(t){let e=this.canvas.height;if(e===t)return;this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null);let n=300,s=performance.now(),o=r=>{let a=r-s,c=Math.min(a/n,1),l=1-Math.pow(1-c,3),p=Math.round(e+(t-e)*l);this.canvas.height=p,this.redraw(),this.currentStroke&&this.drawFullStroke(this.currentStroke),c<1?this.animFrameId=requestAnimationFrame(o):this.animFrameId=null};this.animFrameId=requestAnimationFrame(o)}eventToPoint(t){let e=this.canvas.getBoundingClientRect(),n=this.canvas.width/e.width,s=this.canvas.height/e.height;return{x:(t.clientX-e.left)*n,y:(t.clientY-e.top)*s,pressure:t.pressure>0?t.pressure:.5}}eraseAt(t){let s=!1,o=[];for(let r of this.strokes){let a=[],c=!1;for(let l of r.points){let p=l.x-t.x,m=l.y-t.y;p*p+m*m<225?(a.length>=2&&o.push({points:[...a],color:r.color,width:r.width}),a=[],c=!0):a.push(l)}c?(s=!0,a.length>=2&&o.push({points:[...a],color:r.color,width:r.width})):o.push(r)}s&&(this.strokes=o,this.eraserChanged=!0,this.redraw())}clearBackground(){let t=this.canvas.width,e=this.canvas.height;this.ctx.fillStyle=this.bgColor,this.ctx.fillRect(0,0,t,e),this.ctx.strokeStyle=this.lineColor,this.ctx.lineWidth=.5;for(let n=this.LINE_SPACING;n0?e[s-1]:e[0],r=e[s],a=e[s+1],c=(o.x+r.x)/2,l=(o.y+r.y)/2,p=(r.x+a.x)/2,m=(r.y+a.y)/2;n.moveTo(c,l),n.quadraticCurveTo(r.x,r.y,p,m)}n.stroke()}};function Z(){let i=Date.now().toString(36),t=Math.random().toString(36).substring(2,6);return`hw_${i}_${t}`}function xt(i){if(i.length<2)return"";let t=[];if(t.push(`M ${w(i[0].x)},${w(i[0].y)}`),i.length===2)t.push(`L ${w(i[1].x)},${w(i[1].y)}`);else{for(let n=1;n`)}let r=JSON.stringify(i),a=32,c=[];for(let l=a;l`);return[``,` `,...c,` ${Ct(r)}`,...o,""].join(` +`)}function Q(i){var t;try{let e=i.match(/([\s\S]*?)<\/desc>/);if(!e)return[];let n=St((t=e[1])!=null?t:""),s=JSON.parse(n);return Array.isArray(s)?s.filter(o=>Array.isArray(o.points)&&typeof o.color=="string"&&typeof o.width=="number"):[]}catch(e){return[]}}function Ct(i){return i.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}function St(i){return i.replace(/"/g,'"').replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&")}var Mt="gemini-3.1-flash-lite-preview",Lt=`https://generativelanguage.googleapis.com/v1beta/models/${Mt}:generateContent`,B=class{constructor(t,e){this.apiKey=t;this.languages=e}async recognize(t){var a,c,l,p,m,x,M,k;let n=`Sei un sistema OCR specializzato in scrittura a mano. Analizza l'immagine e trascrivi esattamente il testo scritto. Le lingue attese sono: ${this.languages.join(", ")}. Preserva i simboli markdown scritti dall'utente (es. #, ##, ###, -, *, >, \`\`\`, **testo**, *testo*, ==testo==, ~~testo~~, - [ ], - [x]). Restituisci SOLO il testo trascritto, senza alcuna spiegazione aggiuntiva.`,s=await fetch(`${Lt}?key=${this.apiKey}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contents:[{parts:[{inline_data:{mime_type:"image/png",data:t}},{text:n}]}]})});if(!s.ok){let y=await s.json().catch(()=>({}));throw new Error(`Gemini ${s.status}: ${(c=(a=y==null?void 0:y.error)==null?void 0:a.message)!=null?c:s.statusText}`)}let o=await s.json();return((k=(M=(x=(m=(p=(l=o==null?void 0:o.candidates)==null?void 0:l[0])==null?void 0:p.content)==null?void 0:m.parts)==null?void 0:x[0])==null?void 0:M.text)!=null?k:"").trim()}};function tt(i,t){if(!i.trim())throw new Error("Chiave API Gemini non configurata \u2014 aprire le impostazioni del plugin");return new B(i,t)}function et(i){return i.split(` +`).map(Pt).join(` +`)}function Pt(i){let t=i.trim();return t?/^-{3,}$/.test(t)?"---":/^#{1,3}\s+/.test(t)?t:/^-\s*\[x\]\s*/i.test(t)?`- [x] ${t.replace(/^-\s*\[x\]\s*/i,"")}`:/^-\s*\[\s*\]\s*/.test(t)?`- [ ] ${t.replace(/^-\s*\[\s*\]\s*/,"")}`:/^[-*]\s+/.test(t)?`- ${t.replace(/^[-*]\s+/,"")}`:(/^\d+\.\s+/.test(t)||/^>\s*/.test(t)||t.startsWith("```"),t):""}var A={pencil:'',eraser:'',"rotate-ccw":'',"rotate-cw":'',trash:'',"file-text":'',save:'',x:'',"chevron-down":'',"chevron-up":''};function nt(i){i.registerMarkdownCodeBlockProcessor("handwriting",async(t,e,n)=>{await Et(t,e,n,i)})}async function Et(i,t,e,n){let s;try{s=JSON.parse(i.trim())}catch(c){t.createEl("p",{text:"Handwriting: JSON non valido",cls:"hwm_error"});return}let o=t.createDiv({cls:"hwm_container"}),{strokes:r,canvasHeight:a}=await It(s.svg,n);Ht(o,r,a,s,e,n)}function Ht(i,t,e,n,s,o){i.empty(),i.classList.add("hwm_editing");let r=h.Platform.isMobile;r&&i.classList.add("hwm_mobile");let a=o.settings.bgMode==="dark",c=i.createDiv({cls:"hwm_toolbar"});a&&c.classList.add("hwm_toolbar--dark");let l=null;r&&(c.classList.add("hwm_toolbar--compact"),l=b(c,"chevron-down","Mostra tutti i controlli"),l.classList.add("hwm_toggle-btn"),l.addEventListener("click",()=>{var d,f;c.classList.contains("hwm_toolbar--compact")?(c.classList.remove("hwm_toolbar--compact"),y(!1),l.innerHTML=(d=A["chevron-up"])!=null?d:"",l.title="Comprimi toolbar"):(c.classList.add("hwm_toolbar--compact"),y(!0),l.innerHTML=(f=A["chevron-down"])!=null?f:"",l.title="Mostra tutti i controlli")}));let p=b(c,"pencil","Penna");p.classList.add("hwm_active","hwm_pen-btn");let m=b(c,"eraser","Gomma");m.classList.add("hwm_eraser-btn"),c.createDiv({cls:"hwm_separator"});let x=a?["#ffffff","#60a5fa","#f87171","#4ade80"]:["#000000","#1e40af","#dc2626","#16a34a"],M=c.createDiv({cls:"hwm_colors"}),k=[];for(let u of x){let d=M.createEl("div",{cls:"hwm_color-btn",attr:{title:u,role:"button",tabindex:"0"}});d.style.backgroundColor=u,d.style.setProperty("width","22px","important"),d.style.setProperty("height","22px","important"),d.style.setProperty("min-width","22px","important"),d.style.setProperty("min-height","22px","important"),d.style.setProperty("border-radius","50%","important"),d.style.setProperty("box-sizing","border-box","important"),d.style.setProperty("flex-shrink","0","important"),u===x[0]&&d.classList.add("hwm_active"),k.push(d)}c.createDiv({cls:"hwm_separator"});let y=u=>{k.forEach(d=>{let f=d.classList.contains("hwm_active"),S=!u||f?"22px":"0";d.style.setProperty("min-width",S,"important"),d.style.setProperty("min-height",S,"important")})};r&&y(!0);let F=b(c,"rotate-ccw","Annulla (Undo)");F.classList.add("hwm_undo-btn");let R=b(c,"rotate-cw","Ripristina (Redo)");R.classList.add("hwm_redo-btn");let N=b(c,"trash","Cancella tutto");N.classList.add("hwm_clear-btn"),c.createDiv({cls:"hwm_separator"});let z=b(c,"file-text","Converti in Markdown");z.classList.add("hwm_convert-btn");let O=b(c,"save","Salva");O.classList.add("hwm_save-btn");let G=b(c,"x","Elimina riquadro");G.classList.add("hwm_delete-btn");let ot=i.createDiv({cls:"hwm_canvas-wrap"}),{canvasWidth:rt,canvasHeight:j}=o.settings,at=e!=null?e:j,ct=o.settings.debugMode?u=>new h.Notice(u,3e3):null,g=new E(ot,rt,at,j,r,ct),U=q(o.settings),lt=Y(o.settings);if(g.setBackground(U,lt),g.setColor(x[0]),i.style.backgroundColor=U,t.length>0){let u=t.map(d=>({...d,color:J(d.color,o.settings.bgMode)}));g.loadStrokes(u),_(g,n,o)}let C=i.createDiv({cls:"hwm_resize-handle"});C.createEl("span",{text:"\u22EF"}),a&&(C.style.background="#2a2a2a",C.style.borderTopColor="#444",C.style.color="#888"),Dt(C,g),p.addEventListener("click",()=>{g.setMode("pen"),p.classList.add("hwm_active"),m.classList.remove("hwm_active")}),m.addEventListener("click",()=>{g.setMode("eraser"),m.classList.add("hwm_active"),p.classList.remove("hwm_active")});for(let u=0;u{k.forEach(S=>S.classList.remove("hwm_active")),d.classList.add("hwm_active"),g.setColor(f),r&&y(c.classList.contains("hwm_toolbar--compact"))})}F.addEventListener("click",()=>g.undo()),R.addEventListener("click",()=>g.redo()),N.addEventListener("click",()=>g.clear()),z.addEventListener("click",async()=>{let u=g.getStrokes();if(u.length===0){new h.Notice("Nessun tratto da convertire");return}try{new h.Notice("Riconoscimento in corso\u2026");let d=T(u,g.getWidth(),g.getHeight(),g.getBgColor(),g.getLineColor()),dt=new DOMParser().parseFromString(d,"image/svg+xml").documentElement,ht=await At(dt),V=await tt(o.settings.geminiApiKey,o.settings.ocrLanguages).recognize(ht);if(!V.trim()){new h.Notice("Nessun testo riconosciuto");return}let gt=et(V);await Bt(n,o),g.destroy(),await _t(s,n,gt,o),new h.Notice("Conversione completata!")}catch(d){let f=d instanceof Error?d.message:String(d);new h.Notice("Errore OCR: "+f)}}),O.addEventListener("click",async()=>{await _(g,n,o)}),G.addEventListener("click",async()=>{confirm("Eliminare questo riquadro handwriting e il file SVG associato?")&&(g.destroy(),await Tt(s,n,o))});let D=null;g.onChange(()=>{D&&clearTimeout(D),D=setTimeout(async()=>{await _(g,n,o)},2e3)})}function Dt(i,t){let e=0,n=0,s=r=>{r.preventDefault();let a=r.clientY-e,c=Math.max(100,n+a);t.resizeHeight(c)},o=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",o)};i.addEventListener("pointerdown",r=>{r.preventDefault(),e=r.clientY,n=t.getHeight(),document.addEventListener("pointermove",s),document.addEventListener("pointerup",o)})}async function It(i,t){var n;let e=t.app.vault.getAbstractFileByPath(i);if(e instanceof h.TFile){let s=await t.app.vault.read(e),o=Q(s),r=s.match(/viewBox="0 0 \d+ (\d+)"/),a=r?parseInt((n=r[1])!=null?n:"0"):null;return{strokes:o,canvasHeight:a}}return{strokes:[],canvasHeight:null}}async function _(i,t,e){let n=i.getStrokes(),s=i.getWidth(),o=i.getHeight(),r=T(n,s,o,i.getBgColor(),i.getLineColor()),a=t.svg.substring(0,t.svg.lastIndexOf("/"));a&&(e.app.vault.getAbstractFileByPath(a)||await e.app.vault.createFolder(a));let c=e.app.vault.getAbstractFileByPath(t.svg);c instanceof h.TFile?await e.app.vault.modify(c,r):await e.app.vault.create(t.svg,r)}async function Tt(i,t,e){let n=e.app.vault.getAbstractFileByPath(i.sourcePath);if(!(n instanceof h.TFile)){new h.Notice("File markdown non trovato");return}let s=await e.app.vault.read(n),o=new RegExp('\\n?```handwriting\\n.*?"id"\\s*:\\s*"'+it(t.id)+'".*?\\n```\\n?',"s"),r=s.replace(o,` +`);r!==s&&await e.app.vault.modify(n,r);let a=e.app.vault.getAbstractFileByPath(t.svg);a instanceof h.TFile&&await e.app.vault.delete(a),new h.Notice("Riquadro eliminato")}function it(i){return i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function Bt(i,t){let e=t.app.vault.getAbstractFileByPath(i.svg);if(!(e instanceof h.TFile))return;let n=new Date,s=a=>String(a).padStart(2,"0"),o=`${n.getFullYear()}-${s(n.getMonth()+1)}-${s(n.getDate())}_${s(n.getHours())}-${s(n.getMinutes())}-${s(n.getSeconds())}`,r=`${t.settings.svgFolder}/_converted`;t.app.vault.getAbstractFileByPath(r)||await t.app.vault.createFolder(r),await t.app.vault.rename(e,`${r}/${o}.svg`)}async function _t(i,t,e,n){let s=n.app.vault.getAbstractFileByPath(i.sourcePath);if(!(s instanceof h.TFile)){new h.Notice("File markdown non trovato");return}let o=await n.app.vault.read(s),r=new RegExp('\\n?```handwriting\\n.*?"id"\\s*:\\s*"'+it(t.id)+'".*?\\n```\\n?',"s"),a=o.replace(r,` +`+e+` +`);a!==o&&await n.app.vault.modify(s,a)}function $(i){let t=i.app.workspace.getActiveViewOfType(h.MarkdownView);if(!t){new h.Notice("Apri un file markdown prima");return}let e=t.editor,n=Z(),s=`${i.settings.svgFolder}/${n}.svg`,o=` +\`\`\`handwriting +{"id":"${n}","svg":"${s}"} +\`\`\` +`;e.replaceSelection(o)}function b(i,t,e){var s;let n=i.createEl("button",{cls:"hwm_btn",attr:{title:e}});return n.innerHTML=(s=A[t])!=null?s:"",n}function At(i){return new Promise((t,e)=>{let n=document.createElement("canvas"),s=n.getContext("2d"),o=new Image,r=new Blob([new XMLSerializer().serializeToString(i)],{type:"image/svg+xml"}),a=URL.createObjectURL(r);o.onload=()=>{n.width=o.width,n.height=o.height,s.drawImage(o,0,0),URL.revokeObjectURL(a),t(n.toDataURL("image/png").split(",")[1])},o.onerror=()=>{URL.revokeObjectURL(a),e(new Error("Errore conversione SVG \u2192 PNG"))},o.src=a})}var H=class extends st.Plugin{async onload(){await this.loadSettings(),nt(this),this.addCommand({id:"insert-handwriting",name:"Insert handwriting block",editorCallback:()=>{$(this)}}),this.addRibbonIcon("pencil","Insert handwriting",()=>{$(this)}),this.addSettingTab(new L(this.app,this))}async loadSettings(){this.settings=Object.assign({},K,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}}; diff --git a/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/manifest.json b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/manifest.json new file mode 100644 index 0000000..6164881 --- /dev/null +++ b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/manifest.json @@ -0,0 +1,9 @@ +{ + "id": "handwriting-to-markdown", + "name": "Handwriting to Markdown", + "version": "0.1.0", + "minAppVersion": "0.15.0", + "description": "Inline handwriting canvas with conversion to structured markdown", + "author": "GabrieleC", + "isDesktopOnly": false +} diff --git a/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/styles.css b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/styles.css new file mode 100644 index 0000000..f08abec --- /dev/null +++ b/HandTranscriptMd/C/Projects/CLIENTI/IOTTI/IOTTI_APP/_docs/handwriting-to-markdown/.obsidian/plugins/handwriting-to-markdown/styles.css @@ -0,0 +1,259 @@ +/* ======================================== + Handwriting to Markdown — Plugin Styles + Prefisso hwm_ per evitare conflitti + ======================================== */ + +/* --- Container principale dell'embed --- */ +.hwm_container { + position: relative; + border: 1px solid var(--background-modifier-border); + border-radius: 8px; + overflow: hidden; + margin: 8px 0; + /* Sfondo SEMPRE bianco (anche in dark mode) */ + background: #ffffff; +} + +/* --- Toolbar in alto a destra --- */ +.hwm_toolbar { + position: absolute; + top: 6px; + right: 6px; + z-index: 10; + display: flex; + align-items: center; + gap: 0; /* spacing gestito via margin-right sui bottoni, così i bottoni + nascosti (max-width:0, margin:0) non creano spazi vuoti */ + padding: 3px 6px; + border-radius: 6px; + background: rgba(240, 240, 240, 0.95); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); + opacity: 1; + transition: opacity 0.2s; +} + +/* --- Bottoni toolbar --- */ +.hwm_btn { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + padding: 0; + border: none; + border-radius: 4px; + background: transparent; + color: #666; + cursor: pointer; + line-height: 0; + /* Spacing via margin-right invece di gap, così i bottoni nascosti + (margin:0) non lasciano spazi vuoti nella toolbar compatta */ + margin-right: 4px; + /* Animazione espansione/compressione toolbar */ + overflow: hidden; + max-width: 40px; + flex-shrink: 0; + transition: max-width 0.2s ease, opacity 0.2s ease, + margin 0.2s ease, padding 0.2s ease; +} +/* Icone SVG inline dentro i bottoni */ +.hwm_btn svg { + width: 16px; + height: 16px; + flex-shrink: 0; +} +.hwm_btn:hover { + background: #e0e0e0; + color: #333; +} +/* Bottone attivo (tool selezionato) */ +.hwm_btn.hwm_active { + background: var(--interactive-accent); + color: #ffffff; +} + +/* --- Bottone salva (evidenziato) --- */ +.hwm_save-btn { + margin-left: 4px; +} +.hwm_save-btn:hover { + background: var(--interactive-accent); + color: #ffffff; +} + +/* --- Bottone elimina (X rossa su hover) --- */ +.hwm_delete-btn:hover { + background: #dc2626; + color: #ffffff; +} + +/* --- Selettore colori --- */ +.hwm_colors { + display: flex; + align-items: center; + gap: 3px; + margin: 0 4px; +} +/* I pallini colore sono
(non