当前位置:网站首页>Hugo blog graphical writing tool -- QT practice
Hugo blog graphical writing tool -- QT practice
2022-07-06 09:46:00 【C+++++++++++++++++++】
List of articles
Software use

Project introduction
reminder : If it has not been built locally hugo Blog , You can use my other hugo Blog auto build tool

QtRun:
Introduce : One is pure C++ Write command line tools .
The main role : On the basis of hugo Blog local address for command-line automatic writing , Will put the pictures of each article 、 classification 、 The title and other contents are completed automatically .
Construction mode : Ensure build exe The directory of the file contains the following files , And ensure that the compiler supports C++17.
BlogPath.txt # Provide local hugo Blog path categories.txt # Provide alternative classifications ( It doesn't matter ) initImg.txt # Provide optional pictures mob.txt # Provide templates for generation ed_Path.txt # Provide the open editor path ( It doesn't matter )Usage mode : You can check the source code to get a more detailed answer
QtRun [title name] [category name] Qtrun [-op]
QtRunBlog:
- Introduce : Use Qt+cmake Graphical construction hugo Automation tools , The relevant parts of writing are called QtRun , So the runtime QtRun Configuration files and QtRun Must be in its exe Under the catalogue . Other parts call git Command line , So we need local git Tools .
- The main role : Provide graphical hugo Writing experience .
- Construction mode : Local needs Qt6 Environmental Science , Select this project directory to complete the construction .
QtRun C++ Source code
Realize automatic command line writing ,QtRunBlog The graphical interface calls its command line
//
// Created by Alone on 2022-1-24.
//
//TODO aaaaaaa Get insights :1. Try not to use global variables when the data is complex 2. When initializing the constructor, never directly new Space for it , Remember anytime, anywhere nullptr
#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <unistd.h>
#include <windows.h>
#include <vector>
#include <unordered_map>
#include <ctime>
#include <filesystem>
#include <random>
#define IMGS_PATH "./initImg.txt"
#define MOB_PATH "./mob.txt"
#define CATEGORIES_PATH "./categories.txt"
#define BLOG_SRC "./BlogPath.txt"
std::filesystem::path POSTS_PATH;// Used to get post_path
using namespace std;
//TODO Establish enumeration mapping
enum class SHOW_ARGS : int {
EMPTY, CATEGORIES, IMG, BLOG_PATH
};
//TODO Enumeration mapping of command line parameters
unordered_map<string, SHOW_ARGS> MAP{
{
"-sc", SHOW_ARGS::CATEGORIES},
{
"-si", SHOW_ARGS::IMG},
{
"-sp", SHOW_ARGS::BLOG_PATH}
};
//TODO Package file reading class
class FileReader {
stringstream in_buf;
ifstream reader;
public:
FileReader() = default;
FileReader(const FileReader &) = delete;
FileReader(FileReader &&) = delete;
~FileReader() {
if (reader.is_open())
reader.close();
}
void open(const string &path) {
reader.open(path);
if (!reader.is_open()) {
perror("reader open failed");
exit(1);
}
in_buf << reader.rdbuf();
}
bool readAll(string &dst) {
if (in_buf.good())
dst = in_buf.str();
else
return false;
return true;
}
bool readline(string &dst) {
if (in_buf.good())
getline(in_buf, dst);
else return false;
return true;
}
};
//TODO Package file write class
class FileWriter {
char *out_buf;
ofstream writer;
size_t cur_buf_size;
size_t max_buf_size;
private:
void _write() {
// Buffer full , Write to file
writer.write(out_buf, max_buf_size);
cur_buf_size = 0;
}
public:
FileWriter() : cur_buf_size(0), max_buf_size(512), out_buf(nullptr) {
};
FileWriter(const FileReader &) = delete;
FileWriter(FileReader &&) = delete;
FileWriter(const string &path, ios::openmode mode = ios::out) {
writer.open(path, mode);
if (!writer.is_open()) {
perror("writer open failed");
exit(1);
}
cur_buf_size = 0;
max_buf_size = 512;
out_buf = new char[max_buf_size + 5];
}
~FileWriter() {
if (cur_buf_size > 0) {
writer.write(out_buf, cur_buf_size);
cur_buf_size = 0;
}
delete[] out_buf;
out_buf = nullptr;
writer.flush();
writer.close();
}
static bool exist(const string &path) {
return (access(path.c_str(), F_OK) != -1);
}
void open(const string &path, ios::openmode mode = ios::out) {
writer.open(path, mode);
if (!writer.is_open()) {
perror("writer open failed");
exit(1);
}
out_buf = new char[max_buf_size + 5];
}
void write(const string &src) {
//TODO An important part of the buffer mechanism
if (writer.is_open()) {
// Only in open File before writing
if (src.empty()) return;
if (cur_buf_size == max_buf_size)
_write();
size_t psize = src.size() + cur_buf_size;// If the whole disk is written to the buffer , The required size of the buffer
int startp = 0, maxLen;
while (psize > max_buf_size) {
// When the amount of data written to the buffer this time is greater than the size of the buffer , Then continue to fill up and update
maxLen = max_buf_size - cur_buf_size;
copy(src.begin() + startp, src.begin() + startp + maxLen, out_buf + cur_buf_size);//copy To the full state , Once again write
_write();
startp += maxLen;
psize -= max_buf_size;
}
// If the write data does not exceed the buffer size , Write directly to
copy(src.begin() + startp, src.end(), out_buf + cur_buf_size);
cur_buf_size += src.size() - startp;
}
}
FileWriter &append(const string &src) {
//TODO and write No difference , It only supports chained calls
write(src);
return *this;
}
};
//TODO Variables that need to be operated in the whole project ( It is not recommended to use global variables , This is what caused me bug)
FileReader readImg, readText, readCategories;// Used for file io The variable of
FileWriter appendCategories, fileWriter;
vector<string> imgs, categories; // Used to store data from disk to memory , Judge what is stored according to the name
time_t now = time(NULL);
//TODO open typora Software
void open_exe_from_path(const char *path) {
WinExec(path, SW_SHOWNORMAL);
cout << "open your custom editor successfully!" << endl;
}
//TODO Print the content
void show(vector<string> &src) {
for (int i = 0; i < src.size(); i++) {
if (!src[i].empty())
printf("%d: %s\n", i, src[i].c_str());
}
}
//TODO Replace string The content of
void to_replace(string &s, const string &target, const string &replacement) {
int i = 0;
int find_ret;
int tar_len = target.size();
while ((find_ret = s.find(target, i)) != -1) {
s.replace(find_ret, tar_len, replacement);
i = find_ret;
}
}
//TODO Print the wrong message , And quit the program
void exit_print(const char *content) {
printf("running failed: %s\n", content);
exit(1);
}
//TODO Get the current time
string get_cur_time() {
tm *tm_t = localtime(&now);
char c_time[50];
sprintf(c_time, "%04d-%02d-%02d",
tm_t->tm_year + 1900,
tm_t->tm_mon + 1,
tm_t->tm_mday);
return string(c_time);
}
//TODO Basic initialization data
void InitInputFileInfo() {
readImg.open(IMGS_PATH);
readText.open(MOB_PATH);
readCategories.open(CATEGORIES_PATH);
}
void InitOutputFileInfo(const string &targetPath) {
fileWriter.open(targetPath);
appendCategories.open(CATEGORIES_PATH, ios::app);
}
void InitImgs() {
string tmp;
while (readImg.readline(tmp)) {
if (!tmp.empty())
imgs.push_back(tmp);
}
//todo After shuffling the contents of the array
shuffle(imgs.begin(), imgs.end(), std::default_random_engine(now));
}
void InitCategories() {
string tmp;
while (readCategories.readline(tmp)) {
categories.push_back(tmp);
}
}
void InitPostPath() {
FileReader fd;
fd.open(BLOG_SRC);
string pth;
fd.readline(pth);
POSTS_PATH = pth;
}
//TODO Dealing with three parameters
void solve(const char *arg1, const char *arg2) {
//todo initialization io Logic
InitInputFileInfo();
InitImgs();
InitCategories();
string text;
string category;
InitPostPath();
POSTS_PATH /= "content";
POSTS_PATH /= "posts";
POSTS_PATH /= string(arg1) + ".md";
if (filesystem::exists(POSTS_PATH))
exit_print("file exist!");
InitOutputFileInfo(POSTS_PATH.string());
//todo replace text
srand(now); // Reseed with the current time as the seed
int randomIndex = rand() % imgs.size();// Choose a picture at random
readText.readAll(text);
to_replace(text, "%s", arg1);// Change the article name to the title name
to_replace(text, "%T", imgs[randomIndex]);// Replace the picture content
to_replace(text, "%D", get_cur_time()); // Replace the current date
// according to arg2 To select the replacement classification content
if (to_string(atoi(arg2)) == arg2) {
// Judge arg2 Is the number passed
int index = atoi(arg2);
if (index < categories.size() - 1) {
// The classification of corresponding subscripts is selected by numbers
category = categories[index];
} else {
// The number is illegal , Exit procedure
exit_print("number not allowed");
}
} else {
// Not numbers , It means that a new classification has been created
category = arg2;
appendCategories.append(string(arg2) + "\n");
}
to_replace(text, "#", category);
//todo Finally, write the data to the disk
fileWriter.write(text);
}
int main(int argc, char const *argv[]) {
system("chcp 65001");
SHOW_ARGS state;// because switch The first level of the statement cannot define temporary variables
switch (argc) {
case 2://todo Strings from the outside world are actually not very important , Mainly, the enumeration status can be determined according to this string , Then carry out different content show operation
state = MAP[argv[1]];
if (state == SHOW_ARGS::EMPTY) {
//1. The string is not in the hash table
fputs("args error,may be you should get something below:\n", stderr);
for (auto[k, v]:MAP) {
// Display parameter prompt
if (v == SHOW_ARGS::EMPTY)continue;// Skip the object created when the value is obtained above
fputs((k + '\n').c_str(), stderr);
}
exit(1);
} else if (state == SHOW_ARGS::CATEGORIES) {
//2. Display classification information
InitInputFileInfo();
InitCategories();
show(categories);
} else if (state == SHOW_ARGS::IMG) {
//3. Show links to pictures
InitInputFileInfo();
InitImgs();
show(imgs);
} else if (state == SHOW_ARGS::BLOG_PATH) {
//4. Show blog address
InitPostPath();
cout << POSTS_PATH << '\n';
}
return 0;// Just show the data and exit
case 3:
solve(argv[1], argv[2]);
break;
default:
printf("Usage :\n%s [title name] [category name]\n", argv[0]);
printf("%s [-op]\nsuch as -s to show what category number can choose.\n", argv[0]);
exit(1);
}
ifstream reader;// Read the address of the editor and open
reader.open("./ed_Path.txt");
if (!reader.is_open()) {
exit_print("file reader failed in read editorPath");
}
string str;
reader >> str;
if (!str.empty())
open_exe_from_path(str.c_str());
else {
// If the file editor path is not set , Default to vscode Open Directory
string cmd = "code " + POSTS_PATH.string();
system(cmd.c_str());
printf("open vscode successfully!\n");
}
reader.close();
cout << "finish yet!" << endl;
return 0;
}
边栏推荐
- 发生OOM了,你知道是什么原因吗,又该怎么解决呢?
- Counter attack of noodles: redis asked 52 questions in a series, with detailed pictures and pictures. Now the interview is stable
- 068.查找插入位置--二分查找
- Design and implementation of online shopping system based on Web (attached: source code paper SQL file)
- 英雄联盟轮播图手动轮播
- Hero League rotation map automatic rotation
- Publish and subscribe to redis
- Why can't TN-C use 2p circuit breaker?
- 五月刷题02——字符串
- 【深度学习】语义分割:论文阅读(NeurIPS 2021)MaskFormer: per-pixel classification is not all you need
猜你喜欢

基于B/S的医院管理住院系统的研究与实现(附:源码 论文 sql文件)

Mapreduce实例(九):Reduce端join

Some thoughts on the study of 51 single chip microcomputer

Take you back to spark ecosystem!

【深度学习】语义分割:论文阅读:(CVPR 2022) MPViT(CNN+Transformer):用于密集预测的多路径视觉Transformer

MapReduce working mechanism

Activiti7工作流的使用

Single chip microcomputer realizes modular programming: Thinking + example + system tutorial (the degree of practicality is appalling)

51单片机进修的一些感悟

一大波开源小抄来袭
随机推荐
068. Find the insertion position -- binary search
Learning SCM is of great help to society
Global and Chinese market of electronic tubes 2022-2028: Research Report on technology, participants, trends, market size and share
51单片机进修的一些感悟
Libuv thread
May brush question 03 - sorting
嵌入式开发比单片机要难很多?谈谈单片机和嵌入式开发设计经历
How can I take a shortcut to learn C language in college
What you have to know about network IO model
Release of the sample chapter of "uncover the secrets of asp.net core 6 framework" [200 pages /5 chapters]
五月刷题27——图
Hard core! One configuration center for 8 classes!
33岁可以学PLC吗
美团二面:为什么 Redis 会有哨兵?
Minio distributed file storage cluster for full stack development
CANoe不能自动识别串口号?那就封装个DLL让它必须行
Teach you how to write the first MCU program hand in hand
CAPL 脚本打印函数 write ,writeEx ,writeLineEx ,writeToLog ,writeToLogEx ,writeDbgLevel 你真的分的清楚什么情况下用哪个吗?
MapReduce instance (IV): natural sorting
五月刷题01——数组