fix parse styled strings

This commit is contained in:
REAndroid 2023-05-06 18:25:44 +02:00
parent 70490324bd
commit 193a9b66ee
3 changed files with 106 additions and 39 deletions

View File

@ -1,28 +1,39 @@
/* /*
* Copyright (C) 2022 github.com/REAndroid * Copyright (C) 2022 github.com/REAndroid
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.reandroid.apk.xmlencoder; package com.reandroid.apk.xmlencoder;
import com.reandroid.arsc.decoder.ValueDecoder; import com.reandroid.arsc.decoder.ValueDecoder;
import com.reandroid.arsc.value.Entry; import com.reandroid.arsc.value.Entry;
import com.reandroid.xml.XMLElement;
import com.reandroid.xml.XMLSpannable;
class XMLValuesEncoderString extends XMLValuesEncoder{ class XMLValuesEncoderString extends XMLValuesEncoder{
XMLValuesEncoderString(EncodeMaterials materials) { XMLValuesEncoderString(EncodeMaterials materials) {
super(materials); super(materials);
} }
@Override
void encodeValue(Entry entry, XMLElement element){
if(!element.hasChildElements()){
super.encodeValue(entry, element);
return;
}
encodeStyledString(entry, element);
}
@Override @Override
void encodeStringValue(Entry entry, String value){ void encodeStringValue(Entry entry, String value){
entry.setValueAsString(ValueDecoder.unEscapeSpecialCharacter(value)); entry.setValueAsString(ValueDecoder.unEscapeSpecialCharacter(value));
@ -35,4 +46,8 @@ import com.reandroid.arsc.value.Entry;
void encodeBooleanValue(Entry entry, String value){ void encodeBooleanValue(Entry entry, String value){
entry.setValueAsString(value); entry.setValueAsString(value);
} }
private void encodeStyledString(Entry entry, XMLElement element){
XMLSpannable xmlSpannable = new XMLSpannable(element);
entry.setValueAsString(xmlSpannable.getXml());
}
} }

View File

@ -1,4 +1,4 @@
/* /*
* Copyright (C) 2022 github.com/REAndroid * Copyright (C) 2022 github.com/REAndroid
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -85,6 +85,9 @@ public class StyleSpanInfo implements JSONConvert<JSONObject> {
public String getEndTag(){ public String getEndTag(){
int i= mTag.indexOf(';'); int i= mTag.indexOf(';');
if(i < 0){
i = mTag.indexOf(' ');
}
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();
builder.append('<'); builder.append('<');
builder.append('/'); builder.append('/');

View File

@ -1,29 +1,29 @@
/* /*
* Copyright (C) 2022 github.com/REAndroid * Copyright (C) 2022 github.com/REAndroid
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.reandroid.xml; package com.reandroid.xml;
import com.reandroid.xml.parser.XMLSpanParser; import com.reandroid.xml.parser.XMLSpanParser;
import java.util.*; import java.util.*;
public class XMLSpannable implements Comparable<XMLSpannable>{ public class XMLSpannable implements Comparable<XMLSpannable>{
private XMLElement mElement; private XMLElement mElement;
private String mText; private String mText;
private List<XMLSpanInfo> mSpanInfoList; private List<XMLSpanInfo> mSpanInfoList;
private XMLSpannable(XMLElement element){ public XMLSpannable(XMLElement element){
this.mElement=element; this.mElement=element;
} }
public boolean isValid(){ public boolean isValid(){
@ -38,6 +38,47 @@ import java.util.*;
} }
return true; return true;
} }
public String getXml(){
StringBuilder builder = new StringBuilder();
for(XMLNode xmlNode: mElement.getChildNodes()){
if(xmlNode instanceof XMLElement){
appendXml(builder, (XMLElement) xmlNode);
}else if(xmlNode instanceof XMLText){
appendXml(builder, (XMLText) xmlNode);
}
}
return builder.toString();
}
private void appendXml(StringBuilder builder, XMLElement element){
builder.append('<');
builder.append(element.getTagName());
appendXmlAttributes(builder, element);
builder.append('>');
for(XMLNode xmlNode: element.getChildNodes()){
if(xmlNode instanceof XMLElement){
appendXml(builder, (XMLElement) xmlNode);
}else if(xmlNode instanceof XMLText){
appendXml(builder, (XMLText) xmlNode);
}
}
builder.append('<');
builder.append('/');
builder.append(element.getTagName());
builder.append('>');
}
private void appendXmlAttributes(StringBuilder builder, XMLElement element){
for(XMLAttribute xmlAttribute : element.listAttributes()){
builder.append(' ');
builder.append(xmlAttribute.getName());
builder.append('=');
builder.append('"');
builder.append(xmlAttribute.getValue());
builder.append('"');
}
}
private void appendXml(StringBuilder builder, XMLText xmlText){
builder.append(xmlText.getText(true));
}
public String getText(){ public String getText(){
if(mText==null){ if(mText==null){
buildSpanInfo(); buildSpanInfo();
@ -58,11 +99,15 @@ import java.util.*;
mElement=null; mElement=null;
} }
private void buildSpanInfo(XMLElement element, StringBuilder builder){ private void buildSpanInfo(XMLElement element, StringBuilder builder){
XMLSpanInfo info=null; XMLSpanInfo info = null;
for(XMLNode node:element.listSpannable()){ for(XMLNode node:element.listSpannable()){
if(info!=null){ if(info != null){
info.end=builder.length(); int pos = builder.length();
info=null; if(pos > 0){
pos = pos - 1;
}
info.end = pos;
info = null;
} }
if(node instanceof XMLText){ if(node instanceof XMLText){
builder.append(((XMLText)node).getText()); builder.append(((XMLText)node).getText());
@ -76,7 +121,11 @@ import java.util.*;
buildSpanInfo(child, builder); buildSpanInfo(child, builder);
} }
if(info!=null){ if(info!=null){
info.end=builder.length(); int pos = builder.length();
if(pos > 0){
pos = pos - 1;
}
info.end = pos;
} }
} }
@Override @Override