void FiltersDialog::on_combobox_filters()
{
  // Clear rules buffer.
  gtk_text_buffer_set_text(rulesbuffer, "", -1);

  // Get the name of the script.
  ustring filter = combobox_get_active_string(combobox_filters);

  // Set the type of the script.
  ScriptType scripttype;
  script_get_path(filter, &scripttype);
  gtk_label_set_text(GTK_LABEL(label_type), script_get_named_type(scripttype).c_str());

  // Set sensitivity of widgets.
  bool editable = true;
  if (filter == scripts_straight_through())
    editable = false;
  gtk_widget_set_sensitive(textview_rules, editable);
  gtk_widget_set_sensitive(button_delete, editable);

  // If not sensitive, bail out.
  if (!editable)
    return;

  // Load the script rules or code.
  ustring filename = script_get_path(filter, NULL);
  gchar *contents;
  g_file_get_contents(filename.c_str(), &contents, NULL, NULL);
  if (contents) {
    gtk_text_buffer_set_text(rulesbuffer, contents, -1);
    g_free(contents);
  }
  gtk_text_buffer_set_modified(rulesbuffer, false);
}
void FiltersDialog::on_button_delete()
{
  ustring filter = combobox_get_active_string(combobox_filters);
  ustring filename = script_get_path(filter, NULL);
  unix_unlink(filename.c_str());
  load_filters("");
}
void FiltersDialog::on_rulesbuffer_changed_execute()
{
  // Bail out if there's no change in the rules buffer.
  if (!gtk_text_buffer_get_modified(rulesbuffer))
    return;

  // Get the name of the script. Bail out if straight throug.
  ustring scriptname = combobox_get_active_string(combobox_filters);
  if (scriptname == scripts_straight_through())
    return;

  // Get the filename and type of the script.
  ScriptType scripttype;
  ustring scriptfile = script_get_path(scriptname, &scripttype);

  // Save the rules to the script file.
  GtkTextIter startiter, enditer;
  gtk_text_buffer_get_start_iter(rulesbuffer, &startiter);
  gtk_text_buffer_get_end_iter(rulesbuffer, &enditer);
  gchar *txt = gtk_text_buffer_get_text(rulesbuffer, &startiter, &enditer, false);
  g_file_set_contents(scriptfile.c_str(), txt, -1, NULL);
  g_free(txt); // Postiff: plug memory leak

  // If it is a TECkit mapping, compile it.
  if (scripttype == stTECkit) {
    compile_errors.clear();
    GwSpawn spawn("teckit_compile");
    spawn.workingdirectory(Directories->get_scripts());
    spawn.arg(scriptfile);
    // To compile UTF-8 source that lacks an encoding signature, the -u flag must be specified on the compiler command line.
    spawn.arg("-u");
    spawn.run();
    if (spawn.exitstatus != 0) {
      ustring tecfile = script_get_path(scriptname, scripttype, true);
      unix_unlink(tecfile.c_str());
      spawn.read();
      spawn.run();
      compile_errors = spawn.standarderr;
    }
  }
}
void FiltersDialog::on_button_new()
{
  // Enter the name of the new script.
  EntryDialog namedialog(_("New script"), _("Enter the name of the new script"), "");
  if (namedialog.run() != GTK_RESPONSE_OK)
    return;

  if (script_available(namedialog.entered_value)) {
    gtkw_dialog_error(filterdialog, _("This one already exists"));
    return;
  }
  // Enter the type of the new script.
  vector < ustring > types;
  for (unsigned int i = 0; i < stEnd; i++)
    types.push_back(script_get_named_type((ScriptType) i));
  RadiobuttonDialog typedialog(_("Script type"), _("Select the type of the script"), types, 0, false);
  if (typedialog.run() != GTK_RESPONSE_OK)
    return;

  // Handle the rest.
  g_file_set_contents(script_get_path(namedialog.entered_value, (ScriptType) typedialog.selection).c_str(), "", -1, NULL);
  load_filters(namedialog.entered_value);
}
Exemple #5
0
ustring script_filter(const ustring & scriptname, bool straightthrough, const ustring & inputfile, const ustring & outputfile)
/*
 Runs the filter "scriptname".
 Input text in "inputfile", and the output text goes in "outputfile".
 If everything is okay, it returns nothing.
 If there were errors, it returns these.
 */
{
  // Remove any previous output.
  unlink(outputfile.c_str());
  unlink(script_temporal_error_file().c_str());

  // Handle straight through.
  if (straightthrough) {
    unix_cp(inputfile, outputfile);
    return "";
  }
  // Get the filename and the type of the script.
  ScriptType scripttype;
  ustring scriptfile = script_get_path(scriptname, &scripttype, true);

  // If the rules file does not exist, or the script is of an unknown type, pass it straight through.
  if (!g_file_test(scriptfile.c_str(), G_FILE_TEST_IS_REGULAR) || (scripttype == stEnd)) {
    unix_cp(inputfile, outputfile);
    gw_warning(_("Error in script ") + scriptname);
    return "";
  }
  // Encode the input usfm file.
  ustring encodedinputfile = script_temporal_input_file();
  if (inputfile != encodedinputfile) {
    unix_cp(inputfile, encodedinputfile);
  }
  script_encode_usfm_file(encodedinputfile);

  // Run filter.
  ustring command;
  ustring error;
  switch (scripttype) {
  case stSed:
    {
      command.append(script_sed_binary());
      command.append(" -f");
      command.append(shell_quote_space(scriptfile));
      command.append("<");
      command.append(shell_quote_space(encodedinputfile));
      command.append(">");
      command.append(shell_quote_space(outputfile));
      break;
    }
  case stTECkit:
    {
      command.append(script_teckit_txtconverter());
      command.append(" -i");
      command.append(shell_quote_space(encodedinputfile));
      command.append(" -o");
      command.append(shell_quote_space(outputfile));
      command.append(" -t");
      command.append(shell_quote_space(scriptfile));
      command.append(" -nobom");
      break;
    }
  case stFree:
    {
      // Text of the script.
      ustring scriptdata;
      {
        // Read script.
        gchar *contents;
        g_file_get_contents(scriptfile.c_str(), &contents, NULL, NULL);
        if (contents) {
          scriptdata = contents;
          g_free(contents);
        } else {
          error = _("Can't read script file");
          gw_warning(error);
          return error;
        }
      }
      // Check for and insert the input filename.
      if (scriptdata.find(script_free_input_identifier()) == string::npos) {
        error = _("Can't find where to put input file");
        gw_warning(error);
        return error;
      }
      replace_text(scriptdata, script_free_input_identifier(), shell_quote_space(encodedinputfile));
      // Check for and insert the output filename.
      if (scriptdata.find(script_free_output_identifier()) == string::npos) {
        error = _("Can't find where to put output file");
        gw_warning(error);
        return error;
      }
      replace_text(scriptdata, script_free_output_identifier(), shell_quote_space(outputfile));
      // Write temporal script.
      g_file_set_contents(script_temporal_script_file().c_str(), scriptdata.c_str(), -1, NULL);
      // Assemble command to run.
      command.append("sh");
      command.append(shell_quote_space(script_temporal_script_file()));
      break;
    }
  case stEnd:
    {
      break;
    }
  }

  // Add the error file to the command, and run it.
  command.append(" 2> ");
  command.append(script_temporal_error_file());
  int result = system(command.c_str()); // This one is too unpredictable to be used with GwSpawn.

  // The filters are so much beyond any control that we never can be sure that 
  // their output is in the UTF-8 encoding.
  // Sed would give UTF-8, but as TECkit can also give legacy encodings.
  // We can't know what free scripts will do, it could be anything.
  // So here check the UTF-8 encoding. 
  // If UTF-8 validation fails, we copy the input straight to the output.
  {
    gchar *contents;
    g_file_get_contents(outputfile.c_str(), &contents, NULL, NULL);
    if (contents) {
      if (!g_utf8_validate(contents, -1, NULL)) {
        unix_cp(inputfile, outputfile);
        error = _("UTF-8 validation failure");
        gw_warning(error);
      }
      g_free(contents);
      if (!error.empty())
        return error;
    }
  }

  // Decode the output file.
  script_decode_usfm_file(outputfile);

  // Handle OK.
  if (result == 0)
    return "";

  // Handle error.
  gchar *contents;
  g_file_get_contents(script_temporal_error_file().c_str(), &contents, NULL, NULL);
  if (contents) {
    error = contents;
    g_free(contents);
    gw_warning(error);
  }
  return error;
}