Skip to content

Commit

Permalink
复i 公式
Browse files Browse the repository at this point in the history
  • Loading branch information
MuiseDestiny committed Apr 16, 2023
1 parent 5725d63 commit b048062
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 52 deletions.
8 changes: 8 additions & 0 deletions addon/chrome/content/md.css
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,14 @@
visibility: hidden;
}
}

.markdown-body math {
display: none;
}
.markdown-body svg {
margin-left: 2em;
}

.streaming>span:after,
.streaming>ul:last-child li:last-child:after,
.streaming>pre:last-child code:after,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zotero-gpt",
"version": "0.2.1",
"version": "0.2.2",
"description": "GPT Meet Zotero",
"config": {
"addonName": "Zotero GPT",
Expand Down
161 changes: 113 additions & 48 deletions src/modules/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const markdown = require("markdown-it")({
});
const mathjax3 = require('markdown-it-mathjax3');
markdown.use(mathjax3);
// {
// startup: { AssistiveMMLStartup: false }
// }


const fontFamily = `Söhne,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,Helvetica Neue,Arial,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji`
Expand Down Expand Up @@ -70,6 +73,10 @@ export default class Views {
* 记录当前GPT输出流setInterval的id,防止终止后仍有输出
*/
private _id: number | undefined
/**
* 是否在笔记环境下
*/
private isInNote: boolean = true
private container!: HTMLDivElement;
private inputContainer!: HTMLDivElement;
private outputContainer!: HTMLDivElement;
Expand All @@ -84,12 +91,14 @@ export default class Views {
}

private init() {

if (Zotero.Prefs.get(`${config.addonRef}.autoShow`)) {
this.container = this.buildContainer()
this.container.style.display = "flex"
this.setText(help, true, false)
this.inputContainer!.querySelector("input")!.value = "/help"
this.show(-1, -1, false)

}
}

Expand Down Expand Up @@ -161,34 +170,53 @@ export default class Views {
private setText(text: string, isDone: boolean = false, scrollToNewLine : boolean = true) {
this.outputContainer.style.display = ""
const outputDiv = this.outputContainer.querySelector(".markdown-body")!
outputDiv.classList.add("streaming");
outputDiv.setAttribute("pureText", text);
if (outputDiv.innerHTML == "") {
outputDiv.innerHTML = "<span></span>"
outputDiv.classList.add("streaming");
let ready = () => {
if (outputDiv.innerHTML.trim() == "") {
outputDiv.innerHTML = `<span></span>`
}
}
ready()
/**
* 根据差异渲染,只为保全光标闪烁
*/
let md2html = () => {
let result = markdown.render(text)
// .replace(/<mjx-assistive-mml[^>]*>.*?<\/mjx-assistive-mml>/g, "")
/**
* 监测差异,替换节点或文字
* @param oldNode
* @param newNode
* @returns
*/
let diffRender = (oldNode: any, newNode: any) => {
if (newNode.nodeName == "svg") {
oldNode.parentNode.replaceChild(newNode, oldNode)
return
}
if (oldNode.nodeName == "#text" && newNode.nodeName == "#text") {
oldNode.data = newNode.data
return
} else {
if (oldNode.outerHTML == newNode.outerHTML &&
oldNode.innerHTML == newNode.innerHTML) { return }
if (
oldNode.outerHTML == newNode.outerHTML &&
oldNode.innerHTML == newNode.innerHTML
) {
return
}
}
// 老的比新的多要去除
[...oldNode.childNodes].slice(newNode.childNodes.length).forEach((e: any)=>e.remove())
for (let i = 0; i < newNode.childNodes.length; i++) {
if (i < oldNode.childNodes.length) {
if (oldNode.childNodes[i].tagName != newNode.childNodes[i].tagName) {
oldNode.replaceChild(newNode.childNodes[i], oldNode.childNodes[i])
if (oldNode.childNodes[i].tagName == "#text") {
oldNode.childNodes[i].remove()
oldNode.appendChild(newNode.childNodes[i])
} else {
oldNode.replaceChild(newNode.childNodes[i], oldNode.childNodes[i])
}
continue
} else {
diffRender(oldNode.childNodes[i], newNode.childNodes[i])
Expand All @@ -208,12 +236,27 @@ export default class Views {
}
}
md2html()
ready()
// @ts-ignore
scrollToNewLine && this.outputContainer.scrollBy(0, this.outputContainer.scrollTopMax)
if (isDone) {
outputDiv.innerHTML = ""
md2html()
// 任何实时预览的错误到最后,应该因为下面这句消失
outputDiv.innerHTML = markdown.render(text)
outputDiv.classList.remove("streaming")
if (this.isInNote) {
this.container.style.display = "none"
const BNEditorApi = Zotero.BetterNotes.api.editor
const editor = BNEditorApi.getEditorInstance(Zotero.BetterNotes.data.workspace.mainId);
editor._iframeWindow.focus()
const from = BNEditorApi.getRangeAtCursor(editor).from
BNEditorApi.insert(
editor,
outputDiv.innerHTML,
from,
true
)
editor._iframeWindow.focus()
}
}
}

Expand Down Expand Up @@ -247,46 +290,54 @@ export default class Views {
// 只是结束了setText,而响应还在继续
return window.clearInterval(id)
}
_textArr = textArr.slice(0, _textArr.length+1)
this.setText(_textArr.join(""))
_textArr = textArr.slice(0, _textArr.length + 1)
const _text = _textArr.join("")
_text.length > 0 && this.setText(_text)
}, deltaTime)
this._id = id
await Zotero.HTTP.request(
"POST",
`${api}/chat/completions`,
{
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${secretKey}`,
},
body: JSON.stringify({
model: model,
messages: this.messages,
stream: true,
temperature: Number(temperature)
}),
responseType: "text",
requestObserver: (xmlhttp: XMLHttpRequest) => {
xmlhttp.onprogress = (e: any) => {
try {
textArr = e.target.response.match(/data: (.+)/g).filter((s: string) => s.indexOf("content")>=0).map((s: string) => {
try {
return JSON.parse(s.replace("data: ", "")).choices[0].delta.content.replace(/\n+/g, "\n")
} catch {
return false
}
}).filter(Boolean)
} catch {
// 出错一般是token超出限制
this.setText(e.target.response + "\n\n" + requestText, true)
}
if (e.target.timeout) {
e.target.timeout = 0;
}
};
},
}
);
const url = `${api}/chat/completions`
try {
await Zotero.HTTP.request(
"POST",
url,
{
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${secretKey}`,
},
body: JSON.stringify({
model: model,
messages: this.messages,
stream: true,
temperature: Number(temperature)
}),
responseType: "text",
requestObserver: (xmlhttp: XMLHttpRequest) => {
xmlhttp.onprogress = (e: any) => {
try {
textArr = e.target.response.match(/data: (.+)/g).filter((s: string) => s.indexOf("content")>=0).map((s: string) => {
try {
return JSON.parse(s.replace("data: ", "")).choices[0].delta.content.replace(/\n+/g, "\n")
} catch {
return false
}
}).filter(Boolean)
} catch {
// 出错一般是token超出限制
this.setText(e.target.response + "\n\n" + requestText, true)
}
if (e.target.timeout) {
e.target.timeout = 0;
}
};
},
}
);
} catch (error: any) {
new ztoolkit.ProgressWindow(url, { closeOtherProgressWindows: true })
.createLine({ text: error.message, type: "fail" })
.show()
}
const responseText = textArr.join("")
window.clearInterval(id)
window.setTimeout(() => {
Expand Down Expand Up @@ -615,7 +666,7 @@ export default class Views {
const newStyle = (value: string) => parseFloat(value) * scale + 'px';

for (const key in styleAttributes) {
child.style[key as StyleAttributeKeys] = newStyle(style[key as StyleAttributeKeys]);
child.style && (child.style[key as StyleAttributeKeys] = newStyle(style[key as StyleAttributeKeys]))
}
};
// 为指定的div绑定wheel事件
Expand Down Expand Up @@ -1214,12 +1265,25 @@ export default class Views {
if (
Zotero_Tabs.selectedIndex == 1 &&
event.explicitOriginalTarget.baseURI.indexOf("note-editor") >= 0 &&
event.code == "Space"
event.code == "Space" &&
Zotero.BetterNotes.api.editor
) {
this.isInNote = true
const BNEditorApi = Zotero.BetterNotes.api.editor
const editor = BNEditorApi.getEditorInstance(Zotero.BetterNotes.data.workspace.mainId);
let lines = [...editor._iframeWindow.document.querySelector(".primary-editor").childNodes]
const doc = event.explicitOriginalTarget.ownerDocument
const selection = doc.getSelection()
const range = selection.getRangeAt(0);
const span = range.endContainer
ztoolkit.log(span)
lines = lines.slice(0, lines.indexOf(span))
const context = await Zotero.BetterNotes.api.convert.html2md(lines.map(e => e.outerHTML).join("\n"))
ztoolkit.log(context)
this.messages = [{
role: "user",
content: context
}]
if (/[\n ]+/.test(span.innerText)) {
let { x, y } = span.getBoundingClientRect();
const leftPanel = document.querySelector("#betternotes-workspace-outline-container")!
Expand All @@ -1241,6 +1305,7 @@ export default class Views {
) {
return;
}
this.isInNote = false
if (Zotero_Tabs.selectedIndex == 0) {
const div = document.querySelector("#item-tree-main-default .row.selected")!
if (div) {
Expand Down
4 changes: 2 additions & 2 deletions update.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"zoterogpt@polygon.org": {
"updates": [
{
"version": "0.2.1",
"version": "0.2.2",
"update_link": "https://github.com/MuiseDestiny/zotero-gpt/releases/latest/download/zotero-gpt.xpi",
"applications": {
"gecko": {
Expand All @@ -12,7 +12,7 @@
}
},
{
"version": "0.2.1",
"version": "0.2.2",
"update_link": "https://github.com/MuiseDestiny/zotero-gpt/releases/latest/download/zotero-gpt.xpi",
"applications": {
"zotero": {
Expand Down
2 changes: 1 addition & 1 deletion update.rdf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<rdf:Seq>
<rdf:li>
<rdf:Description>
<em:version>0.2.1</em:version>
<em:version>0.2.2</em:version>
<em:targetApplication>
<rdf:Description>
<em:id>zotero@chnm.gmu.edu</em:id>
Expand Down

0 comments on commit b048062

Please sign in to comment.