跟沐神学读论文-论文阅读管理

摘要

近期有读论文的需求,就需要去了解一下论文到底要怎么读,同一个系列之间的论文如何作整理和归纳,之前也有了解过市面上有成熟的论文阅读工具,但是对于学生党来讲没什么性价比,在B站上看到沐神有讲解他的思路Typora作为工作中的md生产工具,我有一点浅显的认识希望和大家交流学习。Typora可以作为编辑工具,之前有被同事安利过,但是那个时候md格式还并不了解,今天重拾起,简单来讲我的做法就是Typora+gitee形成云端存储的一套方案,配套使用我自己的一些脚本,可以很好的实现论文阅读的功能。

一:Typora的安装

Typora 是一个所见即所得的 Markdown 跨平台写作工具,目前已经发布正式版,并且更改为付费模式,0.11.18_beta 是最后一个免费的测试版,有需要的可以选择下载。

Windows 用户

下载地址: [https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.exe](https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.exe)

0.11.18 现在被远程施法了,会提示过期无法使用,可以使用 0.9.96 版

下载地址:https://github.com/iuxt/src/releases/download/2.0/typora-setup-x64_0.9.96.exe

Mac 用户

下载地址: https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.dmg

Ubuntu 用户

下载地址:https://github.com/iuxt/src/releases/download/2.0/Typora_Linux_0.11.18_amd64.deb

安装方法

使用 apt 安装:

sudo apt install ./Typora_Linux_0.11.18_amd64.deb

如此你就完成了笔记编辑器的安装。

二:Gitee的配置

https://gitee.com在这里去作账户注册和登陆,新建仓库
在这里插入图片描述在这里插入图片描述在本地新建立一个文件夹,在该文件下开命令行

#Git 全局设置:git config --global user.name "YourName"
git config --global user.email "YourInfo@user.noreply.gitee.com"#创建 git 仓库:mkdir paper
cd paper
git init 
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/YourName/paper.git
git push -u origin "master"#已有仓库?cd existing_git_repo
git remote add origin https://gitee.com/YourName/paper.git
git push -u origin "master"

如此每次更改后可以配合gitee去作同步。

三:脚本

脚本一:通过arxiv自动下载论文,提取论文标题,作者,日期,索引数等

arxiv_2_md.py

#!/usr/bin/env python3
import os
import re
import requests
import arxiv
from urllib.parse import urlparse, quotedef extract_arxiv_id(url: str) -> str:"""从arXiv链接中提取arXiv ID。形如:https://arxiv.org/abs/1605.08386则返回:1605.08386"""parsed = urlparse(url)if 'arxiv.org' not in parsed.netloc:raise ValueError("这不是一个有效的arXiv链接。")match = re.search(r'/abs/([0-9]+\.[0-9]+)', parsed.path)if not match:match = re.search(r'/pdf/([0-9]+\.[0-9]+)', parsed.path)if not match:raise ValueError("未能从链接中提取到arXiv ID。")return match.group(1)def fetch_arxiv_metadata(arxiv_id: str):"""使用arxiv Python包从arxiv获取元数据返回字典包含:title, authors, year, journal_ref, pdf_url"""search = arxiv.Search(id_list=[arxiv_id])paper = next(search.results(), None)if paper is None:raise ValueError("未能在arXiv找到对应论文信息。")journal_ref = paper.journal_ref if paper.journal_ref else "N/A"authors = [au.name for au in paper.authors]year = paper.published.yearreturn {"title": paper.title.strip(),"authors": authors,"year": year,"journal": journal_ref,"pdf_url": paper.pdf_url}def download_pdf(pdf_url: str, save_dir: str = "./pdfs") -> str:"""下载pdf文件到本地save_dir中,并返回本地文件相对路径。"""if not os.path.exists(save_dir):os.makedirs(save_dir)# 尝试从pdf_url中提取文件名basename = os.path.basename(pdf_url)if not basename.endswith(".pdf"):basename += ".pdf"local_filename = os.path.join(save_dir, basename)r = requests.get(pdf_url)r.raise_for_status()with open(local_filename, 'wb') as f:f.write(r.content)return local_filenamedef fetch_citation_count_by_arxiv_id(arxiv_id: str) -> int:"""调用 Semantic Scholar API 使用 ArXiv:<arxiv_id> 获取引用数。"""url = f"https://api.semanticscholar.org/graph/v1/paper/ArXiv:{arxiv_id}?fields=citationCount"r = requests.get(url)if r.status_code == 200:data = r.json()return data.get("citationCount", 0)return 0def fetch_citation_count_by_title(title: str) -> int:"""如果直接使用ArXiv ID获取不到合适引用数,则通过标题在 Semantic Scholar 搜索。取搜索结果中匹配度最高(即第一个结果)的citationCount作为参考。"""query = quote(title)url = f"https://api.semanticscholar.org/graph/v1/paper/search?query={query}&fields=title,citationCount"r = requests.get(url)if r.status_code == 200:data = r.json()papers = data.get("data", [])if papers:best_match = papers[0]if best_match["title"].lower().strip() == title.lower().strip():return best_match.get("citationCount", 0)return 0def fetch_citation_count(arxiv_id: str, title: str) -> int:"""尝试通过arxiv_id获取citationCount,如果为0则尝试通过标题获取。"""count = fetch_citation_count_by_arxiv_id(arxiv_id)if count == 0:# 如果通过arxiv_id获取不到或为0,尝试通过标题搜索count = fetch_citation_count_by_title(title)return countdef generate_markdown(md_filename: str, title: str, authors: list, journal: str, year: int, local_pdf_path: str, citation_count: int, arxiv_url: str):"""生成Markdown文件:包含标题、作者、期刊/会议信息、年份、本地PDF链接、原始arxiv链接和引用次数。"""authors_str = ", ".join(authors)rel_pdf_path = os.path.relpath(local_pdf_path)with open(md_filename, 'w', encoding='utf-8') as f:f.write(f"# {title}\n\n")f.write(f"- **Authors:** {authors_str}\n")f.write(f"- **Venue/Journal:** {journal}\n")f.write(f"- **Year:** {year}\n")f.write(f"- **Local PDF:** [{rel_pdf_path}]({rel_pdf_path})\n")f.write(f"- **ArXiv Link:** [{arxiv_url}]({arxiv_url})\n\n")f.write(f"**Citations:** {citation_count}\n")def main():# 输入 arxiv 链接arxiv_url = input("请输入arXiv链接:").strip()arxiv_id = extract_arxiv_id(arxiv_url)# 获取arxiv元数据meta = fetch_arxiv_metadata(arxiv_id)# 下载PDFlocal_pdf = download_pdf(meta["pdf_url"])# 获取引用数citation_count = fetch_citation_count(arxiv_id, meta["title"])# 询问用户md文件名default_md_name = f"{arxiv_id}.md"md_name_input = input(f"请输入要保存的Markdown文件名(不需扩展名,留空则使用 {default_md_name[:-3]}): ").strip()if md_name_input == "":md_filename = default_md_nameelse:md_filename = f"{md_name_input}.md"# 生成markdown文件generate_markdown(md_filename,meta["title"],meta["authors"],meta["journal"],meta["year"],local_pdf,citation_count,arxiv_url)print(f"Markdown文件已生成:{md_filename}")if __name__ == "__main__":main()

运行:

python ./arxiv_2_md.py

如果在输入arXiv后报错:

python ./arxiv_to_md_1.2.py 
请输入arXiv链接:https://arxiv.org/abs/2410.24207
/home/crist/WorkSpace/3D-reconstruction-paper/./arxiv_to_md_1.2.py:30: DeprecationWarning: The 'Search.results' method is deprecated, use 'Client.results' insteadpaper = next(search.results(), None)
Traceback (most recent call last):File "/home/crist/WorkSpace/3D-reconstruction-paper/./arxiv_to_md_1.2.py", line 150, in <module>main()File "/home/crist/WorkSpace/3D-reconstruction-paper/./arxiv_to_md_1.2.py", line 125, in mainlocal_pdf = download_pdf(meta["pdf_url"])^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/WorkSpace/3D-reconstruction-paper/./arxiv_to_md_1.2.py", line 56, in download_pdfr = requests.get(pdf_url)^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/api.py", line 73, in getreturn request("get", url, params=params, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/api.py", line 59, in requestreturn session.request(method=method, url=url, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/sessions.py", line 589, in requestresp = self.send(prep, **send_kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/sessions.py", line 703, in sendr = adapter.send(request, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/adapters.py", line 633, in sendconn = self.get_connection_with_tls_context(^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/adapters.py", line 483, in get_connection_with_tls_contextproxy_manager = self.proxy_manager_for(proxy)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/requests/adapters.py", line 282, in proxy_manager_formanager = self.proxy_manager[proxy] = SOCKSProxyManager(^^^^^^^^^^^^^^^^^^File "/home/crist/miniconda3/lib/python3.12/site-packages/urllib3/contrib/socks.py", line 212, in __init__raise ValueError(f"Unable to determine SOCKS version from {proxy_url}")
ValueError: Unable to determine SOCKS version from socks://127.0.0.1:7890/

解决办法:

export ALL_PROXY=socks5://127.0.0.1:7890
export HTTP_PROXY=socks5://127.0.0.1:7890
export HTTPS_PROXY=socks5://127.0.0.1:7890

脚本二:
提取PDF中的图片,将我的脚本和pdf文件放到一起:

#!/usr/bin/env python3
import os
import subprocess
import tkinter as tk
from tkinter import messagebox, fontdef list_pdfs(directory="."):"""列出指定目录中的所有PDF文件并返回列表。"""pdfs = [f for f in os.listdir(directory) if f.lower().endswith('.pdf')]return pdfsdef extract_images(pdf_path, output_dir="images"):"""使用pdfimages从指定PDF中提取图片。"""if not os.path.exists(output_dir):os.makedirs(output_dir)base_name = os.path.splitext(os.path.basename(pdf_path))[0]output_prefix = os.path.join(output_dir, base_name)cmd = ["pdfimages", "-j", pdf_path, output_prefix]try:subprocess.run(cmd, check=True)return True, f"图片已提取到 {output_dir} 目录中,以 {base_name}-xxx 的形式命名。"except subprocess.CalledProcessError:return False, "提取图片失败,请确保已安装pdfimages工具。"def on_extract():selection = listbox.curselection()if not selection:messagebox.showwarning("警告", "请先选择一个PDF文件")returnindex = selection[0]pdf_file = pdfs[index]success, msg = extract_images(pdf_file)if success:messagebox.showinfo("提取完成", msg)else:messagebox.showerror("错误", msg)root = tk.Tk()
root.title("PDF图片提取器")# 设置全局字体
root.option_add("*Font", "Helvetica 12")pdfs = list_pdfs(".")frame = tk.Frame(root)
frame.pack(padx=10, pady=10, fill="both", expand=True)label = tk.Label(frame, text="请选择一个PDF文件:", font=("Helvetica", 12, "bold"))
label.pack(anchor="w")listbox = tk.Listbox(frame, height=10)
listbox.pack(fill="both", expand=True)for pdf in pdfs:listbox.insert(tk.END, pdf)if not pdfs:listbox.insert(tk.END, "当前目录未找到PDF文件")btn_frame = tk.Frame(root)
btn_frame.pack(pady=5)
extract_btn = tk.Button(btn_frame, text="提取图片", font=("Helvetica", 12))
extract_btn.config(command=on_extract)
extract_btn.pack()root.mainloop()

这样就可以把图片保存到img文件夹下了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/492906.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day38-SSH安全登录

机器准备 什么是SSH SSH 或 Secure Shell 协议是一种远程管理协议&#xff0c;允许用户通过 Internet 访问、控制和修改其远程服务器。 SSH 服务是作为未加密 Telnet 的安全替代品而创建的&#xff0c;它使用加密技术来确保进出远程服务器的所有通信都以加密方式进行。 SS…

使用React构建一个掷骰子的小游戏

这是一个用 React 构建的小游戏应用&#xff0c;名为 Tenzies&#xff0c;目标是掷骰子&#xff0c;直到所有骰子的值相同。玩家可以“冻结”某些骰子&#xff0c;使它们在后续掷骰中保持不变。 1. App.jsx import Die from "../public/components/Die" import { us…

vue 文本域 展示的内容格式要和填写时保持一致

文本域 展示的内容格式要和填写时保持一致 <el-inputtype"textarea":rows"5"placeholder"请输入内容"v-model"formCredit.point"style"width:1010px;" > </el-input> 样式加个&#xff1a; white-space: pre-w…

[Linux] 信号保存与处理

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 信号的保存 下面的概…

【Axure高保真原型】伸缩表单

今天和大家分享伸缩表单的原型模板&#xff0c;效果包括在需要填写内容较多时&#xff0c;可以对填写内容进行分类&#xff0c;然后通过点击上下箭头&#xff0c;收起或展开对应的信息。这个模版里面包含了输入框、下拉列表、选择器、上次图片共多种种常用的元件&#xff0c;后…

InternVL简读

InternVL: Scaling up Vision Foundation Models and Aligning for Generic Visual-Linguistic Tasks 1. Introduction 需要解决的问题&#xff1a; existing VLLMs [5, 81, 131, 177, 187] commonly employ lightweight “glue” layers, such as QFormer [81] or linear pr…

从源码分析swift GCD_DispatchGroup

前言&#xff1a; 最近在写需求的时候用到了DispatchGroup&#xff0c;一直没有深入去学习&#xff0c;既然遇到了那么就总结下吧。。。。 基本介绍&#xff1a; 任务组&#xff08;DispatchGroup&#xff09; DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…

AFL-Fuzz 的使用

AFL-Fuzz 的使用 一、工具二、有源码测试三、无源码测试 一、工具 建议安装LLVM并使用afl-clang-fast或afl-clang-lto进行编译&#xff0c;这些工具提供了更现代和高效的插桩技术。您可以按照以下步骤安装LLVM和afl-clang-fast&#xff1a; sudo apt update sudo apt install…

ONES 功能上新|ONES Copilot、ONES Wiki 新功能一览

ONES Copilot 可基于工作项的标题、描述、属性信息&#xff0c;对工作项产生的动态和评论生成总结。 针对不同类型的工作项&#xff0c;总结输出的内容有对应的侧重点。 应用场景&#xff1a; 在一些流程步骤复杂、上下游参与成员角色丰富的场景中&#xff0c;工作项动态往往会…

EasyGBS国标GB28181平台P2P远程访问故障排查指南:客户端角度的排查思路

在现代视频监控系统中&#xff0c;P2P&#xff08;点对点&#xff09;技术因其便捷性和高效性而被广泛应用。然而&#xff0c;当用户在使用P2P远程访问时遇到设备不在线或无法访问的问题时&#xff0c;有效的排查方法显得尤为重要。本文将从客户端的角度出发&#xff0c;详细探…

Soul Android端稳定性背后的那些事

前言&#xff1a;移动应用的稳定性对于用户体验和产品商业价值都有着至关重要的作用。应用崩溃会导致关键业务中断、用户留存率下降、品牌口碑变差、生命周期价值下降等影响&#xff0c;甚至会导致用户流失。因此&#xff0c;稳定性是APP质量构建体系中最基本和最关键的一环。当…

mfc140u.dll是什么文件?如何解决mfc140u.dll丢失的相关问题

遇到“mfc140u.dll文件丢失”的错误通常影响应用程序的运行&#xff0c;这个问题主要出现在使用Microsoft Visual C环境开发的软件中。mfc140u.dll是一个重要的系统文件&#xff0c;如果它丢失或损坏&#xff0c;会导致相关程序无法启动。本文将简要介绍几种快速有效的方法来恢…

mybatis分页插件的使用

1. 引入依赖包 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>6.1.0</version> </dependency> 2 添加分页插件配置 2.1 使用配置类的方式&#xff08;推荐&#xff09…

手机便签哪个好用?手机桌面便签app下载推荐

在快节奏的现代生活中&#xff0c;我们常常需要记录一些重要的信息和灵感&#xff0c;以便于日后查阅和回顾。手机便签软件因其便携性和易用性&#xff0c;成为了我们日常生活中不可或缺的工具。无论是购物清单、待办事项、灵感记录还是重要笔记&#xff0c;手机便签都能帮助我…

Zabbix6.0升级为6.4

为了体验一些新的功能&#xff0c;比如 Webhook 和问题抑制等&#xff0c;升级个小版本。 一、环境信息 1. 版本要求 一定要事先查看官方文档&#xff0c;确认组件要求的版本&#xff0c;否则版本过高或者过低都会出现问题。 2. 升级前后信息 环境升级前升级后操作系统CentOS…

怎么将pdf中的某一个提取出来?介绍几种提取PDF中页面的方法

怎么将pdf中的某一个提取出来&#xff1f;传统上&#xff0c;我们可能通过手动截取屏幕或使用PDF阅读器的复制功能来提取信息&#xff0c;但这种方法往往不够精确&#xff0c;且无法保留原文档的排版和格式。此外&#xff0c;很多时候我们需要提取的内容可能涉及多个页面、多个…

LeetCode:101. 对称二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输…

力扣-图论-18【算法学习day.68】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…

深度学习之目标检测——RCNN

Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法&#xff1a;穷举法&#xff0c;在原始图片上进行不同尺度不同大小的滑窗&#xff0c;获取每个可能的位置 弊端&#xff1a;计算量大&#xff0c;且尺度不能兼顾 Selective …

【计算机视觉基础CV】03-深度学习图像分类实战:鲜花数据集加载与预处理详解

本文将深入介绍鲜花分类数据集的加载与处理方式&#xff0c;同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向&#xff0c;为读者提供从数据组织、预处理、加载到可视化展示的完整过程&#xff0c;并为后续模型训练打下基础。 前言 在计算机视觉的深…