Инструмент для форматирования HTML кода? — rpilot62.ru

Примеры

Исходный сжатый HTML-код:

<table><tr><td><form class=»search2″ action=»https://yandex.ru/search/» role=»search» aria-label=»Поиск в интернете»><div class=»suggest2-form__node»><div class=»search2__button»><button class=»button» type=»submit»><span class=»button__text»>Найти</span></button></div><div class=»search2__input»><input class=»input__control» id=»text» maxlength=»400″ name=»text»/></div><div class=»i-bem»><div class=»popup__under»></div><div class=»popup__content»></div></div></div></form></td></tr></table>

HTML-код после преобразования:

<table>
  <tr>
    <td>
      <form class=»search2″ action=»https://yandex.ru/search/» role=»search» aria-label=»Поиск в интернете»>
        <div class=»suggest2-form__node»>
          <div class=»search2__button»>
            <button class=»button» type=»submit»><span class=»button__text»>Найти</span></button>
          </div>
          <div class=»search2__input»>
            <input class=»input__control» id=»text» maxlength=»400″ name=»text»/>
          </div>
          <div class=»i-bem»>
            <div class=»popup__under»></div>
            <div class=»popup__content»></div>
          </div>
        </div>
      </form>
    </td>
  </tr>
</table>

Вконтакте

Facebook

Одноклассники

Google+

Мой Мир@Mail.Ru

Внимание! Этот документ ещё не опубликован.

Стандарты программирования

В Epic есть несколько простых соглашений и стандартов программирования. Большинство нижеприведенных примеров применимы к коду сценариев UnrealScript, но эти же соглашения также распространяются и на код на C++. Этот документ отражает текущее состояние стандартов программирования Epic и не подразумевает обсуждение будущих дополнений к текущим соглашениям. Заметим, что код движка не в полной мере соответствует этому стандарту, так как у нас есть несколько сотен тысяч строк старого кода, который мы постепенно обновляем и дополняем.

Соглашения о программировании являются важными для программистов по ряду причин:

  • 80% времени жизни программного обеспечения уходит на его поддержку.
  • Маловероятно, что программное обеспечение в течение всего своего времени жизни будет поддерживаться его изначальным автором.
  • Соглашения о программировании улучшают читаемость кода программного обеспечения, позволяя инженерам понимать новый код быстрее и более тщательно. В течение времени жизни вашего проекта может смениться не один инженер, а на базе существующей версии движка будет создан не один проект.
  • Если Вы решите предоставить исходный код сообществу разработчиков модов, то желательно, чтобы он был легко читаем понятен.
  • Многие из этих соглашений необходимы для обеспечения совместимости между различными компиляторами.

Организация классов: имена классов — существительные

  • Блок комментария к классу
  • Объявление класса
  • Объявления переменных
  • Применительно только к C++:  Статические и постоянные переменные
  • Общедоступные (public) переменные
  • Защищенные (protected) переменные
  • Закрытые (private) переменные
  • Блок cpptext
  • Конструкторы и деструкторы
  • Включения BeginPlay( ), Destroyed( ) и т.д.
  • Методы и состояния, сгруппированые по функциональности
  • Вспомогательные методы, не включенные в состояния (State-less), (не связанные с к каким либо состоянием), сгруппированые по функциональности
  • Вспомогательные методы, не включенные в состояния, но связанные с входом в состояние или выходом из состояния.
  • Прочие методы, не включенные в состояния и автосостояния.
  • Блок defaultpropertieеs

Организация состояний: имена состояний — прилагательные

  • Блок комментария к состоянию (похож на комментарии к методам)
  • Методы
  • Код состояния

Организация методов: имена методов — глаголы

  • Блок комментария к методу
  • Локальные переменные

Переменные: используются соответствующие типы C++!

  • UBOOL для булевых значений (4 байта). BOOL не скомпилируется.
  • TCHAR для символов (НИКОГДА не рассчитывайте на конкретный размер TCHAR)
  • BYTE для беззнаковых байтов (1 байт)
  • SBYTE для байтов со знаком (1 байт)
  • WORD для беззнаковых слов (2 байта)
  • SWORD для слов со знаком (2 байта)
  • UINT для беззнаковых целых чисел (4 байта)
  • INT для целых чисел со знаком (4 байта)
  • QWORD для беззнаковых четверных слов (8 байт)
  • SQWORD для четверных слов со знаком (8 байт)
  • FLOAT для чисел с плавающей точкой обычной точности (4 байта)
  • DOUBLE для чисел с плавающей точкой двойной точности (8 байт)
  • PTRINT для целых чисел, которые могут хранить указатель (НИКОГДА не рассчитывайте на конкретный размер PTRINT)

Комментарии

Несколько советов о комментировании кода (из Kernighan & Pike The Practice of Programming):

  • Пишите самодокументируемый код:
Плохой пример Хороший пример
t = s + l — b; TotalLeaves =  SmallLeaves + LargeLeaves  — SmallAndLargeLeaves;
  • Не пишите очевидное. Напишите что-нибудь полезное:
Плохой пример Хороший пример
// инкремент iLeaves // мы знаем, что есть еще один чайный лист
Leaves++; Leaves++;
  • Не комментируйте плохой код. Перепишите его!
Плохой пример Хороший пример
// общее количество листьев равно сумме
// малых и больших листьев за минусом
// числа малых и больших листьев
t = s + l — b; TotalLeaves = SmallLeaves + LargeLeaves — SmallAndLargeLeaves;
Плохой пример Хороший пример
// инкремент iLeaves не осуществится! // мы знаем, что есть еще один чайный лист
Leaves++; Leaves++;

Наш стиль документирования кода основан на Javadoc (за исключением проектов на C#). В итоге мы получаем автоматически сгенерированную документацию.

Следующий пример демонстрирует комментарии к классу, состоянию, методу и переменной. Помните, что комментарии должны содействовать улучшать читаемость кода. При модификации любого фрагмента кода убедитесь, что соответствующие изменения внесены в коментарий к этому фрагменту.

class Tea extends WarmBeverage native, perobjectconfig, transient; /** * This class does lots of neat things. It works * with a few other classes to do other neat things. */ /** This stores the value of tea in china. */ var float Price; /** * state Brewing * This state was created to represent Brewing in the cup. * entered: AddBoilingWater is called in the default state. * exited: through Pour or too much time elapses (goes to * GettingBitter) */ state Brewing { /** * Brewing::Steep calculates a delta-taste value for the tea given the * volume and temperature of water used to steep. * * @param VolumeOfWater — amount of water used to brew * a positive number of milliliters (not checked!) * * @param TemperatureOfWater — water’s temperature in * degrees Kelvin. 273 < temperatureOfWater < 380 * * @param NewPotency — the tea’s potency after steeping starts; * should be between 0.97 and 1.04 * * @return returns the change in intensity of the tea in tea taste * units (TTU) per minute * */ function float Steep (float VolumeOfWater, float TemperatureOfWater, out float NewPotency) { } }

Что должен включать в себя комментарий к классу?

  • Описание задач, решаемых классом. Почему этот класс был создан?

Что должен включать в себя комментарий к состоянию?

  • Описание задач, решаемых состоянием. За что отвечает обект этого состояния? Заметьте, что параметры функции состояния не включены в блок комментария к состоянию. Они расположены ниже.

Какие части функции должны быть прокомментированы?

  • Описываются задачи, решаемые функцией. Как уже было сказано выше, комментарии предназначены для документирования, описания назначения и особенностей реализации кода.
  • Список всех входных параметров для этого метода. Каждый параметр должен включать единицы измерения, диапазон ожидаемых значений, недопустимых значений, и код значения статуса/ошибки.
  • Список всех входных параметров, через которые возвращаются результаты функции (сюда они не включены, как они в данном случае не нужны). Документируются также, как и обычные входные параметры.
  • Список всех выходных параметров (т.е. параметров, исходные значения которых игнорируются). Здесь также описываются единицы измерения, диапазон ожидаемых значений, недопустимых значений, и код значения статуса/ошибки.
  • Для возвращаемого значения функции описываются все возможные значения или диапазаны значений.

Несколько специальных комментариев. Обратите внимание, что между двумя слешами и комментарием не поставлен пробел, это облегчает поиск.

//@debug отладочный код, который не будет включен в релиз <br> //@todo пояснение, что в этом месте будет помещен необходимый код

Обратите внимание, что перед релизом отладочный код из движка должен быть исключен. Если вам необходимо оставить его в файлах исходного кода, то он должен быть заключен в блоки if(0), а не  в #if 0. В этом случае код будет скомпилирован, но выброшен при оптимизации. Включите соответствующий комментарий, поясняющий, что это отладочный код, укажите свое имя и назначение отладочного кода.

Модификация кода сторонних разработчиков:

При каждой модификации исходного кода библиотек сторонних разработчиков не забудьте пометить свои изменения комментарием //@[Название вашей организации], а также поясните причину внесения изменений. Это облегчит слияние вашего кода с новыми версиями используемых вами библиотек.

Дополнительные стандарты для C#

При документировании кода на C# вместо комментариев вида /** */ применяется формат ///. Например:

namespace UnrealLogging { /// <summary> /// Indicates the level of the message being logged /// </summary> public enum LogLevel { LOG_Error, LOG_Warning, LOG_Debug }; /// <summary> /// Generic logging interface. This interface is to be implemented to /// provide logging support for whichever the target environment is. /// </summary> public interface ILogger { /// <summary> /// Writes the message to the implemented logging support /// </summary> /// <param name="MsgLevel">The severity of the message being written</param> /// <param name="StrMsg">The message to write out</param> void Log(LogLevel MsgLevel,string StrMsg); /// <summary> /// Sets the filtering that will be applied to logging.

No message /// with a level higher than what is set in here will get logged. /// </summary> /// <param name="MaxLevel">Maximum log level to write out</param> void SetFilter(LogLevel MaxLevel); } }

Необходимые настройки для проекта

Включите генерацию файлов XML-документации и всегда держите их в актаульном состоянии.

Включите опцию, генерирующую ошибку при отсутствии документации к коду.

Соглашения по именованию

Имена переменных, функций, состояний и классов должны быть четкими, ясными и однозначно описывающими назначение типа. Избегайте чрезмерного сокращения.

Сразу после объявления переменной желательно написать к ней пояснительный комментарий. Кроме того, это требует стиль Javadoc. Вы можете писать комментарии как к отдельным переменным, так и группам переменных, расположенных в нескольких строках кода, идущих подряд. Отступы между строками не обязательны.

Для именования переменных используйте следующий формат:  ThisIsAGoodVariableName. Не применяйте форматы: "thisIsABadName" или "this_is_a_bad_name".

Имена всех переменных булевого типа, а также имена функций, возвращающих булево значение, должны быть вопросами. Перед именами переменных булевого типа ставьте префикс b.

/** the tea weight in kilograms */ var float TeaWeight; /** the number of tea leaves */ var int TeaNumber; /** TRUE indicates tea is smelly */ var bool bDoesTeaStink; /** non-human-readable FName for tea */ var name TeaName; /** human-readable name of the tea */ var String TeaName;

К концу имен структурированных типов добавляйте имя класса:

/** Which class of tea to use */ var class<Tea> TeaClass; /** The sound of pouring tea */ var Sound TeaSound; /** a picture of tea */ var Texture TeaTexture;

Для классов C++ все переменные по умолчанию должны быть закрытыми (private). Делайте их общедоступными (public) только в случаях, когда необходимо взаимодействие кода на C++ со сценариями, то есть для кода, генерированного в XxxClasses.h.

Для именования процедур (функций без возвращаемого значения) вы должны использовать только глаголы, располагая их перед именами объектов. Исключением являются случаи, когда процедура вызывается из самого объекта. Во избежание неоднозначности при именовании процедур не используйте слова "Handle" и "Process".

Tea SomeT; SteepTea(SomeT); // method names type of object processed SomeT.Pour(); // method invoked on Tea; verb is enough

Имена функции, возвращающих значение, должны описывать возвращаемое значение; имя должно дать ясно понять, какое значение вернет функция. Это особенно важно для булевых функций. Рассмотрим следующие два метода:

function bool CheckTea(Tea t) {…} // what does TRUE mean? function bool IsTeaFresh(Tea t) {…} // name makes it clear TRUE means tea is fresh

Имена состояний и классов для удобства чтения должны начинаться с заглавной буквы. Имена классов должны быть существительными, а имена состояний —  описывать состояние (например, прилагательным). Обратите внимание, что состояние никогда не используется вне класса, то есть всегда есть неявный объект.

Используйте все переменные, которые передаются в функцию. Если вы не используете какой-либо параметр, то удалите его из списка или закомментируйте его имя, оставив только тип:

void Update(FLOAT DeltaTime, UBOOL /*bForceUpdate*/);

В сценариях Unreal Script для параметров, передаваемых по ссылке, используйте префикс out_:

function PassRefs (out float out_wt, float ht, out int out_x)

Константы

При объявлении констант C++ старайтесь вместо директив компилятора применять переменные со спецификатором const.

Виртуальные функции

В производном классе при объявлении виртуальной функции, переопределяющей виртуальную функцию в родительского класса, обязательно используйте ключевое слово virtual. Хотя согласно дополнительному стандарту С++ спецификатор "virtual" наследуется, код намного яснее при явном указании ключевого слова virtual.

Исполняемые блоки

Фигурные скобки { }

Идет вечный спор о правильном расположении фигурных скобок. В Epic каждая фигурная скобка размещается в отдельной строке. Рекомендуем вам придерживаться этого правила.

блоки if — else

При использовании if — else заключайте все исполняемые блоки в фигурные скобки. Это предотвращает возможные ошибки. Если не использовать скобки, то кто-нибудь может невольно добавить еще одну строку в блок if — else, тем самым создав трудно локализуемую ошибку исполнения. Всегда используйте фигурные скобки!

if (bHaveUnrealLicense) { InsertYourGameHere(); } else { CallMarkRein(); }

При необходимости осуществления множества проверок используйте выражение else if. Это улучшит читаемость кода.

if (TannicAcid < 10) { log("Low Acid"); } else if (TannicAcid < 100) { log("Medium Acid"); } else { log("High Acid"); }

Отступы

При наборе кода в пределах исполняемых блоков делайте отступы.

Для самих классов UnrealScript отступов делать не нужно. Для создания отступов используйте знаки табуляции, а не пробелы.

Блоки switch

Во всех блоках switch после кода, следующего за проверяемым значением, не забывайте ставить оператор break. Исключениями являются случаи, когда участок кода следующего проверяемого значения должен быть выполнен и для текущего проверяемого значения.

К каждому блоку switch добавляйте действие по умолчанию (default:), даже в тех случаях, когда действие по умолчанию не требует выполнения каких либо операций.

Антананариво

Возможно необходимость в них появится позже.

switch (condition) { case 1: —code—; // falls through case 2: —code—; break; case 3: —code—; return; case 4: case 5: —code—; break; default: break; }

Блок defaultproperties

Свойства по умолчанию должны быть перечислены в следующем порядке: сначала наследуемые переменные, а затем переменные класса. Помните, что переменные конфигурации и локализации больше не могут быть определяться в блоках defaultproperties движка UE3.

defaultproperties { // variables inherited from Object bGraphicsHacks=TRUE // variables inherited from WarmBeverage bThirsty=FALSE // class variables bTeaDrinker=TRUE }

Булевы выражения

В коде на C++ в качестве значений логических выражений всегда используйте TRUE или FALSE. Не используйте true или false, которые могут вызвать сумасшедшие проблемы при компиляции. Не используйте 0 или 1, назначение подобных выражений будет неочевидным.

В коде сценариев UnrealScript вы должны использовать только true and false (в нижнем регистре).

Не бойтесь определить несколько локальных булевых переменных, чтобы сделать код более читабельным. Во втором примере, приведенном ниже, имена переменных делают причину вызова функции DoSomething() более понятной.

Фрагмент кода:

if ((Blah.BlahP.WindowExists.Etc && stuff) && !(Player exist && Gamestarted && player still has pawn && IsTuesday()))) { DoSomething(); }

должен быть заменен на:

local bool bLegalWindow; local bool bPlayerDead; bLegalWindow = (Blah.BlahP.WindowExists.Etc && stuff); bPlayerDead = (Player exist && Gamestarted && player still has pawn && IsTuesday()); if ( bLegalWindow && !bPlayerDead ) { DoSomething(); }

Обратите внимание: выражение, присваиваемое переменной bPlayerDead, разбито на две строки, а вторая срока этого выражения выровнена по отношению к первой.

Аналогичным образом оформляйте любые участки кода, которые "слишком просты" для их включения в отдельные функции, но сложны для понимания в целом.

Общие вопросы стиля:

  • Избегайте определения нескольких точек возврата из функции.  Это сделает ваш код проще в обслуживании, позволит проще отслеживать алгоритм функции и облегчит отладку.
  • Никогда не передавайте структуры в функции debugf/warnf/appErrorf Применяйте * для типов FName и FString для их форматирования и вывода с использованием %s.
  • Сводите к минимуму внешние зависимости.  Если код зависит от величины, имеющей определенное значение, то перед ее использованием попробуйте присвоить ей правильное значение. Инициализация в верхней части исполняемого блока переменной, не используемой в последующей сотне строк кода, создает вероятность случайного изменения ее значения. Старайтесь определять переменные как можно ближе к тому участку кода, где они используются. Исследование Беркли показало, что переменная, объявленная более, чем за 7 строк до ее использования, имеет крайне высокие шансы (> 80%) неправильного использования.
  • Длина функции. Функции не должны быть больше, чем 60 строк. Это число является произвольным, но вся функция должна поместиться на одной печатной странице. Если ваша функция получилась больше то, возможно, что ее следует реорганизовать. Во избежание снижения производительности старайтесь делать функции поменьше.
  • Сводите число предупреждений компилятора к минимуму Наличие предупреждающих сообщений компилятора означает, что с вашим кодом что-то не так. Исправляйте все участки кода, на которые жалуется компилятор, а если исправить код невозможно, то используйте директиву препроцессора #pragma.
  • Никогда не допускайте неявного преобразования FLOAT в INT.  Это довольно медленная операция, которая к тому же поддерживается не всеми компиляторами. Вместо этого для преобразования из FLOAT в INT используйте функцию appTrunc(). В этом случае будет скомпилирован более быстрый код и достигнута совместимость кода с разными компиляторами.

Страницы: 12Следующая »

12 мая 2011

#UDK, #Unreal Development Kit

Оформление программного кода

Правила оформления отчётов

 

Содержание отчёта

На первой странице отчёта располагается титульный лист. На второй странице располагается содержание. За ним идёт задание. После задания следует исследуемая схема. Над схемой приводится её краткое описание со ссылкой на рисунок.

Следующим пунктом идёт блок-схема реализуемого алгоритма. После неё идет словесное описание алгоритма, представленного на блок схеме и обоснование этого варианта реализации. Процесс повторяется для каждой из реализованных блок схем.

В конце делаются выводы по работе с анализом проведённой работы и оценкой полученных результатов.

В приложение выносятся все программные коды.

Оформление титульного листа

Оформление титульного листа приведено в приложении 1.

Общие настройки оформления отчёта

Печать односторонняя.

Формат листа: А4.

Размер шрифта: 14.

Интервал: 1.5.

Поля: 20 мм.

Отступ красной строки. 10 мм

Выравнивание текста по ширине за исключением специально оговорённых случаев, например, подписей под рисунками.

При рукописном оформлении необходимо выдерживать требо­вания по размеру полей.

Оформление рисунков

На каждый рисунок должна быть ссылка в тексте, например "… приведено на рис. 2.3" или "… составим схему замещения (рис. 2.5)". При повторной ссылке на одну и ту же иллюстрацию указывают сокращенно слово "смот­ри", например: (см. рис. 2.3).

Рисунки могут быть расположены по тексту документа после пер­вой ссылки на них или размещены на отдельных листах так, чтобы их было удобно рассматривать без поворота страницы или с поворотом по часовой стрелке. В этом случае рисунок не прикрепляется к отчёту, а просто вкладывается.

Рисунок выравнивается по центру. Крайне желательно, что бы рисунок и ссылка на него располагались на одной странице, если рисунок не выносится в приложение.

Рисунок без ссылок в тексте использоваться не может.

Оформление таблиц

Таблицу размещают после первого упоминания в тексте так, чтобы ее было удобно читать без поворота отчёта или с поворотом по часовой стрелке.

На все таблицы должны быть ссылки в тексте, например "…

Antananarivo Фото со стоков и изображения

при­ведены в табл.1.2". Если таблица не имеет номера, при ссылке слово "таблица" пишут полностью.

Если все физические величины, приведенные в таблице, выра­жены в одних и тех же единицах, то обозначение единицы помеща­ют в заголовке через запятую, например: "Размеры изделий, мм".

Обозначение единицы физической величины, общей для всех дан­ных в строке или графе, указывают в соответствующей строке бо­ковика или в заголовке графы.

Не допускается делить заголовки таблицы по диагонали и вклю­чать графу "номер по порядку".

Нумерация

Нумерация рисунков

Нумерация рисунков в лабораторном отчёте сквозная.

Рисунок подписывается снизу по центру. Например: Рис. 1. Тестовое изображение “Lena”. После названия рисунка точка не ставится. Подпись под рисунком и сам рисунок должны располагаться на одной странице. Все рисунки должны быть подписаны.

Рис. 1. Тестовое изображение “Lena”

Нумерация таблиц

Нумерация таблиц, так же как и рисунков в лабораторном отчёте сквозная. Все таблицы должны быть пронумерованы. Подписывается таблица справа сверху. Например:

      Таблица 1.
       
       

 

Если в отчете одна таблица, те её не нумеруют (пишут “Таблица”). При переносе таблицы на другой лист в его правом верхнем углу пишут слово "продолжение" и номер таблицы, например, "Продол­жение табл. 1.2". Если в отчете одна таблица, то при ее переносе пишут слово "Продолжение"

 

Нумерация страниц

Титульный лист считается первой страницей и не нумеруется. Нумерация начинается со второй страницы, делается арабскими цифрами и выравнивается по центру внизу страницы.

Нумерация списков

Содержащиеся в тексте перечисления выделяют арабскими циф­рами со скобкой: 1), 2) и т.д., или вместо цифр ставят тире.

Нумерация приложений

Приложения имеют отдельную от общего текста нумерацию.

Оформление программного кода

Табуляция

Табуляция или смещение кода направо делается по следующим правилам.

Код, содержащийся внутри фигурных скобок, смещается направо на 1.

{

<code>;

}

В частности:

Весь код внутри функции должен быть смещён на 1.

Код внутри циклов и операторов if так же должен иметь смещение 1, прибавляемое к уже имеющемуся смещению самого оператора.

void function1(void)

{

<code1>;

if (<условие>)

{

<code2>;

}

}

Пустые строки

Пустые строки должны отделать одну часть кода от другой. В частности.

Должна быть минимум одна пустая строка после всего перечня #include.

Должна быть минимум одна пустая строка после всего перечня #define.

Между функциями должно быть не менее 2-х строк.

Должна быть хотя бы одна пустая строка после объявления всех переменных.

Разделение кода на функции

Крайне желательно разделять код на исполняемые участки (функции). В частности инициализация микроконтроллера должна быть вынесена в отдельные функции. Например: void MCU_ini(void) {} или void LED_ini(void){}. В функции main используются только сами функции.

Использование директивы #define

Часто используемые константы или блоки кода должны быть заменены на ключевые выражения при помощи директивы #define.

#define PI 3.14

#define LED_ON() GPIO_Set(GPIOB, GPIO_Pin_6)

#define LED_OFF() GPIO_Reset(GPIOB, GPIO_Pin_6)

Ключевые выражения традиционно записываются с использованием только заглавных букв.

Комментарии

Как минимум каждый блок кода должен иметь комментарий с описанием того, что он делает. Функции должны сверху иметь как минимум комментарий //—————————————, позволяющий легко вычислять местоположение начала функции. Данный комментарий используется, если применение функции очевидно (говорящее название, не имеет параметров и т.д.).

Если необходимо подробно описать функцию, используется комментарий вида:

//—————————————

// Описание функции

//—————————————

Где во второй строке пишется описание того, что делает эта функция. При необходимости приводится описание входных и выходных параметров.

Правила именования переменных.

Глобальные переменные должны иметь говорящие об их назначении названия (uart_transmit_data[], uart_receive_data[]). Локальные переменные могут иметь короткие, безликие названия в том случае, если их использование ограничивается короткой функцией (счетчик цикла).

В качестве названий локальных переменных как правило используют следующие:

Для циклов зачастую используют переменные I, j, k. Например:

for (i=0;i<N;i++) {}

Для строковых переменных используют название str.

 

 

Приложение



Дата добавления: 2017-03-12; просмотров: 78 | Нарушение авторских прав


Поиск на сайте:


Добавить комментарий

Закрыть меню