Added AsciiDoc support.
This commit is contained in:
parent
914d22569f
commit
a3259626ff
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required (VERSION 3.2)
|
||||
project(remwharead
|
||||
VERSION 0.0.1
|
||||
VERSION 0.0.2
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
135
src/adoc.cpp
Normal 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(" "), "-");
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
32
src/main.cpp
32
src/main.cpp
|
@ -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:
|
||||
{
|
||||
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user