Does Qt Linguist offer the ability to add new entries to the editable .ts file? - c++

I didn't find a way to do this - only to edit the translations to the existing fields.
If there is no way to achieve this - how should this be done (somehow automatically, because right now I was manually adding
<message>
<source>x</source>
<translation>xx</translation>
</message>
blocks to my .ts file and I assume that's not the correct way.

No, that's not the correct way :) Use tr() in the code to mark strings for translation.
For example
label->setText( tr("Error") );
The you run lupdate for your project to extract them to a .ts. See here for more details.
Or do you need to translate strings that are not in the source code?

I just wrote a python script to insert new entries
into the .ts file for a homegrown parser using ElementTree. It doesnt make the code pretty
when it adds it, but I believe it works just fine (so far):
from xml.etree import ElementTree as ET
tree = ET.parse(infile)
doc = tree.getroot()
for e in tree.getiterator()
if e.tag == "context":
for child in e.getchildren():
if child.tag == "name" and child.text == target:
elem = ET.SubElement(e, "message")
src = ET.SubElement(elem, "source")
src.text = newtext
trans = ET.SubElement(elem, "translation")
trans.text = "THE_TRANSLATION"
tree.write(outfile)
Where infile is the .ts file, outfile may be the same as infile or different.
target is the context you are looking for to add a new message into,
and newtext is of course the new source text.

Related

Why is libxml not storing html in my htmlDocPtr?

I am working on a piece of software that uses libxml to store xml on webpages in an xmlDocPtr. I need to expand this functionality to do the same for html.
The original code:
xmlDocPtr doc = xmlParseEntity(filename.c_str());
Where filename = 10.1.1.135/poll_data.xml and everything works just fine
Now, I have html filename = 10.1.1.165/index.htm and would like to store this as well. I have tried using htmlParseDoc with no success.
htmlDocPtr doc = htmlParseFile(filename.c_str(), "windows-1252");
The resulting doc object is not null but it does not contain the contents of the index.html
Netbeans spits out:
http://10.1.1.165/index.htm:1: HTML parser error : Document is empty
Any suggestions?

Python: Is there a way I can add a footnote to word document?

I have tried the following with python-docx:
section = self.document.sections[0]
footer = section._sectPr.footer
footer.text = "I am here"
I couldn't find a clear footer/header directions in docx documentations. Is there a work around to cover this gap?
The work around is:
Create a document with python-docx.
Change the name to 'init.docx'
Comment any adding-new-style code
Open 'init.docx'
Delete everything
Save it.
Add footnote/Headers to 'init.docx'
Change self.document = Document('') to self.document = Document('init.docx').

How to replace text in content control after, XML binding using docx4j

I am using docx4j 2.8.1 with Content Controls in my .docx file. I can replace the CustomXML part by injecting my own XML and then calling BindingHandler.applyBindings after supplying the input XML. I can add a token in my XML such as ¶ then I would like to replace that token in the MainDocumentPart, but using that approach, when I iterate through the content in the MainDocumentPart with this (link) method none of my text from my XML is even in the collection extracted from the MainDocumentPart. I am thinking that even after binding the XML, it remains separate from the MainDocumentPart (??)
I haven't tried this with anything more than a little test doc yet. My token is the Pilcrow: ¶. Since it's a single character, it won't be split in separate runs. My code is:
private void injectXml (WordprocessingMLPackage wordMLPackage) throws JAXBException {
MainDocumentPart part = wordMLPackage.getMainDocumentPart();
String xml = XmlUtils.marshaltoString(part.getJaxbElement(), true);
xml = xml.replaceAll("¶", "</w:t><w:br/><w:t>");
Object obj = XmlUtils.unmarshalString(xml);
part.setJaxbElement((Document) obj);
}
The pilcrow character comes from the XML and is injected by applying the XML bindings to the content controls. The problem is that the content from the XML does not seem to be in the MainDocumentPart so the replace doesn't work.
(Using docx4j 2.8.1)

Rename language after item is created

I'm using sitecore 6.5 with two languages installed, en (default) and fr-CA. There are items in the tree with content in both en and fr-CA.
The problem is that the French url has 'fr-CA' in it and we want that to be 'fr', for example:
http://website.com/fr/page.aspx instead of http://website.com/fr-CA/page.aspx
I tried renaming the language from 'fr-CA' to 'fr' and that fixed the url but the content still points to the old language 'fr-CA', so the item shows three languages: en, fr and fr-CA. It's not recognizing the name change.
Any suggestions are much appreciated.
Thanks,
Tarek
The problem is you have created fr-CA versions of your items which cannot be fixed by renaming the language .. you can now make a fr version but, like you are seeing, this means there are now 3 possible versions.
One suggestion is to leave the languages in Sitecore alone and alter how links are served and processed instead.
You would probably need to look at adding your own method into the httpRequestBegin pipeline in Sitecore. This would follow the LanguageResolver entry. You can then parse the RawUrl and set Sitecore.Context.Langauge' to French if the first element in it matched/fr/`.
Extremely quick & dirty example:
public class MyLanguageResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
string languageText = WebUtil.ExtractLanguageName(args.Context.Request.RawUrl);
if(languageText == "fr")
{
Sitecore.Context.Language = LanguageManager.GetLanguage("fr-CA");
}
}
}
You would probably also have to override the LinkProvider in the <linkManager> section of the web.config to format your URLs when they are resolved by Sitecore.
Another extremely quick & dirty example:
public class MyLinkProvider : LinkProvider
{
public override string GetItemUrl(Sitecore.Data.Items.Item item, UrlOptions options)
{
var url = base.GetItemUrl(item, options);
url = url.Replace("/fr-CA/", "/fr/");
return url;
}
}
Another way (slightly more long-winded as it will need to be executed via a script) is to copy the data from the fr-CA version to the fr version and then delete the fr-CA version of each item.
Rough helper method that encompasses what you're trying to do
private void CopyLanguage(ID id, Language sourceLanguage, Language destinationLanguage)
{
var master = Database.GetDatabase("master");
var sourceLanguageItem = master.GetItem(id, sourceLanguage);
var destinationLanguageItem = master.GetItem(id, destinationLanguage);
using (new SecurityDisabler())
{
destinationLanguageItem.Editing.BeginEdit();
//for each field in source, create in destination if it does not exist
foreach (Field sf in sourceLanguageItem.Fields)
{
if (sf.Name.Contains("_")) continue;
destinationLanguageItem.Fields[sf.Name].Value = sf.Value;
}
destinationLanguageItem.Editing.AcceptChanges();
////Remove the source language version
ItemManager.RemoveVersions(sourceLanguageItem,sourceLanguage, SecurityCheck.Disable);
}
}
Another way to update the languages on your content items is:
Export the fr-CA language to a .xml file (Using the Control Panel)
In the .xml file replace all and tags with the and
Rename fr-CA language in the master database to the fr
Import language from the .xml file
Run Clean Up Databases task (from the Control Panel)
Also you can create a sql script that will change fr-CA language with the fr for all records in the UnversionedFields and VersionedFields tables.
If you need any more information or examples please let me know. :)
I had a similar requirement to rename a language while retaining the content. I decided to migrate content from one language to another by using Unicorn:
1: Create a predicate telling Unicorn to track all of your content. In my case:
<include name="site content" database="master" path="/sitecore/content/mySite" />
Reserialize the content, writing it to disk as YML files
Using a tool that can perform a find & replace in multiple files at once, such as Notepad++, replace all instances of "Language: fr-CA" with "Language: fr" in your yml files.
Run a Unicorn Sync
You will find that all of your content is now associated with the "fr" language instead of "fr-CA".

How to create a C/C++ program that generates an XML and runs a DOS command afterwards?

I need to come up with a program that generates an xml file like this:
<?xml version="1.0"?>
<xc:XmlCache xmlns:xc="XmlCache" xc:action="Update">
<xc:XmlCacheArea xc:target="AllSubFields" xc:value="MarketParameters">
<mp:nickName xmlns:mp="mx.MarketParameters" xc:value="MDS">
<mp:date xc:value="TODAY">
<fx:forex xmlns:fx="mx.MarketParameters.Forex">
<fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot">
<fxsp:pair type="Fields" value="USD/BRL">
<mp:ask xc:type="Field" xc:keyFormat="N">1.890</mp:ask>
<mp:bid xc:type="Field" xc:keyFormat="N">1.800</mp:bid>
</fxsp:pair>
</fxsp:spot>
</fx:forex>
</mp:date>
</mp:nickName>
</xc:XmlCacheArea>
</xc:XmlCache>
with the values in the nodes mp:ask and mp:bid randomly generated but between two predefined values (1.65 and 1.99).
After the xml is generated in the same directory of the program, the program should run a command in the cmd command line that states:
cachetool.bat -i cacheBody.xml -u REALTIME
where cachetool.bat is an already done bash script that cannot be changed and that is also place in the same directory of the program, and where cacheBody.xml is that previously generated xml.
The trick here is that this should run repeatedly overwriting the xml file with new values each time and then running the command again calling the xml with the new values.
There should be a way to easy interrupt the loop, but besides that, this should run indefinitely.
Note: there isn't a strict rule to use c or c++, if it isn't feasible in these languages or if there other ways to do it easily, please feel free to suggest. My initial proposal is in these languages because these are the two that I'm a little used to deal with.
I'm learning how to use javascript for Windows local scripting, so here's a solution in javascript.
It looks like you don't really need to generate the XML dynamically, but rather the XML structure is static and only a couple data fields are dynamic. With that in mind, I approached the problem with search-and-replace using a template file.
The template file (template.xml) contains xml content with some variables to search and replace. The format variable format is $RANDOM_X_Y$, where X and Y are the lower and upper bounds for the random number. To help the example, I generated the ask and bid prices slightly differently in the template file:
<?xml version="1.0"?>
<xc:XmlCache xmlns:xc="XmlCache" xc:action="Update">
<xc:XmlCacheArea xc:target="AllSubFields" xc:value="MarketParameters">
<mp:nickName xmlns:mp="mx.MarketParameters" xc:value="MDS">
<mp:date xc:value="TODAY">
<fx:forex xmlns:fx="mx.MarketParameters.Forex">
<fxsp:spot xmlns:fxsp="mx.MarketParameters.Forex.Spot">
<fxsp:pair type="Fields" value="USD/BRL">
<mp:ask xc:type="Field" xc:keyFormat="N">1.$RANDOM_65_99$0</mp:ask>
<mp:bid xc:type="Field" xc:keyFormat="N">1.$RANDOM_650_990$</mp:bid>
</fxsp:pair>
</fxsp:spot>
</fx:forex>
</mp:date>
</mp:nickName>
</xc:XmlCacheArea>
</xc:XmlCache>
The javascript file is called replace.js. All versions of Windows should be able to execute it natively without installing any extra components.
if( WScript.Arguments.Count() != 2 || WScript.Arguments.Item(0) == WScript.Arguments.Item(1) )
{
WScript.Echo("Usage: replace.js <template> <output filename>");
WScript.Quit();
}
var template_filename = WScript.Arguments.Item(0);
var output_filename = WScript.Arguments.Item(1);
var fso = new ActiveXObject("Scripting.FileSystemObject");
var ForReading = 1;
var file, file_contents, lower, upper;
var var_regex = /\$RANDOM_(\d+)_(\d+)\$/g;
if( fso.FileExists(template_filename) )
{
file = fso.OpenTextFile(template_filename, ForReading, false);
file_contents = file.ReadAll().replace(var_regex,
function(str, lower, upper) {
return Math.floor(
Math.random() * (+upper - +lower + 1)) + +lower;
});
file.Close();
file = fso.CreateTextFile(output_filename, true);
file.Write(file_contents);
file.Close();
}
else
{
WScript.Echo("Template does not exist: " + template_filename);
}
Now to run your scripts indefinitely, just create a batch file called run.bat or whatever and have it run the javascript and batch files in a loop. CTRL-C will exit the script.
#echo off
echo Starting. Press CTRL-C to exit.
:loop
replace.js template.xml cacheBody.xml
cachetool.bat -i cacheBody.xml -u REALTIME
goto loop
Well, to create the random value, you can use the rand() function, and just scale it so it's between the two values you want.
To call the command line, try system("cachetool.bat -i cacheBody.xml -u REALTIME");
And for the xml, if it's all the same except for the numbers, you can just hardcode it. If not, you'll need an xml library.