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) cmake_minimum_required (VERSION 3.2)
project(remwharead project(remwharead
VERSION 0.0.1 VERSION 0.0.2
LANGUAGES CXX LANGUAGES CXX
) )

View File

@ -1,8 +1,7 @@
= remwharead = remwharead
[NOTE] [NOTE]
This program is not usable at the moment. Most of the described functions are Some of the described functions are not yet available.
not yet available.
*remwharead* saves URLs of things you read in a database along with an URL to *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 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 implementation follows RFC 4180 and the full MIME media type is
`text/csv;charset=utf-8;header=present`. `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 == FILES
* *Database*: `${XDG_DATA_HOME}/remwharead/database.sqlite` * *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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream>
#include <regex> #include <regex>
#include "time.hpp" #include "time.hpp"
#include "csv.hpp" #include "export.hpp"
using std::cerr; using std::cerr;
using std::endl; using std::endl;

View File

@ -14,8 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef REMWHAREAD_CSV_HPP #ifndef REMWHAREAD_EXPORT_HPP
#define REMWHAREAD_CSV_HPP #define REMWHAREAD_EXPORT_HPP
#include <vector> #include <vector>
#include <iostream> #include <iostream>
@ -26,6 +26,11 @@ using std::ostream;
using std::cout; using std::cout;
void export_csv(const vector<Database::entry> &entries, ostream &out = cout); void export_csv(const vector<Database::entry> &entries, ostream &out = cout);
//! replaces " with "".
const string quote_csv(const string &field); 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 <iostream>
#include <string> #include <string>
#include <chrono> #include <chrono>
#include <fstream>
#include <memory>
#include "sqlite.hpp" #include "sqlite.hpp"
#include "parse_options.hpp" #include "parse_options.hpp"
#include "csv.hpp"
#include "uri.hpp" #include "uri.hpp"
#include "export.hpp"
using std::cout; using std::cout;
using std::cerr; using std::cerr;
@ -52,16 +54,42 @@ int main(const int argc, const char *argv[])
page.title, page.description, page.fulltext}); 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) switch (opts.format)
{ {
case export_format::csv: 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; break;
} }
case export_format::asciidoc: 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; break;
} }
default: default:

View File

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