Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #define _CRT_NONSTDC_NO_DEPRECATE
- #include <string>
- #include <vector>
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- using std::string, std::string_view, std::vector;
- struct Config {
- const char *markdownLabel = "markdown";
- const char *codeLabel = "cpp";
- const char *markdownExt = ".md";
- const char *codeExt = ".cpp";
- const char *openCodeBlock = "```";
- const char *closeCodeBlock = "````\n";
- const char *openCommentBlock = "/***";
- const char *closeCommentBlock = "****/\n";
- };
- string readFile(const string &path) {
- string result;
- if (int fileDescriptor; (fileDescriptor = open(path.data(), _O_RDONLY | _O_TEXT)) != -1) {
- if (struct stat fileStat; fstat(fileDescriptor, &fileStat) == 0) {
- result.resize(fileStat.st_size);
- result.resize(read(fileDescriptor, &result[0], (int)result.size()));
- }
- close(fileDescriptor);
- }
- return result;
- }
- bool writeFile(const string &path, const string &text) {
- int fileDescriptor = open(path.data(), O_WRONLY | O_CREAT | O_TRUNC | _O_TEXT, 0640);
- if (fileDescriptor == -1)
- return false;
- int written = write(fileDescriptor, &text[0], (int)text.size());
- int closeResult = close(fileDescriptor);
- return written == text.size() && closeResult != -1;
- }
- string join(const vector<string_view> &spans, const char *openBlock, const char *sourceLanguage, const char *closeBlock) {
- auto joinInto = [](char *dest, const vector<string_view> &spans, const char *openBlock, const char *sourceLanguage, const char *closeBlock) {
- size_t totalSize = 0;
- char *cursor = dest;
- size_t maxSize = dest == nullptr ? 0 : size_t(-1);
- bool comment = true;
- for (auto span : spans) {
- if (dest != nullptr)
- cursor = dest + totalSize;
- if (span.size() > 0) {
- if (comment)
- totalSize += snprintf(cursor, maxSize, "%s %s\n%.*s%s", openBlock, sourceLanguage, (int)span.size(), span.data(), closeBlock);
- else
- totalSize += snprintf(cursor, maxSize, "%.*s", (int)span.size(), span.data());
- }
- comment = !comment;
- }
- return totalSize;
- };
- size_t totalSize = joinInto(nullptr, spans, openBlock, sourceLanguage, closeBlock);
- string result(totalSize, '\0');
- joinInto(&result[0], spans, openBlock, sourceLanguage, closeBlock);
- return result;
- }
- string convert(const string &source,
- const char *destLanguage, const char *sourceLanguage,
- const char *destOpenBlock, const char *destCloseBlock,
- const char *srcOpenBlock, const char *srcCloseBlock) {
- vector<string_view> spans;
- const char *token = srcOpenBlock;
- const string::size_type strlenSrcCloseBlock = strlen(srcCloseBlock);
- const string::size_type sourceSize = source.size();
- for (string::size_type spanStart = 0, spanEnd = 0; spanEnd < sourceSize;) {
- spanEnd = source.find(token, spanStart);
- if (spanEnd == string::npos)
- spanEnd = sourceSize;
- if (token == srcCloseBlock)
- spanStart = source.find('\n', spanStart) + 1;
- string_view span = string_view(&source[spanStart], spanEnd - spanStart);
- spans.push_back(span);
- if (token == srcCloseBlock)
- spanEnd += strlenSrcCloseBlock;
- token = token == srcOpenBlock ? srcCloseBlock : srcOpenBlock;
- spanStart = spanEnd;
- }
- string result = join(spans, destOpenBlock, sourceLanguage, destCloseBlock);
- return result;
- }
- string codeFromMarkdown(const string &markdown, const Config &config) {
- return convert(markdown,
- config.codeLabel, config.markdownLabel,
- config.openCommentBlock, config.closeCommentBlock,
- config.openCodeBlock, config.closeCodeBlock);
- }
- string markdownFromCode(const string &code, const Config &config) {
- return convert(code,
- config.markdownLabel, config.codeLabel,
- config.openCodeBlock, config.closeCodeBlock,
- config.openCommentBlock, config.closeCommentBlock);
- }
- bool endsWith(const string s, const char *x) { return s.rfind(x) == (s.size() - strlen(x)); }
- int main(int argc, char *argv[]) {
- Config config;
- int errors = 0;
- for (int arg = 1; arg < argc; arg++) {
- string srcPath(argv[arg]);
- const char *mdExt = config.markdownExt, *codeExt = config.codeExt;
- const char *srcExt = endsWith(srcPath, mdExt) ? mdExt : codeExt;
- const char *dstExt = srcExt == mdExt ? codeExt : mdExt;
- string srcText = readFile(srcPath.data());
- string dstText = dstExt == mdExt ? markdownFromCode(srcText, config)
- : codeFromMarkdown(srcText, config);
- if (dstText.empty()) {
- errors++;
- fprintf(stderr, "Failed to convert %.*s\n", (int)srcPath.size(), srcPath.data());
- }
- else {
- string dstPath = srcPath.replace(srcPath.rfind(srcExt), strlen(srcExt), dstExt);
- if (!writeFile(dstPath.data(), dstText)) {
- errors++;
- fprintf(stderr, "Failed to write %.*s\n", (int)dstPath.size(), dstPath.data());
- }
- }
- }
- return errors;
- }
Add Comment
Please, Sign In to add comment