【优化】读取excel标题头列时,如果遇到不认识的标签,打印警告。将示例中的##+全部统一成##var。

main
walon 2021-12-12 13:12:01 +08:00
parent 8cd9ffee3c
commit 4f8fd20780
20 changed files with 54 additions and 127 deletions

View File

@ -197,7 +197,7 @@ array与list类型都能表示列表它们区别在于array生成的代码为
<table border="1">
<tr align="center"><td>##</td><td>full_name</td><td>flags</td><td>unique</td><td>comment</td><td>tags</td><td colspan="5">*items</td></tr>
<tr align="center"><td>##+</td><td></td><td></td><td></td><td></td><td></td><td>name</td><td>alias</td><td>value</td><td>comment</td><td>tags</td></tr>
<tr align="center"><td>##var</td><td></td><td></td><td></td><td></td><td></td><td>name</td><td>alias</td><td>value</td><td>comment</td><td>tags</td></tr>
<tr align="center"><td/><td>ItemQuality</td><td>false</td><td>true</td><td/><td/><td>WHITE</td><td></td><td>0</td><td/><td/></tr>
<tr align="center"><td/><td></td><td></td><td></td><td/><td/><td>GREEN</td><td>绿</td><td>1</td><td/><td/></tr>
<tr align="center"><td/><td></td><td></td><td></td><td/><td/><td>RED</td><td></td><td>2</td><td/><td/></tr>
@ -234,7 +234,7 @@ array与list类型都能表示列表它们区别在于array生成的代码为
<table border="1">
<tr align="center"><td>##</td><td>full_name</td><td >sep</td><td>comment</td><td colspan="5">fields</td> </tr>
<tr align="center"><td>##+</td><td></td><td/><td/><td>name</td><td>type</td><td>group</td><td>comment</td><td>tags</td></tr>
<tr align="center"><td>##var</td><td></td><td/><td/><td>name</td><td>type</td><td>group</td><td>comment</td><td>tags</td></tr>
<tr><td></td><td>Reward</td><td/><td/><td>item_id</td><td>int</td><td></td><td>道具id</td><td/></tr>
<tr><td></td><td></td><td/><td/><td>count</td><td>int</td><td></td><td>个数</td><td/></tr>
<tr><td></td><td></td><td/><td/><td>desc</td><td>string</td><td></td><td>描述</td><td/></tr>
@ -352,7 +352,7 @@ xml中定义如下
</tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td></td>
<td></td>
<td colspan="3">0</td>
@ -360,7 +360,7 @@ xml中定义如下
<td colspan="3">2</td>
</tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td/>
<td/>
<td>item_id</td><td>num</td><td>desc</td>
@ -625,7 +625,7 @@ xml中定义如下
### 层级标题头 (hierarchy title)
在多行数据或者深层次嵌套的数据中如果数据字段较多填写时不易区分子元素。luban提供层级标题实现深层次的子字段对应。以上面的多行数据列表为例,第一列为##+表示这是个子字段行。
在多行数据或者深层次嵌套的数据中如果数据字段较多填写时不易区分子元素。luban提供层级标题实现深层次的子字段对应。以上面的多行数据列表为例,第一列为##var表示这是个子字段行。
- 普通bean结构的子标题
@ -644,7 +644,7 @@ xml中定义如下
<td colspan="5">Stage</td>
</tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td/>
<td/>
<td>name</td>
@ -687,7 +687,7 @@ xml中定义如下
<td colspan="6">stages</td>
</tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td/>
<td/>
<td>id</td>
@ -745,7 +745,7 @@ xml中定义如下
<tr align="center"><td>##type</td><td>int</td><td>string</td><td colspan="9">list,Item</td></tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td></td>
<td></td>
<td colspan="3">0</td>
@ -753,7 +753,7 @@ xml中定义如下
<td colspan="3">2</td>
</tr>
<tr align="center">
<td>##+</td>
<td>##var</td>
<td/>
<td/>
<td>item_id</td><td>num</td><td>desc</td>
@ -772,7 +772,7 @@ xml中定义如下
<tr align="center"><td>##</td><td>id</td><td colspan="4">lans</td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="4">map,string,string</td></tr>
<tr align="center"><td>##+</td><td/><td>ch-zn</td><td>en</td><td>jp</td><td>fr</td></tr>
<tr align="center"><td>##var</td><td/><td>ch-zn</td><td>en</td><td>jp</td><td>fr</td></tr>
<tr align="center"><td/><td>1</td><td>苹果</td><td>apple</td><td>aaa</td><td>aaa</td></tr>
<tr align="center"><td/><td>2</td><td>香蕉</td><td>banana</td><td>bbb</td><td>bbb</td></tr>
@ -931,11 +931,11 @@ binary格式占空间最小lua其次json最大。
### 自定义代码和数据模板
[自定义模板](docs/render_template.md)
[自定义模板](https://github.com/focus-creative-games/luban/wiki/render_template)
### 本地化
支持以下几种本地化机制,详见[本地化](docs/l10n.md)
支持以下几种本地化机制,详见[本地化](https://github.com/focus-creative-games/luban/wiki/l10n)
- 静态本地化
- 动态本地化

View File

@ -23,21 +23,13 @@ namespace Luban.Common.Utils
public static string GetFileName(string path)
{
int index = path.Replace('\\', '/').LastIndexOf('/');
#if !LUBAN_LITE
return index >= 0 ? path[(index + 1)..] : path;
#else
return index >= 0 ? path.Substring(index + 1, path.Length - index - 1) : path;
#endif
}
public static string GetParent(string path)
{
int index = path.Replace('\\', '/').LastIndexOf('/');
#if !LUBAN_LITE
return index >= 0 ? path[..index] : ".";
#else
return index >= 0 ? path.Substring(0, index) : ".";
#endif
}
public static string GetFileNameWithoutExt(string file)
@ -70,11 +62,7 @@ namespace Luban.Common.Utils
}
var f = new FileInfo(file);
string fname = f.Name;
#if !LUBAN_LITE
return !fname.StartsWith('.') && !fname.StartsWith('_') && !fname.StartsWith('~');
#else
return !fname.StartsWith(".") && !fname.StartsWith("_") && !fname.StartsWith("~");
#endif
}
[ThreadStatic]
@ -129,7 +117,6 @@ namespace Luban.Common.Utils
else
{
int lastPathSep = url.LastIndexOf('/', sheetSepIndex);
#if !LUBAN_LITE
if (lastPathSep >= 0)
{
return (url[0..(lastPathSep + 1)] + url[(sheetSepIndex + 1)..], url[(lastPathSep + 1)..sheetSepIndex]);
@ -138,16 +125,6 @@ namespace Luban.Common.Utils
{
return (url[(sheetSepIndex + 1)..], url[(lastPathSep + 1)..sheetSepIndex]);
}
#else
if (lastPathSep >= 0)
{
return (url.Substring(0, lastPathSep + 1) + url.Substring(sheetSepIndex + 1), url.Substring(lastPathSep + 1, sheetSepIndex - lastPathSep - 1));
}
else
{
return (url.Substring(sheetSepIndex + 1), url.Substring(lastPathSep + 1, sheetSepIndex - lastPathSep - 1));
}
#endif
}
}
@ -182,12 +159,7 @@ namespace Luban.Common.Utils
s_logger.Info("[new] {file}", outputPath);
}
#if !LUBAN_LITE
await File.WriteAllBytesAsync(outputPath, content);
#else
await Task.Run(() => File.WriteAllBytes(outputPath, content));
#endif
}
public static async Task<byte[]> ReadAllBytesAsync(string file)

View File

@ -22,11 +22,7 @@ namespace Luban.Job.Cfg.DataSources
{
try
{
#if !LUBAN_LITE
string ext = url.Contains('.') ? Path.GetExtension(url)?[1..] : url;
#else
string ext = url.Contains(".") ? Path.GetExtension(url)?.Substring(1) : url;
#endif
AbstractDataSource source;
switch (ext)
{

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.DataSources.Excel
@ -31,9 +32,12 @@ namespace Luban.Job.Cfg.DataSources.Excel
}
}
private static readonly AsyncLocal<string> s_curExcel = new();
public static IEnumerable<RawSheet> LoadRawSheets(string rawUrl, string sheetName, Stream stream)
{
s_logger.Trace("{filename} {sheet}", rawUrl, sheetName);
s_curExcel.Value = rawUrl;
string ext = Path.GetExtension(rawUrl);
using (var reader = ext != ".csv" ? ExcelReaderFactory.CreateReader(stream) : ExcelReaderFactory.CreateCsvReader(stream, new ExcelReaderConfiguration() { FallbackEncoding = DetectCsvEncoding(stream) }))
{
@ -68,11 +72,48 @@ namespace Luban.Job.Cfg.DataSources.Excel
return null;
}
var cells = ParseRawSheetContent(reader, orientRow, false);
ValidateTitles(cells);
var title = ParseTitle(cells, reader.MergeCells, orientRow);
cells.RemoveAll(c => IsNotDataRow(c));
return new RawSheet() { Title = title, TableName = tableName, Cells = cells };
}
private static readonly HashSet<string> s_knownSpecialTags = new HashSet<string>
{
"##var",
"##+",
"##type",
"##desc",
"##comment",
"##column",
"##",
};
private static void ValidateTitles(List<List<Cell>> rows)
{
foreach (var row in rows)
{
if (row.Count == 0)
{
continue;
}
string rowTag = row[0].Value?.ToString()?.ToLower()?.Trim();
if (string.IsNullOrEmpty(rowTag))
{
continue;
}
if (!rowTag.StartsWith("##"))
{
break;
}
if (!s_knownSpecialTags.Contains(rowTag))
{
DefAssembly.LocalAssebmly?.Agent?.Error("文件:'{0}' 行标签:'{1}' 未知,是否有拼写错误?", s_curExcel.Value, rowTag);
}
}
}
private static bool IsNotDataRow(List<Cell> row)
{
if (row.Count == 0)
@ -133,11 +174,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
private static bool IsIgnoreTitle(string title)
{
#if !LUBAN_LITE
return string.IsNullOrEmpty(title) || title.StartsWith('#');
#else
return string.IsNullOrEmpty(title) || title.StartsWith("#");
#endif
}
public static (string Name, Dictionary<string, string> Tags) ParseNameAndMetaAttrs(string nameAndAttrs)
@ -241,6 +278,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
var (titleName, tags) = ParseNameAndMetaAttrs(nameAndAttrs);
Title subTitle;
// [field,,,, field] 形成多列字段
if (titleName.StartsWith('['))
{
int startIndex = i;

View File

@ -11,11 +11,7 @@ namespace Luban.Job.Cfg.DataVisitors
public override string Accept(DText type)
{
#if !LUBAN_LITE
return $"\"{type.Key}#{type.TextOfCurrentAssembly}\"";
#else
return $"\"{type.Key}#{type.RawValue}\"";
#endif
}
public override string Accept(DBean type)

View File

@ -1,8 +1,6 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
#if !LUBAN_LITE
using Luban.Job.Cfg.l10n;
#endif
namespace Luban.Job.Cfg.Datas
{
@ -25,7 +23,6 @@ namespace Luban.Job.Cfg.Datas
_rawValue = x;
}
#if !LUBAN_LITE
public string GetText(TextTable stringTable, NotConvertTextSet notConvertKeys)
{
if (stringTable != null)
@ -50,7 +47,6 @@ namespace Luban.Job.Cfg.Datas
return GetText(ass.ExportTextTable, ass.NotConvertTextSet);
}
}
#endif
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{

View File

@ -323,15 +323,8 @@ namespace Luban.Job.Cfg.Defs
string valueTypeName = TypeUtil.GetName(table.ValueType);
var cb = new CfgBean() { Namespace = valueTypeNamespace, Name = valueTypeName, Comment = "" };
#if !LUBAN_LITE
foreach (var (name, f) in tableDefInfo.FieldInfos)
{
#else
foreach (var e in tableDefInfo.FieldInfos)
{
var name = e.Key;
var f = e.Value;
#endif
var cf = new CfgField() { Name = name, Id = 0 };
string[] attrs = f.Type.Trim().Split('&').Select(s => s.Trim()).ToArray();
@ -347,11 +340,7 @@ namespace Luban.Job.Cfg.Defs
for (int i = 1; i < attrs.Length; i++)
{
#if !LUBAN_LITE
var pair = attrs[i].Split('=', 2);
#else
var pair = attrs[i].Split(new char[] { '=' }, 2);
#endif
if (pair.Length != 2)
{
throw new Exception($"table:'{table.Name}' file:{file.OriginFile} title:'{name}' attr:'{attrs[i]}' is invalid!");

View File

@ -1,9 +1,7 @@
using Bright.Collections;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
#if !LUBAN_LITE
using Luban.Job.Cfg.l10n;
#endif
using Luban.Job.Cfg.RawDefs;
using Luban.Job.Cfg.TypeVisitors;
using Luban.Job.Common.Defs;
@ -64,7 +62,6 @@ namespace Luban.Job.Cfg.Defs
public Dictionary<string, DefTable> CfgTablesByName = new();
public Dictionary<string, DefTable> CfgTablesByFullName { get; } = new Dictionary<string, DefTable>();
#if !LUBAN_LITE
public RawTextTable RawTextTable { get; } = new RawTextTable();
public TextTable ExportTextTable { get; private set; }
@ -79,8 +76,6 @@ namespace Luban.Job.Cfg.Defs
NotConvertTextSet = new NotConvertTextSet();
}
#endif
public Patch GetPatch(string name)
{
return _patches.Find(b => b.Name == name);

View File

@ -33,7 +33,6 @@ namespace Luban.Job.Cfg.Defs
return DeepCompareTypeDefine.Ins.Compare(this, b, new Dictionary<DefTypeBase, bool>(), new HashSet<DefTypeBase>());
}
#if !LUBAN_LITE
public override string GoBinImport
{
get
@ -96,7 +95,6 @@ namespace Luban.Job.Cfg.Defs
throw new NotImplementedException();
}
}
#endif
public DefBean(CfgBean b) : base(b)
{
@ -187,11 +185,7 @@ namespace Luban.Job.Cfg.Defs
Id = TypeUtil.ComputCfgHashIdByName(FullName);
}
// 检查别名是否重复
#if !LUBAN_LITE
HashSet<string> nameOrAliasName = cs.Select(b => b.Name).ToHashSet();
#else
HashSet<string> nameOrAliasName = new HashSet<string>(cs.Select(b => b.Name));
#endif
foreach (DefBean c in cs)
{
if (!string.IsNullOrWhiteSpace(c.Alias) && !nameOrAliasName.Add(c.Alias))

View File

@ -33,7 +33,6 @@ namespace Luban.Job.Cfg.Defs
|| (CType is TList tl && tl.ElementType.IsBean)
|| (CType is TMap tm && tm.ValueType.IsBean);
#if !LUBAN_LITE
public string CsRefTypeName
{
get
@ -87,7 +86,6 @@ namespace Luban.Job.Cfg.Defs
return $"{RefVarName} : {table.ValueTType.Apply(TypescriptDefineTypeNameVisitor.Ins)}{(IsNullable ? "" : " = undefined!")}";
}
}
#endif
public string RefVarName => $"{ConventionName}_Ref";

View File

@ -1,7 +1,5 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
#if !LUBAN_LITE
#endif
using Luban.Job.Cfg.RawDefs;
using Luban.Job.Cfg.Utils;
using System;
@ -37,7 +35,6 @@ namespace Luban.Job.Cfg.Defs
private void BuildIndexs()
{
#if !LUBAN_LITE
List<Record> mainRecords = MainRecords;
List<Record> patchRecords = PatchRecords;
@ -171,7 +168,6 @@ namespace Luban.Job.Cfg.Defs
}
default: throw new Exception($"unknown mode:{Table.Mode}");
}
#endif
}
}
}

View File

@ -84,7 +84,6 @@ namespace Luban.Job.Cfg.Utils
foreach (var file in inputFileInfos)
{
var actualFile = file.ActualFile;
//s_logger.Info("== get input file:{file} actualFile:{actual}", file, actualFile);
tasks.Add(Task.Run(async () =>
{

View File

@ -72,12 +72,10 @@ namespace Luban.Job.Cfg
{
CurrentVisitor = visitor;
visitor.ValidateTable(t, records);
#if !LUBAN_LITE
if (this.Assembly.NeedL10nTextTranslate)
{
ValidateText(t, records);
}
#endif
}
finally
{
@ -93,7 +91,6 @@ namespace Luban.Job.Cfg
}
}
#if !LUBAN_LITE
private void ValidateText(DefTable table, List<Record> records)
{
foreach (var r in records)
@ -103,7 +100,6 @@ namespace Luban.Job.Cfg
}
CurrentVisitor.CurrentValidateRecord = null;
}
#endif
private async Task ValidatePaths()
{
@ -154,11 +150,7 @@ namespace Luban.Job.Cfg
{
if (ls.All(f => fileNotExistsSet.Contains(f)))
{
#if !LUBAN_LITE
agent.Error("记录 {0} = {1} (来自文件:{2}) 所引用文件:{3} 不存在", q.DataPath, q.Value, q.Source, string.Join(',', ls));
#else
agent.Error("记录 {0} = {1} (来自文件:{2}) 所引用文件:{3} 不存在", q.DataPath, q.Value, q.Source, string.Join(",", ls));
#endif
}
break;
}

View File

@ -112,11 +112,7 @@ namespace Luban.Job.Cfg.Validators
string suffix = groups[2].Value.Substring(1);
if (suffix.EndsWith("_C"))
{
#if !LUBAN_LITE
suffix = suffix[0..^2];
#else
suffix = suffix.Substring(0, suffix.Length - 2);
#endif
}
return path.EndsWith(suffix);
}
@ -221,17 +217,9 @@ namespace Luban.Job.Cfg.Validators
string patType = ss[0];
bool emptyAble = false;
#if !LUBAN_LITE
if (patType.EndsWith('?'))
#else
if (patType.EndsWith("?"))
#endif
{
#if !LUBAN_LITE
patType = patType[0..^1];
#else
patType = patType.Substring(0, patType.Length - 1);
#endif
emptyAble = true;
}

View File

@ -84,22 +84,14 @@ namespace Luban.Job.Cfg.Validators
case '(': _includeMinBound = false; break;
default: ThrowError(); break;
}
#if !LUBAN_LITE
switch (_str[^1])
#else
switch (_str[_str.Length - 1])
#endif
{
case ']': _includeMaxBound = true; break;
case ')': _includeMaxBound = false; break;
default: ThrowError(); break;
}
#if !LUBAN_LITE
var pars = _str[1..^1].Split(',');
#else
var pars = _str.Substring(1, _str.Length - 2).Split(',');
#endif
if (pars.Length != 2)
{
ThrowError();

View File

@ -41,7 +41,6 @@ namespace Luban.Job.Cfg.Validators
}
var assembly = ctx.Assembly;
#if !LUBAN_LITE
foreach (var tableInfo in _compiledTables)
{
var (defTable, field, zeroAble) = tableInfo;
@ -83,7 +82,6 @@ namespace Luban.Job.Cfg.Validators
{
assembly.Agent.Error("记录 {0} = {1} (来自文件:{2}) 在引用表:{3} 中不存在", ValidatorContext.CurrentRecordPath, key, source, table.Table.FullName);
}
#endif
}

View File

@ -214,11 +214,7 @@ namespace Luban.Job.Common.Defs
rawType = DefUtil.TrimBracePairs(rawType);
var (type, tags) = DefUtil.ParseType(rawType);
#if !LUBAN_LITE
if (type.EndsWith('?'))
#else
if (type.EndsWith("?"))
#endif
{
if (!SupportNullable)
{

View File

@ -59,7 +59,6 @@ namespace Luban.Job.Common.Defs
}
}
#if !LUBAN_LITE
public virtual string GoBinImport
{
get
@ -76,7 +75,6 @@ namespace Luban.Job.Common.Defs
return string.Join('\n', imports.Select(im => $"import \"{im}\""));
}
}
#endif
protected abstract DefFieldBase CreateField(Field f, int idOffset);

View File

@ -248,11 +248,7 @@ namespace Luban.Job.Common.Utils
case ELanguage.PYTHON:
case ELanguage.RUST:
case ELanguage.PROTOBUF:
#if !LUBAN_LITE
return System.Web.HttpUtility.HtmlEncode(comment).Replace("\n", "<br/>");
#else
throw new NotSupportedException();
#endif
default: throw new Exception($"unknown language:{curLan}");
}
}

View File

@ -24,7 +24,6 @@ namespace Luban.Job.Proto.Defs
public List<DefField> Fields { get; set; } = new List<DefField>();
#if !LUBAN_LITE
public virtual string GoBinImport
{
get
@ -41,7 +40,6 @@ namespace Luban.Job.Proto.Defs
return string.Join('\n', imports.Select(im => $"import \"{im}\""));
}
}
#endif
public override void Compile()
{