当前位置:网站首页>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;
}
边栏推荐
- 六月刷题02——字符串
- Counter attack of noodles: redis asked 52 questions in a series, with detailed pictures and pictures. Now the interview is stable
- 嵌入式開發中的防禦性C語言編程
- Popularization of security knowledge - twelve moves to protect mobile phones from network attacks
- 五月集训总结——来自阿光
- 068. Find the insertion position -- binary search
- Why can't TN-C use 2p circuit breaker?
- Can I learn PLC at the age of 33
- Cooperative development in embedded -- function pointer
- 【深度学习】语义分割:论文阅读:(2021-12)Mask2Former
猜你喜欢
Redis connection redis service command
一大波開源小抄來襲
Summary of May training - from a Guang
Research and implementation of hospital management inpatient system based on b/s (attached: source code paper SQL file)
tn-c为何不可用2p断路器?
MapReduce instance (VI): inverted index
Learning SCM is of great help to society
Mapreduce实例(六):倒排索引
【深度学习】语义分割:论文阅读:(2021-12)Mask2Former
听哥一句劝,按这套嵌入式的课程内容和课程体系去学习
随机推荐
Design and implementation of film and television creation forum based on b/s (attached: source code paper SQL file project deployment tutorial)
Mapreduce实例(九):Reduce端join
068. Find the insertion position -- binary search
单片机实现模块化编程:思维+实例+系统教程(实用程度令人发指)
美团二面:为什么 Redis 会有哨兵?
嵌入式开发比单片机要难很多?谈谈单片机和嵌入式开发设计经历
一大波開源小抄來襲
硬件工程师的真实前途我说出来可能你们不信
Can I learn PLC at the age of 33
Une grande vague d'attaques à la source ouverte
[untitled]
Workflow - activiti7 environment setup
Activiti7工作流的使用
零基础学习单片机切记这四点要求,少走弯路
51单片机进修的一些感悟
Yarn organizational structure
Segmentation sémantique de l'apprentissage profond - résumé du code source
基于B/S的网上零食销售系统的设计与实现(附:源码 论文 Sql文件)
A wave of open source notebooks is coming
Why data Tiering