上传2025_04_29备份作为记录
This commit is contained in:
22
.gitignore
vendored
Executable file
22
.gitignore
vendored
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#### 忽略目录
|
||||||
|
# 数据库
|
||||||
|
databases/*
|
||||||
|
public/*.sql
|
||||||
|
public/*.db
|
||||||
|
|
||||||
|
##### 博客文档
|
||||||
|
# 图片
|
||||||
|
src/image/*
|
||||||
|
public/image/*
|
||||||
|
|
||||||
|
|
||||||
|
# 可能未知
|
||||||
|
public/message/static/src/video/*
|
||||||
|
|
||||||
|
# 管理员面板
|
||||||
|
public/blog/admin/*
|
||||||
|
|
||||||
|
|
||||||
|
# 临时区
|
||||||
|
public/blog/md0/*
|
||||||
|
# 临时区
|
||||||
9
LICENSE
Normal file
9
LICENSE
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 skimrme
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
13
README.md
Normal file
13
README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<a href="https://ww3.tw/">点击访问</a>
|
||||||
|
|
||||||
|
## 2025.7.20
|
||||||
|
open-ww3-project-ww3-tw
|
||||||
|
个人博客地址(预计)
|
||||||
|
---
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
**署名**
|
||||||
|
|
||||||
|
skimrme
|
||||||
|
|
||||||
0
public/about/index.html
Executable file
0
public/about/index.html
Executable file
13
public/blog/about/index.html
Executable file
13
public/blog/about/index.html
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>不想写了</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
忘记写了
|
||||||
|
<br>
|
||||||
|
所以暂时就不写了
|
||||||
|
<p>2025.08.05</p>
|
||||||
|
<p>over</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
public/blog/google02f6a3f6004a32c6.html
Normal file
1
public/blog/google02f6a3f6004a32c6.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
google-site-verification: google02f6a3f6004a32c6.html
|
||||||
BIN
public/blog/icon/original.ico
Executable file
BIN
public/blog/icon/original.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
120
public/blog/index.php
Executable file
120
public/blog/index.php
Executable file
@@ -0,0 +1,120 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>首页 | ww3</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
|
||||||
|
<link rel="icon" type="image/x-icon" href="./icon/original.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="black_block">
|
||||||
|
<div id="navbar1">
|
||||||
|
<table border="0" style="background-color: rgba(147, 185, 255, 0.644);">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td id="td_navbar_40px"><b><a href="https://ww3.tw/" id="url_">首页</a></b></td>
|
||||||
|
<td id="td_navbar_40px"><b><a href="https://ww3.tw/about/" id="url_">关于</a></b></td>
|
||||||
|
<td id="td_navbar_75px"><b><a href="https://ww3.tw/jumping-message/" id="url_">弹幕留言</a></b></td>
|
||||||
|
<td id="td_navbar_75px"><b><a href="https://ww3.tw/short-url/" id="url_">短链生成</a></b></td>
|
||||||
|
<td id="td_navbar_52px"><b><a href="https://gitea.ww3.tw/skimrme/" id="url_">gitea</a></b></td>
|
||||||
|
<td id="td_navbar_135px"><b><a href="https://ww3.tw/docker-registry/" id="url_">docker-registry</a></b></td>
|
||||||
|
<td id="td_navbar_40px"><b><a href="https://api.ww3.tw/" id="url_">api</a></b></td>
|
||||||
|
<td id="td_navbar_40px"><b><a href="https://wiki.ww3.tw/" id="url_">wiki</a></b></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<!-- 屑站日志 -->
|
||||||
|
<div id="logs">
|
||||||
|
<h3>屑站日志:<br></h3>
|
||||||
|
<font size="3.2">
|
||||||
|
<table border="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td id="td_logs">2025.07.26</td>
|
||||||
|
<td id="td_logs_content">新增<a href="https://wiki.ww3.tw">wiki</a>页面</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="td_logs">2025.07.20</td>
|
||||||
|
<td id="td_logs_content">新增<a href="https://gitea.ww3.tw/skimrme">gitea</a>、<a href="https://ww3.tw/docker-registry/">docker-registry</a>页面</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="td_logs">2025.07.09</td>
|
||||||
|
<td id="td_logs_content">建立页面</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</font>
|
||||||
|
</div>
|
||||||
|
<!-- 屑站日志 -->
|
||||||
|
<div id="js_date"></div>
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include "../static/html/black-block.html";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body
|
||||||
|
{
|
||||||
|
background-color: rgba(147, 185, 255, 0.644);
|
||||||
|
}
|
||||||
|
|
||||||
|
#url_
|
||||||
|
{
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#logs
|
||||||
|
{
|
||||||
|
height: 220px;
|
||||||
|
width: 450px;
|
||||||
|
overflow: auto;
|
||||||
|
background: #ffffffbc;
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 40px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_40px
|
||||||
|
{
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_52px
|
||||||
|
{
|
||||||
|
width: 52px;;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_75px
|
||||||
|
{
|
||||||
|
width: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_navbar_135px
|
||||||
|
{
|
||||||
|
width: 135px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_logs
|
||||||
|
{
|
||||||
|
width: 75px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td_logs_content
|
||||||
|
{
|
||||||
|
color: rgb(132, 132, 132);
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#js_date{
|
||||||
|
color: rgb(55, 0, 255);
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
47
public/blog/logs.php.text
Normal file
47
public/blog/logs.php.text
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 连接数据库
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
// 连接成功输出连接成功
|
||||||
|
echo "<!--数据库连接成功-->";
|
||||||
|
// 如果连接成功,但是内部状态有问题
|
||||||
|
if ($db->lastErrorCode() !==0) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容区
|
||||||
|
// 执行sql命令 查询表单
|
||||||
|
$select_id_date_content_from_logs_b_to_s /*查询logs表单中的id date content id从大到小排列*/ = $db->query('SELECT id, date, content FROM logs ORDER BY id DESC'); // 执行查询logs表单中的id date content id从大到小排列的命令
|
||||||
|
|
||||||
|
// 循环 写入
|
||||||
|
while ($row = $select_id_date_content_from_logs_b_to_s->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
// 设定 ' ' 占用19个字符
|
||||||
|
$nbsp_count = 0;
|
||||||
|
// 设定变量是 换行 加上 空格重复19个
|
||||||
|
$br_nbsp = '<br>' . str_repeat(' ',$nbsp_count);
|
||||||
|
// 设定变量是 修改 && 为 换行 加上19个空格
|
||||||
|
$alter_br = str_replace('&&', $br_nbsp, $row['content']);
|
||||||
|
|
||||||
|
// 输出 date content
|
||||||
|
echo "<tr>" . "<td id='td_logs'>" . "<a style='font-size: 18px;'>" . $row['date'] . "</a>" . "</td>" . "<td id='td_logs_content'>" . $alter_br . "<br>" . "</tr>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
|
||||||
|
// 捕获php报错
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
7
public/blog/md0/114514.md
Executable file
7
public/blog/md0/114514.md
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
## MD介绍页面
|
||||||
|
|
||||||
|
顾名思义、本文件夹下使用的基本都是markdown
|
||||||
|
|
||||||
|
最后感谢提供php的md插件的开源制作者
|
||||||
|
|
||||||
|
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)
|
||||||
479
public/blog/md0/MD.php
Executable file
479
public/blog/md0/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
public/blog/md0/index.php
Executable file
5
public/blog/md0/index.php
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
require './MD.php';
|
||||||
|
|
||||||
|
$md=new MD('114514.md');
|
||||||
|
$md->output();
|
||||||
479
public/blog/md0/src/php-markdown/MD.php
Executable file
479
public/blog/md0/src/php-markdown/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
public/blog/md0/src/php-markdown/demo/index.php
Executable file
5
public/blog/md0/src/php-markdown/demo/index.php
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
require '../MD.php';
|
||||||
|
|
||||||
|
$md=new MD('test.md');
|
||||||
|
$md->output();
|
||||||
81
public/blog/md0/src/php-markdown/demo/test.md
Executable file
81
public/blog/md0/src/php-markdown/demo/test.md
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
# 一级标题
|
||||||
|
## 二级标题
|
||||||
|
### 三级标题
|
||||||
|
#### 四级标题
|
||||||
|
##### 五级标题
|
||||||
|
###### 六级标题
|
||||||
|
*斜体*
|
||||||
|
**粗体**
|
||||||
|
- 项目1
|
||||||
|
- 项目2
|
||||||
|
- 项目3
|
||||||
|
- 项目4
|
||||||
|
+ 项目5
|
||||||
|
+ 项目6
|
||||||
|
+ 项目7
|
||||||
|
|
||||||
|
1. apple
|
||||||
|
2. boy
|
||||||
|
3. cat
|
||||||
|
|
||||||
|
[ ] 选择1
|
||||||
|
[-] 选择2
|
||||||
|
[-] 选择3
|
||||||
|
[ ] 选择4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
void test();
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
printf("Hello,World!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(){
|
||||||
|
printf("Hello,World!");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[百度](https://www.baidu.com)
|
||||||
|

|
||||||
|
|
||||||
|
**blockquote使用方法**
|
||||||
|
>引言,这是一句引言
|
||||||
|
>Hello,World!
|
||||||
|
>>二级引言
|
||||||
|
>>>三级引言
|
||||||
|
|
||||||
|
apple|boy|cat
|
||||||
|
---|---|---
|
||||||
|
a|b|c
|
||||||
|
d|e|f
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Apple</th>
|
||||||
|
<th>Boy</th>
|
||||||
|
<th>Cat</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>a</td>
|
||||||
|
<td>b</td>
|
||||||
|
<td>c</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>d</td>
|
||||||
|
<td>e</td>
|
||||||
|
<td>f</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
> I o u
|
||||||
|
> This is just a test...
|
||||||
|
>> Hello
|
||||||
|
> World
|
||||||
1
public/blog/md0/src/php-markdown/index.html
Executable file
1
public/blog/md0/src/php-markdown/index.html
Executable file
@@ -0,0 +1 @@
|
|||||||
|
<meta http-equiv="refresh" content="0.1;url=https://github.com/ixysoft/php-markdown">
|
||||||
100
public/blog/post/index.php
Normal file
100
public/blog/post/index.php
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<head>
|
||||||
|
<link rel="icon" type="image/x-icon" href="https://ww3.tw/blog/icon/original.ico">
|
||||||
|
<title>文章列表</title> <!-- 标题 -->
|
||||||
|
</head>
|
||||||
|
<body id=wallpaper>
|
||||||
|
<!-- 背景 -->
|
||||||
|
<div id="div_1">
|
||||||
|
<?php
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 连接数据库
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
// 连接成功输出连接成功
|
||||||
|
echo "<!--数据库连接成功-->";
|
||||||
|
// 如果连接成功,但是内部状态有问题
|
||||||
|
if ($db->lastErrorCode() !==0) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容区
|
||||||
|
// 执行sql命令 查询表单
|
||||||
|
$select_id_date_title_from_posts_btos /*查询posts表单中的id date title id从大到小排列*/ = $db->query('SELECT id, date, title FROM posts ORDER BY id DESC'); // 执行查询posts表单中的id date title id从大到小排列的命令
|
||||||
|
// 循环 写入
|
||||||
|
|
||||||
|
echo "<a href='https://ww3.tw' style='background-color: rgba(147, 185, 255, 0.644);position: absolute;'>返回首页</a>";
|
||||||
|
echo "<center><b><h2>全部文章</h2></b></center>";
|
||||||
|
echo "<br>";
|
||||||
|
echo "文章如下↓";
|
||||||
|
echo "<br>";
|
||||||
|
echo "<br>";
|
||||||
|
echo "<br>";
|
||||||
|
|
||||||
|
echo "<div id='content'>"; # 内容排版
|
||||||
|
|
||||||
|
while ($row = $select_id_date_title_from_posts_btos->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
|
||||||
|
echo "文章id: " . $row['id'] . "<br>";
|
||||||
|
echo $row['date'] . " " . "文章标题: " . $row['title'] . "<br>";
|
||||||
|
echo "<a href='https://ww3.tw/blog/post/s/?id=" . $row['id'] . "'>页面跳转</a><br><br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>"; # 内容排版
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
|
||||||
|
// 捕获php报错
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 依旧显示为连接失败
|
||||||
|
die("数据库连接失败");
|
||||||
|
// 关闭数据库连接
|
||||||
|
$db->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 随机变换图床api
|
||||||
|
|
||||||
|
$wallpaper_apis = ['https://www.loliapi.com/acg/pc/', 'https://api.sretna.cn/api/pc.php', 'https://www.api.plus/API/dongman/', 'https://moe.jitsu.top/img/?sort=pc', 'https://www.dmoe.cc/random.php', 'https://api.r10086.com/樱道随机图片api接口.php?图片系列=猫娘1', 'https://api.mtyqx.cn/tapi/random.php', 'https://api.ww3.tw/touhou'];
|
||||||
|
$suiji_wallpaper = rand(0, count($wallpaper_apis) - 1);
|
||||||
|
$wallpaper = $wallpaper_apis[$suiji_wallpaper];
|
||||||
|
// 显示图床url在页面
|
||||||
|
echo "<div id='wallpaper_url'>图片来源: " . $wallpaper . "</div>";
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#wallpaper {
|
||||||
|
background-image: url(<?php
|
||||||
|
echo $wallpaper;
|
||||||
|
?>); /*图片地址*/ /* https://api.sretna.cn/api/pc.php */
|
||||||
|
background-repeat: no-repeat; /*禁止平铺*/
|
||||||
|
background-size: 100% 100%; /*图片占满100%*/
|
||||||
|
margin: 0; /* 外边框为0 */
|
||||||
|
/*padding: 0;*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#div_1 {
|
||||||
|
height: 100%;
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
font-size: 19px;
|
||||||
|
background-color: rgba(169, 169, 169, 0.48);
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 0px 0px 0px 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wallpaper_url {
|
||||||
|
color: rgba(255, 0, 0, 0.354);
|
||||||
|
/* up、right、down、left */
|
||||||
|
margin: 20% 0px 0px 75%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
100
public/blog/post/s/index.php
Normal file
100
public/blog/post/s/index.php
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
// 设置最大接受id
|
||||||
|
const MAX_ARTICLE_ID = 100000;
|
||||||
|
|
||||||
|
// 获取搜索栏url的id
|
||||||
|
$post_id = $_GET['id'] ?? null;
|
||||||
|
|
||||||
|
// 设定数据库路径
|
||||||
|
$db_path = '/var/www/owp/open-ww3-project-ww3-tw/databases/sqlite/owp.db';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2. 严格的输入验证 (健壮性检查)
|
||||||
|
* 拦截所有非数字、无效范围或为空的输入
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
empty($post_id) ||
|
||||||
|
!is_numeric($post_id) ||
|
||||||
|
(int)$post_id <= 0 ||
|
||||||
|
(int)$post_id > MAX_ARTICLE_ID
|
||||||
|
) {
|
||||||
|
http_response_code(400); // HTTP 400 Bad Request
|
||||||
|
|
||||||
|
$error_msg = "错误:文章 ID 格式不正确。ID 必须是 1 到 " . MAX_ARTICLE_ID . " 之间的整数。";
|
||||||
|
die($error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过检查后,将 ID 强制转换为整数
|
||||||
|
$post_id = (int)$post_id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
/**
|
||||||
|
* 3. 连接 SQLite 数据库
|
||||||
|
* 注意:如果 PHP 运行用户没有读取此路径文件的权限,这里会失败。
|
||||||
|
*/
|
||||||
|
$db = new SQLite3($db_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4. 准备 SQL 查询语句 (核心安全防线:预处理语句)
|
||||||
|
* 使用占位符 :id 代替用户输入。
|
||||||
|
*/
|
||||||
|
$sql = 'SELECT title, content FROM posts WHERE id = :id';
|
||||||
|
|
||||||
|
// 准备语句
|
||||||
|
$stmt = $db->prepare($sql);
|
||||||
|
|
||||||
|
// 绑定参数:将 :id 替换为 $post_id 的值,并明确指定它是一个整数类型
|
||||||
|
$stmt->bindValue(':id', $post_id, SQLITE3_INTEGER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5. 执行查询并获取结果
|
||||||
|
*/
|
||||||
|
$result = $stmt->execute();
|
||||||
|
|
||||||
|
// 从结果集中获取一行数据
|
||||||
|
$row = $result->fetchArray(SQLITE3_ASSOC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 6. 显示内容或 404 错误
|
||||||
|
*/
|
||||||
|
if ($row) {
|
||||||
|
// 使用 htmlspecialchars() 函数防止 XSS 攻击
|
||||||
|
$title = $row['title'];
|
||||||
|
$content = $row['content'];
|
||||||
|
|
||||||
|
// --- 页面输出开始 ---
|
||||||
|
echo "<!DOCTYPE html>";
|
||||||
|
echo "<html lang='zh-CN'>";
|
||||||
|
echo "<head><meta charset='UTF-8'><title>{$title}</title></head>";
|
||||||
|
echo "<body>";
|
||||||
|
echo "<a href='https://ww3.tw'>返回主页</a>";
|
||||||
|
echo "<h1>{$title}</h1>";
|
||||||
|
|
||||||
|
// nl2br 用于将换行符转换成 <br>
|
||||||
|
echo "<article>" . nl2br($content) . "</article>";
|
||||||
|
|
||||||
|
echo "</body>";
|
||||||
|
echo "</html>";
|
||||||
|
// --- 页面输出结束 ---
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 文章未找到
|
||||||
|
http_response_code(404); // 404 Not Found
|
||||||
|
echo "<h1>404 Not Found</h1>";
|
||||||
|
echo "<p>抱歉,ID 为 {$post_id} 的文章不存在。</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 7. 清理资源
|
||||||
|
*/
|
||||||
|
$db->close();
|
||||||
|
//$stmt->close();
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// 处理异常
|
||||||
|
http_response_code(500); // 500 Internal Server Error
|
||||||
|
error_log("SQLite 错误: " . $e->getMessage());
|
||||||
|
die("系统错误,请稍后重试。");
|
||||||
|
}
|
||||||
|
?>
|
||||||
7
public/blog/robots.txt
Normal file
7
public/blog/robots.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
User-agent: *
|
||||||
|
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
Disallow: /admin/
|
||||||
|
|
||||||
|
Sitemap: https://open-ww3-project.ww3.tw/blog/sitemap.xml
|
||||||
23
public/blog/sitemap.xml
Normal file
23
public/blog/sitemap.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/about/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/post/</loc>
|
||||||
|
<lastmod>2025-12-12</lastmod>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://open-ww3-project.ww3.tw/blog/test.html</loc>
|
||||||
|
<lastmod>2025-12-13</lastmod>
|
||||||
|
<priority>0.1</priority>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
58
public/blog/src/css/main.css
Normal file
58
public/blog/src/css/main.css
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* css页面蓝图 */
|
||||||
|
|
||||||
|
/* 外部背景 */
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0; /*外边框*/
|
||||||
|
padding: 0; /*内边框*/
|
||||||
|
overflow: hidden; /* 防止滚动条 */
|
||||||
|
background-color: #333; /* 背景颜色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 内部容器 */
|
||||||
|
#app-canvas {
|
||||||
|
width: 1280px;
|
||||||
|
height: 800px;
|
||||||
|
|
||||||
|
background-color: rgba(147, 185, 255, 0.644);
|
||||||
|
border: 5px solid #0056b3; /* 定义边框 5px 实线 蓝色 */
|
||||||
|
/* transform-origin: 0 0; /* 定义缩放起点 左上角 */
|
||||||
|
|
||||||
|
position:fixed; /* 固定页面,不滚动 */
|
||||||
|
left: 50%; /* 调整左边缘位置到中央 */
|
||||||
|
top: 50%; /* 调整上边缘位置到中央 */
|
||||||
|
|
||||||
|
padding: 30px; /* 内部间距 30px */
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
margin-bottom: 30px; /* 外部间距 30px */
|
||||||
|
text-align: center; /* 文字居中 */
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 48px;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#content-area {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
gap: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 自带 */
|
||||||
|
.box {
|
||||||
|
width: 500px;
|
||||||
|
height: 600px;
|
||||||
|
background-color: #ffffffcc;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: left;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
BIN
public/blog/src/img/my_girl.png
Normal file
BIN
public/blog/src/img/my_girl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
BIN
public/blog/src/img/open-ww3-project.png
Executable file
BIN
public/blog/src/img/open-ww3-project.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
29
public/blog/src/js/main.js
Normal file
29
public/blog/src/js/main.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// js目前不会,先靠ai
|
||||||
|
|
||||||
|
function resizeCanvas() {
|
||||||
|
// 定义设计基准尺寸
|
||||||
|
const designWidth = 1280;
|
||||||
|
const designHeight = 800;
|
||||||
|
|
||||||
|
// 获取当前浏览器视口尺寸
|
||||||
|
const currentWidth = window.innerWidth;
|
||||||
|
const currentHeight = window.innerHeight;
|
||||||
|
|
||||||
|
const canvas = document.getElementById('app-canvas');
|
||||||
|
|
||||||
|
// 计算缩放比例
|
||||||
|
const scaleX = currentWidth / designWidth;
|
||||||
|
const scaleY = currentHeight / designHeight;
|
||||||
|
const scaleFactor = Math.min(scaleX, scaleY);
|
||||||
|
|
||||||
|
// 确保元素中心与 left: 50%; top: 50%; 对齐
|
||||||
|
canvas.style.transform = `translate(-50%, -50%) scale(${scaleFactor})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次加载时执行
|
||||||
|
document.addEventListener('DOMContentLoaded', resizeCanvas);
|
||||||
|
// 监听窗口大小变化时执行,保持动态缩放
|
||||||
|
window.addEventListener('resize', resizeCanvas);
|
||||||
|
|
||||||
|
// 确保在某些情况下也能正确初始化
|
||||||
|
resizeCanvas();
|
||||||
5033
public/blog/test.html
Normal file
5033
public/blog/test.html
Normal file
File diff suppressed because one or more lines are too long
45
public/blog/tui_jian/index.php
Normal file
45
public/blog/tui_jian/index.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>推荐网页</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<center>
|
||||||
|
<h3>漫画</h3>
|
||||||
|
<th>
|
||||||
|
<td id="font_a">
|
||||||
|
<a href="https://xmanhua.com/">xmanhua</a>
|
||||||
|
</td>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<td id="font_a">
|
||||||
|
<a href="https://komiic.com/">komiic</a>
|
||||||
|
</td>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<td id="font_a">
|
||||||
|
<a href="https://mangadex.org/">mangadex</a>
|
||||||
|
</td>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<td id="font_a">
|
||||||
|
<a href="https://mangabz.com/">mangabz</a>
|
||||||
|
</td>
|
||||||
|
</th>
|
||||||
|
<h3>动漫</h3>
|
||||||
|
<th>
|
||||||
|
<td id="font_a">
|
||||||
|
<a href="https://www.agedm.com">age动漫 | 尽量不要开梯</a>
|
||||||
|
</td>
|
||||||
|
</th>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#font_a {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1
public/blog/video.html
Normal file
1
public/blog/video.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115578442356850&bvid=BV12CCdBkEL6&cid=34120008494&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width: 100%; height: 100%;"></iframe>
|
||||||
25
public/docker-registry/all-images/index.php
Executable file
25
public/docker-registry/all-images/index.php
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// 1. 定义你的 Docker Registry 地址
|
||||||
|
// 请将 'http://localhost:5000' 替换为你的实际 Registry 地址。
|
||||||
|
// 例如:如果你的 Registry 是 'my-registry.io',就改为 'https://my-registry.io'
|
||||||
|
$registryUrl = "https://regw.ww3.tw/";
|
||||||
|
|
||||||
|
// 2. 定义你要获取的 API 端点
|
||||||
|
// 这个端点用于获取所有仓库列表。
|
||||||
|
$endpoint = "/v2/_catalog";
|
||||||
|
|
||||||
|
// 3. 组合完整的 URL
|
||||||
|
$fullUrl = $registryUrl . $endpoint;
|
||||||
|
|
||||||
|
// 4. 使用 file_get_contents() 获取 JSON 内容
|
||||||
|
// @ 符号用来抑制可能出现的错误或警告,让输出更干净。
|
||||||
|
$jsonContent = @file_get_contents($fullUrl);
|
||||||
|
|
||||||
|
// 5. 直接输出 JSON 内容
|
||||||
|
// 如果成功获取到内容,就直接打印出来。
|
||||||
|
// 如果获取失败,会打印一个空字符串或PHP的错误信息(如果没用@抑制)。
|
||||||
|
header('Content-Type: application/json'); // 告诉浏览器这是一个JSON响应
|
||||||
|
echo $jsonContent;
|
||||||
|
|
||||||
|
?>
|
||||||
11
public/docker-registry/index.html
Executable file
11
public/docker-registry/index.html
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>docker-registry</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<a href="./all-images/index.php">查看所有镜像</a>
|
||||||
|
<p>tags/list</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
public/index.html
Executable file
1
public/index.html
Executable file
@@ -0,0 +1 @@
|
|||||||
|
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">
|
||||||
29
public/index.php
Normal file
29
public/index.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!-- 主路由配置 -->
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
// 定义条件
|
||||||
|
$found_route = false;
|
||||||
|
|
||||||
|
|
||||||
|
switch($request_uri){
|
||||||
|
case '/':
|
||||||
|
include './re_blog.php';
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts 路由
|
||||||
|
// 整改中
|
||||||
|
|
||||||
|
|
||||||
|
// 所有路由匹配结束后,检查是否找到路由
|
||||||
|
if (!$found_route) {
|
||||||
|
// 设置 HTTP 状态码为 404
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
// 包含 404 页面文件
|
||||||
|
//exit();
|
||||||
|
include "../src/views/error/404.html";
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
}
|
||||||
29
public/index.php.back
Executable file
29
public/index.php.back
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
<!-- 主路由配置 -->
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
// 定义条件
|
||||||
|
$found_route = false;
|
||||||
|
|
||||||
|
|
||||||
|
switch($request_uri){
|
||||||
|
case '/':
|
||||||
|
include './re_blog.php';
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts 路由
|
||||||
|
// 整改中
|
||||||
|
|
||||||
|
|
||||||
|
// 所有路由匹配结束后,检查是否找到路由
|
||||||
|
if (!$found_route) {
|
||||||
|
// 设置 HTTP 状态码为 404
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
// 包含 404 页面文件
|
||||||
|
//exit();
|
||||||
|
include "../src/views/error/404.html";
|
||||||
|
exit(); // 执行成功立即结束
|
||||||
|
}
|
||||||
9
public/jumping-message/index.html
Executable file
9
public/jumping-message/index.html
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>弹幕留言 | jumping-message</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
public/jumping-message/index.php
Executable file
9
public/jumping-message/index.php
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>弹幕留言 | jumping-message</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
173
public/message/index.php
Executable file
173
public/message/index.php
Executable file
@@ -0,0 +1,173 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
<meta name="viewport" content="width=1366px, initial-scale=1.0"> <!-- 页面等比例缩小 -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="./static/css/navbar/body_color.css">
|
||||||
|
<link rel="icon" type="img/icon" href="./static/icon/original.ico">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
$title = "Message | 留言";
|
||||||
|
// title 变量
|
||||||
|
|
||||||
|
echo "<title>" . "$title" . "</title>";
|
||||||
|
// 页面标题
|
||||||
|
?>
|
||||||
|
<body id="body_color">
|
||||||
|
<div id="message_block">
|
||||||
|
<div id="content_page">
|
||||||
|
<?php
|
||||||
|
echo "<h1>欢迎来到 $title</h1>";
|
||||||
|
// 欢迎语
|
||||||
|
|
||||||
|
echo "感谢您的访问" . " " . "<br>" . "顾名思义" . "$title" . "就是用来记录留言的地方";
|
||||||
|
// 介绍部分
|
||||||
|
?>
|
||||||
|
<div id="back_blok">
|
||||||
|
<!-- 返回主页 -->
|
||||||
|
<a id="back_url" href="https://ww3.tw/"><b>..返回主页</b></a>
|
||||||
|
</div>
|
||||||
|
<div id="message_video">
|
||||||
|
<video src="./static/src/video/cirno-up-down.mp4" controls width="640" height="360">
|
||||||
|
您的浏览器不支持视频播放。
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
<div id="message_com">
|
||||||
|
<div id="push_message">
|
||||||
|
<label for="message">输入内容 : </label>
|
||||||
|
<input type="text" id="message" placeholder="qwq">
|
||||||
|
<button onclick="push_message()">发送弹幕</button>
|
||||||
|
<br>
|
||||||
|
<p>弹幕列表</p>
|
||||||
|
<pre id="get_message"></pre>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- php 引入 -->
|
||||||
|
<?php
|
||||||
|
include "./static/css/navbar/index-css.html";
|
||||||
|
// 引入navbar-css
|
||||||
|
?>
|
||||||
|
<!-- php 引入 -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 这里是专属css */
|
||||||
|
#content_page
|
||||||
|
{
|
||||||
|
color: rgb(255, 74, 74);
|
||||||
|
text-align: left;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message_video
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
width: 700px;
|
||||||
|
height: 410px;
|
||||||
|
/* 页面边距 上、右、下、左 */
|
||||||
|
margin: 1.89% 0px 0px 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message_com
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
width: 360px;
|
||||||
|
height: 410px;
|
||||||
|
/* 页面边距 上、右、下、左 */
|
||||||
|
margin: -405px 0px 0px 63.8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#back_blok{
|
||||||
|
/* 返回主页 */
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
width: 20%;
|
||||||
|
height: 4%;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
/* 页面边距 上、右、下、左 */
|
||||||
|
margin: 4% 0px 0px 36.8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#back_url
|
||||||
|
{
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--这里是专属js-->
|
||||||
|
<script>
|
||||||
|
function push_message() {
|
||||||
|
const messageInput = document.getElementById('message'); // 获取输入框元素本身
|
||||||
|
const messageContent = messageInput.value.trim(); // 获取输入框的值
|
||||||
|
|
||||||
|
if (messageContent === "") {
|
||||||
|
alert("弹幕内容不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageInput.value = '';
|
||||||
|
// *** 在这里清空输入框 ***
|
||||||
|
|
||||||
|
messageInput.focus();
|
||||||
|
// 如果你想让输入框在清空后立即获得焦点,方便用户继续输入
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
const API_URL = 'https://api.ww3.tw/public/danmu/get.php'; //连接api的地址
|
||||||
|
|
||||||
|
// 使用 DOMContentLoaded 事件,确保页面 HTML 结构加载完成后再执行 JavaScript
|
||||||
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
// 获取用于显示内容的 <pre> 元素
|
||||||
|
const getMessageElement = document.getElementById('get_message');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 发送 GET 请求到 API
|
||||||
|
const response = await fetch(API_URL);
|
||||||
|
|
||||||
|
// 检查 HTTP 响应状态码。如果不是 2xx(成功),说明有错误
|
||||||
|
if (!response.ok) {
|
||||||
|
// 尝试解析 API 返回的错误信息
|
||||||
|
let errorDetails;
|
||||||
|
try {
|
||||||
|
// 假设 API 错误信息也是 JSON 格式
|
||||||
|
errorDetails = await response.json();
|
||||||
|
} catch (e) {
|
||||||
|
// 如果不是 JSON,就作为纯文本处理
|
||||||
|
errorDetails = await response.text();
|
||||||
|
}
|
||||||
|
// 抛出带有详细信息的错误
|
||||||
|
throw new Error(`HTTP 错误! 状态码: ${response.status} - ${typeof errorDetails === 'object' && errorDetails !== null ? (errorDetails.message || JSON.stringify(errorDetails)) : errorDetails}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 你的 PHP API 返回的是 message.txt 的纯文本内容,所以这里使用 .text() 方法解析响应体
|
||||||
|
const content = await response.text();
|
||||||
|
|
||||||
|
// **** 核心修改:将获取到的内容直接赋值给 <pre> 元素的 textContent ****
|
||||||
|
getMessageElement.textContent = content;
|
||||||
|
getMessageElement.classList.remove('loading'); // 移除加载提示样式
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
// 如果在请求或处理过程中发生任何错误,捕获并显示
|
||||||
|
console.error('获取弹幕内容失败:', error);
|
||||||
|
getMessageElement.textContent = `错误: ${error.message}`;
|
||||||
|
getMessageElement.classList.remove('loading'); // 移除加载提示样式
|
||||||
|
getMessageElement.classList.add('error'); // 添加错误样式
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
0
public/message/static/css/message.css
Executable file
0
public/message/static/css/message.css
Executable file
4
public/message/static/css/navbar/body_color.css
Executable file
4
public/message/static/css/navbar/body_color.css
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#body_color
|
||||||
|
{
|
||||||
|
background-color: rgba(147, 185, 255, 0.644);
|
||||||
|
}
|
||||||
14
public/message/static/css/navbar/index-css.html
Executable file
14
public/message/static/css/navbar/index-css.html
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
<style>
|
||||||
|
#message_block
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.68);
|
||||||
|
position: fixed;
|
||||||
|
width: 1150px;
|
||||||
|
height: 100%;
|
||||||
|
margin: auto;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
0
public/message/static/css/video.css
Executable file
0
public/message/static/css/video.css
Executable file
3
public/message/static/html/content_message.html
Executable file
3
public/message/static/html/content_message.html
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
BIN
public/message/static/icon/original.ico
Executable file
BIN
public/message/static/icon/original.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
0
public/message/static/js/video.js
Executable file
0
public/message/static/js/video.js
Executable file
26
public/message/static/php/google_translate.php
Executable file
26
public/message/static/php/google_translate.php
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
<!-- 谷歌翻译 -->
|
||||||
|
|
||||||
|
<div id="google_translate_element"></div>
|
||||||
|
<!-- 翻译选项 -->
|
||||||
|
|
||||||
|
<!-- js 部分 -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
function googleTranslateElementInit() {
|
||||||
|
new google.translate.TranslateElement({pageLanguage: 'zh-CN'}, 'google_translate_element');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
|
||||||
|
<!-- js 部分 -->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#google_translate_element
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
position: fixed;
|
||||||
|
/* 页面边距 上、右、下、左 */
|
||||||
|
margin: -7.6px 0px 0px 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- 谷歌翻译 -->
|
||||||
1
public/message/static/txt/message.txt
Executable file
1
public/message/static/txt/message.txt
Executable file
@@ -0,0 +1 @@
|
|||||||
|
这是测试
|
||||||
1
public/message/static/txt/测试.txt
Normal file
1
public/message/static/txt/测试.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
测试
|
||||||
2
public/re_blog.php
Executable file
2
public/re_blog.php
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
<!-- 域名跳转 ./blog/ -->
|
||||||
|
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/blog/">
|
||||||
BIN
public/short-url/icon/icon.jpg
Executable file
BIN
public/short-url/icon/icon.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
12
public/short-url/index.php
Executable file
12
public/short-url/index.php
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>short_url | 短链</title>
|
||||||
|
<meta charset="utf-8" lang="zh-CN">
|
||||||
|
<link rel="icon" type="image/x-icon" href="./icon/icon.jpg">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
ww3-short-url | 短链
|
||||||
|
</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
public/short_url/index.php
Executable file
1
public/short_url/index.php
Executable file
@@ -0,0 +1 @@
|
|||||||
|
<meta http-equiv="refresh" content="0.1;url=https://open-ww3-project.ww3.tw/short-url/">
|
||||||
BIN
public/static/error/cirno-image.jpg
Executable file
BIN
public/static/error/cirno-image.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
14
public/static/html/black-block.html
Normal file
14
public/static/html/black-block.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<style>
|
||||||
|
#black_block
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.68);
|
||||||
|
position: fixed;
|
||||||
|
width: 1150px;
|
||||||
|
height: 100%;
|
||||||
|
margin: auto;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
11
src/md/1.md
Executable file
11
src/md/1.md
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
# 今天、2025.7.30
|
||||||
|
----
|
||||||
|
|
||||||
|
blog 正式 完工
|
||||||
|
|
||||||
|
测试
|
||||||
|
|
||||||
|
**署名**
|
||||||
|
|
||||||
|
<br>
|
||||||
|
SkimrMe_
|
||||||
479
src/md/MD.php
Executable file
479
src/md/MD.php
Executable file
@@ -0,0 +1,479 @@
|
|||||||
|
|
||||||
|
<?php
|
||||||
|
Header('Content:text/html;charset=utf-8');
|
||||||
|
?>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body,ol,ul,li,img,p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li{
|
||||||
|
list-style-type: square;
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6{
|
||||||
|
margin:10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3{
|
||||||
|
border-bottom:solid 1px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
padding-bottom:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3{
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body,ul{
|
||||||
|
padding:10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width:1024px;
|
||||||
|
margin:0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote{
|
||||||
|
border-left:solid 4px #bbb;
|
||||||
|
background-color:#eee;
|
||||||
|
min-height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
padding:0px 10px;
|
||||||
|
margin:0;
|
||||||
|
color:#333;
|
||||||
|
font-size:12px;
|
||||||
|
font-style: italic;
|
||||||
|
font-family: consolas,楷体;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,td,th{
|
||||||
|
border:solid 1px #ddd;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding:10px;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table{
|
||||||
|
margin:10px 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-left{
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-right{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even){
|
||||||
|
background-color:#eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
code,pre{
|
||||||
|
border-radius:5px;
|
||||||
|
border:solid 1px #eee;
|
||||||
|
background-color:#f9f9f9;
|
||||||
|
font-family: consolas;
|
||||||
|
font-size:14px;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
code{
|
||||||
|
padding:2px 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre{
|
||||||
|
padding:10px 12px;
|
||||||
|
overflow-x:auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* flag规则:
|
||||||
|
* h1-h6 标题
|
||||||
|
* u1,u2 无序列表
|
||||||
|
* ol 有序列表
|
||||||
|
* p 普通文本
|
||||||
|
* code 代码
|
||||||
|
* table 文本
|
||||||
|
* check 选择
|
||||||
|
* uncheck 未选择
|
||||||
|
* quote 引用
|
||||||
|
* img 图片
|
||||||
|
* url 网址
|
||||||
|
* bold 加粗
|
||||||
|
* italia 斜体
|
||||||
|
* el 空行
|
||||||
|
*
|
||||||
|
* idel 闲置
|
||||||
|
*/
|
||||||
|
class MD{
|
||||||
|
|
||||||
|
private $file; //当前文件
|
||||||
|
private $mdGen; //生成器
|
||||||
|
private $flag; //当前标志
|
||||||
|
private $flag_pre; //上一次的flag
|
||||||
|
private $flag_like; //假定类型
|
||||||
|
|
||||||
|
private $line_count; //总行数
|
||||||
|
private $lines; //所有行
|
||||||
|
private $buf; //缓存行
|
||||||
|
|
||||||
|
public function __construct($filename){
|
||||||
|
$this->file = $filename; //设置当前文件
|
||||||
|
$this->mdGen = $this->content($filename); //获取生成器
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
$this->lines = array(); //所有行状态
|
||||||
|
$this->line_count = 0; //行数归0
|
||||||
|
}
|
||||||
|
|
||||||
|
private function content($file){ //获取生成器
|
||||||
|
if(file_exists($file)){
|
||||||
|
$fh = fopen($file,"r");
|
||||||
|
while(!feof($fh)){
|
||||||
|
yield fgets($fh);
|
||||||
|
}
|
||||||
|
fclose($fh);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历每一个字符
|
||||||
|
private function every($str){
|
||||||
|
$l = strlen($str);
|
||||||
|
for($i=0;$i<$l;$i++)
|
||||||
|
if(ord($str[$i])<0x80)
|
||||||
|
yield $str[$i];
|
||||||
|
else{
|
||||||
|
yield $str[$i].$str[$i+1].$str[$i+2]; //三个字节
|
||||||
|
$i+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析
|
||||||
|
private function parse(){
|
||||||
|
$ctnt = $this->mdGen; //生成器
|
||||||
|
$ret=array();
|
||||||
|
if($ctnt != null){
|
||||||
|
$ret = array();
|
||||||
|
foreach($ctnt as $line){
|
||||||
|
if($this->flag != 'code')
|
||||||
|
$line=ltrim($line); //删除左边
|
||||||
|
if(strlen($line)){
|
||||||
|
$ch = $line[0]; //判断第一个字符
|
||||||
|
$type=ctype_punct($ch);//标点符号
|
||||||
|
if($this->flag !== 'code') $line=preg_replace('/\s{2,}$/','<br>',$line); //非代码模式
|
||||||
|
$ret[] = $this->parseLine($line,$type); //解析行
|
||||||
|
}else{ //空行
|
||||||
|
switch($this->flag){
|
||||||
|
case 'ul':
|
||||||
|
case 'ol':
|
||||||
|
$ret[]="</$this->flag>";
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel';
|
||||||
|
break;
|
||||||
|
case 'table':
|
||||||
|
$this->flag = 'idel';
|
||||||
|
$ret[]='</table>';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if($this->flag != 'el') $ret[] = '<br>';
|
||||||
|
$this->flag = 'el'; //空行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->lines = $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成blockquote
|
||||||
|
private function genQuote($level,$content){
|
||||||
|
if($level<=0) return "";
|
||||||
|
return str_repeat('<blockquote>',$level).$content.str_repeat('</blockquote>',$level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否处于某个状态,默认检查是否处于代码状态
|
||||||
|
private function check($value='code'){
|
||||||
|
return ($this->flag == $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成一行新的表格列
|
||||||
|
* $data:需要输入的数据
|
||||||
|
* $type:生成类型
|
||||||
|
* $wrap:最快层包裹
|
||||||
|
* $sep:分隔符
|
||||||
|
*/
|
||||||
|
private function genRow($data,$type='td',$wrap='tr',$sep='|'){
|
||||||
|
$ret='';
|
||||||
|
$mat = explode($sep,$data);
|
||||||
|
foreach($mat as $elem)
|
||||||
|
$ret.="<$type>".$elem."</$type>";
|
||||||
|
return "<$wrap>".$ret."</$wrap>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析行内元素
|
||||||
|
* bold,italic,code,link,pic
|
||||||
|
*/
|
||||||
|
private function parseInner($str){
|
||||||
|
$str=preg_replace('/\*\*\*([^\*\n\r]+)\*\*\*/','<b><i>\1</i></b>',$str); //加粗并加斜字体
|
||||||
|
$str=preg_replace('/\*\*([^\*\n\r]+)\*\*/','<b>\1</b>',$str); //加粗字体
|
||||||
|
$str=preg_replace('/\*([^\*\n\r]+)\*/','<i>\1</i>',$str); //斜体
|
||||||
|
$str=preg_replace('/```([^`\n\r]+)```/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/`([^`\n\r]+)`/','<code>\1</code>',$str); //代码
|
||||||
|
$str=preg_replace('/!\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<img src="\2" alt="\1" title="\1">',$str); //图片
|
||||||
|
$str=preg_replace('/\[([^\]\r\n]+)\]\(([^\)\r\n]+)\)/','<a href="\2">\1</a>',$str); //图片
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照给定规则解析字符串:
|
||||||
|
* type:
|
||||||
|
* true 符号
|
||||||
|
* false 文字
|
||||||
|
* 返回:
|
||||||
|
* array('type'=>类型,'parts'=>array(...))
|
||||||
|
*/
|
||||||
|
private function parseLine($str,$type){
|
||||||
|
if(strlen($str) == 0){
|
||||||
|
return array('type'=>'p','parts'=>[]); //返回空段
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid_str = rtrim($str); //去除右边的空格
|
||||||
|
|
||||||
|
$str = $valid_str;
|
||||||
|
$output = ''; //需要输出的字符串
|
||||||
|
|
||||||
|
if($type == true){ //标点
|
||||||
|
$type_str = ''; //类型字符串
|
||||||
|
$data_str = '';
|
||||||
|
$flag = 0;
|
||||||
|
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
if(!ctype_punct($ch)){
|
||||||
|
$flag = 1;
|
||||||
|
}
|
||||||
|
if($flag == 0)
|
||||||
|
$type_str .= $ch;
|
||||||
|
else
|
||||||
|
$data_str .= $ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($type_str){
|
||||||
|
case '#':
|
||||||
|
$wrap = 'h1';
|
||||||
|
$this->flag_like = 'h1';
|
||||||
|
break;
|
||||||
|
case '##':
|
||||||
|
$wrap = 'h2';
|
||||||
|
$this->flag_like = 'h2';
|
||||||
|
break;
|
||||||
|
case '###':
|
||||||
|
$wrap = 'h3';
|
||||||
|
$this->flag_like = 'h3';
|
||||||
|
break;
|
||||||
|
case '####':
|
||||||
|
$wrap = 'h4';
|
||||||
|
$this->flag_like = 'h4';
|
||||||
|
break;
|
||||||
|
case '#####':
|
||||||
|
$wrap = 'h5';
|
||||||
|
$this->flag_like = 'h5';
|
||||||
|
break;
|
||||||
|
case '######':
|
||||||
|
$wrap = 'h6';
|
||||||
|
$this->flag_like = 'h6';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '```': //代码模式,不进行干扰
|
||||||
|
if($this->flag != 'code'){ //不为code,判断是否为单行代码
|
||||||
|
$output.='<pre>';
|
||||||
|
if(preg_match('/^\s*```([^`]+)```([^\s]+)\s*$/',$str,$mat)){ //单行代码
|
||||||
|
$output.="$mat[1]</pre>$mat[2]";
|
||||||
|
$str = '';
|
||||||
|
$data_str = '';
|
||||||
|
}else{
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'code'; //代码
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$output.='</pre>';
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'idel'; //闲置
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(preg_match('/^\[\s\]\s*(.+)$/',$str,$mat)){ //选择
|
||||||
|
$output.="<label><input type='checkbox' disabled> $mat[1]</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
}else if(preg_match('/^\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){ //未选择
|
||||||
|
$output.="<a href='$mat[2]'>$mat[1]</a>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'a'; //网址
|
||||||
|
}else if(preg_match('/^\s*(\[\d+\]\:)\s+([^\s]+)\s+([^\r\n]+)\s*$/',$str,$mat)){ //外部资料
|
||||||
|
$output.="$mat[1] <a href='$mat[2]'>$mat[3]</a>";
|
||||||
|
}else{
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '[-]':
|
||||||
|
$output.="<label><input type='checkbox' checked disabled>$data_str</label><br>";
|
||||||
|
$this->flag_like = 'check';
|
||||||
|
break;
|
||||||
|
case '![':
|
||||||
|
if(preg_match('/^!\[([^\]]+)\]\(([^\)]+)\)([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.="<img src='$mat[2]' alt='$mat[1]'>".$this->parseInner($mat[3]);
|
||||||
|
$this->flag_like = 'img';
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p'; //没有模式
|
||||||
|
$output.="$str";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*': //斜体
|
||||||
|
if(preg_match('/^\*(.*)\*([^\s]+)\s*$/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'i';
|
||||||
|
}else if(preg_match('/^\s*\*\s+(.+)\s*$/',$str,$mat)){
|
||||||
|
$str=$mat[1];
|
||||||
|
$wrap = 'li';
|
||||||
|
$this->flag_like = 'ul';
|
||||||
|
if($this->flag != 'code'){
|
||||||
|
if($this->flag != 'ul'){
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = 'ul';
|
||||||
|
$output.='<ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '**': //粗体
|
||||||
|
if(preg_match('/^\*\*(.*)\*\*/',$str,$mat)){
|
||||||
|
$output.=$this->parseInner($str);
|
||||||
|
$this->flag_like = 'b';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$output.=$str;
|
||||||
|
$this->flag_like = 'html';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!$this->check()){ //非代码模式
|
||||||
|
if(preg_match('/^>+$/',$type_str)){ //引用
|
||||||
|
$level = strlen($type_str);
|
||||||
|
$this->flag_like = 'quote';
|
||||||
|
$output.=$this->genQuote($level,$data_str); //引用
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格确定格式---|---|....
|
||||||
|
if($this->flag == 'table'){
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$output.='<table><thead>'.$this->genRow($this->buf,'th').'</thead><tbody>';
|
||||||
|
}else{ //非表格格式,上一行没有标题
|
||||||
|
$this->flag_like = 'p'; //没有格式
|
||||||
|
$output.=$this->buf;
|
||||||
|
$this->buf = '';
|
||||||
|
}
|
||||||
|
}else if(preg_match('/^\s*(\-{3,})|(\={3,})$/',$type_str)){ //hr
|
||||||
|
$output.='<hr>';
|
||||||
|
$this->flag_like = 'hr';
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'p';
|
||||||
|
$output.=$str.'<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$br = '';
|
||||||
|
preg_match('/^(.*)(<br\s*\/?>)?$/',$data_str,$mat);
|
||||||
|
$data_str = htmlspecialchars($mat[1]);
|
||||||
|
if(!$this->check()){ //代码
|
||||||
|
if(!empty($wrap)) $output.="<$wrap>$mat[1]</$wrap>".(isset($mat[2])?'<br>':'');
|
||||||
|
}else if($type_str!='```'){
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}
|
||||||
|
}else{ //首个非空字符不为符号
|
||||||
|
if($this->flag == 'code'){ //代码,直接输出
|
||||||
|
$str=str_replace("\t",' ',$str);
|
||||||
|
$output.=htmlspecialchars($str).'<br>';
|
||||||
|
}else if(is_numeric($str[0])){ //可能为有序列表,也可能是表格
|
||||||
|
if(preg_match('/^\s*\d+\.\s+([^\r\n]+)\s*$/',$str)){ //有序列表
|
||||||
|
$this->flag_like = 'ol';
|
||||||
|
$output.=$str;
|
||||||
|
}else{
|
||||||
|
$this->flag_like = 'idel';
|
||||||
|
foreach($this->every($str) as $ch){
|
||||||
|
$output.=$ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output.='<br>';
|
||||||
|
}else if(preg_match('/^([^\|\n\r]+)(?:\|[^\|\n\r]+)+$/',$str)){ //表格
|
||||||
|
$mat = explode('|',$str);
|
||||||
|
|
||||||
|
if($this->flag!='table'){ //进入表格
|
||||||
|
$this->buf = $str;
|
||||||
|
$this->flag_like = 'table';
|
||||||
|
$wrap = '';
|
||||||
|
}else{
|
||||||
|
$output.=$this->genRow($str);
|
||||||
|
}
|
||||||
|
//echo $mat[0].'<br>';
|
||||||
|
//var_dump($mat);
|
||||||
|
}else{ //其他
|
||||||
|
$this->flag = 'p';
|
||||||
|
$output.=$str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->check()){ //不为代码,设置flag
|
||||||
|
$this->flag_pre = $this->flag;
|
||||||
|
$this->flag = $this->flag_like;
|
||||||
|
if($this->flag_pre == 'table' && $this->flag != 'table')
|
||||||
|
$output='</table>'.$output;
|
||||||
|
else if($this->flag_pre == 'ul' && $this->flag != 'ul'){
|
||||||
|
$output='</ul>'.$output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseInner($output); //输出需要输出的内容
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取输出内容
|
||||||
|
public function output(){
|
||||||
|
$this->parse();
|
||||||
|
echo implode('',$this->lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/md/inite.php
Executable file
6
src/md/inite.php
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require '/var/www/owp/open-ww3-project-ww3-tw/src/md/MD.php';
|
||||||
|
|
||||||
|
$md=new MD('/var/www/owp/open-ww3-project-ww3-tw/src/md/inte.md');
|
||||||
|
$md->output();
|
||||||
10
src/md/inte.md
Executable file
10
src/md/inte.md
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
## MD介绍页面
|
||||||
|
|
||||||
|
顾名思义、本文件夹下使用的基本都是markdown
|
||||||
|
|
||||||
|
最后感谢提供php的md插件的开源制作者
|
||||||
|
|
||||||
|
[点击跳转](https://ww3.tw/blog/md/src/php-markdown/)
|
||||||
|
|
||||||
|
日期 2025.07.30
|
||||||
|
|
||||||
19
src/views/error/404.html
Executable file
19
src/views/error/404.html
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-Hant">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>404 Not Found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="font-size: 250%;">到达世界尽头,这里什么都没有哦</h1>
|
||||||
|
<a style="font-size: 150%;" href="/">返回主页</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
background-image: url(https://open-ww3-project.ww3.tw/static/error/cirno-image.jpg);
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user