diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-02-17 23:44:07 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-02-17 23:44:07 +0100 |
| commit | e30801b1d356cf6a7998601433b0c881d6546dcb (patch) | |
| tree | d6794f490a8301b5357159443d02baa74e0a05de | |
| download | oide2java-e30801b1d356cf6a7998601433b0c881d6546dcb.tar.gz oide2java-e30801b1d356cf6a7998601433b0c881d6546dcb.zip | |
add initial prototype
| -rw-r--r-- | oide2java.html | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/oide2java.html b/oide2java.html new file mode 100644 index 0000000..5971dfd --- /dev/null +++ b/oide2java.html @@ -0,0 +1,261 @@ +<!DOCTYPE html> +<html> +<head> + <title>Convert online-ide projects to java</title> + <meta charset="utf8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="author" content="Florian Fischer"> + + <style> + :root { + /* define applied colors */ + --bg: #fdfdfd; + --fg: #1a1a1a; + --link-color: #0000EE; + } + @media (prefers-color-scheme: dark) { + /* change apllied colors to the dark gruvbox pallet + * https://github.com/morhetz/gruvbox + */ + :root { + --bg: #282828; /* dark bg */ + --fg: #ebdbb2; /* dark fg */ + --link-color: #d79921; /* yellow */ + } + } + + html { + line-height: 1.5; + font-family: Georgia, serif; + font-size: 20px; + color: var(--fg); + background-color: var(--bg); + } + + body { + margin: 0 auto; + max-width: 36em; + padding-left: 50px; + padding-right: 50px; + padding-top: 50px; + padding-bottom: 50px; + hyphens: auto; + word-wrap: break-word; + text-rendering: optimizeLegibility; + font-kerning: normal; + } + + footer { + position:absolute; + bottom: 0; + } + + a { + color: var(--link-color); + } + + a:visited { + color: var(--link-color); + } + + @media (max-width: 600px) { + body { + font-size: 0.9em; + padding: 1em; + } + } + </style> + + <script language="javascript" type="text/javascript"> + /* Zip class put into public domain by Spiderpoison + https://stackoverflow.com/questions/8608724/how-to-zip-files-using-javascript + */ + class Zip { + + constructor(name) { + this.name = name; + this.zip = new Array(); + this.file = new Array(); + } + + dec2bin=(dec,size)=>dec.toString(2).padStart(size,'0'); + str2dec=str=>Array.from(new TextEncoder().encode(str)); + str2hex=str=>[...new TextEncoder().encode(str)].map(x=>x.toString(16).padStart(2,'0')); + hex2buf=hex=>new Uint8Array(hex.split(' ').map(x=>parseInt(x,16))); + bin2hex=bin=>(parseInt(bin.slice(8),2).toString(16).padStart(2,'0')+' '+parseInt(bin.slice(0,8),2).toString(16).padStart(2,'0')); + + reverse=hex=>{ + let hexArray=new Array(); + for(let i=0;i<hex.length;i=i+2)hexArray[i]=hex[i]+''+hex[i+1]; + return hexArray.filter((a)=>a).reverse().join(' '); + } + + crc32=r=>{ + for(var a,o=[],c=0;c<256;c++){ + a=c; + for(var f=0;f<8;f++)a=1&a?3988292384^a>>>1:a>>>1; + o[c]=a; + } + for(var n=-1,t=0;t<r.length;t++)n=n>>>8^o[255&(n^r[t])]; + return this.reverse(((-1^n)>>>0).toString(16).padStart(8,'0')); + } + + fecth2zip(filesArray,folder=''){ + filesArray.forEach(fileUrl=>{ + let resp; + fetch(fileUrl).then(response=>{ + resp=response; + return response.arrayBuffer(); + }).then(blob=>{ + new Response(blob).arrayBuffer().then(buffer=>{ + console.log(`File: ${fileUrl} load`); + let uint=[...new Uint8Array(buffer)]; + uint.modTime=resp.headers.get('Last-Modified'); + uint.fileUrl=`${this.name}/${folder}${fileUrl}`; + this.zip[fileUrl]=uint; + }); + }); + }); + } + + str2zip(name,str,folder){ + let uint=[...new Uint8Array(this.str2dec(str))]; + uint.name=name; + uint.modTime=new Date(); + uint.fileUrl=`${this.name}/${folder}${name}`; + this.zip[uint.fileUrl]=uint; + } + + files2zip(files,folder){ + for(let i=0;i<files.length;i++){ + files[i].arrayBuffer().then(data=>{ + let uint=[...new Uint8Array(data)]; + uint.name=files[i].name; + uint.modTime=files[i].lastModifiedDate; + uint.fileUrl=`${this.name}/${folder}${files[i].name}`; + this.zip[uint.fileUrl]=uint; + }); + } + } + + makeZip(){ + let count=0; + let fileHeader=''; + let centralDirectoryFileHeader=''; + let directoryInit=0; + let offSetLocalHeader='00 00 00 00'; + let zip=this.zip; + for(const name in zip){ + let modTime=(()=>{ + const lastMod=new Date(zip[name].modTime); + const hour=this.dec2bin(lastMod.getHours(),5); + const minutes=this.dec2bin(lastMod.getMinutes(),6); + const seconds=this.dec2bin(Math.round(lastMod.getSeconds()/2),5); + const year=this.dec2bin(lastMod.getFullYear()-1980,7); + const month=this.dec2bin(lastMod.getMonth()+1,4); + const day=this.dec2bin(lastMod.getDate(),5); + return this.bin2hex(`${hour}${minutes}${seconds}`)+' '+this.bin2hex(`${year}${month}${day}`); + })(); + let crc=this.crc32(zip[name]); + let size=this.reverse(parseInt(zip[name].length).toString(16).padStart(8,'0')); + let nameFile=this.str2hex(zip[name].fileUrl).join(' '); + let nameSize=this.reverse(zip[name].fileUrl.length.toString(16).padStart(4,'0')); + let fileHeader=`50 4B 03 04 14 00 00 00 00 00 ${modTime} ${crc} ${size} ${size} ${nameSize} 00 00 ${nameFile}`; + let fileHeaderBuffer=this.hex2buf(fileHeader); + directoryInit=directoryInit+fileHeaderBuffer.length+zip[name].length; + centralDirectoryFileHeader=`${centralDirectoryFileHeader}50 4B 01 02 14 00 14 00 00 00 00 00 ${modTime} ${crc} ${size} ${size} ${nameSize} 00 00 00 00 00 00 01 00 20 00 00 00 ${offSetLocalHeader} ${nameFile} `; + offSetLocalHeader=this.reverse(directoryInit.toString(16).padStart(8,'0')); + this.file.push(fileHeaderBuffer,new Uint8Array(zip[name])); + count++; + } + centralDirectoryFileHeader=centralDirectoryFileHeader.trim(); + let entries=this.reverse(count.toString(16).padStart(4,'0')); + let dirSize=this.reverse(centralDirectoryFileHeader.split(' ').length.toString(16).padStart(8,'0')); + let dirInit=this.reverse(directoryInit.toString(16).padStart(8,'0')); + let centralDirectory=`50 4b 05 06 00 00 00 00 ${entries} ${entries} ${dirSize} ${dirInit} 00 00`; + this.file.push(this.hex2buf(centralDirectoryFileHeader),this.hex2buf(centralDirectory)); + let a = document.createElement('a'); + a.href = URL.createObjectURL(new Blob([...this.file],{type:'application/octet-stream'})); + a.download = `${this.name}.zip`; + a.click(); + } + } + </script> + + <script language="javascript" type="text/javascript"> + /* + @licstart The following is the entire license notice for the + JavaScript code in this page. + + Copyright (C) 2025 Florian Fischer + + The JavaScript code in this page is free software: you can + redistribute it and/or modify it under the terms of the GNU + General Public License (GNU GPL) as published by the Free Software + Foundation, either version 3 of the License, or any later version. + The code is distributed WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. + + As additional permission under GNU GPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + @licend The above is the entire license notice + for the JavaScript code in this page. + */ + + function convertCode(oideCode) { + // TODO: Use a better regex + // let printlnRegex = /^(\s*)(println)/g + let printlnRegex = /println/g + javaCode = oideCode.replace(printlnRegex, "System.out.println"); + + // TODO: Warn about long + + // TODO: Implement Online-IDE convenience conversion + + // TODO: move code outside of a class into a main method + return javaCode; + } + + function oide2java(workspace) { + let z = new Zip(workspace.name); + for (let module of workspace.modules) { + let moduleCode = convertCode(module.text); + z.str2zip(module.name + ".java", moduleCode, ""); + } + z.makeZip(); + } + + function convertWorkspaceFile() { + let workspaceFile = document.getElementById("json").files[0]; + let reader = new FileReader(); + reader.readAsText(workspaceFile); + + reader.onload = function() { + oide2java(JSON.parse(reader.result)); + }; + } + </script> +</head> + +<body> +<h2>Convert an Online-IDE workspace to java code</h2> +<p><i>The conversation is done by your browser and no data is transfered to or otherwise processed by a third party.</i></p> +<div> +<form> + Online-IDE workspace: + <input id="json" type="file" /> + <input id="convert_button" value="convert" type="button" onclick="convertWorkspaceFile();" /> + </code> +</form> +</div> +<footer> +<p xmlns:cc="http://creativecommons.org/ns#">Diese Seite von <span property="cc:attributionName">Florian Fischer</span> ist unter folgender Lizenz veröffentlicht: <a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-SA 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt=""></a></p> +</footer> + +</body> +</html> |
