mdkatex.html 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <head>
  2. <base>
  3. <script src="https://fastly.jsdelivr.net/npm/marked@3.0.7/marked.min.js"></script>
  4. <script src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js" crossorigin="anonymous"></script>
  5. <script>
  6. const renderer = new marked.Renderer();
  7. var options = {
  8. renderer: renderer,
  9. pedantic: false,
  10. gfm: true,
  11. breaks: false,
  12. sanitize: false,
  13. smartLists: true,
  14. smartypants: false,
  15. xhtml: false
  16. };
  17. marked.setOptions(options);
  18. function htmldecode(text){
  19. var temp = document.createElement("div");
  20. temp.innerHTML = text;
  21. var output = temp.innerText || temp.textContent;
  22. temp = null;
  23. return output;
  24. }
  25. function mathsExpression(expr) {
  26. if (expr.match(/^\$\$[\s\S]*\$\$$/)) {
  27. expr = expr.substr(2, expr.length - 4);
  28. return katex.renderToString(expr, { displayMode: true });
  29. } else if (expr.match(/^\$[\s\S]*\$$/)) {
  30. expr = htmldecode(expr); // temp solution
  31. expr = expr.substr(1, expr.length - 2);
  32. return katex.renderToString(expr, { displayMode: false });
  33. }
  34. }
  35. const unchanged = new marked.Renderer()
  36. renderer.code = function(code, lang, escaped) {
  37. if (!lang) {
  38. const math = mathsExpression(code);
  39. if (math) {
  40. return math;
  41. }
  42. }
  43. return unchanged.code(code, lang, escaped);
  44. };
  45. renderer.codespan = function(text) {
  46. const math = mathsExpression(text);
  47. if (math) {
  48. return math;
  49. }
  50. return unchanged.codespan(text);
  51. };
  52. function markedWithKatex(text) {
  53. return marked(text, options);
  54. }
  55. function absFile(url) {
  56. this.name=url;
  57. this.slice = async(offset, length) =>{
  58. const headers = new Headers();
  59. headers.append('range', 'bytes=' + offset + '-' + ( offset + length -1).toString());
  60. const opts = {
  61. credentials: 'include',
  62. headers : headers
  63. };
  64. const resp = await fetch( this.name, opts );
  65. return await resp.arrayBuffer();
  66. //alert(JSON.stringify(resp.headers));
  67. //return await resp.text();
  68. }
  69. }
  70. var file;
  71. var blocksize = 20480;
  72. function loadSlice(){
  73. function render(u8array){
  74. document.body.innerHTML = markedWithKatex(new TextDecoder().decode(u8array));
  75. scroll(0,0);
  76. }
  77. function setPageUrl(pageurl){
  78. let a = document.createElement('a');
  79. a.href = "i:5c"+pageurl;
  80. a.click();
  81. }
  82. var page = 1;
  83. var extrasize = blocksize; //extrasize should <= blocksize
  84. let lhash = location.hash;
  85. if(lhash){
  86. if("p"!==lhash.charAt(1)){//#offset=&[len]
  87. let iAmpersand = lhash.indexOf('&',8);
  88. let offset = parseInt(lhash.substring(8,iAmpersand));
  89. let len = parseInt(lhash.substring(iAmpersand+1));
  90. {//update urlInc() url
  91. let href = location.href;
  92. let iHash = href.indexOf('#');
  93. href=href.substring(0,iHash)+"#page="+Math.floor((offset+len)/blocksize);
  94. setPageUrl(href);
  95. }
  96. file.slice(offset,len).then((buffer)=>{
  97. let u8 = new Uint8Array(buffer);
  98. render(u8);
  99. });
  100. return;
  101. }
  102. //#page=
  103. page = parseInt(lhash.substring(6));
  104. }else
  105. setPageUrl(location.href+"#page=1");
  106. file.slice(blocksize*(page-1),blocksize+extrasize).then((buffer)=>{
  107. let u8 = new Uint8Array(buffer);
  108. let u8len = u8.length;
  109. let iStart = 0;
  110. let limit = Math.min(u8len,extrasize);
  111. if(1!=page){
  112. for(let i=1;i<limit;i=i+2){
  113. if(10==u8[i] && 10==u8[i-1]) {
  114. iStart = i+1;
  115. break;
  116. }
  117. }
  118. }
  119. let iEnd = Math.min(u8len,blocksize);
  120. limit = Math.min(u8len,blocksize+extrasize);
  121. for(let i=blocksize+1;i<limit;i=i+2){
  122. if(10==u8[i] && 10==u8[i-1]) {
  123. iEnd = i+1;
  124. break;
  125. }
  126. }
  127. render(u8.slice(iStart,iEnd));
  128. });
  129. }
  130. //?url=#offset=&[len]&page=
  131. {
  132. let url = location.search.substring(5);
  133. file = new absFile(url);
  134. document.getElementsByTagName('base')[0].href=url;
  135. }
  136. window.addEventListener('hashchange',loadSlice);
  137. </script>
  138. </head>
  139. <body>
  140. <script>loadSlice();</script>
  141. </body>