I can easily convert this by replacing <p> and \n to <div> and <br>, and so on for other things as well. But, the issue is that the client always thinks that the data was modified and it wants us to save data each time we open the record because it’s not normalised in the format that client expects it.
The normalize function doesn’t handle all the cases. Like I’ve described <p> and \n are not properly formatted and it renders the text in a very different format from the original format.
In my testing I saw that it removes all the tags it doesn’t support like <p>, <span> and encloses everything in a single div. While the correct output would be if it would replace \n\n with a <br>, convert all <p> to <div> and \n with empty string and only after that I can run normalize which would let tryton client know that the record is not in a dirty state.
If there’s no official way of doing this then I’ll just pick the normalize function from tryton client and write a python script to update all the records.