当前位置:网站首页>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;
}
边栏推荐
- Design and implementation of film and television creation forum based on b/s (attached: source code paper SQL file project deployment tutorial)
- Selection of software load balancing and hardware load balancing
- 发生OOM了,你知道是什么原因吗,又该怎么解决呢?
- max-flow min-cut
- Summary of May training - from a Guang
- Mapreduce实例(九):Reduce端join
- Popularization of security knowledge - twelve moves to protect mobile phones from network attacks
- Scoped in webrtc_ refptr
- Design and implementation of online shopping system based on Web (attached: source code paper SQL file)
- One article read, DDD landing database design practice
猜你喜欢
MapReduce instance (V): secondary sorting
51单片机进修的一些感悟
《ASP.NET Core 6框架揭秘》样章发布[200页/5章]
Mapreduce实例(九):Reduce端join
运维,放过监控-也放过自己吧
Redis distributed lock implementation redison 15 questions
[deep learning] semantic segmentation: thesis reading (neurips 2021) maskformer: per pixel classification is not all you need
How can I take a shortcut to learn C language in college
MapReduce instance (IV): natural sorting
Une grande vague d'attaques à la source ouverte
随机推荐
O & M, let go of monitoring - let go of yourself
软件负载均衡和硬件负载均衡的选择
六月刷题01——数组
Mapreduce实例(九):Reduce端join
美团二面:为什么 Redis 会有哨兵?
Global and Chinese market for annunciator panels 2022-2028: Research Report on technology, participants, trends, market size and share
Global and Chinese market of bank smart cards 2022-2028: Research Report on technology, participants, trends, market size and share
Listen to my advice and learn according to this embedded curriculum content and curriculum system
MySQL数据库优化的几种方式(笔面试必问)
June brush question 01 - array
018. Valid palindromes
Redis distributed lock implementation redison 15 questions
为什么要数据分层
[deep learning] semantic segmentation - source code summary
May brush question 03 - sorting
Global and Chinese market of linear regulators 2022-2028: Research Report on technology, participants, trends, market size and share
If a university wants to choose to study automation, what books can it read in advance?
max-flow min-cut
Release of the sample chapter of "uncover the secrets of asp.net core 6 framework" [200 pages /5 chapters]
【深度学习】语义分割-源代码汇总