Perl OpenOffice::OODoc Modifying header/footer style text - perl

I am trying to figure out how to change text in a footer of an ODT file. The footer is kept in the styles.xml, however I can't seem to access it using selectElementsByContent or any other method:
my $a = odfContainer('test.odt');
my $styles = odfDocument(container => $a, part => 'styles');
foreach my $element ($styles->selectElementsByContent('mytest'))
{
#never runs...
}
The styles.xml in the odt is like:
<office:document-styles>
<office:master-styles>
<style:master-page>
<style:footer>
<text:p test:style-name="P49">
mytest
</text:p>
</style:footer>
</style:master-page>
</office:master-styles>
</office:document-styles>
What is the right way to change the text:p contents?

I ended up having to use odfXPath to loop through:
my $ss = odfXPath(file => 'myfile.odt' , part => 'styles');
my $p =0;
while (my $p = $ss->getElement('//text:p',$p))
{
if ($ss->getText($para) eq 'mytest') { $ss->setText($p,'foobar');}
$p++;
}
$ss->save('mynewfile.odt');

Related

ExifTool Perl Library Module: How to separate keyword- from subject-values

I am using ExifToolVersion : 9.13 to read out metainformations of a pdf-file to formfields, where users can edit the values.
With a second perl-script I write these changed values back to the file.
That works fine with the exception, that subject-values appear in keyword-tags and keyword-values in subject-tags, although I write the new values explizite to each tag.
$exifTool->SetNewValue($tag[$i], \#keywords, Replace => 1);
$exifTool->SetNewValue($tag[$i], $file_beschreibung, Replace => 1);
$exifTool->SetNewValue($data[$i]=>\#keywords, Group0 => 'PDF');
$exifTool->SetNewValue($data[$i]=>$file_beschreibung, Group0 => 'PDF');
I tried to write an empty value to the XMP tags, but that doesn't work
$exifTool->SetNewValue($data[$i]=>$leer, Group0 => 'XMP');
Is there a way to to avoid the concatenation of both values?
I now found, that I have to clear all XMP-Tags
my #data = ("Author","Keywords","ModifyDate","Rights","Title","Subject");
my $elemente = #data;
for ($i=0; $i<$elemente; $i++)
{
if ($i==1)
{
if (my $tagname =~ m/^XMP-.*:$data[$i]/)
{
$exifTool->SetNewValue($tagname=>'', Group => 'XMP');
}
$exifTool->SetNewValue($data[$i]=>\#keywords, Group => 'PDF');
}
if ($i==5)
{
my $tagname = "XMP-dc:".$data[$i];
$exifTool->SetNewValue($tagname=>'', Group => 'XMP');
$exifTool->SetNewValue($data[$i]=>$file_beschreibung, Group => 'PDF');
}
}
This works fine. Thank you for helping!

How to display uploaded csv file into tablular format in drupal 7

I have created a form in drupal 7 and it has a field to upload file (csv file only ) now how to display uploaded csv file into table on form submit ?
Not sure about theme function, but you can do it on your own.
I.e. use:
http://php.net/manual/en/function.file-get-contents.php
To read the file and then:
http://php.net/manual/en/function.str-getcsv.php
to parse CSV.
Or, maybe:
http://php.net/manual/en/function.fgetcsv.php
to read row by row. Anyway, you'll end up with looping trough rows so just print values the way you want, add markup around the values...
After go through various code exercises i have come up with solution which is as follows :
`function display_table($filename, $head=false) {
$handle = fopen($filename, "r");
$all_rows = array();
$header = null;
while ($row = fgetcsv($handle)) {
if ($header === null) {
$header = $row;
continue;
}
$all_rows[] = array_combine($header, $row);
}
$table = theme('table', array('header' => $header, 'rows' => $all_rows));
return $table;
}`
Hope it would be helpful to others as well !

inserting new line with OpenOffice::OODoc

I am having quite the issue creating a new line with this module and feel like I am just missing something.
my perl code looks like this:
use OpenOffice::OODoc;
my $name = "foo <br> bar";
$name=~s/<br>/\n/g;
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
...
Problem is when I open it in word or open office I have no newlines. Although if it open it in a text edit I have my new lines.. Any ideas of how to fix this?
Ok I figured it out, hopefully this will save someone hours of searching for the same thing. I added:
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
$doc->substituteText($p,'<br>', $linebreak);
So my final code looks like this:
use OpenOffice::OODoc;
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
my $outdir = "template.odt";
my $name = "foo <br> bar";
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
$doc->substituteText($p,'<br>', $linebreak);
...
Maybe not the best way to do things but it worked!
You could try and insert and empty para after the current one:
If the 'text' option is empty, calling this method is the equivalent
of adding a line feed.
This sequence (in a text document) inserts a linefeed immediately after paragraph 4. Replace 4 with current position.
$doc->insertElement
(
'//text:p', 4, 'text:p',
position => 'after',
text => '',
);

Write config in Zend Framework with APPLICATION_PATH

For an application I'd like to create some kind of setup-steps. In one of the steps the database configuration is written to the application.ini file. This all works, but something very strange happens: All the paths to the directories (library, layout, ...) are changed from paths with APPLICATION_PATH . to full paths. As you can imagine, this isn't very systemfriendly. Any idea how I can prevent that?
I update the application.ini with this code:
# read existing configuration
$config = new Zend_Config_Ini(
$location,
null,
array('skipExtends' => true,
'allowModifications' => true));
# add new values
$config->production->doctrine->connection = array();
$config->production->doctrine->connection->host = $data['server'];
$config->production->doctrine->connection->user = $data['username'];
$config->production->doctrine->connection->password = $data['password'];
$config->production->doctrine->connection->database = $data['database'];
# write new configuration
$writer = new Zend_Config_Writer_Ini(
array(
'config' => $config,
'filename' => $location));
$writer->write();
Since Zend_Config_Ini uses the default ini scanning mode (INI_SCANNER_NORMAL), it will parse all options and replace constants with their respective values. What you could do, is call parse_ini_file directly, using the INI_SCANNER_RAW mode, so the options aren't parsed.
ie. use
$config = parse_ini_file('/path/to/your.ini', TRUE, INI_SCANNER_RAW);
You will get an associative array that you can manipulate as you see fit, and afterwards you can write that back with the following snippet (from the comments):
function write_ini_file($assoc_arr, $path, $has_sections=FALSE) {
$content = "";
if ($has_sections) {
foreach ($assoc_arr as $key=>$elem) {
$content .= "[".$key."]\n";
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = ".$elem2[$i]."\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem2."\n";
}
}
}
else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key2."[] = ".$elem[$i]."\n";
}
}
else if($elem=="") $content .= $key2." = \n";
else $content .= $key2." = ".$elem."\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
if (!fwrite($handle, $content)) {
return false;
}
fclose($handle);
return true;
}
ie. call it with :
write_ini_file($config, '/path/to/your.ini', TRUE);
after manipulating the $config array. Just make sure you add double quotes to the option values where needed...
Or alternatively - instead of using that function - you could try writing it back using Zend_Config_Writer_Ini, after converting the array back to a Zend_Config object, I guess that should work as well...
I'm guess you could iterate over the values, checking for a match between the value of APPLICATION_PATH, and replacing it with string literal APPLICATION_PATH.
That is if you know that APPLICATION_PATH contains the string '/home/david/apps/myapp/application' and you find a config value '/home/david/apps/myapp/application/views/helpers', then you do some kind of replacement of the leading string '/home/david/apps/myapp/application' with the string 'APPLICATION_PATH', ending up with 'APPLICATION_PATH "/views/helpers"'.
Kind of a kludge, but something like that might work.
This is a long shot - but have you tried running your Zend_Config_Writer_Ini code while the APPLICATION_PATH constant is not defined? It should interpret it as the literal string 'APPLICATION_PATH' and could possibly work.

Cannot print on multiple pages using PDF::API2

I have been tinkering around with PDF::API2 and i am facing a problem, create a pdf file very well and add text into it. However say if the text to be written flows over to more than one page, the script does not print over to the next page. I have tried researching for an answer to this but to no avail. I would like each page to have exactly 50 lines of text. My script is as below. It only prints on the first page, creates the other pages but does not print into them. Anyone with a solution
!/usr/bin/perl
use PDF::API2;
use POSIX qw(setsid strftime);
my $filename = scalar(strftime('%F', localtime));
my $pdf = PDF::API2->new(-file => "$filename.pdf");
$pdf->mediabox(595,842);
my $page = $pdf->page;
my $fnt = $pdf->corefont('Arial',-encoding => 'latin1');
my $txt = $page->text;
$txt->textstart;
$txt->font($fnt, 20);
$txt->translate(100,800);
$txt->text("Lines for $filename");
my $i=0;
my $line = 780;
while($i<310)
{
if(($i%50) == 0)
{
my $page = $pdf->page;
my $fnt = $pdf->corefont('Arial',-encoding => 'latin1');
my $txt = $page->text;
}
$txt->font($fnt, 10);
$txt->translate(100,$line);
$txt->text("$i This is the first line");
$line=$line-15;
$i++;
}
$txt->textend;
$pdf->save;
$pdf->end( );
The problem is that you are making new page, but forget new variables instantly:
if(($i%50) == 0)
{
my $page = $pdf->page;
my $fnt = $pdf->corefont('Arial',-encoding => 'latin1');
my $txt = $page->text;
}
All my variables you make disappear on closing parentheses. Just remove my and you will modify variables from top-level scope.
Edit: You also probably want to reset $line variable when making new page.
The typeface, $fnt, does not have to be changed since it depends on the PDF, $pdf, and not the page, $page.
As much as I love Perl, I learned enough Python to use the ReportLabs library for PDF generation. Creating PDF is one of the weak spots of Perl v. Python.