当前位置:网站首页>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;
}
边栏推荐
- Single chip microcomputer realizes modular programming: Thinking + example + system tutorial (the degree of practicality is appalling)
- In order to get an offer, "I believe that hard work will make great achievements
- Mapreduce实例(六):倒排索引
- 五月集训总结——来自阿光
- Publish and subscribe to redis
- Nc17 longest palindrome substring
- Basic concepts of libuv
- CANoe不能自动识别串口号?那就封装个DLL让它必须行
- 基于B/S的医院管理住院系统的研究与实现(附:源码 论文 sql文件)
- CAP理论
猜你喜欢

Listen to my advice and learn according to this embedded curriculum content and curriculum system

MapReduce instance (VII): single table join

I2C summary (single host and multi host)

Oom happened. Do you know the reason and how to solve it?

MapReduce instance (VI): inverted index

英雄联盟轮播图手动轮播

为拿 Offer,“闭关修炼,相信努力必成大器

【深度学习】语义分割-源代码汇总

Counter attack of noodles: redis asked 52 questions in a series, with detailed pictures and pictures. Now the interview is stable

Solve the problem of inconsistency between database field name and entity class attribute name (resultmap result set mapping)
随机推荐
MySQL数据库优化的几种方式(笔面试必问)
Redis connection redis service command
Scoped in webrtc_ refptr
解决小文件处过多
【深度学习】语义分割:论文阅读:(CVPR 2022) MPViT(CNN+Transformer):用于密集预测的多路径视觉Transformer
Counter attack of noodles: redis asked 52 questions in a series, with detailed pictures and pictures. Now the interview is stable
五月刷题26——并查集
Webrtc blog reference:
Interview shock 62: what are the precautions for group by?
Global and Chinese market of electric pruners 2022-2028: Research Report on technology, participants, trends, market size and share
六月刷题02——字符串
What you have to know about network IO model
Libuv thread
Segmentation sémantique de l'apprentissage profond - résumé du code source
YARN组织架构
五月集训总结——来自阿光
Mapreduce实例(七):单表join
Global and Chinese market of appointment reminder software 2022-2028: Research Report on technology, participants, trends, market size and share
Global and Chinese market of airport kiosks 2022-2028: Research Report on technology, participants, trends, market size and share
CAPL 脚本打印函数 write ,writeEx ,writeLineEx ,writeToLog ,writeToLogEx ,writeDbgLevel 你真的分的清楚什么情况下用哪个吗?