tabfile: make it possible to set metadata

And some related clean-up.
This commit is contained in:
Přemysl Eric Janouch 2021-10-07 16:26:57 +02:00
parent ed8b1bcdad
commit 20fcf2a0c7
Signed by: p
GPG Key ID: A0420B94F92B9493
6 changed files with 85 additions and 56 deletions

View File

@ -5,4 +5,8 @@
curl -Lo- https://slovnik-cizich-slov.abz.cz/export.php | \ curl -Lo- https://slovnik-cizich-slov.abz.cz/export.php | \
iconv -f latin2 -t UTF-8 | perl -CSD -F\\\| -le ' iconv -f latin2 -t UTF-8 | perl -CSD -F\\\| -le '
print "$_\t" . $F[2] =~ s/\\/\\\\/gr =~ s/; /\\n/gr for split(", ", $F[0]) print "$_\t" . $F[2] =~ s/\\/\\\\/gr =~ s/; /\\n/gr for split(", ", $F[0])
' | sort -u | tabfile slovnik-cizich-slov ' | sort -u | tabfile slovnik-cizich-slov \
--book-name="Slovník cizích slov" \
--website=https://slovnik-cizich-slov.abz.cz \
--date="$(date +%F)" \
--collation=cs_CZ

View File

@ -250,30 +250,6 @@ worker (WorkerData *data)
// --- Main -------------------------------------------------------------------- // --- Main --------------------------------------------------------------------
/// Copy the contents of one StardictInfo object into another. Ignores path.
static void
stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
{
dest->version = src->version;
guint i;
for (i = 0; i < _stardict_ifo_keys_length; i++)
{
const struct stardict_ifo_key *key = &_stardict_ifo_keys[i];
if (key->type == IFO_STRING)
{
gchar **p = &G_STRUCT_MEMBER (gchar *, dest, key->offset);
gchar *q = G_STRUCT_MEMBER (gchar *, src, key->offset);
g_free (*p);
*p = q ? g_strdup (q) : NULL;
}
else
G_STRUCT_MEMBER (gulong, dest, key->offset) =
G_STRUCT_MEMBER (gulong, src, key->offset);
}
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {

View File

@ -79,4 +79,6 @@ extern const struct stardict_ifo_key _stardict_ifo_keys[];
/// Denotes the length of _stardict_ifo_keys. /// Denotes the length of _stardict_ifo_keys.
extern gsize _stardict_ifo_keys_length; extern gsize _stardict_ifo_keys_length;
void stardict_info_copy (StardictInfo *dest, const StardictInfo *src);
#endif // ! STARDICTPRIVATE_H #endif // ! STARDICTPRIVATE_H

View File

@ -209,6 +209,30 @@ const struct stardict_ifo_key _stardict_ifo_keys[] =
gsize _stardict_ifo_keys_length = G_N_ELEMENTS (_stardict_ifo_keys); gsize _stardict_ifo_keys_length = G_N_ELEMENTS (_stardict_ifo_keys);
/// Copy the contents of one StardictInfo object into another. Ignores path.
void
stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
{
dest->version = src->version;
guint i;
for (i = 0; i < _stardict_ifo_keys_length; i++)
{
const struct stardict_ifo_key *key = &_stardict_ifo_keys[i];
if (key->type == IFO_STRING)
{
gchar **p = &G_STRUCT_MEMBER (gchar *, dest, key->offset);
gchar *q = G_STRUCT_MEMBER (gchar *, src, key->offset);
g_free (*p);
*p = q ? g_strdup (q) : NULL;
}
else
G_STRUCT_MEMBER (gulong, dest, key->offset) =
G_STRUCT_MEMBER (gulong, src, key->offset);
}
}
static gboolean static gboolean
load_ifo (StardictInfo *sti, const gchar *path, GError **error) load_ifo (StardictInfo *sti, const gchar *path, GError **error)
{ {

View File

@ -25,11 +25,15 @@
#include <glib.h> #include <glib.h>
#include <gio/gio.h> #include <gio/gio.h>
#include <unicode/ucol.h>
#include "config.h"
#include "stardict.h" #include "stardict.h"
#include "stardict-private.h" #include "stardict-private.h"
#include "generator.h" #include "generator.h"
#include "utils.h" #include "utils.h"
static gboolean static gboolean
set_data_error (GError **error, const gchar *message) set_data_error (GError **error, const gchar *message)
{ {
@ -119,6 +123,17 @@ transform (FILE *fsorted, Generator *generator, GError **error)
return TRUE; return TRUE;
} }
static void
validate_collation_locale (const gchar *locale)
{
UErrorCode error = U_ZERO_ERROR;
UCollator *collator = ucol_open (locale, &error);
if (!collator)
fatal ("failed to create a collator for %s: %s\n",
locale, u_errorName (error));
ucol_close (collator);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -129,13 +144,50 @@ main (int argc, char *argv[])
GOptionContext *ctx = g_option_context_new ("output-basename < input"); GOptionContext *ctx = g_option_context_new ("output-basename < input");
g_option_context_set_summary (ctx, g_option_context_set_summary (ctx,
"Create a StarDict dictionary from plaintext."); "Create a StarDict dictionary from plaintext.");
StardictInfo template =
{
.same_type_sequence = "m",
};
GOptionEntry entries[] =
{
{ "book-name", 'b', 0, G_OPTION_ARG_STRING, &template.book_name,
"Set the book name field", "TEXT" },
{ "author", 'a', 0, G_OPTION_ARG_STRING, &template.author,
"Set the author field ", "NAME" },
{ "e-mail", 'e', 0, G_OPTION_ARG_STRING, &template.email,
"Set the e-mail field", "ADDRESS" },
{ "website", 'w', 0, G_OPTION_ARG_STRING, &template.website,
"Set the website field", "LINK" },
{ "description", 'd', 0, G_OPTION_ARG_STRING, &template.description,
"Set the description field (newlines supported)", "TEXT" },
{ "date", 'D', 0, G_OPTION_ARG_STRING, &template.date,
"Set the date field", "DATE" },
{ "collation", 'c', 0, G_OPTION_ARG_STRING, &template.collation,
"Set the collation field (for ICU)", "LOCALE" },
{ }
};
g_option_context_add_main_entries (ctx, entries, GETTEXT_PACKAGE);
if (!g_option_context_parse (ctx, &argc, &argv, &error)) if (!g_option_context_parse (ctx, &argc, &argv, &error))
fatal ("Error: option parsing failed: %s\n", error->message); fatal ("Error: option parsing failed: %s\n", error->message);
if (argc != 2) if (argc != 2)
fatal ("%s", g_option_context_get_help (ctx, TRUE, FALSE)); fatal ("%s", g_option_context_get_help (ctx, TRUE, FALSE));
g_option_context_free (ctx); g_option_context_free (ctx);
if (!template.book_name)
template.book_name = argv[1];
if (template.description)
{
gchar **lines = g_strsplit (template.description, "\n", -1);
g_free (template.description);
gchar *in_one_line = g_strjoinv ("<br>", lines);
g_strfreev (lines);
template.description = in_one_line;
}
if (template.collation)
validate_collation_locale (template.collation);
// This actually implements stardict_strcmp(), POSIX-compatibly. // This actually implements stardict_strcmp(), POSIX-compatibly.
// Your sort(1) is not expected to be stable by default, like bsdsort is. // Your sort(1) is not expected to be stable by default, like bsdsort is.
FILE *fsorted = popen ("LC_ALL=C sort -t'\t' -k1f,1", "r"); FILE *fsorted = popen ("LC_ALL=C sort -t'\t' -k1f,1", "r");
@ -149,11 +201,7 @@ main (int argc, char *argv[])
StardictInfo *info = generator->info; StardictInfo *info = generator->info;
info->version = SD_VERSION_3_0_0; info->version = SD_VERSION_3_0_0;
info->book_name = g_strdup (argv[1]); stardict_info_copy (info, &template);
info->same_type_sequence = g_strdup ("m");
// This gets incremented each time an entry is finished
info->word_count = 0;
if (!transform (fsorted, generator, &error) if (!transform (fsorted, generator, &error)
|| !generator_finish (generator, &error)) || !generator_finish (generator, &error))

View File

@ -140,31 +140,6 @@ update_from_filter (StardictDict *dict, Generator *generator,
return TRUE; return TRUE;
} }
// FIXME: copied from add-pronunciation.c, should merge it somewhere (utils?)
/// Copy the contents of one StardictInfo object into another. Ignores path.
static void
stardict_info_copy (StardictInfo *dest, const StardictInfo *src)
{
dest->version = src->version;
guint i;
for (i = 0; i < _stardict_ifo_keys_length; i++)
{
const struct stardict_ifo_key *key = &_stardict_ifo_keys[i];
if (key->type == IFO_STRING)
{
gchar **p = &G_STRUCT_MEMBER (gchar *, dest, key->offset);
gchar *q = G_STRUCT_MEMBER (gchar *, src, key->offset);
g_free (*p);
*p = q ? g_strdup (q) : NULL;
}
else
G_STRUCT_MEMBER (gulong, dest, key->offset) =
G_STRUCT_MEMBER (gulong, src, key->offset);
}
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {