Added AsciiDoc support.

This commit is contained in:
tastytea 2019-05-16 08:37:50 +02:00
parent 914d22569f
commit a3259626ff
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
8 changed files with 183 additions and 12 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.2)
project(remwharead
VERSION 0.0.1
VERSION 0.0.2
LANGUAGES CXX
)

View File

@ -1,8 +1,7 @@
= remwharead
[NOTE]
This program is not usable at the moment. Most of the described functions are
not yet available.
Some of the described functions are not yet available.
*remwharead* saves URLs of things you read in a database along with an URL to
the archived version, the current date and time, title, description, the full

View File

@ -66,6 +66,11 @@ commas. Line breaks in the full text are converted to "\n". Our CSV
implementation follows RFC 4180 and the full MIME media type is
`text/csv;charset=utf-8;header=present`.
=== AsciiDoc
AsciiDoc is a markup language that can be read as plain text or converted to
HTML, PDF and many other formats.
== FILES
* *Database*: `${XDG_DATA_HOME}/remwharead/database.sqlite`

135
src/adoc.cpp Normal file
View File

@ -0,0 +1,135 @@
/* This file is part of remwharead.
* Copyright © 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <map>
#include <regex>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <curlpp/cURLpp.hpp>
#include "version.hpp"
#include "time.hpp"
#include "export.hpp"
using std::cerr;
using std::endl;
using std::uint64_t;
using std::regex;
using std::regex_replace;
using std::pair;
void export_adoc(const vector<Database::entry> &entries, ostream &out)
{
try
{
out << "= Visited things\n"
<< ":Author: remwharead " << global::version << endl
<< ":Date: " << timepoint_to_string(system_clock::now()) << endl
<< ":toc: right" << endl
// << ":toc-title:" << endl
<< endl;
std::map<string,uint64_t> alltags;
string day;
for (const Database::entry &entry : entries)
{
const string datetime = timepoint_to_string(entry.datetime);
const string newday = datetime.substr(0, datetime.find('T'));
const string time = datetime.substr(datetime.find('T') + 1);
if (newday != day)
{
day = newday;
out << "== " << day << endl << endl;
}
out << ".link:" << entry.uri;
if (!entry.title.empty())
{
out << '[' << entry.title << ']';
}
else
{
out << "[]";
}
out << endl;
out << '_' << time << '_';
for (const string &tag : entry.tags)
{
if (tag.empty())
{
continue;
}
auto globaltag = alltags.find(tag);
if (globaltag != alltags.end())
{
++(globaltag->second);
}
else
{
alltags.insert({ tag, 1 });
}
out << " xref:" << replace_spaces(tag) << '[' << tag << ']';
if (tag != *(entry.tags.rbegin()))
{
out << ',';
}
}
out << endl;
if (!entry.archive_uri.empty())
{
out << " (" << entry.archive_uri << "[archived version])\n";
}
out << endl;
if (!entry.description.empty())
{
out << entry.description << endl << endl;
}
}
if (!alltags.empty())
{
out << "== Tags\n\n";
vector<pair<string,uint64_t>> sortedtags(alltags.size());
std::move(alltags.begin(), alltags.end(), sortedtags.begin());
std::sort(sortedtags.begin(), sortedtags.end(),
[](const pair<string,uint64_t> &a, pair<string,uint64_t> &b)
{
return a.second > b.second;
});
for (const auto &tag : sortedtags)
{
out << "[[" << replace_spaces(tag.first) << "]]" << tag.first
<< "(" << tag.second << ")";
if (tag != *(sortedtags.rbegin()))
{
out << ", ";
}
}
out << endl;
}
}
catch (std::exception &e)
{
cerr << "Error in " << __func__ << ": " << e.what() << endl;
}
}
const string replace_spaces(const string &text)
{
return regex_replace(text, regex(" "), "-");
}

View File

@ -14,10 +14,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <regex>
#include "time.hpp"
#include "csv.hpp"
#include "export.hpp"
using std::cerr;
using std::endl;

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REMWHAREAD_CSV_HPP
#define REMWHAREAD_CSV_HPP
#ifndef REMWHAREAD_EXPORT_HPP
#define REMWHAREAD_EXPORT_HPP
#include <vector>
#include <iostream>
@ -26,6 +26,11 @@ using std::ostream;
using std::cout;
void export_csv(const vector<Database::entry> &entries, ostream &out = cout);
//! replaces " with "".
const string quote_csv(const string &field);
#endif // REMWHAREAD_CSV_HPP
void export_adoc(const vector<Database::entry> &entries, ostream &out = cout);
//! Replaces spaces with -.
const string replace_spaces(const string &text);
#endif // REMWHAREAD_EXPORT_HPP

View File

@ -17,10 +17,12 @@
#include <iostream>
#include <string>
#include <chrono>
#include <fstream>
#include <memory>
#include "sqlite.hpp"
#include "parse_options.hpp"
#include "csv.hpp"
#include "uri.hpp"
#include "export.hpp"
using std::cout;
using std::cerr;
@ -52,16 +54,42 @@ int main(const int argc, const char *argv[])
page.title, page.description, page.fulltext});
}
std::ofstream file;
if (!opts.file.empty())
{
file.open(opts.file);
if (!file.good())
{
cerr << "Error: Could not open file: " << opts.file << endl;
return 3;
}
}
switch (opts.format)
{
case export_format::csv:
{
export_csv(db.retrieve(opts.span[0], opts.span[1]));
if (file.is_open())
{
export_csv(db.retrieve(opts.span[0], opts.span[1]), file);
file.close();
}
else
{
export_csv(db.retrieve(opts.span[0], opts.span[1]));
}
break;
}
case export_format::asciidoc:
{
cerr << "Error: AsciiDoc is not yet supported.\n";
if (file.is_open())
{
export_adoc(db.retrieve(opts.span[0], opts.span[1]), file);
file.close();
}
else
{
export_adoc(db.retrieve(opts.span[0], opts.span[1]));
}
break;
}
default:

View File

@ -99,7 +99,7 @@ const options parse_options(const int argc, const char *argv[])
{
opts.format = export_format::csv;
}
else if (format == "asciidoc")
else if (format == "asciidoc" || format == "adoc")
{
opts.format = export_format::asciidoc;
}